]> git.wh0rd.org Git - tt-rss.git/blob - simplepie/simplepie.inc
update_daemon2: don't expect client part to be executable
[tt-rss.git] / simplepie / simplepie.inc
1 <?php
2 /**
3  * SimplePie
4  *
5  * A PHP-Based RSS and Atom Feed Framework.
6  * Takes the hard work out of managing a complete RSS/Atom solution.
7  *
8  * Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without modification, are
12  * permitted provided that the following conditions are met:
13  *
14  *      * Redistributions of source code must retain the above copyright notice, this list of
15  *        conditions and the following disclaimer.
16  *
17  *      * Redistributions in binary form must reproduce the above copyright notice, this list
18  *        of conditions and the following disclaimer in the documentation and/or other materials
19  *        provided with the distribution.
20  *
21  *      * Neither the name of the SimplePie Team nor the names of its contributors may be used
22  *        to endorse or promote products derived from this software without specific prior
23  *        written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
26  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
28  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
32  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  *
35  * @package SimplePie
36  * @version "Razzleberry"
37  * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
38  * @author Ryan Parman
39  * @author Geoffrey Sneddon
40  * @link http://simplepie.org/ SimplePie
41  * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
42  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
43  * @todo phpDoc comments
44  */
45
46 /**
47  * SimplePie Name
48  */
49 define('SIMPLEPIE_NAME', 'SimplePie');
50
51 /**
52  * SimplePie Version
53  */
54 define('SIMPLEPIE_VERSION', '1.0.1');
55
56 /**
57  * SimplePie Build
58  * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::parse_date() only every load of simplepie.inc)
59  */
60 define('SIMPLEPIE_BUILD', 20070719221955);
61
62 /**
63  * SimplePie Website URL
64  */
65 define('SIMPLEPIE_URL', 'http://simplepie.org/');
66
67 /**
68  * SimplePie Useragent
69  * @see SimplePie::set_useragent()
70  */
71 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
72
73 /**
74  * SimplePie Linkback
75  */
76 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
77
78 /**
79  * No Autodiscovery
80  * @see SimplePie::set_autodiscovery_level()
81  */
82 define('SIMPLEPIE_LOCATOR_NONE', 0);
83
84 /**
85  * Feed Link Element Autodiscovery
86  * @see SimplePie::set_autodiscovery_level()
87  */
88 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
89
90 /**
91  * Local Feed Extension Autodiscovery
92  * @see SimplePie::set_autodiscovery_level()
93  */
94 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
95
96 /**
97  * Local Feed Body Autodiscovery
98  * @see SimplePie::set_autodiscovery_level()
99  */
100 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
101
102 /**
103  * Remote Feed Extension Autodiscovery
104  * @see SimplePie::set_autodiscovery_level()
105  */
106 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
107
108 /**
109  * Remote Feed Body Autodiscovery
110  * @see SimplePie::set_autodiscovery_level()
111  */
112 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
113
114 /**
115  * All Feed Autodiscovery
116  * @see SimplePie::set_autodiscovery_level()
117  */
118 define('SIMPLEPIE_LOCATOR_ALL', 31);
119
120 /**
121  * No known feed type
122  */
123 define('SIMPLEPIE_TYPE_NONE', 0);
124
125 /**
126  * RSS 0.90
127  */
128 define('SIMPLEPIE_TYPE_RSS_090', 1);
129
130 /**
131  * RSS 0.91 (Netscape)
132  */
133 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
134
135 /**
136  * RSS 0.91 (Userland)
137  */
138 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
139
140 /**
141  * RSS 0.91 (both Netscape and Userland)
142  */
143 define('SIMPLEPIE_TYPE_RSS_091', 6);
144
145 /**
146  * RSS 0.92
147  */
148 define('SIMPLEPIE_TYPE_RSS_092', 8);
149
150 /**
151  * RSS 0.93
152  */
153 define('SIMPLEPIE_TYPE_RSS_093', 16);
154
155 /**
156  * RSS 0.94
157  */
158 define('SIMPLEPIE_TYPE_RSS_094', 32);
159
160 /**
161  * RSS 1.0
162  */
163 define('SIMPLEPIE_TYPE_RSS_10', 64);
164
165 /**
166  * RSS 2.0
167  */
168 define('SIMPLEPIE_TYPE_RSS_20', 128);
169
170 /**
171  * RDF-based RSS
172  */
173 define('SIMPLEPIE_TYPE_RSS_RDF', 65);
174
175 /**
176  * Non-RDF-based RSS (truly intended as syndication format)
177  */
178 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
179
180 /**
181  * All RSS
182  */
183 define('SIMPLEPIE_TYPE_RSS_ALL', 255);
184
185 /**
186  * Atom 0.3
187  */
188 define('SIMPLEPIE_TYPE_ATOM_03', 256);
189
190 /**
191  * Atom 1.0
192  */
193 define('SIMPLEPIE_TYPE_ATOM_10', 512);
194
195 /**
196  * All Atom
197  */
198 define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
199
200 /**
201  * All feed types
202  */
203 define('SIMPLEPIE_TYPE_ALL', 1023);
204
205 /**
206  * No construct
207  */
208 define('SIMPLEPIE_CONSTRUCT_NONE', 0);
209
210 /**
211  * Text construct
212  */
213 define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
214
215 /**
216  * HTML construct
217  */
218 define('SIMPLEPIE_CONSTRUCT_HTML', 2);
219
220 /**
221  * XHTML construct
222  */
223 define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
224
225 /**
226  * base64-encoded construct
227  */
228 define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
229
230 /**
231  * IRI construct
232  */
233 define('SIMPLEPIE_CONSTRUCT_IRI', 16);
234
235 /**
236  * A construct that might be HTML
237  */
238 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
239
240 /**
241  * All constructs
242  */
243 define('SIMPLEPIE_CONSTRUCT_ALL', 63);
244
245 /**
246  * PCRE for HTML attributes
247  */
248 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[a-z0-9\-._:]*)))?)*)\s*');
249
250 /**
251  * PCRE for XML attributes
252  */
253 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
254
255 /**
256  * XML Namespace
257  */
258 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
259
260 /**
261  * Atom 1.0 Namespace
262  */
263 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
264
265 /**
266  * Atom 0.3 Namespace
267  */
268 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
269
270 /**
271  * RDF Namespace
272  */
273 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
274
275 /**
276  * RSS 0.90 Namespace
277  */
278 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
279
280 /**
281  * RSS 1.0 Namespace
282  */
283 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
284
285 /**
286  * RSS 1.0 Content Module Namespace
287  */
288 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
289
290 /**
291  * DC 1.0 Namespace
292  */
293 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
294
295 /**
296  * DC 1.1 Namespace
297  */
298 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
299
300 /**
301  * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
302  */
303 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
304
305 /**
306  * GeoRSS Namespace
307  */
308 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
309
310 /**
311  * Media RSS Namespace
312  */
313 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
314
315 /**
316  * iTunes RSS Namespace
317  */
318 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
319
320 /**
321  * XHTML Namespace
322  */
323 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
324
325 /**
326  * IANA Link Relations Registry
327  */
328 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
329
330 /**
331  * Whether we're running on PHP5
332  */
333 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
334
335 /**
336  * SimplePie
337  *
338  * @package SimplePie
339  * @version "Razzleberry"
340  * @copyright 2004-2007 Ryan Parman, Geoffrey Sneddon
341  * @author Ryan Parman
342  * @author Geoffrey Sneddon
343  * @todo Option for type of fetching (cache, not modified header, fetch, etc.)
344  */
345 class SimplePie
346 {
347         /**
348          * @var array Raw data
349          * @access private
350          */
351         var $data = array();
352
353         /**
354          * @var mixed Error string
355          * @access private
356          */
357         var $error;
358
359         /**
360          * @var object Instance of SimplePie_Sanitize (or other class)
361          * @see SimplePie::set_sanitize_class()
362          * @access private
363          */
364         var $sanitize;
365
366         /**
367          * @var string SimplePie Useragent
368          * @see SimplePie::set_useragent()
369          * @access private
370          */
371         var $useragent = SIMPLEPIE_USERAGENT;
372
373         /**
374          * @var string Feed URL
375          * @see SimplePie::set_feed_url()
376          * @access private
377          */
378         var $feed_url;
379
380         /**
381          * @var object Instance of SimplePie_File to use as a feed
382          * @see SimplePie::set_file()
383          * @access private
384          */
385         var $file;
386
387         /**
388          * @var string Raw feed data
389          * @see SimplePie::set_raw_data()
390          * @access private
391          */
392         var $raw_data;
393
394         /**
395          * @var int Timeout for fetching remote files
396          * @see SimplePie::set_timeout()
397          * @access private
398          */
399         var $timeout = 10;
400
401         /**
402          * @var bool Forces fsockopen() to be used for remote files instead
403          * of cURL, even if a new enough version is installed
404          * @see SimplePie::force_fsockopen()
405          * @access private
406          */
407         var $force_fsockopen = false;
408
409         /**
410          * @var bool Enable/Disable XML dump
411          * @see SimplePie::enable_xml_dump()
412          * @access private
413          */
414         var $xml_dump = false;
415
416         /**
417          * @var bool Enable/Disable Caching
418          * @see SimplePie::enable_cache()
419          * @access private
420          */
421         var $cache = true;
422
423         /**
424          * @var int Cache duration (in seconds)
425          * @see SimplePie::set_cache_duration()
426          * @access private
427          */
428         var $cache_duration = 3600;
429
430         /**
431          * @var int Auto-discovery cache duration (in seconds)
432          * @see SimplePie::set_autodiscovery_cache_duration()
433          * @access private
434          */
435         var $autodiscovery_cache_duration = 604800; // 7 Days.
436
437         /**
438          * @var string Cache location (relative to executing script)
439          * @see SimplePie::set_cache_location()
440          * @access private
441          */
442         var $cache_location = './cache';
443
444         /**
445          * @var string Function that creates the cache filename
446          * @see SimplePie::set_cache_name_function()
447          * @access private
448          */
449         var $cache_name_function = 'md5';
450
451         /**
452          * @var bool Reorder feed by date descending
453          * @see SimplePie::enable_order_by_date()
454          * @access private
455          */
456         var $order_by_date = true;
457
458         /**
459          * @var mixed Force input encoding to be set to the follow value
460          * (false, or anything type-cast to false, disables this feature)
461          * @see SimplePie::set_input_encoding()
462          * @access private
463          */
464         var $input_encoding = false;
465
466         /**
467          * @var int Feed Autodiscovery Level
468          * @see SimplePie::set_autodiscovery_level()
469          * @access private
470          */
471         var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
472
473         /**
474          * @var string Class used for caching feeds
475          * @see SimplePie::set_cache_class()
476          * @access private
477          */
478         var $cache_class = 'SimplePie_Cache';
479
480         /**
481          * @var string Class used for locating feeds
482          * @see SimplePie::set_locator_class()
483          * @access private
484          */
485         var $locator_class = 'SimplePie_Locator';
486
487         /**
488          * @var string Class used for parsing feeds
489          * @see SimplePie::set_parser_class()
490          * @access private
491          */
492         var $parser_class = 'SimplePie_Parser';
493
494         /**
495          * @var string Class used for fetching feeds
496          * @see SimplePie::set_file_class()
497          * @access private
498          */
499         var $file_class = 'SimplePie_File';
500
501         /**
502          * @var string Class used for items
503          * @see SimplePie::set_item_class()
504          * @access private
505          */
506         var $item_class = 'SimplePie_Item';
507
508         /**
509          * @var string Class used for authors
510          * @see SimplePie::set_author_class()
511          * @access private
512          */
513         var $author_class = 'SimplePie_Author';
514
515         /**
516          * @var string Class used for categories
517          * @see SimplePie::set_category_class()
518          * @access private
519          */
520         var $category_class = 'SimplePie_Category';
521
522         /**
523          * @var string Class used for enclosures
524          * @see SimplePie::set_enclosures_class()
525          * @access private
526          */
527         var $enclosure_class = 'SimplePie_Enclosure';
528
529         /**
530          * @var string Class used for Media RSS <media:text> captions
531          * @see SimplePie::set_caption_class()
532          * @access private
533          */
534         var $caption_class = 'SimplePie_Caption';
535
536         /**
537          * @var string Class used for Media RSS <media:copyright>
538          * @see SimplePie::set_copyright_class()
539          * @access private
540          */
541         var $copyright_class = 'SimplePie_Copyright';
542
543         /**
544          * @var string Class used for Media RSS <media:credit>
545          * @see SimplePie::set_credit_class()
546          * @access private
547          */
548         var $credit_class = 'SimplePie_Credit';
549
550         /**
551          * @var string Class used for Media RSS <media:rating>
552          * @see SimplePie::set_rating_class()
553          * @access private
554          */
555         var $rating_class = 'SimplePie_Rating';
556
557         /**
558          * @var string Class used for Media RSS <media:restriction>
559          * @see SimplePie::set_restriction_class()
560          * @access private
561          */
562         var $restriction_class = 'SimplePie_Restriction';
563
564         /**
565          * @var mixed Set javascript query string parameter (false, or
566          * anything type-cast to false, disables this feature)
567          * @see SimplePie::set_javascript()
568          * @access private
569          */
570         var $javascript = 'js';
571
572         /**
573          * @var int Maximum number of feeds to check with autodiscovery
574          * @see SimplePie::set_max_checked_feeds()
575          * @access private
576          */
577         var $max_checked_feeds = 10;
578
579         /**
580          * @var string Web-accessible path to the handler_favicon.php file.
581          * @see SimplePie::set_favicon_handler()
582          * @access private
583          */
584         var $favicon_handler = '';
585
586         /**
587          * @var string Web-accessible path to the handler_image.php file.
588          * @see SimplePie::set_image_handler()
589          * @access private
590          */
591         var $image_handler = '';
592
593         /**
594          * @var array Stores the URLs when multiple feeds are being initialized.
595          * @see SimplePie::set_feed_url()
596          * @access private
597          */
598         var $multifeed_url = array();
599
600         /**
601          * @var array Stores SimplePie objects when multiple feeds initialized.
602          * @access private
603          */
604         var $multifeed_objects = array();
605
606         /**
607          * @var array Stores the get_object_vars() array for use with multifeeds.
608          * @see SimplePie::set_feed_url()
609          * @access private
610          */
611         var $config_settings = null;
612
613         /**
614          * @var array Stores the default attributes to be stripped by strip_attributes().
615          * @see SimplePie::strip_attributes()
616          * @access private
617          */
618         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
619
620         /**
621          * @var array Stores the default tags to be stripped by strip_htmltags().
622          * @see SimplePie::strip_htmltags()
623          * @access private
624          */
625         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
626
627         /**
628          * The SimplePie class contains feed level data and options
629          *
630          * There are two ways that you can create a new SimplePie object. The first
631          * is by passing a feed URL as a parameter to the SimplePie constructor
632          * (as well as optionally setting the cache location and cache expiry). This
633          * will initialise the whole feed with all of the default settings, and you
634          * can begin accessing methods and properties immediately.
635          *
636          * The second way is to create the SimplePie object with no parameters
637          * at all. This will enable you to set configuration options. After setting
638          * them, you must initialise the feed using $feed->init(). At that point the
639          * object's methods and properties will be available to you. This format is
640          * what is used throughout this documentation.
641          *
642          * @access public
643          * @since 1.0 Preview Release
644          * @param string $feed_url This is the URL you want to parse.
645          * @param string $cache_location This is where you want the cache to be stored.
646          * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
647          */
648         function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
649         {
650                 // Other objects, instances created here so we can set options on them
651                 $this->sanitize =& new SimplePie_Sanitize;
652
653                 // Set options if they're passed to the constructor
654                 if ($cache_location !== null)
655                 {
656                         $this->set_cache_location($cache_location);
657                 }
658
659                 if ($cache_duration !== null)
660                 {
661                         $this->set_cache_duration($cache_duration);
662                 }
663
664                 // Only init the script if we're passed a feed URL
665                 if ($feed_url !== null)
666                 {
667                         $this->set_feed_url($feed_url);
668                         $this->init();
669                 }
670         }
671
672         /**
673          * Used for converting object to a string
674          */
675         function __toString()
676         {
677                 return md5(serialize($this->data));
678         }
679
680         /**
681          * This is the URL of the feed you want to parse.
682          *
683          * This allows you to enter the URL of the feed you want to parse, or the
684          * website you want to try to use auto-discovery on. This takes priority
685          * over any set raw data.
686          *
687          * You can set multiple feeds to mash together by passing an array instead
688          * of a string for the $url. Remember that with each additional feed comes
689          * additional processing and resources.
690          *
691          * @access public
692          * @since 1.0 Preview Release
693          * @param mixed $url This is the URL (or array of URLs) that you want to parse.
694          * @see SimplePie::set_raw_data()
695          */
696         function set_feed_url($url)
697         {
698                 if (is_array($url))
699                 {
700                         $this->multifeed_url = array();
701                         foreach ($url as $value)
702                         {
703                                 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
704                         }
705                 }
706                 else
707                 {
708                         $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
709                 }
710         }
711
712         /**
713          * Provides an instance of SimplePie_File to use as a feed
714          *
715          * @access public
716          * @param object &$file Instance of SimplePie_File (or subclass)
717          * @return bool True on success, false on failure
718          */
719         function set_file(&$file)
720         {
721                 if (SimplePie_Misc::is_a($file, 'SimplePie_File'))
722                 {
723                         $this->feed_url = $file->url;
724                         $this->file =& $file;
725                         return true;
726                 }
727                 return false;
728         }
729
730         /**
731          * Allows you to use a string of RSS/Atom data instead of a remote feed.
732          *
733          * If you have a feed available as a string in PHP, you can tell SimplePie
734          * to parse that data string instead of a remote feed. Any set feed URL
735          * takes precedence.
736          *
737          * @access public
738          * @since 1.0 Beta 3
739          * @param string $data RSS or Atom data as a string.
740          * @see SimplePie::set_feed_url()
741          */
742         function set_raw_data($data)
743         {
744                 $this->raw_data = trim($data);
745         }
746
747         /**
748          * Allows you to override the default timeout for fetching remote feeds.
749          *
750          * This allows you to change the maximum time the feed's server to respond
751          * and send the feed back.
752          *
753          * @access public
754          * @since 1.0 Beta 3
755          * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
756          */
757         function set_timeout($timeout = 10)
758         {
759                 $this->timeout = (int) $timeout;
760         }
761
762         /**
763          * Forces SimplePie to use fsockopen() instead of the preferred cURL
764          * functions.
765          *
766          * @access public
767          * @since 1.0 Beta 3
768          * @param bool $enable Force fsockopen() to be used
769          */
770         function force_fsockopen($enable = false)
771         {
772                 $this->force_fsockopen = (bool) $enable;
773         }
774
775         /**
776          * Outputs the raw XML content of the feed, after it has gone through
777          * SimplePie's filters.
778          *
779          * Used only for debugging, this function will output the XML content as
780          * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
781          * before trying to parse it. Many parts of the feed are re-written in
782          * memory, and in the end, you have a parsable feed. XML dump shows you the
783          * actual XML that SimplePie tries to parse, which may or may not be very
784          * different from the original feed.
785          *
786          * @access public
787          * @since 1.0 Preview Release
788          * @param bool $enable Enable XML dump
789          */
790         function enable_xml_dump($enable = false)
791         {
792                 $this->xml_dump = (bool) $enable;
793         }
794
795         /**
796          * Enables/disables caching in SimplePie.
797          *
798          * This option allows you to disable caching all-together in SimplePie.
799          * However, disabling the cache can lead to longer load times.
800          *
801          * @access public
802          * @since 1.0 Preview Release
803          * @param bool $enable Enable caching
804          */
805         function enable_cache($enable = true)
806         {
807                 $this->cache = (bool) $enable;
808         }
809
810         /**
811          * Set the length of time (in seconds) that the contents of a feed
812          * will be cached.
813          *
814          * @access public
815          * @param int $seconds The feed content cache duration.
816          */
817         function set_cache_duration($seconds = 3600)
818         {
819                 $this->cache_duration = (int) $seconds;
820         }
821
822         /**
823          * Set the length of time (in seconds) that the autodiscovered feed
824          * URL will be cached.
825          *
826          * @access public
827          * @param int $seconds The autodiscovered feed URL cache duration.
828          */
829         function set_autodiscovery_cache_duration($seconds = 604800)
830         {
831                 $this->autodiscovery_cache_duration = (int) $seconds;
832         }
833
834         /**
835          * Set the file system location where the cached files should be stored.
836          *
837          * @access public
838          * @param string $location The file system location.
839          */
840         function set_cache_location($location = './cache')
841         {
842                 $this->cache_location = (string) $location;
843         }
844
845         /**
846          * Determines whether feed items should be sorted into reverse chronological order.
847          *
848          * @access public
849          * @param bool $enable Sort as reverse chronological order.
850          */
851         function enable_order_by_date($enable = true)
852         {
853                 $this->order_by_date = (bool) $enable;
854         }
855
856         /**
857          * Allows you to override the character encoding reported by the feed.
858          *
859          * @access public
860          * @param string $encoding Character encoding.
861          */
862         function set_input_encoding($encoding = false)
863         {
864                 if ($encoding)
865                 {
866                         $this->input_encoding = (string) $encoding;
867                 }
868                 else
869                 {
870                         $this->input_encoding = false;
871                 }
872         }
873
874         /**
875          * Set how much feed autodiscovery to do
876          *
877          * @access public
878          * @see SIMPLEPIE_LOCATOR_NONE
879          * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
880          * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
881          * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
882          * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
883          * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
884          * @see SIMPLEPIE_LOCATOR_ALL
885          * @param int $level Feed Autodiscovery Level (level can be a
886          * combination of the above constants, see bitwise OR operator)
887          */
888         function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
889         {
890                 $this->autodiscovery = (int) $level;
891         }
892
893         /**
894          * Allows you to change which class SimplePie uses for caching.
895          * Useful when you are overloading or extending SimplePie's default classes.
896          *
897          * @access public
898          * @param string $class Name of custom class.
899          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
900          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
901          */
902         function set_cache_class($class = 'SimplePie_Cache')
903         {
904                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
905                 {
906                         $this->cache_class = $class;
907                         return true;
908                 }
909                 return false;
910         }
911
912         /**
913          * Allows you to change which class SimplePie uses for auto-discovery.
914          * Useful when you are overloading or extending SimplePie's default classes.
915          *
916          * @access public
917          * @param string $class Name of custom class.
918          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
919          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
920          */
921         function set_locator_class($class = 'SimplePie_Locator')
922         {
923                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
924                 {
925                         $this->locator_class = $class;
926                         return true;
927                 }
928                 return false;
929         }
930
931         /**
932          * Allows you to change which class SimplePie uses for XML parsing.
933          * Useful when you are overloading or extending SimplePie's default classes.
934          *
935          * @access public
936          * @param string $class Name of custom class.
937          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
938          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
939          */
940         function set_parser_class($class = 'SimplePie_Parser')
941         {
942                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
943                 {
944                         $this->parser_class = $class;
945                         return true;
946                 }
947                 return false;
948         }
949
950         /**
951          * Allows you to change which class SimplePie uses for remote file fetching.
952          * Useful when you are overloading or extending SimplePie's default classes.
953          *
954          * @access public
955          * @param string $class Name of custom class.
956          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
957          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
958          */
959         function set_file_class($class = 'SimplePie_File')
960         {
961                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
962                 {
963                         $this->file_class = $class;
964                         return true;
965                 }
966                 return false;
967         }
968
969         /**
970          * Allows you to change which class SimplePie uses for data sanitization.
971          * Useful when you are overloading or extending SimplePie's default classes.
972          *
973          * @access public
974          * @param string $class Name of custom class.
975          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
976          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
977          */
978         function set_sanitize_class($class = 'SimplePie_Sanitize')
979         {
980                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
981                 {
982                         $this->sanitize =& new $class;
983                         return true;
984                 }
985                 return false;
986         }
987
988         /**
989          * Allows you to change which class SimplePie uses for handling feed items.
990          * Useful when you are overloading or extending SimplePie's default classes.
991          *
992          * @access public
993          * @param string $class Name of custom class.
994          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
995          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
996          */
997         function set_item_class($class = 'SimplePie_Item')
998         {
999                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1000                 {
1001                         $this->item_class = $class;
1002                         return true;
1003                 }
1004                 return false;
1005         }
1006
1007         /**
1008          * Allows you to change which class SimplePie uses for handling author data.
1009          * Useful when you are overloading or extending SimplePie's default classes.
1010          *
1011          * @access public
1012          * @param string $class Name of custom class.
1013          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1014          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1015          */
1016         function set_author_class($class = 'SimplePie_Author')
1017         {
1018                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1019                 {
1020                         $this->author_class = $class;
1021                         return true;
1022                 }
1023                 return false;
1024         }
1025
1026         /**
1027          * Allows you to change which class SimplePie uses for handling category data.
1028          * Useful when you are overloading or extending SimplePie's default classes.
1029          *
1030          * @access public
1031          * @param string $class Name of custom class.
1032          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1033          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1034          */
1035         function set_category_class($class = 'SimplePie_Category')
1036         {
1037                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1038                 {
1039                         $this->category_class = $class;
1040                         return true;
1041                 }
1042                 return false;
1043         }
1044
1045         /**
1046          * Allows you to change which class SimplePie uses for feed enclosures.
1047          * Useful when you are overloading or extending SimplePie's default classes.
1048          *
1049          * @access public
1050          * @param string $class Name of custom class.
1051          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1052          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1053          */
1054         function set_enclosure_class($class = 'SimplePie_Enclosure')
1055         {
1056                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1057                 {
1058                         $this->enclosure_class = $class;
1059                         return true;
1060                 }
1061                 return false;
1062         }
1063
1064         /**
1065          * Allows you to change which class SimplePie uses for <media:text> captions
1066          * Useful when you are overloading or extending SimplePie's default classes.
1067          *
1068          * @access public
1069          * @param string $class Name of custom class.
1070          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1071          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1072          */
1073         function set_caption_class($class = 'SimplePie_Caption')
1074         {
1075                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1076                 {
1077                         $this->caption_class = $class;
1078                         return true;
1079                 }
1080                 return false;
1081         }
1082
1083         /**
1084          * Allows you to change which class SimplePie uses for <media:copyright>
1085          * Useful when you are overloading or extending SimplePie's default classes.
1086          *
1087          * @access public
1088          * @param string $class Name of custom class.
1089          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1090          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1091          */
1092         function set_copyright_class($class = 'SimplePie_Copyright')
1093         {
1094                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1095                 {
1096                         $this->copyright_class = $class;
1097                         return true;
1098                 }
1099                 return false;
1100         }
1101
1102         /**
1103          * Allows you to change which class SimplePie uses for <media:credit>
1104          * Useful when you are overloading or extending SimplePie's default classes.
1105          *
1106          * @access public
1107          * @param string $class Name of custom class.
1108          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1109          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1110          */
1111         function set_credit_class($class = 'SimplePie_Credit')
1112         {
1113                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1114                 {
1115                         $this->credit_class = $class;
1116                         return true;
1117                 }
1118                 return false;
1119         }
1120
1121         /**
1122          * Allows you to change which class SimplePie uses for <media:rating>
1123          * Useful when you are overloading or extending SimplePie's default classes.
1124          *
1125          * @access public
1126          * @param string $class Name of custom class.
1127          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1128          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1129          */
1130         function set_rating_class($class = 'SimplePie_Rating')
1131         {
1132                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1133                 {
1134                         $this->rating_class = $class;
1135                         return true;
1136                 }
1137                 return false;
1138         }
1139
1140         /**
1141          * Allows you to change which class SimplePie uses for <media:restriction>
1142          * Useful when you are overloading or extending SimplePie's default classes.
1143          *
1144          * @access public
1145          * @param string $class Name of custom class.
1146          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1147          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1148          */
1149         function set_restriction_class($class = 'SimplePie_Restriction')
1150         {
1151                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1152                 {
1153                         $this->restriction_class = $class;
1154                         return true;
1155                 }
1156                 return false;
1157         }
1158
1159         /**
1160          * Allows you to override the default user agent string.
1161          *
1162          * @access public
1163          * @param string $ua New user agent string.
1164          */
1165         function set_useragent($ua = SIMPLEPIE_USERAGENT)
1166         {
1167                 $this->useragent = (string) $ua;
1168         }
1169
1170         /**
1171          * Set callback function to create cache filename with
1172          *
1173          * @access public
1174          * @param mixed $function Callback function
1175          */
1176         function set_cache_name_function($function = 'md5')
1177         {
1178                 if (is_callable($function))
1179                 {
1180                         $this->cache_name_function = $function;
1181                 }
1182         }
1183
1184         /**
1185          * Set javascript query string parameter
1186          *
1187          * @access public
1188          * @param mixed $get Javascript query string parameter
1189          */
1190         function set_javascript($get = 'js')
1191         {
1192                 if ($get)
1193                 {
1194                         $this->javascript = (string) $get;
1195                 }
1196                 else
1197                 {
1198                         $this->javascript = false;
1199                 }
1200         }
1201
1202         /**
1203          * Set options to make SP as fast as possible.  Forgoes a
1204          * substantial amount of data sanitization in favor of speed.
1205          *
1206          * @access public
1207          * @param bool $set Whether to set them or not
1208          */
1209         function set_stupidly_fast($set = false)
1210         {
1211                 if ($set)
1212                 {
1213                         $this->enable_order_by_date(false);
1214                         $this->remove_div(false);
1215                         $this->strip_comments(false);
1216                         $this->strip_htmltags(false);
1217                         $this->strip_attributes(false);
1218                         $this->set_image_handler(false);
1219                 }
1220         }
1221
1222         /**
1223          * Set maximum number of feeds to check with autodiscovery
1224          *
1225          * @access public
1226          * @param int $max Maximum number of feeds to check
1227          */
1228         function set_max_checked_feeds($max = 10)
1229         {
1230                 $this->max_checked_feeds = (int) $max;
1231         }
1232
1233         function remove_div($enable = true)
1234         {
1235                 $this->sanitize->remove_div($enable);
1236         }
1237
1238         function strip_htmltags($tags = '', $encode = null)
1239         {
1240                 if ($tags === '')
1241                 {
1242                         $tags = $this->strip_htmltags;
1243                 }
1244                 $this->sanitize->strip_htmltags($tags);
1245                 if ($encode !== null)
1246                 {
1247                         $this->sanitize->encode_instead_of_strip($tags);
1248                 }
1249         }
1250
1251         function encode_instead_of_strip($enable = true)
1252         {
1253                 $this->sanitize->encode_instead_of_strip($enable);
1254         }
1255
1256         function strip_attributes($attribs = '')
1257         {
1258                 if ($attribs === '')
1259                 {
1260                         $attribs = $this->strip_attributes;
1261                 }
1262                 $this->sanitize->strip_attributes($attribs);
1263         }
1264
1265         function set_output_encoding($encoding = 'UTF-8')
1266         {
1267                 $this->sanitize->set_output_encoding($encoding);
1268         }
1269
1270         function strip_comments($strip = false)
1271         {
1272                 $this->sanitize->strip_comments($strip);
1273         }
1274
1275         /**
1276          * Set element/attribute key/value pairs of HTML attributes
1277          * containing URLs that need to be resolved relative to the feed
1278          *
1279          * @access public
1280          * @since 1.0
1281          * @param array $element_attribute Element/attribute key/value pairs
1282          */
1283         function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
1284         {
1285                 $this->sanitize->set_url_replacements($element_attribute);
1286         }
1287
1288         /**
1289          * Set the handler to enable the display of cached favicons.
1290          *
1291          * @access public
1292          * @param str $page Web-accessible path to the handler_favicon.php file.
1293          * @param str $qs The query string that the value should be passed to.
1294          */
1295         function set_favicon_handler($page = false, $qs = 'i')
1296         {
1297                 if ($page != false)
1298                 {
1299                         $this->favicon_handler = $page . '?' . $qs . '=';
1300                 }
1301                 else
1302                 {
1303                         $this->favicon_handler = '';
1304                 }
1305         }
1306
1307         /**
1308          * Set the handler to enable the display of cached images.
1309          *
1310          * @access public
1311          * @param str $page Web-accessible path to the handler_image.php file.
1312          * @param str $qs The query string that the value should be passed to.
1313          */
1314         function set_image_handler($page = false, $qs = 'i')
1315         {
1316                 if ($page != false)
1317                 {
1318                         $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1319                 }
1320                 else
1321                 {
1322                         $this->image_handler = '';
1323                 }
1324         }
1325
1326         function init()
1327         {
1328                 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.1.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1329                 {
1330                         return false;
1331                 }
1332                 if (isset($_GET[$this->javascript]))
1333                 {
1334                         if (function_exists('ob_gzhandler'))
1335                         {
1336                                 ob_start('ob_gzhandler');
1337                         }
1338                         header('Content-type: text/javascript; charset: UTF-8');
1339                         header('Cache-Control: must-revalidate');
1340                         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
1341                         ?>
1342 function embed_odeo(link) {
1343         document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');
1344 }
1345
1346 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
1347         if (placeholder != '') {
1348                 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1349         }
1350         else {
1351                 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
1352         }
1353 }
1354
1355 function embed_flash(bgcolor, width, height, link, loop, type) {
1356         document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');
1357 }
1358
1359 function embed_flv(width, height, link, placeholder, loop, player) {
1360         document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');
1361 }
1362
1363 function embed_wmedia(width, height, link) {
1364         document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
1365 }
1366                         <?php
1367                         exit;
1368                 }
1369
1370                 // Pass whatever was set with config options over to the sanitizer.
1371                 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1372                 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1373
1374                 if ($this->feed_url !== null || $this->raw_data !== null)
1375                 {
1376                         $this->data = array();
1377                         $this->multifeed_objects = array();
1378                         $cache = false;
1379
1380                         if ($this->feed_url !== null)
1381                         {
1382                                 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1383                                 // Decide whether to enable caching
1384                                 if ($this->cache && $parsed_feed_url['scheme'] !== '')
1385                                 {
1386                                         $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1387                                 }
1388                                 // If it's enabled and we don't want an XML dump, use the cache
1389                                 if ($cache && !$this->xml_dump)
1390                                 {
1391                                         // Load the Cache
1392                                         $this->data = $cache->load();
1393                                         if (!empty($this->data))
1394                                         {
1395                                                 // If the cache is for an outdated build of SimplePie
1396                                                 if (!isset($this->data['build']) || $this->data['build'] != SIMPLEPIE_BUILD)
1397                                                 {
1398                                                         $cache->unlink();
1399                                                         $this->data = array();
1400                                                 }
1401                                                 // If we've hit a collision just rerun it with caching disabled
1402                                                 elseif (isset($this->data['url']) && $this->data['url'] != $this->feed_url)
1403                                                 {
1404                                                         $cache = false;
1405                                                         $this->data = array();
1406                                                 }
1407                                                 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1408                                                 elseif (isset($this->data['feed_url']))
1409                                                 {
1410                                                         // If the autodiscovery cache is still valid use it.
1411                                                         if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1412                                                         {
1413                                                                 // Do not need to do feed autodiscovery yet.
1414                                                                 if ($this->data['feed_url'] == $this->data['url'])
1415                                                                 {
1416                                                                         $cache->unlink();
1417                                                                         $this->data = array();
1418                                                                 }
1419                                                                 else
1420                                                                 {
1421                                                                         $this->set_feed_url($this->data['feed_url']);
1422                                                                         return $this->init();
1423                                                                 }
1424                                                         }
1425                                                 }
1426                                                 // Check if the cache has been updated
1427                                                 elseif ($cache->mtime() + $this->cache_duration < time())
1428                                                 {
1429                                                         // If we have last-modified and/or etag set
1430                                                         if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1431                                                         {
1432                                                                 $headers = array();
1433                                                                 if (isset($this->data['headers']['last-modified']))
1434                                                                 {
1435                                                                         $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1436                                                                 }
1437                                                                 if (isset($this->data['headers']['etag']))
1438                                                                 {
1439                                                                         $headers['if-none-match'] = $this->data['headers']['etag'];
1440                                                                 }
1441                                                                 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1442                                                                 if ($file->success)
1443                                                                 {
1444                                                                         if ($file->status_code == 304)
1445                                                                         {
1446                                                                                 $cache->touch();
1447                                                                                 return true;
1448                                                                         }
1449                                                                         else
1450                                                                         {
1451                                                                                 $headers = $file->headers;
1452                                                                         }
1453                                                                 }
1454                                                                 else
1455                                                                 {
1456                                                                         unset($file);
1457                                                                 }
1458                                                         }
1459                                                 }
1460                                                 // If the cache is still valid, just return true
1461                                                 else
1462                                                 {
1463                                                         return true;
1464                                                 }
1465                                         }
1466                                         // If the cache is empty, delete it
1467                                         else
1468                                         {
1469                                                 $cache->unlink();
1470                                                 $this->data = array();
1471                                         }
1472                                 }
1473                                 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
1474                                 if (!isset($file))
1475                                 {
1476                                         if (SimplePie_Misc::is_a($this->file, 'SimplePie_File') && $this->file->url == $this->feed_url)
1477                                         {
1478                                                 $file =& $this->file;
1479                                         }
1480                                         else
1481                                         {
1482                                                 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1483                                         }
1484                                 }
1485                                 // If the file connection has an error, set SimplePie::error to that and quit
1486                                 if (!$file->success)
1487                                 {
1488                                         $this->error = $file->error;
1489                                         if (!empty($this->data))
1490                                         {
1491                                                 return true;
1492                                         }
1493                                         else
1494                                         {
1495                                                 return false;
1496                                         }
1497                                 }
1498
1499                                 // Check if the supplied URL is a feed, if it isn't, look for it.
1500                                 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds);
1501                                 if (!$locate->is_feed($file))
1502                                 {
1503                                         // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1504                                         unset($file);
1505                                         if ($file = $locate->find($this->autodiscovery))
1506                                         {
1507                                                 if ($cache)
1508                                                 {
1509                                                         if (!$cache->save(array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD)))
1510                                                         {
1511                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1512                                                         }
1513                                                         $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1514                                                 }
1515                                                 $this->feed_url = $file->url;
1516                                         }
1517                                         else
1518                                         {
1519                                                 $this->error = "A feed could not be found at $this->feed_url";
1520                                                 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1521                                                 return false;
1522                                         }
1523                                 }
1524                                 $locate = null;
1525
1526                                 $headers = $file->headers;
1527                                 $data = trim($file->body);
1528                                 unset($file);
1529                         }
1530                         else
1531                         {
1532                                 $data = $this->raw_data;
1533                         }
1534
1535                         // First check to see if input has been overridden.
1536                         if ($this->input_encoding !== false)
1537                         {
1538                                 $encoding = $this->input_encoding;
1539                         }
1540                         // Second try HTTP headers
1541                         elseif (isset($headers['content-type']) && preg_match('/;[\x09\x20]*charset=([^;]*)/i', $headers['content-type'], $charset))
1542                         {
1543                                 $encoding = $charset[1];
1544                         }
1545                         // Then prolog, if at the very start of the document
1546                         elseif (preg_match("/^<\?xml[\x20\x9\xD\xA]+version([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"1.0\"|'1.0'|\"1.1\"|'1.1')[\x20\x9\xD\xA]+encoding([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"[A-Za-z][A-Za-z0-9._\-]*\"|'[A-Za-z][A-Za-z0-9._\-]*')([\x20\x9\xD\xA]+standalone([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"(yes|no)\"|'(yes|no)'))?([\x20\x9\xD\xA]+)?\?>/", $data, $prolog))
1547                         {
1548                                 $encoding = substr($prolog[6], 1, -1);
1549                         }
1550                         // UTF-32 Big Endian BOM
1551                         elseif (strpos($data, "\x0\x0\xFE\xFF") === 0)
1552                         {
1553                                 $encoding = 'UTF-32be';
1554                         }
1555                         // UTF-32 Little Endian BOM
1556                         elseif (strpos($data, "\xFF\xFE\x0\x0") === 0)
1557                         {
1558                                 $encoding = 'UTF-32';
1559                         }
1560                         // UTF-16 Big Endian BOM
1561                         elseif (strpos($data, "\xFE\xFF") === 0)
1562                         {
1563                                 $encoding = 'UTF-16be';
1564                         }
1565                         // UTF-16 Little Endian BOM
1566                         elseif (strpos($data, "\xFF\xFE") === 0)
1567                         {
1568                                 $encoding = 'UTF-16le';
1569                         }
1570                         // UTF-8 BOM
1571                         elseif (strpos($data, "\xEF\xBB\xBF") === 0)
1572                         {
1573                                 $encoding = 'UTF-8';
1574                         }
1575                         // Fallback to the default (US-ASCII for text/xml, ISO-8859-1 for text/* MIME types, UTF-8 otherwise)
1576                         elseif (isset($headers['content-type']) && strtolower(SimplePie_Misc::parse_mime($headers['content-type'])) == 'text/xml')
1577                         {
1578                                 $encoding = 'US-ASCII';
1579                         }
1580                         elseif (isset($headers['content-type']) && SimplePie_Misc::stripos(SimplePie_Misc::parse_mime($headers['content-type']), 'text/') === 0)
1581                         {
1582                                 $encoding = 'ISO-8859-1';
1583                         }
1584                         else
1585                         {
1586                                 $encoding = 'UTF-8';
1587                         }
1588
1589                         // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1590                         if ($encoding != 'UTF-8')
1591                         {
1592                                 $data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8');
1593                         }
1594
1595                         // Strip illegal characters
1596                         $data = SimplePie_Misc::utf8_bad_replace($data);
1597
1598                         $parser =& new $this->parser_class();
1599                         $parser->pre_process($data, 'UTF-8');
1600                         // If we want the XML, just output that and quit
1601                         if ($this->xml_dump)
1602                         {
1603                                 header('Content-type: text/xml; charset=UTF-8');
1604                                 echo $data;
1605                                 exit;
1606                         }
1607                         // If it's parsed fine
1608                         elseif ($parser->parse($data))
1609                         {
1610                                 unset($data);
1611                                 $this->data = $parser->get_data();
1612                                 if (isset($this->data['child']))
1613                                 {
1614                                         if (isset($headers))
1615                                         {
1616                                                 $this->data['headers'] = $headers;
1617                                         }
1618                                         $this->data['build'] = SIMPLEPIE_BUILD;
1619
1620                                         // Cache the file if caching is enabled
1621                                         if ($cache && !$cache->save($this->data))
1622                                         {
1623                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
1624                                         }
1625                                         return true;
1626                                 }
1627                                 else
1628                                 {
1629                                         $this->error = "A feed could not be found at $this->feed_url";
1630                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1631                                         return false;
1632                                 }
1633                         }
1634                         // If we have an error, just set SimplePie::error to it and quit
1635                         else
1636                         {
1637                                 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
1638                                 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1639                                 return false;
1640                         }
1641                 }
1642                 elseif (!empty($this->multifeed_url))
1643                 {
1644                         $i = 0;
1645                         $success = 0;
1646                         $this->multifeed_objects = array();
1647                         foreach ($this->multifeed_url as $url)
1648                         {
1649                                 if (SIMPLEPIE_PHP5)
1650                                 {
1651                                         // This keyword needs to defy coding standards for PHP4 compatibility
1652                                         $this->multifeed_objects[$i] = clone($this);
1653                                 }
1654                                 else
1655                                 {
1656                                         $this->multifeed_objects[$i] = $this;
1657                                 }
1658                                 $this->multifeed_objects[$i]->set_feed_url($url);
1659                                 $success |= $this->multifeed_objects[$i]->init();
1660                                 $i++;
1661                         }
1662                         return (bool) $success;
1663                 }
1664                 else
1665                 {
1666                         return false;
1667                 }
1668         }
1669
1670         /**
1671          * Return the error message for the occured error
1672          *
1673          * @access public
1674          * @return string Error message
1675          */
1676         function error()
1677         {
1678                 return $this->error;
1679         }
1680
1681         function get_encoding()
1682         {
1683                 return $this->sanitize->output_encoding;
1684         }
1685
1686         function handle_content_type($mime = 'text/html')
1687         {
1688                 if (!headers_sent())
1689                 {
1690                         $header = "Content-type: $mime;";
1691                         if ($this->get_encoding())
1692                         {
1693                                 $header .= ' charset=' . $this->get_encoding();
1694                         }
1695                         else
1696                         {
1697                                 $header .= ' charset=UTF-8';
1698                         }
1699                         header($header);
1700                 }
1701         }
1702
1703         function get_type()
1704         {
1705                 if (!isset($this->data['type']))
1706                 {
1707                         $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1708                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1709                         {
1710                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1711                         }
1712                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1713                         {
1714                                 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1715                         }
1716                         elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1717                         {
1718                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1719                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1720                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1721                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1722                                 {
1723                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1724                                 }
1725                                 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1726                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1727                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1728                                 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1729                                 {
1730                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1731                                 }
1732                         }
1733                         elseif (isset($this->data['child']['']['rss']))
1734                         {
1735                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1736                                 if (isset($this->data['child']['']['rss'][0]['attribs']['']['version']))
1737                                 {
1738                                         switch (trim($this->data['child']['']['rss'][0]['attribs']['']['version']))
1739                                         {
1740                                                 case '0.91':
1741                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1742                                                         if (isset($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1743                                                         {
1744                                                                 switch (trim($this->data['child']['']['rss'][0]['child']['']['skiphours']['hour'][0]['data']))
1745                                                                 {
1746                                                                         case '0':
1747                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1748                                                                                 break;
1749
1750                                                                         case '24':
1751                                                                                 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1752                                                                                 break;
1753                                                                 }
1754                                                         }
1755                                                         break;
1756
1757                                                 case '0.92':
1758                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1759                                                         break;
1760
1761                                                 case '0.93':
1762                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1763                                                         break;
1764
1765                                                 case '0.94':
1766                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1767                                                         break;
1768
1769                                                 case '2.0':
1770                                                         $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1771                                                         break;
1772                                         }
1773                                 }
1774                         }
1775                         else
1776                         {
1777                                 $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1778                         }
1779                 }
1780                 return $this->data['type'];
1781         }
1782
1783         /**
1784          * Returns the URL for the favicon of the feed's website.
1785          *
1786          * @access public
1787          * @since 1.0
1788          */
1789         function get_favicon()
1790         {
1791                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1792                 {
1793                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1794                 }
1795                 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1796                 {
1797                         $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1798
1799                         if ($this->cache && $this->favicon_handler)
1800                         {
1801                                 $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $favicon), 'spi');
1802
1803                                 if ($cache->load())
1804                                 {
1805                                         return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
1806                                 }
1807                                 else
1808                                 {
1809                                         $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1810
1811                                         if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1812                                         {
1813                                                 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
1814                                                 {
1815                                                         return $this->sanitize($this->favicon_handler . rawurlencode($favicon), SIMPLEPIE_CONSTRUCT_IRI);
1816                                                 }
1817                                                 else
1818                                                 {
1819                                                         trigger_error("$cache->name is not writeable", E_USER_WARNING);
1820                                                         return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1821                                                 }
1822                                         }
1823                                 }
1824                         }
1825                         else
1826                         {
1827                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
1828                         }
1829                 }
1830                 return false;
1831         }
1832
1833         /**
1834          * @todo If we have a perm redirect we should return the new URL
1835          * @todo When we make the above change, let's support <itunes:new-feed-url> as well
1836          * @todo Also, |atom:link|@rel=self
1837          */
1838         function subscribe_url()
1839         {
1840                 if ($this->feed_url !== null)
1841                 {
1842                         return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
1843                 }
1844                 else
1845                 {
1846                         return null;
1847                 }
1848         }
1849
1850         function subscribe_feed()
1851         {
1852                 if ($this->feed_url !== null)
1853                 {
1854                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1855                 }
1856                 else
1857                 {
1858                         return null;
1859                 }
1860         }
1861
1862         function subscribe_outlook()
1863         {
1864                 if ($this->feed_url !== null)
1865                 {
1866                         return 'outlook' . $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
1867                 }
1868                 else
1869                 {
1870                         return null;
1871                 }
1872         }
1873
1874         function subscribe_podcast()
1875         {
1876                 if ($this->feed_url !== null)
1877                 {
1878                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
1879                 }
1880                 else
1881                 {
1882                         return null;
1883                 }
1884         }
1885
1886         function subscribe_itunes()
1887         {
1888                 if ($this->feed_url !== null)
1889                 {
1890                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
1891                 }
1892                 else
1893                 {
1894                         return null;
1895                 }
1896         }
1897
1898         /**
1899          * Creates the subscribe_* methods' return data
1900          *
1901          * @access private
1902          * @param string $feed_url String to prefix to the feed URL
1903          * @param string $site_url String to prefix to the site URL (and
1904          * suffix to the feed URL)
1905          * @return mixed URL if feed exists, false otherwise
1906          */
1907         function subscribe_service($feed_url, $site_url = null)
1908         {
1909                 if ($this->subscribe_url())
1910                 {
1911                         $return = $this->sanitize($feed_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->subscribe_url());
1912                         if ($site_url !== null && $this->get_link() !== null)
1913                         {
1914                                 $return .= $this->sanitize($site_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_link());
1915                         }
1916                         return $return;
1917                 }
1918                 else
1919                 {
1920                         return null;
1921                 }
1922         }
1923
1924         function subscribe_aol()
1925         {
1926                 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
1927         }
1928
1929         function subscribe_bloglines()
1930         {
1931                 return urldecode($this->subscribe_service('http://www.bloglines.com/sub/'));
1932         }
1933
1934         function subscribe_eskobo()
1935         {
1936                 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
1937         }
1938
1939         function subscribe_feedfeeds()
1940         {
1941                 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
1942         }
1943
1944         function subscribe_feedster()
1945         {
1946                 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
1947         }
1948
1949         function subscribe_google()
1950         {
1951                 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
1952         }
1953
1954         function subscribe_gritwire()
1955         {
1956                 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
1957         }
1958
1959         function subscribe_msn()
1960         {
1961                 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
1962         }
1963
1964         function subscribe_netvibes()
1965         {
1966                 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
1967         }
1968
1969         function subscribe_newsburst()
1970         {
1971                 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
1972         }
1973
1974         function subscribe_newsgator()
1975         {
1976                 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
1977         }
1978
1979         function subscribe_odeo()
1980         {
1981                 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
1982         }
1983
1984         function subscribe_podnova()
1985         {
1986                 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
1987         }
1988
1989         function subscribe_rojo()
1990         {
1991                 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
1992         }
1993
1994         function subscribe_yahoo()
1995         {
1996                 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
1997         }
1998
1999         function get_feed_tags($namespace, $tag)
2000         {
2001                 $type = $this->get_type();
2002                 if ($type & SIMPLEPIE_TYPE_ATOM_10)
2003                 {
2004                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2005                         {
2006                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2007                         }
2008                 }
2009                 if ($type & SIMPLEPIE_TYPE_ATOM_03)
2010                 {
2011                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2012                         {
2013                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2014                         }
2015                 }
2016                 if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2017                 {
2018                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2019                         {
2020                                 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2021                         }
2022                 }
2023                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2024                 {
2025                         if (isset($this->data['child']['']['rss'][0]['child'][$namespace][$tag]))
2026                         {
2027                                 return $this->data['child']['']['rss'][0]['child'][$namespace][$tag];
2028                         }
2029                 }
2030                 return null;
2031         }
2032
2033         function get_channel_tags($namespace, $tag)
2034         {
2035                 $type = $this->get_type();
2036                 if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2037                 {
2038                         if ($return = $this->get_feed_tags($namespace, $tag))
2039                         {
2040                                 return $return;
2041                         }
2042                 }
2043                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2044                 {
2045                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2046                         {
2047                                 if (isset($channel[0]['child'][$namespace][$tag]))
2048                                 {
2049                                         return $channel[0]['child'][$namespace][$tag];
2050                                 }
2051                         }
2052                 }
2053                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2054                 {
2055                         if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2056                         {
2057                                 if (isset($channel[0]['child'][$namespace][$tag]))
2058                                 {
2059                                         return $channel[0]['child'][$namespace][$tag];
2060                                 }
2061                         }
2062                 }
2063                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2064                 {
2065                         if ($channel = $this->get_feed_tags('', 'channel'))
2066                         {
2067                                 if (isset($channel[0]['child'][$namespace][$tag]))
2068                                 {
2069                                         return $channel[0]['child'][$namespace][$tag];
2070                                 }
2071                         }
2072                 }
2073                 return null;
2074         }
2075
2076         function get_image_tags($namespace, $tag)
2077         {
2078                 $type = $this->get_type();
2079                 if ($type & SIMPLEPIE_TYPE_RSS_10)
2080                 {
2081                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2082                         {
2083                                 if (isset($image[0]['child'][$namespace][$tag]))
2084                                 {
2085                                         return $image[0]['child'][$namespace][$tag];
2086                                 }
2087                         }
2088                 }
2089                 if ($type & SIMPLEPIE_TYPE_RSS_090)
2090                 {
2091                         if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2092                         {
2093                                 if (isset($image[0]['child'][$namespace][$tag]))
2094                                 {
2095                                         return $image[0]['child'][$namespace][$tag];
2096                                 }
2097                         }
2098                 }
2099                 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2100                 {
2101                         if ($image = $this->get_channel_tags('', 'image'))
2102                         {
2103                                 if (isset($image[0]['child'][$namespace][$tag]))
2104                                 {
2105                                         return $image[0]['child'][$namespace][$tag];
2106                                 }
2107                         }
2108                 }
2109                 return null;
2110         }
2111
2112         function get_base($element = array())
2113         {
2114                 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2115                 {
2116                         return $element['xml_base'];
2117                 }
2118                 elseif ($this->get_link() !== null)
2119                 {
2120                         return $this->get_link();
2121                 }
2122                 elseif (isset($this->data['headers']['content-location']))
2123                 {
2124                         return SimplePie_Misc::absolutize_url($this->data['headers']['content-location'], $this->subscribe_url());
2125                 }
2126                 else
2127                 {
2128                         return $this->subscribe_url();
2129                 }
2130         }
2131
2132         function sanitize($data, $type, $base = '')
2133         {
2134                 return $this->sanitize->sanitize($data, $type, $base);
2135         }
2136
2137         function get_title()
2138         {
2139                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2140                 {
2141                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2142                 }
2143                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2144                 {
2145                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2146                 }
2147                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2148                 {
2149                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2150                 }
2151                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2152                 {
2153                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2154                 }
2155                 elseif ($return = $this->get_channel_tags('', 'title'))
2156                 {
2157                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2158                 }
2159                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2160                 {
2161                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2162                 }
2163                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2164                 {
2165                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2166                 }
2167                 else
2168                 {
2169                         return null;
2170                 }
2171         }
2172
2173         function get_link($key = 0, $rel = 'alternate')
2174         {
2175                 $links = $this->get_links($rel);
2176                 if (isset($links[$key]))
2177                 {
2178                         return $links[$key];
2179                 }
2180                 else
2181                 {
2182                         return null;
2183                 }
2184         }
2185
2186         /**
2187          * Added for parity between the parent-level and the item/entry-level.
2188          */
2189         function get_permalink()
2190         {
2191                 return $this->get_link(0);
2192         }
2193
2194         function get_links($rel = 'alternate')
2195         {
2196                 if (!isset($this->data['links']))
2197                 {
2198                         $this->data['links'] = array();
2199                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2200                         {
2201                                 foreach ($links as $link)
2202                                 {
2203                                         if (isset($link['attribs']['']['href']))
2204                                         {
2205                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2206                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2207                                         }
2208                                 }
2209                         }
2210                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2211                         {
2212                                 foreach ($links as $link)
2213                                 {
2214                                         if (isset($link['attribs']['']['href']))
2215                                         {
2216                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2217                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2218
2219                                         }
2220                                 }
2221                         }
2222                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2223                         {
2224                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2225                         }
2226                         if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2227                         {
2228                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2229                         }
2230                         if ($links = $this->get_channel_tags('', 'link'))
2231                         {
2232                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2233                         }
2234
2235                         $keys = array_keys($this->data['links']);
2236                         foreach ($keys as $key)
2237                         {
2238                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
2239                                 {
2240                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2241                                         {
2242                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2243                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2244                                         }
2245                                         else
2246                                         {
2247                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2248                                         }
2249                                 }
2250                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2251                                 {
2252                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2253                                 }
2254                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2255                         }
2256                 }
2257
2258                 if (isset($this->data['links'][$rel]))
2259                 {
2260                         return $this->data['links'][$rel];
2261                 }
2262                 else
2263                 {
2264                         return null;
2265                 }
2266         }
2267
2268         function get_description()
2269         {
2270                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2271                 {
2272                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2273                 }
2274                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2275                 {
2276                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2277                 }
2278                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2279                 {
2280                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2281                 }
2282                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2283                 {
2284                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2285                 }
2286                 elseif ($return = $this->get_channel_tags('', 'description'))
2287                 {
2288                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2289                 }
2290                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2291                 {
2292                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2293                 }
2294                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2295                 {
2296                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2297                 }
2298                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2299                 {
2300                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2301                 }
2302                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2303                 {
2304                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2305                 }
2306                 else
2307                 {
2308                         return null;
2309                 }
2310         }
2311
2312         function get_copyright()
2313         {
2314                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2315                 {
2316                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2317                 }
2318                 elseif ($return = $this->get_channel_tags('', 'copyright'))
2319                 {
2320                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2321                 }
2322                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2323                 {
2324                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2325                 }
2326                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2327                 {
2328                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2329                 }
2330                 else
2331                 {
2332                         return null;
2333                 }
2334         }
2335
2336         function get_language()
2337         {
2338                 if ($return = $this->get_channel_tags('', 'language'))
2339                 {
2340                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2341                 }
2342                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2343                 {
2344                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2345                 }
2346                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2347                 {
2348                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2349                 }
2350                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2351                 {
2352                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2353                 }
2354                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2355                 {
2356                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2357                 }
2358                 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2359                 {
2360                         return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2361                 }
2362                 elseif (isset($this->data['headers']['content-language']))
2363                 {
2364                         return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2365                 }
2366                 else
2367                 {
2368                         return null;
2369                 }
2370         }
2371
2372         function get_latitude()
2373         {
2374                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2375                 {
2376                         return (float) $return[0]['data'];
2377                 }
2378                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2379                 {
2380                         return (float) $match[1];
2381                 }
2382                 else
2383                 {
2384                         return null;
2385                 }
2386         }
2387
2388         function get_longitude()
2389         {
2390                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2391                 {
2392                         return (float) $return[0]['data'];
2393                 }
2394                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2395                 {
2396                         return (float) $return[0]['data'];
2397                 }
2398                 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
2399                 {
2400                         return (float) $match[2];
2401                 }
2402                 else
2403                 {
2404                         return null;
2405                 }
2406         }
2407
2408         function get_image_title()
2409         {
2410                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2411                 {
2412                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2413                 }
2414                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2415                 {
2416                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2417                 }
2418                 elseif ($return = $this->get_image_tags('', 'title'))
2419                 {
2420                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2421                 }
2422                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2423                 {
2424                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2425                 }
2426                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2427                 {
2428                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2429                 }
2430                 else
2431                 {
2432                         return null;
2433                 }
2434         }
2435
2436         function get_image_url()
2437         {
2438                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2439                 {
2440                         return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2441                 }
2442                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2443                 {
2444                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2445                 }
2446                 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2447                 {
2448                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2449                 }
2450                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2451                 {
2452                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2453                 }
2454                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2455                 {
2456                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2457                 }
2458                 elseif ($return = $this->get_image_tags('', 'url'))
2459                 {
2460                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2461                 }
2462                 else
2463                 {
2464                         return null;
2465                 }
2466         }
2467
2468         function get_image_link()
2469         {
2470                 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2471                 {
2472                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2473                 }
2474                 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2475                 {
2476                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2477                 }
2478                 elseif ($return = $this->get_image_tags('', 'link'))
2479                 {
2480                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2481                 }
2482                 else
2483                 {
2484                         return null;
2485                 }
2486         }
2487
2488         function get_image_width()
2489         {
2490                 if ($return = $this->get_image_tags('', 'width'))
2491                 {
2492                         return round($return[0]['data']);
2493                 }
2494                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2495                 {
2496                         return 88.0;
2497                 }
2498                 else
2499                 {
2500                         return null;
2501                 }
2502         }
2503
2504         function get_image_height()
2505         {
2506                 if ($return = $this->get_image_tags('', 'height'))
2507                 {
2508                         return round($return[0]['data']);
2509                 }
2510                 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags('', 'url'))
2511                 {
2512                         return 31.0;
2513                 }
2514                 else
2515                 {
2516                         return null;
2517                 }
2518         }
2519
2520         function get_item_quantity($max = 0)
2521         {
2522                 $qty = count($this->get_items());
2523                 if ($max == 0)
2524                 {
2525                         return $qty;
2526                 }
2527                 else
2528                 {
2529                         return ($qty > $max) ? $max : $qty;
2530                 }
2531         }
2532
2533         function get_item($key = 0)
2534         {
2535                 $items = $this->get_items();
2536                 if (isset($items[$key]))
2537                 {
2538                         return $items[$key];
2539                 }
2540                 else
2541                 {
2542                         return null;
2543                 }
2544         }
2545
2546         function get_items($start = 0, $end = 0)
2547         {
2548                 if (!empty($this->multifeed_objects))
2549                 {
2550                         return SimplePie::merge_items($this->multifeed_objects, $start, $end);
2551                 }
2552                 elseif (!isset($this->data['items']))
2553                 {
2554                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2555                         {
2556                                 $keys = array_keys($items);
2557                                 foreach ($keys as $key)
2558                                 {
2559                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2560                                 }
2561                         }
2562                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2563                         {
2564                                 $keys = array_keys($items);
2565                                 foreach ($keys as $key)
2566                                 {
2567                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2568                                 }
2569                         }
2570                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
2571                         {
2572                                 $keys = array_keys($items);
2573                                 foreach ($keys as $key)
2574                                 {
2575                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2576                                 }
2577                         }
2578                         if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
2579                         {
2580                                 $keys = array_keys($items);
2581                                 foreach ($keys as $key)
2582                                 {
2583                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2584                                 }
2585                         }
2586                         if ($items = $this->get_channel_tags('', 'item'))
2587                         {
2588                                 $keys = array_keys($items);
2589                                 foreach ($keys as $key)
2590                                 {
2591                                         $this->data['items'][] =& new $this->item_class($this, $items[$key]);
2592                                 }
2593                         }
2594                 }
2595
2596                 if (!empty($this->data['items']))
2597                 {
2598                         // If we want to order it by date, check if all items have a date, and then sort it
2599                         if ($this->order_by_date)
2600                         {
2601                                 if (!isset($this->data['ordered_items']))
2602                                 {
2603                                         $do_sort = true;
2604                                         foreach ($this->data['items'] as $item)
2605                                         {
2606                                                 if (!$item->get_date('U'))
2607                                                 {
2608                                                         $do_sort = false;
2609                                                         break;
2610                                                 }
2611                                         }
2612                                         $item = null;
2613                                         $this->data['ordered_items'] = $this->data['items'];
2614                                         if ($do_sort)
2615                                         {
2616                                                 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
2617                                         }
2618                                 }
2619                                 $items = $this->data['ordered_items'];
2620                         }
2621                         else
2622                         {
2623                                 $items = $this->data['items'];
2624                         }
2625
2626                         // Slice the data as desired
2627                         if ($end == 0)
2628                         {
2629                                 return array_slice($items, $start);
2630                         }
2631                         else
2632                         {
2633                                 return array_slice($items, $start, $end);
2634                         }
2635                 }
2636                 else
2637                 {
2638                         return array();
2639                 }
2640         }
2641
2642         function sort_items($a, $b)
2643         {
2644                 return $a->get_date('U') <= $b->get_date('U');
2645         }
2646
2647         function merge_items($urls, $start = 0, $end = 0)
2648         {
2649                 if (is_array($urls) && sizeof($urls) > 0)
2650                 {
2651                         $items = array();
2652                         foreach ($urls as $arg)
2653                         {
2654                                 if (SimplePie_Misc::is_a($arg, 'SimplePie'))
2655                                 {
2656                                         $items = array_merge($items, $arg->get_items());
2657                                 }
2658                                 else
2659                                 {
2660                                         trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
2661                                 }
2662                         }
2663
2664                         $do_sort = true;
2665                         foreach ($items as $item)
2666                         {
2667                                 if (!$item->get_date('U'))
2668                                 {
2669                                         $do_sort = false;
2670                                         break;
2671                                 }
2672                         }
2673                         $item = null;
2674                         if ($do_sort)
2675                         {
2676                                 usort($items, array('SimplePie', 'sort_items'));
2677                         }
2678
2679                         if ($end == 0)
2680                         {
2681                                 return array_slice($items, $start);
2682                         }
2683                         else
2684                         {
2685                                 return array_slice($items, $start, $end);
2686                         }
2687                 }
2688                 else
2689                 {
2690                         trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
2691                         return array();
2692                 }
2693         }
2694 }
2695
2696 class SimplePie_Item
2697 {
2698         var $feed;
2699         var $data = array();
2700
2701         function SimplePie_Item($feed, $data)
2702         {
2703                 $this->feed = $feed;
2704                 $this->data = $data;
2705         }
2706
2707         function __toString()
2708         {
2709                 return md5(serialize($this->data));
2710         }
2711
2712         function get_item_tags($namespace, $tag)
2713         {
2714                 if (isset($this->data['child'][$namespace][$tag]))
2715                 {
2716                         return $this->data['child'][$namespace][$tag];
2717                 }
2718                 else
2719                 {
2720                         return null;
2721                 }
2722         }
2723
2724         function get_base($element = array())
2725         {
2726                 return $this->feed->get_base($element);
2727         }
2728
2729         function sanitize($data, $type, $base = '')
2730         {
2731                 return $this->feed->sanitize($data, $type, $base);
2732         }
2733
2734         function get_feed()
2735         {
2736                 return $this->feed;
2737         }
2738
2739         function get_id($hash = false)
2740         {
2741                 if ($hash)
2742                 {
2743                         return $this->__toString();
2744                 }
2745                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
2746                 {
2747                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2748                 }
2749                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
2750                 {
2751                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2752                 }
2753                 elseif ($return = $this->get_item_tags('', 'guid'))
2754                 {
2755                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2756                 }
2757                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
2758                 {
2759                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2760                 }
2761                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
2762                 {
2763                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2764                 }
2765                 elseif (($return = $this->get_permalink()) !== null)
2766                 {
2767                         return $return;
2768                 }
2769                 elseif (($return = $this->get_title()) !== null)
2770                 {
2771                         return $return;
2772                 }
2773                 else
2774                 {
2775                         return $this->__toString();
2776                 }
2777         }
2778
2779         function get_title()
2780         {
2781                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2782                 {
2783                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2784                 }
2785                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2786                 {
2787                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2788                 }
2789                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2790                 {
2791                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2792                 }
2793                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2794                 {
2795                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2796                 }
2797                 elseif ($return = $this->get_item_tags('', 'title'))
2798                 {
2799                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2800                 }
2801                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2802                 {
2803                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2804                 }
2805                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2806                 {
2807                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2808                 }
2809                 else
2810                 {
2811                         return null;
2812                 }
2813         }
2814
2815         function get_description($description_only = false)
2816         {
2817                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
2818                 {
2819                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2820                 }
2821                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
2822                 {
2823                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2824                 }
2825                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2826                 {
2827                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2828                 }
2829                 elseif ($return = $this->get_item_tags('', 'description'))
2830                 {
2831                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2832                 }
2833                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2834                 {
2835                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2836                 }
2837                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2838                 {
2839                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2840                 }
2841                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2842                 {
2843                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2844                 }
2845                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2846                 {
2847                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2848                 }
2849                 elseif (!$description_only)
2850                 {
2851                         return $this->get_content(true);
2852                 }
2853                 else
2854                 {
2855                         return null;
2856                 }
2857         }
2858
2859         function get_content($content_only = false)
2860         {
2861                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
2862                 {
2863                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2864                 }
2865                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
2866                 {
2867                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2868                 }
2869                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
2870                 {
2871                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2872                 }
2873                 elseif (!$content_only)
2874                 {
2875                         return $this->get_description(true);
2876                 }
2877                 else
2878                 {
2879                         return null;
2880                 }
2881         }
2882
2883         function get_category($key = 0)
2884         {
2885                 $categories = $this->get_categories();
2886                 if (isset($categories[$key]))
2887                 {
2888                         return $categories[$key];
2889                 }
2890                 else
2891                 {
2892                         return null;
2893                 }
2894         }
2895
2896         function get_categories()
2897         {
2898                 $categories = array();
2899
2900                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2901                 {
2902                         $term = null;
2903                         $scheme = null;
2904                         $label = null;
2905                         if (isset($category['attribs']['']['term']))
2906                         {
2907                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2908                         }
2909                         if (isset($category['attribs']['']['scheme']))
2910                         {
2911                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2912                         }
2913                         if (isset($category['attribs']['']['label']))
2914                         {
2915                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2916                         }
2917                         $categories[] =& new $this->feed->category_class($term, $scheme, $label);
2918                 }
2919                 foreach ((array) $this->get_item_tags('', 'category') as $category)
2920                 {
2921                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2922                 }
2923                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2924                 {
2925                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2926                 }
2927                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2928                 {
2929                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2930                 }
2931
2932                 if (!empty($categories))
2933                 {
2934                         return SimplePie_Misc::array_unique($categories);
2935                 }
2936                 else
2937                 {
2938                         return null;
2939                 }
2940         }
2941
2942         function get_author($key = 0)
2943         {
2944                 $authors = $this->get_authors();
2945                 if (isset($authors[$key]))
2946                 {
2947                         return $authors[$key];
2948                 }
2949                 else
2950                 {
2951                         return null;
2952                 }
2953         }
2954
2955         /**
2956          * @todo Atom inheritance (item author, source author, feed author)
2957          */
2958         function get_authors()
2959         {
2960                 $authors = array();
2961                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2962                 {
2963                         $name = null;
2964                         $uri = null;
2965                         $email = null;
2966                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2967                         {
2968                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2969                         }
2970                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2971                         {
2972                                 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
2973                         }
2974                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2975                         {
2976                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2977                         }
2978                         if ($name !== null || $email !== null || $uri !== null)
2979                         {
2980                                 $authors[] =& new $this->feed->author_class($name, $uri, $email);
2981                         }
2982                 }
2983                 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2984                 {
2985                         $name = null;
2986                         $url = null;
2987                         $email = null;
2988                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2989                         {
2990                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2991                         }
2992                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2993                         {
2994                                 $uri = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
2995                         }
2996                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2997                         {
2998                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2999                         }
3000                         if ($name !== null || $email !== null || $uri !== null)
3001                         {
3002                                 $authors[] =& new $this->feed->author_class($name, $url, $email);
3003                         }
3004                 }
3005                 if ($author = $this->get_item_tags('', 'author'))
3006                 {
3007                         $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3008                 }
3009                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3010                 {
3011                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3012                 }
3013                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3014                 {
3015                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3016                 }
3017                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3018                 {
3019                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3020                 }
3021
3022                 if (!empty($authors))
3023                 {
3024                         return SimplePie_Misc::array_unique($authors);
3025                 }
3026                 else
3027                 {
3028                         return null;
3029                 }
3030         }
3031
3032         function get_date($date_format = 'j F Y, g:i a')
3033         {
3034                 if (!isset($this->data['date']))
3035                 {
3036                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3037                         {
3038                                 $this->data['date']['raw'] = $return[0]['data'];
3039                         }
3040                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3041                         {
3042                                 $this->data['date']['raw'] = $return[0]['data'];
3043                         }
3044                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3045                         {
3046                                 $this->data['date']['raw'] = $return[0]['data'];
3047                         }
3048                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3049                         {
3050                                 $this->data['date']['raw'] = $return[0]['data'];
3051                         }
3052                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3053                         {
3054                                 $this->data['date']['raw'] = $return[0]['data'];
3055                         }
3056                         elseif ($return = $this->get_item_tags('', 'pubDate'))
3057                         {
3058                                 $this->data['date']['raw'] = $return[0]['data'];
3059                         }
3060                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3061                         {
3062                                 $this->data['date']['raw'] = $return[0]['data'];
3063                         }
3064                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3065                         {
3066                                 $this->data['date']['raw'] = $return[0]['data'];
3067                         }
3068
3069                         if (!empty($this->data['date']['raw']))
3070                         {
3071                                 $this->data['date']['parsed'] = SimplePie_Misc::parse_date($this->data['date']['raw']);
3072                         }
3073                         else
3074                         {
3075                                 $this->data['date'] = null;
3076                         }
3077                 }
3078                 if ($this->data['date'])
3079                 {
3080                         $date_format = (string) $date_format;
3081                         switch ($date_format)
3082                         {
3083                                 case '':
3084                                         return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3085
3086                                 case 'U':
3087                                         return $this->data['date']['parsed'];
3088
3089                                 default:
3090                                         return date($date_format, $this->data['date']['parsed']);
3091                         }
3092                 }
3093                 else
3094                 {
3095                         return null;
3096                 }
3097         }
3098
3099         function get_local_date($date_format = '%c')
3100         {
3101                 if (!$date_format)
3102                 {
3103                         return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3104                 }
3105                 elseif (($date = $this->get_date('U')) !== null)
3106                 {
3107                         return strftime($date_format, $date);
3108                 }
3109                 else
3110                 {
3111                         return null;
3112                 }
3113         }
3114
3115         function get_permalink()
3116         {
3117                 $link = $this->get_link();
3118                 $enclosure = $this->get_enclosure(0);
3119                 if ($link !== null)
3120                 {
3121                         return $link;
3122                 }
3123                 elseif ($enclosure !== null)
3124                 {
3125                         return $enclosure->get_link();
3126                 }
3127                 else
3128                 {
3129                         return null;
3130                 }
3131         }
3132
3133         function get_link($key = 0, $rel = 'alternate')
3134         {
3135                 $links = $this->get_links($rel);
3136                 if ($links[$key] !== null)
3137                 {
3138                         return $links[$key];
3139                 }
3140                 else
3141                 {
3142                         return null;
3143                 }
3144         }
3145
3146         function get_links($rel = 'alternate')
3147         {
3148                 if (!isset($this->data['links']))
3149                 {
3150                         $this->data['links'] = array();
3151                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3152                         {
3153                                 if (isset($link['attribs']['']['href']))
3154                                 {
3155                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3156                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3157
3158                                 }
3159                         }
3160                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3161                         {
3162                                 if (isset($link['attribs']['']['href']))
3163                                 {
3164                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3165                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3166                                 }
3167                         }
3168                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3169                         {
3170                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3171                         }
3172                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3173                         {
3174                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3175                         }
3176                         if ($links = $this->get_item_tags('', 'link'))
3177                         {
3178                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3179                         }
3180                         if ($links = $this->get_item_tags('', 'guid'))
3181                         {
3182                                 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) == 'true')
3183                                 {
3184                                         $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3185                                 }
3186                         }
3187
3188                         $keys = array_keys($this->data['links']);
3189                         foreach ($keys as $key)
3190                         {
3191                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
3192                                 {
3193                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3194                                         {
3195                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3196                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3197                                         }
3198                                         else
3199                                         {
3200                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3201                                         }
3202                                 }
3203                                 elseif (substr($key, 0, 41) == SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3204                                 {
3205                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3206                                 }
3207                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3208                         }
3209                 }
3210                 if (isset($this->data['links'][$rel]))
3211                 {
3212                         return $this->data['links'][$rel];
3213                 }
3214                 else
3215                 {
3216                         return null;
3217                 }
3218         }
3219
3220         /**
3221          * @todo Add ability to prefer one type of content over another (in a media group).
3222          */
3223         function get_enclosure($key = 0, $prefer = null)
3224         {
3225                 $enclosures = $this->get_enclosures();
3226                 if (isset($enclosures[$key]))
3227                 {
3228                         return $enclosures[$key];
3229                 }
3230                 else
3231                 {
3232                         return null;
3233                 }
3234         }
3235
3236         /**
3237          * Grabs all available enclosures (podcasts, etc.)
3238          *
3239          * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3240          *
3241          * At this point, we're pretty much assuming that all enclosures for an item are the same content.  Anything else is too complicated to properly support.
3242          *
3243          * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3244          * @todo Add support for itunes: tags.  These should be relatively simple compared to media:.
3245          * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).
3246          */
3247         function get_enclosures()
3248         {
3249                 if (!isset($this->data['enclosures']))
3250                 {
3251                         $this->data['enclosures'] = array();
3252
3253                         // Elements
3254                         $captions_parent = null;
3255                         $categories_parent = null;
3256                         $copyrights_parent = null;
3257                         $credits_parent = null;
3258                         $description_parent = null;
3259                         $duration_parent = null;
3260                         $hashes_parent = null;
3261                         $keywords_parent = null;
3262                         $player_parent = null;
3263                         $ratings_parent = null;
3264                         $restrictions_parent = null;
3265                         $thumbnails_parent = null;
3266                         $title_parent = null;
3267
3268                         // Let's do the channel and item-level ones first, and just re-use them if we need to.
3269                         $parent = $this->get_feed();
3270
3271                         // CAPTIONS
3272                         if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3273                         {
3274                                 foreach ($captions as $caption)
3275                                 {
3276                                         $caption_type = null;
3277                                         $caption_lang = null;
3278                                         $caption_startTime = null;
3279                                         $caption_endTime = null;
3280                                         $caption_text = null;
3281                                         if (isset($caption['attribs']['']['type']))
3282                                         {
3283                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3284                                         }
3285                                         if (isset($caption['attribs']['']['lang']))
3286                                         {
3287                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3288                                         }
3289                                         if (isset($caption['attribs']['']['start']))
3290                                         {
3291                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3292                                         }
3293                                         if (isset($caption['attribs']['']['end']))
3294                                         {
3295                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3296                                         }
3297                                         if (isset($caption['data']))
3298                                         {
3299                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3300                                         }
3301                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3302                                 }
3303                         }
3304                         elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3305                         {
3306                                 foreach ($captions as $caption)
3307                                 {
3308                                         $caption_type = null;
3309                                         $caption_lang = null;
3310                                         $caption_startTime = null;
3311                                         $caption_endTime = null;
3312                                         $caption_text = null;
3313                                         if (isset($caption['attribs']['']['type']))
3314                                         {
3315                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3316                                         }
3317                                         if (isset($caption['attribs']['']['lang']))
3318                                         {
3319                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3320                                         }
3321                                         if (isset($caption['attribs']['']['start']))
3322                                         {
3323                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3324                                         }
3325                                         if (isset($caption['attribs']['']['end']))
3326                                         {
3327                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3328                                         }
3329                                         if (isset($caption['data']))
3330                                         {
3331                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3332                                         }
3333                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3334                                 }
3335                         }
3336                         if (is_array($captions_parent))
3337                         {
3338                                 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3339                         }
3340
3341                         // CATEGORIES
3342                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3343                         {
3344                                 $term = null;
3345                                 $scheme = null;
3346                                 $label = null;
3347                                 if (isset($category['data']))
3348                                 {
3349                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3350                                 }
3351                                 if (isset($category['attribs']['']['scheme']))
3352                                 {
3353                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3354                                 }
3355                                 else
3356                                 {
3357                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
3358                                 }
3359                                 if (isset($category['attribs']['']['label']))
3360                                 {
3361                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3362                                 }
3363                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3364                         }
3365                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3366                         {
3367                                 $term = null;
3368                                 $scheme = null;
3369                                 $label = null;
3370                                 if (isset($category['data']))
3371                                 {
3372                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3373                                 }
3374                                 if (isset($category['attribs']['']['scheme']))
3375                                 {
3376                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3377                                 }
3378                                 else
3379                                 {
3380                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
3381                                 }
3382                                 if (isset($category['attribs']['']['label']))
3383                                 {
3384                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3385                                 }
3386                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3387                         }
3388                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3389                         {
3390                                 $term = null;
3391                                 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3392                                 $label = null;
3393                                 if (isset($category['attribs']['']['text']))
3394                                 {
3395                                         $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3396                                 }
3397                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3398
3399                                 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3400                                 {
3401                                         foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3402                                         {
3403                                                 if (isset($subcategory['attribs']['']['text']))
3404                                                 {
3405                                                         $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3406                                                 }
3407                                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
3408                                         }
3409                                 }
3410                         }
3411                         if (is_array($categories_parent))
3412                         {
3413                                 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3414                         }
3415
3416                         // COPYRIGHT
3417                         if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3418                         {
3419                                 $copyright_url = null;
3420                                 $copyright_label = null;
3421                                 if (isset($copyright[0]['attribs']['']['url']))
3422                                 {
3423                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3424                                 }
3425                                 if (isset($copyright[0]['data']))
3426                                 {
3427                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3428                                 }
3429                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3430                         }
3431                         elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3432                         {
3433                                 $copyright_url = null;
3434                                 $copyright_label = null;
3435                                 if (isset($copyright[0]['attribs']['']['url']))
3436                                 {
3437                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3438                                 }
3439                                 if (isset($copyright[0]['data']))
3440                                 {
3441                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3442                                 }
3443                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
3444                         }
3445
3446                         // CREDITS
3447                         if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3448                         {
3449                                 foreach ($credits as $credit)
3450                                 {
3451                                         $credit_role = null;
3452                                         $credit_scheme = null;
3453                                         $credit_name = null;
3454                                         if (isset($credit['attribs']['']['role']))
3455                                         {
3456                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3457                                         }
3458                                         if (isset($credit['attribs']['']['scheme']))
3459                                         {
3460                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3461                                         }
3462                                         else
3463                                         {
3464                                                 $credit_scheme = 'urn:ebu';
3465                                         }
3466                                         if (isset($credit['data']))
3467                                         {
3468                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3469                                         }
3470                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3471                                 }
3472                         }
3473                         elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
3474                         {
3475                                 foreach ($credits as $credit)
3476                                 {
3477                                         $credit_role = null;
3478                                         $credit_scheme = null;
3479                                         $credit_name = null;
3480                                         if (isset($credit['attribs']['']['role']))
3481                                         {
3482                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
3483                                         }
3484                                         if (isset($credit['attribs']['']['scheme']))
3485                                         {
3486                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3487                                         }
3488                                         else
3489                                         {
3490                                                 $credit_scheme = 'urn:ebu';
3491                                         }
3492                                         if (isset($credit['data']))
3493                                         {
3494                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3495                                         }
3496                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
3497                                 }
3498                         }
3499                         if (is_array($credits_parent))
3500                         {
3501                                 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
3502                         }
3503
3504                         // DESCRIPTION
3505                         if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3506                         {
3507                                 if (isset($description_parent[0]['data']))
3508                                 {
3509                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3510                                 }
3511                         }
3512                         elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
3513                         {
3514                                 if (isset($description_parent[0]['data']))
3515                                 {
3516                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3517                                 }
3518                         }
3519
3520                         // DURATION
3521                         if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
3522                         {
3523                                 $seconds = null;
3524                                 $minutes = null;
3525                                 $hours = null;
3526                                 if (isset($duration_parent[0]['data']))
3527                                 {
3528                                         $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3529                                         if (sizeof($temp) > 0)
3530                                         {
3531                                                 (int) $seconds = array_pop($temp);
3532                                         }
3533                                         if (sizeof($temp) > 0)
3534                                         {
3535                                                 (int) $minutes = array_pop($temp);
3536                                                 $seconds += $minutes * 60;
3537                                         }
3538                                         if (sizeof($temp) > 0)
3539                                         {
3540                                                 (int) $hours = array_pop($temp);
3541                                                 $seconds += $hours * 3600;
3542                                         }
3543                                         unset($temp);
3544                                         $duration_parent = $seconds;
3545                                 }
3546                         }
3547
3548                         // HASHES
3549                         if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
3550                         {
3551                                 foreach ($hashes_iterator as $hash)
3552                                 {
3553                                         $value = null;
3554                                         $algo = null;
3555                                         if (isset($hash['data']))
3556                                         {
3557                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3558                                         }
3559                                         if (isset($hash['attribs']['']['algo']))
3560                                         {
3561                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
3562                                         }
3563                                         else
3564                                         {
3565                                                 $algo = 'md5';
3566                                         }
3567                                         $hashes_parent[] = $algo.':'.$value;
3568                                 }
3569                         }
3570                         elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
3571                         {
3572                                 foreach ($hashes_iterator as $hash)
3573                                 {
3574                                         $value = null;
3575                                         $algo = null;
3576                                         if (isset($hash['data']))
3577                                         {
3578                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3579                                         }
3580                                         if (isset($hash['attribs']['']['algo']))
3581                                         {
3582                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
3583                                         }
3584                                         else
3585                                         {
3586                                                 $algo = 'md5';
3587                                         }
3588                                         $hashes_parent[] = $algo.':'.$value;
3589                                 }
3590                         }
3591                         if (is_array($hashes_parent))
3592                         {
3593                                 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
3594                         }
3595
3596                         // KEYWORDS
3597                         if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
3598                         {
3599                                 if (isset($keywords[0]['data']))
3600                                 {
3601                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3602                                         foreach ($temp as $word)
3603                                         {
3604                                                 $keywords_parent[] = trim($word);
3605                                         }
3606                                 }
3607                                 unset($temp);
3608                         }
3609                         elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
3610                         {
3611                                 if (isset($keywords[0]['data']))
3612                                 {
3613                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3614                                         foreach ($temp as $word)
3615                                         {
3616                                                 $keywords_parent[] = trim($word);
3617                                         }
3618                                 }
3619                                 unset($temp);
3620                         }
3621                         elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
3622                         {
3623                                 if (isset($keywords[0]['data']))
3624                                 {
3625                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3626                                         foreach ($temp as $word)
3627                                         {
3628                                                 $keywords_parent[] = trim($word);
3629                                         }
3630                                 }
3631                                 unset($temp);
3632                         }
3633                         elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
3634                         {
3635                                 if (isset($keywords[0]['data']))
3636                                 {
3637                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3638                                         foreach ($temp as $word)
3639                                         {
3640                                                 $keywords_parent[] = trim($word);
3641                                         }
3642                                 }
3643                                 unset($temp);
3644                         }
3645                         if (is_array($keywords_parent))
3646                         {
3647                                 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
3648                         }
3649
3650                         // PLAYER
3651                         if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
3652                         {
3653                                 if (isset($player_parent[0]['attribs']['']['url']))
3654                                 {
3655                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3656                                 }
3657                         }
3658                         elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
3659                         {
3660                                 if (isset($player_parent[0]['attribs']['']['url']))
3661                                 {
3662                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3663                                 }
3664                         }
3665
3666                         // RATINGS
3667                         if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
3668                         {
3669                                 foreach ($ratings as $rating)
3670                                 {
3671                                         $rating_scheme = null;
3672                                         $rating_value = null;
3673                                         if (isset($rating['attribs']['']['scheme']))
3674                                         {
3675                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3676                                         }
3677                                         else
3678                                         {
3679                                                 $rating_scheme = 'urn:simple';
3680                                         }
3681                                         if (isset($rating['data']))
3682                                         {
3683                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3684                                         }
3685                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3686                                 }
3687                         }
3688                         elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
3689                         {
3690                                 foreach ($ratings as $rating)
3691                                 {
3692                                         $rating_scheme = 'urn:itunes';
3693                                         $rating_value = null;
3694                                         if (isset($rating['data']))
3695                                         {
3696                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3697                                         }
3698                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3699                                 }
3700                         }
3701                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
3702                         {
3703                                 foreach ($ratings as $rating)
3704                                 {
3705                                         $rating_scheme = null;
3706                                         $rating_value = null;
3707                                         if (isset($rating['attribs']['']['scheme']))
3708                                         {
3709                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3710                                         }
3711                                         else
3712                                         {
3713                                                 $rating_scheme = 'urn:simple';
3714                                         }
3715                                         if (isset($rating['data']))
3716                                         {
3717                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3718                                         }
3719                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3720                                 }
3721                         }
3722                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
3723                         {
3724                                 foreach ($ratings as $rating)
3725                                 {
3726                                         $rating_scheme = 'urn:itunes';
3727                                         $rating_value = null;
3728                                         if (isset($rating['data']))
3729                                         {
3730                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3731                                         }
3732                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
3733                                 }
3734                         }
3735                         if (is_array($ratings_parent))
3736                         {
3737                                 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
3738                         }
3739
3740                         // RESTRICTIONS
3741                         if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
3742                         {
3743                                 foreach ($restrictions as $restriction)
3744                                 {
3745                                         $restriction_relationship = null;
3746                                         $restriction_type = null;
3747                                         $restriction_value = null;
3748                                         if (isset($restriction['attribs']['']['relationship']))
3749                                         {
3750                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
3751                                         }
3752                                         if (isset($restriction['attribs']['']['type']))
3753                                         {
3754                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3755                                         }
3756                                         if (isset($restriction['data']))
3757                                         {
3758                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3759                                         }
3760                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3761                                 }
3762                         }
3763                         elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
3764                         {
3765                                 foreach ($restrictions as $restriction)
3766                                 {
3767                                         $restriction_relationship = 'allow';
3768                                         $restriction_type = null;
3769                                         $restriction_value = 'itunes';
3770                                         if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
3771                                         {
3772                                                 $restriction_relationship = 'deny';
3773                                         }
3774                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3775                                 }
3776                         }
3777                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
3778                         {
3779                                 foreach ($restrictions as $restriction)
3780                                 {
3781                                         $restriction_relationship = null;
3782                                         $restriction_type = null;
3783                                         $restriction_value = null;
3784                                         if (isset($restriction['attribs']['']['relationship']))
3785                                         {
3786                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
3787                                         }
3788                                         if (isset($restriction['attribs']['']['type']))
3789                                         {
3790                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3791                                         }
3792                                         if (isset($restriction['data']))
3793                                         {
3794                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3795                                         }
3796                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3797                                 }
3798                         }
3799                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
3800                         {
3801                                 foreach ($restrictions as $restriction)
3802                                 {
3803                                         $restriction_relationship = 'allow';
3804                                         $restriction_type = null;
3805                                         $restriction_value = 'itunes';
3806                                         if (isset($restriction['data']) && strtolower($restriction['data']) == 'yes')
3807                                         {
3808                                                 $restriction_relationship = 'deny';
3809                                         }
3810                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
3811                                 }
3812                         }
3813                         if (is_array($restrictions_parent))
3814                         {
3815                                 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
3816                         }
3817
3818                         // THUMBNAILS
3819                         if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
3820                         {
3821                                 foreach ($thumbnails as $thumbnail)
3822                                 {
3823                                         if (isset($thumbnail['attribs']['']['url']))
3824                                         {
3825                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3826                                         }
3827                                 }
3828                         }
3829                         elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
3830                         {
3831                                 foreach ($thumbnails as $thumbnail)
3832                                 {
3833                                         if (isset($thumbnail['attribs']['']['url']))
3834                                         {
3835                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3836                                         }
3837                                 }
3838                         }
3839
3840                         // TITLES
3841                         if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
3842                         {
3843                                 if (isset($title_parent[0]['data']))
3844                                 {
3845                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3846                                 }
3847                         }
3848                         elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
3849                         {
3850                                 if (isset($title_parent[0]['data']))
3851                                 {
3852                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3853                                 }
3854                         }
3855
3856                         // Clear the memory
3857                         unset($parent);
3858
3859                         // If we have media:group tags, loop through them.
3860                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
3861                         {
3862                                 // If we have media:content tags, loop through them.
3863                                 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
3864                                 {
3865                                         if (isset($content['attribs']['']['url']))
3866                                         {
3867                                                 // Attributes
3868                                                 $bitrate = null;
3869                                                 $channels = null;
3870                                                 $duration = null;
3871                                                 $expression = null;
3872                                                 $framerate = null;
3873                                                 $height = null;
3874                                                 $javascript = null;
3875                                                 $lang = null;
3876                                                 $length = null;
3877                                                 $medium = null;
3878                                                 $samplingrate = null;
3879                                                 $type = null;
3880                                                 $url = null;
3881                                                 $width = null;
3882
3883                                                 // Elements
3884                                                 $captions = null;
3885                                                 $categories = null;
3886                                                 $copyrights = null;
3887                                                 $credits = null;
3888                                                 $description = null;
3889                                                 $hashes = null;
3890                                                 $keywords = null;
3891                                                 $player = null;
3892                                                 $ratings = null;
3893                                                 $restrictions = null;
3894                                                 $thumbnails = null;
3895                                                 $title = null;
3896
3897                                                 // Start checking the attributes of media:content
3898                                                 if (isset($content['attribs']['']['bitrate']))
3899                                                 {
3900                                                         $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
3901                                                 }
3902                                                 if (isset($content['attribs']['']['channels']))
3903                                                 {
3904                                                         $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
3905                                                 }
3906                                                 if (isset($content['attribs']['']['duration']))
3907                                                 {
3908                                                         $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
3909                                                 }
3910                                                 else
3911                                                 {
3912                                                         $duration = $duration_parent;
3913                                                 }
3914                                                 if (isset($content['attribs']['']['expression']))
3915                                                 {
3916                                                         $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
3917                                                 }
3918                                                 if (isset($content['attribs']['']['framerate']))
3919                                                 {
3920                                                         $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
3921                                                 }
3922                                                 if (isset($content['attribs']['']['height']))
3923                                                 {
3924                                                         $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
3925                                                 }
3926                                                 if (isset($content['attribs']['']['lang']))
3927                                                 {
3928                                                         $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3929                                                 }
3930                                                 if (isset($content['attribs']['']['fileSize']))
3931                                                 {
3932                                                         $length = ceil($content['attribs']['']['fileSize']);
3933                                                 }
3934                                                 if (isset($content['attribs']['']['medium']))
3935                                                 {
3936                                                         $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
3937                                                 }
3938                                                 if (isset($content['attribs']['']['samplingrate']))
3939                                                 {
3940                                                         $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
3941                                                 }
3942                                                 if (isset($content['attribs']['']['type']))
3943                                                 {
3944                                                         $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3945                                                 }
3946                                                 if (isset($content['attribs']['']['width']))
3947                                                 {
3948                                                         $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
3949                                                 }
3950                                                 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
3951
3952                                                 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
3953
3954                                                 // CAPTIONS
3955                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
3956                                                 {
3957                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
3958                                                         {
3959                                                                 $caption_type = null;
3960                                                                 $caption_lang = null;
3961                                                                 $caption_startTime = null;
3962                                                                 $caption_endTime = null;
3963                                                                 $caption_text = null;
3964                                                                 if (isset($caption['attribs']['']['type']))
3965                                                                 {
3966                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3967                                                                 }
3968                                                                 if (isset($caption['attribs']['']['lang']))
3969                                                                 {
3970                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3971                                                                 }
3972                                                                 if (isset($caption['attribs']['']['start']))
3973                                                                 {
3974                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3975                                                                 }
3976                                                                 if (isset($caption['attribs']['']['end']))
3977                                                                 {
3978                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3979                                                                 }
3980                                                                 if (isset($caption['data']))
3981                                                                 {
3982                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3983                                                                 }
3984                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3985                                                         }
3986                                                         if (is_array($captions))
3987                                                         {
3988                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
3989                                                         }
3990                                                 }
3991                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
3992                                                 {
3993                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
3994                                                         {
3995                                                                 $caption_type = null;
3996                                                                 $caption_lang = null;
3997                                                                 $caption_startTime = null;
3998                                                                 $caption_endTime = null;
3999                                                                 $caption_text = null;
4000                                                                 if (isset($caption['attribs']['']['type']))
4001                                                                 {
4002                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4003                                                                 }
4004                                                                 if (isset($caption['attribs']['']['lang']))
4005                                                                 {
4006                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4007                                                                 }
4008                                                                 if (isset($caption['attribs']['']['start']))
4009                                                                 {
4010                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4011                                                                 }
4012                                                                 if (isset($caption['attribs']['']['end']))
4013                                                                 {
4014                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4015                                                                 }
4016                                                                 if (isset($caption['data']))
4017                                                                 {
4018                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4019                                                                 }
4020                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4021                                                         }
4022                                                         if (is_array($captions))
4023                                                         {
4024                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
4025                                                         }
4026                                                 }
4027                                                 else
4028                                                 {
4029                                                         $captions = $captions_parent;
4030                                                 }
4031
4032                                                 // CATEGORIES
4033                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4034                                                 {
4035                                                         foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4036                                                         {
4037                                                                 $term = null;
4038                                                                 $scheme = null;
4039                                                                 $label = null;
4040                                                                 if (isset($category['data']))
4041                                                                 {
4042                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4043                                                                 }
4044                                                                 if (isset($category['attribs']['']['scheme']))
4045                                                                 {
4046                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4047                                                                 }
4048                                                                 else
4049                                                                 {
4050                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
4051                                                                 }
4052                                                                 if (isset($category['attribs']['']['label']))
4053                                                                 {
4054                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4055                                                                 }
4056                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4057                                                         }
4058                                                 }
4059                                                 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4060                                                 {
4061                                                         foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4062                                                         {
4063                                                                 $term = null;
4064                                                                 $scheme = null;
4065                                                                 $label = null;
4066                                                                 if (isset($category['data']))
4067                                                                 {
4068                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4069                                                                 }
4070                                                                 if (isset($category['attribs']['']['scheme']))
4071                                                                 {
4072                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4073                                                                 }
4074                                                                 else
4075                                                                 {
4076                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
4077                                                                 }
4078                                                                 if (isset($category['attribs']['']['label']))
4079                                                                 {
4080                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4081                                                                 }
4082                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4083                                                         }
4084                                                 }
4085                                                 if (is_array($categories) && is_array($categories_parent))
4086                                                 {
4087                                                         $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4088                                                 }
4089                                                 elseif (is_array($categories))
4090                                                 {
4091                                                         $categories = array_values(SimplePie_Misc::array_unique($categories));
4092                                                 }
4093                                                 elseif (is_array($categories_parent))
4094                                                 {
4095                                                         $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4096                                                 }
4097
4098                                                 // COPYRIGHTS
4099                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4100                                                 {
4101                                                         $copyright_url = null;
4102                                                         $copyright_label = null;
4103                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4104                                                         {
4105                                                                 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4106                                                         }
4107                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4108                                                         {
4109                                                                 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4110                                                         }
4111                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4112                                                 }
4113                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4114                                                 {
4115                                                         $copyright_url = null;
4116                                                         $copyright_label = null;
4117                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4118                                                         {
4119                                                                 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4120                                                         }
4121                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4122                                                         {
4123                                                                 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4124                                                         }
4125                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4126                                                 }
4127                                                 else
4128                                                 {
4129                                                         $copyrights = $copyrights_parent;
4130                                                 }
4131
4132                                                 // CREDITS
4133                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4134                                                 {
4135                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4136                                                         {
4137                                                                 $credit_role = null;
4138                                                                 $credit_scheme = null;
4139                                                                 $credit_name = null;
4140                                                                 if (isset($credit['attribs']['']['role']))
4141                                                                 {
4142                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4143                                                                 }
4144                                                                 if (isset($credit['attribs']['']['scheme']))
4145                                                                 {
4146                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4147                                                                 }
4148                                                                 else
4149                                                                 {
4150                                                                         $credit_scheme = 'urn:ebu';
4151                                                                 }
4152                                                                 if (isset($credit['data']))
4153                                                                 {
4154                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4155                                                                 }
4156                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4157                                                         }
4158                                                         if (is_array($credits))
4159                                                         {
4160                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
4161                                                         }
4162                                                 }
4163                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4164                                                 {
4165                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4166                                                         {
4167                                                                 $credit_role = null;
4168                                                                 $credit_scheme = null;
4169                                                                 $credit_name = null;
4170                                                                 if (isset($credit['attribs']['']['role']))
4171                                                                 {
4172                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4173                                                                 }
4174                                                                 if (isset($credit['attribs']['']['scheme']))
4175                                                                 {
4176                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4177                                                                 }
4178                                                                 else
4179                                                                 {
4180                                                                         $credit_scheme = 'urn:ebu';
4181                                                                 }
4182                                                                 if (isset($credit['data']))
4183                                                                 {
4184                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4185                                                                 }
4186                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4187                                                         }
4188                                                         if (is_array($credits))
4189                                                         {
4190                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
4191                                                         }
4192                                                 }
4193                                                 else
4194                                                 {
4195                                                         $credits = $credits_parent;
4196                                                 }
4197
4198                                                 // DESCRIPTION
4199                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4200                                                 {
4201                                                         $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4202                                                 }
4203                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4204                                                 {
4205                                                         $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4206                                                 }
4207                                                 else
4208                                                 {
4209                                                         $description = $description_parent;
4210                                                 }
4211
4212                                                 // HASHES
4213                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4214                                                 {
4215                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4216                                                         {
4217                                                                 $value = null;
4218                                                                 $algo = null;
4219                                                                 if (isset($hash['data']))
4220                                                                 {
4221                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4222                                                                 }
4223                                                                 if (isset($hash['attribs']['']['algo']))
4224                                                                 {
4225                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4226                                                                 }
4227                                                                 else
4228                                                                 {
4229                                                                         $algo = 'md5';
4230                                                                 }
4231                                                                 $hashes[] = $algo.':'.$value;
4232                                                         }
4233                                                         if (is_array($hashes))
4234                                                         {
4235                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4236                                                         }
4237                                                 }
4238                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4239                                                 {
4240                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4241                                                         {
4242                                                                 $value = null;
4243                                                                 $algo = null;
4244                                                                 if (isset($hash['data']))
4245                                                                 {
4246                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4247                                                                 }
4248                                                                 if (isset($hash['attribs']['']['algo']))
4249                                                                 {
4250                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4251                                                                 }
4252                                                                 else
4253                                                                 {
4254                                                                         $algo = 'md5';
4255                                                                 }
4256                                                                 $hashes[] = $algo.':'.$value;
4257                                                         }
4258                                                         if (is_array($hashes))
4259                                                         {
4260                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4261                                                         }
4262                                                 }
4263                                                 else
4264                                                 {
4265                                                         $hashes = $hashes_parent;
4266                                                 }
4267
4268                                                 // KEYWORDS
4269                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4270                                                 {
4271                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4272                                                         {
4273                                                                 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4274                                                                 foreach ($temp as $word)
4275                                                                 {
4276                                                                         $keywords[] = trim($word);
4277                                                                 }
4278                                                                 unset($temp);
4279                                                         }
4280                                                         if (is_array($keywords))
4281                                                         {
4282                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4283                                                         }
4284                                                 }
4285                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4286                                                 {
4287                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4288                                                         {
4289                                                                 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4290                                                                 foreach ($temp as $word)
4291                                                                 {
4292                                                                         $keywords[] = trim($word);
4293                                                                 }
4294                                                                 unset($temp);
4295                                                         }
4296                                                         if (is_array($keywords))
4297                                                         {
4298                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4299                                                         }
4300                                                 }
4301                                                 else
4302                                                 {
4303                                                         $keywords = $keywords_parent;
4304                                                 }
4305
4306                                                 // PLAYER
4307                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4308                                                 {
4309                                                         $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4310                                                 }
4311                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4312                                                 {
4313                                                         $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4314                                                 }
4315                                                 else
4316                                                 {
4317                                                         $player = $player_parent;
4318                                                 }
4319
4320                                                 // RATINGS
4321                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4322                                                 {
4323                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4324                                                         {
4325                                                                 $rating_scheme = null;
4326                                                                 $rating_value = null;
4327                                                                 if (isset($rating['attribs']['']['scheme']))
4328                                                                 {
4329                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4330                                                                 }
4331                                                                 else
4332                                                                 {
4333                                                                         $rating_scheme = 'urn:simple';
4334                                                                 }
4335                                                                 if (isset($rating['data']))
4336                                                                 {
4337                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4338                                                                 }
4339                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4340                                                         }
4341                                                         if (is_array($ratings))
4342                                                         {
4343                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4344                                                         }
4345                                                 }
4346                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4347                                                 {
4348                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4349                                                         {
4350                                                                 $rating_scheme = null;
4351                                                                 $rating_value = null;
4352                                                                 if (isset($rating['attribs']['']['scheme']))
4353                                                                 {
4354                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4355                                                                 }
4356                                                                 else
4357                                                                 {
4358                                                                         $rating_scheme = 'urn:simple';
4359                                                                 }
4360                                                                 if (isset($rating['data']))
4361                                                                 {
4362                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4363                                                                 }
4364                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4365                                                         }
4366                                                         if (is_array($ratings))
4367                                                         {
4368                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4369                                                         }
4370                                                 }
4371                                                 else
4372                                                 {
4373                                                         $ratings = $ratings_parent;
4374                                                 }
4375
4376                                                 // RESTRICTIONS
4377                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4378                                                 {
4379                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4380                                                         {
4381                                                                 $restriction_relationship = null;
4382                                                                 $restriction_type = null;
4383                                                                 $restriction_value = null;
4384                                                                 if (isset($restriction['attribs']['']['relationship']))
4385                                                                 {
4386                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4387                                                                 }
4388                                                                 if (isset($restriction['attribs']['']['type']))
4389                                                                 {
4390                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4391                                                                 }
4392                                                                 if (isset($restriction['data']))
4393                                                                 {
4394                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4395                                                                 }
4396                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4397                                                         }
4398                                                         if (is_array($restrictions))
4399                                                         {
4400                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4401                                                         }
4402                                                 }
4403                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4404                                                 {
4405                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4406                                                         {
4407                                                                 $restriction_relationship = null;
4408                                                                 $restriction_type = null;
4409                                                                 $restriction_value = null;
4410                                                                 if (isset($restriction['attribs']['']['relationship']))
4411                                                                 {
4412                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4413                                                                 }
4414                                                                 if (isset($restriction['attribs']['']['type']))
4415                                                                 {
4416                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4417                                                                 }
4418                                                                 if (isset($restriction['data']))
4419                                                                 {
4420                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4421                                                                 }
4422                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4423                                                         }
4424                                                         if (is_array($restrictions))
4425                                                         {
4426                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4427                                                         }
4428                                                 }
4429                                                 else
4430                                                 {
4431                                                         $restrictions = $restrictions_parent;
4432                                                 }
4433
4434                                                 // THUMBNAILS
4435                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4436                                                 {
4437                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4438                                                         {
4439                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4440                                                         }
4441                                                         if (is_array($thumbnails))
4442                                                         {
4443                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4444                                                         }
4445                                                 }
4446                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4447                                                 {
4448                                                         foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4449                                                         {
4450                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4451                                                         }
4452                                                         if (is_array($thumbnails))
4453                                                         {
4454                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4455                                                         }
4456                                                 }
4457                                                 else
4458                                                 {
4459                                                         $thumbnails = $thumbnails_parent;
4460                                                 }
4461
4462                                                 // TITLES
4463                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4464                                                 {
4465                                                         $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4466                                                 }
4467                                                 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4468                                                 {
4469                                                         $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4470                                                 }
4471                                                 else
4472                                                 {
4473                                                         $title = $title_parent;
4474                                                 }
4475
4476                                                 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
4477                                         }
4478                                 }
4479                         }
4480
4481                         // If we have standalone media:content tags, loop through them.
4482                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4483                         {
4484                                 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4485                                 {
4486                                         if (isset($content['attribs']['']['url']))
4487                                         {
4488                                                 // Attributes
4489                                                 $bitrate = null;
4490                                                 $channels = null;
4491                                                 $duration = null;
4492                                                 $expression = null;
4493                                                 $framerate = null;
4494                                                 $height = null;
4495                                                 $javascript = null;
4496                                                 $lang = null;
4497                                                 $length = null;
4498                                                 $medium = null;
4499                                                 $samplingrate = null;
4500                                                 $type = null;
4501                                                 $url = null;
4502                                                 $width = null;
4503
4504                                                 // Elements
4505                                                 $captions = null;
4506                                                 $categories = null;
4507                                                 $copyrights = null;
4508                                                 $credits = null;
4509                                                 $description = null;
4510                                                 $hashes = null;
4511                                                 $keywords = null;
4512                                                 $player = null;
4513                                                 $ratings = null;
4514                                                 $restrictions = null;
4515                                                 $thumbnails = null;
4516                                                 $title = null;
4517
4518                                                 // Start checking the attributes of media:content
4519                                                 if (isset($content['attribs']['']['bitrate']))
4520                                                 {
4521                                                         $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4522                                                 }
4523                                                 if (isset($content['attribs']['']['channels']))
4524                                                 {
4525                                                         $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4526                                                 }
4527                                                 if (isset($content['attribs']['']['duration']))
4528                                                 {
4529                                                         $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4530                                                 }
4531                                                 else
4532                                                 {
4533                                                         $duration = $duration_parent;
4534                                                 }
4535                                                 if (isset($content['attribs']['']['expression']))
4536                                                 {
4537                                                         $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4538                                                 }
4539                                                 if (isset($content['attribs']['']['framerate']))
4540                                                 {
4541                                                         $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4542                                                 }
4543                                                 if (isset($content['attribs']['']['height']))
4544                                                 {
4545                                                         $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4546                                                 }
4547                                                 if (isset($content['attribs']['']['lang']))
4548                                                 {
4549                                                         $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4550                                                 }
4551                                                 if (isset($content['attribs']['']['fileSize']))
4552                                                 {
4553                                                         $length = ceil($content['attribs']['']['fileSize']);
4554                                                 }
4555                                                 if (isset($content['attribs']['']['medium']))
4556                                                 {
4557                                                         $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4558                                                 }
4559                                                 if (isset($content['attribs']['']['samplingrate']))
4560                                                 {
4561                                                         $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4562                                                 }
4563                                                 if (isset($content['attribs']['']['type']))
4564                                                 {
4565                                                         $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4566                                                 }
4567                                                 if (isset($content['attribs']['']['width']))
4568                                                 {
4569                                                         $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4570                                                 }
4571                                                 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4572
4573                                                 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4574
4575                                                 // CAPTIONS
4576                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4577                                                 {
4578                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4579                                                         {
4580                                                                 $caption_type = null;
4581                                                                 $caption_lang = null;
4582                                                                 $caption_startTime = null;
4583                                                                 $caption_endTime = null;
4584                                                                 $caption_text = null;
4585                                                                 if (isset($caption['attribs']['']['type']))
4586                                                                 {
4587                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4588                                                                 }
4589                                                                 if (isset($caption['attribs']['']['lang']))
4590                                                                 {
4591                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4592                                                                 }
4593                                                                 if (isset($caption['attribs']['']['start']))
4594                                                                 {
4595                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4596                                                                 }
4597                                                                 if (isset($caption['attribs']['']['end']))
4598                                                                 {
4599                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4600                                                                 }
4601                                                                 if (isset($caption['data']))
4602                                                                 {
4603                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4604                                                                 }
4605                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4606                                                         }
4607                                                         if (is_array($captions))
4608                                                         {
4609                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
4610                                                         }
4611                                                 }
4612                                                 else
4613                                                 {
4614                                                         $captions = $captions_parent;
4615                                                 }
4616
4617                                                 // CATEGORIES
4618                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4619                                                 {
4620                                                         foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4621                                                         {
4622                                                                 $term = null;
4623                                                                 $scheme = null;
4624                                                                 $label = null;
4625                                                                 if (isset($category['data']))
4626                                                                 {
4627                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4628                                                                 }
4629                                                                 if (isset($category['attribs']['']['scheme']))
4630                                                                 {
4631                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4632                                                                 }
4633                                                                 else
4634                                                                 {
4635                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
4636                                                                 }
4637                                                                 if (isset($category['attribs']['']['label']))
4638                                                                 {
4639                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4640                                                                 }
4641                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
4642                                                         }
4643                                                 }
4644                                                 if (is_array($categories) && is_array($categories_parent))
4645                                                 {
4646                                                         $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4647                                                 }
4648                                                 elseif (is_array($categories))
4649                                                 {
4650                                                         $categories = array_values(SimplePie_Misc::array_unique($categories));
4651                                                 }
4652                                                 elseif (is_array($categories_parent))
4653                                                 {
4654                                                         $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4655                                                 }
4656                                                 else
4657                                                 {
4658                                                         $categories = null;
4659                                                 }
4660
4661                                                 // COPYRIGHTS
4662                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4663                                                 {
4664                                                         $copyright_url = null;
4665                                                         $copyright_label = null;
4666                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4667                                                         {
4668                                                                 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4669                                                         }
4670                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4671                                                         {
4672                                                                 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4673                                                         }
4674                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
4675                                                 }
4676                                                 else
4677                                                 {
4678                                                         $copyrights = $copyrights_parent;
4679                                                 }
4680
4681                                                 // CREDITS
4682                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4683                                                 {
4684                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4685                                                         {
4686                                                                 $credit_role = null;
4687                                                                 $credit_scheme = null;
4688                                                                 $credit_name = null;
4689                                                                 if (isset($credit['attribs']['']['role']))
4690                                                                 {
4691                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4692                                                                 }
4693                                                                 if (isset($credit['attribs']['']['scheme']))
4694                                                                 {
4695                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4696                                                                 }
4697                                                                 else
4698                                                                 {
4699                                                                         $credit_scheme = 'urn:ebu';
4700                                                                 }
4701                                                                 if (isset($credit['data']))
4702                                                                 {
4703                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4704                                                                 }
4705                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4706                                                         }
4707                                                         if (is_array($credits))
4708                                                         {
4709                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
4710                                                         }
4711                                                 }
4712                                                 else
4713                                                 {
4714                                                         $credits = $credits_parent;
4715                                                 }
4716
4717                                                 // DESCRIPTION
4718                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4719                                                 {
4720                                                         $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4721                                                 }
4722                                                 else
4723                                                 {
4724                                                         $description = $description_parent;
4725                                                 }
4726
4727                                                 // HASHES
4728                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4729                                                 {
4730                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4731                                                         {
4732                                                                 $value = null;
4733                                                                 $algo = null;
4734                                                                 if (isset($hash['data']))
4735                                                                 {
4736                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4737                                                                 }
4738                                                                 if (isset($hash['attribs']['']['algo']))
4739                                                                 {
4740                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4741                                                                 }
4742                                                                 else
4743                                                                 {
4744                                                                         $algo = 'md5';
4745                                                                 }
4746                                                                 $hashes[] = $algo.':'.$value;
4747                                                         }
4748                                                         if (is_array($hashes))
4749                                                         {
4750                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4751                                                         }
4752                                                 }
4753                                                 else
4754                                                 {
4755                                                         $hashes = $hashes_parent;
4756                                                 }
4757
4758                                                 // KEYWORDS
4759                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4760                                                 {
4761                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4762                                                         {
4763                                                                 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4764                                                                 foreach ($temp as $word)
4765                                                                 {
4766                                                                         $keywords[] = trim($word);
4767                                                                 }
4768                                                                 unset($temp);
4769                                                         }
4770                                                         if (is_array($keywords))
4771                                                         {
4772                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4773                                                         }
4774                                                 }
4775                                                 else
4776                                                 {
4777                                                         $keywords = $keywords_parent;
4778                                                 }
4779
4780                                                 // PLAYER
4781                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4782                                                 {
4783                                                         $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4784                                                 }
4785                                                 else
4786                                                 {
4787                                                         $player = $player_parent;
4788                                                 }
4789
4790                                                 // RATINGS
4791                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4792                                                 {
4793                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4794                                                         {
4795                                                                 $rating_scheme = null;
4796                                                                 $rating_value = null;
4797                                                                 if (isset($rating['attribs']['']['scheme']))
4798                                                                 {
4799                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4800                                                                 }
4801                                                                 else
4802                                                                 {
4803                                                                         $rating_scheme = 'urn:simple';
4804                                                                 }
4805                                                                 if (isset($rating['data']))
4806                                                                 {
4807                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4808                                                                 }
4809                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
4810                                                         }
4811                                                         if (is_array($ratings))
4812                                                         {
4813                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4814                                                         }
4815                                                 }
4816                                                 else
4817                                                 {
4818                                                         $ratings = $ratings_parent;
4819                                                 }
4820
4821                                                 // RESTRICTIONS
4822                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4823                                                 {
4824                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4825                                                         {
4826                                                                 $restriction_relationship = null;
4827                                                                 $restriction_type = null;
4828                                                                 $restriction_value = null;
4829                                                                 if (isset($restriction['attribs']['']['relationship']))
4830                                                                 {
4831                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4832                                                                 }
4833                                                                 if (isset($restriction['attribs']['']['type']))
4834                                                                 {
4835                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4836                                                                 }
4837                                                                 if (isset($restriction['data']))
4838                                                                 {
4839                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4840                                                                 }
4841                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4842                                                         }
4843                                                         if (is_array($restrictions))
4844                                                         {
4845                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4846                                                         }
4847                                                 }
4848                                                 else
4849                                                 {
4850                                                         $restrictions = $restrictions_parent;
4851                                                 }
4852
4853                                                 // THUMBNAILS
4854                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
4855                                                 {
4856                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
4857                                                         {
4858                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4859                                                         }
4860                                                         if (is_array($thumbnails))
4861                                                         {
4862                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
4863                                                         }
4864                                                 }
4865                                                 else
4866                                                 {
4867                                                         $thumbnails = $thumbnails_parent;
4868                                                 }
4869
4870                                                 // TITLES
4871                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
4872                                                 {
4873                                                         $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4874                                                 }
4875                                                 else
4876                                                 {
4877                                                         $title = $title_parent;
4878                                                 }
4879
4880                                                 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
4881                                         }
4882                                 }
4883                         }
4884
4885                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
4886                         {
4887                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
4888                                 {
4889                                         // Attributes
4890                                         $bitrate = null;
4891                                         $channels = null;
4892                                         $duration = null;
4893                                         $expression = null;
4894                                         $framerate = null;
4895                                         $height = null;
4896                                         $javascript = null;
4897                                         $lang = null;
4898                                         $length = null;
4899                                         $medium = null;
4900                                         $samplingrate = null;
4901                                         $type = null;
4902                                         $url = null;
4903                                         $width = null;
4904
4905                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
4906                                         if (isset($link['attribs']['']['type']))
4907                                         {
4908                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4909                                         }
4910                                         if (isset($link['attribs']['']['length']))
4911                                         {
4912                                                 $length = ceil($link['attribs']['']['length']);
4913                                         }
4914
4915                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4916                                         $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
4917                                 }
4918                         }
4919
4920                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
4921                         {
4922                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] == 'enclosure')
4923                                 {
4924                                         // Attributes
4925                                         $bitrate = null;
4926                                         $channels = null;
4927                                         $duration = null;
4928                                         $expression = null;
4929                                         $framerate = null;
4930                                         $height = null;
4931                                         $javascript = null;
4932                                         $lang = null;
4933                                         $length = null;
4934                                         $medium = null;
4935                                         $samplingrate = null;
4936                                         $type = null;
4937                                         $url = null;
4938                                         $width = null;
4939
4940                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
4941                                         if (isset($link['attribs']['']['type']))
4942                                         {
4943                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4944                                         }
4945                                         if (isset($link['attribs']['']['length']))
4946                                         {
4947                                                 $length = ceil($link['attribs']['']['length']);
4948                                         }
4949
4950                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4951                                         $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
4952                                 }
4953                         }
4954
4955                         if ($enclosure = $this->get_item_tags('', 'enclosure'))
4956                         {
4957                                 if (isset($enclosure[0]['attribs']['']['url']))
4958                                 {
4959                                         // Attributes
4960                                         $bitrate = null;
4961                                         $channels = null;
4962                                         $duration = null;
4963                                         $expression = null;
4964                                         $framerate = null;
4965                                         $height = null;
4966                                         $javascript = null;
4967                                         $lang = null;
4968                                         $length = null;
4969                                         $medium = null;
4970                                         $samplingrate = null;
4971                                         $type = null;
4972                                         $url = null;
4973                                         $width = null;
4974
4975                                         $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
4976                                         if (isset($enclosure[0]['attribs']['']['type']))
4977                                         {
4978                                                 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4979                                         }
4980                                         if (isset($enclosure[0]['attribs']['']['length']))
4981                                         {
4982                                                 $length = ceil($enclosure[0]['attribs']['']['length']);
4983                                         }
4984
4985                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
4986                                         $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
4987                                 }
4988                         }
4989                         $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
4990                 }
4991                 if (!empty($this->data['enclosures']))
4992                 {
4993                         return $this->data['enclosures'];
4994                 }
4995                 else
4996                 {
4997                         return null;
4998                 }
4999         }
5000
5001         function get_latitude()
5002         {
5003                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5004                 {
5005                         return (float) $return[0]['data'];
5006                 }
5007                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5008                 {
5009                         return (float) $match[1];
5010                 }
5011                 else
5012                 {
5013                         return null;
5014                 }
5015         }
5016
5017         function get_longitude()
5018         {
5019                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5020                 {
5021                         return (float) $return[0]['data'];
5022                 }
5023                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5024                 {
5025                         return (float) $return[0]['data'];
5026                 }
5027                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match))
5028                 {
5029                         return (float) $match[2];
5030                 }
5031                 else
5032                 {
5033                         return null;
5034                 }
5035         }
5036
5037         /**
5038          * Creates the add_to_* methods' return data
5039          *
5040          * @access private
5041          * @param string $item_url String to prefix to the item permalink
5042          * @param string $title_url String to prefix to the item title
5043          * (and suffix to the item permalink)
5044          * @return mixed URL if feed exists, false otherwise
5045          */
5046         function add_to_service($item_url, $title_url = null)
5047         {
5048                 if ($this->get_permalink() !== null)
5049                 {
5050                         $return = $this->sanitize($item_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_permalink());
5051                         if ($title_url !== null && $this->get_title() !== null)
5052                         {
5053                                 $return .= $this->sanitize($title_url, SIMPLEPIE_CONSTRUCT_IRI) . rawurlencode($this->get_title());
5054                         }
5055                         return $return;
5056                 }
5057                 else
5058                 {
5059                         return null;
5060                 }
5061         }
5062
5063         function add_to_blinklist()
5064         {
5065                 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5066         }
5067
5068         function add_to_blogmarks()
5069         {
5070                 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5071         }
5072
5073         function add_to_delicious()
5074         {
5075                 return $this->add_to_service('http://del.icio.us/post/?v=3&url=', '&title=');
5076         }
5077
5078         function add_to_digg()
5079         {
5080                 return $this->add_to_service('http://digg.com/submit?phase=2&URL=');
5081         }
5082
5083         function add_to_furl()
5084         {
5085                 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5086         }
5087
5088         function add_to_magnolia()
5089         {
5090                 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5091         }
5092
5093         function add_to_myweb20()
5094         {
5095                 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5096         }
5097
5098         function add_to_newsvine()
5099         {
5100                 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5101         }
5102
5103         function add_to_reddit()
5104         {
5105                 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5106         }
5107
5108         function add_to_segnalo()
5109         {
5110                 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5111         }
5112
5113         function add_to_simpy()
5114         {
5115                 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5116         }
5117
5118         function add_to_spurl()
5119         {
5120                 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5121         }
5122
5123         function add_to_wists()
5124         {
5125                 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5126         }
5127
5128         function search_technorati()
5129         {
5130                 return $this->add_to_service('http://www.technorati.com/search/');
5131         }
5132 }
5133
5134 class SimplePie_Author
5135 {
5136         var $name;
5137         var $link;
5138         var $email;
5139
5140         // Constructor, used to input the data
5141         function SimplePie_Author($name = null, $link = null, $email = null)
5142         {
5143                 $this->name = $name;
5144                 $this->link = $link;
5145                 $this->email = $email;
5146         }
5147
5148         function __toString()
5149         {
5150                 // There is no $this->data here
5151                 return md5(serialize($this));
5152         }
5153
5154         function get_name()
5155         {
5156                 if ($this->name !== null)
5157                 {
5158                         return $this->name;
5159                 }
5160                 else
5161                 {
5162                         return null;
5163                 }
5164         }
5165
5166         function get_link()
5167         {
5168                 if ($this->link !== null)
5169                 {
5170                         return $this->link;
5171                 }
5172                 else
5173                 {
5174                         return null;
5175                 }
5176         }
5177
5178         function get_email()
5179         {
5180                 if ($this->email !== null)
5181                 {
5182                         return $this->email;
5183                 }
5184                 else
5185                 {
5186                         return null;
5187                 }
5188         }
5189 }
5190
5191 class SimplePie_Category
5192 {
5193         var $term;
5194         var $scheme;
5195         var $label;
5196
5197         // Constructor, used to input the data
5198         function SimplePie_Category($term = null, $scheme = null, $label = null)
5199         {
5200                 $this->term = $term;
5201                 $this->scheme = $scheme;
5202                 $this->label = $label;
5203         }
5204
5205         function __toString()
5206         {
5207                 // There is no $this->data here
5208                 return md5(serialize($this));
5209         }
5210
5211         function get_term()
5212         {
5213                 if ($this->term !== null)
5214                 {
5215                         return $this->term;
5216                 }
5217                 else
5218                 {
5219                         return null;
5220                 }
5221         }
5222
5223         function get_scheme()
5224         {
5225                 if ($this->scheme !== null)
5226                 {
5227                         return $this->scheme;
5228                 }
5229                 else
5230                 {
5231                         return null;
5232                 }
5233         }
5234
5235         function get_label()
5236         {
5237                 if ($this->label !== null)
5238                 {
5239                         return $this->label;
5240                 }
5241                 else
5242                 {
5243                         return $this->get_term();
5244                 }
5245         }
5246 }
5247
5248 class SimplePie_Enclosure
5249 {
5250         var $bitrate;
5251         var $captions;
5252         var $categories;
5253         var $channels;
5254         var $copyright;
5255         var $credits;
5256         var $description;
5257         var $duration;
5258         var $expression;
5259         var $framerate;
5260         var $handler;
5261         var $hashes;
5262         var $height;
5263         var $javascript;
5264         var $keywords;
5265         var $lang;
5266         var $length;
5267         var $link;
5268         var $medium;
5269         var $player;
5270         var $ratings;
5271         var $restrictions;
5272         var $samplingrate;
5273         var $thumbnails;
5274         var $title;
5275         var $type;
5276         var $width;
5277
5278         // Constructor, used to input the data
5279         function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
5280         {
5281                 $this->bitrate = $bitrate;
5282                 $this->captions = $captions;
5283                 $this->categories = $categories;
5284                 $this->channels = $channels;
5285                 $this->copyright = $copyright;
5286                 $this->credits = $credits;
5287                 $this->description = $description;
5288                 $this->duration = $duration;
5289                 $this->expression = $expression;
5290                 $this->framerate = $framerate;
5291                 $this->hashes = $hashes;
5292                 $this->height = $height;
5293                 $this->javascript = $javascript;
5294                 $this->keywords = $keywords;
5295                 $this->lang = $lang;
5296                 $this->length = $length;
5297                 $this->link = $link;
5298                 $this->medium = $medium;
5299                 $this->player = $player;
5300                 $this->ratings = $ratings;
5301                 $this->restrictions = $restrictions;
5302                 $this->samplingrate = $samplingrate;
5303                 $this->thumbnails = $thumbnails;
5304                 $this->title = $title;
5305                 $this->type = $type;
5306                 $this->width = $width;
5307                 if (class_exists('idna_convert'))
5308                 {
5309                         $idn =& new idna_convert;
5310                         $parsed = SimplePie_Misc::parse_url($link);
5311                         $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
5312                 }
5313                 $this->handler = $this->get_handler(); // Needs to load last
5314         }
5315
5316         function __toString()
5317         {
5318                 // There is no $this->data here
5319                 return md5(serialize($this));
5320         }
5321
5322         function get_bitrate()
5323         {
5324                 if ($this->bitrate !== null)
5325                 {
5326                         return $this->bitrate;
5327                 }
5328                 else
5329                 {
5330                         return null;
5331                 }
5332         }
5333
5334         function get_caption($key = 0)
5335         {
5336                 $captions = $this->get_captions();
5337                 if (isset($captions[$key]))
5338                 {
5339                         return $captions[$key];
5340                 }
5341                 else
5342                 {
5343                         return null;
5344                 }
5345         }
5346
5347         function get_captions()
5348         {
5349                 if ($this->captions !== null)
5350                 {
5351                         return $this->captions;
5352                 }
5353                 else
5354                 {
5355                         return null;
5356                 }
5357         }
5358
5359         function get_category($key = 0)
5360         {
5361                 $categories = $this->get_categories();
5362                 if (isset($categories[$key]))
5363                 {
5364                         return $categories[$key];
5365                 }
5366                 else
5367                 {
5368                         return null;
5369                 }
5370         }
5371
5372         function get_categories()
5373         {
5374                 if ($this->categories !== null)
5375                 {
5376                         return $this->categories;
5377                 }
5378                 else
5379                 {
5380                         return null;
5381                 }
5382         }
5383
5384         function get_channels()
5385         {
5386                 if ($this->channels !== null)
5387                 {
5388                         return $this->channels;
5389                 }
5390                 else
5391                 {
5392                         return null;
5393                 }
5394         }
5395
5396         function get_copyright()
5397         {
5398                 if ($this->copyright !== null)
5399                 {
5400                         return $this->copyright;
5401                 }
5402                 else
5403                 {
5404                         return null;
5405                 }
5406         }
5407
5408         function get_credit($key = 0)
5409         {
5410                 $credits = $this->get_credits();
5411                 if (isset($credits[$key]))
5412                 {
5413                         return $credits[$key];
5414                 }
5415                 else
5416                 {
5417                         return null;
5418                 }
5419         }
5420
5421         function get_credits()
5422         {
5423                 if ($this->credits !== null)
5424                 {
5425                         return $this->credits;
5426                 }
5427                 else
5428                 {
5429                         return null;
5430                 }
5431         }
5432
5433         function get_description()
5434         {
5435                 if ($this->description !== null)
5436                 {
5437                         return $this->description;
5438                 }
5439                 else
5440                 {
5441                         return null;
5442                 }
5443         }
5444
5445         function get_duration($convert = false)
5446         {
5447                 if ($this->duration !== null)
5448                 {
5449                         if ($convert)
5450                         {
5451                                 $time = SimplePie_Misc::time_hms($this->duration);
5452                                 return $time;
5453                         }
5454                         else
5455                         {
5456                                 return $this->duration;
5457                         }
5458                 }
5459                 else
5460                 {
5461                         return null;
5462                 }
5463         }
5464
5465         function get_expression()
5466         {
5467                 if ($this->expression !== null)
5468                 {
5469                         return $this->expression;
5470                 }
5471                 else
5472                 {
5473                         return 'full';
5474                 }
5475         }
5476
5477         function get_extension()
5478         {
5479                 if ($this->link !== null)
5480                 {
5481                         $url = SimplePie_Misc::parse_url($this->link);
5482                         if ($url['path'] !== '')
5483                         {
5484                                 return pathinfo($url['path'], PATHINFO_EXTENSION);
5485                         }
5486                 }
5487                 return null;
5488         }
5489
5490         function get_framerate()
5491         {
5492                 if ($this->framerate !== null)
5493                 {
5494                         return $this->framerate;
5495                 }
5496                 else
5497                 {
5498                         return null;
5499                 }
5500         }
5501
5502         function get_handler()
5503         {
5504                 return $this->get_real_type(true);
5505         }
5506
5507         function get_hash($key = 0)
5508         {
5509                 $hashes = $this->get_hashes();
5510                 if (isset($hashes[$key]))
5511                 {
5512                         return $hashes[$key];
5513                 }
5514                 else
5515                 {
5516                         return null;
5517                 }
5518         }
5519
5520         function get_hashes()
5521         {
5522                 if ($this->hashes !== null)
5523                 {
5524                         return $this->hashes;
5525                 }
5526                 else
5527                 {
5528                         return null;
5529                 }
5530         }
5531
5532         function get_height()
5533         {
5534                 if ($this->height !== null)
5535                 {
5536                         return $this->height;
5537                 }
5538                 else
5539                 {
5540                         return null;
5541                 }
5542         }
5543
5544         function get_language()
5545         {
5546                 if ($this->lang !== null)
5547                 {
5548                         return $this->lang;
5549                 }
5550                 else
5551                 {
5552                         return null;
5553                 }
5554         }
5555
5556         function get_keyword($key = 0)
5557         {
5558                 $keywords = $this->get_keywords();
5559                 if (isset($keywords[$key]))
5560                 {
5561                         return $keywords[$key];
5562                 }
5563                 else
5564                 {
5565                         return null;
5566                 }
5567         }
5568
5569         function get_keywords()
5570         {
5571                 if ($this->keywords !== null)
5572                 {
5573                         return $this->keywords;
5574                 }
5575                 else
5576                 {
5577                         return null;
5578                 }
5579         }
5580
5581         function get_length()
5582         {
5583                 if ($this->length !== null)
5584                 {
5585                         return $this->length;
5586                 }
5587                 else
5588                 {
5589                         return null;
5590                 }
5591         }
5592
5593         function get_link()
5594         {
5595                 if ($this->link !== null)
5596                 {
5597                         return urldecode($this->link);
5598                 }
5599                 else
5600                 {
5601                         return null;
5602                 }
5603         }
5604
5605         function get_medium()
5606         {
5607                 if ($this->medium !== null)
5608                 {
5609                         return $this->medium;
5610                 }
5611                 else
5612                 {
5613                         return null;
5614                 }
5615         }
5616
5617         function get_player()
5618         {
5619                 if ($this->player !== null)
5620                 {
5621                         return $this->player;
5622                 }
5623                 else
5624                 {
5625                         return null;
5626                 }
5627         }
5628
5629         function get_rating($key = 0)
5630         {
5631                 $ratings = $this->get_ratings();
5632                 if (isset($ratings[$key]))
5633                 {
5634                         return $ratings[$key];
5635                 }
5636                 else
5637                 {
5638                         return null;
5639                 }
5640         }
5641
5642         function get_ratings()
5643         {
5644                 if ($this->ratings !== null)
5645                 {
5646                         return $this->ratings;
5647                 }
5648                 else
5649                 {
5650                         return null;
5651                 }
5652         }
5653
5654         function get_restriction($key = 0)
5655         {
5656                 $restrictions = $this->get_restrictions();
5657                 if (isset($restrictions[$key]))
5658                 {
5659                         return $restrictions[$key];
5660                 }
5661                 else
5662                 {
5663                         return null;
5664                 }
5665         }
5666
5667         function get_restrictions()
5668         {
5669                 if ($this->restrictions !== null)
5670                 {
5671                         return $this->restrictions;
5672                 }
5673                 else
5674                 {
5675                         return null;
5676                 }
5677         }
5678
5679         function get_sampling_rate()
5680         {
5681                 if ($this->samplingrate !== null)
5682                 {
5683                         return $this->samplingrate;
5684                 }
5685                 else
5686                 {
5687                         return null;
5688                 }
5689         }
5690
5691         function get_size()
5692         {
5693                 $length = $this->get_length();
5694                 if ($length !== null)
5695                 {
5696                         return round($length/1048576, 2);
5697                 }
5698                 else
5699                 {
5700                         return null;
5701                 }
5702         }
5703
5704         function get_thumbnail($key = 0)
5705         {
5706                 $thumbnails = $this->get_thumbnails();
5707                 if (isset($thumbnails[$key]))
5708                 {
5709                         return $thumbnails[$key];
5710                 }
5711                 else
5712                 {
5713                         return null;
5714                 }
5715         }
5716
5717         function get_thumbnails()
5718         {
5719                 if ($this->thumbnails !== null)
5720                 {
5721                         return $this->thumbnails;
5722                 }
5723                 else
5724                 {
5725                         return null;
5726                 }
5727         }
5728
5729         function get_title()
5730         {
5731                 if ($this->title !== null)
5732                 {
5733                         return $this->title;
5734                 }
5735                 else
5736                 {
5737                         return null;
5738                 }
5739         }
5740
5741         function get_type()
5742         {
5743                 if ($this->type !== null)
5744                 {
5745                         return $this->type;
5746                 }
5747                 else
5748                 {
5749                         return null;
5750                 }
5751         }
5752
5753         function get_width()
5754         {
5755                 if ($this->width !== null)
5756                 {
5757                         return $this->width;
5758                 }
5759                 else
5760                 {
5761                         return null;
5762                 }
5763         }
5764
5765         function native_embed($options='')
5766         {
5767                 return $this->embed($options, true);
5768         }
5769
5770         /**
5771          * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
5772          */
5773         function embed($options = '', $native = false)
5774         {
5775                 // Set up defaults
5776                 $audio = '';
5777                 $video = '';
5778                 $alt = '';
5779                 $altclass = '';
5780                 $loop = 'false';
5781                 $width = 'auto';
5782                 $height = 'auto';
5783                 $bgcolor = '#ffffff';
5784                 $mediaplayer = '';
5785                 $widescreen = false;
5786                 $handler = $this->get_handler();
5787                 $type = $this->get_real_type();
5788
5789                 // Process options and reassign values as necessary
5790                 if (is_array($options))
5791                 {
5792                         extract($options);
5793                 }
5794                 else
5795                 {
5796                         $options = explode(',', $options);
5797                         foreach($options as $option)
5798                         {
5799                                 $opt = explode(':', $option, 2);
5800                                 if (isset($opt[0], $opt[1]))
5801                                 {
5802                                         $opt[0] = trim($opt[0]);
5803                                         $opt[1] = trim($opt[1]);
5804                                         switch ($opt[0])
5805                                         {
5806                                                 case 'audio':
5807                                                         $audio = $opt[1];
5808                                                         break;
5809
5810                                                 case 'video':
5811                                                         $video = $opt[1];
5812                                                         break;
5813
5814                                                 case 'alt':
5815                                                         $alt = $opt[1];
5816                                                         break;
5817
5818                                                 case 'altclass':
5819                                                         $altclass = $opt[1];
5820                                                         break;
5821
5822                                                 case 'loop':
5823                                                         $loop = $opt[1];
5824                                                         break;
5825
5826                                                 case 'width':
5827                                                         $width = $opt[1];
5828                                                         break;
5829
5830                                                 case 'height':
5831                                                         $height = $opt[1];
5832                                                         break;
5833
5834                                                 case 'bgcolor':
5835                                                         $bgcolor = $opt[1];
5836                                                         break;
5837
5838                                                 case 'mediaplayer':
5839                                                         $mediaplayer = $opt[1];
5840                                                         break;
5841
5842                                                 case 'widescreen':
5843                                                         $widescreen = $opt[1];
5844                                                         break;
5845                                         }
5846                                 }
5847                         }
5848                 }
5849
5850                 $mime = explode('/', $type, 2);
5851                 $mime = $mime[0];
5852
5853                 // Process values for 'auto'
5854                 if ($width == 'auto')
5855                 {
5856                         if ($mime == 'video')
5857                         {
5858                                 if ($height == 'auto')
5859                                 {
5860                                         $width = 480;
5861                                 }
5862                                 elseif ($widescreen)
5863                                 {
5864                                         $width = round((intval($height)/9)*16);
5865                                 }
5866                                 else
5867                                 {
5868                                         $width = round((intval($height)/3)*4);
5869                                 }
5870                         }
5871                         else
5872                         {
5873                                 $width = '100%';
5874                         }
5875                 }
5876
5877                 if ($height == 'auto')
5878                 {
5879                         if ($mime == 'audio')
5880                         {
5881                                 $height = 0;
5882                         }
5883                         elseif ($mime == 'video')
5884                         {
5885                                 if ($width == 'auto')
5886                                 {
5887                                         if ($widescreen)
5888                                         {
5889                                                 $height = 270;
5890                                         }
5891                                         else
5892                                         {
5893                                                 $height = 360;
5894                                         }
5895                                 }
5896                                 elseif ($widescreen)
5897                                 {
5898                                         $height = round((intval($width)/16)*9);
5899                                 }
5900                                 else
5901                                 {
5902                                         $height = round((intval($width)/4)*3);
5903                                 }
5904                         }
5905                         else
5906                         {
5907                                 $height = 376;
5908                         }
5909                 }
5910                 elseif ($mime == 'audio')
5911                 {
5912                         $height = 0;
5913                 }
5914
5915                 // Set proper placeholder value
5916                 if ($mime == 'audio')
5917                 {
5918                         $placeholder = $audio;
5919                 }
5920                 elseif ($mime == 'video')
5921                 {
5922                         $placeholder = $video;
5923                 }
5924
5925                 $embed = '';
5926
5927                 // Make sure the JS library is included
5928                 if (!$native)
5929                 {
5930                         static $javascript_outputted = null;
5931                         if (!$javascript_outputted && $this->javascript)
5932                         {
5933                                 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
5934                                 $javascript_outputted = true;
5935                         }
5936                 }
5937
5938                 // Odeo Feed MP3's
5939                 if ($handler == 'odeo')
5940                 {
5941                         if ($native)
5942                         {
5943                                 $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url=' . $this->get_link() . '"></embed>';
5944                         }
5945                         else
5946                         {
5947                                 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
5948                         }
5949                 }
5950
5951                 // Flash
5952                 elseif ($handler == 'flash')
5953                 {
5954                         if ($native)
5955                         {
5956                                 $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
5957                         }
5958                         else
5959                         {
5960                                 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
5961                         }
5962                 }
5963
5964                 // Flash Media Player file types.
5965                 // Preferred handler for MP3 file types.
5966                 elseif ($handler == 'fmedia' || ($handler == 'mp3' && $mediaplayer != ''))
5967                 {
5968                         $height += 20;
5969                         if ($native)
5970                         {
5971                                 $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
5972                         }
5973                         else
5974                         {
5975                                 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
5976                         }
5977                 }
5978
5979                 // QuickTime 7 file types.  Need to test with QuickTime 6.
5980                 // Only handle MP3's if the Flash Media Player is not present.
5981                 elseif ($handler == 'quicktime' || ($handler == 'mp3' && $mediaplayer == ''))
5982                 {
5983                         $height += 16;
5984                         if ($native)
5985                         {
5986                                 if ($placeholder != ""){
5987                                         $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
5988                                 }
5989                                 else {
5990                                         $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
5991                                 }
5992                         }
5993                         else
5994                         {
5995                                 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
5996                         }
5997                 }
5998
5999                 // Windows Media
6000                 elseif ($handler == 'wmedia')
6001                 {
6002                         $height += 45;
6003                         if ($native)
6004                         {
6005                                 $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
6006                         }
6007                         else
6008                         {
6009                                 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
6010                         }
6011                 }
6012
6013                 // Everything else
6014                 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
6015
6016                 return $embed;
6017         }
6018
6019         function get_real_type($find_handler = false)
6020         {
6021                 // If it's Odeo, let's get it out of the way.
6022                 if (substr(strtolower($this->get_link()), 0, 15) == 'http://odeo.com')
6023                 {
6024                         return 'odeo';
6025                 }
6026
6027                 // Mime-types by handler.
6028                 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
6029                 $types_fmedia = array('video/flv', 'video/x-flv'); // Flash Media Player
6030                 $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
6031                 $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
6032                 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
6033
6034                 if ($this->get_type() !== null)
6035                 {
6036                         $type = strtolower($this->type);
6037                 }
6038                 else
6039                 {
6040                         $type = null;
6041                 }
6042
6043                 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
6044                 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
6045                 {
6046                         switch (strtolower($this->get_extension()))
6047                         {
6048                                 // Audio mime-types
6049                                 case 'aac':
6050                                 case 'adts':
6051                                         $type = 'audio/acc';
6052                                         break;
6053
6054                                 case 'aif':
6055                                 case 'aifc':
6056                                 case 'aiff':
6057                                 case 'cdda':
6058                                         $type = 'audio/aiff';
6059                                         break;
6060
6061                                 case 'bwf':
6062                                         $type = 'audio/wav';
6063                                         break;
6064
6065                                 case 'kar':
6066                                 case 'mid':
6067                                 case 'midi':
6068                                 case 'smf':
6069                                         $type = 'audio/midi';
6070                                         break;
6071
6072                                 case 'm4a':
6073                                         $type = 'audio/x-m4a';
6074                                         break;
6075
6076                                 case 'mp3':
6077                                 case 'swa':
6078                                         $type = 'audio/mp3';
6079                                         break;
6080
6081                                 case 'wav':
6082                                         $type = 'audio/wav';
6083                                         break;
6084
6085                                 case 'wax':
6086                                         $type = 'audio/x-ms-wax';
6087                                         break;
6088
6089                                 case 'wma':
6090                                         $type = 'audio/x-ms-wma';
6091                                         break;
6092
6093                                 // Video mime-types
6094                                 case '3gp':
6095                                 case '3gpp':
6096                                         $type = 'video/3gpp';
6097                                         break;
6098
6099                                 case '3g2':
6100                                 case '3gp2':
6101                                         $type = 'video/3gpp2';
6102                                         break;
6103
6104                                 case 'asf':
6105                                         $type = 'video/x-ms-asf';
6106                                         break;
6107
6108                                 case 'flv':
6109                                         $type = 'video/x-flv';
6110                                         break;
6111
6112                                 case 'm1a':
6113                                 case 'm1s':
6114                                 case 'm1v':
6115                                 case 'm15':
6116                                 case 'm75':
6117                                 case 'mp2':
6118                                 case 'mpa':
6119                                 case 'mpeg':
6120                                 case 'mpg':
6121                                 case 'mpm':
6122                                 case 'mpv':
6123                                         $type = 'video/mpeg';
6124                                         break;
6125
6126                                 case 'm4v':
6127                                         $type = 'video/x-m4v';
6128                                         break;
6129
6130                                 case 'mov':
6131                                 case 'qt':
6132                                         $type = 'video/quicktime';
6133                                         break;
6134
6135                                 case 'mp4':
6136                                 case 'mpg4':
6137                                         $type = 'video/mp4';
6138                                         break;
6139
6140                                 case 'sdv':
6141                                         $type = 'video/sd-video';
6142                                         break;
6143
6144                                 case 'wm':
6145                                         $type = 'video/x-ms-wm';
6146                                         break;
6147
6148                                 case 'wmv':
6149                                         $type = 'video/x-ms-wmv';
6150                                         break;
6151
6152                                 case 'wvx':
6153                                         $type = 'video/x-ms-wvx';
6154                                         break;
6155
6156                                 // Flash mime-types
6157                                 case 'spl':
6158                                         $type = 'application/futuresplash';
6159                                         break;
6160
6161                                 case 'swf':
6162                                         $type = 'application/x-shockwave-flash';
6163                                         break;
6164                         }
6165                 }
6166
6167                 if ($find_handler)
6168                 {
6169                         if (in_array($type, $types_flash))
6170                         {
6171                                 return 'flash';
6172                         }
6173                         elseif (in_array($type, $types_fmedia))
6174                         {
6175                                 return 'fmedia';
6176                         }
6177                         elseif (in_array($type, $types_quicktime))
6178                         {
6179                                 return 'quicktime';
6180                         }
6181                         elseif (in_array($type, $types_wmedia))
6182                         {
6183                                 return 'wmedia';
6184                         }
6185                         elseif (in_array($type, $types_mp3))
6186                         {
6187                                 return 'mp3';
6188                         }
6189                         else
6190                         {
6191                                 return null;
6192                         }
6193                 }
6194                 else
6195                 {
6196                         return $type;
6197                 }
6198         }
6199 }
6200
6201 class SimplePie_Caption
6202 {
6203         var $type;
6204         var $lang;
6205         var $startTime;
6206         var $endTime;
6207         var $text;
6208
6209         // Constructor, used to input the data
6210         function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
6211         {
6212                 $this->type = $type;
6213                 $this->lang = $lang;
6214                 $this->startTime = $startTime;
6215                 $this->endTime = $endTime;
6216                 $this->text = $text;
6217         }
6218
6219         function __toString()
6220         {
6221                 // There is no $this->data here
6222                 return md5(serialize($this));
6223         }
6224
6225         function get_endtime()
6226         {
6227                 if ($this->endTime !== null)
6228                 {
6229                         return $this->endTime;
6230                 }
6231                 else
6232                 {
6233                         return null;
6234                 }
6235         }
6236
6237         function get_language()
6238         {
6239                 if ($this->language !== null)
6240                 {
6241                         return $this->language;
6242                 }
6243                 else
6244                 {
6245                         return null;
6246                 }
6247         }
6248
6249         function get_starttime()
6250         {
6251                 if ($this->startTime !== null)
6252                 {
6253                         return $this->startTime;
6254                 }
6255                 else
6256                 {
6257                         return null;
6258                 }
6259         }
6260
6261         function get_text()
6262         {
6263                 if ($this->text !== null)
6264                 {
6265                         return $this->text;
6266                 }
6267                 else
6268                 {
6269                         return null;
6270                 }
6271         }
6272
6273         function get_type()
6274         {
6275                 if ($this->type !== null)
6276                 {
6277                         return $this->type;
6278                 }
6279                 else
6280                 {
6281                         return null;
6282                 }
6283         }
6284 }
6285
6286 class SimplePie_Credit
6287 {
6288         var $role;
6289         var $scheme;
6290         var $name;
6291
6292         // Constructor, used to input the data
6293         function SimplePie_Credit($role = null, $scheme = null, $name = null)
6294         {
6295                 $this->role = $role;
6296                 $this->scheme = $scheme;
6297                 $this->name = $name;
6298         }
6299
6300         function __toString()
6301         {
6302                 // There is no $this->data here
6303                 return md5(serialize($this));
6304         }
6305
6306         function get_role()
6307         {
6308                 if ($this->role !== null)
6309                 {
6310                         return $this->role;
6311                 }
6312                 else
6313                 {
6314                         return null;
6315                 }
6316         }
6317
6318         function get_scheme()
6319         {
6320                 if ($this->scheme !== null)
6321                 {
6322                         return $this->scheme;
6323                 }
6324                 else
6325                 {
6326                         return null;
6327                 }
6328         }
6329
6330         function get_name()
6331         {
6332                 if ($this->name !== null)
6333                 {
6334                         return $this->name;
6335                 }
6336                 else
6337                 {
6338                         return null;
6339                 }
6340         }
6341 }
6342
6343 class SimplePie_Copyright
6344 {
6345         var $url;
6346         var $label;
6347
6348         // Constructor, used to input the data
6349         function SimplePie_Copyright($url = null, $label = null)
6350         {
6351                 $this->url = $url;
6352                 $this->label = $label;
6353         }
6354
6355         function __toString()
6356         {
6357                 // There is no $this->data here
6358                 return md5(serialize($this));
6359         }
6360
6361         function get_url()
6362         {
6363                 if ($this->url !== null)
6364                 {
6365                         return $this->url;
6366                 }
6367                 else
6368                 {
6369                         return null;
6370                 }
6371         }
6372
6373         function get_attribution()
6374         {
6375                 if ($this->label !== null)
6376                 {
6377                         return $this->label;
6378                 }
6379                 else
6380                 {
6381                         return null;
6382                 }
6383         }
6384 }
6385
6386 class SimplePie_Rating
6387 {
6388         var $scheme;
6389         var $value;
6390
6391         // Constructor, used to input the data
6392         function SimplePie_Rating($scheme = null, $value = null)
6393         {
6394                 $this->scheme = $scheme;
6395                 $this->value = $value;
6396         }
6397
6398         function __toString()
6399         {
6400                 // There is no $this->data here
6401                 return md5(serialize($this));
6402         }
6403
6404         function get_scheme()
6405         {
6406                 if ($this->scheme !== null)
6407                 {
6408                         return $this->scheme;
6409                 }
6410                 else
6411                 {
6412                         return null;
6413                 }
6414         }
6415
6416         function get_value()
6417         {
6418                 if ($this->value !== null)
6419                 {
6420                         return $this->value;
6421                 }
6422                 else
6423                 {
6424                         return null;
6425                 }
6426         }
6427 }
6428
6429 class SimplePie_Restriction
6430 {
6431         var $relationship;
6432         var $type;
6433         var $value;
6434
6435         // Constructor, used to input the data
6436         function SimplePie_Restriction($relationship = null, $type = null, $value = null)
6437         {
6438                 $this->relationship = $relationship;
6439                 $this->type = $type;
6440                 $this->value = $value;
6441         }
6442
6443         function __toString()
6444         {
6445                 // There is no $this->data here
6446                 return md5(serialize($this));
6447         }
6448
6449         function get_relationship()
6450         {
6451                 if ($this->relationship !== null)
6452                 {
6453                         return $this->relationship;
6454                 }
6455                 else
6456                 {
6457                         return null;
6458                 }
6459         }
6460
6461         function get_type()
6462         {
6463                 if ($this->type !== null)
6464                 {
6465                         return $this->type;
6466                 }
6467                 else
6468                 {
6469                         return null;
6470                 }
6471         }
6472
6473         function get_value()
6474         {
6475                 if ($this->value !== null)
6476                 {
6477                         return $this->value;
6478                 }
6479                 else
6480                 {
6481                         return null;
6482                 }
6483         }
6484 }
6485
6486 /**
6487  * @todo Move to properly supporting RFC2616 (HTTP/1.1)
6488  */
6489 class SimplePie_File
6490 {
6491         var $url;
6492         var $useragent;
6493         var $success = true;
6494         var $headers = array();
6495         var $body;
6496         var $status_code;
6497         var $redirects = 0;
6498         var $error;
6499         var $method;
6500
6501         function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
6502         {
6503                 if (class_exists('idna_convert'))
6504                 {
6505                         $idn =& new idna_convert;
6506                         $parsed = SimplePie_Misc::parse_url($url);
6507                         $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6508                 }
6509                 $this->url = $url;
6510                 $this->useragent = $useragent;
6511                 if (preg_match('/^http(s)?:\/\//i', $url))
6512                 {
6513                         if ($useragent === null)
6514                         {
6515                                 $useragent = ini_get('user_agent');
6516                                 $this->useragent = $useragent;
6517                         }
6518                         if (!is_array($headers))
6519                         {
6520                                 $headers = array();
6521                         }
6522                         if (!$force_fsockopen && extension_loaded('curl'))
6523                         {
6524                                 $this->method = 'curl';
6525                                 $fp = curl_init();
6526                                 $headers2 = array();
6527                                 foreach ($headers as $key => $value)
6528                                 {
6529                                         $headers2[] = "$key: $value";
6530                                 }
6531                                 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
6532                                 {
6533                                         curl_setopt($fp, CURLOPT_ENCODING, '');
6534                                 }
6535                                 curl_setopt($fp, CURLOPT_URL, $url);
6536                                 curl_setopt($fp, CURLOPT_HEADER, 1);
6537                                 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
6538                                 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
6539                                 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
6540                                 curl_setopt($fp, CURLOPT_REFERER, $url);
6541                                 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
6542                                 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
6543                                 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
6544                                 {
6545                                         curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
6546                                         curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
6547                                 }
6548
6549                                 curl_setopt($fp, CURLOPT_SSL_VERIFYPEER, false); 
6550                                 curl_setopt($fp, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
6551
6552                                 $this->headers = curl_exec($fp);
6553                                 if (curl_errno($fp) == 23 || curl_errno($fp) == 61)
6554                                 {
6555                                         curl_setopt($fp, CURLOPT_ENCODING, 'none');
6556                                         $this->headers = curl_exec($fp);
6557                                 }
6558                                 if (curl_errno($fp))
6559                                 {
6560                                         $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
6561                                         $this->success = false;
6562                                 }
6563                                 else
6564                                 {
6565                                         $info = curl_getinfo($fp);
6566                                         curl_close($fp);
6567                                         $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
6568                                         $this->headers = array_pop($this->headers);
6569                                         $parser =& new SimplePie_HTTP_Parser($this->headers);
6570                                         if ($parser->parse())
6571                                         {
6572                                                 $this->headers = $parser->headers;
6573                                                 $this->body = $parser->body;
6574                                                 $this->status_code = $parser->status_code;
6575                                                 if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
6576                                                 {
6577                                                         $this->redirects++;
6578                                                         if (isset($this->headers['content-location']))
6579                                                         {
6580                                                                 $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
6581                                                         }
6582                                                         else
6583                                                         {
6584                                                                 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
6585                                                         }
6586                                                         return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
6587                                                 }
6588                                         }
6589                                 }
6590                         }
6591                         else
6592                         {
6593                                 $this->method = 'fsockopen';
6594                                 $url_parts = parse_url($url);
6595                                 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) == 'https')
6596                                 {
6597                                         $url_parts['host'] = "ssl://$url_parts[host]";
6598                                         $url_parts['port'] = 443;
6599                                 }
6600                                 if (!isset($url_parts['port']))
6601                                 {
6602                                         $url_parts['port'] = 80;
6603                                 }
6604                                 $fp = fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
6605                                 if (!$fp)
6606                                 {
6607                                         $this->error = 'fsockopen error: ' . $errstr;
6608                                         $this->success = false;
6609                                 }
6610                                 else
6611                                 {
6612                                         if (function_exists('stream_set_timeout'))
6613                                         {
6614                                                 stream_set_timeout($fp, $timeout);
6615                                         }
6616                                         else
6617                                         {
6618                                                 socket_set_timeout($fp, $timeout);
6619                                         }
6620                                         if (isset($url_parts['path']))
6621                                         {
6622                                                 if (isset($url_parts['query']))
6623                                                 {
6624                                                         $get = "$url_parts[path]?$url_parts[query]";
6625                                                 }
6626                                                 else
6627                                                 {
6628                                                         $get = $url_parts['path'];
6629                                                 }
6630                                         }
6631                                         else
6632                                         {
6633                                                 $get = '/';
6634                                         }
6635                                         $out = "GET $get HTTP/1.0\r\n";
6636                                         $out .= "Host: $url_parts[host]\r\n";
6637                                         $out .= "User-Agent: $useragent\r\n";
6638                                         if (function_exists('gzinflate'))
6639                                         {
6640                                                 $out .= "Accept-Encoding: gzip,deflate\r\n";
6641                                         }
6642
6643                                         if (isset($url_parts['user']) && isset($url_parts['pass']))
6644                                         {
6645                                                 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
6646                                         }
6647                                         foreach ($headers as $key => $value)
6648                                         {
6649                                                 $out .= "$key: $value\r\n";
6650                                         }
6651                                         $out .= "Connection: Close\r\n\r\n";
6652                                         fwrite($fp, $out);
6653
6654                                         if (function_exists('stream_get_meta_data'))
6655                                         {
6656                                                 $info = stream_get_meta_data($fp);
6657                                         }
6658                                         else
6659                                         {
6660                                                 $info = socket_get_status($fp);
6661                                         }
6662
6663                                         $this->headers = '';
6664                                         while (!$info['eof'] && !$info['timed_out'])
6665                                         {
6666                                                 $this->headers .= fread($fp, 1160);
6667                                                 if (function_exists('stream_get_meta_data'))
6668                                                 {
6669                                                         $info = stream_get_meta_data($fp);
6670                                                 }
6671                                                 else
6672                                                 {
6673                                                         $info = socket_get_status($fp);
6674                                                 }
6675                                         }
6676                                         if (!$info['timed_out'])
6677                                         {
6678                                                 $parser =& new SimplePie_HTTP_Parser($this->headers);
6679                                                 if ($parser->parse())
6680                                                 {
6681                                                         $this->headers = $parser->headers;
6682                                                         $this->body = $parser->body;
6683                                                         $this->status_code = $parser->status_code;
6684                                                         if (($this->status_code == 300 || $this->status_code == 301 || $this->status_code == 302 || $this->status_code == 303 || $this->status_code == 307 || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
6685                                                         {
6686                                                                 $this->redirects++;
6687                                                                 if (isset($this->headers['content-location']))
6688                                                                 {
6689                                                                         $location = SimplePie_Misc::absolutize_url($this->headers['location'], SimplePie_Misc::absolutize_url($this->headers['content-location'], $url));
6690                                                                 }
6691                                                                 else
6692                                                                 {
6693                                                                         $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
6694                                                                 }
6695                                                                 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
6696                                                         }
6697                                                         if (isset($this->headers['content-encoding']) && ($this->headers['content-encoding'] == 'gzip' || $this->headers['content-encoding'] == 'deflate'))
6698                                                         {
6699                                                                 if (substr($this->body, 0, 8) == "\x1f\x8b\x08\x00\x00\x00\x00\x00")
6700                                                                 {
6701                                                                         $this->body = substr($this->body, 10);
6702                                                                 }
6703                                                                 $this->body = gzinflate($this->body);
6704                                                         }
6705                                                 }
6706                                         }
6707                                         else
6708                                         {
6709                                                 $this->error = 'fsocket timed out';
6710                                                 $this->success = false;
6711                                         }
6712                                         fclose($fp);
6713                                 }
6714                         }
6715                 }
6716                 elseif (function_exists('file_get_contents'))
6717                 {
6718                         $this->method = 'file_get_contents';
6719                         if (!$this->body = file_get_contents($url))
6720                         {
6721                                 $this->error = 'file_get_contents could not read the file';
6722                                 $this->success = false;
6723                         }
6724                 }
6725                 else
6726                 {
6727                         $this->method = 'fopen';
6728                         if (($fp = fopen($url, 'rb')) === false)
6729                         {
6730                                 $this->error = 'failed to open stream: No such file or directory';
6731                                 $this->success = false;
6732                         }
6733                         else
6734                         {
6735                                 $this->body = '';
6736                                 while (!feof($fp))
6737                                 {
6738                                         $this->body .= fread($fp, 8192);
6739                                 }
6740                                 fclose($fp);
6741                         }
6742                 }
6743         }
6744 }
6745
6746 /**
6747  * HTTP Response Parser
6748  *
6749  * @package SimplePie
6750  * @todo Support HTTP Requests
6751  */
6752 class SimplePie_HTTP_Parser
6753 {
6754         /**
6755          * HTTP Version
6756          *
6757          * @access public
6758          * @var string
6759          */
6760         var $http_version = '';
6761
6762         /**
6763          * Status code
6764          *
6765          * @access public
6766          * @var string
6767          */
6768         var $status_code = '';
6769
6770         /**
6771          * Reason phrase
6772          *
6773          * @access public
6774          * @var string
6775          */
6776         var $reason = '';
6777
6778         /**
6779          * Key/value pairs of the headers
6780          *
6781          * @access public
6782          * @var array
6783          */
6784         var $headers = array();
6785
6786         /**
6787          * Body of the response
6788          *
6789          * @access public
6790          * @var string
6791          */
6792         var $body = '';
6793
6794         /**
6795          * Current state of the state machine
6796          *
6797          * @access private
6798          * @var string
6799          */
6800         var $state = 'start';
6801
6802         /**
6803          * Input data
6804          *
6805          * @access private
6806          * @var string
6807          */
6808         var $data = '';
6809
6810         /**
6811          * Input data length (to avoid calling strlen() everytime this is needed)
6812          *
6813          * @access private
6814          * @var int
6815          */
6816         var $data_length = 0;
6817
6818         /**
6819          * Current position of the pointer
6820          *
6821          * @access private
6822          * @var int
6823          */
6824         var $position = 0;
6825
6826         /**
6827          * Name of the hedaer currently being parsed
6828          *
6829          * @access private
6830          * @var string
6831          */
6832         var $name = '';
6833
6834         /**
6835          * Value of the hedaer currently being parsed
6836          *
6837          * @access private
6838          * @var string
6839          */
6840         var $value = '';
6841
6842         /**
6843          * Create an instance of the class with the input data
6844          *
6845          * @access public
6846          * @param string $data Input data
6847          */
6848         function SimplePie_HTTP_Parser($data)
6849         {
6850                 $this->data = $data;
6851                 $this->data_length = strlen($this->data);
6852         }
6853
6854         /**
6855          * Parse the input data
6856          *
6857          * @access public
6858          * @return bool true on success, false on failure
6859          */
6860         function parse()
6861         {
6862                 while ($this->state && $this->state != 'emit' && $this->has_data())
6863                 {
6864                         $state = $this->state;
6865                         $this->$state();
6866                 }
6867                 $this->data = '';
6868                 if ($this->state == 'emit')
6869                 {
6870                         return true;
6871                 }
6872                 else
6873                 {
6874                         $this->http_version = '';
6875                         $this->status_code = '';
6876                         $this->headers = array();
6877                         $this->body = '';
6878                         return false;
6879                 }
6880         }
6881
6882         /**
6883          * Check whether there is data beyond the pointer
6884          *
6885          * @access private
6886          * @return bool true if there is further data, false if not
6887          */
6888         function has_data()
6889         {
6890                 return (bool) ($this->position < $this->data_length);
6891         }
6892
6893         /**
6894          * See if the next character is LWS
6895          *
6896          * @access private
6897          * @return bool true if the next character is LWS, false if not
6898          */
6899         function is_linear_whitespace()
6900         {
6901                 return (bool) (strspn($this->data, "\x09\x20", $this->position, 1)
6902                         || (substr($this->data, $this->position, 2) == "\r\n" && strspn($this->data, "\x09\x20", $this->position + 2, 1))
6903                         || (strspn($this->data, "\r\n", $this->position, 1) && strspn($this->data, "\x09\x20", $this->position + 1, 1)));
6904         }
6905
6906         /**
6907          * The starting state of the state machine, see if the data is a response or request
6908          *
6909          * @access private
6910          */
6911         function start()
6912         {
6913                 $this->state = 'http_version_response';
6914         }
6915
6916         /**
6917          * Parse an HTTP-version string
6918          *
6919          * @access private
6920          */
6921         function http_version()
6922         {
6923                 if (preg_match('/^HTTP\/([0-9]+\.[0-9]+)/i', substr($this->data, $this->position, strcspn($this->data, "\r\n", $this->position)), $match))
6924                 {
6925                         $this->position += strlen($match[0]);
6926                         $this->http_version = $match[1];
6927                         return true;
6928                 }
6929                 else
6930                 {
6931                         return false;
6932                 }
6933         }
6934
6935         /**
6936          * Parse LWS, replacing consecutive characters with a single space
6937          *
6938          * @access private
6939          */
6940         function linear_whitespace()
6941         {
6942                 do
6943                 {
6944                         if (substr($this->data, $this->position, 2) == "\r\n")
6945                         {
6946                                 $this->position += 2;
6947                         }
6948                         elseif (strspn($this->data, "\r\n", $this->position, 1))
6949                         {
6950                                 $this->position++;
6951                         }
6952                         $this->position += strspn($this->data, "\x09\x20", $this->position);
6953                 } while ($this->is_linear_whitespace());
6954                 $this->value .= "\x20";
6955         }
6956
6957         /**
6958          * Parse an HTTP-version string within a response
6959          *
6960          * @access private
6961          */
6962         function http_version_response()
6963         {
6964                 if ($this->http_version() && $this->data[$this->position] == "\x20")
6965                 {
6966                         $this->state = 'status_code';
6967                         $this->position++;
6968                 }
6969                 else
6970                 {
6971                         $this->state = false;
6972                 }
6973         }
6974
6975         /**
6976          * Parse a status code
6977          *
6978          * @access private
6979          */
6980         function status_code()
6981         {
6982                 if (strspn($this->data, '1234567890', $this->position, 3) == 3)
6983                 {
6984                         $this->status_code = substr($this->data, $this->position, 3);
6985                         $this->state = 'reason_phrase';
6986                         $this->position += 3;
6987                 }
6988                 else
6989                 {
6990                         $this->state = false;
6991                 }
6992         }
6993
6994         /**
6995          * Skip over the reason phrase (it has no normative value, and you can send absolutely anything here)
6996          *
6997          * @access private
6998          */
6999         function reason_phrase()
7000         {
7001                 $len = strcspn($this->data, "\r\n", $this->position);
7002                 $this->reason = substr($this->data, $this->position, $len);
7003                 $this->position += $len;
7004                 if ($this->has_data())
7005                 {
7006                         if (substr($this->data, $this->position, 2) == "\r\n")
7007                         {
7008                                 $this->position += 2;
7009                         }
7010                         elseif (strspn($this->data, "\r\n", $this->position, 1))
7011                         {
7012                                 $this->position++;
7013                         }
7014                         $this->state = 'name';
7015                 }
7016         }
7017
7018         /**
7019          * Parse a header name
7020          *
7021          * @access private
7022          */
7023         function name()
7024         {
7025                 $len = strcspn($this->data, ':', $this->position);
7026                 $this->name = substr($this->data, $this->position, $len);
7027                 $this->position += $len;
7028
7029                 if ($this->has_data() && $this->data[$this->position] == ':')
7030                 {
7031                         $this->state = 'value_next';
7032                         $this->position++;
7033                 }
7034                 else
7035                 {
7036                         $this->state = false;
7037                 }
7038         }
7039
7040         /**
7041          * See what state to move the state machine to while within non-quoted header values
7042          *
7043          * @access private
7044          */
7045         function value_next()
7046         {
7047                 if ($this->is_linear_whitespace())
7048                 {
7049                         $this->state = 'value_linear_whitespace';
7050                 }
7051                 elseif ($this->data[$this->position] == '"')
7052                 {
7053                         $this->state = 'value_quote_next';
7054                         $this->position++;
7055                 }
7056                 elseif (substr($this->data, $this->position, 2) == "\r\n")
7057                 {
7058                         $this->state = 'end_crlf';
7059                         $this->position += 2;
7060                 }
7061                 elseif (strspn($this->data, "\r\n", $this->position, 1))
7062                 {
7063                         $this->state = 'end_crlf';
7064                         $this->position++;
7065                 }
7066                 else
7067                 {
7068                         $this->state = 'value_no_quote';
7069                 }
7070         }
7071
7072         /**
7073          * Parse a header value while outside quotes
7074          *
7075          * @access private
7076          */
7077         function value_no_quote()
7078         {
7079                 $len = strcspn($this->data, "\x09\x20\r\n\"", $this->position);
7080                 $this->value .= substr($this->data, $this->position, $len);
7081                 $this->state = 'value_next';
7082                 $this->position += $len;
7083         }
7084
7085         /**
7086          * Parse LWS outside quotes
7087          *
7088          * @access private
7089          */
7090         function value_linear_whitespace()
7091         {
7092                 $this->linear_whitespace();
7093                 $this->state = 'value_next';
7094         }
7095
7096         /**
7097          * See what state to move the state machine to while within quoted header values
7098          *
7099          * @access private
7100          */
7101         function value_quote_next()
7102         {
7103                 if ($this->is_linear_whitespace())
7104                 {
7105                         $this->state = 'value_linear_whitespace_quote';
7106                 }
7107                 else
7108                 {
7109                         switch ($this->data[$this->position])
7110                         {
7111                                 case '"':
7112                                         $this->state = 'value_next';
7113                                         $this->position++;
7114                                         break;
7115
7116                                 case '\\':
7117                                         $this->state = 'value_quote_char';
7118                                         $this->position++;
7119                                         break;
7120
7121                                 default:
7122                                         $this->state = 'value_quote';
7123                                         break;
7124                         }
7125                 }
7126         }
7127
7128         /**
7129          * Parse a header value while within quotes
7130          *
7131          * @access private
7132          */
7133         function value_quote()
7134         {
7135                 $len = strcspn($this->data, "\x09\x20\r\n\"\\", $this->position);
7136                 $this->value .= substr($this->data, $this->position, $len);
7137                 $this->position += $len;
7138                 $this->state = 'value_quote_next';
7139         }
7140
7141         /**
7142          * Parse an escaped character within quotes
7143          *
7144          * @access private
7145          */
7146         function value_quote_char()
7147         {
7148                 $this->value .= $this->data[$this->position];
7149                 $this->state = 'value_quote_next';
7150                 $this->position++;
7151         }
7152
7153         /**
7154          * Parse LWS within quotes
7155          *
7156          * @access private
7157          */
7158         function value_linear_whitespace_quote()
7159         {
7160                 $this->linear_whitespace();
7161                 $this->state = 'value_quote_next';
7162         }
7163
7164         /**
7165          * Parse a CRLF, and see whether we have a further header, or whether we are followed by the body
7166          *
7167          * @access private
7168          */
7169         function end_crlf()
7170         {
7171                 $this->name = strtolower($this->name);
7172                 $this->value = trim($this->value, "\x20");
7173                 if (isset($this->headers[$this->name]))
7174                 {
7175                         $this->headers[$this->name] .= ', ' . $this->value;
7176                 }
7177                 else
7178                 {
7179                         $this->headers[$this->name] = $this->value;
7180                 }
7181
7182                 if (substr($this->data, $this->position, 2) == "\r\n")
7183                 {
7184                         $this->body = substr($this->data, $this->position + 2);
7185                         $this->state = 'emit';
7186                 }
7187                 elseif (strspn($this->data, "\r\n", $this->position, 1))
7188                 {
7189                         $this->body = substr($this->data, $this->position + 1);
7190                         $this->state = 'emit';
7191                 }
7192                 else
7193                 {
7194                         $this->name = '';
7195                         $this->value = '';
7196                         $this->state = 'name';
7197                 }
7198         }
7199 }
7200
7201 class SimplePie_Cache
7202 {
7203         var $location;
7204         var $filename;
7205         var $extension;
7206         var $name;
7207
7208         function SimplePie_Cache($location, $filename, $extension)
7209         {
7210                 $this->location = $location;
7211                 $this->filename = rawurlencode($filename);
7212                 $this->extension = rawurlencode($extension);
7213                 $this->name = "$location/$this->filename.$this->extension";
7214         }
7215
7216         function save($data)
7217         {
7218                 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
7219                 {
7220                         if (function_exists('file_put_contents'))
7221                         {
7222                                 return (bool) file_put_contents($this->name, serialize($data));
7223                         }
7224                         else
7225                         {
7226                                 $fp = fopen($this->name, 'wb');
7227                                 if ($fp)
7228                                 {
7229                                         fwrite($fp, serialize($data));
7230                                         fclose($fp);
7231                                         return true;
7232                                 }
7233                         }
7234                 }
7235                 return false;
7236         }
7237
7238         function load()
7239         {
7240                 if (file_exists($this->name) && is_readable($this->name))
7241                 {
7242                         if (function_exists('file_get_contents'))
7243                         {
7244                                 return unserialize(file_get_contents($this->name));
7245                         }
7246                         elseif (($fp = fopen($this->name, 'rb')) !== false)
7247                         {
7248                                 $data = '';
7249                                 while (!feof($fp))
7250                                 {
7251                                         $data .= fread($fp, 8192);
7252                                 }
7253                                 fclose($fp);
7254                                 return unserialize($data);
7255                         }
7256                 }
7257                 return false;
7258         }
7259
7260         function mtime()
7261         {
7262                 if (file_exists($this->name))
7263                 {
7264                         return filemtime($this->name);
7265                 }
7266                 return false;
7267         }
7268
7269         function touch()
7270         {
7271                 if (file_exists($this->name))
7272                 {
7273                         return touch($this->name);
7274                 }
7275                 return false;
7276         }
7277
7278         function unlink()
7279         {
7280                 if (file_exists($this->name))
7281                 {
7282                         return unlink($this->name);
7283                 }
7284                 return false;
7285         }
7286 }
7287
7288 class SimplePie_Misc
7289 {
7290         function time_hms($seconds)
7291         {
7292                 $time = '';
7293
7294                 $hours = floor($seconds / 3600);
7295                 $remainder = $seconds % 3600;
7296                 if ($hours > 0)
7297                 {
7298                         $time .= $hours.':';
7299                 }
7300
7301                 $minutes = floor($remainder / 60);
7302                 $seconds = $remainder % 60;
7303                 if ($minutes < 10 && $hours > 0)
7304                 {
7305                         $minutes = '0' . $minutes;
7306                 }
7307                 if ($seconds < 10)
7308                 {
7309                         $seconds = '0' . $seconds;
7310                 }
7311
7312                 $time .= $minutes.':';
7313                 $time .= $seconds;
7314
7315                 return $time;
7316         }
7317
7318         function absolutize_url($relative, $base)
7319         {
7320                 if ($relative !== '')
7321                 {
7322                         $relative = SimplePie_Misc::parse_url($relative);
7323                         if ($relative['scheme'] !== '')
7324                         {
7325                                 $target = $relative;
7326                         }
7327                         elseif ($base !== '')
7328                         {
7329                                 $base = SimplePie_Misc::parse_url($base);
7330                                 $target = SimplePie_Misc::parse_url('');
7331                                 if ($relative['authority'] !== '')
7332                                 {
7333                                         $target = $relative;
7334                                         $target['scheme'] = $base['scheme'];
7335                                 }
7336                                 else
7337                                 {
7338                                         $target['scheme'] = $base['scheme'];
7339                                         $target['authority'] = $base['authority'];
7340                                         if ($relative['path'] !== '')
7341                                         {
7342                                                 if (strpos($relative['path'], '/') === 0)
7343                                                 {
7344                                                         $target['path'] = $relative['path'];
7345                                                 }
7346                                                 elseif (($target['path'] = dirname("$base[path].")) == '/')
7347                                                 {
7348                                                         $target['path'] .= $relative['path'];
7349                                                 }
7350                                                 else
7351                                                 {
7352                                                         $target['path'] .= '/' . $relative['path'];
7353                                                 }
7354                                                 if ($relative['query'] !== '')
7355                                                 {
7356                                                         $target['query'] = $relative['query'];
7357                                                 }
7358                                         }
7359                                         else
7360                                         {
7361                                                 if ($base['path'] !== '')
7362                                                 {
7363                                                         $target['path'] = $base['path'];
7364                                                 }
7365                                                 else
7366                                                 {
7367                                                         $target['path'] = '/';
7368                                                 }
7369                                                 if ($relative['query'] !== '')
7370                                                 {
7371                                                         $target['query'] = $relative['query'];
7372                                                 }
7373                                                 elseif ($base['query'] !== '')
7374                                                 {
7375                                                         $target['query'] = $base['query'];
7376                                                 }
7377                                         }
7378                                 }
7379                                 if ($relative['fragment'] !== '')
7380                                 {
7381                                         $target['fragment'] = $relative['fragment'];
7382                                 }
7383                         }
7384                         else
7385                         {
7386                                 // No base URL, just return the relative URL
7387                                 $target = $relative;
7388                         }
7389                         $return = SimplePie_Misc::compress_parse_url($target['scheme'], $target['authority'], $target['path'], $target['query'], $target['fragment']);
7390                 }
7391                 else
7392                 {
7393                         $return = $base;
7394                 }
7395                 $return = SimplePie_Misc::normalize_url($return);
7396                 return $return;
7397         }
7398
7399         function remove_dot_segments($input)
7400         {
7401                 $output = '';
7402                 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input == '.' || $input == '..')
7403                 {
7404                         // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
7405                         if (strpos($input, '../') === 0)
7406                         {
7407                                 $input = substr($input, 3);
7408                         }
7409                         elseif (strpos($input, './') === 0)
7410                         {
7411                                 $input = substr($input, 2);
7412                         }
7413                         // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
7414                         elseif (strpos($input, '/./') === 0)
7415                         {
7416                                 $input = substr_replace($input, '/', 0, 3);
7417                         }
7418                         elseif ($input == '/.')
7419                         {
7420                                 $input = '/';
7421                         }
7422                         // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
7423                         elseif (strpos($input, '/../') === 0)
7424                         {
7425                                 $input = substr_replace($input, '/', 0, 4);
7426                                 $output = substr_replace($output, '', strrpos($output, '/'));
7427                         }
7428                         elseif ($input == '/..')
7429                         {
7430                                 $input = '/';
7431                                 $output = substr_replace($output, '', strrpos($output, '/'));
7432                         }
7433                         // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
7434                         elseif ($input == '.' || $input == '..')
7435                         {
7436                                 $input = '';
7437                         }
7438                         // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
7439                         elseif (($pos = strpos($input, '/', 1)) !== false)
7440                         {
7441                                 $output .= substr($input, 0, $pos);
7442                                 $input = substr_replace($input, '', 0, $pos);
7443                         }
7444                         else
7445                         {
7446                                 $output .= $input;
7447                                 $input = '';
7448                         }
7449                 }
7450                 return $output . $input;
7451         }
7452
7453         function get_element($realname, $string)
7454         {
7455                 $return = array();
7456                 $name = preg_quote($realname, '/');
7457                 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
7458                 {
7459                         for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
7460                         {
7461                                 $return[$i]['tag'] = $realname;
7462                                 $return[$i]['full'] = $matches[$i][0][0];
7463                                 $return[$i]['offset'] = $matches[$i][0][1];
7464                                 if (strlen($matches[$i][3][0]) <= 2)
7465                                 {
7466                                         $return[$i]['self_closing'] = true;
7467                                 }
7468                                 else
7469                                 {
7470                                         $return[$i]['self_closing'] = false;
7471                                         $return[$i]['content'] = $matches[$i][4][0];
7472                                 }
7473                                 $return[$i]['attribs'] = array();
7474                                 if (isset($matches[$i][2][0]) && preg_match_all('/((?:[^\s:]+:)?[^\s:]+)(?:\s*=\s*(?:"([^"]*)"|\'([^\']*)\'|([a-z0-9\-._:]*)))?\s/U', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
7475                                 {
7476                                         for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
7477                                         {
7478                                                 if (count($attribs[$j]) == 2)
7479                                                 {
7480                                                         $attribs[$j][2] = $attribs[$j][1];
7481                                                 }
7482                                                 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
7483                                         }
7484                                 }
7485                         }
7486                 }
7487                 return $return;
7488         }
7489
7490         function element_implode($element)
7491         {
7492                 $full = "<$element[tag]";
7493                 foreach ($element['attribs'] as $key => $value)
7494                 {
7495                         $key = strtolower($key);
7496                         $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
7497                 }
7498                 if ($element['self_closing'])
7499                 {
7500                         $full .= ' />';
7501                 }
7502                 else
7503                 {
7504                         $full .= ">$element[content]</$element[tag]>";
7505                 }
7506                 return $full;
7507         }
7508
7509         function error($message, $level, $file, $line)
7510         {
7511                 switch ($level)
7512                 {
7513                         case E_USER_ERROR:
7514                                 $note = 'PHP Error';
7515                                 break;
7516                         case E_USER_WARNING:
7517                                 $note = 'PHP Warning';
7518                                 break;
7519                         case E_USER_NOTICE:
7520                                 $note = 'PHP Notice';
7521                                 break;
7522                         default:
7523                                 $note = 'Unknown Error';
7524                                 break;
7525                 }
7526                 error_log("$note: $message in $file on line $line", 0);
7527                 return $message;
7528         }
7529
7530         /**
7531          * If a file has been cached, retrieve and display it.
7532          *
7533          * This is most useful for caching images (get_favicon(), etc.),
7534          * however it works for all cached files.  This WILL NOT display ANY
7535          * file/image/page/whatever, but rather only display what has already
7536          * been cached by SimplePie.
7537          *
7538          * @access public
7539          * @see SimplePie::get_favicon()
7540          * @param str $identifier_url URL that is used to identify the content.
7541          * This may or may not be the actual URL of the live content.
7542          * @param str $cache_location Location of SimplePie's cache.  Defaults
7543          * to './cache'.
7544          * @param str $cache_extension The file extension that the file was
7545          * cached with.  Defaults to 'spc'.
7546          * @param str $cache_class Name of the cache-handling class being used
7547          * in SimplePie.  Defaults to 'SimplePie_Cache', and should be left
7548          * as-is unless you've overloaded the class.
7549          * @param str $cache_name_function Function that converts the filename
7550          * for saving.  Defaults to 'md5'.
7551          */
7552         function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
7553         {
7554                 $cache =& new $cache_class($cache_location, call_user_func($cache_name_function, $identifier_url), $cache_extension);
7555
7556                 if ($file = $cache->load())
7557                 {
7558                         header('Content-type:' . $file['headers']['content-type']);
7559                         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
7560                         echo $file['body'];
7561                         exit;
7562                 }
7563
7564                 die('Cached file for ' . $identifier_url . ' cannot be found.');
7565         }
7566
7567         function fix_protocol($url, $http = 1)
7568         {
7569                 $url = SimplePie_Misc::normalize_url($url);
7570                 $parsed = SimplePie_Misc::parse_url($url);
7571                 if ($parsed['scheme'] !== '' && $parsed['scheme'] != 'http' && $parsed['scheme'] != 'https')
7572                 {
7573                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
7574                 }
7575                 
7576                 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
7577                 {
7578                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
7579                 }
7580
7581                 if ($http == 2 && $parsed['scheme'] !== '')
7582                 {
7583                         return "feed:$url";
7584                 }
7585                 elseif ($http == 3 && strtolower($parsed['scheme']) == 'http')
7586                 {
7587                         return substr_replace($url, 'podcast', 0, 4);
7588                 }
7589                 elseif ($http == 4 && strtolower($parsed['scheme']) == 'http')
7590                 {
7591                         return substr_replace($url, 'itpc', 0, 4);
7592                 }
7593                 else
7594                 {
7595                         return $url;
7596                 }
7597         }
7598
7599         function parse_url($url)
7600         {
7601                 static $cache = array();
7602                 if (isset($cache[$url]))
7603                 {
7604                         return $cache[$url];
7605                 }
7606                 elseif (preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $url, $match))
7607                 {
7608                         for ($i = count($match); $i <= 9; $i++)
7609                         {
7610                                 $match[$i] = '';
7611                         }
7612                         return $cache[$url] = array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
7613                 }
7614                 else
7615                 {
7616                         return $cache[$url] = array('scheme' => '', 'authority' => '', 'path' => '', 'query' => '', 'fragment' => '');
7617                 }
7618         }
7619
7620         function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
7621         {
7622                 $return = '';
7623                 if ($scheme !== '')
7624                 {
7625                         $return .= "$scheme:";
7626                 }
7627                 if ($authority !== '')
7628                 {
7629                         $return .= "//$authority";
7630                 }
7631                 if ($path !== '')
7632                 {
7633                         $return .= $path;
7634                 }
7635                 if ($query !== '')
7636                 {
7637                         $return .= "?$query";
7638                 }
7639                 if ($fragment !== '')
7640                 {
7641                         $return .= "#$fragment";
7642                 }
7643                 return $return;
7644         }
7645
7646         function normalize_url($url)
7647         {
7648                 $url = preg_replace_callback('/%([0-9A-Fa-f]{2})/', array('SimplePie_Misc', 'percent_encoding_normalization'), $url);
7649                 $url = SimplePie_Misc::parse_url($url);
7650                 $url['scheme'] = strtolower($url['scheme']);
7651                 if ($url['authority'] !== '')
7652                 {
7653                         $url['authority'] = strtolower($url['authority']);
7654                         $url['path'] = SimplePie_Misc::remove_dot_segments($url['path']);
7655                 }
7656                 return SimplePie_Misc::compress_parse_url($url['scheme'], $url['authority'], $url['path'], $url['query'], $url['fragment']);
7657         }
7658
7659         function percent_encoding_normalization($match)
7660         {
7661                 $integer = hexdec($match[1]);
7662                 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer == 0x2D || $integer == 0x2E || $integer == 0x5F || $integer == 0x7E)
7663                 {
7664                         return chr($integer);
7665                 }
7666                 else
7667                 {
7668                         return strtoupper($match[0]);
7669                 }
7670         }
7671
7672         /**
7673          * Remove bad UTF-8 bytes
7674          *
7675          * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
7676          * FAQ: Multilingual Forms (modified to include full ASCII range)
7677          *
7678          * @author Geoffrey Sneddon
7679          * @see http://www.w3.org/International/questions/qa-forms-utf-8
7680          * @param string $str String to remove bad UTF-8 bytes from
7681          * @return string UTF-8 string
7682          */
7683         function utf8_bad_replace($str)
7684         {
7685                 if (function_exists('iconv'))
7686                 {
7687                         return iconv('UTF-8', 'UTF-8//IGNORE', $str);
7688                 }
7689                 elseif (function_exists('mb_convert_encoding'))
7690                 {
7691                         return mb_convert_encoding($str, 'UTF-8', 'UTF-8');
7692                 }
7693                 elseif (preg_match_all('/([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})/', $str, $matches))
7694                 {
7695                         return implode("\xEF\xBF\xBD", $matches[0]);
7696                 }
7697                 elseif ($str !== '')
7698                 {
7699                         return "\xEF\xBF\xBD";
7700                 }
7701                 else
7702                 {
7703                         return '';
7704                 }
7705         }
7706
7707         function change_encoding($data, $input, $output)
7708         {
7709                 $input = SimplePie_Misc::encoding($input);
7710                 $output = SimplePie_Misc::encoding($output);
7711
7712                 if (function_exists('iconv') && ($return = @iconv($input, "$output//IGNORE", $data)))
7713                 {
7714                         return $return;
7715                 }
7716                 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
7717                 {
7718                         return $return;
7719                 }
7720                 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($data, $output, $input)))
7721                 {
7722                         return $return;
7723                 }
7724                 elseif ($input == 'ISO-8859-1' && $output == 'UTF-8')
7725                 {
7726                         return utf8_encode($data);
7727                 }
7728                 elseif ($input == 'UTF-8' && $output == 'ISO-8859-1')
7729                 {
7730                         return utf8_decode($data);
7731                 }
7732                 return $data;
7733         }
7734
7735         function encoding($encoding)
7736         {
7737                 // Character sets are case-insensitive (though we'll return them in the form given in their registration)
7738                 switch (strtoupper($encoding))
7739                 {
7740                         case 'ANSI_X3.4-1968':
7741                         case 'ISO-IR-6':
7742                         case 'ANSI_X3.4-1986':
7743                         case 'ISO_646.IRV:1991':
7744                         case 'ASCII':
7745                         case 'ISO646-US':
7746                         case 'US-ASCII':
7747                         case 'US':
7748                         case 'IBM367':
7749                         case 'CP367':
7750                         case 'CSASCII':
7751                                 return 'US-ASCII';
7752
7753                         case 'ISO_8859-1:1987':
7754                         case 'ISO-IR-100':
7755                         case 'ISO_8859-1':
7756                         case 'ISO-8859-1':
7757                         case 'LATIN1':
7758                         case 'L1':
7759                         case 'IBM819':
7760                         case 'CP819':
7761                         case 'CSISOLATIN1':
7762                                 return 'ISO-8859-1';
7763
7764                         case 'ISO_8859-2:1987':
7765                         case 'ISO-IR-101':
7766                         case 'ISO_8859-2':
7767                         case 'ISO-8859-2':
7768                         case 'LATIN2':
7769                         case 'L2':
7770                         case 'CSISOLATIN2':
7771                                 return 'ISO-8859-2';
7772
7773                         case 'ISO_8859-3:1988':
7774                         case 'ISO-IR-109':
7775                         case 'ISO_8859-3':
7776                         case 'ISO-8859-3':
7777                         case 'LATIN3':
7778                         case 'L3':
7779                         case 'CSISOLATIN3':
7780                                 return 'ISO-8859-3';
7781
7782                         case 'ISO_8859-4:1988':
7783                         case 'ISO-IR-110':
7784                         case 'ISO_8859-4':
7785                         case 'ISO-8859-4':
7786                         case 'LATIN4':
7787                         case 'L4':
7788                         case 'CSISOLATIN4':
7789                                 return 'ISO-8859-4';
7790
7791                         case 'ISO_8859-5:1988':
7792                         case 'ISO-IR-144':
7793                         case 'ISO_8859-5':
7794                         case 'ISO-8859-5':
7795                         case 'CYRILLIC':
7796                         case 'CSISOLATINCYRILLIC':
7797                                 return 'ISO-8859-5';
7798
7799                         case 'ISO_8859-6:1987':
7800                         case 'ISO-IR-127':
7801                         case 'ISO_8859-6':
7802                         case 'ISO-8859-6':
7803                         case 'ECMA-114':
7804                         case 'ASMO-708':
7805                         case 'ARABIC':
7806                         case 'CSISOLATINARABIC':
7807                                 return 'ISO-8859-6';
7808
7809                         case 'ISO_8859-7:1987':
7810                         case 'ISO-IR-126':
7811                         case 'ISO_8859-7':
7812                         case 'ISO-8859-7':
7813                         case 'ELOT_928':
7814                         case 'ECMA-118':
7815                         case 'GREEK':
7816                         case 'GREEK8':
7817                         case 'CSISOLATINGREEK':
7818                                 return 'ISO-8859-7';
7819
7820                         case 'ISO_8859-8:1988':
7821                         case 'ISO-IR-138':
7822                         case 'ISO_8859-8':
7823                         case 'ISO-8859-8':
7824                         case 'HEBREW':
7825                         case 'CSISOLATINHEBREW':
7826                                 return 'ISO-8859-8';
7827
7828                         case 'ISO_8859-9:1989':
7829                         case 'ISO-IR-148':
7830                         case 'ISO_8859-9':
7831                         case 'ISO-8859-9':
7832                         case 'LATIN5':
7833                         case 'L5':
7834                         case 'CSISOLATIN5':
7835                                 return 'ISO-8859-9';
7836
7837                         case 'ISO-8859-10':
7838                         case 'ISO-IR-157':
7839                         case 'L6':
7840                         case 'ISO_8859-10:1992':
7841                         case 'CSISOLATIN6':
7842                         case 'LATIN6':
7843                                 return 'ISO-8859-10';
7844
7845                         case 'ISO_6937-2-ADD':
7846                         case 'ISO-IR-142':
7847                         case 'CSISOTEXTCOMM':
7848                                 return 'ISO_6937-2-add';
7849
7850                         case 'JIS_X0201':
7851                         case 'X0201':
7852                         case 'CSHALFWIDTHKATAKANA':
7853                                 return 'JIS_X0201';
7854
7855                         case 'JIS_ENCODING':
7856                         case 'CSJISENCODING':
7857                                 return 'JIS_Encoding';
7858
7859                         case 'SHIFT_JIS':
7860                         case 'MS_KANJI':
7861                         case 'CSSHIFTJIS':
7862                                 return 'Shift_JIS';
7863
7864                         case 'EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE':
7865                         case 'CSEUCPKDFMTJAPANESE':
7866                         case 'EUC-JP':
7867                                 return 'EUC-JP';
7868
7869                         case 'EXTENDED_UNIX_CODE_FIXED_WIDTH_FOR_JAPANESE':
7870                         case 'CSEUCFIXWIDJAPANESE':
7871                                 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
7872
7873                         case 'BS_4730':
7874                         case 'ISO-IR-4':
7875                         case 'ISO646-GB':
7876                         case 'GB':
7877                         case 'UK':
7878                         case 'CSISO4UNITEDKINGDOM':
7879                                 return 'BS_4730';
7880
7881                         case 'SEN_850200_C':
7882                         case 'ISO-IR-11':
7883                         case 'ISO646-SE2':
7884                         case 'SE2':
7885                         case 'CSISO11SWEDISHFORNAMES':
7886                                 return 'SEN_850200_C';
7887
7888                         case 'IT':
7889                         case 'ISO-IR-15':
7890                         case 'ISO646-IT':
7891                         case 'CSISO15ITALIAN':
7892                                 return 'IT';
7893
7894                         case 'ES':
7895                         case 'ISO-IR-17':
7896                         case 'ISO646-ES':
7897                         case 'CSISO17SPANISH':
7898                                 return 'ES';
7899
7900                         case 'DIN_66003':
7901                         case 'ISO-IR-21':
7902                         case 'DE':
7903                         case 'ISO646-DE':
7904                         case 'CSISO21GERMAN':
7905                                 return 'DIN_66003';
7906
7907                         case 'NS_4551-1':
7908                         case 'ISO-IR-60':
7909                         case 'ISO646-NO':
7910                         case 'NO':
7911                         case 'CSISO60DANISHNORWEGIAN':
7912                         case 'CSISO60NORWEGIAN1':
7913                                 return 'NS_4551-1';
7914
7915                         case 'NF_Z_62-010':
7916                         case 'ISO-IR-69':
7917                         case 'ISO646-FR':
7918                         case 'FR':
7919                         case 'CSISO69FRENCH':
7920                                 return 'NF_Z_62-010';
7921
7922                         case 'ISO-10646-UTF-1':
7923                         case 'CSISO10646UTF1':
7924                                 return 'ISO-10646-UTF-1';
7925
7926                         case 'ISO_646.BASIC:1983':
7927                         case 'REF':
7928                         case 'CSISO646BASIC1983':
7929                                 return 'ISO_646.basic:1983';
7930
7931                         case 'INVARIANT':
7932                         case 'CSINVARIANT':
7933                                 return 'INVARIANT';
7934
7935                         case 'ISO_646.IRV:1983':
7936                         case 'ISO-IR-2':
7937                         case 'IRV':
7938                         case 'CSISO2INTLREFVERSION':
7939                                 return 'ISO_646.irv:1983';
7940
7941                         case 'NATS-SEFI':
7942                         case 'ISO-IR-8-1':
7943                         case 'CSNATSSEFI':
7944                                 return 'NATS-SEFI';
7945
7946                         case 'NATS-SEFI-ADD':
7947                         case 'ISO-IR-8-2':
7948                         case 'CSNATSSEFIADD':
7949                                 return 'NATS-SEFI-ADD';
7950
7951                         case 'NATS-DANO':
7952                         case 'ISO-IR-9-1':
7953                         case 'CSNATSDANO':
7954                                 return 'NATS-DANO';
7955
7956                         case 'NATS-DANO-ADD':
7957                         case 'ISO-IR-9-2':
7958                         case 'CSNATSDANOADD':
7959                                 return 'NATS-DANO-ADD';
7960
7961                         case 'SEN_850200_B':
7962                         case 'ISO-IR-10':
7963                         case 'FI':
7964                         case 'ISO646-FI':
7965                         case 'ISO646-SE':
7966                         case 'SE':
7967                         case 'CSISO10SWEDISH':
7968                                 return 'SEN_850200_B';
7969
7970                         case 'KS_C_5601-1987':
7971                         case 'ISO-IR-149':
7972                         case 'KS_C_5601-1989':
7973                         case 'KSC_5601':
7974                         case 'KOREAN':
7975                         case 'CSKSC56011987':
7976                                 return 'KS_C_5601-1987';
7977
7978                         case 'ISO-2022-KR':
7979                         case 'CSISO2022KR':
7980                                 return 'ISO-2022-KR';
7981
7982                         case 'EUC-KR':
7983                         case 'CSEUCKR':
7984                                 return 'EUC-KR';
7985
7986                         case 'ISO-2022-JP':
7987                         case 'CSISO2022JP':
7988                                 return 'ISO-2022-JP';
7989
7990                         case 'ISO-2022-JP-2':
7991                         case 'CSISO2022JP2':
7992                                 return 'ISO-2022-JP-2';
7993
7994                         case 'JIS_C6220-1969-JP':
7995                         case 'JIS_C6220-1969':
7996                         case 'ISO-IR-13':
7997                         case 'KATAKANA':
7998                         case 'X0201-7':
7999                         case 'CSISO13JISC6220JP':
8000                                 return 'JIS_C6220-1969-jp';
8001
8002                         case 'JIS_C6220-1969-RO':
8003                         case 'ISO-IR-14':
8004                         case 'JP':
8005                         case 'ISO646-JP':
8006                         case 'CSISO14JISC6220RO':
8007                                 return 'JIS_C6220-1969-ro';
8008
8009                         case 'PT':
8010                         case 'ISO-IR-16':
8011                         case 'ISO646-PT':
8012                         case 'CSISO16PORTUGUESE':
8013                                 return 'PT';
8014
8015                         case 'GREEK7-OLD':
8016                         case 'ISO-IR-18':
8017                         case 'CSISO18GREEK7OLD':
8018                                 return 'greek7-old';
8019
8020                         case 'LATIN-GREEK':
8021                         case 'ISO-IR-19':
8022                         case 'CSISO19LATINGREEK':
8023                                 return 'latin-greek';
8024
8025                         case 'NF_Z_62-010_(1973)':
8026                         case 'ISO-IR-25':
8027                         case 'ISO646-FR1':
8028                         case 'CSISO25FRENCH':
8029                                 return 'NF_Z_62-010_(1973)';
8030
8031                         case 'LATIN-GREEK-1':
8032                         case 'ISO-IR-27':
8033                         case 'CSISO27LATINGREEK1':
8034                                 return 'Latin-greek-1';
8035
8036                         case 'ISO_5427':
8037                         case 'ISO-IR-37':
8038                         case 'CSISO5427CYRILLIC':
8039                                 return 'ISO_5427';
8040
8041                         case 'JIS_C6226-1978':
8042                         case 'ISO-IR-42':
8043                         case 'CSISO42JISC62261978':
8044                                 return 'JIS_C6226-1978';
8045
8046                         case 'BS_VIEWDATA':
8047                         case 'ISO-IR-47':
8048                         case 'CSISO47BSVIEWDATA':
8049                                 return 'BS_viewdata';
8050
8051                         case 'INIS':
8052                         case 'ISO-IR-49':
8053                         case 'CSISO49INIS':
8054                                 return 'INIS';
8055
8056                         case 'INIS-8':
8057                         case 'ISO-IR-50':
8058                         case 'CSISO50INIS8':
8059                                 return 'INIS-8';
8060
8061                         case 'INIS-CYRILLIC':
8062                         case 'ISO-IR-51':
8063                         case 'CSISO51INISCYRILLIC':
8064                                 return 'INIS-cyrillic';
8065
8066                         case 'ISO_5427:1981':
8067                         case 'ISO-IR-54':
8068                         case 'ISO5427CYRILLIC1981':
8069                                 return 'ISO_5427:1981';
8070
8071                         case 'ISO_5428:1980':
8072                         case 'ISO-IR-55':
8073                         case 'CSISO5428GREEK':
8074                                 return 'ISO_5428:1980';
8075
8076                         case 'GB_1988-80':
8077                         case 'ISO-IR-57':
8078                         case 'CN':
8079                         case 'ISO646-CN':
8080                         case 'CSISO57GB1988':
8081                                 return 'GB_1988-80';
8082
8083                         case 'GB_2312-80':
8084                         case 'ISO-IR-58':
8085                         case 'CHINESE':
8086                         case 'CSISO58GB231280':
8087                                 return 'GB_2312-80';
8088
8089                         case 'NS_4551-2':
8090                         case 'ISO646-NO2':
8091                         case 'ISO-IR-61':
8092                         case 'NO2':
8093                         case 'CSISO61NORWEGIAN2':
8094                                 return 'NS_4551-2';
8095
8096                         case 'VIDEOTEX-SUPPL':
8097                         case 'ISO-IR-70':
8098                         case 'CSISO70VIDEOTEXSUPP1':
8099                                 return 'videotex-suppl';
8100
8101                         case 'PT2':
8102                         case 'ISO-IR-84':
8103                         case 'ISO646-PT2':
8104                         case 'CSISO84PORTUGUESE2':
8105                                 return 'PT2';
8106
8107                         case 'ES2':
8108                         case 'ISO-IR-85':
8109                         case 'ISO646-ES2':
8110                         case 'CSISO85SPANISH2':
8111                                 return 'ES2';
8112
8113                         case 'MSZ_7795.3':
8114                         case 'ISO-IR-86':
8115                         case 'ISO646-HU':
8116                         case 'HU':
8117                         case 'CSISO86HUNGARIAN':
8118                                 return 'MSZ_7795.3';
8119
8120                         case 'JIS_C6226-1983':
8121                         case 'ISO-IR-87':
8122                         case 'X0208':
8123                         case 'JIS_X0208-1983':
8124                         case 'CSISO87JISX0208':
8125                                 return 'JIS_C6226-1983';
8126
8127                         case 'GREEK7':
8128                         case 'ISO-IR-88':
8129                         case 'CSISO88GREEK7':
8130                                 return 'greek7';
8131
8132                         case 'ASMO_449':
8133                         case 'ISO_9036':
8134                         case 'ARABIC7':
8135                         case 'ISO-IR-89':
8136                         case 'CSISO89ASMO449':
8137                                 return 'ASMO_449';
8138
8139                         case 'ISO-IR-90':
8140                         case 'CSISO90':
8141                                 return 'iso-ir-90';
8142
8143                         case 'JIS_C6229-1984-A':
8144                         case 'ISO-IR-91':
8145                         case 'JP-OCR-A':
8146                         case 'CSISO91JISC62291984A':
8147                                 return 'JIS_C6229-1984-a';
8148
8149                         case 'JIS_C6229-1984-B':
8150                         case 'ISO-IR-92':
8151                         case 'ISO646-JP-OCR-B':
8152                         case 'JP-OCR-B':
8153                         case 'CSISO92JISC62991984B':
8154                                 return 'JIS_C6229-1984-b';
8155
8156                         case 'JIS_C6229-1984-B-ADD':
8157                         case 'ISO-IR-93':
8158                         case 'JP-OCR-B-ADD':
8159                         case 'CSISO93JIS62291984BADD':
8160                                 return 'JIS_C6229-1984-b-add';
8161
8162                         case 'JIS_C6229-1984-HAND':
8163                         case 'ISO-IR-94':
8164                         case 'JP-OCR-HAND':
8165                         case 'CSISO94JIS62291984HAND':
8166                                 return 'JIS_C6229-1984-hand';
8167
8168                         case 'JIS_C6229-1984-HAND-ADD':
8169                         case 'ISO-IR-95':
8170                         case 'JP-OCR-HAND-ADD':
8171                         case 'CSISO95JIS62291984HANDADD':
8172                                 return 'JIS_C6229-1984-hand-add';
8173
8174                         case 'JIS_C6229-1984-KANA':
8175                         case 'ISO-IR-96':
8176                         case 'CSISO96JISC62291984KANA':
8177                                 return 'JIS_C6229-1984-kana';
8178
8179                         case 'ISO_2033-1983':
8180                         case 'ISO-IR-98':
8181                         case 'E13B':
8182                         case 'CSISO2033':
8183                                 return 'ISO_2033-1983';
8184
8185                         case 'ANSI_X3.110-1983':
8186                         case 'ISO-IR-99':
8187                         case 'CSA_T500-1983':
8188                         case 'NAPLPS':
8189                         case 'CSISO99NAPLPS':
8190                                 return 'ANSI_X3.110-1983';
8191
8192                         case 'T.61-7BIT':
8193                         case 'ISO-IR-102':
8194                         case 'CSISO102T617BIT':
8195                                 return 'T.61-7bit';
8196
8197                         case 'T.61-8BIT':
8198                         case 'T.61':
8199                         case 'ISO-IR-103':
8200                         case 'CSISO103T618BIT':
8201                                 return 'T.61-8bit';
8202
8203                         case 'ECMA-CYRILLIC':
8204                         case 'ISO-IR-111':
8205                         case 'KOI8-E':
8206                         case 'CSISO111ECMACYRILLIC':
8207                                 return 'ECMA-cyrillic';
8208
8209                         case 'CSA_Z243.4-1985-1':
8210                         case 'ISO-IR-121':
8211                         case 'ISO646-CA':
8212                         case 'CSA7-1':
8213                         case 'CA':
8214                         case 'CSISO121CANADIAN1':
8215                                 return 'CSA_Z243.4-1985-1';
8216
8217                         case 'CSA_Z243.4-1985-2':
8218                         case 'ISO-IR-122':
8219                         case 'ISO646-CA2':
8220                         case 'CSA7-2':
8221                         case 'CSISO122CANADIAN2':
8222                                 return 'CSA_Z243.4-1985-2';
8223
8224                         case 'CSA_Z243.4-1985-GR':
8225                         case 'ISO-IR-123':
8226                         case 'CSISO123CSAZ24341985GR':
8227                                 return 'CSA_Z243.4-1985-gr';
8228
8229                         case 'ISO_8859-6-E':
8230                         case 'CSISO88596E':
8231                         case 'ISO-8859-6-E':
8232                                 return 'ISO-8859-6-E';
8233
8234                         case 'ISO_8859-6-I':
8235                         case 'CSISO88596I':
8236                         case 'ISO-8859-6-I':
8237                                 return 'ISO-8859-6-I';
8238
8239                         case 'T.101-G2':
8240                         case 'ISO-IR-128':
8241                         case 'CSISO128T101G2':
8242                                 return 'T.101-G2';
8243
8244                         case 'ISO_8859-8-E':
8245                         case 'CSISO88598E':
8246                         case 'ISO-8859-8-E':
8247                                 return 'ISO-8859-8-E';
8248
8249                         case 'ISO_8859-8-I':
8250                         case 'CSISO88598I':
8251                         case 'ISO-8859-8-I':
8252                                 return 'ISO-8859-8-I';
8253
8254                         case 'CSN_369103':
8255                         case 'ISO-IR-139':
8256                         case 'CSISO139CSN369103':
8257                                 return 'CSN_369103';
8258
8259                         case 'JUS_I.B1.002':
8260                         case 'ISO-IR-141':
8261                         case 'ISO646-YU':
8262                         case 'JS':
8263                         case 'YU':
8264                         case 'CSISO141JUSIB1002':
8265                                 return 'JUS_I.B1.002';
8266
8267                         case 'IEC_P27-1':
8268                         case 'ISO-IR-143':
8269                         case 'CSISO143IECP271':
8270                                 return 'IEC_P27-1';
8271
8272                         case 'JUS_I.B1.003-SERB':
8273                         case 'ISO-IR-146':
8274                         case 'SERBIAN':
8275                         case 'CSISO146SERBIAN':
8276                                 return 'JUS_I.B1.003-serb';
8277
8278                         case 'JUS_I.B1.003-MAC':
8279                         case 'MACEDONIAN':
8280                         case 'ISO-IR-147':
8281                         case 'CSISO147MACEDONIAN':
8282                                 return 'JUS_I.B1.003-mac';
8283
8284                         case 'GREEK-CCITT':
8285                         case 'ISO-IR-150':
8286                         case 'CSISO150':
8287                         case 'CSISO150GREEKCCITT':
8288                                 return 'greek-ccitt';
8289
8290                         case 'NC_NC00-10:81':
8291                         case 'CUBA':
8292                         case 'ISO-IR-151':
8293                         case 'ISO646-CU':
8294                         case 'CSISO151CUBA':
8295                                 return 'NC_NC00-10:81';
8296
8297                         case 'ISO_6937-2-25':
8298                         case 'ISO-IR-152':
8299                         case 'CSISO6937ADD':
8300                                 return 'ISO_6937-2-25';
8301
8302                         case 'GOST_19768-74':
8303                         case 'ST_SEV_358-88':
8304                         case 'ISO-IR-153':
8305                         case 'CSISO153GOST1976874':
8306                                 return 'GOST_19768-74';
8307
8308                         case 'ISO_8859-SUPP':
8309                         case 'ISO-IR-154':
8310                         case 'LATIN1-2-5':
8311                         case 'CSISO8859SUPP':
8312                                 return 'ISO_8859-supp';
8313
8314                         case 'ISO_10367-BOX':
8315                         case 'ISO-IR-155':
8316                         case 'CSISO10367BOX':
8317                                 return 'ISO_10367-box';
8318
8319                         case 'LATIN-LAP':
8320                         case 'LAP':
8321                         case 'ISO-IR-158':
8322                         case 'CSISO158LAP':
8323                                 return 'latin-lap';
8324
8325                         case 'JIS_X0212-1990':
8326                         case 'X0212':
8327                         case 'ISO-IR-159':
8328                         case 'CSISO159JISX02121990':
8329                                 return 'JIS_X0212-1990';
8330
8331                         case 'DS_2089':
8332                         case 'DS2089':
8333                         case 'ISO646-DK':
8334                         case 'DK':
8335                         case 'CSISO646DANISH':
8336                                 return 'DS_2089';
8337
8338                         case 'US-DK':
8339                         case 'CSUSDK':
8340                                 return 'us-dk';
8341
8342                         case 'DK-US':
8343                         case 'CSDKUS':
8344                                 return 'dk-us';
8345
8346                         case 'KSC5636':
8347                         case 'ISO646-KR':
8348                         case 'CSKSC5636':
8349                                 return 'KSC5636';
8350
8351                         case 'UNICODE-1-1-UTF-7':
8352                         case 'CSUNICODE11UTF7':
8353                                 return 'UNICODE-1-1-UTF-7';
8354
8355                         case 'ISO-2022-CN':
8356                                 return 'ISO-2022-CN';
8357
8358                         case 'ISO-2022-CN-EXT':
8359                                 return 'ISO-2022-CN-EXT';
8360
8361                         case 'UTF-8':
8362                                 return 'UTF-8';
8363
8364                         case 'ISO-8859-13':
8365                                 return 'ISO-8859-13';
8366
8367                         case 'ISO-8859-14':
8368                         case 'ISO-IR-199':
8369                         case 'ISO_8859-14:1998':
8370                         case 'ISO_8859-14':
8371                         case 'LATIN8':
8372                         case 'ISO-CELTIC':
8373                         case 'L8':
8374                                 return 'ISO-8859-14';
8375
8376                         case 'ISO-8859-15':
8377                         case 'ISO_8859-15':
8378                         case 'LATIN-9':
8379                                 return 'ISO-8859-15';
8380
8381                         case 'ISO-8859-16':
8382                         case 'ISO-IR-226':
8383                         case 'ISO_8859-16:2001':
8384                         case 'ISO_8859-16':
8385                         case 'LATIN10':
8386                         case 'L10':
8387                                 return 'ISO-8859-16';
8388
8389                         case 'GBK':
8390                         case 'CP936':
8391                         case 'MS936':
8392                         case 'WINDOWS-936':
8393                                 return 'GBK';
8394
8395                         case 'GB18030':
8396                                 return 'GB18030';
8397
8398                         case 'OSD_EBCDIC_DF04_15':
8399                                 return 'OSD_EBCDIC_DF04_15';
8400
8401                         case 'OSD_EBCDIC_DF03_IRV':
8402                                 return 'OSD_EBCDIC_DF03_IRV';
8403
8404                         case 'OSD_EBCDIC_DF04_1':
8405                                 return 'OSD_EBCDIC_DF04_1';
8406
8407                         case 'ISO-11548-1':
8408                         case 'ISO_11548-1':
8409                         case 'ISO_TR_11548-1':
8410                         case 'CSISO115481':
8411                                 return 'ISO-11548-1';
8412
8413                         case 'KZ-1048':
8414                         case 'STRK1048-2002':
8415                         case 'RK1048':
8416                         case 'CSKZ1048':
8417                                 return 'KZ-1048';
8418
8419                         case 'ISO-10646-UCS-2':
8420                         case 'CSUNICODE':
8421                                 return 'ISO-10646-UCS-2';
8422
8423                         case 'ISO-10646-UCS-4':
8424                         case 'CSUCS4':
8425                                 return 'ISO-10646-UCS-4';
8426
8427                         case 'ISO-10646-UCS-BASIC':
8428                         case 'CSUNICODEASCII':
8429                                 return 'ISO-10646-UCS-Basic';
8430
8431                         case 'ISO-10646-UNICODE-LATIN1':
8432                         case 'CSUNICODELATIN1':
8433                         case 'ISO-10646':
8434                                 return 'ISO-10646-Unicode-Latin1';
8435
8436                         case 'ISO-10646-J-1':
8437                                 return 'ISO-10646-J-1';
8438
8439                         case 'ISO-UNICODE-IBM-1261':
8440                         case 'CSUNICODEIBM1261':
8441                                 return 'ISO-Unicode-IBM-1261';
8442
8443                         case 'ISO-UNICODE-IBM-1268':
8444                         case 'CSUNICODEIBM1268':
8445                                 return 'ISO-Unicode-IBM-1268';
8446
8447                         case 'ISO-UNICODE-IBM-1276':
8448                         case 'CSUNICODEIBM1276':
8449                                 return 'ISO-Unicode-IBM-1276';
8450
8451                         case 'ISO-UNICODE-IBM-1264':
8452                         case 'CSUNICODEIBM1264':
8453                                 return 'ISO-Unicode-IBM-1264';
8454
8455                         case 'ISO-UNICODE-IBM-1265':
8456                         case 'CSUNICODEIBM1265':
8457                                 return 'ISO-Unicode-IBM-1265';
8458
8459                         case 'UNICODE-1-1':
8460                         case 'CSUNICODE11':
8461                                 return 'UNICODE-1-1';
8462
8463                         case 'SCSU':
8464                                 return 'SCSU';
8465
8466                         case 'UTF-7':
8467                                 return 'UTF-7';
8468
8469                         case 'UTF-16BE':
8470                                 return 'UTF-16BE';
8471
8472                         case 'UTF-16LE':
8473                                 return 'UTF-16LE';
8474
8475                         case 'UTF-16':
8476                                 return 'UTF-16';
8477
8478                         case 'CESU-8':
8479                         case 'CSCESU-8':
8480                                 return 'CESU-8';
8481
8482                         case 'UTF-32':
8483                                 return 'UTF-32';
8484
8485                         case 'UTF-32BE':
8486                                 return 'UTF-32BE';
8487
8488                         case 'UTF-32LE':
8489                                 return 'UTF-32LE';
8490
8491                         case 'BOCU-1':
8492                         case 'CSBOCU-1':
8493                                 return 'BOCU-1';
8494
8495                         case 'ISO-8859-1-WINDOWS-3.0-LATIN-1':
8496                         case 'CSWINDOWS30LATIN1':
8497                                 return 'ISO-8859-1-Windows-3.0-Latin-1';
8498
8499                         case 'ISO-8859-1-WINDOWS-3.1-LATIN-1':
8500                         case 'CSWINDOWS31LATIN1':
8501                                 return 'ISO-8859-1-Windows-3.1-Latin-1';
8502
8503                         case 'ISO-8859-2-WINDOWS-LATIN-2':
8504                         case 'CSWINDOWS31LATIN2':
8505                                 return 'ISO-8859-2-Windows-Latin-2';
8506
8507                         case 'ISO-8859-9-WINDOWS-LATIN-5':
8508                         case 'CSWINDOWS31LATIN5':
8509                                 return 'ISO-8859-9-Windows-Latin-5';
8510
8511                         case 'HP-ROMAN8':
8512                         case 'ROMAN8':
8513                         case 'R8':
8514                         case 'CSHPROMAN8':
8515                                 return 'hp-roman8';
8516
8517                         case 'ADOBE-STANDARD-ENCODING':
8518                         case 'CSADOBESTANDARDENCODING':
8519                                 return 'Adobe-Standard-Encoding';
8520
8521                         case 'VENTURA-US':
8522                         case 'CSVENTURAUS':
8523                                 return 'Ventura-US';
8524
8525                         case 'VENTURA-INTERNATIONAL':
8526                         case 'CSVENTURAINTERNATIONAL':
8527                                 return 'Ventura-International';
8528
8529                         case 'DEC-MCS':
8530                         case 'DEC':
8531                         case 'CSDECMCS':
8532                                 return 'DEC-MCS';
8533
8534                         case 'IBM850':
8535                         case 'CP850':
8536                         case '850':
8537                         case 'CSPC850MULTILINGUAL':
8538                                 return 'IBM850';
8539
8540                         case 'PC8-DANISH-NORWEGIAN':
8541                         case 'CSPC8DANISHNORWEGIAN':
8542                                 return 'PC8-Danish-Norwegian';
8543
8544                         case 'IBM862':
8545                         case 'CP862':
8546                         case '862':
8547                         case 'CSPC862LATINHEBREW':
8548                                 return 'IBM862';
8549
8550                         case 'PC8-TURKISH':
8551                         case 'CSPC8TURKISH':
8552                                 return 'PC8-Turkish';
8553
8554                         case 'IBM-SYMBOLS':
8555                         case 'CSIBMSYMBOLS':
8556                                 return 'IBM-Symbols';
8557
8558                         case 'IBM-THAI':
8559                         case 'CSIBMTHAI':
8560                                 return 'IBM-Thai';
8561
8562                         case 'HP-LEGAL':
8563                         case 'CSHPLEGAL':
8564                                 return 'HP-Legal';
8565
8566                         case 'HP-PI-FONT':
8567                         case 'CSHPPIFONT':
8568                                 return 'HP-Pi-font';
8569
8570                         case 'HP-MATH8':
8571                         case 'CSHPMATH8':
8572                                 return 'HP-Math8';
8573
8574                         case 'ADOBE-SYMBOL-ENCODING':
8575                         case 'CSHPPSMATH':
8576                                 return 'Adobe-Symbol-Encoding';
8577
8578                         case 'HP-DESKTOP':
8579                         case 'CSHPDESKTOP':
8580                                 return 'HP-DeskTop';
8581
8582                         case 'VENTURA-MATH':
8583                         case 'CSVENTURAMATH':
8584                                 return 'Ventura-Math';
8585
8586                         case 'MICROSOFT-PUBLISHING':
8587                         case 'CSMICROSOFTPUBLISHING':
8588                                 return 'Microsoft-Publishing';
8589
8590                         case 'WINDOWS-31J':
8591                         case 'CSWINDOWS31J':
8592                                 return 'Windows-31J';
8593
8594                         case 'GB2312':
8595                         case 'CSGB2312':
8596                                 return 'GB2312';
8597
8598                         case 'BIG5':
8599                         case 'CSBIG5':
8600                                 return 'Big5';
8601
8602                         case 'MACINTOSH':
8603                         case 'MAC':
8604                         case 'CSMACINTOSH':
8605                                 return 'macintosh';
8606
8607                         case 'IBM037':
8608                         case 'CP037':
8609                         case 'EBCDIC-CP-US':
8610                         case 'EBCDIC-CP-CA':
8611                         case 'EBCDIC-CP-WT':
8612                         case 'EBCDIC-CP-NL':
8613                         case 'CSIBM037':
8614                                 return 'IBM037';
8615
8616                         case 'IBM038':
8617                         case 'EBCDIC-INT':
8618                         case 'CP038':
8619                         case 'CSIBM038':
8620                                 return 'IBM038';
8621
8622                         case 'IBM273':
8623                         case 'CP273':
8624                         case 'CSIBM273':
8625                                 return 'IBM273';
8626
8627                         case 'IBM274':
8628                         case 'EBCDIC-BE':
8629                         case 'CP274':
8630                         case 'CSIBM274':
8631                                 return 'IBM274';
8632
8633                         case 'IBM275':
8634                         case 'EBCDIC-BR':
8635                         case 'CP275':
8636                         case 'CSIBM275':
8637                                 return 'IBM275';
8638
8639                         case 'IBM277':
8640                         case 'EBCDIC-CP-DK':
8641                         case 'EBCDIC-CP-NO':
8642                         case 'CSIBM277':
8643                                 return 'IBM277';
8644
8645                         case 'IBM278':
8646                         case 'CP278':
8647                         case 'EBCDIC-CP-FI':
8648                         case 'EBCDIC-CP-SE':
8649                         case 'CSIBM278':
8650                                 return 'IBM278';
8651
8652                         case 'IBM280':
8653                         case 'CP280':
8654                         case 'EBCDIC-CP-IT':
8655                         case 'CSIBM280':
8656                                 return 'IBM280';
8657
8658                         case 'IBM281':
8659                         case 'EBCDIC-JP-E':
8660                         case 'CP281':
8661                         case 'CSIBM281':
8662                                 return 'IBM281';
8663
8664                         case 'IBM284':
8665                         case 'CP284':
8666                         case 'EBCDIC-CP-ES':
8667                         case 'CSIBM284':
8668                                 return 'IBM284';
8669
8670                         case 'IBM285':
8671                         case 'CP285':
8672                         case 'EBCDIC-CP-GB':
8673                         case 'CSIBM285':
8674                                 return 'IBM285';
8675
8676                         case 'IBM290':
8677                         case 'CP290':
8678                         case 'EBCDIC-JP-KANA':
8679                         case 'CSIBM290':
8680                                 return 'IBM290';
8681
8682                         case 'IBM297':
8683                         case 'CP297':
8684                         case 'EBCDIC-CP-FR':
8685                         case 'CSIBM297':
8686                                 return 'IBM297';
8687
8688                         case 'IBM420':
8689                         case 'CP420':
8690                         case 'EBCDIC-CP-AR1':
8691                         case 'CSIBM420':
8692                                 return 'IBM420';
8693
8694                         case 'IBM423':
8695                         case 'CP423':
8696                         case 'EBCDIC-CP-GR':
8697                         case 'CSIBM423':
8698                                 return 'IBM423';
8699
8700                         case 'IBM424':
8701                         case 'CP424':
8702                         case 'EBCDIC-CP-HE':
8703                         case 'CSIBM424':
8704                                 return 'IBM424';
8705
8706                         case 'IBM437':
8707                         case 'CP437':
8708                         case '437':
8709                         case 'CSPC8CODEPAGE437':
8710                                 return 'IBM437';
8711
8712                         case 'IBM500':
8713                         case 'CP500':
8714                         case 'EBCDIC-CP-BE':
8715                         case 'EBCDIC-CP-CH':
8716                         case 'CSIBM500':
8717                                 return 'IBM500';
8718
8719                         case 'IBM851':
8720                         case 'CP851':
8721                         case '851':
8722                         case 'CSIBM851':
8723                                 return 'IBM851';
8724
8725                         case 'IBM852':
8726                         case 'CP852':
8727                         case '852':
8728                         case 'CSPCP852':
8729                                 return 'IBM852';
8730
8731                         case 'IBM855':
8732                         case 'CP855':
8733                         case '855':
8734                         case 'CSIBM855':
8735                                 return 'IBM855';
8736
8737                         case 'IBM857':
8738                         case 'CP857':
8739                         case '857':
8740                         case 'CSIBM857':
8741                                 return 'IBM857';
8742
8743                         case 'IBM860':
8744                         case 'CP860':
8745                         case '860':
8746                         case 'CSIBM860':
8747                                 return 'IBM860';
8748
8749                         case 'IBM861':
8750                         case 'CP861':
8751                         case '861':
8752                         case 'CP-IS':
8753                         case 'CSIBM861':
8754                                 return 'IBM861';
8755
8756                         case 'IBM863':
8757                         case 'CP863':
8758                         case '863':
8759                         case 'CSIBM863':
8760                                 return 'IBM863';
8761
8762                         case 'IBM864':
8763                         case 'CP864':
8764                         case 'CSIBM864':
8765                                 return 'IBM864';
8766
8767                         case 'IBM865':
8768                         case 'CP865':
8769                         case '865':
8770                         case 'CSIBM865':
8771                                 return 'IBM865';
8772
8773                         case 'IBM868':
8774                         case 'CP868':
8775                         case 'CP-AR':
8776                         case 'CSIBM868':
8777                                 return 'IBM868';
8778
8779                         case 'IBM869':
8780                         case 'CP869':
8781                         case '869':
8782                         case 'CP-GR':
8783                         case 'CSIBM869':
8784                                 return 'IBM869';
8785
8786                         case 'IBM870':
8787                         case 'CP870':
8788                         case 'EBCDIC-CP-ROECE':
8789                         case 'EBCDIC-CP-YU':
8790                         case 'CSIBM870':
8791                                 return 'IBM870';
8792
8793                         case 'IBM871':
8794                         case 'CP871':
8795                         case 'EBCDIC-CP-IS':
8796                         case 'CSIBM871':
8797                                 return 'IBM871';
8798
8799                         case 'IBM880':
8800                         case 'CP880':
8801                         case 'EBCDIC-CYRILLIC':
8802                         case 'CSIBM880':
8803                                 return 'IBM880';
8804
8805                         case 'IBM891':
8806                         case 'CP891':
8807                         case 'CSIBM891':
8808                                 return 'IBM891';
8809
8810                         case 'IBM903':
8811                         case 'CP903':
8812                         case 'CSIBM903':
8813                                 return 'IBM903';
8814
8815                         case 'IBM904':
8816                         case 'CP904':
8817                         case '904':
8818                         case 'CSIBBM904':
8819                                 return 'IBM904';
8820
8821                         case 'IBM905':
8822                         case 'CP905':
8823                         case 'EBCDIC-CP-TR':
8824                         case 'CSIBM905':
8825                                 return 'IBM905';
8826
8827                         case 'IBM918':
8828                         case 'CP918':
8829                         case 'EBCDIC-CP-AR2':
8830                         case 'CSIBM918':
8831                                 return 'IBM918';
8832
8833                         case 'IBM1026':
8834                         case 'CP1026':
8835                         case 'CSIBM1026':
8836                                 return 'IBM1026';
8837
8838                         case 'EBCDIC-AT-DE':
8839                         case 'CSIBMEBCDICATDE':
8840                                 return 'EBCDIC-AT-DE';
8841
8842                         case 'EBCDIC-AT-DE-A':
8843                         case 'CSEBCDICATDEA':
8844                                 return 'EBCDIC-AT-DE-A';
8845
8846                         case 'EBCDIC-CA-FR':
8847                         case 'CSEBCDICCAFR':
8848                                 return 'EBCDIC-CA-FR';
8849
8850                         case 'EBCDIC-DK-NO':
8851                         case 'CSEBCDICDKNO':
8852                                 return 'EBCDIC-DK-NO';
8853
8854                         case 'EBCDIC-DK-NO-A':
8855                         case 'CSEBCDICDKNOA':
8856                                 return 'EBCDIC-DK-NO-A';
8857
8858                         case 'EBCDIC-FI-SE':
8859                         case 'CSEBCDICFISE':
8860                                 return 'EBCDIC-FI-SE';
8861
8862                         case 'EBCDIC-FI-SE-A':
8863                         case 'CSEBCDICFISEA':
8864                                 return 'EBCDIC-FI-SE-A';
8865
8866                         case 'EBCDIC-FR':
8867                         case 'CSEBCDICFR':
8868                                 return 'EBCDIC-FR';
8869
8870                         case 'EBCDIC-IT':
8871                         case 'CSEBCDICIT':
8872                                 return 'EBCDIC-IT';
8873
8874                         case 'EBCDIC-PT':
8875                         case 'CSEBCDICPT':
8876                                 return 'EBCDIC-PT';
8877
8878                         case 'EBCDIC-ES':
8879                         case 'CSEBCDICES':
8880                                 return 'EBCDIC-ES';
8881
8882                         case 'EBCDIC-ES-A':
8883                         case 'CSEBCDICESA':
8884                                 return 'EBCDIC-ES-A';
8885
8886                         case 'EBCDIC-ES-S':
8887                         case 'CSEBCDICESS':
8888                                 return 'EBCDIC-ES-S';
8889
8890                         case 'EBCDIC-UK':
8891                         case 'CSEBCDICUK':
8892                                 return 'EBCDIC-UK';
8893
8894                         case 'EBCDIC-US':
8895                         case 'CSEBCDICUS':
8896                                 return 'EBCDIC-US';
8897
8898                         case 'UNKNOWN-8BIT':
8899                         case 'CSUNKNOWN8BIT':
8900                                 return 'UNKNOWN-8BIT';
8901
8902                         case 'MNEMONIC':
8903                         case 'CSMNEMONIC':
8904                                 return 'MNEMONIC';
8905
8906                         case 'MNEM':
8907                         case 'CSMNEM':
8908                                 return 'MNEM';
8909
8910                         case 'VISCII':
8911                         case 'CSVISCII':
8912                                 return 'VISCII';
8913
8914                         case 'VIQR':
8915                         case 'CSVIQR':
8916                                 return 'VIQR';
8917
8918                         case 'KOI8-R':
8919                         case 'CSKOI8R':
8920                                 return 'KOI8-R';
8921
8922                         case 'HZ-GB-2312':
8923                                 return 'HZ-GB-2312';
8924
8925                         case 'IBM866':
8926                         case 'CP866':
8927                         case '866':
8928                         case 'CSIBM866':
8929                                 return 'IBM866';
8930
8931                         case 'IBM775':
8932                         case 'CP775':
8933                         case 'CSPC775BALTIC':
8934                                 return 'IBM775';
8935
8936                         case 'KOI8-U':
8937                                 return 'KOI8-U';
8938
8939                         case 'IBM00858':
8940                         case 'CCSID00858':
8941                         case 'CP00858':
8942                         case 'PC-MULTILINGUAL-850+EURO':
8943                                 return 'IBM00858';
8944
8945                         case 'IBM00924':
8946                         case 'CCSID00924':
8947                         case 'CP00924':
8948                         case 'EBCDIC-LATIN9--EURO':
8949                                 return 'IBM00924';
8950
8951                         case 'IBM01140':
8952                         case 'CCSID01140':
8953                         case 'CP01140':
8954                         case 'EBCDIC-US-37+EURO':
8955                                 return 'IBM01140';
8956
8957                         case 'IBM01141':
8958                         case 'CCSID01141':
8959                         case 'CP01141':
8960                         case 'EBCDIC-DE-273+EURO':
8961                                 return 'IBM01141';
8962
8963                         case 'IBM01142':
8964                         case 'CCSID01142':
8965                         case 'CP01142':
8966                         case 'EBCDIC-DK-277+EURO':
8967                         case 'EBCDIC-NO-277+EURO':
8968                                 return 'IBM01142';
8969
8970                         case 'IBM01143':
8971                         case 'CCSID01143':
8972                         case 'CP01143':
8973                         case 'EBCDIC-FI-278+EURO':
8974                         case 'EBCDIC-SE-278+EURO':
8975                                 return 'IBM01143';
8976
8977                         case 'IBM01144':
8978                         case 'CCSID01144':
8979                         case 'CP01144':
8980                         case 'EBCDIC-IT-280+EURO':
8981                                 return 'IBM01144';
8982
8983                         case 'IBM01145':
8984                         case 'CCSID01145':
8985                         case 'CP01145':
8986                         case 'EBCDIC-ES-284+EURO':
8987                                 return 'IBM01145';
8988
8989                         case 'IBM01146':
8990                         case 'CCSID01146':
8991                         case 'CP01146':
8992                         case 'EBCDIC-GB-285+EURO':
8993                                 return 'IBM01146';
8994
8995                         case 'IBM01147':
8996                         case 'CCSID01147':
8997                         case 'CP01147':
8998                         case 'EBCDIC-FR-297+EURO':
8999                                 return 'IBM01147';
9000
9001                         case 'IBM01148':
9002                         case 'CCSID01148':
9003                         case 'CP01148':
9004                         case 'EBCDIC-INTERNATIONAL-500+EURO':
9005                                 return 'IBM01148';
9006
9007                         case 'IBM01149':
9008                         case 'CCSID01149':
9009                         case 'CP01149':
9010                         case 'EBCDIC-IS-871+EURO':
9011                                 return 'IBM01149';
9012
9013                         case 'BIG5-HKSCS':
9014                                 return 'Big5-HKSCS';
9015
9016                         case 'IBM1047':
9017                         case 'IBM-1047':
9018                                 return 'IBM1047';
9019
9020                         case 'PTCP154':
9021                         case 'CSPTCP154':
9022                         case 'PT154':
9023                         case 'CP154':
9024                         case 'CYRILLIC-ASIAN':
9025                                 return 'PTCP154';
9026
9027                         case 'AMIGA-1251':
9028                         case 'AMI1251':
9029                         case 'AMIGA1251':
9030                         case 'AMI-1251':
9031                                 return 'Amiga-1251';
9032
9033                         case 'KOI7-SWITCHED':
9034                                 return 'KOI7-switched';
9035
9036                         case 'BRF':
9037                         case 'CSBRF':
9038                                 return 'BRF';
9039
9040                         case 'TSCII':
9041                         case 'CSTSCII':
9042                                 return 'TSCII';
9043
9044                         case 'WINDOWS-1250':
9045                                 return 'windows-1250';
9046
9047                         case 'WINDOWS-1251':
9048                                 return 'windows-1251';
9049
9050                         case 'WINDOWS-1252':
9051                                 return 'windows-1252';
9052
9053                         case 'WINDOWS-1253':
9054                                 return 'windows-1253';
9055
9056                         case 'WINDOWS-1254':
9057                                 return 'windows-1254';
9058
9059                         case 'WINDOWS-1255':
9060                                 return 'windows-1255';
9061
9062                         case 'WINDOWS-1256':
9063                                 return 'windows-1256';
9064
9065                         case 'WINDOWS-1257':
9066                                 return 'windows-1257';
9067
9068                         case 'WINDOWS-1258':
9069                                 return 'windows-1258';
9070
9071                         default:
9072                                 return (string) $encoding;
9073                 }
9074         }
9075
9076         function get_curl_version()
9077         {
9078                 if (is_array($curl = curl_version()))
9079                 {
9080                         $curl = $curl['version'];
9081                 }
9082                 elseif (substr($curl, 0, 5) == 'curl/')
9083                 {
9084                         $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
9085                 }
9086                 elseif (substr($curl, 0, 8) == 'libcurl/')
9087                 {
9088                         $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
9089                 }
9090                 else
9091                 {
9092                         $curl = 0;
9093                 }
9094                 return $curl;
9095         }
9096
9097         function is_subclass_of($class1, $class2)
9098         {
9099                 if (func_num_args() != 2)
9100                 {
9101                         trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
9102                 }
9103                 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
9104                 {
9105                         return is_subclass_of($class1, $class2);
9106                 }
9107                 elseif (is_string($class1) && is_string($class2))
9108                 {
9109                         if (class_exists($class1))
9110                         {
9111                                 if (class_exists($class2))
9112                                 {
9113                                         $class2 = strtolower($class2);
9114                                         while ($class1 = strtolower(get_parent_class($class1)))
9115                                         {
9116                                                 if ($class1 == $class2)
9117                                                 {
9118                                                         return true;
9119                                                 }
9120                                         }
9121                                 }
9122                         }
9123                         else
9124                         {
9125                                 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
9126                         }
9127                 }
9128                 return false;
9129         }
9130
9131         /**
9132          * Strip HTML comments
9133          *
9134          * @access public
9135          * @param string $data Data to strip comments from
9136          * @return string Comment stripped string
9137          */
9138         function strip_comments($data)
9139         {
9140                 $output = '';
9141                 while (($start = strpos($data, '<!--')) !== false)
9142                 {
9143                         $output .= substr($data, 0, $start);
9144                         if (($end = strpos($data, '-->', $start)) !== false)
9145                         {
9146                                 $data = substr_replace($data, '', 0, $end + 3);
9147                         }
9148                         else
9149                         {
9150                                 $data = '';
9151                         }
9152                 }
9153                 return $output . $data;
9154         }
9155
9156         function parse_date($dt, $rfc822_tz = true)
9157         {
9158                 static $cache = array();
9159                 if (!isset($cache[$dt][$rfc822_tz]))
9160                 {
9161                         $dt = SimplePie_Misc::uncomment_rfc822($dt);
9162                         /*
9163                         Capturing subpatterns:
9164                         1: RFC 822 date
9165                         2: RFC 822 day
9166                         3: RFC 822 month
9167                         4: RFC 822 year
9168                         5: ISO 8601 date
9169                         6: ISO 8601 century
9170                         7: ISO 8601 year
9171                         8: ISO 8601 month
9172                         9: ISO 8601 day
9173                         10: ISO 8601 ordinal day
9174                         11: ISO 8601 month
9175                         12: ISO 8601 day
9176                         13: ISO 8601 week
9177                         14: ISO 8601 day of week
9178                         15: Time
9179                         16: Hour
9180                         17: Hour Decimal
9181                         18: Minute
9182                         19: Minute Decimal
9183                         20: Second
9184                         21: Second Decimal
9185                         22: Timezone
9186                         23: Diff Â±
9187                         24: Hour
9188                         25: Hour Decimal
9189                         26: Minute
9190                         27: Minute Decimal
9191                         28: Alphabetic Timezone
9192                         */
9193                         if (preg_match('/^(?:(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)[,\s]+)?(([0-9]{1,2})\s*(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s*([0-9]{4}|[0-9]{2}))|(([0-9]{2})(?:([0-9]{2})(?:(?:-|\s)*(?:([0-9]{2})([0-9]{2})|([0-9]{3})|([0-9]{2})(?:(?:-|\s)*([0-9]{2}))?|W([0-9]{2})(?:(?:-|\s)*([0-9]))?))?)?))((?:T|\s)+([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*([0-9]{2})(?:(?:,|\.)([0-9]*))?)?)?(?:\s)*((?:(\+|-)([0-9]{2})(?:(?:,|\.)([0-9]*)|(?:\:|\s)*(?:([0-9]{2})(?:(?:,|\.)([0-9]*))?))?)|(UTC|GMT|EST|CST|MST|PST|EDT|CDT|MDT|PDT|UT|[A-IK-Z]))?)?$/i', $dt, $match))
9194                         {
9195                                 // Fill all matches
9196                                 for ($i = count($match); $i <= 28; $i++)
9197                                 {
9198                                         $match[$i] = '';
9199                                 }
9200                                 
9201                                 // Set blank vars
9202                                 $year = 1970;
9203                                 $month = 1;
9204                                 $day = 1;
9205                                 $hour = 0;
9206                                 $minute = 0;
9207                                 $second = 0;
9208                                 $timezone = false;
9209
9210                                 // RFC 822
9211                                 if ($match[1] !== '')
9212                                 {
9213                                         if (strlen($match[4]) == 2)
9214                                         {
9215                                                 $year = ($match[4] < 70) ? "20$match[4]" : "19$match[4]";
9216                                         }
9217                                         else
9218                                         {
9219                                                 $year = $match[4];
9220                                         }
9221                                         switch (strtolower($match[3]))
9222                                         {
9223                                                 case 'jan':
9224                                                         $month = 1;
9225                                                         break;
9226
9227                                                 case 'feb':
9228                                                         $month = 2;
9229                                                         break;
9230
9231                                                 case 'mar':
9232                                                         $month = 3;
9233                                                         break;
9234
9235                                                 case 'apr':
9236                                                         $month = 4;
9237                                                         break;
9238
9239                                                 case 'may':
9240                                                         $month = 5;
9241                                                         break;
9242
9243                                                 case 'jun':
9244                                                         $month = 6;
9245                                                         break;
9246
9247                                                 case 'jul':
9248                                                         $month = 7;
9249                                                         break;
9250
9251                                                 case 'aug':
9252                                                         $month = 8;
9253                                                         break;
9254
9255                                                 case 'sep':
9256                                                         $month = 9;
9257                                                         break;
9258
9259                                                 case 'oct':
9260                                                         $month = 10;
9261                                                         break;
9262
9263                                                 case 'nov':
9264                                                         $month = 11;
9265                                                         break;
9266
9267                                                 case 'dec':
9268                                                         $month = 12;
9269                                                         break;
9270                                         }
9271                                         $day = $match[2];
9272                                 }
9273                                 // ISO 8601
9274                                 else
9275                                 {
9276                                         // Year
9277                                         if ($match[7] !== '')
9278                                         {
9279                                                 $year = "$match[6]$match[7]";
9280
9281                                                 // Two Digit Month/Day
9282                                                 if ($match[11] !== '')
9283                                                 {
9284                                                         $month = $match[11];
9285                                                         if ($match[12] !== '')
9286                                                         {
9287                                                                 $day = $match[12];
9288                                                         }
9289                                                 }
9290
9291                                                 // Four Digit Month/Day
9292                                                 elseif ($match[8] !== '')
9293                                                 {
9294                                                         $month = $match[8];
9295                                                         $day = $match[9];
9296                                                 }
9297
9298                                                 // Ordinal Day
9299                                                 elseif ($match[10] !== '')
9300                                                 {
9301                                                         $day = $match[10];
9302                                                 }
9303
9304                                                 // Week Date
9305                                                 elseif ($match[13] !== '')
9306                                                 {
9307                                                         // Week Day
9308                                                         if ($match[14] !== '')
9309                                                         {
9310                                                                 $day = $match[14];
9311                                                         }
9312
9313                                                         $first_day_of_year = date('w', mktime(0, 0, 0, 1, 1, $year));
9314                                                         if ($first_day_of_year == 0)
9315                                                         {
9316                                                                 $first_day_of_year = 7;
9317                                                         }
9318
9319                                                         $day = 7 * ($match[13] - 1) + $day - ($first_day_of_year - 1);
9320                                                 }
9321                                         }
9322                                         else
9323                                         {
9324                                                 $year = "$match[6]00";
9325                                         }
9326                                 }
9327                                 // Time
9328                                 if ($match[15] !== '')
9329                                 {
9330                                         $time = 0;
9331                                         $time += ($match[16] + ('.' . $match[17])) * 3600;
9332                                         $time += ($match[18] + ('.' . $match[19])) * 60;
9333                                         $time += $match[20] + ('.' . $match[21]);
9334                                         $hour = floor($time / 3600);
9335                                         $time -= $hour * 3600;
9336                                         $minute = floor($time / 60);
9337                                         $time -= $minute * 60;
9338                                         $second = round($time);
9339
9340                                         // Timezone
9341                                         if ($match[22] !== '')
9342                                         {
9343                                                 // Alphabetic Timezone
9344                                                 if ($match[28] !== '')
9345                                                 {
9346                                                         // Military
9347                                                         if (strlen($match[28]) == 1)
9348                                                         {
9349                                                                 if ($match[28] == 'Z' || $match[28] == 'z' || !$rfc822_tz)
9350                                                                 {
9351                                                                         $timezone = 0;
9352                                                                 }
9353                                                                 else
9354                                                                 {
9355                                                                         $timezone = ord(strtoupper($match[28]));
9356
9357                                                                         if ($timezone > 74)
9358                                                                         {
9359                                                                                 $timezone--;
9360                                                                         }
9361
9362                                                                         if ($timezone <= 76)
9363                                                                         {
9364                                                                                 $timezone = -($timezone - 64);
9365                                                                         }
9366                                                                         else
9367                                                                         {
9368                                                                                 $timezone -= 76;
9369                                                                         }
9370
9371                                                                         $timezone *= 3600;
9372                                                                 }
9373                                                         }
9374                                                         // Code
9375                                                         else
9376                                                         {
9377                                                                 switch (strtoupper($match[28]))
9378                                                                 {
9379                                                                         case 'UT':
9380                                                                         case 'UTC':
9381                                                                         case 'GMT':
9382                                                                                 $timezone = 0;
9383                                                                                 break;
9384
9385                                                                         case 'EST':
9386                                                                                 $timezone = -18000;
9387                                                                                 break;
9388
9389                                                                         case 'CST':
9390                                                                                 $timezone = -21600;
9391                                                                                 break;
9392
9393                                                                         case 'MST':
9394                                                                                 $timezone = -25200;
9395                                                                                 break;
9396
9397                                                                         case 'PST':
9398                                                                                 $timezone = -28800;
9399                                                                                 break;
9400
9401                                                                         case 'EDT':
9402                                                                                 $timezone = -14400;
9403                                                                                 break;
9404
9405                                                                         case 'CDT':
9406                                                                                 $timezone = -18000;
9407                                                                                 break;
9408
9409                                                                         case 'MDT':
9410                                                                                 $timezone = -21600;
9411                                                                                 break;
9412
9413                                                                         case 'PDT':
9414                                                                                 $timezone = -25200;
9415                                                                                 break;
9416                                                                 }
9417                                                         }
9418                                                 }
9419                                                 // Timezone difference from UTC
9420                                                 else
9421                                                 {
9422                                                         $timezone = 0;
9423                                                         $timezone += ($match[24] + ('.' . $match[25])) * 3600;
9424                                                         $timezone += ($match[26] + ('.' . $match[27])) * 60;
9425                                                         $timezone = (int) round($timezone);
9426
9427                                                         if ($match[23] == '-')
9428                                                         {
9429                                                                 $timezone = -$timezone;
9430                                                         }
9431                                                 }
9432                                         }
9433                                 }
9434                                 if ($timezone === false)
9435                                 {
9436                                         $cache[$dt][$rfc822_tz] = mktime($hour, $minute, $second, $month, $day, $year);
9437                                 }
9438                                 else
9439                                 {
9440                                         $cache[$dt][$rfc822_tz] = gmmktime($hour, $minute, $second, $month, $day, $year) - $timezone;
9441                                 }
9442                         }
9443                         elseif (($time = strtotime($dt)) > 0)
9444                         {
9445                                 $cache[$dt][$rfc822_tz] = $time;
9446                         }
9447                         else
9448                         {
9449                                 $cache[$dt][$rfc822_tz] = false;
9450                         }
9451                 }
9452                 return $cache[$dt][$rfc822_tz];
9453         }
9454
9455         /**
9456          * Decode HTML entities
9457          *
9458          * @static
9459          * @access public
9460          * @param string $data Input data
9461          * @return string Output data
9462          */
9463         function entities_decode($data)
9464         {
9465                 $decoder = new SimplePie_Decode_HTML_Entities($data);
9466                 return $decoder->parse();
9467         }
9468
9469         /**
9470          * Remove RFC822 comments
9471          *
9472          * @author Tomas V.V.Cox <cox@idecnet.com>
9473          * @author Pierre-Alain Joye <pajoye@php.net>
9474          * @author Amir Mohammad Saied <amir@php.net>
9475          * @copyright 1997-2006 Pierre-Alain Joye,Tomas V.V.Cox,Amir Mohammad Saied
9476          * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
9477          * @version CVS: $Id: Validate.php,v 1.104 2006/11/17 16:32:06 amir Exp $
9478          * @link http://pear.php.net/package/Validate
9479          * @access public
9480          * @param string $data Data to strip comments from
9481          * @return string Comment stripped string
9482          */
9483         function uncomment_rfc822($data)
9484         {
9485                 if ((version_compare(PHP_VERSION, '4.4.6', '>=') && version_compare(PHP_VERSION, '5', '<')) || version_compare(PHP_VERSION, '5.2.2', '>='))
9486                 {
9487                         return $data;
9488                 }
9489                 else
9490                 {
9491                         return preg_replace('/((?:(?:\\\\"|[^("])*(?:"(?:[^"\\\\\r]|\\\\.)*"\s*)?)*)((?<!\\\\)\((?:(?2)|.)*?(?<!\\\\)\))/', '$1', $data);
9492                 }
9493         }
9494
9495         function parse_mime($mime)
9496         {
9497                 if (($pos = strpos($mime, ';')) === false)
9498                 {
9499                         return trim($mime);
9500                 }
9501                 else
9502                 {
9503                         return trim(substr($mime, 0, $pos));
9504                 }
9505         }
9506
9507         function htmlspecialchars_decode($string, $quote_style)
9508         {
9509                 if (function_exists('htmlspecialchars_decode'))
9510                 {
9511                         return htmlspecialchars_decode($string, $quote_style);
9512                 }
9513                 else
9514                 {
9515                         return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
9516                 }
9517         }
9518
9519         function atom_03_construct_type($attribs)
9520         {
9521                 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) == 'base64'))
9522                 {
9523                         $mode = SIMPLEPIE_CONSTRUCT_BASE64;
9524                 }
9525                 else
9526                 {
9527                         $mode = SIMPLEPIE_CONSTRUCT_NONE;
9528                 }
9529                 if (isset($attribs['']['type']))
9530                 {
9531                         switch (strtolower(trim($attribs['']['type'])))
9532                         {
9533                                 case 'text':
9534                                 case 'text/plain':
9535                                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
9536
9537                                 case 'html':
9538                                 case 'text/html':
9539                                         return SIMPLEPIE_CONSTRUCT_HTML | $mode;
9540
9541                                 case 'xhtml':
9542                                 case 'application/xhtml+xml':
9543                                         return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
9544
9545                                 default:
9546                                         return SIMPLEPIE_CONSTRUCT_NONE | $mode;
9547                         }
9548                 }
9549                 else
9550                 {
9551                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
9552                 }
9553         }
9554
9555         function atom_10_construct_type($attribs)
9556         {
9557                 if (isset($attribs['']['type']))
9558                 {
9559                         switch (strtolower(trim($attribs['']['type'])))
9560                         {
9561                                 case 'text':
9562                                         return SIMPLEPIE_CONSTRUCT_TEXT;
9563
9564                                 case 'html':
9565                                         return SIMPLEPIE_CONSTRUCT_HTML;
9566
9567                                 case 'xhtml':
9568                                         return SIMPLEPIE_CONSTRUCT_XHTML;
9569
9570                                 default:
9571                                         return SIMPLEPIE_CONSTRUCT_NONE;
9572                         }
9573                 }
9574                 return SIMPLEPIE_CONSTRUCT_TEXT;
9575         }
9576
9577         function atom_10_content_construct_type($attribs)
9578         {
9579                 if (isset($attribs['']['type']))
9580                 {
9581                         $type = strtolower(trim($attribs['']['type']));
9582                         switch ($type)
9583                         {
9584                                 case 'text':
9585                                         return SIMPLEPIE_CONSTRUCT_TEXT;
9586
9587                                 case 'html':
9588                                         return SIMPLEPIE_CONSTRUCT_HTML;
9589
9590                                 case 'xhtml':
9591                                         return SIMPLEPIE_CONSTRUCT_XHTML;
9592                         }
9593                         if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) == 'text/')
9594                         {
9595                                 return SIMPLEPIE_CONSTRUCT_NONE;
9596                         }
9597                         else
9598                         {
9599                                 return SIMPLEPIE_CONSTRUCT_BASE64;
9600                         }
9601                 }
9602                 else
9603                 {
9604                         return SIMPLEPIE_CONSTRUCT_TEXT;
9605                 }
9606         }
9607
9608         function is_isegment_nz_nc($string)
9609         {
9610                 return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
9611         }
9612
9613         function space_seperated_tokens($string)
9614         {
9615                 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
9616                 $string_length = strlen($string);
9617
9618                 $position = strspn($string, $space_characters);
9619                 $tokens = array();
9620
9621                 while ($position < $string_length)
9622                 {
9623                         $len = strcspn($string, $space_characters, $position);
9624                         $tokens[] = substr($string, $position, $len);
9625                         $position += $len;
9626                         $position += strspn($string, $space_characters, $position);
9627                 }
9628
9629                 return $tokens;
9630         }
9631
9632         function array_unique($array)
9633         {
9634                 if (version_compare(PHP_VERSION, '5.2', '>='))
9635                 {
9636                         return array_unique($array);
9637                 }
9638                 else
9639                 {
9640                         $array = (array) $array;
9641                         $new_array = array();
9642                         $new_array_strings = array();
9643                         foreach ($array as $key => $value)
9644                         {
9645                                 if (is_object($value))
9646                                 {
9647                                         if (method_exists($value, '__toString'))
9648                                         {
9649                                                 $cmp = $value->__toString();
9650                                         }
9651                                         else
9652                                         {
9653                                                 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
9654                                         }
9655                                 }
9656                                 elseif (is_array($value))
9657                                 {
9658                                         $cmp = (string) reset($value);
9659                                 }
9660                                 else
9661                                 {
9662                                         $cmp = (string) $value;
9663                                 }
9664                                 if (!in_array($cmp, $new_array_strings))
9665                                 {
9666                                         $new_array[$key] = $value;
9667                                         $new_array_strings[] = $cmp;
9668                                 }
9669                         }
9670                         return $new_array;
9671                 }
9672         }
9673
9674         /**
9675          * Converts a unicode codepoint to a UTF-8 character
9676          *
9677          * @static
9678          * @access public
9679          * @param int $codepoint Unicode codepoint
9680          * @return string UTF-8 character
9681          */
9682         function codepoint_to_utf8($codepoint)
9683         {
9684                 static $cache = array();
9685                 $codepoint = (int) $codepoint;
9686                 if (isset($cache[$codepoint]))
9687                 {
9688                         return $cache[$codepoint];
9689                 }
9690                 elseif ($codepoint < 0)
9691                 {
9692                         return $cache[$codepoint] = false;
9693                 }
9694                 else if ($codepoint <= 0x7f)
9695                 {
9696                         return $cache[$codepoint] = chr($codepoint);
9697                 }
9698                 else if ($codepoint <= 0x7ff)
9699                 {
9700                         return $cache[$codepoint] = chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
9701                 }
9702                 else if ($codepoint <= 0xffff)
9703                 {
9704                         return $cache[$codepoint] = chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
9705                 }
9706                 else if ($codepoint <= 0x10ffff)
9707                 {
9708                         return $cache[$codepoint] = chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
9709                 }
9710                 else
9711                 {
9712                         // U+FFFD REPLACEMENT CHARACTER
9713                         return $cache[$codepoint] = "\xEF\xBF\xBD";
9714                 }
9715         }
9716
9717         /**
9718          * Re-implementation of PHP 4.2.0's is_a()
9719          *
9720          * @static
9721          * @access public
9722          * @param object $object The tested object
9723          * @param string $class_name The class name
9724          * @return bool Returns true if the object is of this class or has this class as one of its parents, false otherwise
9725          */
9726          function is_a($object, $class_name)
9727          {
9728                 if (function_exists('is_a'))
9729                 {
9730                         return is_a($object, $class_name);
9731                 }
9732                 elseif (!is_object($object))
9733                 {
9734                         return false;
9735                 }
9736                 elseif (get_class($object) == strtolower($class_name))
9737                 {
9738                         return true;
9739                 }
9740                 else
9741                 {
9742                         return is_subclass_of($object, $class_name);
9743                 }
9744          }
9745
9746         /**
9747          * Re-implementation of PHP 5's stripos()
9748          *
9749          * Returns the numeric position of the first occurrence of needle in the
9750          * haystack string.
9751          *
9752          * @static
9753          * @access string
9754          * @param object $haystack
9755          * @param string $needle Note that the needle may be a string of one or more
9756          *     characters. If needle is not a string, it is converted to an integer
9757          *     and applied as the ordinal value of a character.
9758          * @param int $offset The optional offset parameter allows you to specify which
9759          *     character in haystack to start searching. The position returned is still
9760          *     relative to the beginning of haystack.
9761          * @return bool If needle is not found, stripos() will return boolean false.
9762          */
9763          function stripos($haystack, $needle, $offset = 0)
9764          {
9765                 if (function_exists('stripos'))
9766                 {
9767                         return stripos($haystack, $needle, $offset);
9768                 }
9769                 else
9770                 {
9771                         if (is_string($needle))
9772                         {
9773                                 $needle = strtolower($needle);
9774                         }
9775                         elseif (is_int($needle) || is_bool($needle) || is_double($needle))
9776                         {
9777                                 $needle = strtolower(chr($needle));
9778                         }
9779                         else
9780                         {
9781                                 trigger_error('needle is not a string or an integer', E_USER_WARNING);
9782                                 return false;
9783                         }
9784          
9785                         return strpos(strtolower($haystack), $needle, $offset);
9786                 }
9787          }
9788 }
9789
9790 /**
9791  * Decode HTML Entities
9792  *
9793  * This implements HTML5 as of revision 967 (2007-06-28)
9794  *
9795  * @package SimplePie
9796  */
9797 class SimplePie_Decode_HTML_Entities
9798 {
9799         /**
9800          * Data to be parsed
9801          *
9802          * @access private
9803          * @var string
9804          */
9805         var $data = '';
9806
9807         /**
9808          * Currently consumed bytes
9809          *
9810          * @access private
9811          * @var string
9812          */
9813         var $consumed = '';
9814
9815         /**
9816          * Position of the current byte being parsed
9817          *
9818          * @access private
9819          * @var int
9820          */
9821         var $position = 0;
9822
9823         /**
9824          * Create an instance of the class with the input data
9825          *
9826          * @access public
9827          * @param string $data Input data
9828          */
9829         function SimplePie_Decode_HTML_Entities($data)
9830         {
9831                 $this->data = $data;
9832         }
9833
9834         /**
9835          * Parse the input data
9836          *
9837          * @access public
9838          * @return string Output data
9839          */
9840         function parse()
9841         {
9842                 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
9843                 {
9844                         $this->consume();
9845                         $this->entity();
9846                         $this->consumed = '';
9847                 }
9848                 return $this->data;
9849         }
9850
9851         /**
9852          * Consume the next byte
9853          *
9854          * @access private
9855          * @return mixed The next byte, or false, if there is no more data
9856          */
9857         function consume()
9858         {
9859                 if (isset($this->data[$this->position]))
9860                 {
9861                         $this->consumed .= $this->data[$this->position];
9862                         return $this->data[$this->position++];
9863                 }
9864                 else
9865                 {
9866                         $this->consumed = false;
9867                         return false;
9868                 }
9869         }
9870
9871         /**
9872          * Consume a range of characters
9873          *
9874          * @access private
9875          * @param string $chars Characters to consume
9876          * @return mixed A series of characters that match the range, or false
9877          */
9878         function consume_range($chars)
9879         {
9880                 if ($len = strspn($this->data, $chars, $this->position))
9881                 {
9882                         $data = substr($this->data, $this->position, $len);
9883                         $this->consumed .= $data;
9884                         $this->position += $len;
9885                         return $data;
9886                 }
9887                 else
9888                 {
9889                         $this->consumed = false;
9890                         return false;
9891                 }
9892         }
9893
9894         /**
9895          * Unconsume one byte
9896          *
9897          * @access private
9898          */
9899         function unconsume()
9900         {
9901                 $this->consumed = substr($this->consumed, 0, -1);
9902                 $this->position--;
9903         }
9904
9905         /**
9906          * Decode an entity
9907          *
9908          * @access private
9909          */
9910         function entity()
9911         {
9912                 switch ($this->consume())
9913                 {
9914                         case "\x09":
9915                         case "\x0A":
9916                         case "\x0B":
9917                         case "\x0B":
9918                         case "\x0C":
9919                         case "\x20":
9920                         case "\x3C":
9921                         case "\x26":
9922                         case false:
9923                                 break;
9924
9925                         case "\x23":
9926                                 switch ($this->consume())
9927                                 {
9928                                         case "\x78":
9929                                         case "\x58":
9930                                                 $range = '0123456789ABCDEFabcdef';
9931                                                 $hex = true;
9932                                                 break;
9933
9934                                         default:
9935                                                 $range = '0123456789';
9936                                                 $hex = false;
9937                                                 $this->unconsume();
9938                                                 break;
9939                                 }
9940
9941                                 if ($codepoint = $this->consume_range($range))
9942                                 {
9943                                         static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
9944
9945                                         if ($hex)
9946                                         {
9947                                                 $codepoint = hexdec($codepoint);
9948                                         }
9949                                         else
9950                                         {
9951                                                 $codepoint = intval($codepoint);
9952                                         }
9953
9954                                         if (isset($windows_1252_specials[$codepoint]))
9955                                         {
9956                                                 $replacement = $windows_1252_specials[$codepoint];
9957                                         }
9958                                         else
9959                                         {
9960                                                 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
9961                                         }
9962
9963                                         if ($this->consume() != ';')
9964                                         {
9965                                                 $this->unconsume();
9966                                         }
9967
9968                                         $consumed_length = strlen($this->consumed);
9969                                         $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
9970                                         $this->position += strlen($replacement) - $consumed_length;
9971                                 }
9972                                 break;
9973
9974                         default:
9975                                 static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");
9976
9977                                 for ($i = 0, $match = null; $i < 9 && $this->consume(); $i++)
9978                                 {
9979                                         $consumed = substr($this->consumed, 1);
9980                                         if (isset($entities[$consumed]))
9981                                         {
9982                                                 $match = $consumed;
9983                                         }
9984                                 }
9985
9986                                 if ($match !== null)
9987                                 {
9988                                         $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
9989                                         $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
9990                                 }
9991                                 break;
9992                 }
9993         }
9994 }
9995
9996 class SimplePie_Locator
9997 {
9998         var $useragent;
9999         var $timeout;
10000         var $file;
10001         var $local = array();
10002         var $elsewhere = array();
10003         var $file_class = 'SimplePie_File';
10004         var $cached_entities = array();
10005         var $http_base;
10006         var $base;
10007         var $base_location = 0;
10008         var $checked_feeds = 0;
10009         var $max_checked_feeds = 10;
10010
10011         function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10)
10012         {
10013                 $this->file =& $file;
10014                 $this->file_class = $file_class;
10015                 $this->useragent = $useragent;
10016                 $this->timeout = $timeout;
10017                 $this->max_checked_feeds = $max_checked_feeds;
10018         }
10019
10020         function find($type = SIMPLEPIE_LOCATOR_ALL)
10021         {
10022                 if ($this->is_feed($this->file))
10023                 {
10024                         return $this->file;
10025                 }
10026
10027                 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
10028                 {
10029                         $this->get_base();
10030                 }
10031
10032                 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
10033                 {
10034                         return $working;
10035                 }
10036
10037                 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
10038                 {
10039                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
10040                         {
10041                                 return $working;
10042                         }
10043
10044                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
10045                         {
10046                                 return $working;
10047                         }
10048
10049                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
10050                         {
10051                                 return $working;
10052                         }
10053
10054                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
10055                         {
10056                                 return $working;
10057                         }
10058                 }
10059                 return null;
10060         }
10061
10062         function is_feed(&$file)
10063         {
10064                 $body = SimplePie_Misc::strip_comments($file->body);
10065                 if (preg_match('/<([^\s:]+:)?(rss|RDF|feed)' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/i', $body))
10066                 {
10067                         return true;
10068                 }
10069                 return false;
10070         }
10071
10072         function get_base()
10073         {
10074                 if (isset($this->file->headers['content-location']))
10075                 {
10076                         $this->http_base = SimplePie_Misc::absolutize_url(trim($this->file->headers['content-location']), $this->file->url);
10077                 }
10078                 else
10079                 {
10080                         $this->http_base = $this->file->url;
10081                 }
10082                 $this->base = $this->http_base;
10083                 $elements = SimplePie_Misc::get_element('base', $this->file->body);
10084                 foreach ($elements as $element)
10085                 {
10086                         if ($element['attribs']['href']['data'] !== '')
10087                         {
10088                                 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
10089                                 $this->base_location = $element['offset'];
10090                                 break;
10091                         }
10092                 }
10093         }
10094
10095         function autodiscovery()
10096         {
10097                 $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body));
10098                 $done = array();
10099                 foreach ($links as $link)
10100                 {
10101                         if ($this->checked_feeds == $this->max_checked_feeds)
10102                         {
10103                                 break;
10104                         }
10105                         if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
10106                         {
10107                                 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
10108
10109                                 if ($this->base_location < $link['offset'])
10110                                 {
10111                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
10112                                 }
10113                                 else
10114                                 {
10115                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
10116                                 }
10117
10118                                 if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))))
10119                                 {
10120                                         $this->checked_feeds++;
10121                                         $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
10122                                         if ($this->is_feed($feed))
10123                                         {
10124                                                 return $feed;
10125                                         }
10126                                 }
10127                                 $done[] = $href;
10128                         }
10129                 }
10130                 return null;
10131         }
10132
10133         function get_links()
10134         {
10135                 $links = SimplePie_Misc::get_element('a', $this->file->body);
10136                 foreach ($links as $link)
10137                 {
10138                         if (isset($link['attribs']['href']['data']))
10139                         {
10140                                 $href = trim($link['attribs']['href']['data']);
10141                                 $parsed = SimplePie_Misc::parse_url($href);
10142                                 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
10143                                 {
10144                                         if ($this->base_location < $link['offset'])
10145                                         {
10146                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
10147                                         }
10148                                         else
10149                                         {
10150                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
10151                                         }
10152
10153                                         $current = SimplePie_Misc::parse_url($this->file->url);
10154
10155                                         if ($parsed['authority'] === '' || $parsed['authority'] == $current['authority'])
10156                                         {
10157                                                 $this->local[] = $href;
10158                                         }
10159                                         else
10160                                         {
10161                                                 $this->elsewhere[] = $href;
10162                                         }
10163                                 }
10164                         }
10165                 }
10166                 $this->local = array_unique($this->local);
10167                 $this->elsewhere = array_unique($this->elsewhere);
10168                 if (!empty($this->local) || !empty($this->elsewhere))
10169                 {
10170                         return true;
10171                 }
10172                 return null;
10173         }
10174
10175         function extension(&$array)
10176         {
10177                 foreach ($array as $key => $value)
10178                 {
10179                         if ($this->checked_feeds == $this->max_checked_feeds)
10180                         {
10181                                 break;
10182                         }
10183                         if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
10184                         {
10185                                 $this->checked_feeds++;
10186                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
10187                                 if ($this->is_feed($feed))
10188                                 {
10189                                         return $feed;
10190                                 }
10191                                 else
10192                                 {
10193                                         unset($array[$key]);
10194                                 }
10195                         }
10196                 }
10197                 return null;
10198         }
10199
10200         function body(&$array)
10201         {
10202                 foreach ($array as $key => $value)
10203                 {
10204                         if ($this->checked_feeds == $this->max_checked_feeds)
10205                         {
10206                                 break;
10207                         }
10208                         if (preg_match('/(rss|rdf|atom|xml)/i', $value))
10209                         {
10210                                 $this->checked_feeds++;
10211                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
10212                                 if ($this->is_feed($feed))
10213                                 {
10214                                         return $feed;
10215                                 }
10216                                 else
10217                                 {
10218                                         unset($array[$key]);
10219                                 }
10220                         }
10221                 }
10222                 return null;
10223         }
10224 }
10225
10226 class SimplePie_Parser
10227 {
10228         var $xml;
10229         var $error_code;
10230         var $error_string;
10231         var $current_line;
10232         var $current_column;
10233         var $current_byte;
10234         var $separator = ' ';
10235         var $feed = false;
10236         var $namespace = array('');
10237         var $element = array('');
10238         var $xml_base = array('');
10239         var $xml_base_explicit = array(false);
10240         var $xml_lang = array('');
10241         var $data = array();
10242         var $datas = array(array());
10243         var $current_xhtml_construct = -1;
10244         var $encoding;
10245
10246         function pre_process(&$data, $encoding)
10247         {
10248                 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
10249                 if (strtoupper($encoding) == 'US-ASCII')
10250                 {
10251                         $this->encoding = 'UTF-8';
10252                 }
10253                 else
10254                 {
10255                         $this->encoding = $encoding;
10256                 }
10257
10258                 // Strip BOM:
10259                 // UTF-32 Big Endian BOM
10260                 if (strpos($data, "\x0\x0\xFE\xFF") === 0)
10261                 {
10262                         $data = substr($data, 4);
10263                 }
10264                 // UTF-32 Little Endian BOM
10265                 elseif (strpos($data, "\xFF\xFE\x0\x0") === 0)
10266                 {
10267                         $data = substr($data, 4);
10268                 }
10269                 // UTF-16 Big Endian BOM
10270                 elseif (strpos($data, "\xFE\xFF") === 0)
10271                 {
10272                         $data = substr($data, 2);
10273                 }
10274                 // UTF-16 Little Endian BOM
10275                 elseif (strpos($data, "\xFF\xFE") === 0)
10276                 {
10277                         $data = substr($data, 2);
10278                 }
10279                 // UTF-8 BOM
10280                 elseif (strpos($data, "\xEF\xBB\xBF") === 0)
10281                 {
10282                         $data = substr($data, 3);
10283                 }
10284
10285                 // Make sure the XML prolog is sane and has the correct encoding
10286                 $data = preg_replace("/^<\?xml[\x20\x9\xD\xA]+version([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"1.0\"|'1.0'|\"1.1\"|'1.1')([\x20\x9\xD\xA]+encoding([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"[A-Za-z][A-Za-z0-9._\-]*\"|'[A-Za-z][A-Za-z0-9._\-]*'))?([\x20\x9\xD\xA]+standalone([\x20\x9\xD\xA]+)?=([\x20\x9\xD\xA]+)?(\"(yes|no)\"|'(yes|no)'))?([\x20\x9\xD\xA]+)?\?>/", '', $data);
10287                 $data = "<?xml version='1.0' encoding='$encoding'?>\n" . $data;
10288         }
10289
10290         function parse(&$data)
10291         {
10292                 $return = true;
10293
10294                 // Create the parser
10295                 $this->xml = xml_parser_create_ns($this->encoding, $this->separator);
10296                 xml_parser_set_option($this->xml, XML_OPTION_SKIP_WHITE, 1);
10297                 xml_parser_set_option($this->xml, XML_OPTION_CASE_FOLDING, 0);
10298                 xml_set_object($this->xml, $this);
10299                 xml_set_character_data_handler($this->xml, 'cdata');
10300                 xml_set_element_handler($this->xml, 'tag_open', 'tag_close');
10301
10302                 // Parse!
10303                 if (!xml_parse($this->xml, $data, true))
10304                 {
10305                         $this->data = null;
10306                         $this->error_code = xml_get_error_code($this->xml);
10307                         $this->error_string = xml_error_string($this->error_code);
10308                         $return = false;
10309                 }
10310                 $this->current_line = xml_get_current_line_number($this->xml);
10311                 $this->current_column = xml_get_current_column_number($this->xml);
10312                 $this->current_byte = xml_get_current_byte_index($this->xml);
10313                 xml_parser_free($this->xml);
10314                 return $return;
10315         }
10316
10317         function get_error_code()
10318         {
10319                 return $this->error_code;
10320         }
10321
10322         function get_error_string()
10323         {
10324                 return $this->error_string;
10325         }
10326
10327         function get_current_line()
10328         {
10329                 return $this->current_line;
10330         }
10331
10332         function get_current_column()
10333         {
10334                 return $this->current_column;
10335         }
10336
10337         function get_current_byte()
10338         {
10339                 return $this->current_byte;
10340         }
10341
10342         function get_data()
10343         {
10344                 return $this->data;
10345         }
10346
10347         function tag_open($parser, $tag, $attributes)
10348         {
10349                 if ($this->feed === 0)
10350                 {
10351                         return;
10352                 }
10353                 elseif ($this->feed == false)
10354                 {
10355                         if (in_array($tag, array(
10356                                 SIMPLEPIE_NAMESPACE_ATOM_10 . $this->separator . 'feed',
10357                                 SIMPLEPIE_NAMESPACE_ATOM_03 . $this->separator . 'feed',
10358                                 'rss',
10359                                 SIMPLEPIE_NAMESPACE_RDF . $this->separator . 'RDF'
10360                         )))
10361                         {
10362                                         $this->feed = 1;
10363                         }
10364                 }
10365                 else
10366                 {
10367                         $this->feed++;
10368                 }
10369
10370                 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
10371
10372                 $attribs = array();
10373                 foreach ($attributes as $name => $value)
10374                 {
10375                         list($attrib_namespace, $attribute) = $this->split_ns($name);
10376                         $attribs[$attrib_namespace][$attribute] = $value;
10377                 }
10378
10379                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
10380                 {
10381                         $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
10382                         $this->xml_base_explicit[] = true;
10383                 }
10384                 else
10385                 {
10386                         $this->xml_base[] = end($this->xml_base);
10387                         $this->xml_base_explicit[] = end($this->xml_base_explicit);
10388                 }
10389
10390                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
10391                 {
10392                         $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
10393                 }
10394                 else
10395                 {
10396                         $this->xml_lang[] = end($this->xml_lang);
10397                 }
10398
10399                 if ($this->current_xhtml_construct >= 0)
10400                 {
10401                         $this->current_xhtml_construct++;
10402                         if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML)
10403                         {
10404                                 $this->data['data'] .= '<' . end($this->element);
10405                                 if (isset($attribs['']))
10406                                 {
10407                                         foreach ($attribs[''] as $name => $value)
10408                                         {
10409                                                 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
10410                                         }
10411                                 }
10412                                 $this->data['data'] .= '>';
10413                         }
10414                 }
10415                 else
10416                 {
10417                         $this->datas[] =& $this->data;
10418                         $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
10419                         $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));
10420                         if ((end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] == 'xml')
10421                         || (end($this->namespace) == SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] == 'xhtml'))
10422                         {
10423                                 $this->current_xhtml_construct = 0;
10424                         }
10425                 }
10426         }
10427
10428         function cdata($parser, $cdata)
10429         {
10430                 if ($this->current_xhtml_construct >= 0)
10431                 {
10432                         $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
10433                 }
10434                 elseif ($this->feed > 1)
10435                 {
10436                         $this->data['data'] .= $cdata;
10437                 }
10438         }
10439
10440         function tag_close($parser, $tag)
10441         {
10442                 if (!$this->feed)
10443                 {
10444                         return;
10445                 }
10446
10447                 if ($this->current_xhtml_construct >= 0)
10448                 {
10449                         $this->current_xhtml_construct--;
10450                         if (end($this->namespace) == SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))
10451                         {
10452                                 $this->data['data'] .= '</' . end($this->element) . '>';
10453                         }
10454                 }
10455                 if ($this->current_xhtml_construct == -1)
10456                 {
10457                         $this->data =& $this->datas[$this->feed];
10458                         array_pop($this->datas);
10459                 }
10460
10461                 array_pop($this->element);
10462                 array_pop($this->namespace);
10463                 array_pop($this->xml_base);
10464                 array_pop($this->xml_base_explicit);
10465                 array_pop($this->xml_lang);
10466                 $this->feed--;
10467         }
10468
10469         function split_ns($string)
10470         {
10471                 static $cache = array();
10472                 if (!isset($cache[$string]))
10473                 {
10474                         if ($pos = strpos($string, $this->separator))
10475                         {
10476                                 static $separator_length;
10477                                 if (!$separator_length)
10478                                 {
10479                                         $separator_length = strlen($this->separator);
10480                                 }
10481                                 $cache[$string] = array(substr($string, 0, $pos), substr($string, $pos + $separator_length));
10482                         }
10483                         else
10484                         {
10485                                 $cache[$string] = array('', $string);
10486                         }
10487                 }
10488                 return $cache[$string];
10489         }
10490 }
10491
10492 /**
10493  * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shortern a string while preserving HTML tags
10494  */
10495 class SimplePie_Sanitize
10496 {
10497         // Private vars
10498         var $base;
10499
10500         // Options
10501         var $remove_div = true;
10502         var $image_handler = '';
10503         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
10504         var $encode_instead_of_strip = false;
10505         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
10506         var $strip_comments = false;
10507         var $output_encoding = 'UTF-8';
10508         var $enable_cache = true;
10509         var $cache_location = './cache';
10510         var $cache_name_function = 'md5';
10511         var $cache_class = 'SimplePie_Cache';
10512         var $file_class = 'SimplePie_File';
10513         var $timeout = 10;
10514         var $useragent = '';
10515         var $force_fsockopen = false;
10516
10517         var $replace_url_attributes = array(
10518                 'a' => 'href',
10519                 'area' => 'href',
10520                 'blockquote' => 'cite',
10521                 'del' => 'cite',
10522                 'form' => 'action',
10523                 'img' => array('longdesc', 'src'),
10524                 'input' => 'src',
10525                 'ins' => 'cite',
10526                 'q' => 'cite'
10527         );
10528
10529         function remove_div($enable = true)
10530         {
10531                 $this->remove_div = (bool) $enable;
10532         }
10533
10534         function set_image_handler($page = false)
10535         {
10536                 if ($page)
10537                 {
10538                         $this->image_handler = (string) $page;
10539                 }
10540                 else
10541                 {
10542                         $this->image_handler = false;
10543                 }
10544         }
10545
10546         function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
10547         {
10548                 if (isset($enable_cache))
10549                 {
10550                         $this->enable_cache = (bool) $enable_cache;
10551                 }
10552
10553                 if ($cache_location)
10554                 {
10555                         $this->cache_location = (string) $cache_location;
10556                 }
10557
10558                 if ($cache_name_function)
10559                 {
10560                         $this->cache_name_function = (string) $cache_name_function;
10561                 }
10562
10563                 if ($cache_class)
10564                 {
10565                         $this->cache_class = (string) $cache_class;
10566                 }
10567         }
10568
10569         function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
10570         {
10571                 if ($file_class)
10572                 {
10573                         $this->file_class = (string) $file_class;
10574                 }
10575
10576                 if ($timeout)
10577                 {
10578                         $this->timeout = (string) $timeout;
10579                 }
10580
10581                 if ($useragent)
10582                 {
10583                         $this->useragent = (string) $useragent;
10584                 }
10585
10586                 if ($force_fsockopen)
10587                 {
10588                         $this->force_fsockopen = (string) $force_fsockopen;
10589                 }
10590         }
10591
10592         function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
10593         {
10594                 if ($tags)
10595                 {
10596                         if (is_array($tags))
10597                         {
10598                                 $this->strip_htmltags = $tags;
10599                         }
10600                         else
10601                         {
10602                                 $this->strip_htmltags = explode(',', $tags);
10603                         }
10604                 }
10605                 else
10606                 {
10607                         $this->strip_htmltags = false;
10608                 }
10609         }
10610
10611         function encode_instead_of_strip($encode = false)
10612         {
10613                 $this->encode_instead_of_strip = (bool) $encode;
10614         }
10615
10616         function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
10617         {
10618                 if ($attribs)
10619                 {
10620                         if (is_array($attribs))
10621                         {
10622                                 $this->strip_attributes = $attribs;
10623                         }
10624                         else
10625                         {
10626                                 $this->strip_attributes = explode(',', $attribs);
10627                         }
10628                 }
10629                 else
10630                 {
10631                         $this->strip_attributes = false;
10632                 }
10633         }
10634
10635         function strip_comments($strip = false)
10636         {
10637                 $this->strip_comments = (bool) $strip;
10638         }
10639
10640         function set_output_encoding($encoding = 'UTF-8')
10641         {
10642                 $this->output_encoding = (string) $encoding;
10643         }
10644
10645         /**
10646          * Set element/attribute key/value pairs of HTML attributes
10647          * containing URLs that need to be resolved relative to the feed
10648          *
10649          * @access public
10650          * @since 1.0
10651          * @param array $element_attribute Element/attribute key/value pairs
10652          */
10653         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'))
10654         {
10655                 $this->replace_url_attributes = (array) $element_attribute;
10656         }
10657
10658         function sanitize($data, $type, $base = '')
10659         {
10660                 $data = trim($data);
10661                 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
10662                 {
10663                         if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
10664                         {
10665                                 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/(\w+)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
10666                                 {
10667                                         $type |= SIMPLEPIE_CONSTRUCT_HTML;
10668                                 }
10669                                 else
10670                                 {
10671                                         $type |= SIMPLEPIE_CONSTRUCT_TEXT;
10672                                 }
10673                         }
10674
10675                         if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
10676                         {
10677                                 $data = base64_decode($data);
10678                         }
10679
10680                         if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
10681                         {
10682                                 if ($this->remove_div)
10683                                 {
10684                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
10685                                         $data = preg_replace('/<\/div>$/', '', $data);
10686                                 }
10687                                 else
10688                                 {
10689                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
10690                                 }
10691                         }
10692
10693                         if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
10694                         {
10695                                 // Strip comments
10696                                 if ($this->strip_comments)
10697                                 {
10698                                         $data = SimplePie_Misc::strip_comments($data);
10699                                 }
10700
10701                                 // Strip out HTML tags and attributes that might cause various security problems.
10702                                 // Based on recommendations by Mark Pilgrim at:
10703                                 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
10704                                 if ($this->strip_htmltags)
10705                                 {
10706                                         foreach ($this->strip_htmltags as $tag)
10707                                         {
10708                                                 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
10709                                                 while (preg_match($pcre, $data))
10710                                                 {
10711                                                         $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
10712                                                 }
10713                                         }
10714                                 }
10715
10716                                 if ($this->strip_attributes)
10717                                 {
10718                                         foreach ($this->strip_attributes as $attrib)
10719                                         {
10720                                                 $data = preg_replace('/ '. trim($attrib) .'=("|&quot;)(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\'|&apos;|<|>|\+|{|})*("|&quot;)/i', '', $data);
10721                                                 $data = preg_replace('/ '. trim($attrib) .'=(\'|&apos;)(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|"|&quot;|<|>|\+|{|})*(\'|&apos;)/i', '', $data);
10722                                                 $data = preg_replace('/ '. trim($attrib) .'=(\w|\s|=|-|:|;|\/|\.|\?|&|,|#|!|\(|\)|\+|{|})*/i', '', $data);
10723                                         }
10724                                 }
10725
10726                                 // Replace relative URLs
10727                                 $this->base = $base;
10728                                 foreach ($this->replace_url_attributes as $element => $attributes)
10729                                 {
10730                                         $data = $this->replace_urls($data, $element, $attributes);
10731                                 }
10732
10733                                 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
10734                                 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
10735                                 {
10736                                         $images = SimplePie_Misc::get_element('img', $data);
10737                                         foreach ($images as $img)
10738                                         {
10739                                                 if (isset($img['attribs']['src']['data']))
10740                                                 {
10741                                                         $image_url = $img['attribs']['src']['data'];
10742                                                         $cache =& new $this->cache_class($this->cache_location, call_user_func($this->cache_name_function, $image_url), 'spi');
10743
10744                                                         if ($cache->load())
10745                                                         {
10746                                                                 $img['attribs']['src']['data'] = $this->image_handler . rawurlencode($img['attribs']['src']['data']);
10747                                                                 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
10748                                                         }
10749                                                         else
10750                                                         {
10751                                                                 $file =& new $this->file_class($image_url, $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
10752                                                                 $headers = $file->headers;
10753
10754                                                                 if ($file->success && ($file->status_code == 200 || ($file->status_code > 206 && $file->status_code < 300)))
10755                                                                 {
10756                                                                         if (!$cache->save(array('headers' => $file->headers, 'body' => $file->body)))
10757                                                                         {
10758                                                                                 trigger_error("$cache->name is not writeable", E_USER_WARNING);
10759                                                                         }
10760                                                                         $img['attribs']['src']['data'] = $this->image_handler . rawurlencode($img['attribs']['src']['data']);
10761                                                                         $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
10762                                                                 }
10763                                                         }
10764                                                 }
10765                                         }
10766                                 }
10767
10768                                 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
10769                                 $data = trim($data);
10770                         }
10771
10772                         if ($type & SIMPLEPIE_CONSTRUCT_IRI)
10773                         {
10774                                 $data = SimplePie_Misc::absolutize_url($data, $base);
10775                         }
10776
10777                         if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
10778                         {
10779                                 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
10780                         }
10781
10782                         if ($this->output_encoding != 'UTF-8')
10783                         {
10784                                 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
10785                         }
10786                 }
10787                 return $data;
10788         }
10789
10790         function replace_urls($data, $tag, $attributes)
10791         {
10792                 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
10793                 {
10794                         $elements = SimplePie_Misc::get_element($tag, $data);
10795                         foreach ($elements as $element)
10796                         {
10797                                 if (is_array($attributes))
10798                                 {
10799                                         foreach ($attributes as $attribute)
10800                                         {
10801                                                 if (isset($element['attribs'][$attribute]['data']))
10802                                                 {
10803                                                         $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
10804                                                         $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
10805                                                 }
10806                                         }
10807                                 }
10808                                 elseif (isset($element['attribs'][$attributes]['data']))
10809                                 {
10810                                         $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
10811                                         $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
10812                                 }
10813                         }
10814                 }
10815                 return $data;
10816         }
10817
10818         function do_strip_htmltags($match)
10819         {
10820                 if ($this->encode_instead_of_strip)
10821                 {
10822                         if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
10823                         {
10824                                 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
10825                                 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
10826                                 return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
10827                         }
10828                         else
10829                         {
10830                                 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
10831                         }
10832                 }
10833                 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
10834                 {
10835                         return $match[4];
10836                 }
10837                 else
10838                 {
10839                         return '';
10840                 }
10841         }
10842 }
10843
10844 ?>