Make WordPress Core

Changeset 21644


Ignore:
Timestamp:
08/28/2012 05:24:33 PM (14 years ago)
Author:
nacin
Message:

Update to SimplePie 1.3. props rmccue.

Uses individual files for each class. We now conditionally load only the pieces
we need, resulting in less memory usage. Also easier to maintain now that it is
not a single 387KB file.

fixes #21183.

Location:
trunk/wp-includes
Files:
42 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/class-feed.php

    r17928 r21644  
    1111         * @access public
    1212         */
    13         function create($location, $filename, $extension) {
     13        public static function create($location, $filename, $extension) {
    1414                return new WP_Feed_Cache_Transient($location, $filename, $extension);
    1515        }
  • trunk/wp-includes/class-simplepie.php

    r20715 r21644  
    11<?php
    22if ( ! class_exists( 'SimplePie' ) ) :
     3
     4// Load classes we will need.
     5require ABSPATH . WPINC . '/SimplePie/Misc.php';
     6require ABSPATH . WPINC . '/SimplePie/Cache.php';
     7require ABSPATH . WPINC . '/SimplePie/File.php';
     8require ABSPATH . WPINC . '/SimplePie/Sanitize.php';
     9require ABSPATH . WPINC . '/SimplePie/Registry.php';
     10require ABSPATH . WPINC . '/SimplePie/IRI.php';
     11require ABSPATH . WPINC . '/SimplePie/Locator.php';
     12require ABSPATH . WPINC . '/SimplePie/Content/Type/Sniffer.php';
     13require ABSPATH . WPINC . '/SimplePie/XML/Declaration/Parser.php';
     14require ABSPATH . WPINC . '/SimplePie/Parser.php';
     15require ABSPATH . WPINC . '/SimplePie/Item.php';
     16require ABSPATH . WPINC . '/SimplePie/Parse/Date.php';
     17require ABSPATH . WPINC . '/SimplePie/Author.php';
     18
     19/**
     20 * WordPress autoloader for SimplePie.
     21 *
     22 * @since 3.5.0
     23 */
     24function wp_simplepie_autoload( $class ) {
     25        if ( 0 !== strpos( $class, 'SimplePie_' ) )
     26                return;
     27
     28        $file = dirname( __FILE__ ) . '/' . str_replace( '_', '/', $class ) . '.php';
     29        include $file;
     30}
     31
     32if ( function_exists( 'spl_autoload_register' ) ) {
     33        /**
     34         * We autoload classes we may not need.
     35         *
     36         * If SPL is disabled, we load all of SimplePie manually.
     37         *
     38         * Core.php is not loaded manually, because SimplePie_Core (a deprecated class)
     39         * was never included in WordPress core.
     40         */
     41        spl_autoload_register( 'wp_simplepie_autoload' );
     42} else {
     43        require ABSPATH . WPINC . '/SimplePie/Cache/Base.php';
     44        require ABSPATH . WPINC . '/SimplePie/Cache/DB.php';
     45        require ABSPATH . WPINC . '/SimplePie/Cache/File.php';
     46        require ABSPATH . WPINC . '/SimplePie/Cache/Memcache.php';
     47        require ABSPATH . WPINC . '/SimplePie/Cache/MySQL.php';
     48        require ABSPATH . WPINC . '/SimplePie/Caption.php';
     49        require ABSPATH . WPINC . '/SimplePie/Category.php';
     50        require ABSPATH . WPINC . '/SimplePie/Copyright.php';
     51        require ABSPATH . WPINC . '/SimplePie/Credit.php';
     52        require ABSPATH . WPINC . '/SimplePie/Decode/HTML/Entities.php';
     53        require ABSPATH . WPINC . '/SimplePie/Enclosure.php';
     54        require ABSPATH . WPINC . '/SimplePie/gzdecode.php';
     55        require ABSPATH . WPINC . '/SimplePie/HTTP/Parser.php';
     56        require ABSPATH . WPINC . '/SimplePie/Net/IPv6.php';
     57        require ABSPATH . WPINC . '/SimplePie/Rating.php';
     58        require ABSPATH . WPINC . '/SimplePie/Restriction.php';
     59        require ABSPATH . WPINC . '/SimplePie/Source.php';
     60}
     61
    362/**
    463 * SimplePie
     
    766 * Takes the hard work out of managing a complete RSS/Atom solution.
    867 *
    9  * Copyright (c) 2004-2011, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
     68 * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
    1069 * All rights reserved.
    1170 *
     
    3594 *
    3695 * @package SimplePie
    37  * @version 1.2.1
    38  * @copyright 2004-2011 Ryan Parman, Geoffrey Sneddon, Ryan McCue
     96 * @version 1.3
     97 * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
    3998 * @author Ryan Parman
    4099 * @author Geoffrey Sneddon
    41100 * @author Ryan McCue
    42101 * @link http://simplepie.org/ SimplePie
    43  * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
    44102 * @license http://www.opensource.org/licenses/bsd-license.php BSD License
    45  * @todo phpDoc comments
    46103 */
    47104
     
    54111 * SimplePie Version
    55112 */
    56 define('SIMPLEPIE_VERSION', '1.2.1');
     113define('SIMPLEPIE_VERSION', '1.3');
    57114
    58115/**
    59116 * SimplePie Build
    60  */
    61 define('SIMPLEPIE_BUILD', '20111015034325');
     117 * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::get_build() only every load of simplepie.inc)
     118 */
     119define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc::get_build()));
    62120
    63121/**
     
    336394
    337395/**
    338  * Wrong Media RSS Namespace
     396 * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec.
    339397 */
    340398define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
    341399
    342400/**
     401 * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5.
     402 */
     403define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss');
     404
     405/**
     406 * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace.
     407 */
     408define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/');
     409
     410/**
     411 * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace.
     412 */
     413define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss');
     414
     415/**
     416 * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL.
     417 */
     418define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/');
     419
     420/**
    343421 * iTunes RSS Namespace
    344422 */
     
    356434
    357435/**
    358  * Whether we're running on PHP5
    359  */
    360 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
    361 
    362 /**
    363436 * No file source
    364437 */
     
    389462 */
    390463define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
     464
     465
    391466
    392467/**
     
    394469 *
    395470 * @package SimplePie
     471 * @subpackage API
    396472 */
    397473class SimplePie
     
    401477         * @access private
    402478         */
    403         var $data = array();
     479        public $data = array();
    404480
    405481        /**
     
    407483         * @access private
    408484         */
    409         var $error;
     485        public $error;
    410486
    411487        /**
     
    414490         * @access private
    415491         */
    416         var $sanitize;
     492        public $sanitize;
    417493
    418494        /**
     
    421497         * @access private
    422498         */
    423         var $useragent = SIMPLEPIE_USERAGENT;
     499        public $useragent = SIMPLEPIE_USERAGENT;
    424500
    425501        /**
     
    428504         * @access private
    429505         */
    430         var $feed_url;
     506        public $feed_url;
    431507
    432508        /**
     
    435511         * @access private
    436512         */
    437         var $file;
     513        public $file;
    438514
    439515        /**
     
    442518         * @access private
    443519         */
    444         var $raw_data;
     520        public $raw_data;
    445521
    446522        /**
     
    449525         * @access private
    450526         */
    451         var $timeout = 10;
     527        public $timeout = 10;
    452528
    453529        /**
     
    457533         * @access private
    458534         */
    459         var $force_fsockopen = false;
     535        public $force_fsockopen = false;
    460536
    461537        /**
     
    465541         * @access private
    466542         */
    467         var $force_feed = false;
    468 
    469         /**
    470          * @var bool Enable/Disable XML dump
    471          * @see SimplePie::enable_xml_dump()
    472          * @access private
    473          */
    474         var $xml_dump = false;
     543        public $force_feed = false;
    475544
    476545        /**
     
    479548         * @access private
    480549         */
    481         var $cache = true;
     550        public $cache = true;
    482551
    483552        /**
     
    486555         * @access private
    487556         */
    488         var $cache_duration = 3600;
     557        public $cache_duration = 3600;
    489558
    490559        /**
     
    493562         * @access private
    494563         */
    495         var $autodiscovery_cache_duration = 604800; // 7 Days.
     564        public $autodiscovery_cache_duration = 604800; // 7 Days.
    496565
    497566        /**
     
    500569         * @access private
    501570         */
    502         var $cache_location = './cache';
     571        public $cache_location = './cache';
    503572
    504573        /**
     
    507576         * @access private
    508577         */
    509         var $cache_name_function = 'md5';
     578        public $cache_name_function = 'md5';
    510579
    511580        /**
     
    514583         * @access private
    515584         */
    516         var $order_by_date = true;
     585        public $order_by_date = true;
    517586
    518587        /**
     
    522591         * @access private
    523592         */
    524         var $input_encoding = false;
     593        public $input_encoding = false;
    525594
    526595        /**
     
    529598         * @access private
    530599         */
    531         var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
    532 
    533         /**
    534          * @var string Class used for caching feeds
    535          * @see SimplePie::set_cache_class()
    536          * @access private
    537          */
    538         var $cache_class = 'SimplePie_Cache';
    539 
    540         /**
    541          * @var string Class used for locating feeds
    542          * @see SimplePie::set_locator_class()
    543          * @access private
    544          */
    545         var $locator_class = 'SimplePie_Locator';
    546 
    547         /**
    548          * @var string Class used for parsing feeds
    549          * @see SimplePie::set_parser_class()
    550          * @access private
    551          */
    552         var $parser_class = 'SimplePie_Parser';
    553 
    554         /**
    555          * @var string Class used for fetching feeds
    556          * @see SimplePie::set_file_class()
    557          * @access private
    558          */
    559         var $file_class = 'SimplePie_File';
    560 
    561         /**
    562          * @var string Class used for items
    563          * @see SimplePie::set_item_class()
    564          * @access private
    565          */
    566         var $item_class = 'SimplePie_Item';
    567 
    568         /**
    569          * @var string Class used for authors
    570          * @see SimplePie::set_author_class()
    571          * @access private
    572          */
    573         var $author_class = 'SimplePie_Author';
    574 
    575         /**
    576          * @var string Class used for categories
    577          * @see SimplePie::set_category_class()
    578          * @access private
    579          */
    580         var $category_class = 'SimplePie_Category';
    581 
    582         /**
    583          * @var string Class used for enclosures
    584          * @see SimplePie::set_enclosures_class()
    585          * @access private
    586          */
    587         var $enclosure_class = 'SimplePie_Enclosure';
    588 
    589         /**
    590          * @var string Class used for Media RSS <media:text> captions
    591          * @see SimplePie::set_caption_class()
    592          * @access private
    593          */
    594         var $caption_class = 'SimplePie_Caption';
    595 
    596         /**
    597          * @var string Class used for Media RSS <media:copyright>
    598          * @see SimplePie::set_copyright_class()
    599          * @access private
    600          */
    601         var $copyright_class = 'SimplePie_Copyright';
    602 
    603         /**
    604          * @var string Class used for Media RSS <media:credit>
    605          * @see SimplePie::set_credit_class()
    606          * @access private
    607          */
    608         var $credit_class = 'SimplePie_Credit';
    609 
    610         /**
    611          * @var string Class used for Media RSS <media:rating>
    612          * @see SimplePie::set_rating_class()
    613          * @access private
    614          */
    615         var $rating_class = 'SimplePie_Rating';
    616 
    617         /**
    618          * @var string Class used for Media RSS <media:restriction>
    619          * @see SimplePie::set_restriction_class()
    620          * @access private
    621          */
    622         var $restriction_class = 'SimplePie_Restriction';
    623 
    624         /**
    625          * @var string Class used for content-type sniffing
    626          * @see SimplePie::set_content_type_sniffer_class()
    627          * @access private
    628          */
    629         var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
    630 
    631         /**
    632          * @var string Class used for item sources.
    633          * @see SimplePie::set_source_class()
    634          * @access private
    635          */
    636         var $source_class = 'SimplePie_Source';
    637 
    638         /**
    639          * @var mixed Set javascript query string parameter (false, or
    640          * anything type-cast to false, disables this feature)
    641          * @see SimplePie::set_javascript()
    642          * @access private
    643          */
    644         var $javascript = 'js';
     600        public $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
     601
     602        /**
     603         * Class registry object
     604         *
     605         * @var SimplePie_Registry
     606         */
     607        public $registry;
    645608
    646609        /**
     
    649612         * @access private
    650613         */
    651         var $max_checked_feeds = 10;
     614        public $max_checked_feeds = 10;
    652615
    653616        /**
     
    656619         * @access private
    657620         */
    658         var $all_discovered_feeds = array();
    659 
    660         /**
    661          * @var string Web-accessible path to the handler_favicon.php file.
    662          * @see SimplePie::set_favicon_handler()
    663          * @access private
    664          */
    665         var $favicon_handler = '';
     621        public $all_discovered_feeds = array();
    666622
    667623        /**
     
    670626         * @access private
    671627         */
    672         var $image_handler = '';
     628        public $image_handler = '';
    673629
    674630        /**
     
    677633         * @access private
    678634         */
    679         var $multifeed_url = array();
     635        public $multifeed_url = array();
    680636
    681637        /**
     
    683639         * @access private
    684640         */
    685         var $multifeed_objects = array();
     641        public $multifeed_objects = array();
    686642
    687643        /**
     
    690646         * @access private
    691647         */
    692         var $config_settings = null;
     648        public $config_settings = null;
    693649
    694650        /**
     
    697653         * @access private
    698654         */
    699         var $item_limit = 0;
     655        public $item_limit = 0;
    700656
    701657        /**
     
    704660         * @access private
    705661         */
    706         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
     662        public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
    707663
    708664        /**
     
    711667         * @access private
    712668         */
    713         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
     669        public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
    714670
    715671        /**
    716672         * The SimplePie class contains feed level data and options
    717673         *
    718          * There are two ways that you can create a new SimplePie object. The first
    719          * is by passing a feed URL as a parameter to the SimplePie constructor
    720          * (as well as optionally setting the cache location and cache expiry). This
    721          * will initialise the whole feed with all of the default settings, and you
    722          * can begin accessing methods and properties immediately.
    723          *
    724          * The second way is to create the SimplePie object with no parameters
    725          * at all. This will enable you to set configuration options. After setting
     674         * To use SimplePie, create the SimplePie object with no parameters. You can
     675         * then set configuration options using the provided methods. After setting
    726676         * them, you must initialise the feed using $feed->init(). At that point the
    727          * object's methods and properties will be available to you. This format is
    728          * what is used throughout this documentation.
    729          *
    730          * @access public
     677         * object's methods and properties will be available to you.
     678         *
     679         * Previously, it was possible to pass in the feed URL along with cache
     680         * options directly into the constructor. This has been removed as of 1.3 as
     681         * it caused a lot of confusion.
     682         *
    731683         * @since 1.0 Preview Release
    732          * @param string $feed_url This is the URL you want to parse.
    733          * @param string $cache_location This is where you want the cache to be stored.
    734          * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
    735          */
    736         function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
    737         {
     684         */
     685        public function __construct()
     686        {
     687                if (version_compare(PHP_VERSION, '5.2', '<'))
     688                {
     689                        trigger_error('PHP 4.x, 5.0 and 5.1 are no longer supported. Please upgrade to PHP 5.2 or newer.');
     690                        die();
     691                }
     692
    738693                // Other objects, instances created here so we can set options on them
    739                 $this->sanitize =& new SimplePie_Sanitize;
    740 
    741                 // Set options if they're passed to the constructor
    742                 if ($cache_location !== null)
    743                 {
    744                         $this->set_cache_location($cache_location);
    745                 }
    746 
    747                 if ($cache_duration !== null)
    748                 {
    749                         $this->set_cache_duration($cache_duration);
    750                 }
    751 
    752                 // Only init the script if we're passed a feed URL
    753                 if ($feed_url !== null)
    754                 {
    755                         $this->set_feed_url($feed_url);
    756                         $this->init();
     694                $this->sanitize = new SimplePie_Sanitize();
     695                $this->registry = new SimplePie_Registry();
     696
     697                if (func_num_args() > 0)
     698                {
     699                        trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_location() directly.');
    757700                }
    758701        }
     
    761704         * Used for converting object to a string
    762705         */
    763         function __toString()
     706        public function __toString()
    764707        {
    765708                return md5(serialize($this->data));
     
    769712         * Remove items that link back to this before destroying this object
    770713         */
    771         function __destruct()
     714        public function __destruct()
    772715        {
    773716                if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
     
    793736
    794737        /**
    795          * Force the given data/URL to be treated as a feed no matter what it
    796          * appears like
    797          *
    798          * @access public
     738         * Force the given data/URL to be treated as a feed
     739         *
     740         * This tells SimplePie to ignore the content-type provided by the server.
     741         * Be careful when using this option, as it will also disable autodiscovery.
     742         *
    799743         * @since 1.1
    800744         * @param bool $enable Force the given data/URL to be treated as a feed
    801745         */
    802         function force_feed($enable = false)
     746        public function force_feed($enable = false)
    803747        {
    804748                $this->force_feed = (bool) $enable;
     
    806750
    807751        /**
    808          * This is the URL of the feed you want to parse.
     752         * Set the URL of the feed you want to parse
    809753         *
    810754         * This allows you to enter the URL of the feed you want to parse, or the
     
    816760         * additional processing and resources.
    817761         *
    818          * @access public
    819762         * @since 1.0 Preview Release
    820          * @param mixed $url This is the URL (or array of URLs) that you want to parse.
    821          * @see SimplePie::set_raw_data()
    822          */
    823         function set_feed_url($url)
    824         {
     763         * @see set_raw_data()
     764         * @param string|array $url This is the URL (or array of URLs) that you want to parse.
     765         */
     766        public function set_feed_url($url)
     767        {
     768                $this->multifeed_url = array();
    825769                if (is_array($url))
    826770                {
    827                         $this->multifeed_url = array();
    828771                        foreach ($url as $value)
    829772                        {
    830                                 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
     773                                $this->multifeed_url[] = $this->registry->call('Misc', 'fix_protocol', array($value, 1));
    831774                        }
    832775                }
    833776                else
    834777                {
    835                         $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
    836                 }
    837         }
    838 
    839         /**
    840          * Provides an instance of SimplePie_File to use as a feed
    841          *
    842          * @access public
    843          * @param object &$file Instance of SimplePie_File (or subclass)
     778                        $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1));
     779                }
     780        }
     781
     782        /**
     783         * Set an instance of {@see SimplePie_File} to use as a feed
     784         *
     785         * @param SimplePie_File &$file
    844786         * @return bool True on success, false on failure
    845787         */
    846         function set_file(&$file)
    847         {
    848                 if (is_a($file, 'SimplePie_File'))
     788        public function set_file(&$file)
     789        {
     790                if ($file instanceof SimplePie_File)
    849791                {
    850792                        $this->feed_url = $file->url;
     
    856798
    857799        /**
     800         * Set the raw XML data to parse
     801         *
    858802         * Allows you to use a string of RSS/Atom data instead of a remote feed.
    859803         *
     
    862806         * takes precedence.
    863807         *
    864          * @access public
    865808         * @since 1.0 Beta 3
    866809         * @param string $data RSS or Atom data as a string.
    867          * @see SimplePie::set_feed_url()
    868          */
    869         function set_raw_data($data)
     810         * @see set_feed_url()
     811         */
     812        public function set_raw_data($data)
    870813        {
    871814                $this->raw_data = $data;
     
    873816
    874817        /**
    875          * Allows you to override the default timeout for fetching remote feeds.
     818         * Set the the default timeout for fetching remote feeds
    876819         *
    877820         * This allows you to change the maximum time the feed's server to respond
    878821         * and send the feed back.
    879822         *
    880          * @access public
    881823         * @since 1.0 Beta 3
    882824         * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
    883825         */
    884         function set_timeout($timeout = 10)
     826        public function set_timeout($timeout = 10)
    885827        {
    886828                $this->timeout = (int) $timeout;
     
    888830
    889831        /**
    890          * Forces SimplePie to use fsockopen() instead of the preferred cURL
    891          * functions.
    892          *
    893          * @access public
     832         * Force SimplePie to use fsockopen() instead of cURL
     833         *
    894834         * @since 1.0 Beta 3
    895835         * @param bool $enable Force fsockopen() to be used
    896836         */
    897         function force_fsockopen($enable = false)
     837        public function force_fsockopen($enable = false)
    898838        {
    899839                $this->force_fsockopen = (bool) $enable;
     
    901841
    902842        /**
    903          * Outputs the raw XML content of the feed, after it has gone through
    904          * SimplePie's filters.
    905          *
    906          * Used only for debugging, this function will output the XML content as
    907          * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
    908          * before trying to parse it. Many parts of the feed are re-written in
    909          * memory, and in the end, you have a parsable feed. XML dump shows you the
    910          * actual XML that SimplePie tries to parse, which may or may not be very
    911          * different from the original feed.
    912          *
    913          * @access public
    914          * @since 1.0 Preview Release
    915          * @param bool $enable Enable XML dump
    916          */
    917         function enable_xml_dump($enable = false)
    918         {
    919                 $this->xml_dump = (bool) $enable;
    920         }
    921 
    922         /**
    923          * Enables/disables caching in SimplePie.
     843         * Enable/disable caching in SimplePie.
    924844         *
    925845         * This option allows you to disable caching all-together in SimplePie.
    926846         * However, disabling the cache can lead to longer load times.
    927847         *
    928          * @access public
    929848         * @since 1.0 Preview Release
    930849         * @param bool $enable Enable caching
    931850         */
    932         function enable_cache($enable = true)
     851        public function enable_cache($enable = true)
    933852        {
    934853                $this->cache = (bool) $enable;
     
    936855
    937856        /**
    938          * Set the length of time (in seconds) that the contents of a feed
    939          * will be cached.
    940          *
    941          * @access public
    942          * @param int $seconds The feed content cache duration.
    943          */
    944         function set_cache_duration($seconds = 3600)
     857         * Set the length of time (in seconds) that the contents of a feed will be
     858         * cached
     859         *
     860         * @param int $seconds The feed content cache duration
     861         */
     862        public function set_cache_duration($seconds = 3600)
    945863        {
    946864                $this->cache_duration = (int) $seconds;
     
    948866
    949867        /**
    950          * Set the length of time (in seconds) that the autodiscovered feed
    951          * URL will be cached.
    952          *
    953          * @access public
     868         * Set the length of time (in seconds) that the autodiscovered feed URL will
     869         * be cached
     870         *
    954871         * @param int $seconds The autodiscovered feed URL cache duration.
    955872         */
    956         function set_autodiscovery_cache_duration($seconds = 604800)
     873        public function set_autodiscovery_cache_duration($seconds = 604800)
    957874        {
    958875                $this->autodiscovery_cache_duration = (int) $seconds;
     
    960877
    961878        /**
    962          * Set the file system location where the cached files should be stored.
    963          *
    964          * @access public
     879         * Set the file system location where the cached files should be stored
     880         *
    965881         * @param string $location The file system location.
    966882         */
    967         function set_cache_location($location = './cache')
     883        public function set_cache_location($location = './cache')
    968884        {
    969885                $this->cache_location = (string) $location;
     
    971887
    972888        /**
    973          * Determines whether feed items should be sorted into reverse chronological order.
    974          *
    975          * @access public
     889         * Set whether feed items should be sorted into reverse chronological order
     890         *
    976891         * @param bool $enable Sort as reverse chronological order.
    977892         */
    978         function enable_order_by_date($enable = true)
     893        public function enable_order_by_date($enable = true)
    979894        {
    980895                $this->order_by_date = (bool) $enable;
     
    982897
    983898        /**
    984          * Allows you to override the character encoding reported by the feed.
    985          *
    986          * @access public
    987          * @param string $encoding Character encoding.
    988          */
    989         function set_input_encoding($encoding = false)
     899         * Set the character encoding used to parse the feed
     900         *
     901         * This overrides the encoding reported by the feed, however it will fall
     902         * back to the normal encoding detection if the override fails
     903         *
     904         * @param string $encoding Character encoding
     905         */
     906        public function set_input_encoding($encoding = false)
    990907        {
    991908                if ($encoding)
     
    1002919         * Set how much feed autodiscovery to do
    1003920         *
    1004          * @access public
    1005921         * @see SIMPLEPIE_LOCATOR_NONE
    1006922         * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
     
    1010926         * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
    1011927         * @see SIMPLEPIE_LOCATOR_ALL
    1012          * @param int $level Feed Autodiscovery Level (level can be a
    1013          * combination of the above constants, see bitwise OR operator)
    1014          */
    1015         function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
     928         * @param int $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator)
     929         */
     930        public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
    1016931        {
    1017932                $this->autodiscovery = (int) $level;
     
    1019934
    1020935        /**
    1021          * Allows you to change which class SimplePie uses for caching.
     936         * Get the class registry
     937         *
     938         * Use this to override SimplePie's default classes
     939         * @see SimplePie_Registry
     940         * @return SimplePie_Registry
     941         */
     942        public function &get_registry()
     943        {
     944                return $this->registry;
     945        }
     946
     947        /**#@+
    1022948         * Useful when you are overloading or extending SimplePie's default classes.
    1023949         *
    1024          * @access public
    1025          * @param string $class Name of custom class.
    1026          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
     950         * @deprecated Use {@see get_registry()} instead
    1027951         * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1028          */
    1029         function set_cache_class($class = 'SimplePie_Cache')
    1030         {
    1031                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
    1032                 {
    1033                         $this->cache_class = $class;
    1034                         return true;
    1035                 }
    1036                 return false;
    1037         }
    1038 
    1039         /**
    1040          * Allows you to change which class SimplePie uses for auto-discovery.
    1041          * Useful when you are overloading or extending SimplePie's default classes.
    1042          *
    1043          * @access public
    1044          * @param string $class Name of custom class.
    1045          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1046          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1047          */
    1048         function set_locator_class($class = 'SimplePie_Locator')
    1049         {
    1050                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
    1051                 {
    1052                         $this->locator_class = $class;
    1053                         return true;
    1054                 }
    1055                 return false;
    1056         }
    1057 
    1058         /**
    1059          * Allows you to change which class SimplePie uses for XML parsing.
    1060          * Useful when you are overloading or extending SimplePie's default classes.
    1061          *
    1062          * @access public
    1063          * @param string $class Name of custom class.
    1064          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1065          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1066          */
    1067         function set_parser_class($class = 'SimplePie_Parser')
    1068         {
    1069                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
    1070                 {
    1071                         $this->parser_class = $class;
    1072                         return true;
    1073                 }
    1074                 return false;
    1075         }
    1076 
    1077         /**
    1078          * Allows you to change which class SimplePie uses for remote file fetching.
    1079          * Useful when you are overloading or extending SimplePie's default classes.
    1080          *
    1081          * @access public
    1082          * @param string $class Name of custom class.
    1083          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1084          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1085          */
    1086         function set_file_class($class = 'SimplePie_File')
    1087         {
    1088                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
    1089                 {
    1090                         $this->file_class = $class;
    1091                         return true;
    1092                 }
    1093                 return false;
    1094         }
    1095 
    1096         /**
    1097          * Allows you to change which class SimplePie uses for data sanitization.
    1098          * Useful when you are overloading or extending SimplePie's default classes.
    1099          *
    1100          * @access public
    1101          * @param string $class Name of custom class.
    1102          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1103          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1104          */
    1105         function set_sanitize_class($class = 'SimplePie_Sanitize')
    1106         {
    1107                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
    1108                 {
    1109                         $this->sanitize =& new $class;
    1110                         return true;
    1111                 }
    1112                 return false;
    1113         }
    1114 
    1115         /**
    1116          * Allows you to change which class SimplePie uses for handling feed items.
    1117          * Useful when you are overloading or extending SimplePie's default classes.
    1118          *
    1119          * @access public
    1120          * @param string $class Name of custom class.
    1121          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1122          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1123          */
    1124         function set_item_class($class = 'SimplePie_Item')
    1125         {
    1126                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
    1127                 {
    1128                         $this->item_class = $class;
    1129                         return true;
    1130                 }
    1131                 return false;
    1132         }
    1133 
    1134         /**
    1135          * Allows you to change which class SimplePie uses for handling author data.
    1136          * Useful when you are overloading or extending SimplePie's default classes.
    1137          *
    1138          * @access public
    1139          * @param string $class Name of custom class.
    1140          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1141          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1142          */
    1143         function set_author_class($class = 'SimplePie_Author')
    1144         {
    1145                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
    1146                 {
    1147                         $this->author_class = $class;
    1148                         return true;
    1149                 }
    1150                 return false;
    1151         }
    1152 
    1153         /**
    1154          * Allows you to change which class SimplePie uses for handling category data.
    1155          * Useful when you are overloading or extending SimplePie's default classes.
    1156          *
    1157          * @access public
    1158          * @param string $class Name of custom class.
    1159          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1160          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1161          */
    1162         function set_category_class($class = 'SimplePie_Category')
    1163         {
    1164                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
    1165                 {
    1166                         $this->category_class = $class;
    1167                         return true;
    1168                 }
    1169                 return false;
    1170         }
    1171 
    1172         /**
    1173          * Allows you to change which class SimplePie uses for feed enclosures.
    1174          * Useful when you are overloading or extending SimplePie's default classes.
    1175          *
    1176          * @access public
    1177          * @param string $class Name of custom class.
    1178          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1179          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1180          */
    1181         function set_enclosure_class($class = 'SimplePie_Enclosure')
    1182         {
    1183                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
    1184                 {
    1185                         $this->enclosure_class = $class;
    1186                         return true;
    1187                 }
    1188                 return false;
    1189         }
    1190 
    1191         /**
    1192          * Allows you to change which class SimplePie uses for <media:text> captions
    1193          * Useful when you are overloading or extending SimplePie's default classes.
    1194          *
    1195          * @access public
    1196          * @param string $class Name of custom class.
    1197          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1198          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1199          */
    1200         function set_caption_class($class = 'SimplePie_Caption')
    1201         {
    1202                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
    1203                 {
    1204                         $this->caption_class = $class;
    1205                         return true;
    1206                 }
    1207                 return false;
    1208         }
    1209 
    1210         /**
    1211          * Allows you to change which class SimplePie uses for <media:copyright>
    1212          * Useful when you are overloading or extending SimplePie's default classes.
    1213          *
    1214          * @access public
    1215          * @param string $class Name of custom class.
    1216          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1217          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1218          */
    1219         function set_copyright_class($class = 'SimplePie_Copyright')
    1220         {
    1221                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
    1222                 {
    1223                         $this->copyright_class = $class;
    1224                         return true;
    1225                 }
    1226                 return false;
    1227         }
    1228 
    1229         /**
    1230          * Allows you to change which class SimplePie uses for <media:credit>
    1231          * Useful when you are overloading or extending SimplePie's default classes.
    1232          *
    1233          * @access public
    1234          * @param string $class Name of custom class.
    1235          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1236          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1237          */
    1238         function set_credit_class($class = 'SimplePie_Credit')
    1239         {
    1240                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
    1241                 {
    1242                         $this->credit_class = $class;
    1243                         return true;
    1244                 }
    1245                 return false;
    1246         }
    1247 
    1248         /**
    1249          * Allows you to change which class SimplePie uses for <media:rating>
    1250          * Useful when you are overloading or extending SimplePie's default classes.
    1251          *
    1252          * @access public
    1253          * @param string $class Name of custom class.
    1254          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1255          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1256          */
    1257         function set_rating_class($class = 'SimplePie_Rating')
    1258         {
    1259                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
    1260                 {
    1261                         $this->rating_class = $class;
    1262                         return true;
    1263                 }
    1264                 return false;
    1265         }
    1266 
    1267         /**
    1268          * Allows you to change which class SimplePie uses for <media:restriction>
    1269          * Useful when you are overloading or extending SimplePie's default classes.
    1270          *
    1271          * @access public
    1272          * @param string $class Name of custom class.
    1273          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1274          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1275          */
    1276         function set_restriction_class($class = 'SimplePie_Restriction')
    1277         {
    1278                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
    1279                 {
    1280                         $this->restriction_class = $class;
    1281                         return true;
    1282                 }
    1283                 return false;
    1284         }
    1285 
    1286         /**
    1287          * Allows you to change which class SimplePie uses for content-type sniffing.
    1288          * Useful when you are overloading or extending SimplePie's default classes.
    1289          *
    1290          * @access public
    1291          * @param string $class Name of custom class.
    1292          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1293          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1294          */
    1295         function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
    1296         {
    1297                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
    1298                 {
    1299                         $this->content_type_sniffer_class = $class;
    1300                         return true;
    1301                 }
    1302                 return false;
    1303         }
    1304 
    1305         /**
    1306          * Allows you to change which class SimplePie uses item sources.
    1307          * Useful when you are overloading or extending SimplePie's default classes.
    1308          *
    1309          * @access public
    1310          * @param string $class Name of custom class.
    1311          * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
    1312          * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
    1313          */
    1314         function set_source_class($class = 'SimplePie_Source')
    1315         {
    1316                 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
    1317                 {
    1318                         $this->source_class = $class;
    1319                         return true;
    1320                 }
    1321                 return false;
    1322         }
    1323 
    1324         /**
    1325          * Allows you to override the default user agent string.
    1326          *
    1327          * @access public
     952         * @param string $class Name of custom class
     953         * @return boolean True on success, false otherwise
     954         */
     955        /**
     956         * Set which class SimplePie uses for caching
     957         */
     958        public function set_cache_class($class = 'SimplePie_Cache')
     959        {
     960                return $this->registry->register('Cache', $class, true);
     961        }
     962
     963        /**
     964         * Set which class SimplePie uses for auto-discovery
     965         */
     966        public function set_locator_class($class = 'SimplePie_Locator')
     967        {
     968                return $this->registry->register('Locator', $class, true);
     969        }
     970
     971        /**
     972         * Set which class SimplePie uses for XML parsing
     973         */
     974        public function set_parser_class($class = 'SimplePie_Parser')
     975        {
     976                return $this->registry->register('Parser', $class, true);
     977        }
     978
     979        /**
     980         * Set which class SimplePie uses for remote file fetching
     981         */
     982        public function set_file_class($class = 'SimplePie_File')
     983        {
     984                return $this->registry->register('File', $class, true);
     985        }
     986
     987        /**
     988         * Set which class SimplePie uses for data sanitization
     989         */
     990        public function set_sanitize_class($class = 'SimplePie_Sanitize')
     991        {
     992                return $this->registry->register('Sanitize', $class, true);
     993        }
     994
     995        /**
     996         * Set which class SimplePie uses for handling feed items
     997         */
     998        public function set_item_class($class = 'SimplePie_Item')
     999        {
     1000                return $this->registry->register('Item', $class, true);
     1001        }
     1002
     1003        /**
     1004         * Set which class SimplePie uses for handling author data
     1005         */
     1006        public function set_author_class($class = 'SimplePie_Author')
     1007        {
     1008                return $this->registry->register('Author', $class, true);
     1009        }
     1010
     1011        /**
     1012         * Set which class SimplePie uses for handling category data
     1013         */
     1014        public function set_category_class($class = 'SimplePie_Category')
     1015        {
     1016                return $this->registry->register('Category', $class, true);
     1017        }
     1018
     1019        /**
     1020         * Set which class SimplePie uses for feed enclosures
     1021         */
     1022        public function set_enclosure_class($class = 'SimplePie_Enclosure')
     1023        {
     1024                return $this->registry->register('Enclosure', $class, true);
     1025        }
     1026
     1027        /**
     1028         * Set which class SimplePie uses for `<media:text>` captions
     1029         */
     1030        public function set_caption_class($class = 'SimplePie_Caption')
     1031        {
     1032                return $this->registry->register('Caption', $class, true);
     1033        }
     1034
     1035        /**
     1036         * Set which class SimplePie uses for `<media:copyright>`
     1037         */
     1038        public function set_copyright_class($class = 'SimplePie_Copyright')
     1039        {
     1040                return $this->registry->register('Copyright', $class, true);
     1041        }
     1042
     1043        /**
     1044         * Set which class SimplePie uses for `<media:credit>`
     1045         */
     1046        public function set_credit_class($class = 'SimplePie_Credit')
     1047        {
     1048                return $this->registry->register('Credit', $class, true);
     1049        }
     1050
     1051        /**
     1052         * Set which class SimplePie uses for `<media:rating>`
     1053         */
     1054        public function set_rating_class($class = 'SimplePie_Rating')
     1055        {
     1056                return $this->registry->register('Rating', $class, true);
     1057        }
     1058
     1059        /**
     1060         * Set which class SimplePie uses for `<media:restriction>`
     1061         */
     1062        public function set_restriction_class($class = 'SimplePie_Restriction')
     1063        {
     1064                return $this->registry->register('Restriction', $class, true);
     1065        }
     1066
     1067        /**
     1068         * Set which class SimplePie uses for content-type sniffing
     1069         */
     1070        public function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
     1071        {
     1072                return $this->registry->register('Content_Type_Sniffer', $class, true);
     1073        }
     1074
     1075        /**
     1076         * Set which class SimplePie uses item sources
     1077         */
     1078        public function set_source_class($class = 'SimplePie_Source')
     1079        {
     1080                return $this->registry->register('Source', $class, true);
     1081        }
     1082        /**#@-*/
     1083
     1084        /**
     1085         * Set the user agent string
     1086         *
    13281087         * @param string $ua New user agent string.
    13291088         */
    1330         function set_useragent($ua = SIMPLEPIE_USERAGENT)
     1089        public function set_useragent($ua = SIMPLEPIE_USERAGENT)
    13311090        {
    13321091                $this->useragent = (string) $ua;
     
    13361095         * Set callback function to create cache filename with
    13371096         *
    1338          * @access public
    13391097         * @param mixed $function Callback function
    13401098         */
    1341         function set_cache_name_function($function = 'md5')
     1099        public function set_cache_name_function($function = 'md5')
    13421100        {
    13431101                if (is_callable($function))
     
    13481106
    13491107        /**
    1350          * Set javascript query string parameter
    1351          *
    1352          * @access public
    1353          * @param mixed $get Javascript query string parameter
    1354          */
    1355         function set_javascript($get = 'js')
    1356         {
    1357                 if ($get)
    1358                 {
    1359                         $this->javascript = (string) $get;
    1360                 }
    1361                 else
    1362                 {
    1363                         $this->javascript = false;
    1364                 }
    1365         }
    1366 
    1367         /**
    1368          * Set options to make SP as fast as possible.  Forgoes a
    1369          * substantial amount of data sanitization in favor of speed.
    1370          *
    1371          * @access public
     1108         * Set options to make SP as fast as possible
     1109         *
     1110         * Forgoes a substantial amount of data sanitization in favor of speed. This
     1111         * turns SimplePie into a dumb parser of feeds.
     1112         *
    13721113         * @param bool $set Whether to set them or not
    13731114         */
    1374         function set_stupidly_fast($set = false)
     1115        public function set_stupidly_fast($set = false)
    13751116        {
    13761117                if ($set)
     
    13881129         * Set maximum number of feeds to check with autodiscovery
    13891130         *
    1390          * @access public
    13911131         * @param int $max Maximum number of feeds to check
    13921132         */
    1393         function set_max_checked_feeds($max = 10)
     1133        public function set_max_checked_feeds($max = 10)
    13941134        {
    13951135                $this->max_checked_feeds = (int) $max;
    13961136        }
    13971137
    1398         function remove_div($enable = true)
     1138        public function remove_div($enable = true)
    13991139        {
    14001140                $this->sanitize->remove_div($enable);
    14011141        }
    14021142
    1403         function strip_htmltags($tags = '', $encode = null)
     1143        public function strip_htmltags($tags = '', $encode = null)
    14041144        {
    14051145                if ($tags === '')
     
    14141154        }
    14151155
    1416         function encode_instead_of_strip($enable = true)
     1156        public function encode_instead_of_strip($enable = true)
    14171157        {
    14181158                $this->sanitize->encode_instead_of_strip($enable);
    14191159        }
    14201160
    1421         function strip_attributes($attribs = '')
     1161        public function strip_attributes($attribs = '')
    14221162        {
    14231163                if ($attribs === '')
     
    14281168        }
    14291169
    1430         function set_output_encoding($encoding = 'UTF-8')
     1170        /**
     1171         * Set the output encoding
     1172         *
     1173         * Allows you to override SimplePie's output to match that of your webpage.
     1174         * This is useful for times when your webpages are not being served as
     1175         * UTF-8.  This setting will be obeyed by {@see handle_content_type()}, and
     1176         * is similar to {@see set_input_encoding()}.
     1177         *
     1178         * It should be noted, however, that not all character encodings can support
     1179         * all characters.  If your page is being served as ISO-8859-1 and you try
     1180         * to display a Japanese feed, you'll likely see garbled characters.
     1181         * Because of this, it is highly recommended to ensure that your webpages
     1182         * are served as UTF-8.
     1183         *
     1184         * The number of supported character encodings depends on whether your web
     1185         * host supports {@link http://php.net/mbstring mbstring},
     1186         * {@link http://php.net/iconv iconv}, or both. See
     1187         * {@link http://simplepie.org/wiki/faq/Supported_Character_Encodings} for
     1188         * more information.
     1189         *
     1190         * @param string $encoding
     1191         */
     1192        public function set_output_encoding($encoding = 'UTF-8')
    14311193        {
    14321194                $this->sanitize->set_output_encoding($encoding);
    14331195        }
    14341196
    1435         function strip_comments($strip = false)
     1197        public function strip_comments($strip = false)
    14361198        {
    14371199                $this->sanitize->strip_comments($strip);
     
    14421204         * containing URLs that need to be resolved relative to the feed
    14431205         *
    1444          * @access public
     1206         * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite,
     1207         * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite,
     1208         * |q|@cite
     1209         *
    14451210         * @since 1.0
    1446          * @param array $element_attribute Element/attribute key/value pairs
    1447          */
    1448         function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
     1211         * @param array|null $element_attribute Element/attribute key/value pairs, null for default
     1212         */
     1213        public function set_url_replacements($element_attribute = null)
    14491214        {
    14501215                $this->sanitize->set_url_replacements($element_attribute);
     
    14521217
    14531218        /**
    1454          * Set the handler to enable the display of cached favicons.
    1455          *
    1456          * @access public
    1457          * @param str $page Web-accessible path to the handler_favicon.php file.
    1458          * @param str $qs The query string that the value should be passed to.
    1459          */
    1460         function set_favicon_handler($page = false, $qs = 'i')
    1461         {
    1462                 if ($page !== false)
    1463                 {
    1464                         $this->favicon_handler = $page . '?' . $qs . '=';
    1465                 }
    1466                 else
    1467                 {
    1468                         $this->favicon_handler = '';
    1469                 }
    1470         }
    1471 
    1472         /**
    14731219         * Set the handler to enable the display of cached images.
    14741220         *
    1475          * @access public
    14761221         * @param str $page Web-accessible path to the handler_image.php file.
    14771222         * @param str $qs The query string that the value should be passed to.
    14781223         */
    1479         function set_image_handler($page = false, $qs = 'i')
     1224        public function set_image_handler($page = false, $qs = 'i')
    14801225        {
    14811226                if ($page !== false)
     
    14901235
    14911236        /**
    1492          * Set the limit for items returned per-feed with multifeeds.
    1493          *
    1494          * @access public
     1237         * Set the limit for items returned per-feed with multifeeds
     1238         *
    14951239         * @param integer $limit The maximum number of items to return.
    14961240         */
    1497         function set_item_limit($limit = 0)
     1241        public function set_item_limit($limit = 0)
    14981242        {
    14991243                $this->item_limit = (int) $limit;
    15001244        }
    15011245
    1502         function init()
     1246        /**
     1247         * Initialize the feed object
     1248         *
     1249         * This is what makes everything happen.  Period.  This is where all of the
     1250         * configuration options get processed, feeds are fetched, cached, and
     1251         * parsed, and all of that other good stuff.
     1252         *
     1253         * @return boolean True if successful, false otherwise
     1254         */
     1255        public function init()
    15031256        {
    15041257                // Check absolute bare minimum requirements.
    1505                 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
     1258                if (!extension_loaded('xml') || !extension_loaded('pcre'))
    15061259                {
    15071260                        return false;
     
    15241277                }
    15251278
    1526                 if (isset($_GET[$this->javascript]))
    1527                 {
    1528                         SimplePie_Misc::output_javascript();
    1529                         exit;
     1279                if (method_exists($this->sanitize, 'set_registry'))
     1280                {
     1281                        $this->sanitize->set_registry($this->registry);
    15301282                }
    15311283
    15321284                // Pass whatever was set with config options over to the sanitizer.
    1533                 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
    1534                 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
    1535 
    1536                 if ($this->feed_url !== null || $this->raw_data !== null)
    1537                 {
    1538                         $this->data = array();
     1285                // Pass the classes in for legacy support; new classes should use the registry instead
     1286                $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache'));
     1287                $this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen);
     1288
     1289                if (!empty($this->multifeed_url))
     1290                {
     1291                        $i = 0;
     1292                        $success = 0;
    15391293                        $this->multifeed_objects = array();
    1540                         $cache = false;
    1541 
    1542                         if ($this->feed_url !== null)
    1543                         {
    1544                                 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
    1545                                 // Decide whether to enable caching
    1546                                 if ($this->cache && $parsed_feed_url['scheme'] !== '')
    1547                                 {
    1548                                         $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
    1549                                 }
    1550                                 // If it's enabled and we don't want an XML dump, use the cache
    1551                                 if ($cache && !$this->xml_dump)
    1552                                 {
    1553                                         // Load the Cache
    1554                                         $this->data = $cache->load();
    1555                                         if (!empty($this->data))
     1294                        $this->error = array();
     1295                        foreach ($this->multifeed_url as $url)
     1296                        {
     1297                                $this->multifeed_objects[$i] = clone $this;
     1298                                $this->multifeed_objects[$i]->set_feed_url($url);
     1299                                $single_success = $this->multifeed_objects[$i]->init();
     1300                                $success |= $single_success;
     1301                                if (!$single_success)
     1302                                {
     1303                                        $this->error[$i] = $this->multifeed_objects[$i]->error();
     1304                                }
     1305                                $i++;
     1306                        }
     1307                        return (bool) $success;
     1308                }
     1309                elseif ($this->feed_url === null && $this->raw_data === null)
     1310                {
     1311                        return false;
     1312                }
     1313
     1314                $this->error = null;
     1315                $this->data = array();
     1316                $this->multifeed_objects = array();
     1317                $cache = false;
     1318
     1319                if ($this->feed_url !== null)
     1320                {
     1321                        $parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url));
     1322
     1323                        // Decide whether to enable caching
     1324                        if ($this->cache && $parsed_feed_url['scheme'] !== '')
     1325                        {
     1326                                $cache = $this->registry->call('Cache', 'create', array($this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'));
     1327                        }
     1328
     1329                        // Fetch the data via SimplePie_File into $this->raw_data
     1330                        if (($fetched = $this->fetch_data($cache)) === true)
     1331                        {
     1332                                return true;
     1333                        }
     1334                        elseif ($fetched === false) {
     1335                                return false;
     1336                        }
     1337
     1338                        list($headers, $sniffed) = $fetched;
     1339                }
     1340
     1341                // Set up array of possible encodings
     1342                $encodings = array();
     1343
     1344                // First check to see if input has been overridden.
     1345                if ($this->input_encoding !== false)
     1346                {
     1347                        $encodings[] = $this->input_encoding;
     1348                }
     1349
     1350                $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
     1351                $text_types = array('text/xml', 'text/xml-external-parsed-entity');
     1352
     1353                // RFC 3023 (only applies to sniffed content)
     1354                if (isset($sniffed))
     1355                {
     1356                        if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
     1357                        {
     1358                                if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
     1359                                {
     1360                                        $encodings[] = strtoupper($charset[1]);
     1361                                }
     1362                                $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
     1363                                $encodings[] = 'UTF-8';
     1364                        }
     1365                        elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
     1366                        {
     1367                                if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
     1368                                {
     1369                                        $encodings[] = $charset[1];
     1370                                }
     1371                                $encodings[] = 'US-ASCII';
     1372                        }
     1373                        // Text MIME-type default
     1374                        elseif (substr($sniffed, 0, 5) === 'text/')
     1375                        {
     1376                                $encodings[] = 'US-ASCII';
     1377                        }
     1378                }
     1379
     1380                // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
     1381                $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
     1382                $encodings[] = 'UTF-8';
     1383                $encodings[] = 'ISO-8859-1';
     1384
     1385                // There's no point in trying an encoding twice
     1386                $encodings = array_unique($encodings);
     1387
     1388                // Loop through each possible encoding, till we return something, or run out of possibilities
     1389                foreach ($encodings as $encoding)
     1390                {
     1391                        // Change the encoding to UTF-8 (as we always use UTF-8 internally)
     1392                        if ($utf8_data = $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8')))
     1393                        {
     1394                                // Create new parser
     1395                                $parser = $this->registry->create('Parser');
     1396
     1397                                // If it's parsed fine
     1398                                if ($parser->parse($utf8_data, 'UTF-8'))
     1399                                {
     1400                                        $this->data = $parser->get_data();
     1401                                        if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE))
    15561402                                        {
    1557                                                 // If the cache is for an outdated build of SimplePie
    1558                                                 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
     1403                                                $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
     1404                                                $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
     1405                                                return false;
     1406                                        }
     1407
     1408                                        if (isset($headers))
     1409                                        {
     1410                                                $this->data['headers'] = $headers;
     1411                                        }
     1412                                        $this->data['build'] = SIMPLEPIE_BUILD;
     1413
     1414                                        // Cache the file if caching is enabled
     1415                                        if ($cache && !$cache->save($this))
     1416                                        {
     1417                                                trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
     1418                                        }
     1419                                        return true;
     1420                                }
     1421                        }
     1422                }
     1423
     1424                if (isset($parser))
     1425                {
     1426                        // We have an error, just set SimplePie_Misc::error to it and quit
     1427                        $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
     1428                }
     1429                else
     1430                {
     1431                        $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
     1432                }
     1433
     1434                $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
     1435
     1436                return false;
     1437        }
     1438
     1439        /**
     1440         * Fetch the data via SimplePie_File
     1441         *
     1442         * If the data is already cached, attempt to fetch it from there instead
     1443         * @param SimplePie_Cache|false $cache Cache handler, or false to not load from the cache
     1444         * @return array|true Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type
     1445         */
     1446        protected function fetch_data(&$cache)
     1447        {
     1448                // If it's enabled, use the cache
     1449                if ($cache)
     1450                {
     1451                        // Load the Cache
     1452                        $this->data = $cache->load();
     1453                        if (!empty($this->data))
     1454                        {
     1455                                // If the cache is for an outdated build of SimplePie
     1456                                if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
     1457                                {
     1458                                        $cache->unlink();
     1459                                        $this->data = array();
     1460                                }
     1461                                // If we've hit a collision just rerun it with caching disabled
     1462                                elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
     1463                                {
     1464                                        $cache = false;
     1465                                        $this->data = array();
     1466                                }
     1467                                // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
     1468                                elseif (isset($this->data['feed_url']))
     1469                                {
     1470                                        // If the autodiscovery cache is still valid use it.
     1471                                        if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
     1472                                        {
     1473                                                // Do not need to do feed autodiscovery yet.
     1474                                                if ($this->data['feed_url'] !== $this->data['url'])
    15591475                                                {
    1560                                                         $cache->unlink();
    1561                                                         $this->data = array();
     1476                                                        $this->set_feed_url($this->data['feed_url']);
     1477                                                        return $this->init();
    15621478                                                }
    1563                                                 // If we've hit a collision just rerun it with caching disabled
    1564                                                 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
    1565                                                 {
    1566                                                         $cache = false;
    1567                                                         $this->data = array();
    1568                                                 }
    1569                                                 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
    1570                                                 elseif (isset($this->data['feed_url']))
    1571                                                 {
    1572                                                         // If the autodiscovery cache is still valid use it.
    1573                                                         if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
    1574                                                         {
    1575                                                                 // Do not need to do feed autodiscovery yet.
    1576                                                                 if ($this->data['feed_url'] === $this->data['url'])
    1577                                                                 {
    1578                                                                         $cache->unlink();
    1579                                                                         $this->data = array();
    1580                                                                 }
    1581                                                                 else
    1582                                                                 {
    1583                                                                         $this->set_feed_url($this->data['feed_url']);
    1584                                                                         return $this->init();
    1585                                                                 }
    1586                                                         }
    1587                                                 }
    1588                                                 // Check if the cache has been updated
    1589                                                 elseif ($cache->mtime() + $this->cache_duration < time())
    1590                                                 {
    1591                                                         // If we have last-modified and/or etag set
    1592                                                         if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
    1593                                                         {
    1594                                                                 $headers = array();
    1595                                                                 if (isset($this->data['headers']['last-modified']))
    1596                                                                 {
    1597                                                                         $headers['if-modified-since'] = $this->data['headers']['last-modified'];
    1598                                                                 }
    1599                                                                 if (isset($this->data['headers']['etag']))
    1600                                                                 {
    1601                                                                         $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
    1602                                                                 }
    1603                                                                 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
    1604                                                                 if ($file->success)
    1605                                                                 {
    1606                                                                         if ($file->status_code === 304)
    1607                                                                         {
    1608                                                                                 $cache->touch();
    1609                                                                                 return true;
    1610                                                                         }
    1611                                                                         else
    1612                                                                         {
    1613                                                                                 $headers = $file->headers;
    1614                                                                         }
    1615                                                                 }
    1616                                                                 else
    1617                                                                 {
    1618                                                                         unset($file);
    1619                                                                 }
    1620                                                         }
    1621                                                 }
    1622                                                 // If the cache is still valid, just return true
    1623                                                 else
    1624                                                 {
    1625                                                         return true;
    1626                                                 }
    1627                                         }
    1628                                         // If the cache is empty, delete it
    1629                                         else
    1630                                         {
     1479
    16311480                                                $cache->unlink();
    16321481                                                $this->data = array();
    16331482                                        }
    16341483                                }
    1635                                 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
    1636                                 if (!isset($file))
    1637                                 {
    1638                                         if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
     1484                                // Check if the cache has been updated
     1485                                elseif ($cache->mtime() + $this->cache_duration < time())
     1486                                {
     1487                                        // If we have last-modified and/or etag set
     1488                                        if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
    16391489                                        {
    1640                                                 $file =& $this->file;
    1641                                         }
    1642                                         else
    1643                                         {
    1644                                                 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
    1645                                         }
    1646                                 }
    1647                                 // If the file connection has an error, set SimplePie::error to that and quit
    1648                                 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
    1649                                 {
    1650                                         $this->error = $file->error;
    1651                                         if (!empty($this->data))
    1652                                         {
    1653                                                 return true;
    1654                                         }
    1655                                         else
    1656                                         {
    1657                                                 return false;
    1658                                         }
    1659                                 }
    1660 
    1661                                 if (!$this->force_feed)
    1662                                 {
    1663                                         // Check if the supplied URL is a feed, if it isn't, look for it.
    1664                                         $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
    1665                                         if (!$locate->is_feed($file))
    1666                                         {
    1667                                                 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
    1668                                                 unset($file);
    1669                                                 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
     1490                                                $headers = array(
     1491                                                        'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
     1492                                                );
     1493                                                if (isset($this->data['headers']['last-modified']))
    16701494                                                {
    1671                                                         if ($cache)
     1495                                                        $headers['if-modified-since'] = $this->data['headers']['last-modified'];
     1496                                                }
     1497                                                if (isset($this->data['headers']['etag']))
     1498                                                {
     1499                                                        $headers['if-none-match'] = $this->data['headers']['etag'];
     1500                                                }
     1501
     1502                                                $file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen));
     1503
     1504                                                if ($file->success)
     1505                                                {
     1506                                                        if ($file->status_code === 304)
    16721507                                                        {
    1673                                                                 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
    1674                                                                 if (!$cache->save($this))
    1675                                                                 {
    1676                                                                         trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
    1677                                                                 }
    1678                                                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
     1508                                                                $cache->touch();
     1509                                                                return true;
    16791510                                                        }
    1680                                                         $this->feed_url = $file->url;
    16811511                                                }
    16821512                                                else
    16831513                                                {
    1684                                                         $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
    1685                                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
    1686                                                         return false;
     1514                                                        unset($file);
    16871515                                                }
    16881516                                        }
    1689                                         $locate = null;
    1690                                 }
    1691 
    1692                                 $headers = $file->headers;
    1693                                 $data = $file->body;
    1694                                 $sniffer =& new $this->content_type_sniffer_class($file);
    1695                                 $sniffed = $sniffer->get_type();
    1696                         }
     1517                                }
     1518                                // If the cache is still valid, just return true
     1519                                else
     1520                                {
     1521                                        $this->raw_data = false;
     1522                                        return true;
     1523                                }
     1524                        }
     1525                        // If the cache is empty, delete it
    16971526                        else
    16981527                        {
    1699                                 $data = $this->raw_data;
    1700                         }
    1701 
    1702                         // Set up array of possible encodings
    1703                         $encodings = array();
    1704 
    1705                         // First check to see if input has been overridden.
    1706                         if ($this->input_encoding !== false)
    1707                         {
    1708                                 $encodings[] = $this->input_encoding;
    1709                         }
    1710 
    1711                         $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
    1712                         $text_types = array('text/xml', 'text/xml-external-parsed-entity');
    1713 
    1714                         // RFC 3023 (only applies to sniffed content)
    1715                         if (isset($sniffed))
    1716                         {
    1717                                 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
    1718                                 {
    1719                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
     1528                                $cache->unlink();
     1529                                $this->data = array();
     1530                        }
     1531                }
     1532                // 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.
     1533                if (!isset($file))
     1534                {
     1535                        if ($this->file instanceof SimplePie_File && $this->file->url === $this->feed_url)
     1536                        {
     1537                                $file =& $this->file;
     1538                        }
     1539                        else
     1540                        {
     1541                                $headers = array(
     1542                                        'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
     1543                                );
     1544                                $file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen));
     1545                        }
     1546                }
     1547                // If the file connection has an error, set SimplePie::error to that and quit
     1548                if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
     1549                {
     1550                        $this->error = $file->error;
     1551                        return !empty($this->data);
     1552                }
     1553
     1554                if (!$this->force_feed)
     1555                {
     1556                        // Check if the supplied URL is a feed, if it isn't, look for it.
     1557                        $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds));
     1558
     1559                        if (!$locate->is_feed($file))
     1560                        {
     1561                                // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
     1562                                unset($file);
     1563                                if (!($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)))
     1564                                {
     1565                                        $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed.";
     1566                                        $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
     1567                                        return false;
     1568                                }
     1569                                if ($cache)
     1570                                {
     1571                                        $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
     1572                                        if (!$cache->save($this))
    17201573                                        {
    1721                                                 $encodings[] = strtoupper($charset[1]);
     1574                                                trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
    17221575                                        }
    1723                                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
    1724                                         $encodings[] = 'UTF-8';
    1725                                 }
    1726                                 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
    1727                                 {
    1728                                         if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
    1729                                         {
    1730                                                 $encodings[] = $charset[1];
    1731                                         }
    1732                                         $encodings[] = 'US-ASCII';
    1733                                 }
    1734                                 // Text MIME-type default
    1735                                 elseif (substr($sniffed, 0, 5) === 'text/')
    1736                                 {
    1737                                         $encodings[] = 'US-ASCII';
    1738                                 }
    1739                         }
    1740 
    1741                         // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
    1742                         $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
    1743                         $encodings[] = 'UTF-8';
    1744                         $encodings[] = 'ISO-8859-1';
    1745 
    1746                         // There's no point in trying an encoding twice
    1747                         $encodings = array_unique($encodings);
    1748 
    1749                         // If we want the XML, just output that with the most likely encoding and quit
    1750                         if ($this->xml_dump)
    1751                         {
    1752                                 header('Content-type: text/xml; charset=' . $encodings[0]);
    1753                                 echo $data;
    1754                                 exit;
    1755                         }
    1756 
    1757                         // Loop through each possible encoding, till we return something, or run out of possibilities
    1758                         foreach ($encodings as $encoding)
    1759                         {
    1760                                 // Change the encoding to UTF-8 (as we always use UTF-8 internally)
    1761                                 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
    1762                                 {
    1763                                         // Create new parser
    1764                                         $parser =& new $this->parser_class();
    1765 
    1766                                         // If it's parsed fine
    1767                                         if ($parser->parse($utf8_data, 'UTF-8'))
    1768                                         {
    1769                                                 $this->data = $parser->get_data();
    1770                                                 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
    1771                                                 {
    1772                                                         if (isset($headers))
    1773                                                         {
    1774                                                                 $this->data['headers'] = $headers;
    1775                                                         }
    1776                                                         $this->data['build'] = SIMPLEPIE_BUILD;
    1777 
    1778                                                         // Cache the file if caching is enabled
    1779                                                         if ($cache && !$cache->save($this))
    1780                                                         {
    1781                                                                 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
    1782                                                         }
    1783                                                         return true;
    1784                                                 }
    1785                                                 else
    1786                                                 {
    1787                                                         $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
    1788                                                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
    1789                                                         return false;
    1790                                                 }
    1791                                         }
    1792                                 }
    1793                         }
    1794                         if (isset($parser))
    1795                         {
    1796                                 // We have an error, just set SimplePie_Misc::error to it and quit
    1797                                 $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
    1798                         }
    1799                         else
    1800                         {
    1801                                 $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.';
    1802                         }
    1803                         SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
    1804                         return false;
    1805                 }
    1806                 elseif (!empty($this->multifeed_url))
    1807                 {
    1808                         $i = 0;
    1809                         $success = 0;
    1810                         $this->multifeed_objects = array();
    1811                         foreach ($this->multifeed_url as $url)
    1812                         {
    1813                                 if (SIMPLEPIE_PHP5)
    1814                                 {
    1815                                         // This keyword needs to defy coding standards for PHP4 compatibility
    1816                                         $this->multifeed_objects[$i] = clone($this);
    1817                                 }
    1818                                 else
    1819                                 {
    1820                                         $this->multifeed_objects[$i] = $this;
    1821                                 }
    1822                                 $this->multifeed_objects[$i]->set_feed_url($url);
    1823                                 $success |= $this->multifeed_objects[$i]->init();
    1824                                 $i++;
    1825                         }
    1826                         return (bool) $success;
    1827                 }
    1828                 else
    1829                 {
    1830                         return false;
    1831                 }
    1832         }
    1833 
    1834         /**
    1835          * Return the error message for the occured error
    1836          *
    1837          * @access public
    1838          * @return string Error message
    1839          */
    1840         function error()
     1576                                        $cache = $this->registry->call('Cache', 'create', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'));
     1577                                }
     1578                                $this->feed_url = $file->url;
     1579                        }
     1580                        $locate = null;
     1581                }
     1582
     1583                $this->raw_data = $file->body;
     1584
     1585                $headers = $file->headers;
     1586                $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
     1587                $sniffed = $sniffer->get_type();
     1588
     1589                return array($headers, $sniffed);
     1590        }
     1591
     1592        /**
     1593         * Get the error message for the occured error
     1594         *
     1595         * @return string|array Error message, or array of messages for multifeeds
     1596         */
     1597        public function error()
    18411598        {
    18421599                return $this->error;
    18431600        }
    18441601
    1845         function get_encoding()
     1602        /**
     1603         * Get the raw XML
     1604         *
     1605         * This is the same as the old `$feed->enable_xml_dump(true)`, but returns
     1606         * the data instead of printing it.
     1607         *
     1608         * @return string|boolean Raw XML data, false if the cache is used
     1609         */
     1610        public function get_raw_data()
     1611        {
     1612                return $this->raw_data;
     1613        }
     1614
     1615        /**
     1616         * Get the character encoding used for output
     1617         *
     1618         * @since Preview Release
     1619         * @return string
     1620         */
     1621        public function get_encoding()
    18461622        {
    18471623                return $this->sanitize->output_encoding;
    18481624        }
    18491625
    1850         function handle_content_type($mime = 'text/html')
     1626        /**
     1627         * Send the content-type header with correct encoding
     1628         *
     1629         * This method ensures that the SimplePie-enabled page is being served with
     1630         * the correct {@link http://www.iana.org/assignments/media-types/ mime-type}
     1631         * and character encoding HTTP headers (character encoding determined by the
     1632         * {@see set_output_encoding} config option).
     1633         *
     1634         * This won't work properly if any content or whitespace has already been
     1635         * sent to the browser, because it relies on PHP's
     1636         * {@link http://php.net/header header()} function, and these are the
     1637         * circumstances under which the function works.
     1638         *
     1639         * Because it's setting these settings for the entire page (as is the nature
     1640         * of HTTP headers), this should only be used once per page (again, at the
     1641         * top).
     1642         *
     1643         * @param string $mime MIME type to serve the page as
     1644         */
     1645        public function handle_content_type($mime = 'text/html')
    18511646        {
    18521647                if (!headers_sent())
     
    18651660        }
    18661661
    1867         function get_type()
     1662        /**
     1663         * Get the type of the feed
     1664         *
     1665         * This returns a SIMPLEPIE_TYPE_* constant, which can be tested against
     1666         * using {@link http://php.net/language.operators.bitwise bitwise operators}
     1667         *
     1668         * @since 0.8 (usage changed to using constants in 1.0)
     1669         * @see SIMPLEPIE_TYPE_NONE Unknown.
     1670         * @see SIMPLEPIE_TYPE_RSS_090 RSS 0.90.
     1671         * @see SIMPLEPIE_TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape).
     1672         * @see SIMPLEPIE_TYPE_RSS_091_USERLAND RSS 0.91 (Userland).
     1673         * @see SIMPLEPIE_TYPE_RSS_091 RSS 0.91.
     1674         * @see SIMPLEPIE_TYPE_RSS_092 RSS 0.92.
     1675         * @see SIMPLEPIE_TYPE_RSS_093 RSS 0.93.
     1676         * @see SIMPLEPIE_TYPE_RSS_094 RSS 0.94.
     1677         * @see SIMPLEPIE_TYPE_RSS_10 RSS 1.0.
     1678         * @see SIMPLEPIE_TYPE_RSS_20 RSS 2.0.x.
     1679         * @see SIMPLEPIE_TYPE_RSS_RDF RDF-based RSS.
     1680         * @see SIMPLEPIE_TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format).
     1681         * @see SIMPLEPIE_TYPE_RSS_ALL Any version of RSS.
     1682         * @see SIMPLEPIE_TYPE_ATOM_03 Atom 0.3.
     1683         * @see SIMPLEPIE_TYPE_ATOM_10 Atom 1.0.
     1684         * @see SIMPLEPIE_TYPE_ATOM_ALL Any version of Atom.
     1685         * @see SIMPLEPIE_TYPE_ALL Any known/supported feed type.
     1686         * @return int SIMPLEPIE_TYPE_* constant
     1687         */
     1688        public function get_type()
    18681689        {
    18691690                if (!isset($this->data['type']))
     
    19461767
    19471768        /**
    1948          * Returns the URL for the favicon of the feed's website.
    1949          *
    1950          * @todo Cache atom:icon
    1951          * @access public
    1952          * @since 1.0
    1953          */
    1954         function get_favicon()
    1955         {
    1956                 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
    1957                 {
    1958                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
    1959                 }
    1960                 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
    1961                 {
    1962                         $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
    1963 
    1964                         if ($this->cache && $this->favicon_handler)
    1965                         {
    1966                                 $favicon_filename = call_user_func($this->cache_name_function, $favicon);
    1967                                 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
    1968 
    1969                                 if ($cache->load())
    1970                                 {
    1971                                         return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
    1972                                 }
    1973                                 else
    1974                                 {
    1975                                         $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
    1976 
    1977                                         if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
    1978                                         {
    1979                                                 $sniffer =& new $this->content_type_sniffer_class($file);
    1980                                                 if (substr($sniffer->get_type(), 0, 6) === 'image/')
    1981                                                 {
    1982                                                         if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
    1983                                                         {
    1984                                                                 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
    1985                                                         }
    1986                                                         else
    1987                                                         {
    1988                                                                 trigger_error("$cache->name is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
    1989                                                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
    1990                                                         }
    1991                                                 }
    1992                                                 // not an image
    1993                                                 else
    1994                                                 {
    1995                                                         return false;
    1996                                                 }
    1997                                         }
    1998                                 }
    1999                         }
    2000                         else
    2001                         {
    2002                                 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
    2003                         }
    2004                 }
    2005                 return false;
    2006         }
    2007 
    2008         /**
     1769         * Get the URL for the feed
     1770         *
     1771         * May or may not be different from the URL passed to {@see set_feed_url()},
     1772         * depending on whether auto-discovery was used.
     1773         *
     1774         * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.)
    20091775         * @todo If we have a perm redirect we should return the new URL
    20101776         * @todo When we make the above change, let's support <itunes:new-feed-url> as well
    20111777         * @todo Also, |atom:link|@rel=self
    2012          */
    2013         function subscribe_url()
     1778         * @return string|null
     1779         */
     1780        public function subscribe_url()
    20141781        {
    20151782                if ($this->feed_url !== null)
     
    20231790        }
    20241791
    2025         function subscribe_feed()
    2026         {
    2027                 if ($this->feed_url !== null)
    2028                 {
    2029                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
    2030                 }
    2031                 else
    2032                 {
    2033                         return null;
    2034                 }
    2035         }
    2036 
    2037         function subscribe_outlook()
    2038         {
    2039                 if ($this->feed_url !== null)
    2040                 {
    2041                         return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
    2042                 }
    2043                 else
    2044                 {
    2045                         return null;
    2046                 }
    2047         }
    2048 
    2049         function subscribe_podcast()
    2050         {
    2051                 if ($this->feed_url !== null)
    2052                 {
    2053                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
    2054                 }
    2055                 else
    2056                 {
    2057                         return null;
    2058                 }
    2059         }
    2060 
    2061         function subscribe_itunes()
    2062         {
    2063                 if ($this->feed_url !== null)
    2064                 {
    2065                         return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
    2066                 }
    2067                 else
    2068                 {
    2069                         return null;
    2070                 }
    2071         }
    2072 
    2073         /**
    2074          * Creates the subscribe_* methods' return data
    2075          *
    2076          * @access private
    2077          * @param string $feed_url String to prefix to the feed URL
    2078          * @param string $site_url String to prefix to the site URL (and
    2079          * suffix to the feed URL)
    2080          * @return mixed URL if feed exists, false otherwise
    2081          */
    2082         function subscribe_service($feed_url, $site_url = null)
    2083         {
    2084                 if ($this->subscribe_url())
    2085                 {
    2086                         $return = $feed_url . rawurlencode($this->feed_url);
    2087                         if ($site_url !== null && $this->get_link() !== null)
    2088                         {
    2089                                 $return .= $site_url . rawurlencode($this->get_link());
    2090                         }
    2091                         return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
    2092                 }
    2093                 else
    2094                 {
    2095                         return null;
    2096                 }
    2097         }
    2098 
    2099         function subscribe_aol()
    2100         {
    2101                 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
    2102         }
    2103 
    2104         function subscribe_bloglines()
    2105         {
    2106                 return $this->subscribe_service('http://www.bloglines.com/sub/');
    2107         }
    2108 
    2109         function subscribe_eskobo()
    2110         {
    2111                 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
    2112         }
    2113 
    2114         function subscribe_feedfeeds()
    2115         {
    2116                 return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
    2117         }
    2118 
    2119         function subscribe_feedster()
    2120         {
    2121                 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
    2122         }
    2123 
    2124         function subscribe_google()
    2125         {
    2126                 return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
    2127         }
    2128 
    2129         function subscribe_gritwire()
    2130         {
    2131                 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
    2132         }
    2133 
    2134         function subscribe_msn()
    2135         {
    2136                 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
    2137         }
    2138 
    2139         function subscribe_netvibes()
    2140         {
    2141                 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
    2142         }
    2143 
    2144         function subscribe_newsburst()
    2145         {
    2146                 return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
    2147         }
    2148 
    2149         function subscribe_newsgator()
    2150         {
    2151                 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
    2152         }
    2153 
    2154         function subscribe_odeo()
    2155         {
    2156                 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
    2157         }
    2158 
    2159         function subscribe_podnova()
    2160         {
    2161                 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
    2162         }
    2163 
    2164         function subscribe_rojo()
    2165         {
    2166                 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
    2167         }
    2168 
    2169         function subscribe_yahoo()
    2170         {
    2171                 return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
    2172         }
    2173 
    2174         function get_feed_tags($namespace, $tag)
     1792        /**
     1793         * Get data for an feed-level element
     1794         *
     1795         * This method allows you to get access to ANY element/attribute that is a
     1796         * sub-element of the opening feed tag.
     1797         *
     1798         * The return value is an indexed array of elements matching the given
     1799         * namespace and tag name. Each element has `attribs`, `data` and `child`
     1800         * subkeys. For `attribs` and `child`, these contain namespace subkeys.
     1801         * `attribs` then has one level of associative name => value data (where
     1802         * `value` is a string) after the namespace. `child` has tag-indexed keys
     1803         * after the namespace, each member of which is an indexed array matching
     1804         * this same format.
     1805         *
     1806         * For example:
     1807         * <pre>
     1808         * // This is probably a bad example because we already support
     1809         * // <media:content> natively, but it shows you how to parse through
     1810         * // the nodes.
     1811         * $group = $item->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group');
     1812         * $content = $group[0]['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'];
     1813         * $file = $content[0]['attribs']['']['url'];
     1814         * echo $file;
     1815         * </pre>
     1816         *
     1817         * @since 1.0
     1818         * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
     1819         * @param string $namespace The URL of the XML namespace of the elements you're trying to access
     1820         * @param string $tag Tag name
     1821         * @return array
     1822         */
     1823        public function get_feed_tags($namespace, $tag)
    21751824        {
    21761825                $type = $this->get_type();
     
    22061855        }
    22071856
    2208         function get_channel_tags($namespace, $tag)
     1857        /**
     1858         * Get data for an channel-level element
     1859         *
     1860         * This method allows you to get access to ANY element/attribute in the
     1861         * channel/header section of the feed.
     1862         *
     1863         * See {@see SimplePie::get_feed_tags()} for a description of the return value
     1864         *
     1865         * @since 1.0
     1866         * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
     1867         * @param string $namespace The URL of the XML namespace of the elements you're trying to access
     1868         * @param string $tag Tag name
     1869         * @return array
     1870         */
     1871        public function get_channel_tags($namespace, $tag)
    22091872        {
    22101873                $type = $this->get_type();
     
    22491912        }
    22501913
    2251         function get_image_tags($namespace, $tag)
     1914        /**
     1915         * Get data for an channel-level element
     1916         *
     1917         * This method allows you to get access to ANY element/attribute in the
     1918         * image/logo section of the feed.
     1919         *
     1920         * See {@see SimplePie::get_feed_tags()} for a description of the return value
     1921         *
     1922         * @since 1.0
     1923         * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
     1924         * @param string $namespace The URL of the XML namespace of the elements you're trying to access
     1925         * @param string $tag Tag name
     1926         * @return array
     1927         */
     1928        public function get_image_tags($namespace, $tag)
    22521929        {
    22531930                $type = $this->get_type();
     
    22851962        }
    22861963
    2287         function get_base($element = array())
     1964        /**
     1965         * Get the base URL value from the feed
     1966         *
     1967         * Uses `<xml:base>` if available, otherwise uses the first link in the
     1968         * feed, or failing that, the URL of the feed itself.
     1969         *
     1970         * @see get_link
     1971         * @see subscribe_url
     1972         *
     1973         * @param array $element
     1974         * @return string
     1975         */
     1976        public function get_base($element = array())
    22881977        {
    22891978                if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
     
    23011990        }
    23021991
    2303         function sanitize($data, $type, $base = '')
     1992        /**
     1993         * Sanitize feed data
     1994         *
     1995         * @access private
     1996         * @see SimplePie_Sanitize::sanitize()
     1997         * @param string $data Data to sanitize
     1998         * @param int $type One of the SIMPLEPIE_CONSTRUCT_* constants
     1999         * @param string $base Base URL to resolve URLs against
     2000         * @return string Sanitized data
     2001         */
     2002        public function sanitize($data, $type, $base = '')
    23042003        {
    23052004                return $this->sanitize->sanitize($data, $type, $base);
    23062005        }
    23072006
    2308         function get_title()
     2007        /**
     2008         * Get the title of the feed
     2009         *
     2010         * Uses `<atom:title>`, `<title>` or `<dc:title>`
     2011         *
     2012         * @since 1.0 (previously called `get_feed_title` since 0.8)
     2013         * @return string|null
     2014         */
     2015        public function get_title()
    23092016        {
    23102017                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
    23112018                {
    2312                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
     2019                        return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
    23132020                }
    23142021                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
    23152022                {
    2316                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
     2023                        return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
    23172024                }
    23182025                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
     
    23422049        }
    23432050
    2344         function get_category($key = 0)
     2051        /**
     2052         * Get a category for the feed
     2053         *
     2054         * @since Unknown
     2055         * @param int $key The category that you want to return.  Remember that arrays begin with 0, not 1
     2056         * @return SimplePie_Category|null
     2057         */
     2058        public function get_category($key = 0)
    23452059        {
    23462060                $categories = $this->get_categories();
     
    23552069        }
    23562070
    2357         function get_categories()
     2071        /**
     2072         * Get all categories for the feed
     2073         *
     2074         * Uses `<atom:category>`, `<category>` or `<dc:subject>`
     2075         *
     2076         * @since Unknown
     2077         * @return array|null List of {@see SimplePie_Category} objects
     2078         */
     2079        public function get_categories()
    23582080        {
    23592081                $categories = array();
     
    23762098                                $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
    23772099                        }
    2378                         $categories[] =& new $this->category_class($term, $scheme, $label);
     2100                        $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
    23792101                }
    23802102                foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
     
    23912113                                $scheme = null;
    23922114                        }
    2393                         $categories[] =& new $this->category_class($term, $scheme, null);
     2115                        $categories[] = $this->registry->create('Category', array($term, $scheme, null));
    23942116                }
    23952117                foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
    23962118                {
    2397                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
     2119                        $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
    23982120                }
    23992121                foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
    24002122                {
    2401                         $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
     2123                        $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
    24022124                }
    24032125
    24042126                if (!empty($categories))
    24052127                {
    2406                         return SimplePie_Misc::array_unique($categories);
     2128                        return array_unique($categories);
    24072129                }
    24082130                else
     
    24122134        }
    24132135
    2414         function get_author($key = 0)
     2136        /**
     2137         * Get an author for the feed
     2138         *
     2139         * @since 1.1
     2140         * @param int $key The author that you want to return.  Remember that arrays begin with 0, not 1
     2141         * @return SimplePie_Author|null
     2142         */
     2143        public function get_author($key = 0)
    24152144        {
    24162145                $authors = $this->get_authors();
     
    24252154        }
    24262155
    2427         function get_authors()
     2156        /**
     2157         * Get all authors for the feed
     2158         *
     2159         * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
     2160         *
     2161         * @since 1.1
     2162         * @return array|null List of {@see SimplePie_Author} objects
     2163         */
     2164        public function get_authors()
    24282165        {
    24292166                $authors = array();
     
    24472184                        if ($name !== null || $email !== null || $uri !== null)
    24482185                        {
    2449                                 $authors[] =& new $this->author_class($name, $uri, $email);
     2186                                $authors[] = $this->registry->create('Author', array($name, $uri, $email));
    24502187                        }
    24512188                }
     
    24692206                        if ($name !== null || $email !== null || $url !== null)
    24702207                        {
    2471                                 $authors[] =& new $this->author_class($name, $url, $email);
     2208                                $authors[] = $this->registry->create('Author', array($name, $url, $email));
    24722209                        }
    24732210                }
    24742211                foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
    24752212                {
    2476                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
     2213                        $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
    24772214                }
    24782215                foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
    24792216                {
    2480                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
     2217                        $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
    24812218                }
    24822219                foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
    24832220                {
    2484                         $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
     2221                        $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
    24852222                }
    24862223
    24872224                if (!empty($authors))
    24882225                {
    2489                         return SimplePie_Misc::array_unique($authors);
     2226                        return array_unique($authors);
    24902227                }
    24912228                else
     
    24952232        }
    24962233
    2497         function get_contributor($key = 0)
     2234        /**
     2235         * Get a contributor for the feed
     2236         *
     2237         * @since 1.1
     2238         * @param int $key The contrbutor that you want to return.  Remember that arrays begin with 0, not 1
     2239         * @return SimplePie_Author|null
     2240         */
     2241        public function get_contributor($key = 0)
    24982242        {
    24992243                $contributors = $this->get_contributors();
     
    25082252        }
    25092253
    2510         function get_contributors()
     2254        /**
     2255         * Get all contributors for the feed
     2256         *
     2257         * Uses `<atom:contributor>`
     2258         *
     2259         * @since 1.1
     2260         * @return array|null List of {@see SimplePie_Author} objects
     2261         */
     2262        public function get_contributors()
    25112263        {
    25122264                $contributors = array();
     
    25302282                        if ($name !== null || $email !== null || $uri !== null)
    25312283                        {
    2532                                 $contributors[] =& new $this->author_class($name, $uri, $email);
     2284                                $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
    25332285                        }
    25342286                }
     
    25522304                        if ($name !== null || $email !== null || $url !== null)
    25532305                        {
    2554                                 $contributors[] =& new $this->author_class($name, $url, $email);
     2306                                $contributors[] = $this->registry->create('Author', array($name, $url, $email));
    25552307                        }
    25562308                }
     
    25582310                if (!empty($contributors))
    25592311                {
    2560                         return SimplePie_Misc::array_unique($contributors);
     2312                        return array_unique($contributors);
    25612313                }
    25622314                else
     
    25662318        }
    25672319
    2568         function get_link($key = 0, $rel = 'alternate')
     2320        /**
     2321         * Get a single link for the feed
     2322         *
     2323         * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
     2324         * @param int $key The link that you want to return.  Remember that arrays begin with 0, not 1
     2325         * @param string $rel The relationship of the link to return
     2326         * @return string|null Link URL
     2327         */
     2328        public function get_link($key = 0, $rel = 'alternate')
    25692329        {
    25702330                $links = $this->get_links($rel);
     
    25802340
    25812341        /**
    2582          * Added for parity between the parent-level and the item/entry-level.
    2583          */
    2584         function get_permalink()
     2342         * Get the permalink for the item
     2343         *
     2344         * Returns the first link available with a relationship of "alternate".
     2345         * Identical to {@see get_link()} with key 0
     2346         *
     2347         * @see get_link
     2348         * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
     2349         * @internal Added for parity between the parent-level and the item/entry-level.
     2350         * @return string|null Link URL
     2351         */
     2352        public function get_permalink()
    25852353        {
    25862354                return $this->get_link(0);
    25872355        }
    25882356
    2589         function get_links($rel = 'alternate')
     2357        /**
     2358         * Get all links for the feed
     2359         *
     2360         * Uses `<atom:link>` or `<link>`
     2361         *
     2362         * @since Beta 2
     2363         * @param string $rel The relationship of links to return
     2364         * @return array|null Links found for the feed (strings)
     2365         */
     2366        public function get_links($rel = 'alternate')
    25902367        {
    25912368                if (!isset($this->data['links']))
     
    26312408                        foreach ($keys as $key)
    26322409                        {
    2633                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
     2410                                if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
    26342411                                {
    26352412                                        if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
     
    26612438        }
    26622439
    2663         function get_all_discovered_feeds()
     2440        public function get_all_discovered_feeds()
    26642441        {
    26652442                return $this->all_discovered_feeds;
    26662443        }
    26672444
    2668         function get_description()
     2445        /**
     2446         * Get the content for the item
     2447         *
     2448         * Uses `<atom:subtitle>`, `<atom:tagline>`, `<description>`,
     2449         * `<dc:description>`, `<itunes:summary>` or `<itunes:subtitle>`
     2450         *
     2451         * @since 1.0 (previously called `get_feed_description()` since 0.8)
     2452         * @return string|null
     2453         */
     2454        public function get_description()
    26692455        {
    26702456                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
    26712457                {
    2672                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
     2458                        return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
    26732459                }
    26742460                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
    26752461                {
    2676                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
     2462                        return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
    26772463                }
    26782464                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
     
    27102496        }
    27112497
    2712         function get_copyright()
     2498        /**
     2499         * Get the copyright info for the feed
     2500         *
     2501         * Uses `<atom:rights>`, `<atom:copyright>` or `<dc:rights>`
     2502         *
     2503         * @since 1.0 (previously called `get_feed_copyright()` since 0.8)
     2504         * @return string|null
     2505         */
     2506        public function get_copyright()
    27132507        {
    27142508                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
    27152509                {
    2716                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
     2510                        return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
    27172511                }
    27182512                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
    27192513                {
    2720                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
     2514                        return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
    27212515                }
    27222516                elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
     
    27382532        }
    27392533
    2740         function get_language()
     2534        /**
     2535         * Get the language for the feed
     2536         *
     2537         * Uses `<language>`, `<dc:language>`, or @xml_lang
     2538         *
     2539         * @since 1.0 (previously called `get_feed_language()` since 0.8)
     2540         * @return string|null
     2541         */
     2542        public function get_language()
    27412543        {
    27422544                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
     
    27742576        }
    27752577
    2776         function get_latitude()
     2578        /**
     2579         * Get the latitude coordinates for the item
     2580         *
     2581         * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
     2582         *
     2583         * Uses `<geo:lat>` or `<georss:point>`
     2584         *
     2585         * @since 1.0
     2586         * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
     2587         * @link http://www.georss.org/ GeoRSS
     2588         * @return string|null
     2589         */
     2590        public function get_latitude()
    27772591        {
    27782592
     
    27912605        }
    27922606
    2793         function get_longitude()
     2607        /**
     2608         * Get the longitude coordinates for the feed
     2609         *
     2610         * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
     2611         *
     2612         * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
     2613         *
     2614         * @since 1.0
     2615         * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
     2616         * @link http://www.georss.org/ GeoRSS
     2617         * @return string|null
     2618         */
     2619        public function get_longitude()
    27942620        {
    27952621                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
     
    28112637        }
    28122638
    2813         function get_image_title()
     2639        /**
     2640         * Get the feed logo's title
     2641         *
     2642         * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" title.
     2643         *
     2644         * Uses `<image><title>` or `<image><dc:title>`
     2645         *
     2646         * @return string|null
     2647         */
     2648        public function get_image_title()
    28142649        {
    28152650                if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
     
    28392674        }
    28402675
    2841         function get_image_url()
     2676        /**
     2677         * Get the feed logo's URL
     2678         *
     2679         * RSS 0.9.0, 2.0, Atom 1.0, and feeds with iTunes RSS tags are allowed to
     2680         * have a "feed logo" URL. This points directly to the image itself.
     2681         *
     2682         * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
     2683         * `<image><title>` or `<image><dc:title>`
     2684         *
     2685         * @return string|null
     2686         */
     2687        public function get_image_url()
    28422688        {
    28432689                if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
     
    28712717        }
    28722718
    2873         function get_image_link()
     2719
     2720        /**
     2721         * Get the feed logo's link
     2722         *
     2723         * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" link. This
     2724         * points to a human-readable page that the image should link to.
     2725         *
     2726         * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
     2727         * `<image><title>` or `<image><dc:title>`
     2728         *
     2729         * @return string|null
     2730         */
     2731        public function get_image_link()
    28742732        {
    28752733                if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
     
    28912749        }
    28922750
    2893         function get_image_width()
     2751        /**
     2752         * Get the feed logo's link
     2753         *
     2754         * RSS 2.0 feeds are allowed to have a "feed logo" width.
     2755         *
     2756         * Uses `<image><width>` or defaults to 88.0 if no width is specified and
     2757         * the feed is an RSS 2.0 feed.
     2758         *
     2759         * @return int|float|null
     2760         */
     2761        public function get_image_width()
    28942762        {
    28952763                if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
     
    29072775        }
    29082776
    2909         function get_image_height()
     2777        /**
     2778         * Get the feed logo's height
     2779         *
     2780         * RSS 2.0 feeds are allowed to have a "feed logo" height.
     2781         *
     2782         * Uses `<image><height>` or defaults to 31.0 if no height is specified and
     2783         * the feed is an RSS 2.0 feed.
     2784         *
     2785         * @return int|float|null
     2786         */
     2787        public function get_image_height()
    29102788        {
    29112789                if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
     
    29232801        }
    29242802
    2925         function get_item_quantity($max = 0)
     2803        /**
     2804         * Get the number of items in the feed
     2805         *
     2806         * This is well-suited for {@link http://php.net/for for()} loops with
     2807         * {@see get_item()}
     2808         *
     2809         * @param int $max Maximum value to return. 0 for no limit
     2810         * @return int Number of items in the feed
     2811         */
     2812        public function get_item_quantity($max = 0)
    29262813        {
    29272814                $max = (int) $max;
     
    29372824        }
    29382825
    2939         function get_item($key = 0)
     2826        /**
     2827         * Get a single item from the feed
     2828         *
     2829         * This is better suited for {@link http://php.net/for for()} loops, whereas
     2830         * {@see get_items()} is better suited for
     2831         * {@link http://php.net/foreach foreach()} loops.
     2832         *
     2833         * @see get_item_quantity()
     2834         * @since Beta 2
     2835         * @param int $key The item that you want to return.  Remember that arrays begin with 0, not 1
     2836         * @return SimplePie_Item|null
     2837         */
     2838        public function get_item($key = 0)
    29402839        {
    29412840                $items = $this->get_items();
     
    29502849        }
    29512850
    2952         function get_items($start = 0, $end = 0)
     2851        /**
     2852         * Get all items from the feed
     2853         *
     2854         * This is better suited for {@link http://php.net/for for()} loops, whereas
     2855         * {@see get_items()} is better suited for
     2856         * {@link http://php.net/foreach foreach()} loops.
     2857         *
     2858         * @see get_item_quantity
     2859         * @since Beta 2
     2860         * @param int $start Index to start at
     2861         * @param int $end Number of items to return. 0 for all items after `$start`
     2862         * @return array|null List of {@see SimplePie_Item} objects
     2863         */
     2864        public function get_items($start = 0, $end = 0)
    29532865        {
    29542866                if (!isset($this->data['items']))
     
    29662878                                        foreach ($keys as $key)
    29672879                                        {
    2968                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
     2880                                                $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
    29692881                                        }
    29702882                                }
     
    29742886                                        foreach ($keys as $key)
    29752887                                        {
    2976                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
     2888                                                $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
    29772889                                        }
    29782890                                }
     
    29822894                                        foreach ($keys as $key)
    29832895                                        {
    2984                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
     2896                                                $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
    29852897                                        }
    29862898                                }
     
    29902902                                        foreach ($keys as $key)
    29912903                                        {
    2992                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
     2904                                                $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
    29932905                                        }
    29942906                                }
     
    29982910                                        foreach ($keys as $key)
    29992911                                        {
    3000                                                 $this->data['items'][] =& new $this->item_class($this, $items[$key]);
     2912                                                $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
    30012913                                        }
    30022914                                }
     
    30242936                                        if ($do_sort)
    30252937                                        {
    3026                                                 usort($this->data['ordered_items'], array(&$this, 'sort_items'));
     2938                                                usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
    30272939                                        }
    30282940                                }
     
    30512963
    30522964        /**
    3053          * @static
    3054          */
    3055         function sort_items($a, $b)
     2965         * Sorting callback for items
     2966         *
     2967         * @access private
     2968         * @param SimplePie $a
     2969         * @param SimplePie $b
     2970         * @return boolean
     2971         */
     2972        public static function sort_items($a, $b)
    30562973        {
    30572974                return $a->get_date('U') <= $b->get_date('U');
     
    30592976
    30602977        /**
    3061          * @static
    3062          */
    3063         function merge_items($urls, $start = 0, $end = 0, $limit = 0)
     2978         * Merge items from several feeds into one
     2979         *
     2980         * If you're merging multiple feeds together, they need to all have dates
     2981         * for the items or else SimplePie will refuse to sort them.
     2982         *
     2983         * @link http://simplepie.org/wiki/tutorial/sort_multiple_feeds_by_time_and_date#if_feeds_require_separate_per-feed_settings
     2984         * @param array $urls List of SimplePie feed objects to merge
     2985         * @param int $start Starting item
     2986         * @param int $end Number of items to return
     2987         * @param int $limit Maximum number of items per feed
     2988         * @return array
     2989         */
     2990        public static function merge_items($urls, $start = 0, $end = 0, $limit = 0)
    30642991        {
    30652992                if (is_array($urls) && sizeof($urls) > 0)
     
    30682995                        foreach ($urls as $arg)
    30692996                        {
    3070                                 if (is_a($arg, 'SimplePie'))
     2997                                if ($arg instanceof SimplePie)
    30712998                                {
    30722999                                        $items = array_merge($items, $arg->get_items(0, $limit));
     
    30903017                        if ($do_sort)
    30913018                        {
    3092                                 usort($items, array('SimplePie', 'sort_items'));
     3019                                usort($items, array(get_class($urls[0]), 'sort_items'));
    30933020                        }
    30943021
     
    31093036        }
    31103037}
    3111 
    3112 class SimplePie_Item
    3113 {
    3114         var $feed;
    3115         var $data = array();
    3116 
    3117         function SimplePie_Item($feed, $data)
    3118         {
    3119                 $this->feed = $feed;
    3120                 $this->data = $data;
    3121         }
    3122 
    3123         function __toString()
    3124         {
    3125                 return md5(serialize($this->data));
    3126         }
    3127 
    3128         /**
    3129          * Remove items that link back to this before destroying this object
    3130          */
    3131         function __destruct()
    3132         {
    3133                 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
    3134                 {
    3135                         unset($this->feed);
    3136                 }
    3137         }
    3138 
    3139         function get_item_tags($namespace, $tag)
    3140         {
    3141                 if (isset($this->data['child'][$namespace][$tag]))
    3142                 {
    3143                         return $this->data['child'][$namespace][$tag];
    3144                 }
    3145                 else
    3146                 {
    3147                         return null;
    3148                 }
    3149         }
    3150 
    3151         function get_base($element = array())
    3152         {
    3153                 return $this->feed->get_base($element);
    3154         }
    3155 
    3156         function sanitize($data, $type, $base = '')
    3157         {
    3158                 return $this->feed->sanitize($data, $type, $base);
    3159         }
    3160 
    3161         function get_feed()
    3162         {
    3163                 return $this->feed;
    3164         }
    3165 
    3166         function get_id($hash = false)
    3167         {
    3168                 if (!$hash)
    3169                 {
    3170                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
    3171                         {
    3172                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3173                         }
    3174                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
    3175                         {
    3176                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3177                         }
    3178                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
    3179                         {
    3180                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3181                         }
    3182                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
    3183                         {
    3184                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3185                         }
    3186                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
    3187                         {
    3188                                 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3189                         }
    3190                         elseif (($return = $this->get_permalink()) !== null)
    3191                         {
    3192                                 return $return;
    3193                         }
    3194                         elseif (($return = $this->get_title()) !== null)
    3195                         {
    3196                                 return $return;
    3197                         }
    3198                 }
    3199                 if ($this->get_permalink() !== null || $this->get_title() !== null)
    3200                 {
    3201                         return md5($this->get_permalink() . $this->get_title());
    3202                 }
    3203                 else
    3204                 {
    3205                         return md5(serialize($this->data));
    3206                 }
    3207         }
    3208 
    3209         function get_title()
    3210         {
    3211                 if (!isset($this->data['title']))
    3212                 {
    3213                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
    3214                         {
    3215                                 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    3216                         }
    3217                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
    3218                         {
    3219                                 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    3220                         }
    3221                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
    3222                         {
    3223                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    3224                         }
    3225                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
    3226                         {
    3227                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    3228                         }
    3229                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
    3230                         {
    3231                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    3232                         }
    3233                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
    3234                         {
    3235                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3236                         }
    3237                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
    3238                         {
    3239                                 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3240                         }
    3241                         else
    3242                         {
    3243                                 $this->data['title'] = null;
    3244                         }
    3245                 }
    3246                 return $this->data['title'];
    3247         }
    3248 
    3249         function get_description($description_only = false)
    3250         {
    3251                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
    3252                 {
    3253                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    3254                 }
    3255                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
    3256                 {
    3257                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    3258                 }
    3259                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
    3260                 {
    3261                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    3262                 }
    3263                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
    3264                 {
    3265                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
    3266                 }
    3267                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
    3268                 {
    3269                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3270                 }
    3271                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
    3272                 {
    3273                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3274                 }
    3275                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
    3276                 {
    3277                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
    3278                 }
    3279                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
    3280                 {
    3281                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3282                 }
    3283                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
    3284                 {
    3285                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
    3286                 }
    3287 
    3288                 elseif (!$description_only)
    3289                 {
    3290                         return $this->get_content(true);
    3291                 }
    3292                 else
    3293                 {
    3294                         return null;
    3295                 }
    3296         }
    3297 
    3298         function get_content($content_only = false)
    3299         {
    3300                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
    3301                 {
    3302                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    3303                 }
    3304                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
    3305                 {
    3306                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    3307                 }
    3308                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
    3309                 {
    3310                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
    3311                 }
    3312                 elseif (!$content_only)
    3313                 {
    3314                         return $this->get_description(true);
    3315                 }
    3316                 else
    3317                 {
    3318                         return null;
    3319                 }
    3320         }
    3321 
    3322         function get_category($key = 0)
    3323         {
    3324                 $categories = $this->get_categories();
    3325                 if (isset($categories[$key]))
    3326                 {
    3327                         return $categories[$key];
    3328                 }
    3329                 else
    3330                 {
    3331                         return null;
    3332                 }
    3333         }
    3334 
    3335         function get_categories()
    3336         {
    3337                 $categories = array();
    3338 
    3339                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
    3340                 {
    3341                         $term = null;
    3342                         $scheme = null;
    3343                         $label = null;
    3344                         if (isset($category['attribs']['']['term']))
    3345                         {
    3346                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
    3347                         }
    3348                         if (isset($category['attribs']['']['scheme']))
    3349                         {
    3350                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    3351                         }
    3352                         if (isset($category['attribs']['']['label']))
    3353                         {
    3354                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
    3355                         }
    3356                         $categories[] =& new $this->feed->category_class($term, $scheme, $label);
    3357                 }
    3358                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
    3359                 {
    3360                         // This is really the label, but keep this as the term also for BC.
    3361                         // Label will also work on retrieving because that falls back to term.
    3362                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3363                         if (isset($category['attribs']['']['domain']))
    3364                         {
    3365                                 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
    3366                         }
    3367                         else
    3368                         {
    3369                                 $scheme = null;
    3370                         }
    3371                         $categories[] =& new $this->feed->category_class($term, $scheme, null);
    3372                 }
    3373                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
    3374                 {
    3375                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    3376                 }
    3377                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
    3378                 {
    3379                         $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    3380                 }
    3381 
    3382                 if (!empty($categories))
    3383                 {
    3384                         return SimplePie_Misc::array_unique($categories);
    3385                 }
    3386                 else
    3387                 {
    3388                         return null;
    3389                 }
    3390         }
    3391 
    3392         function get_author($key = 0)
    3393         {
    3394                 $authors = $this->get_authors();
    3395                 if (isset($authors[$key]))
    3396                 {
    3397                         return $authors[$key];
    3398                 }
    3399                 else
    3400                 {
    3401                         return null;
    3402                 }
    3403         }
    3404 
    3405         function get_contributor($key = 0)
    3406         {
    3407                 $contributors = $this->get_contributors();
    3408                 if (isset($contributors[$key]))
    3409                 {
    3410                         return $contributors[$key];
    3411                 }
    3412                 else
    3413                 {
    3414                         return null;
    3415                 }
    3416         }
    3417 
    3418         function get_contributors()
    3419         {
    3420                 $contributors = array();
    3421                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
    3422                 {
    3423                         $name = null;
    3424                         $uri = null;
    3425                         $email = null;
    3426                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
    3427                         {
    3428                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3429                         }
    3430                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
    3431                         {
    3432                                 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
    3433                         }
    3434                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
    3435                         {
    3436                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3437                         }
    3438                         if ($name !== null || $email !== null || $uri !== null)
    3439                         {
    3440                                 $contributors[] =& new $this->feed->author_class($name, $uri, $email);
    3441                         }
    3442                 }
    3443                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
    3444                 {
    3445                         $name = null;
    3446                         $url = null;
    3447                         $email = null;
    3448                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
    3449                         {
    3450                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3451                         }
    3452                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
    3453                         {
    3454                                 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
    3455                         }
    3456                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
    3457                         {
    3458                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3459                         }
    3460                         if ($name !== null || $email !== null || $url !== null)
    3461                         {
    3462                                 $contributors[] =& new $this->feed->author_class($name, $url, $email);
    3463                         }
    3464                 }
    3465 
    3466                 if (!empty($contributors))
    3467                 {
    3468                         return SimplePie_Misc::array_unique($contributors);
    3469                 }
    3470                 else
    3471                 {
    3472                         return null;
    3473                 }
    3474         }
    3475 
    3476         function get_authors()
    3477         {
    3478                 $authors = array();
    3479                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
    3480                 {
    3481                         $name = null;
    3482                         $uri = null;
    3483                         $email = null;
    3484                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
    3485                         {
    3486                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3487                         }
    3488                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
    3489                         {
    3490                                 $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]));
    3491                         }
    3492                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
    3493                         {
    3494                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3495                         }
    3496                         if ($name !== null || $email !== null || $uri !== null)
    3497                         {
    3498                                 $authors[] =& new $this->feed->author_class($name, $uri, $email);
    3499                         }
    3500                 }
    3501                 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
    3502                 {
    3503                         $name = null;
    3504                         $url = null;
    3505                         $email = null;
    3506                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
    3507                         {
    3508                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3509                         }
    3510                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
    3511                         {
    3512                                 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
    3513                         }
    3514                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
    3515                         {
    3516                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3517                         }
    3518                         if ($name !== null || $email !== null || $url !== null)
    3519                         {
    3520                                 $authors[] =& new $this->feed->author_class($name, $url, $email);
    3521                         }
    3522                 }
    3523                 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
    3524                 {
    3525                         $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
    3526                 }
    3527                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
    3528                 {
    3529                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    3530                 }
    3531                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
    3532                 {
    3533                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    3534                 }
    3535                 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
    3536                 {
    3537                         $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    3538                 }
    3539 
    3540                 if (!empty($authors))
    3541                 {
    3542                         return SimplePie_Misc::array_unique($authors);
    3543                 }
    3544                 elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
    3545                 {
    3546                         return $authors;
    3547                 }
    3548                 elseif ($authors = $this->feed->get_authors())
    3549                 {
    3550                         return $authors;
    3551                 }
    3552                 else
    3553                 {
    3554                         return null;
    3555                 }
    3556         }
    3557 
    3558         function get_copyright()
    3559         {
    3560                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
    3561                 {
    3562                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    3563                 }
    3564                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
    3565                 {
    3566                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3567                 }
    3568                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
    3569                 {
    3570                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3571                 }
    3572                 else
    3573                 {
    3574                         return null;
    3575                 }
    3576         }
    3577 
    3578         function get_date($date_format = 'j F Y, g:i a')
    3579         {
    3580                 if (!isset($this->data['date']))
    3581                 {
    3582                         if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
    3583                         {
    3584                                 $this->data['date']['raw'] = $return[0]['data'];
    3585                         }
    3586                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
    3587                         {
    3588                                 $this->data['date']['raw'] = $return[0]['data'];
    3589                         }
    3590                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
    3591                         {
    3592                                 $this->data['date']['raw'] = $return[0]['data'];
    3593                         }
    3594                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
    3595                         {
    3596                                 $this->data['date']['raw'] = $return[0]['data'];
    3597                         }
    3598                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
    3599                         {
    3600                                 $this->data['date']['raw'] = $return[0]['data'];
    3601                         }
    3602                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
    3603                         {
    3604                                 $this->data['date']['raw'] = $return[0]['data'];
    3605                         }
    3606                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
    3607                         {
    3608                                 $this->data['date']['raw'] = $return[0]['data'];
    3609                         }
    3610                         elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
    3611                         {
    3612                                 $this->data['date']['raw'] = $return[0]['data'];
    3613                         }
    3614 
    3615                         if (!empty($this->data['date']['raw']))
    3616                         {
    3617                                 $parser = SimplePie_Parse_Date::get();
    3618                                 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
    3619                         }
    3620                         else
    3621                         {
    3622                                 $this->data['date'] = null;
    3623                         }
    3624                 }
    3625                 if ($this->data['date'])
    3626                 {
    3627                         $date_format = (string) $date_format;
    3628                         switch ($date_format)
    3629                         {
    3630                                 case '':
    3631                                         return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
    3632 
    3633                                 case 'U':
    3634                                         return $this->data['date']['parsed'];
    3635 
    3636                                 default:
    3637                                         return date($date_format, $this->data['date']['parsed']);
    3638                         }
    3639                 }
    3640                 else
    3641                 {
    3642                         return null;
    3643                 }
    3644         }
    3645 
    3646         function get_local_date($date_format = '%c')
    3647         {
    3648                 if (!$date_format)
    3649                 {
    3650                         return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
    3651                 }
    3652                 elseif (($date = $this->get_date('U')) !== null && $date !== false)
    3653                 {
    3654                         return strftime($date_format, $date);
    3655                 }
    3656                 else
    3657                 {
    3658                         return null;
    3659                 }
    3660         }
    3661 
    3662         function get_permalink()
    3663         {
    3664                 $link = $this->get_link();
    3665                 $enclosure = $this->get_enclosure(0);
    3666                 if ($link !== null)
    3667                 {
    3668                         return $link;
    3669                 }
    3670                 elseif ($enclosure !== null)
    3671                 {
    3672                         return $enclosure->get_link();
    3673                 }
    3674                 else
    3675                 {
    3676                         return null;
    3677                 }
    3678         }
    3679 
    3680         function get_link($key = 0, $rel = 'alternate')
    3681         {
    3682                 $links = $this->get_links($rel);
    3683                 if ($links[$key] !== null)
    3684                 {
    3685                         return $links[$key];
    3686                 }
    3687                 else
    3688                 {
    3689                         return null;
    3690                 }
    3691         }
    3692 
    3693         function get_links($rel = 'alternate')
    3694         {
    3695                 if (!isset($this->data['links']))
    3696                 {
    3697                         $this->data['links'] = array();
    3698                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
    3699                         {
    3700                                 if (isset($link['attribs']['']['href']))
    3701                                 {
    3702                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
    3703                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
    3704 
    3705                                 }
    3706                         }
    3707                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
    3708                         {
    3709                                 if (isset($link['attribs']['']['href']))
    3710                                 {
    3711                                         $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
    3712                                         $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
    3713                                 }
    3714                         }
    3715                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
    3716                         {
    3717                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
    3718                         }
    3719                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
    3720                         {
    3721                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
    3722                         }
    3723                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
    3724                         {
    3725                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
    3726                         }
    3727                         if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
    3728                         {
    3729                                 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
    3730                                 {
    3731                                         $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
    3732                                 }
    3733                         }
    3734 
    3735                         $keys = array_keys($this->data['links']);
    3736                         foreach ($keys as $key)
    3737                         {
    3738                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
    3739                                 {
    3740                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
    3741                                         {
    3742                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
    3743                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
    3744                                         }
    3745                                         else
    3746                                         {
    3747                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
    3748                                         }
    3749                                 }
    3750                                 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
    3751                                 {
    3752                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
    3753                                 }
    3754                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
    3755                         }
    3756                 }
    3757                 if (isset($this->data['links'][$rel]))
    3758                 {
    3759                         return $this->data['links'][$rel];
    3760                 }
    3761                 else
    3762                 {
    3763                         return null;
    3764                 }
    3765         }
    3766 
    3767         /**
    3768          * @todo Add ability to prefer one type of content over another (in a media group).
    3769          */
    3770         function get_enclosure($key = 0, $prefer = null)
    3771         {
    3772                 $enclosures = $this->get_enclosures();
    3773                 if (isset($enclosures[$key]))
    3774                 {
    3775                         return $enclosures[$key];
    3776                 }
    3777                 else
    3778                 {
    3779                         return null;
    3780                 }
    3781         }
    3782 
    3783         /**
    3784          * Grabs all available enclosures (podcasts, etc.)
    3785          *
    3786          * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
    3787          *
    3788          * 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.
    3789          *
    3790          * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
    3791          * @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).
    3792          */
    3793         function get_enclosures()
    3794         {
    3795                 if (!isset($this->data['enclosures']))
    3796                 {
    3797                         $this->data['enclosures'] = array();
    3798 
    3799                         // Elements
    3800                         $captions_parent = null;
    3801                         $categories_parent = null;
    3802                         $copyrights_parent = null;
    3803                         $credits_parent = null;
    3804                         $description_parent = null;
    3805                         $duration_parent = null;
    3806                         $hashes_parent = null;
    3807                         $keywords_parent = null;
    3808                         $player_parent = null;
    3809                         $ratings_parent = null;
    3810                         $restrictions_parent = null;
    3811                         $thumbnails_parent = null;
    3812                         $title_parent = null;
    3813 
    3814                         // Let's do the channel and item-level ones first, and just re-use them if we need to.
    3815                         $parent = $this->get_feed();
    3816 
    3817                         // CAPTIONS
    3818                         if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
    3819                         {
    3820                                 foreach ($captions as $caption)
    3821                                 {
    3822                                         $caption_type = null;
    3823                                         $caption_lang = null;
    3824                                         $caption_startTime = null;
    3825                                         $caption_endTime = null;
    3826                                         $caption_text = null;
    3827                                         if (isset($caption['attribs']['']['type']))
    3828                                         {
    3829                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    3830                                         }
    3831                                         if (isset($caption['attribs']['']['lang']))
    3832                                         {
    3833                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
    3834                                         }
    3835                                         if (isset($caption['attribs']['']['start']))
    3836                                         {
    3837                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
    3838                                         }
    3839                                         if (isset($caption['attribs']['']['end']))
    3840                                         {
    3841                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
    3842                                         }
    3843                                         if (isset($caption['data']))
    3844                                         {
    3845                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3846                                         }
    3847                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
    3848                                 }
    3849                         }
    3850                         elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
    3851                         {
    3852                                 foreach ($captions as $caption)
    3853                                 {
    3854                                         $caption_type = null;
    3855                                         $caption_lang = null;
    3856                                         $caption_startTime = null;
    3857                                         $caption_endTime = null;
    3858                                         $caption_text = null;
    3859                                         if (isset($caption['attribs']['']['type']))
    3860                                         {
    3861                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    3862                                         }
    3863                                         if (isset($caption['attribs']['']['lang']))
    3864                                         {
    3865                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
    3866                                         }
    3867                                         if (isset($caption['attribs']['']['start']))
    3868                                         {
    3869                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
    3870                                         }
    3871                                         if (isset($caption['attribs']['']['end']))
    3872                                         {
    3873                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
    3874                                         }
    3875                                         if (isset($caption['data']))
    3876                                         {
    3877                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3878                                         }
    3879                                         $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
    3880                                 }
    3881                         }
    3882                         if (is_array($captions_parent))
    3883                         {
    3884                                 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
    3885                         }
    3886 
    3887                         // CATEGORIES
    3888                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
    3889                         {
    3890                                 $term = null;
    3891                                 $scheme = null;
    3892                                 $label = null;
    3893                                 if (isset($category['data']))
    3894                                 {
    3895                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3896                                 }
    3897                                 if (isset($category['attribs']['']['scheme']))
    3898                                 {
    3899                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    3900                                 }
    3901                                 else
    3902                                 {
    3903                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
    3904                                 }
    3905                                 if (isset($category['attribs']['']['label']))
    3906                                 {
    3907                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
    3908                                 }
    3909                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
    3910                         }
    3911                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
    3912                         {
    3913                                 $term = null;
    3914                                 $scheme = null;
    3915                                 $label = null;
    3916                                 if (isset($category['data']))
    3917                                 {
    3918                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3919                                 }
    3920                                 if (isset($category['attribs']['']['scheme']))
    3921                                 {
    3922                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    3923                                 }
    3924                                 else
    3925                                 {
    3926                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
    3927                                 }
    3928                                 if (isset($category['attribs']['']['label']))
    3929                                 {
    3930                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
    3931                                 }
    3932                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
    3933                         }
    3934                         foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
    3935                         {
    3936                                 $term = null;
    3937                                 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
    3938                                 $label = null;
    3939                                 if (isset($category['attribs']['']['text']))
    3940                                 {
    3941                                         $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
    3942                                 }
    3943                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
    3944 
    3945                                 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
    3946                                 {
    3947                                         foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
    3948                                         {
    3949                                                 if (isset($subcategory['attribs']['']['text']))
    3950                                                 {
    3951                                                         $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
    3952                                                 }
    3953                                                 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label);
    3954                                         }
    3955                                 }
    3956                         }
    3957                         if (is_array($categories_parent))
    3958                         {
    3959                                 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
    3960                         }
    3961 
    3962                         // COPYRIGHT
    3963                         if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
    3964                         {
    3965                                 $copyright_url = null;
    3966                                 $copyright_label = null;
    3967                                 if (isset($copyright[0]['attribs']['']['url']))
    3968                                 {
    3969                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
    3970                                 }
    3971                                 if (isset($copyright[0]['data']))
    3972                                 {
    3973                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3974                                 }
    3975                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
    3976                         }
    3977                         elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
    3978                         {
    3979                                 $copyright_url = null;
    3980                                 $copyright_label = null;
    3981                                 if (isset($copyright[0]['attribs']['']['url']))
    3982                                 {
    3983                                         $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
    3984                                 }
    3985                                 if (isset($copyright[0]['data']))
    3986                                 {
    3987                                         $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    3988                                 }
    3989                                 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label);
    3990                         }
    3991 
    3992                         // CREDITS
    3993                         if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
    3994                         {
    3995                                 foreach ($credits as $credit)
    3996                                 {
    3997                                         $credit_role = null;
    3998                                         $credit_scheme = null;
    3999                                         $credit_name = null;
    4000                                         if (isset($credit['attribs']['']['role']))
    4001                                         {
    4002                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
    4003                                         }
    4004                                         if (isset($credit['attribs']['']['scheme']))
    4005                                         {
    4006                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4007                                         }
    4008                                         else
    4009                                         {
    4010                                                 $credit_scheme = 'urn:ebu';
    4011                                         }
    4012                                         if (isset($credit['data']))
    4013                                         {
    4014                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4015                                         }
    4016                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
    4017                                 }
    4018                         }
    4019                         elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
    4020                         {
    4021                                 foreach ($credits as $credit)
    4022                                 {
    4023                                         $credit_role = null;
    4024                                         $credit_scheme = null;
    4025                                         $credit_name = null;
    4026                                         if (isset($credit['attribs']['']['role']))
    4027                                         {
    4028                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
    4029                                         }
    4030                                         if (isset($credit['attribs']['']['scheme']))
    4031                                         {
    4032                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4033                                         }
    4034                                         else
    4035                                         {
    4036                                                 $credit_scheme = 'urn:ebu';
    4037                                         }
    4038                                         if (isset($credit['data']))
    4039                                         {
    4040                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4041                                         }
    4042                                         $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
    4043                                 }
    4044                         }
    4045                         if (is_array($credits_parent))
    4046                         {
    4047                                 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
    4048                         }
    4049 
    4050                         // DESCRIPTION
    4051                         if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
    4052                         {
    4053                                 if (isset($description_parent[0]['data']))
    4054                                 {
    4055                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4056                                 }
    4057                         }
    4058                         elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
    4059                         {
    4060                                 if (isset($description_parent[0]['data']))
    4061                                 {
    4062                                         $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4063                                 }
    4064                         }
    4065 
    4066                         // DURATION
    4067                         if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
    4068                         {
    4069                                 $seconds = null;
    4070                                 $minutes = null;
    4071                                 $hours = null;
    4072                                 if (isset($duration_parent[0]['data']))
    4073                                 {
    4074                                         $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
    4075                                         if (sizeof($temp) > 0)
    4076                                         {
    4077                                                 $seconds = (int) array_pop($temp);
    4078                                         }
    4079                                         if (sizeof($temp) > 0)
    4080                                         {
    4081                                                 $minutes = (int) array_pop($temp);
    4082                                                 $seconds += $minutes * 60;
    4083                                         }
    4084                                         if (sizeof($temp) > 0)
    4085                                         {
    4086                                                 $hours = (int) array_pop($temp);
    4087                                                 $seconds += $hours * 3600;
    4088                                         }
    4089                                         unset($temp);
    4090                                         $duration_parent = $seconds;
    4091                                 }
    4092                         }
    4093 
    4094                         // HASHES
    4095                         if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
    4096                         {
    4097                                 foreach ($hashes_iterator as $hash)
    4098                                 {
    4099                                         $value = null;
    4100                                         $algo = null;
    4101                                         if (isset($hash['data']))
    4102                                         {
    4103                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4104                                         }
    4105                                         if (isset($hash['attribs']['']['algo']))
    4106                                         {
    4107                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
    4108                                         }
    4109                                         else
    4110                                         {
    4111                                                 $algo = 'md5';
    4112                                         }
    4113                                         $hashes_parent[] = $algo.':'.$value;
    4114                                 }
    4115                         }
    4116                         elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
    4117                         {
    4118                                 foreach ($hashes_iterator as $hash)
    4119                                 {
    4120                                         $value = null;
    4121                                         $algo = null;
    4122                                         if (isset($hash['data']))
    4123                                         {
    4124                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4125                                         }
    4126                                         if (isset($hash['attribs']['']['algo']))
    4127                                         {
    4128                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
    4129                                         }
    4130                                         else
    4131                                         {
    4132                                                 $algo = 'md5';
    4133                                         }
    4134                                         $hashes_parent[] = $algo.':'.$value;
    4135                                 }
    4136                         }
    4137                         if (is_array($hashes_parent))
    4138                         {
    4139                                 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
    4140                         }
    4141 
    4142                         // KEYWORDS
    4143                         if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
    4144                         {
    4145                                 if (isset($keywords[0]['data']))
    4146                                 {
    4147                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
    4148                                         foreach ($temp as $word)
    4149                                         {
    4150                                                 $keywords_parent[] = trim($word);
    4151                                         }
    4152                                 }
    4153                                 unset($temp);
    4154                         }
    4155                         elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
    4156                         {
    4157                                 if (isset($keywords[0]['data']))
    4158                                 {
    4159                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
    4160                                         foreach ($temp as $word)
    4161                                         {
    4162                                                 $keywords_parent[] = trim($word);
    4163                                         }
    4164                                 }
    4165                                 unset($temp);
    4166                         }
    4167                         elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
    4168                         {
    4169                                 if (isset($keywords[0]['data']))
    4170                                 {
    4171                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
    4172                                         foreach ($temp as $word)
    4173                                         {
    4174                                                 $keywords_parent[] = trim($word);
    4175                                         }
    4176                                 }
    4177                                 unset($temp);
    4178                         }
    4179                         elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
    4180                         {
    4181                                 if (isset($keywords[0]['data']))
    4182                                 {
    4183                                         $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
    4184                                         foreach ($temp as $word)
    4185                                         {
    4186                                                 $keywords_parent[] = trim($word);
    4187                                         }
    4188                                 }
    4189                                 unset($temp);
    4190                         }
    4191                         if (is_array($keywords_parent))
    4192                         {
    4193                                 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
    4194                         }
    4195 
    4196                         // PLAYER
    4197                         if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
    4198                         {
    4199                                 if (isset($player_parent[0]['attribs']['']['url']))
    4200                                 {
    4201                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    4202                                 }
    4203                         }
    4204                         elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
    4205                         {
    4206                                 if (isset($player_parent[0]['attribs']['']['url']))
    4207                                 {
    4208                                         $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    4209                                 }
    4210                         }
    4211 
    4212                         // RATINGS
    4213                         if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
    4214                         {
    4215                                 foreach ($ratings as $rating)
    4216                                 {
    4217                                         $rating_scheme = null;
    4218                                         $rating_value = null;
    4219                                         if (isset($rating['attribs']['']['scheme']))
    4220                                         {
    4221                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4222                                         }
    4223                                         else
    4224                                         {
    4225                                                 $rating_scheme = 'urn:simple';
    4226                                         }
    4227                                         if (isset($rating['data']))
    4228                                         {
    4229                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4230                                         }
    4231                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
    4232                                 }
    4233                         }
    4234                         elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
    4235                         {
    4236                                 foreach ($ratings as $rating)
    4237                                 {
    4238                                         $rating_scheme = 'urn:itunes';
    4239                                         $rating_value = null;
    4240                                         if (isset($rating['data']))
    4241                                         {
    4242                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4243                                         }
    4244                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
    4245                                 }
    4246                         }
    4247                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
    4248                         {
    4249                                 foreach ($ratings as $rating)
    4250                                 {
    4251                                         $rating_scheme = null;
    4252                                         $rating_value = null;
    4253                                         if (isset($rating['attribs']['']['scheme']))
    4254                                         {
    4255                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4256                                         }
    4257                                         else
    4258                                         {
    4259                                                 $rating_scheme = 'urn:simple';
    4260                                         }
    4261                                         if (isset($rating['data']))
    4262                                         {
    4263                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4264                                         }
    4265                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
    4266                                 }
    4267                         }
    4268                         elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
    4269                         {
    4270                                 foreach ($ratings as $rating)
    4271                                 {
    4272                                         $rating_scheme = 'urn:itunes';
    4273                                         $rating_value = null;
    4274                                         if (isset($rating['data']))
    4275                                         {
    4276                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4277                                         }
    4278                                         $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
    4279                                 }
    4280                         }
    4281                         if (is_array($ratings_parent))
    4282                         {
    4283                                 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
    4284                         }
    4285 
    4286                         // RESTRICTIONS
    4287                         if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
    4288                         {
    4289                                 foreach ($restrictions as $restriction)
    4290                                 {
    4291                                         $restriction_relationship = null;
    4292                                         $restriction_type = null;
    4293                                         $restriction_value = null;
    4294                                         if (isset($restriction['attribs']['']['relationship']))
    4295                                         {
    4296                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
    4297                                         }
    4298                                         if (isset($restriction['attribs']['']['type']))
    4299                                         {
    4300                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    4301                                         }
    4302                                         if (isset($restriction['data']))
    4303                                         {
    4304                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4305                                         }
    4306                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
    4307                                 }
    4308                         }
    4309                         elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
    4310                         {
    4311                                 foreach ($restrictions as $restriction)
    4312                                 {
    4313                                         $restriction_relationship = 'allow';
    4314                                         $restriction_type = null;
    4315                                         $restriction_value = 'itunes';
    4316                                         if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
    4317                                         {
    4318                                                 $restriction_relationship = 'deny';
    4319                                         }
    4320                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
    4321                                 }
    4322                         }
    4323                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
    4324                         {
    4325                                 foreach ($restrictions as $restriction)
    4326                                 {
    4327                                         $restriction_relationship = null;
    4328                                         $restriction_type = null;
    4329                                         $restriction_value = null;
    4330                                         if (isset($restriction['attribs']['']['relationship']))
    4331                                         {
    4332                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
    4333                                         }
    4334                                         if (isset($restriction['attribs']['']['type']))
    4335                                         {
    4336                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    4337                                         }
    4338                                         if (isset($restriction['data']))
    4339                                         {
    4340                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4341                                         }
    4342                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
    4343                                 }
    4344                         }
    4345                         elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
    4346                         {
    4347                                 foreach ($restrictions as $restriction)
    4348                                 {
    4349                                         $restriction_relationship = 'allow';
    4350                                         $restriction_type = null;
    4351                                         $restriction_value = 'itunes';
    4352                                         if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
    4353                                         {
    4354                                                 $restriction_relationship = 'deny';
    4355                                         }
    4356                                         $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
    4357                                 }
    4358                         }
    4359                         if (is_array($restrictions_parent))
    4360                         {
    4361                                 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
    4362                         }
    4363 
    4364                         // THUMBNAILS
    4365                         if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
    4366                         {
    4367                                 foreach ($thumbnails as $thumbnail)
    4368                                 {
    4369                                         if (isset($thumbnail['attribs']['']['url']))
    4370                                         {
    4371                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    4372                                         }
    4373                                 }
    4374                         }
    4375                         elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
    4376                         {
    4377                                 foreach ($thumbnails as $thumbnail)
    4378                                 {
    4379                                         if (isset($thumbnail['attribs']['']['url']))
    4380                                         {
    4381                                                 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    4382                                         }
    4383                                 }
    4384                         }
    4385 
    4386                         // TITLES
    4387                         if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
    4388                         {
    4389                                 if (isset($title_parent[0]['data']))
    4390                                 {
    4391                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4392                                 }
    4393                         }
    4394                         elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
    4395                         {
    4396                                 if (isset($title_parent[0]['data']))
    4397                                 {
    4398                                         $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4399                                 }
    4400                         }
    4401 
    4402                         // Clear the memory
    4403                         unset($parent);
    4404 
    4405                         // Attributes
    4406                         $bitrate = null;
    4407                         $channels = null;
    4408                         $duration = null;
    4409                         $expression = null;
    4410                         $framerate = null;
    4411                         $height = null;
    4412                         $javascript = null;
    4413                         $lang = null;
    4414                         $length = null;
    4415                         $medium = null;
    4416                         $samplingrate = null;
    4417                         $type = null;
    4418                         $url = null;
    4419                         $width = null;
    4420 
    4421                         // Elements
    4422                         $captions = null;
    4423                         $categories = null;
    4424                         $copyrights = null;
    4425                         $credits = null;
    4426                         $description = null;
    4427                         $hashes = null;
    4428                         $keywords = null;
    4429                         $player = null;
    4430                         $ratings = null;
    4431                         $restrictions = null;
    4432                         $thumbnails = null;
    4433                         $title = null;
    4434 
    4435                         // If we have media:group tags, loop through them.
    4436                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
    4437                         {
    4438                                 if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
    4439                                 {
    4440                                         // If we have media:content tags, loop through them.
    4441                                         foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
    4442                                         {
    4443                                                 if (isset($content['attribs']['']['url']))
    4444                                                 {
    4445                                                         // Attributes
    4446                                                         $bitrate = null;
    4447                                                         $channels = null;
    4448                                                         $duration = null;
    4449                                                         $expression = null;
    4450                                                         $framerate = null;
    4451                                                         $height = null;
    4452                                                         $javascript = null;
    4453                                                         $lang = null;
    4454                                                         $length = null;
    4455                                                         $medium = null;
    4456                                                         $samplingrate = null;
    4457                                                         $type = null;
    4458                                                         $url = null;
    4459                                                         $width = null;
    4460 
    4461                                                         // Elements
    4462                                                         $captions = null;
    4463                                                         $categories = null;
    4464                                                         $copyrights = null;
    4465                                                         $credits = null;
    4466                                                         $description = null;
    4467                                                         $hashes = null;
    4468                                                         $keywords = null;
    4469                                                         $player = null;
    4470                                                         $ratings = null;
    4471                                                         $restrictions = null;
    4472                                                         $thumbnails = null;
    4473                                                         $title = null;
    4474 
    4475                                                         // Start checking the attributes of media:content
    4476                                                         if (isset($content['attribs']['']['bitrate']))
    4477                                                         {
    4478                                                                 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
    4479                                                         }
    4480                                                         if (isset($content['attribs']['']['channels']))
    4481                                                         {
    4482                                                                 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
    4483                                                         }
    4484                                                         if (isset($content['attribs']['']['duration']))
    4485                                                         {
    4486                                                                 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
    4487                                                         }
    4488                                                         else
    4489                                                         {
    4490                                                                 $duration = $duration_parent;
    4491                                                         }
    4492                                                         if (isset($content['attribs']['']['expression']))
    4493                                                         {
    4494                                                                 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
    4495                                                         }
    4496                                                         if (isset($content['attribs']['']['framerate']))
    4497                                                         {
    4498                                                                 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
    4499                                                         }
    4500                                                         if (isset($content['attribs']['']['height']))
    4501                                                         {
    4502                                                                 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
    4503                                                         }
    4504                                                         if (isset($content['attribs']['']['lang']))
    4505                                                         {
    4506                                                                 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
    4507                                                         }
    4508                                                         if (isset($content['attribs']['']['fileSize']))
    4509                                                         {
    4510                                                                 $length = ceil($content['attribs']['']['fileSize']);
    4511                                                         }
    4512                                                         if (isset($content['attribs']['']['medium']))
    4513                                                         {
    4514                                                                 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
    4515                                                         }
    4516                                                         if (isset($content['attribs']['']['samplingrate']))
    4517                                                         {
    4518                                                                 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
    4519                                                         }
    4520                                                         if (isset($content['attribs']['']['type']))
    4521                                                         {
    4522                                                                 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    4523                                                         }
    4524                                                         if (isset($content['attribs']['']['width']))
    4525                                                         {
    4526                                                                 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
    4527                                                         }
    4528                                                         $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    4529 
    4530                                                         // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
    4531 
    4532                                                         // CAPTIONS
    4533                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
    4534                                                         {
    4535                                                                 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
    4536                                                                 {
    4537                                                                         $caption_type = null;
    4538                                                                         $caption_lang = null;
    4539                                                                         $caption_startTime = null;
    4540                                                                         $caption_endTime = null;
    4541                                                                         $caption_text = null;
    4542                                                                         if (isset($caption['attribs']['']['type']))
    4543                                                                         {
    4544                                                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    4545                                                                         }
    4546                                                                         if (isset($caption['attribs']['']['lang']))
    4547                                                                         {
    4548                                                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
    4549                                                                         }
    4550                                                                         if (isset($caption['attribs']['']['start']))
    4551                                                                         {
    4552                                                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
    4553                                                                         }
    4554                                                                         if (isset($caption['attribs']['']['end']))
    4555                                                                         {
    4556                                                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
    4557                                                                         }
    4558                                                                         if (isset($caption['data']))
    4559                                                                         {
    4560                                                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4561                                                                         }
    4562                                                                         $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
    4563                                                                 }
    4564                                                                 if (is_array($captions))
    4565                                                                 {
    4566                                                                         $captions = array_values(SimplePie_Misc::array_unique($captions));
    4567                                                                 }
    4568                                                         }
    4569                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
    4570                                                         {
    4571                                                                 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
    4572                                                                 {
    4573                                                                         $caption_type = null;
    4574                                                                         $caption_lang = null;
    4575                                                                         $caption_startTime = null;
    4576                                                                         $caption_endTime = null;
    4577                                                                         $caption_text = null;
    4578                                                                         if (isset($caption['attribs']['']['type']))
    4579                                                                         {
    4580                                                                                 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    4581                                                                         }
    4582                                                                         if (isset($caption['attribs']['']['lang']))
    4583                                                                         {
    4584                                                                                 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
    4585                                                                         }
    4586                                                                         if (isset($caption['attribs']['']['start']))
    4587                                                                         {
    4588                                                                                 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
    4589                                                                         }
    4590                                                                         if (isset($caption['attribs']['']['end']))
    4591                                                                         {
    4592                                                                                 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
    4593                                                                         }
    4594                                                                         if (isset($caption['data']))
    4595                                                                         {
    4596                                                                                 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4597                                                                         }
    4598                                                                         $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
    4599                                                                 }
    4600                                                                 if (is_array($captions))
    4601                                                                 {
    4602                                                                         $captions = array_values(SimplePie_Misc::array_unique($captions));
    4603                                                                 }
    4604                                                         }
    4605                                                         else
    4606                                                         {
    4607                                                                 $captions = $captions_parent;
    4608                                                         }
    4609 
    4610                                                         // CATEGORIES
    4611                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
    4612                                                         {
    4613                                                                 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
    4614                                                                 {
    4615                                                                         $term = null;
    4616                                                                         $scheme = null;
    4617                                                                         $label = null;
    4618                                                                         if (isset($category['data']))
    4619                                                                         {
    4620                                                                                 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4621                                                                         }
    4622                                                                         if (isset($category['attribs']['']['scheme']))
    4623                                                                         {
    4624                                                                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4625                                                                         }
    4626                                                                         else
    4627                                                                         {
    4628                                                                                 $scheme = 'http://search.yahoo.com/mrss/category_schema';
    4629                                                                         }
    4630                                                                         if (isset($category['attribs']['']['label']))
    4631                                                                         {
    4632                                                                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
    4633                                                                         }
    4634                                                                         $categories[] =& new $this->feed->category_class($term, $scheme, $label);
    4635                                                                 }
    4636                                                         }
    4637                                                         if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
    4638                                                         {
    4639                                                                 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
    4640                                                                 {
    4641                                                                         $term = null;
    4642                                                                         $scheme = null;
    4643                                                                         $label = null;
    4644                                                                         if (isset($category['data']))
    4645                                                                         {
    4646                                                                                 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4647                                                                         }
    4648                                                                         if (isset($category['attribs']['']['scheme']))
    4649                                                                         {
    4650                                                                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4651                                                                         }
    4652                                                                         else
    4653                                                                         {
    4654                                                                                 $scheme = 'http://search.yahoo.com/mrss/category_schema';
    4655                                                                         }
    4656                                                                         if (isset($category['attribs']['']['label']))
    4657                                                                         {
    4658                                                                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
    4659                                                                         }
    4660                                                                         $categories[] =& new $this->feed->category_class($term, $scheme, $label);
    4661                                                                 }
    4662                                                         }
    4663                                                         if (is_array($categories) && is_array($categories_parent))
    4664                                                         {
    4665                                                                 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
    4666                                                         }
    4667                                                         elseif (is_array($categories))
    4668                                                         {
    4669                                                                 $categories = array_values(SimplePie_Misc::array_unique($categories));
    4670                                                         }
    4671                                                         elseif (is_array($categories_parent))
    4672                                                         {
    4673                                                                 $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
    4674                                                         }
    4675 
    4676                                                         // COPYRIGHTS
    4677                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
    4678                                                         {
    4679                                                                 $copyright_url = null;
    4680                                                                 $copyright_label = null;
    4681                                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
    4682                                                                 {
    4683                                                                         $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
    4684                                                                 }
    4685                                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
    4686                                                                 {
    4687                                                                         $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4688                                                                 }
    4689                                                                 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
    4690                                                         }
    4691                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
    4692                                                         {
    4693                                                                 $copyright_url = null;
    4694                                                                 $copyright_label = null;
    4695                                                                 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
    4696                                                                 {
    4697                                                                         $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
    4698                                                                 }
    4699                                                                 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
    4700                                                                 {
    4701                                                                         $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4702                                                                 }
    4703                                                                 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
    4704                                                         }
    4705                                                         else
    4706                                                         {
    4707                                                                 $copyrights = $copyrights_parent;
    4708                                                         }
    4709 
    4710                                                         // CREDITS
    4711                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
    4712                                                         {
    4713                                                                 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
    4714                                                                 {
    4715                                                                         $credit_role = null;
    4716                                                                         $credit_scheme = null;
    4717                                                                         $credit_name = null;
    4718                                                                         if (isset($credit['attribs']['']['role']))
    4719                                                                         {
    4720                                                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
    4721                                                                         }
    4722                                                                         if (isset($credit['attribs']['']['scheme']))
    4723                                                                         {
    4724                                                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4725                                                                         }
    4726                                                                         else
    4727                                                                         {
    4728                                                                                 $credit_scheme = 'urn:ebu';
    4729                                                                         }
    4730                                                                         if (isset($credit['data']))
    4731                                                                         {
    4732                                                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4733                                                                         }
    4734                                                                         $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
    4735                                                                 }
    4736                                                                 if (is_array($credits))
    4737                                                                 {
    4738                                                                         $credits = array_values(SimplePie_Misc::array_unique($credits));
    4739                                                                 }
    4740                                                         }
    4741                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
    4742                                                         {
    4743                                                                 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
    4744                                                                 {
    4745                                                                         $credit_role = null;
    4746                                                                         $credit_scheme = null;
    4747                                                                         $credit_name = null;
    4748                                                                         if (isset($credit['attribs']['']['role']))
    4749                                                                         {
    4750                                                                                 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
    4751                                                                         }
    4752                                                                         if (isset($credit['attribs']['']['scheme']))
    4753                                                                         {
    4754                                                                                 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4755                                                                         }
    4756                                                                         else
    4757                                                                         {
    4758                                                                                 $credit_scheme = 'urn:ebu';
    4759                                                                         }
    4760                                                                         if (isset($credit['data']))
    4761                                                                         {
    4762                                                                                 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4763                                                                         }
    4764                                                                         $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
    4765                                                                 }
    4766                                                                 if (is_array($credits))
    4767                                                                 {
    4768                                                                         $credits = array_values(SimplePie_Misc::array_unique($credits));
    4769                                                                 }
    4770                                                         }
    4771                                                         else
    4772                                                         {
    4773                                                                 $credits = $credits_parent;
    4774                                                         }
    4775 
    4776                                                         // DESCRIPTION
    4777                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
    4778                                                         {
    4779                                                                 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4780                                                         }
    4781                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
    4782                                                         {
    4783                                                                 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4784                                                         }
    4785                                                         else
    4786                                                         {
    4787                                                                 $description = $description_parent;
    4788                                                         }
    4789 
    4790                                                         // HASHES
    4791                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
    4792                                                         {
    4793                                                                 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
    4794                                                                 {
    4795                                                                         $value = null;
    4796                                                                         $algo = null;
    4797                                                                         if (isset($hash['data']))
    4798                                                                         {
    4799                                                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4800                                                                         }
    4801                                                                         if (isset($hash['attribs']['']['algo']))
    4802                                                                         {
    4803                                                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
    4804                                                                         }
    4805                                                                         else
    4806                                                                         {
    4807                                                                                 $algo = 'md5';
    4808                                                                         }
    4809                                                                         $hashes[] = $algo.':'.$value;
    4810                                                                 }
    4811                                                                 if (is_array($hashes))
    4812                                                                 {
    4813                                                                         $hashes = array_values(SimplePie_Misc::array_unique($hashes));
    4814                                                                 }
    4815                                                         }
    4816                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
    4817                                                         {
    4818                                                                 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
    4819                                                                 {
    4820                                                                         $value = null;
    4821                                                                         $algo = null;
    4822                                                                         if (isset($hash['data']))
    4823                                                                         {
    4824                                                                                 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4825                                                                         }
    4826                                                                         if (isset($hash['attribs']['']['algo']))
    4827                                                                         {
    4828                                                                                 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
    4829                                                                         }
    4830                                                                         else
    4831                                                                         {
    4832                                                                                 $algo = 'md5';
    4833                                                                         }
    4834                                                                         $hashes[] = $algo.':'.$value;
    4835                                                                 }
    4836                                                                 if (is_array($hashes))
    4837                                                                 {
    4838                                                                         $hashes = array_values(SimplePie_Misc::array_unique($hashes));
    4839                                                                 }
    4840                                                         }
    4841                                                         else
    4842                                                         {
    4843                                                                 $hashes = $hashes_parent;
    4844                                                         }
    4845 
    4846                                                         // KEYWORDS
    4847                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
    4848                                                         {
    4849                                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
    4850                                                                 {
    4851                                                                         $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
    4852                                                                         foreach ($temp as $word)
    4853                                                                         {
    4854                                                                                 $keywords[] = trim($word);
    4855                                                                         }
    4856                                                                         unset($temp);
    4857                                                                 }
    4858                                                                 if (is_array($keywords))
    4859                                                                 {
    4860                                                                         $keywords = array_values(SimplePie_Misc::array_unique($keywords));
    4861                                                                 }
    4862                                                         }
    4863                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
    4864                                                         {
    4865                                                                 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
    4866                                                                 {
    4867                                                                         $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
    4868                                                                         foreach ($temp as $word)
    4869                                                                         {
    4870                                                                                 $keywords[] = trim($word);
    4871                                                                         }
    4872                                                                         unset($temp);
    4873                                                                 }
    4874                                                                 if (is_array($keywords))
    4875                                                                 {
    4876                                                                         $keywords = array_values(SimplePie_Misc::array_unique($keywords));
    4877                                                                 }
    4878                                                         }
    4879                                                         else
    4880                                                         {
    4881                                                                 $keywords = $keywords_parent;
    4882                                                         }
    4883 
    4884                                                         // PLAYER
    4885                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
    4886                                                         {
    4887                                                                 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    4888                                                         }
    4889                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
    4890                                                         {
    4891                                                                 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    4892                                                         }
    4893                                                         else
    4894                                                         {
    4895                                                                 $player = $player_parent;
    4896                                                         }
    4897 
    4898                                                         // RATINGS
    4899                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
    4900                                                         {
    4901                                                                 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
    4902                                                                 {
    4903                                                                         $rating_scheme = null;
    4904                                                                         $rating_value = null;
    4905                                                                         if (isset($rating['attribs']['']['scheme']))
    4906                                                                         {
    4907                                                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4908                                                                         }
    4909                                                                         else
    4910                                                                         {
    4911                                                                                 $rating_scheme = 'urn:simple';
    4912                                                                         }
    4913                                                                         if (isset($rating['data']))
    4914                                                                         {
    4915                                                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4916                                                                         }
    4917                                                                         $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
    4918                                                                 }
    4919                                                                 if (is_array($ratings))
    4920                                                                 {
    4921                                                                         $ratings = array_values(SimplePie_Misc::array_unique($ratings));
    4922                                                                 }
    4923                                                         }
    4924                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
    4925                                                         {
    4926                                                                 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
    4927                                                                 {
    4928                                                                         $rating_scheme = null;
    4929                                                                         $rating_value = null;
    4930                                                                         if (isset($rating['attribs']['']['scheme']))
    4931                                                                         {
    4932                                                                                 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    4933                                                                         }
    4934                                                                         else
    4935                                                                         {
    4936                                                                                 $rating_scheme = 'urn:simple';
    4937                                                                         }
    4938                                                                         if (isset($rating['data']))
    4939                                                                         {
    4940                                                                                 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4941                                                                         }
    4942                                                                         $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
    4943                                                                 }
    4944                                                                 if (is_array($ratings))
    4945                                                                 {
    4946                                                                         $ratings = array_values(SimplePie_Misc::array_unique($ratings));
    4947                                                                 }
    4948                                                         }
    4949                                                         else
    4950                                                         {
    4951                                                                 $ratings = $ratings_parent;
    4952                                                         }
    4953 
    4954                                                         // RESTRICTIONS
    4955                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
    4956                                                         {
    4957                                                                 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
    4958                                                                 {
    4959                                                                         $restriction_relationship = null;
    4960                                                                         $restriction_type = null;
    4961                                                                         $restriction_value = null;
    4962                                                                         if (isset($restriction['attribs']['']['relationship']))
    4963                                                                         {
    4964                                                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
    4965                                                                         }
    4966                                                                         if (isset($restriction['attribs']['']['type']))
    4967                                                                         {
    4968                                                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    4969                                                                         }
    4970                                                                         if (isset($restriction['data']))
    4971                                                                         {
    4972                                                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4973                                                                         }
    4974                                                                         $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
    4975                                                                 }
    4976                                                                 if (is_array($restrictions))
    4977                                                                 {
    4978                                                                         $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
    4979                                                                 }
    4980                                                         }
    4981                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
    4982                                                         {
    4983                                                                 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
    4984                                                                 {
    4985                                                                         $restriction_relationship = null;
    4986                                                                         $restriction_type = null;
    4987                                                                         $restriction_value = null;
    4988                                                                         if (isset($restriction['attribs']['']['relationship']))
    4989                                                                         {
    4990                                                                                 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
    4991                                                                         }
    4992                                                                         if (isset($restriction['attribs']['']['type']))
    4993                                                                         {
    4994                                                                                 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    4995                                                                         }
    4996                                                                         if (isset($restriction['data']))
    4997                                                                         {
    4998                                                                                 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    4999                                                                         }
    5000                                                                         $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
    5001                                                                 }
    5002                                                                 if (is_array($restrictions))
    5003                                                                 {
    5004                                                                         $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
    5005                                                                 }
    5006                                                         }
    5007                                                         else
    5008                                                         {
    5009                                                                 $restrictions = $restrictions_parent;
    5010                                                         }
    5011 
    5012                                                         // THUMBNAILS
    5013                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
    5014                                                         {
    5015                                                                 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
    5016                                                                 {
    5017                                                                         $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    5018                                                                 }
    5019                                                                 if (is_array($thumbnails))
    5020                                                                 {
    5021                                                                         $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
    5022                                                                 }
    5023                                                         }
    5024                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
    5025                                                         {
    5026                                                                 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
    5027                                                                 {
    5028                                                                         $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    5029                                                                 }
    5030                                                                 if (is_array($thumbnails))
    5031                                                                 {
    5032                                                                         $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
    5033                                                                 }
    5034                                                         }
    5035                                                         else
    5036                                                         {
    5037                                                                 $thumbnails = $thumbnails_parent;
    5038                                                         }
    5039 
    5040                                                         // TITLES
    5041                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
    5042                                                         {
    5043                                                                 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5044                                                         }
    5045                                                         elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
    5046                                                         {
    5047                                                                 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5048                                                         }
    5049                                                         else
    5050                                                         {
    5051                                                                 $title = $title_parent;
    5052                                                         }
    5053 
    5054                                                         $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);
    5055                                                 }
    5056                                         }
    5057                                 }
    5058                         }
    5059 
    5060                         // If we have standalone media:content tags, loop through them.
    5061                         if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
    5062                         {
    5063                                 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
    5064                                 {
    5065                                         if (isset($content['attribs']['']['url']) || isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
    5066                                         {
    5067                                                 // Attributes
    5068                                                 $bitrate = null;
    5069                                                 $channels = null;
    5070                                                 $duration = null;
    5071                                                 $expression = null;
    5072                                                 $framerate = null;
    5073                                                 $height = null;
    5074                                                 $javascript = null;
    5075                                                 $lang = null;
    5076                                                 $length = null;
    5077                                                 $medium = null;
    5078                                                 $samplingrate = null;
    5079                                                 $type = null;
    5080                                                 $url = null;
    5081                                                 $width = null;
    5082 
    5083                                                 // Elements
    5084                                                 $captions = null;
    5085                                                 $categories = null;
    5086                                                 $copyrights = null;
    5087                                                 $credits = null;
    5088                                                 $description = null;
    5089                                                 $hashes = null;
    5090                                                 $keywords = null;
    5091                                                 $player = null;
    5092                                                 $ratings = null;
    5093                                                 $restrictions = null;
    5094                                                 $thumbnails = null;
    5095                                                 $title = null;
    5096 
    5097                                                 // Start checking the attributes of media:content
    5098                                                 if (isset($content['attribs']['']['bitrate']))
    5099                                                 {
    5100                                                         $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
    5101                                                 }
    5102                                                 if (isset($content['attribs']['']['channels']))
    5103                                                 {
    5104                                                         $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
    5105                                                 }
    5106                                                 if (isset($content['attribs']['']['duration']))
    5107                                                 {
    5108                                                         $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
    5109                                                 }
    5110                                                 else
    5111                                                 {
    5112                                                         $duration = $duration_parent;
    5113                                                 }
    5114                                                 if (isset($content['attribs']['']['expression']))
    5115                                                 {
    5116                                                         $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
    5117                                                 }
    5118                                                 if (isset($content['attribs']['']['framerate']))
    5119                                                 {
    5120                                                         $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
    5121                                                 }
    5122                                                 if (isset($content['attribs']['']['height']))
    5123                                                 {
    5124                                                         $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
    5125                                                 }
    5126                                                 if (isset($content['attribs']['']['lang']))
    5127                                                 {
    5128                                                         $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
    5129                                                 }
    5130                                                 if (isset($content['attribs']['']['fileSize']))
    5131                                                 {
    5132                                                         $length = ceil($content['attribs']['']['fileSize']);
    5133                                                 }
    5134                                                 if (isset($content['attribs']['']['medium']))
    5135                                                 {
    5136                                                         $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
    5137                                                 }
    5138                                                 if (isset($content['attribs']['']['samplingrate']))
    5139                                                 {
    5140                                                         $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
    5141                                                 }
    5142                                                 if (isset($content['attribs']['']['type']))
    5143                                                 {
    5144                                                         $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    5145                                                 }
    5146                                                 if (isset($content['attribs']['']['width']))
    5147                                                 {
    5148                                                         $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
    5149                                                 }
    5150                                                 if (isset($content['attribs']['']['url']))
    5151                                                 {
    5152                                                         $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    5153                                                 }
    5154                                                 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
    5155 
    5156                                                 // CAPTIONS
    5157                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
    5158                                                 {
    5159                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
    5160                                                         {
    5161                                                                 $caption_type = null;
    5162                                                                 $caption_lang = null;
    5163                                                                 $caption_startTime = null;
    5164                                                                 $caption_endTime = null;
    5165                                                                 $caption_text = null;
    5166                                                                 if (isset($caption['attribs']['']['type']))
    5167                                                                 {
    5168                                                                         $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    5169                                                                 }
    5170                                                                 if (isset($caption['attribs']['']['lang']))
    5171                                                                 {
    5172                                                                         $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
    5173                                                                 }
    5174                                                                 if (isset($caption['attribs']['']['start']))
    5175                                                                 {
    5176                                                                         $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
    5177                                                                 }
    5178                                                                 if (isset($caption['attribs']['']['end']))
    5179                                                                 {
    5180                                                                         $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
    5181                                                                 }
    5182                                                                 if (isset($caption['data']))
    5183                                                                 {
    5184                                                                         $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5185                                                                 }
    5186                                                                 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
    5187                                                         }
    5188                                                         if (is_array($captions))
    5189                                                         {
    5190                                                                 $captions = array_values(SimplePie_Misc::array_unique($captions));
    5191                                                         }
    5192                                                 }
    5193                                                 else
    5194                                                 {
    5195                                                         $captions = $captions_parent;
    5196                                                 }
    5197 
    5198                                                 // CATEGORIES
    5199                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
    5200                                                 {
    5201                                                         foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
    5202                                                         {
    5203                                                                 $term = null;
    5204                                                                 $scheme = null;
    5205                                                                 $label = null;
    5206                                                                 if (isset($category['data']))
    5207                                                                 {
    5208                                                                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5209                                                                 }
    5210                                                                 if (isset($category['attribs']['']['scheme']))
    5211                                                                 {
    5212                                                                         $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    5213                                                                 }
    5214                                                                 else
    5215                                                                 {
    5216                                                                         $scheme = 'http://search.yahoo.com/mrss/category_schema';
    5217                                                                 }
    5218                                                                 if (isset($category['attribs']['']['label']))
    5219                                                                 {
    5220                                                                         $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
    5221                                                                 }
    5222                                                                 $categories[] =& new $this->feed->category_class($term, $scheme, $label);
    5223                                                         }
    5224                                                 }
    5225                                                 if (is_array($categories) && is_array($categories_parent))
    5226                                                 {
    5227                                                         $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
    5228                                                 }
    5229                                                 elseif (is_array($categories))
    5230                                                 {
    5231                                                         $categories = array_values(SimplePie_Misc::array_unique($categories));
    5232                                                 }
    5233                                                 elseif (is_array($categories_parent))
    5234                                                 {
    5235                                                         $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
    5236                                                 }
    5237                                                 else
    5238                                                 {
    5239                                                         $categories = null;
    5240                                                 }
    5241 
    5242                                                 // COPYRIGHTS
    5243                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
    5244                                                 {
    5245                                                         $copyright_url = null;
    5246                                                         $copyright_label = null;
    5247                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
    5248                                                         {
    5249                                                                 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
    5250                                                         }
    5251                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
    5252                                                         {
    5253                                                                 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5254                                                         }
    5255                                                         $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label);
    5256                                                 }
    5257                                                 else
    5258                                                 {
    5259                                                         $copyrights = $copyrights_parent;
    5260                                                 }
    5261 
    5262                                                 // CREDITS
    5263                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
    5264                                                 {
    5265                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
    5266                                                         {
    5267                                                                 $credit_role = null;
    5268                                                                 $credit_scheme = null;
    5269                                                                 $credit_name = null;
    5270                                                                 if (isset($credit['attribs']['']['role']))
    5271                                                                 {
    5272                                                                         $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
    5273                                                                 }
    5274                                                                 if (isset($credit['attribs']['']['scheme']))
    5275                                                                 {
    5276                                                                         $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    5277                                                                 }
    5278                                                                 else
    5279                                                                 {
    5280                                                                         $credit_scheme = 'urn:ebu';
    5281                                                                 }
    5282                                                                 if (isset($credit['data']))
    5283                                                                 {
    5284                                                                         $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5285                                                                 }
    5286                                                                 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
    5287                                                         }
    5288                                                         if (is_array($credits))
    5289                                                         {
    5290                                                                 $credits = array_values(SimplePie_Misc::array_unique($credits));
    5291                                                         }
    5292                                                 }
    5293                                                 else
    5294                                                 {
    5295                                                         $credits = $credits_parent;
    5296                                                 }
    5297 
    5298                                                 // DESCRIPTION
    5299                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
    5300                                                 {
    5301                                                         $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5302                                                 }
    5303                                                 else
    5304                                                 {
    5305                                                         $description = $description_parent;
    5306                                                 }
    5307 
    5308                                                 // HASHES
    5309                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
    5310                                                 {
    5311                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
    5312                                                         {
    5313                                                                 $value = null;
    5314                                                                 $algo = null;
    5315                                                                 if (isset($hash['data']))
    5316                                                                 {
    5317                                                                         $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5318                                                                 }
    5319                                                                 if (isset($hash['attribs']['']['algo']))
    5320                                                                 {
    5321                                                                         $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
    5322                                                                 }
    5323                                                                 else
    5324                                                                 {
    5325                                                                         $algo = 'md5';
    5326                                                                 }
    5327                                                                 $hashes[] = $algo.':'.$value;
    5328                                                         }
    5329                                                         if (is_array($hashes))
    5330                                                         {
    5331                                                                 $hashes = array_values(SimplePie_Misc::array_unique($hashes));
    5332                                                         }
    5333                                                 }
    5334                                                 else
    5335                                                 {
    5336                                                         $hashes = $hashes_parent;
    5337                                                 }
    5338 
    5339                                                 // KEYWORDS
    5340                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
    5341                                                 {
    5342                                                         if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
    5343                                                         {
    5344                                                                 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
    5345                                                                 foreach ($temp as $word)
    5346                                                                 {
    5347                                                                         $keywords[] = trim($word);
    5348                                                                 }
    5349                                                                 unset($temp);
    5350                                                         }
    5351                                                         if (is_array($keywords))
    5352                                                         {
    5353                                                                 $keywords = array_values(SimplePie_Misc::array_unique($keywords));
    5354                                                         }
    5355                                                 }
    5356                                                 else
    5357                                                 {
    5358                                                         $keywords = $keywords_parent;
    5359                                                 }
    5360 
    5361                                                 // PLAYER
    5362                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
    5363                                                 {
    5364                                                         $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    5365                                                 }
    5366                                                 else
    5367                                                 {
    5368                                                         $player = $player_parent;
    5369                                                 }
    5370 
    5371                                                 // RATINGS
    5372                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
    5373                                                 {
    5374                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
    5375                                                         {
    5376                                                                 $rating_scheme = null;
    5377                                                                 $rating_value = null;
    5378                                                                 if (isset($rating['attribs']['']['scheme']))
    5379                                                                 {
    5380                                                                         $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    5381                                                                 }
    5382                                                                 else
    5383                                                                 {
    5384                                                                         $rating_scheme = 'urn:simple';
    5385                                                                 }
    5386                                                                 if (isset($rating['data']))
    5387                                                                 {
    5388                                                                         $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5389                                                                 }
    5390                                                                 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value);
    5391                                                         }
    5392                                                         if (is_array($ratings))
    5393                                                         {
    5394                                                                 $ratings = array_values(SimplePie_Misc::array_unique($ratings));
    5395                                                         }
    5396                                                 }
    5397                                                 else
    5398                                                 {
    5399                                                         $ratings = $ratings_parent;
    5400                                                 }
    5401 
    5402                                                 // RESTRICTIONS
    5403                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
    5404                                                 {
    5405                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
    5406                                                         {
    5407                                                                 $restriction_relationship = null;
    5408                                                                 $restriction_type = null;
    5409                                                                 $restriction_value = null;
    5410                                                                 if (isset($restriction['attribs']['']['relationship']))
    5411                                                                 {
    5412                                                                         $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
    5413                                                                 }
    5414                                                                 if (isset($restriction['attribs']['']['type']))
    5415                                                                 {
    5416                                                                         $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    5417                                                                 }
    5418                                                                 if (isset($restriction['data']))
    5419                                                                 {
    5420                                                                         $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5421                                                                 }
    5422                                                                 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
    5423                                                         }
    5424                                                         if (is_array($restrictions))
    5425                                                         {
    5426                                                                 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
    5427                                                         }
    5428                                                 }
    5429                                                 else
    5430                                                 {
    5431                                                         $restrictions = $restrictions_parent;
    5432                                                 }
    5433 
    5434                                                 // THUMBNAILS
    5435                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
    5436                                                 {
    5437                                                         foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
    5438                                                         {
    5439                                                                 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
    5440                                                         }
    5441                                                         if (is_array($thumbnails))
    5442                                                         {
    5443                                                                 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
    5444                                                         }
    5445                                                 }
    5446                                                 else
    5447                                                 {
    5448                                                         $thumbnails = $thumbnails_parent;
    5449                                                 }
    5450 
    5451                                                 // TITLES
    5452                                                 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
    5453                                                 {
    5454                                                         $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5455                                                 }
    5456                                                 else
    5457                                                 {
    5458                                                         $title = $title_parent;
    5459                                                 }
    5460 
    5461                                                 $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);
    5462                                         }
    5463                                 }
    5464                         }
    5465 
    5466                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
    5467                         {
    5468                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
    5469                                 {
    5470                                         // Attributes
    5471                                         $bitrate = null;
    5472                                         $channels = null;
    5473                                         $duration = null;
    5474                                         $expression = null;
    5475                                         $framerate = null;
    5476                                         $height = null;
    5477                                         $javascript = null;
    5478                                         $lang = null;
    5479                                         $length = null;
    5480                                         $medium = null;
    5481                                         $samplingrate = null;
    5482                                         $type = null;
    5483                                         $url = null;
    5484                                         $width = null;
    5485 
    5486                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
    5487                                         if (isset($link['attribs']['']['type']))
    5488                                         {
    5489                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    5490                                         }
    5491                                         if (isset($link['attribs']['']['length']))
    5492                                         {
    5493                                                 $length = ceil($link['attribs']['']['length']);
    5494                                         }
    5495 
    5496                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
    5497                                         $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);
    5498                                 }
    5499                         }
    5500 
    5501                         foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
    5502                         {
    5503                                 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
    5504                                 {
    5505                                         // Attributes
    5506                                         $bitrate = null;
    5507                                         $channels = null;
    5508                                         $duration = null;
    5509                                         $expression = null;
    5510                                         $framerate = null;
    5511                                         $height = null;
    5512                                         $javascript = null;
    5513                                         $lang = null;
    5514                                         $length = null;
    5515                                         $medium = null;
    5516                                         $samplingrate = null;
    5517                                         $type = null;
    5518                                         $url = null;
    5519                                         $width = null;
    5520 
    5521                                         $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
    5522                                         if (isset($link['attribs']['']['type']))
    5523                                         {
    5524                                                 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    5525                                         }
    5526                                         if (isset($link['attribs']['']['length']))
    5527                                         {
    5528                                                 $length = ceil($link['attribs']['']['length']);
    5529                                         }
    5530 
    5531                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
    5532                                         $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);
    5533                                 }
    5534                         }
    5535 
    5536                         if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
    5537                         {
    5538                                 if (isset($enclosure[0]['attribs']['']['url']))
    5539                                 {
    5540                                         // Attributes
    5541                                         $bitrate = null;
    5542                                         $channels = null;
    5543                                         $duration = null;
    5544                                         $expression = null;
    5545                                         $framerate = null;
    5546                                         $height = null;
    5547                                         $javascript = null;
    5548                                         $lang = null;
    5549                                         $length = null;
    5550                                         $medium = null;
    5551                                         $samplingrate = null;
    5552                                         $type = null;
    5553                                         $url = null;
    5554                                         $width = null;
    5555 
    5556                                         $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
    5557                                         if (isset($enclosure[0]['attribs']['']['type']))
    5558                                         {
    5559                                                 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
    5560                                         }
    5561                                         if (isset($enclosure[0]['attribs']['']['length']))
    5562                                         {
    5563                                                 $length = ceil($enclosure[0]['attribs']['']['length']);
    5564                                         }
    5565 
    5566                                         // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
    5567                                         $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);
    5568                                 }
    5569                         }
    5570 
    5571                         if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $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))
    5572                         {
    5573                                 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
    5574                                 $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);
    5575                         }
    5576 
    5577                         $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
    5578                 }
    5579                 if (!empty($this->data['enclosures']))
    5580                 {
    5581                         return $this->data['enclosures'];
    5582                 }
    5583                 else
    5584                 {
    5585                         return null;
    5586                 }
    5587         }
    5588 
    5589         function get_latitude()
    5590         {
    5591                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
    5592                 {
    5593                         return (float) $return[0]['data'];
    5594                 }
    5595                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
    5596                 {
    5597                         return (float) $match[1];
    5598                 }
    5599                 else
    5600                 {
    5601                         return null;
    5602                 }
    5603         }
    5604 
    5605         function get_longitude()
    5606         {
    5607                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
    5608                 {
    5609                         return (float) $return[0]['data'];
    5610                 }
    5611                 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
    5612                 {
    5613                         return (float) $return[0]['data'];
    5614                 }
    5615                 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
    5616                 {
    5617                         return (float) $match[2];
    5618                 }
    5619                 else
    5620                 {
    5621                         return null;
    5622                 }
    5623         }
    5624 
    5625         function get_source()
    5626         {
    5627                 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
    5628                 {
    5629                         return new $this->feed->source_class($this, $return[0]);
    5630                 }
    5631                 else
    5632                 {
    5633                         return null;
    5634                 }
    5635         }
    5636 
    5637         /**
    5638          * Creates the add_to_* methods' return data
    5639          *
    5640          * @access private
    5641          * @param string $item_url String to prefix to the item permalink
    5642          * @param string $title_url String to prefix to the item title
    5643          * (and suffix to the item permalink)
    5644          * @return mixed URL if feed exists, false otherwise
    5645          */
    5646         function add_to_service($item_url, $title_url = null, $summary_url = null)
    5647         {
    5648                 if ($this->get_permalink() !== null)
    5649                 {
    5650                         $return = $item_url . rawurlencode($this->get_permalink());
    5651                         if ($title_url !== null && $this->get_title() !== null)
    5652                         {
    5653                                 $return .= $title_url . rawurlencode($this->get_title());
    5654                         }
    5655                         if ($summary_url !== null && $this->get_description() !== null)
    5656                         {
    5657                                 $return .= $summary_url . rawurlencode($this->get_description());
    5658                         }
    5659                         return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
    5660                 }
    5661                 else
    5662                 {
    5663                         return null;
    5664                 }
    5665         }
    5666 
    5667         function add_to_blinklist()
    5668         {
    5669                 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
    5670         }
    5671 
    5672         function add_to_blogmarks()
    5673         {
    5674                 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
    5675         }
    5676 
    5677         function add_to_delicious()
    5678         {
    5679                 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
    5680         }
    5681 
    5682         function add_to_digg()
    5683         {
    5684                 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
    5685         }
    5686 
    5687         function add_to_furl()
    5688         {
    5689                 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
    5690         }
    5691 
    5692         function add_to_magnolia()
    5693         {
    5694                 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
    5695         }
    5696 
    5697         function add_to_myweb20()
    5698         {
    5699                 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
    5700         }
    5701 
    5702         function add_to_newsvine()
    5703         {
    5704                 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
    5705         }
    5706 
    5707         function add_to_reddit()
    5708         {
    5709                 return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
    5710         }
    5711 
    5712         function add_to_segnalo()
    5713         {
    5714                 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
    5715         }
    5716 
    5717         function add_to_simpy()
    5718         {
    5719                 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
    5720         }
    5721 
    5722         function add_to_spurl()
    5723         {
    5724                 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
    5725         }
    5726 
    5727         function add_to_wists()
    5728         {
    5729                 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
    5730         }
    5731 
    5732         function search_technorati()
    5733         {
    5734                 return $this->add_to_service('http://www.technorati.com/search/');
    5735         }
    5736 }
    5737 
    5738 class SimplePie_Source
    5739 {
    5740         var $item;
    5741         var $data = array();
    5742 
    5743         function SimplePie_Source($item, $data)
    5744         {
    5745                 $this->item = $item;
    5746                 $this->data = $data;
    5747         }
    5748 
    5749         function __toString()
    5750         {
    5751                 return md5(serialize($this->data));
    5752         }
    5753 
    5754         function get_source_tags($namespace, $tag)
    5755         {
    5756                 if (isset($this->data['child'][$namespace][$tag]))
    5757                 {
    5758                         return $this->data['child'][$namespace][$tag];
    5759                 }
    5760                 else
    5761                 {
    5762                         return null;
    5763                 }
    5764         }
    5765 
    5766         function get_base($element = array())
    5767         {
    5768                 return $this->item->get_base($element);
    5769         }
    5770 
    5771         function sanitize($data, $type, $base = '')
    5772         {
    5773                 return $this->item->sanitize($data, $type, $base);
    5774         }
    5775 
    5776         function get_item()
    5777         {
    5778                 return $this->item;
    5779         }
    5780 
    5781         function get_title()
    5782         {
    5783                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
    5784                 {
    5785                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    5786                 }
    5787                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
    5788                 {
    5789                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    5790                 }
    5791                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
    5792                 {
    5793                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    5794                 }
    5795                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
    5796                 {
    5797                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    5798                 }
    5799                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
    5800                 {
    5801                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    5802                 }
    5803                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
    5804                 {
    5805                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5806                 }
    5807                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
    5808                 {
    5809                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5810                 }
    5811                 else
    5812                 {
    5813                         return null;
    5814                 }
    5815         }
    5816 
    5817         function get_category($key = 0)
    5818         {
    5819                 $categories = $this->get_categories();
    5820                 if (isset($categories[$key]))
    5821                 {
    5822                         return $categories[$key];
    5823                 }
    5824                 else
    5825                 {
    5826                         return null;
    5827                 }
    5828         }
    5829 
    5830         function get_categories()
    5831         {
    5832                 $categories = array();
    5833 
    5834                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
    5835                 {
    5836                         $term = null;
    5837                         $scheme = null;
    5838                         $label = null;
    5839                         if (isset($category['attribs']['']['term']))
    5840                         {
    5841                                 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
    5842                         }
    5843                         if (isset($category['attribs']['']['scheme']))
    5844                         {
    5845                                 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
    5846                         }
    5847                         if (isset($category['attribs']['']['label']))
    5848                         {
    5849                                 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
    5850                         }
    5851                         $categories[] =& new $this->item->feed->category_class($term, $scheme, $label);
    5852                 }
    5853                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
    5854                 {
    5855                         // This is really the label, but keep this as the term also for BC.
    5856                         // Label will also work on retrieving because that falls back to term.
    5857                         $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5858                         if (isset($category['attribs']['']['domain']))
    5859                         {
    5860                                 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
    5861                         }
    5862                         else
    5863                         {
    5864                                 $scheme = null;
    5865                         }
    5866                         $categories[] =& new $this->item->feed->category_class($term, $scheme, null);
    5867                 }
    5868                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
    5869                 {
    5870                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    5871                 }
    5872                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
    5873                 {
    5874                         $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    5875                 }
    5876 
    5877                 if (!empty($categories))
    5878                 {
    5879                         return SimplePie_Misc::array_unique($categories);
    5880                 }
    5881                 else
    5882                 {
    5883                         return null;
    5884                 }
    5885         }
    5886 
    5887         function get_author($key = 0)
    5888         {
    5889                 $authors = $this->get_authors();
    5890                 if (isset($authors[$key]))
    5891                 {
    5892                         return $authors[$key];
    5893                 }
    5894                 else
    5895                 {
    5896                         return null;
    5897                 }
    5898         }
    5899 
    5900         function get_authors()
    5901         {
    5902                 $authors = array();
    5903                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
    5904                 {
    5905                         $name = null;
    5906                         $uri = null;
    5907                         $email = null;
    5908                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
    5909                         {
    5910                                 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5911                         }
    5912                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
    5913                         {
    5914                                 $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]));
    5915                         }
    5916                         if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
    5917                         {
    5918                                 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5919                         }
    5920                         if ($name !== null || $email !== null || $uri !== null)
    5921                         {
    5922                                 $authors[] =& new $this->item->feed->author_class($name, $uri, $email);
    5923                         }
    5924                 }
    5925                 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
    5926                 {
    5927                         $name = null;
    5928                         $url = null;
    5929                         $email = null;
    5930                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
    5931                         {
    5932                                 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5933                         }
    5934                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
    5935                         {
    5936                                 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
    5937                         }
    5938                         if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
    5939                         {
    5940                                 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5941                         }
    5942                         if ($name !== null || $email !== null || $url !== null)
    5943                         {
    5944                                 $authors[] =& new $this->item->feed->author_class($name, $url, $email);
    5945                         }
    5946                 }
    5947                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
    5948                 {
    5949                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    5950                 }
    5951                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
    5952                 {
    5953                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    5954                 }
    5955                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
    5956                 {
    5957                         $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
    5958                 }
    5959 
    5960                 if (!empty($authors))
    5961                 {
    5962                         return SimplePie_Misc::array_unique($authors);
    5963                 }
    5964                 else
    5965                 {
    5966                         return null;
    5967                 }
    5968         }
    5969 
    5970         function get_contributor($key = 0)
    5971         {
    5972                 $contributors = $this->get_contributors();
    5973                 if (isset($contributors[$key]))
    5974                 {
    5975                         return $contributors[$key];
    5976                 }
    5977                 else
    5978                 {
    5979                         return null;
    5980                 }
    5981         }
    5982 
    5983         function get_contributors()
    5984         {
    5985                 $contributors = array();
    5986                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
    5987                 {
    5988                         $name = null;
    5989                         $uri = null;
    5990                         $email = null;
    5991                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
    5992                         {
    5993                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    5994                         }
    5995                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
    5996                         {
    5997                                 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
    5998                         }
    5999                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
    6000                         {
    6001                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6002                         }
    6003                         if ($name !== null || $email !== null || $uri !== null)
    6004                         {
    6005                                 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email);
    6006                         }
    6007                 }
    6008                 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
    6009                 {
    6010                         $name = null;
    6011                         $url = null;
    6012                         $email = null;
    6013                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
    6014                         {
    6015                                 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6016                         }
    6017                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
    6018                         {
    6019                                 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
    6020                         }
    6021                         if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
    6022                         {
    6023                                 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6024                         }
    6025                         if ($name !== null || $email !== null || $url !== null)
    6026                         {
    6027                                 $contributors[] =& new $this->item->feed->author_class($name, $url, $email);
    6028                         }
    6029                 }
    6030 
    6031                 if (!empty($contributors))
    6032                 {
    6033                         return SimplePie_Misc::array_unique($contributors);
    6034                 }
    6035                 else
    6036                 {
    6037                         return null;
    6038                 }
    6039         }
    6040 
    6041         function get_link($key = 0, $rel = 'alternate')
    6042         {
    6043                 $links = $this->get_links($rel);
    6044                 if (isset($links[$key]))
    6045                 {
    6046                         return $links[$key];
    6047                 }
    6048                 else
    6049                 {
    6050                         return null;
    6051                 }
    6052         }
    6053 
    6054         /**
    6055          * Added for parity between the parent-level and the item/entry-level.
    6056          */
    6057         function get_permalink()
    6058         {
    6059                 return $this->get_link(0);
    6060         }
    6061 
    6062         function get_links($rel = 'alternate')
    6063         {
    6064                 if (!isset($this->data['links']))
    6065                 {
    6066                         $this->data['links'] = array();
    6067                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
    6068                         {
    6069                                 foreach ($links as $link)
    6070                                 {
    6071                                         if (isset($link['attribs']['']['href']))
    6072                                         {
    6073                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
    6074                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
    6075                                         }
    6076                                 }
    6077                         }
    6078                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
    6079                         {
    6080                                 foreach ($links as $link)
    6081                                 {
    6082                                         if (isset($link['attribs']['']['href']))
    6083                                         {
    6084                                                 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
    6085                                                 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
    6086 
    6087                                         }
    6088                                 }
    6089                         }
    6090                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
    6091                         {
    6092                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
    6093                         }
    6094                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
    6095                         {
    6096                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
    6097                         }
    6098                         if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
    6099                         {
    6100                                 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
    6101                         }
    6102 
    6103                         $keys = array_keys($this->data['links']);
    6104                         foreach ($keys as $key)
    6105                         {
    6106                                 if (SimplePie_Misc::is_isegment_nz_nc($key))
    6107                                 {
    6108                                         if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
    6109                                         {
    6110                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
    6111                                                 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
    6112                                         }
    6113                                         else
    6114                                         {
    6115                                                 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
    6116                                         }
    6117                                 }
    6118                                 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
    6119                                 {
    6120                                         $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
    6121                                 }
    6122                                 $this->data['links'][$key] = array_unique($this->data['links'][$key]);
    6123                         }
    6124                 }
    6125 
    6126                 if (isset($this->data['links'][$rel]))
    6127                 {
    6128                         return $this->data['links'][$rel];
    6129                 }
    6130                 else
    6131                 {
    6132                         return null;
    6133                 }
    6134         }
    6135 
    6136         function get_description()
    6137         {
    6138                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
    6139                 {
    6140                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    6141                 }
    6142                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
    6143                 {
    6144                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    6145                 }
    6146                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
    6147                 {
    6148                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    6149                 }
    6150                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
    6151                 {
    6152                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    6153                 }
    6154                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
    6155                 {
    6156                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
    6157                 }
    6158                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
    6159                 {
    6160                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6161                 }
    6162                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
    6163                 {
    6164                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6165                 }
    6166                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
    6167                 {
    6168                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
    6169                 }
    6170                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
    6171                 {
    6172                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
    6173                 }
    6174                 else
    6175                 {
    6176                         return null;
    6177                 }
    6178         }
    6179 
    6180         function get_copyright()
    6181         {
    6182                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
    6183                 {
    6184                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    6185                 }
    6186                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
    6187                 {
    6188                         return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
    6189                 }
    6190                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
    6191                 {
    6192                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6193                 }
    6194                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
    6195                 {
    6196                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6197                 }
    6198                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
    6199                 {
    6200                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6201                 }
    6202                 else
    6203                 {
    6204                         return null;
    6205                 }
    6206         }
    6207 
    6208         function get_language()
    6209         {
    6210                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
    6211                 {
    6212                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6213                 }
    6214                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
    6215                 {
    6216                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6217                 }
    6218                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
    6219                 {
    6220                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
    6221                 }
    6222                 elseif (isset($this->data['xml_lang']))
    6223                 {
    6224                         return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
    6225                 }
    6226                 else
    6227                 {
    6228                         return null;
    6229                 }
    6230         }
    6231 
    6232         function get_latitude()
    6233         {
    6234                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
    6235                 {
    6236                         return (float) $return[0]['data'];
    6237                 }
    6238                 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
    6239                 {
    6240                         return (float) $match[1];
    6241                 }
    6242                 else
    6243                 {
    6244                         return null;
    6245                 }
    6246         }
    6247 
    6248         function get_longitude()
    6249         {
    6250                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
    6251                 {
    6252                         return (float) $return[0]['data'];
    6253                 }
    6254                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
    6255                 {
    6256                         return (float) $return[0]['data'];
    6257                 }
    6258                 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
    6259                 {
    6260                         return (float) $match[2];
    6261                 }
    6262                 else
    6263                 {
    6264                         return null;
    6265                 }
    6266         }
    6267 
    6268         function get_image_url()
    6269         {
    6270                 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
    6271                 {
    6272                         return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
    6273                 }
    6274                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
    6275                 {
    6276                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
    6277                 }
    6278                 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
    6279                 {
    6280                         return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
    6281                 }
    6282                 else
    6283                 {
    6284                         return null;
    6285                 }
    6286         }
    6287 }
    6288 
    6289 class SimplePie_Author
    6290 {
    6291         var $name;
    6292         var $link;
    6293         var $email;
    6294 
    6295         // Constructor, used to input the data
    6296         function SimplePie_Author($name = null, $link = null, $email = null)
    6297         {
    6298                 $this->name = $name;
    6299                 $this->link = $link;
    6300                 $this->email = $email;
    6301         }
    6302 
    6303         function __toString()
    6304         {
    6305                 // There is no $this->data here
    6306                 return md5(serialize($this));
    6307         }
    6308 
    6309         function get_name()
    6310         {
    6311                 if ($this->name !== null)
    6312                 {
    6313                         return $this->name;
    6314                 }
    6315                 else
    6316                 {
    6317                         return null;
    6318                 }
    6319         }
    6320 
    6321         function get_link()
    6322         {
    6323                 if ($this->link !== null)
    6324                 {
    6325                         return $this->link;
    6326                 }
    6327                 else
    6328                 {
    6329                         return null;
    6330                 }
    6331         }
    6332 
    6333         function get_email()
    6334         {
    6335                 if ($this->email !== null)
    6336                 {
    6337                         return $this->email;
    6338                 }
    6339                 else
    6340                 {
    6341                         return null;
    6342                 }
    6343         }
    6344 }
    6345 
    6346 class SimplePie_Category
    6347 {
    6348         var $term;
    6349         var $scheme;
    6350         var $label;
    6351 
    6352         // Constructor, used to input the data
    6353         function SimplePie_Category($term = null, $scheme = null, $label = null)
    6354         {
    6355                 $this->term = $term;
    6356                 $this->scheme = $scheme;
    6357                 $this->label = $label;
    6358         }
    6359 
    6360         function __toString()
    6361         {
    6362                 // There is no $this->data here
    6363                 return md5(serialize($this));
    6364         }
    6365 
    6366         function get_term()
    6367         {
    6368                 if ($this->term !== null)
    6369                 {
    6370                         return $this->term;
    6371                 }
    6372                 else
    6373                 {
    6374                         return null;
    6375                 }
    6376         }
    6377 
    6378         function get_scheme()
    6379         {
    6380                 if ($this->scheme !== null)
    6381                 {
    6382                         return $this->scheme;
    6383                 }
    6384                 else
    6385                 {
    6386                         return null;
    6387                 }
    6388         }
    6389 
    6390         function get_label()
    6391         {
    6392                 if ($this->label !== null)
    6393                 {
    6394                         return $this->label;
    6395                 }
    6396                 else
    6397                 {
    6398                         return $this->get_term();
    6399                 }
    6400         }
    6401 }
    6402 
    6403 class SimplePie_Enclosure
    6404 {
    6405         var $bitrate;
    6406         var $captions;
    6407         var $categories;
    6408         var $channels;
    6409         var $copyright;
    6410         var $credits;
    6411         var $description;
    6412         var $duration;
    6413         var $expression;
    6414         var $framerate;
    6415         var $handler;
    6416         var $hashes;
    6417         var $height;
    6418         var $javascript;
    6419         var $keywords;
    6420         var $lang;
    6421         var $length;
    6422         var $link;
    6423         var $medium;
    6424         var $player;
    6425         var $ratings;
    6426         var $restrictions;
    6427         var $samplingrate;
    6428         var $thumbnails;
    6429         var $title;
    6430         var $type;
    6431         var $width;
    6432 
    6433         // Constructor, used to input the data
    6434         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)
    6435         {
    6436                 $this->bitrate = $bitrate;
    6437                 $this->captions = $captions;
    6438                 $this->categories = $categories;
    6439                 $this->channels = $channels;
    6440                 $this->copyright = $copyright;
    6441                 $this->credits = $credits;
    6442                 $this->description = $description;
    6443                 $this->duration = $duration;
    6444                 $this->expression = $expression;
    6445                 $this->framerate = $framerate;
    6446                 $this->hashes = $hashes;
    6447                 $this->height = $height;
    6448                 $this->javascript = $javascript;
    6449                 $this->keywords = $keywords;
    6450                 $this->lang = $lang;
    6451                 $this->length = $length;
    6452                 $this->link = $link;
    6453                 $this->medium = $medium;
    6454                 $this->player = $player;
    6455                 $this->ratings = $ratings;
    6456                 $this->restrictions = $restrictions;
    6457                 $this->samplingrate = $samplingrate;
    6458                 $this->thumbnails = $thumbnails;
    6459                 $this->title = $title;
    6460                 $this->type = $type;
    6461                 $this->width = $width;
    6462                 if (class_exists('idna_convert'))
    6463                 {
    6464                         $idn =& new idna_convert;
    6465                         $parsed = SimplePie_Misc::parse_url($link);
    6466                         $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
    6467                 }
    6468                 $this->handler = $this->get_handler(); // Needs to load last
    6469         }
    6470 
    6471         function __toString()
    6472         {
    6473                 // There is no $this->data here
    6474                 return md5(serialize($this));
    6475         }
    6476 
    6477         function get_bitrate()
    6478         {
    6479                 if ($this->bitrate !== null)
    6480                 {
    6481                         return $this->bitrate;
    6482                 }
    6483                 else
    6484                 {
    6485                         return null;
    6486                 }
    6487         }
    6488 
    6489         function get_caption($key = 0)
    6490         {
    6491                 $captions = $this->get_captions();
    6492                 if (isset($captions[$key]))
    6493                 {
    6494                         return $captions[$key];
    6495                 }
    6496                 else
    6497                 {
    6498                         return null;
    6499                 }
    6500         }
    6501 
    6502         function get_captions()
    6503         {
    6504                 if ($this->captions !== null)
    6505                 {
    6506                         return $this->captions;
    6507                 }
    6508                 else
    6509                 {
    6510                         return null;
    6511                 }
    6512         }
    6513 
    6514         function get_category($key = 0)
    6515         {
    6516                 $categories = $this->get_categories();
    6517                 if (isset($categories[$key]))
    6518                 {
    6519                         return $categories[$key];
    6520                 }
    6521                 else
    6522                 {
    6523                         return null;
    6524                 }
    6525         }
    6526 
    6527         function get_categories()
    6528         {
    6529                 if ($this->categories !== null)
    6530                 {
    6531                         return $this->categories;
    6532                 }
    6533                 else
    6534                 {
    6535                         return null;
    6536                 }
    6537         }
    6538 
    6539         function get_channels()
    6540         {
    6541                 if ($this->channels !== null)
    6542                 {
    6543                         return $this->channels;
    6544                 }
    6545                 else
    6546                 {
    6547                         return null;
    6548                 }
    6549         }
    6550 
    6551         function get_copyright()
    6552         {
    6553                 if ($this->copyright !== null)
    6554                 {
    6555                         return $this->copyright;
    6556                 }
    6557                 else
    6558                 {
    6559                         return null;
    6560                 }
    6561         }
    6562 
    6563         function get_credit($key = 0)
    6564         {
    6565                 $credits = $this->get_credits();
    6566                 if (isset($credits[$key]))
    6567                 {
    6568                         return $credits[$key];
    6569                 }
    6570                 else
    6571                 {
    6572                         return null;
    6573                 }
    6574         }
    6575 
    6576         function get_credits()
    6577         {
    6578                 if ($this->credits !== null)
    6579                 {
    6580                         return $this->credits;
    6581                 }
    6582                 else
    6583                 {
    6584                         return null;
    6585                 }
    6586         }
    6587 
    6588         function get_description()
    6589         {
    6590                 if ($this->description !== null)
    6591                 {
    6592                         return $this->description;
    6593                 }
    6594                 else
    6595                 {
    6596                         return null;
    6597                 }
    6598         }
    6599 
    6600         function get_duration($convert = false)
    6601         {
    6602                 if ($this->duration !== null)
    6603                 {
    6604                         if ($convert)
    6605                         {
    6606                                 $time = SimplePie_Misc::time_hms($this->duration);
    6607                                 return $time;
    6608                         }
    6609                         else
    6610                         {
    6611                                 return $this->duration;
    6612                         }
    6613                 }
    6614                 else
    6615                 {
    6616                         return null;
    6617                 }
    6618         }
    6619 
    6620         function get_expression()
    6621         {
    6622                 if ($this->expression !== null)
    6623                 {
    6624                         return $this->expression;
    6625                 }
    6626                 else
    6627                 {
    6628                         return 'full';
    6629                 }
    6630         }
    6631 
    6632         function get_extension()
    6633         {
    6634                 if ($this->link !== null)
    6635                 {
    6636                         $url = SimplePie_Misc::parse_url($this->link);
    6637                         if ($url['path'] !== '')
    6638                         {
    6639                                 return pathinfo($url['path'], PATHINFO_EXTENSION);
    6640                         }
    6641                 }
    6642                 return null;
    6643         }
    6644 
    6645         function get_framerate()
    6646         {
    6647                 if ($this->framerate !== null)
    6648                 {
    6649                         return $this->framerate;
    6650                 }
    6651                 else
    6652                 {
    6653                         return null;
    6654                 }
    6655         }
    6656 
    6657         function get_handler()
    6658         {
    6659                 return $this->get_real_type(true);
    6660         }
    6661 
    6662         function get_hash($key = 0)
    6663         {
    6664                 $hashes = $this->get_hashes();
    6665                 if (isset($hashes[$key]))
    6666                 {
    6667                         return $hashes[$key];
    6668                 }
    6669                 else
    6670                 {
    6671                         return null;
    6672                 }
    6673         }
    6674 
    6675         function get_hashes()
    6676         {
    6677                 if ($this->hashes !== null)
    6678                 {
    6679                         return $this->hashes;
    6680                 }
    6681                 else
    6682                 {
    6683                         return null;
    6684                 }
    6685         }
    6686 
    6687         function get_height()
    6688         {
    6689                 if ($this->height !== null)
    6690                 {
    6691                         return $this->height;
    6692                 }
    6693                 else
    6694                 {
    6695                         return null;
    6696                 }
    6697         }
    6698 
    6699         function get_language()
    6700         {
    6701                 if ($this->lang !== null)
    6702                 {
    6703                         return $this->lang;
    6704                 }
    6705                 else
    6706                 {
    6707                         return null;
    6708                 }
    6709         }
    6710 
    6711         function get_keyword($key = 0)
    6712         {
    6713                 $keywords = $this->get_keywords();
    6714                 if (isset($keywords[$key]))
    6715                 {
    6716                         return $keywords[$key];
    6717                 }
    6718                 else
    6719                 {
    6720                         return null;
    6721                 }
    6722         }
    6723 
    6724         function get_keywords()
    6725         {
    6726                 if ($this->keywords !== null)
    6727                 {
    6728                         return $this->keywords;
    6729                 }
    6730                 else
    6731                 {
    6732                         return null;
    6733                 }
    6734         }
    6735 
    6736         function get_length()
    6737         {
    6738                 if ($this->length !== null)
    6739                 {
    6740                         return $this->length;
    6741                 }
    6742                 else
    6743                 {
    6744                         return null;
    6745                 }
    6746         }
    6747 
    6748         function get_link()
    6749         {
    6750                 if ($this->link !== null)
    6751                 {
    6752                         return urldecode($this->link);
    6753                 }
    6754                 else
    6755                 {
    6756                         return null;
    6757                 }
    6758         }
    6759 
    6760         function get_medium()
    6761         {
    6762                 if ($this->medium !== null)
    6763                 {
    6764                         return $this->medium;
    6765                 }
    6766                 else
    6767                 {
    6768                         return null;
    6769                 }
    6770         }
    6771 
    6772         function get_player()
    6773         {
    6774                 if ($this->player !== null)
    6775                 {
    6776                         return $this->player;
    6777                 }
    6778                 else
    6779                 {
    6780                         return null;
    6781                 }
    6782         }
    6783 
    6784         function get_rating($key = 0)
    6785         {
    6786                 $ratings = $this->get_ratings();
    6787                 if (isset($ratings[$key]))
    6788                 {
    6789                         return $ratings[$key];
    6790                 }
    6791                 else
    6792                 {
    6793                         return null;
    6794                 }
    6795         }
    6796 
    6797         function get_ratings()
    6798         {
    6799                 if ($this->ratings !== null)
    6800                 {
    6801                         return $this->ratings;
    6802                 }
    6803                 else
    6804                 {
    6805                         return null;
    6806                 }
    6807         }
    6808 
    6809         function get_restriction($key = 0)
    6810         {
    6811                 $restrictions = $this->get_restrictions();
    6812                 if (isset($restrictions[$key]))
    6813                 {
    6814                         return $restrictions[$key];
    6815                 }
    6816                 else
    6817                 {
    6818                         return null;
    6819                 }
    6820         }
    6821 
    6822         function get_restrictions()
    6823         {
    6824                 if ($this->restrictions !== null)
    6825                 {
    6826                         return $this->restrictions;
    6827                 }
    6828                 else
    6829                 {
    6830                         return null;
    6831                 }
    6832         }
    6833 
    6834         function get_sampling_rate()
    6835         {
    6836                 if ($this->samplingrate !== null)
    6837                 {
    6838                         return $this->samplingrate;
    6839                 }
    6840                 else
    6841                 {
    6842                         return null;
    6843                 }
    6844         }
    6845 
    6846         function get_size()
    6847         {
    6848                 $length = $this->get_length();
    6849                 if ($length !== null)
    6850                 {
    6851                         return round($length/1048576, 2);
    6852                 }
    6853                 else
    6854                 {
    6855                         return null;
    6856                 }
    6857         }
    6858 
    6859         function get_thumbnail($key = 0)
    6860         {
    6861                 $thumbnails = $this->get_thumbnails();
    6862                 if (isset($thumbnails[$key]))
    6863                 {
    6864                         return $thumbnails[$key];
    6865                 }
    6866                 else
    6867                 {
    6868                         return null;
    6869                 }
    6870         }
    6871 
    6872         function get_thumbnails()
    6873         {
    6874                 if ($this->thumbnails !== null)
    6875                 {
    6876                         return $this->thumbnails;
    6877                 }
    6878                 else
    6879                 {
    6880                         return null;
    6881                 }
    6882         }
    6883 
    6884         function get_title()
    6885         {
    6886                 if ($this->title !== null)
    6887                 {
    6888                         return $this->title;
    6889                 }
    6890                 else
    6891                 {
    6892                         return null;
    6893                 }
    6894         }
    6895 
    6896         function get_type()
    6897         {
    6898                 if ($this->type !== null)
    6899                 {
    6900                         return $this->type;
    6901                 }
    6902                 else
    6903                 {
    6904                         return null;
    6905                 }
    6906         }
    6907 
    6908         function get_width()
    6909         {
    6910                 if ($this->width !== null)
    6911                 {
    6912                         return $this->width;
    6913                 }
    6914                 else
    6915                 {
    6916                         return null;
    6917                 }
    6918         }
    6919 
    6920         function native_embed($options='')
    6921         {
    6922                 return $this->embed($options, true);
    6923         }
    6924 
    6925         /**
    6926          * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
    6927          */
    6928         function embed($options = '', $native = false)
    6929         {
    6930                 // Set up defaults
    6931                 $audio = '';
    6932                 $video = '';
    6933                 $alt = '';
    6934                 $altclass = '';
    6935                 $loop = 'false';
    6936                 $width = 'auto';
    6937                 $height = 'auto';
    6938                 $bgcolor = '#ffffff';
    6939                 $mediaplayer = '';
    6940                 $widescreen = false;
    6941                 $handler = $this->get_handler();
    6942                 $type = $this->get_real_type();
    6943 
    6944                 // Process options and reassign values as necessary
    6945                 if (is_array($options))
    6946                 {
    6947                         extract($options);
    6948                 }
    6949                 else
    6950                 {
    6951                         $options = explode(',', $options);
    6952                         foreach($options as $option)
    6953                         {
    6954                                 $opt = explode(':', $option, 2);
    6955                                 if (isset($opt[0], $opt[1]))
    6956                                 {
    6957                                         $opt[0] = trim($opt[0]);
    6958                                         $opt[1] = trim($opt[1]);
    6959                                         switch ($opt[0])
    6960                                         {
    6961                                                 case 'audio':
    6962                                                         $audio = $opt[1];
    6963                                                         break;
    6964 
    6965                                                 case 'video':
    6966                                                         $video = $opt[1];
    6967                                                         break;
    6968 
    6969                                                 case 'alt':
    6970                                                         $alt = $opt[1];
    6971                                                         break;
    6972 
    6973                                                 case 'altclass':
    6974                                                         $altclass = $opt[1];
    6975                                                         break;
    6976 
    6977                                                 case 'loop':
    6978                                                         $loop = $opt[1];
    6979                                                         break;
    6980 
    6981                                                 case 'width':
    6982                                                         $width = $opt[1];
    6983                                                         break;
    6984 
    6985                                                 case 'height':
    6986                                                         $height = $opt[1];
    6987                                                         break;
    6988 
    6989                                                 case 'bgcolor':
    6990                                                         $bgcolor = $opt[1];
    6991                                                         break;
    6992 
    6993                                                 case 'mediaplayer':
    6994                                                         $mediaplayer = $opt[1];
    6995                                                         break;
    6996 
    6997                                                 case 'widescreen':
    6998                                                         $widescreen = $opt[1];
    6999                                                         break;
    7000                                         }
    7001                                 }
    7002                         }
    7003                 }
    7004 
    7005                 $mime = explode('/', $type, 2);
    7006                 $mime = $mime[0];
    7007 
    7008                 // Process values for 'auto'
    7009                 if ($width === 'auto')
    7010                 {
    7011                         if ($mime === 'video')
    7012                         {
    7013                                 if ($height === 'auto')
    7014                                 {
    7015                                         $width = 480;
    7016                                 }
    7017                                 elseif ($widescreen)
    7018                                 {
    7019                                         $width = round((intval($height)/9)*16);
    7020                                 }
    7021                                 else
    7022                                 {
    7023                                         $width = round((intval($height)/3)*4);
    7024                                 }
    7025                         }
    7026                         else
    7027                         {
    7028                                 $width = '100%';
    7029                         }
    7030                 }
    7031 
    7032                 if ($height === 'auto')
    7033                 {
    7034                         if ($mime === 'audio')
    7035                         {
    7036                                 $height = 0;
    7037                         }
    7038                         elseif ($mime === 'video')
    7039                         {
    7040                                 if ($width === 'auto')
    7041                                 {
    7042                                         if ($widescreen)
    7043                                         {
    7044                                                 $height = 270;
    7045                                         }
    7046                                         else
    7047                                         {
    7048                                                 $height = 360;
    7049                                         }
    7050                                 }
    7051                                 elseif ($widescreen)
    7052                                 {
    7053                                         $height = round((intval($width)/16)*9);
    7054                                 }
    7055                                 else
    7056                                 {
    7057                                         $height = round((intval($width)/4)*3);
    7058                                 }
    7059                         }
    7060                         else
    7061                         {
    7062                                 $height = 376;
    7063                         }
    7064                 }
    7065                 elseif ($mime === 'audio')
    7066                 {
    7067                         $height = 0;
    7068                 }
    7069 
    7070                 // Set proper placeholder value
    7071                 if ($mime === 'audio')
    7072                 {
    7073                         $placeholder = $audio;
    7074                 }
    7075                 elseif ($mime === 'video')
    7076                 {
    7077                         $placeholder = $video;
    7078                 }
    7079 
    7080                 $embed = '';
    7081 
    7082                 // Make sure the JS library is included
    7083                 if (!$native)
    7084                 {
    7085                         static $javascript_outputted = null;
    7086                         if (!$javascript_outputted && $this->javascript)
    7087                         {
    7088                                 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
    7089                                 $javascript_outputted = true;
    7090                         }
    7091                 }
    7092 
    7093                 // Odeo Feed MP3's
    7094                 if ($handler === 'odeo')
    7095                 {
    7096                         if ($native)
    7097                         {
    7098                                 $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>';
    7099                         }
    7100                         else
    7101                         {
    7102                                 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
    7103                         }
    7104                 }
    7105 
    7106                 // Flash
    7107                 elseif ($handler === 'flash')
    7108                 {
    7109                         if ($native)
    7110                         {
    7111                                 $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>";
    7112                         }
    7113                         else
    7114                         {
    7115                                 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
    7116                         }
    7117                 }
    7118 
    7119                 // Flash Media Player file types.
    7120                 // Preferred handler for MP3 file types.
    7121                 elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
    7122                 {
    7123                         $height += 20;
    7124                         if ($native)
    7125                         {
    7126                                 $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>";
    7127                         }
    7128                         else
    7129                         {
    7130                                 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
    7131                         }
    7132                 }
    7133 
    7134                 // QuickTime 7 file types.  Need to test with QuickTime 6.
    7135                 // Only handle MP3's if the Flash Media Player is not present.
    7136                 elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
    7137                 {
    7138                         $height += 16;
    7139                         if ($native)
    7140                         {
    7141                                 if ($placeholder !== '')
    7142                                 {
    7143                                         $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>";
    7144                                 }
    7145                                 else
    7146                                 {
    7147                                         $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>";
    7148                                 }
    7149                         }
    7150                         else
    7151                         {
    7152                                 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
    7153                         }
    7154                 }
    7155 
    7156                 // Windows Media
    7157                 elseif ($handler === 'wmedia')
    7158                 {
    7159                         $height += 45;
    7160                         if ($native)
    7161                         {
    7162                                 $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>";
    7163                         }
    7164                         else
    7165                         {
    7166                                 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
    7167                         }
    7168                 }
    7169 
    7170                 // Everything else
    7171                 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
    7172 
    7173                 return $embed;
    7174         }
    7175 
    7176         function get_real_type($find_handler = false)
    7177         {
    7178                 // If it's Odeo, let's get it out of the way.
    7179                 if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
    7180                 {
    7181                         return 'odeo';
    7182                 }
    7183 
    7184                 // Mime-types by handler.
    7185                 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
    7186                 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
    7187                 $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
    7188                 $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
    7189                 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
    7190 
    7191                 if ($this->get_type() !== null)
    7192                 {
    7193                         $type = strtolower($this->type);
    7194                 }
    7195                 else
    7196                 {
    7197                         $type = null;
    7198                 }
    7199 
    7200                 // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
    7201                 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
    7202                 {
    7203                         switch (strtolower($this->get_extension()))
    7204                         {
    7205                                 // Audio mime-types
    7206                                 case 'aac':
    7207                                 case 'adts':
    7208                                         $type = 'audio/acc';
    7209                                         break;
    7210 
    7211                                 case 'aif':
    7212                                 case 'aifc':
    7213                                 case 'aiff':
    7214                                 case 'cdda':
    7215                                         $type = 'audio/aiff';
    7216                                         break;
    7217 
    7218                                 case 'bwf':
    7219                                         $type = 'audio/wav';
    7220                                         break;
    7221 
    7222                                 case 'kar':
    7223                                 case 'mid':
    7224                                 case 'midi':
    7225                                 case 'smf':
    7226                                         $type = 'audio/midi';
    7227                                         break;
    7228 
    7229                                 case 'm4a':
    7230                                         $type = 'audio/x-m4a';
    7231                                         break;
    7232 
    7233                                 case 'mp3':
    7234                                 case 'swa':
    7235                                         $type = 'audio/mp3';
    7236                                         break;
    7237 
    7238                                 case 'wav':
    7239                                         $type = 'audio/wav';
    7240                                         break;
    7241 
    7242                                 case 'wax':
    7243                                         $type = 'audio/x-ms-wax';
    7244                                         break;
    7245 
    7246                                 case 'wma':
    7247                                         $type = 'audio/x-ms-wma';
    7248                                         break;
    7249 
    7250                                 // Video mime-types
    7251                                 case '3gp':
    7252                                 case '3gpp':
    7253                                         $type = 'video/3gpp';
    7254                                         break;
    7255 
    7256                                 case '3g2':
    7257                                 case '3gp2':
    7258                                         $type = 'video/3gpp2';
    7259                                         break;
    7260 
    7261                                 case 'asf':
    7262                                         $type = 'video/x-ms-asf';
    7263                                         break;
    7264 
    7265                                 case 'flv':
    7266                                         $type = 'video/x-flv';
    7267                                         break;
    7268 
    7269                                 case 'm1a':
    7270                                 case 'm1s':
    7271                                 case 'm1v':
    7272                                 case 'm15':
    7273                                 case 'm75':
    7274                                 case 'mp2':
    7275                                 case 'mpa':
    7276                                 case 'mpeg':
    7277                                 case 'mpg':
    7278                                 case 'mpm':
    7279                                 case 'mpv':
    7280                                         $type = 'video/mpeg';
    7281                                         break;
    7282 
    7283                                 case 'm4v':
    7284                                         $type = 'video/x-m4v';
    7285                                         break;
    7286 
    7287                                 case 'mov':
    7288                                 case 'qt':
    7289                                         $type = 'video/quicktime';
    7290                                         break;
    7291 
    7292                                 case 'mp4':
    7293                                 case 'mpg4':
    7294                                         $type = 'video/mp4';
    7295                                         break;
    7296 
    7297                                 case 'sdv':
    7298                                         $type = 'video/sd-video';
    7299                                         break;
    7300 
    7301                                 case 'wm':
    7302                                         $type = 'video/x-ms-wm';
    7303                                         break;
    7304 
    7305                                 case 'wmv':
    7306                                         $type = 'video/x-ms-wmv';
    7307                                         break;
    7308 
    7309                                 case 'wvx':
    7310                                         $type = 'video/x-ms-wvx';
    7311                                         break;
    7312 
    7313                                 // Flash mime-types
    7314                                 case 'spl':
    7315                                         $type = 'application/futuresplash';
    7316                                         break;
    7317 
    7318                                 case 'swf':
    7319                                         $type = 'application/x-shockwave-flash';
    7320                                         break;
    7321                         }
    7322                 }
    7323 
    7324                 if ($find_handler)
    7325                 {
    7326                         if (in_array($type, $types_flash))
    7327                         {
    7328                                 return 'flash';
    7329                         }
    7330                         elseif (in_array($type, $types_fmedia))
    7331                         {
    7332                                 return 'fmedia';
    7333                         }
    7334                         elseif (in_array($type, $types_quicktime))
    7335                         {
    7336                                 return 'quicktime';
    7337                         }
    7338                         elseif (in_array($type, $types_wmedia))
    7339                         {
    7340                                 return 'wmedia';
    7341                         }
    7342                         elseif (in_array($type, $types_mp3))
    7343                         {
    7344                                 return 'mp3';
    7345                         }
    7346                         else
    7347                         {
    7348                                 return null;
    7349                         }
    7350                 }
    7351                 else
    7352                 {
    7353                         return $type;
    7354                 }
    7355         }
    7356 }
    7357 
    7358 class SimplePie_Caption
    7359 {
    7360         var $type;
    7361         var $lang;
    7362         var $startTime;
    7363         var $endTime;
    7364         var $text;
    7365 
    7366         // Constructor, used to input the data
    7367         function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
    7368         {
    7369                 $this->type = $type;
    7370                 $this->lang = $lang;
    7371                 $this->startTime = $startTime;
    7372                 $this->endTime = $endTime;
    7373                 $this->text = $text;
    7374         }
    7375 
    7376         function __toString()
    7377         {
    7378                 // There is no $this->data here
    7379                 return md5(serialize($this));
    7380         }
    7381 
    7382         function get_endtime()
    7383         {
    7384                 if ($this->endTime !== null)
    7385                 {
    7386                         return $this->endTime;
    7387                 }
    7388                 else
    7389                 {
    7390                         return null;
    7391                 }
    7392         }
    7393 
    7394         function get_language()
    7395         {
    7396                 if ($this->lang !== null)
    7397                 {
    7398                         return $this->lang;
    7399                 }
    7400                 else
    7401                 {
    7402                         return null;
    7403                 }
    7404         }
    7405 
    7406         function get_starttime()
    7407         {
    7408                 if ($this->startTime !== null)
    7409                 {
    7410                         return $this->startTime;
    7411                 }
    7412                 else
    7413                 {
    7414                         return null;
    7415                 }
    7416         }
    7417 
    7418         function get_text()
    7419         {
    7420                 if ($this->text !== null)
    7421                 {
    7422                         return $this->text;
    7423                 }
    7424                 else
    7425                 {
    7426                         return null;
    7427                 }
    7428         }
    7429 
    7430         function get_type()
    7431         {
    7432                 if ($this->type !== null)
    7433                 {
    7434                         return $this->type;
    7435                 }
    7436                 else
    7437                 {
    7438                         return null;
    7439                 }
    7440         }
    7441 }
    7442 
    7443 class SimplePie_Credit
    7444 {
    7445         var $role;
    7446         var $scheme;
    7447         var $name;
    7448 
    7449         // Constructor, used to input the data
    7450         function SimplePie_Credit($role = null, $scheme = null, $name = null)
    7451         {
    7452                 $this->role = $role;
    7453                 $this->scheme = $scheme;
    7454                 $this->name = $name;
    7455         }
    7456 
    7457         function __toString()
    7458         {
    7459                 // There is no $this->data here
    7460                 return md5(serialize($this));
    7461         }
    7462 
    7463         function get_role()
    7464         {
    7465                 if ($this->role !== null)
    7466                 {
    7467                         return $this->role;
    7468                 }
    7469                 else
    7470                 {
    7471                         return null;
    7472                 }
    7473         }
    7474 
    7475         function get_scheme()
    7476         {
    7477                 if ($this->scheme !== null)
    7478                 {
    7479                         return $this->scheme;
    7480                 }
    7481                 else
    7482                 {
    7483                         return null;
    7484                 }
    7485         }
    7486 
    7487         function get_name()
    7488         {
    7489                 if ($this->name !== null)
    7490                 {
    7491                         return $this->name;
    7492                 }
    7493                 else
    7494                 {
    7495                         return null;
    7496                 }
    7497         }
    7498 }
    7499 
    7500 class SimplePie_Copyright
    7501 {
    7502         var $url;
    7503         var $label;
    7504 
    7505         // Constructor, used to input the data
    7506         function SimplePie_Copyright($url = null, $label = null)
    7507         {
    7508                 $this->url = $url;
    7509                 $this->label = $label;
    7510         }
    7511 
    7512         function __toString()
    7513         {
    7514                 // There is no $this->data here
    7515                 return md5(serialize($this));
    7516         }
    7517 
    7518         function get_url()
    7519         {
    7520                 if ($this->url !== null)
    7521                 {
    7522                         return $this->url;
    7523                 }
    7524                 else
    7525                 {
    7526                         return null;
    7527                 }
    7528         }
    7529 
    7530         function get_attribution()
    7531         {
    7532                 if ($this->label !== null)
    7533                 {
    7534                         return $this->label;
    7535                 }
    7536                 else
    7537                 {
    7538                         return null;
    7539                 }
    7540         }
    7541 }
    7542 
    7543 class SimplePie_Rating
    7544 {
    7545         var $scheme;
    7546         var $value;
    7547 
    7548         // Constructor, used to input the data
    7549         function SimplePie_Rating($scheme = null, $value = null)
    7550         {
    7551                 $this->scheme = $scheme;
    7552                 $this->value = $value;
    7553         }
    7554 
    7555         function __toString()
    7556         {
    7557                 // There is no $this->data here
    7558                 return md5(serialize($this));
    7559         }
    7560 
    7561         function get_scheme()
    7562         {
    7563                 if ($this->scheme !== null)
    7564                 {
    7565                         return $this->scheme;
    7566                 }
    7567                 else
    7568                 {
    7569                         return null;
    7570                 }
    7571         }
    7572 
    7573         function get_value()
    7574         {
    7575                 if ($this->value !== null)
    7576                 {
    7577                         return $this->value;
    7578                 }
    7579                 else
    7580                 {
    7581                         return null;
    7582                 }
    7583         }
    7584 }
    7585 
    7586 class SimplePie_Restriction
    7587 {
    7588         var $relationship;
    7589         var $type;
    7590         var $value;
    7591 
    7592         // Constructor, used to input the data
    7593         function SimplePie_Restriction($relationship = null, $type = null, $value = null)
    7594         {
    7595                 $this->relationship = $relationship;
    7596                 $this->type = $type;
    7597                 $this->value = $value;
    7598         }
    7599 
    7600         function __toString()
    7601         {
    7602                 // There is no $this->data here
    7603                 return md5(serialize($this));
    7604         }
    7605 
    7606         function get_relationship()
    7607         {
    7608                 if ($this->relationship !== null)
    7609                 {
    7610                         return $this->relationship;
    7611                 }
    7612                 else
    7613                 {
    7614                         return null;
    7615                 }
    7616         }
    7617 
    7618         function get_type()
    7619         {
    7620                 if ($this->type !== null)
    7621                 {
    7622                         return $this->type;
    7623                 }
    7624                 else
    7625                 {
    7626                         return null;
    7627                 }
    7628         }
    7629 
    7630         function get_value()
    7631         {
    7632                 if ($this->value !== null)
    7633                 {
    7634                         return $this->value;
    7635                 }
    7636                 else
    7637                 {
    7638                         return null;
    7639                 }
    7640         }
    7641 }
    7642 
    7643 /**
    7644  * @todo Move to properly supporting RFC2616 (HTTP/1.1)
    7645  */
    7646 class SimplePie_File
    7647 {
    7648         var $url;
    7649         var $useragent;
    7650         var $success = true;
    7651         var $headers = array();
    7652         var $body;
    7653         var $status_code;
    7654         var $redirects = 0;
    7655         var $error;
    7656         var $method = SIMPLEPIE_FILE_SOURCE_NONE;
    7657 
    7658         function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
    7659         {
    7660                 if (class_exists('idna_convert'))
    7661                 {
    7662                         $idn =& new idna_convert;
    7663                         $parsed = SimplePie_Misc::parse_url($url);
    7664                         $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
    7665                 }
    7666                 $this->url = $url;
    7667                 $this->useragent = $useragent;
    7668                 if (preg_match('/^http(s)?:\/\//i', $url))
    7669                 {
    7670                         if ($useragent === null)
    7671                         {
    7672                                 $useragent = ini_get('user_agent');
    7673                                 $this->useragent = $useragent;
    7674                         }
    7675                         if (!is_array($headers))
    7676                         {
    7677                                 $headers = array();
    7678                         }
    7679                         if (!$force_fsockopen && function_exists('curl_exec'))
    7680                         {
    7681                                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
    7682                                 $fp = curl_init();
    7683                                 $headers2 = array();
    7684                                 foreach ($headers as $key => $value)
    7685                                 {
    7686                                         $headers2[] = "$key: $value";
    7687                                 }
    7688                                 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
    7689                                 {
    7690                                         curl_setopt($fp, CURLOPT_ENCODING, '');
    7691                                 }
    7692                                 curl_setopt($fp, CURLOPT_URL, $url);
    7693                                 curl_setopt($fp, CURLOPT_HEADER, 1);
    7694                                 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
    7695                                 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
    7696                                 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
    7697                                 curl_setopt($fp, CURLOPT_REFERER, $url);
    7698                                 curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
    7699                                 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
    7700                                 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
    7701                                 {
    7702                                         curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
    7703                                         curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
    7704                                 }
    7705 
    7706                                 $this->headers = curl_exec($fp);
    7707                                 if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
    7708                                 {
    7709                                         curl_setopt($fp, CURLOPT_ENCODING, 'none');
    7710                                         $this->headers = curl_exec($fp);
    7711                                 }
    7712                                 if (curl_errno($fp))
    7713                                 {
    7714                                         $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
    7715                                         $this->success = false;
    7716                                 }
    7717                                 else
    7718                                 {
    7719                                         $info = curl_getinfo($fp);
    7720                                         curl_close($fp);
    7721                                         $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
    7722                                         $this->headers = array_pop($this->headers);
    7723                                         $parser =& new SimplePie_HTTP_Parser($this->headers);
    7724                                         if ($parser->parse())
    7725                                         {
    7726                                                 $this->headers = $parser->headers;
    7727                                                 $this->body = $parser->body;
    7728                                                 $this->status_code = $parser->status_code;
    7729                                                 if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
    7730                                                 {
    7731                                                         $this->redirects++;
    7732                                                         $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
    7733                                                         return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
    7734                                                 }
    7735                                         }
    7736                                 }
    7737                         }
    7738                         else
    7739                         {
    7740                                 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
    7741                                 $url_parts = parse_url($url);
    7742                                 $socket_host = $url_parts['host'];
    7743                                 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
    7744                                 {
    7745                                         $socket_host = "ssl://$url_parts[host]";
    7746                                         $url_parts['port'] = 443;
    7747                                 }
    7748                                 if (!isset($url_parts['port']))
    7749                                 {
    7750                                         $url_parts['port'] = 80;
    7751                                 }
    7752                                 $fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);
    7753                                 if (!$fp)
    7754                                 {
    7755                                         $this->error = 'fsockopen error: ' . $errstr;
    7756                                         $this->success = false;
    7757                                 }
    7758                                 else
    7759                                 {
    7760                                         stream_set_timeout($fp, $timeout);
    7761                                         if (isset($url_parts['path']))
    7762                                         {
    7763                                                 if (isset($url_parts['query']))
    7764                                                 {
    7765                                                         $get = "$url_parts[path]?$url_parts[query]";
    7766                                                 }
    7767                                                 else
    7768                                                 {
    7769                                                         $get = $url_parts['path'];
    7770                                                 }
    7771                                         }
    7772                                         else
    7773                                         {
    7774                                                 $get = '/';
    7775                                         }
    7776                                         $out = "GET $get HTTP/1.0\r\n";
    7777                                         $out .= "Host: $url_parts[host]\r\n";
    7778                                         $out .= "User-Agent: $useragent\r\n";
    7779                                         if (extension_loaded('zlib'))
    7780                                         {
    7781                                                 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
    7782                                         }
    7783 
    7784                                         if (isset($url_parts['user']) && isset($url_parts['pass']))
    7785                                         {
    7786                                                 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
    7787                                         }
    7788                                         foreach ($headers as $key => $value)
    7789                                         {
    7790                                                 $out .= "$key: $value\r\n";
    7791                                         }
    7792                                         $out .= "Connection: Close\r\n\r\n";
    7793                                         fwrite($fp, $out);
    7794 
    7795                                         $info = stream_get_meta_data($fp);
    7796 
    7797                                         $this->headers = '';
    7798                                         while (!$info['eof'] && !$info['timed_out'])
    7799                                         {
    7800                                                 $this->headers .= fread($fp, 1160);
    7801                                                 $info = stream_get_meta_data($fp);
    7802                                         }
    7803                                         if (!$info['timed_out'])
    7804                                         {
    7805                                                 $parser =& new SimplePie_HTTP_Parser($this->headers);
    7806                                                 if ($parser->parse())
    7807                                                 {
    7808                                                         $this->headers = $parser->headers;
    7809                                                         $this->body = $parser->body;
    7810                                                         $this->status_code = $parser->status_code;
    7811                                                         if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
    7812                                                         {
    7813                                                                 $this->redirects++;
    7814                                                                 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
    7815                                                                 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
    7816                                                         }
    7817                                                         if (isset($this->headers['content-encoding']))
    7818                                                         {
    7819                                                                 // Hey, we act dumb elsewhere, so let's do that here too
    7820                                                                 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
    7821                                                                 {
    7822                                                                         case 'gzip':
    7823                                                                         case 'x-gzip':
    7824                                                                                 $decoder =& new SimplePie_gzdecode($this->body);
    7825                                                                                 if (!$decoder->parse())
    7826                                                                                 {
    7827                                                                                         $this->error = 'Unable to decode HTTP "gzip" stream';
    7828                                                                                         $this->success = false;
    7829                                                                                 }
    7830                                                                                 else
    7831                                                                                 {
    7832                                                                                         $this->body = $decoder->data;
    7833                                                                                 }
    7834                                                                                 break;
    7835 
    7836                                                                         case 'deflate':
    7837                                                                                 if (($body = gzuncompress($this->body)) === false)
    7838                                                                                 {
    7839                                                                                         if (($body = gzinflate($this->body)) === false)
    7840                                                                                         {
    7841                                                                                                 $this->error = 'Unable to decode HTTP "deflate" stream';
    7842                                                                                                 $this->success = false;
    7843                                                                                         }
    7844                                                                                 }
    7845                                                                                 $this->body = $body;
    7846                                                                                 break;
    7847 
    7848                                                                         default:
    7849                                                                                 $this->error = 'Unknown content coding';
    7850                                                                                 $this->success = false;
    7851                                                                 }
    7852                                                         }
    7853                                                 }
    7854                                         }
    7855                                         else
    7856                                         {
    7857                                                 $this->error = 'fsocket timed out';
    7858                                                 $this->success = false;
    7859                                         }
    7860                                         fclose($fp);
    7861                                 }
    7862                         }
    7863                 }
    7864                 else
    7865                 {
    7866                         $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
    7867                         if (!$this->body = file_get_contents($url))
    7868                         {
    7869                                 $this->error = 'file_get_contents could not read the file';
    7870                                 $this->success = false;
    7871                         }
    7872                 }
    7873         }
    7874 }
    7875 
    7876 /**
    7877  * HTTP Response Parser
    7878  *
    7879  * @package SimplePie
    7880  */
    7881 class SimplePie_HTTP_Parser
    7882 {
    7883         /**
    7884          * HTTP Version
    7885          *
    7886          * @access public
    7887          * @var float
    7888          */
    7889         var $http_version = 0.0;
    7890 
    7891         /**
    7892          * Status code
    7893          *
    7894          * @access public
    7895          * @var int
    7896          */
    7897         var $status_code = 0;
    7898 
    7899         /**
    7900          * Reason phrase
    7901          *
    7902          * @access public
    7903          * @var string
    7904          */
    7905         var $reason = '';
    7906 
    7907         /**
    7908          * Key/value pairs of the headers
    7909          *
    7910          * @access public
    7911          * @var array
    7912          */
    7913         var $headers = array();
    7914 
    7915         /**
    7916          * Body of the response
    7917          *
    7918          * @access public
    7919          * @var string
    7920          */
    7921         var $body = '';
    7922 
    7923         /**
    7924          * Current state of the state machine
    7925          *
    7926          * @access private
    7927          * @var string
    7928          */
    7929         var $state = 'http_version';
    7930 
    7931         /**
    7932          * Input data
    7933          *
    7934          * @access private
    7935          * @var string
    7936          */
    7937         var $data = '';
    7938 
    7939         /**
    7940          * Input data length (to avoid calling strlen() everytime this is needed)
    7941          *
    7942          * @access private
    7943          * @var int
    7944          */
    7945         var $data_length = 0;
    7946 
    7947         /**
    7948          * Current position of the pointer
    7949          *
    7950          * @var int
    7951          * @access private
    7952          */
    7953         var $position = 0;
    7954 
    7955         /**
    7956          * Name of the hedaer currently being parsed
    7957          *
    7958          * @access private
    7959          * @var string
    7960          */
    7961         var $name = '';
    7962 
    7963         /**
    7964          * Value of the hedaer currently being parsed
    7965          *
    7966          * @access private
    7967          * @var string
    7968          */
    7969         var $value = '';
    7970 
    7971         /**
    7972          * Create an instance of the class with the input data
    7973          *
    7974          * @access public
    7975          * @param string $data Input data
    7976          */
    7977         function SimplePie_HTTP_Parser($data)
    7978         {
    7979                 $this->data = $data;
    7980                 $this->data_length = strlen($this->data);
    7981         }
    7982 
    7983         /**
    7984          * Parse the input data
    7985          *
    7986          * @access public
    7987          * @return bool true on success, false on failure
    7988          */
    7989         function parse()
    7990         {
    7991                 while ($this->state && $this->state !== 'emit' && $this->has_data())
    7992                 {
    7993                         $state = $this->state;
    7994                         $this->$state();
    7995                 }
    7996                 $this->data = '';
    7997                 if ($this->state === 'emit' || $this->state === 'body')
    7998                 {
    7999                         return true;
    8000                 }
    8001                 else
    8002                 {
    8003                         $this->http_version = '';
    8004                         $this->status_code = '';
    8005                         $this->reason = '';
    8006                         $this->headers = array();
    8007                         $this->body = '';
    8008                         return false;
    8009                 }
    8010         }
    8011 
    8012         /**
    8013          * Check whether there is data beyond the pointer
    8014          *
    8015          * @access private
    8016          * @return bool true if there is further data, false if not
    8017          */
    8018         function has_data()
    8019         {
    8020                 return (bool) ($this->position < $this->data_length);
    8021         }
    8022 
    8023         /**
    8024          * See if the next character is LWS
    8025          *
    8026          * @access private
    8027          * @return bool true if the next character is LWS, false if not
    8028          */
    8029         function is_linear_whitespace()
    8030         {
    8031                 return (bool) ($this->data[$this->position] === "\x09"
    8032                         || $this->data[$this->position] === "\x20"
    8033                         || ($this->data[$this->position] === "\x0A"
    8034                                 && isset($this->data[$this->position + 1])
    8035                                 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
    8036         }
    8037 
    8038         /**
    8039          * Parse the HTTP version
    8040          *
    8041          * @access private
    8042          */
    8043         function http_version()
    8044         {
    8045                 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
    8046                 {
    8047                         $len = strspn($this->data, '0123456789.', 5);
    8048                         $this->http_version = substr($this->data, 5, $len);
    8049                         $this->position += 5 + $len;
    8050                         if (substr_count($this->http_version, '.') <= 1)
    8051                         {
    8052                                 $this->http_version = (float) $this->http_version;
    8053                                 $this->position += strspn($this->data, "\x09\x20", $this->position);
    8054                                 $this->state = 'status';
    8055                         }
    8056                         else
    8057                         {
    8058                                 $this->state = false;
    8059                         }
    8060                 }
    8061                 else
    8062                 {
    8063                         $this->state = false;
    8064                 }
    8065         }
    8066 
    8067         /**
    8068          * Parse the status code
    8069          *
    8070          * @access private
    8071          */
    8072         function status()
    8073         {
    8074                 if ($len = strspn($this->data, '0123456789', $this->position))
    8075                 {
    8076                         $this->status_code = (int) substr($this->data, $this->position, $len);
    8077                         $this->position += $len;
    8078                         $this->state = 'reason';
    8079                 }
    8080                 else
    8081                 {
    8082                         $this->state = false;
    8083                 }
    8084         }
    8085 
    8086         /**
    8087          * Parse the reason phrase
    8088          *
    8089          * @access private
    8090          */
    8091         function reason()
    8092         {
    8093                 $len = strcspn($this->data, "\x0A", $this->position);
    8094                 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
    8095                 $this->position += $len + 1;
    8096                 $this->state = 'new_line';
    8097         }
    8098 
    8099         /**
    8100          * Deal with a new line, shifting data around as needed
    8101          *
    8102          * @access private
    8103          */
    8104         function new_line()
    8105         {
    8106                 $this->value = trim($this->value, "\x0D\x20");
    8107                 if ($this->name !== '' && $this->value !== '')
    8108                 {
    8109                         $this->name = strtolower($this->name);
    8110                         if (isset($this->headers[$this->name]))
    8111                         {
    8112                                 $this->headers[$this->name] .= ', ' . $this->value;
    8113                         }
    8114                         else
    8115                         {
    8116                                 $this->headers[$this->name] = $this->value;
    8117                         }
    8118                 }
    8119                 $this->name = '';
    8120                 $this->value = '';
    8121                 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
    8122                 {
    8123                         $this->position += 2;
    8124                         $this->state = 'body';
    8125                 }
    8126                 elseif ($this->data[$this->position] === "\x0A")
    8127                 {
    8128                         $this->position++;
    8129                         $this->state = 'body';
    8130                 }
    8131                 else
    8132                 {
    8133                         $this->state = 'name';
    8134                 }
    8135         }
    8136 
    8137         /**
    8138          * Parse a header name
    8139          *
    8140          * @access private
    8141          */
    8142         function name()
    8143         {
    8144                 $len = strcspn($this->data, "\x0A:", $this->position);
    8145                 if (isset($this->data[$this->position + $len]))
    8146                 {
    8147                         if ($this->data[$this->position + $len] === "\x0A")
    8148                         {
    8149                                 $this->position += $len;
    8150                                 $this->state = 'new_line';
    8151                         }
    8152                         else
    8153                         {
    8154                                 $this->name = substr($this->data, $this->position, $len);
    8155                                 $this->position += $len + 1;
    8156                                 $this->state = 'value';
    8157                         }
    8158                 }
    8159                 else
    8160                 {
    8161                         $this->state = false;
    8162                 }
    8163         }
    8164 
    8165         /**
    8166          * Parse LWS, replacing consecutive LWS characters with a single space
    8167          *
    8168          * @access private
    8169          */
    8170         function linear_whitespace()
    8171         {
    8172                 do
    8173                 {
    8174                         if (substr($this->data, $this->position, 2) === "\x0D\x0A")
    8175                         {
    8176                                 $this->position += 2;
    8177                         }
    8178                         elseif ($this->data[$this->position] === "\x0A")
    8179                         {
    8180                                 $this->position++;
    8181                         }
    8182                         $this->position += strspn($this->data, "\x09\x20", $this->position);
    8183                 } while ($this->has_data() && $this->is_linear_whitespace());
    8184                 $this->value .= "\x20";
    8185         }
    8186 
    8187         /**
    8188          * See what state to move to while within non-quoted header values
    8189          *
    8190          * @access private
    8191          */
    8192         function value()
    8193         {
    8194                 if ($this->is_linear_whitespace())
    8195                 {
    8196                         $this->linear_whitespace();
    8197                 }
    8198                 else
    8199                 {
    8200                         switch ($this->data[$this->position])
    8201                         {
    8202                                 case '"':
    8203                                         $this->position++;
    8204                                         $this->state = 'quote';
    8205                                         break;
    8206 
    8207                                 case "\x0A":
    8208                                         $this->position++;
    8209                                         $this->state = 'new_line';
    8210                                         break;
    8211 
    8212                                 default:
    8213                                         $this->state = 'value_char';
    8214                                         break;
    8215                         }
    8216                 }
    8217         }
    8218 
    8219         /**
    8220          * Parse a header value while outside quotes
    8221          *
    8222          * @access private
    8223          */
    8224         function value_char()
    8225         {
    8226                 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
    8227                 $this->value .= substr($this->data, $this->position, $len);
    8228                 $this->position += $len;
    8229                 $this->state = 'value';
    8230         }
    8231 
    8232         /**
    8233          * See what state to move to while within quoted header values
    8234          *
    8235          * @access private
    8236          */
    8237         function quote()
    8238         {
    8239                 if ($this->is_linear_whitespace())
    8240                 {
    8241                         $this->linear_whitespace();
    8242                 }
    8243                 else
    8244                 {
    8245                         switch ($this->data[$this->position])
    8246                         {
    8247                                 case '"':
    8248                                         $this->position++;
    8249                                         $this->state = 'value';
    8250                                         break;
    8251 
    8252                                 case "\x0A":
    8253                                         $this->position++;
    8254                                         $this->state = 'new_line';
    8255                                         break;
    8256 
    8257                                 case '\\':
    8258                                         $this->position++;
    8259                                         $this->state = 'quote_escaped';
    8260                                         break;
    8261 
    8262                                 default:
    8263                                         $this->state = 'quote_char';
    8264                                         break;
    8265                         }
    8266                 }
    8267         }
    8268 
    8269         /**
    8270          * Parse a header value while within quotes
    8271          *
    8272          * @access private
    8273          */
    8274         function quote_char()
    8275         {
    8276                 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
    8277                 $this->value .= substr($this->data, $this->position, $len);
    8278                 $this->position += $len;
    8279                 $this->state = 'value';
    8280         }
    8281 
    8282         /**
    8283          * Parse an escaped character within quotes
    8284          *
    8285          * @access private
    8286          */
    8287         function quote_escaped()
    8288         {
    8289                 $this->value .= $this->data[$this->position];
    8290                 $this->position++;
    8291                 $this->state = 'quote';
    8292         }
    8293 
    8294         /**
    8295          * Parse the body
    8296          *
    8297          * @access private
    8298          */
    8299         function body()
    8300         {
    8301                 $this->body = substr($this->data, $this->position);
    8302                 $this->state = 'emit';
    8303         }
    8304 }
    8305 
    8306 /**
    8307  * gzdecode
    8308  *
    8309  * @package SimplePie
    8310  */
    8311 class SimplePie_gzdecode
    8312 {
    8313         /**
    8314          * Compressed data
    8315          *
    8316          * @access private
    8317          * @see gzdecode::$data
    8318          */
    8319         var $compressed_data;
    8320 
    8321         /**
    8322          * Size of compressed data
    8323          *
    8324          * @access private
    8325          */
    8326         var $compressed_size;
    8327 
    8328         /**
    8329          * Minimum size of a valid gzip string
    8330          *
    8331          * @access private
    8332          */
    8333         var $min_compressed_size = 18;
    8334 
    8335         /**
    8336          * Current position of pointer
    8337          *
    8338          * @access private
    8339          */
    8340         var $position = 0;
    8341 
    8342         /**
    8343          * Flags (FLG)
    8344          *
    8345          * @access private
    8346          */
    8347         var $flags;
    8348 
    8349         /**
    8350          * Uncompressed data
    8351          *
    8352          * @access public
    8353          * @see gzdecode::$compressed_data
    8354          */
    8355         var $data;
    8356 
    8357         /**
    8358          * Modified time
    8359          *
    8360          * @access public
    8361          */
    8362         var $MTIME;
    8363 
    8364         /**
    8365          * Extra Flags
    8366          *
    8367          * @access public
    8368          */
    8369         var $XFL;
    8370 
    8371         /**
    8372          * Operating System
    8373          *
    8374          * @access public
    8375          */
    8376         var $OS;
    8377 
    8378         /**
    8379          * Subfield ID 1
    8380          *
    8381          * @access public
    8382          * @see gzdecode::$extra_field
    8383          * @see gzdecode::$SI2
    8384          */
    8385         var $SI1;
    8386 
    8387         /**
    8388          * Subfield ID 2
    8389          *
    8390          * @access public
    8391          * @see gzdecode::$extra_field
    8392          * @see gzdecode::$SI1
    8393          */
    8394         var $SI2;
    8395 
    8396         /**
    8397          * Extra field content
    8398          *
    8399          * @access public
    8400          * @see gzdecode::$SI1
    8401          * @see gzdecode::$SI2
    8402          */
    8403         var $extra_field;
    8404 
    8405         /**
    8406          * Original filename
    8407          *
    8408          * @access public
    8409          */
    8410         var $filename;
    8411 
    8412         /**
    8413          * Human readable comment
    8414          *
    8415          * @access public
    8416          */
    8417         var $comment;
    8418 
    8419         /**
    8420          * Don't allow anything to be set
    8421          *
    8422          * @access public
    8423          */
    8424         function __set($name, $value)
    8425         {
    8426                 trigger_error("Cannot write property $name", E_USER_ERROR);
    8427         }
    8428 
    8429         /**
    8430          * Set the compressed string and related properties
    8431          *
    8432          * @access public
    8433          */
    8434         function SimplePie_gzdecode($data)
    8435         {
    8436                 $this->compressed_data = $data;
    8437                 $this->compressed_size = strlen($data);
    8438         }
    8439 
    8440         /**
    8441          * Decode the GZIP stream
    8442          *
    8443          * @access public
    8444          */
    8445         function parse()
    8446         {
    8447                 if ($this->compressed_size >= $this->min_compressed_size)
    8448                 {
    8449                         // Check ID1, ID2, and CM
    8450                         if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
    8451                         {
    8452                                 return false;
    8453                         }
    8454 
    8455                         // Get the FLG (FLaGs)
    8456                         $this->flags = ord($this->compressed_data[3]);
    8457 
    8458                         // FLG bits above (1 << 4) are reserved
    8459                         if ($this->flags > 0x1F)
    8460                         {
    8461                                 return false;
    8462                         }
    8463 
    8464                         // Advance the pointer after the above
    8465                         $this->position += 4;
    8466 
    8467                         // MTIME
    8468                         $mtime = substr($this->compressed_data, $this->position, 4);
    8469                         // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
    8470                         if (current(unpack('S', "\x00\x01")) === 1)
    8471                         {
    8472                                 $mtime = strrev($mtime);
    8473                         }
    8474                         $this->MTIME = current(unpack('l', $mtime));
    8475                         $this->position += 4;
    8476 
    8477                         // Get the XFL (eXtra FLags)
    8478                         $this->XFL = ord($this->compressed_data[$this->position++]);
    8479 
    8480                         // Get the OS (Operating System)
    8481                         $this->OS = ord($this->compressed_data[$this->position++]);
    8482 
    8483                         // Parse the FEXTRA
    8484                         if ($this->flags & 4)
    8485                         {
    8486                                 // Read subfield IDs
    8487                                 $this->SI1 = $this->compressed_data[$this->position++];
    8488                                 $this->SI2 = $this->compressed_data[$this->position++];
    8489 
    8490                                 // SI2 set to zero is reserved for future use
    8491                                 if ($this->SI2 === "\x00")
    8492                                 {
    8493                                         return false;
    8494                                 }
    8495 
    8496                                 // Get the length of the extra field
    8497                                 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
    8498                                 $this->position += 2;
    8499 
    8500                                 // Check the length of the string is still valid
    8501                                 $this->min_compressed_size += $len + 4;
    8502                                 if ($this->compressed_size >= $this->min_compressed_size)
    8503                                 {
    8504                                         // Set the extra field to the given data
    8505                                         $this->extra_field = substr($this->compressed_data, $this->position, $len);
    8506                                         $this->position += $len;
    8507                                 }
    8508                                 else
    8509                                 {
    8510                                         return false;
    8511                                 }
    8512                         }
    8513 
    8514                         // Parse the FNAME
    8515                         if ($this->flags & 8)
    8516                         {
    8517                                 // Get the length of the filename
    8518                                 $len = strcspn($this->compressed_data, "\x00", $this->position);
    8519 
    8520                                 // Check the length of the string is still valid
    8521                                 $this->min_compressed_size += $len + 1;
    8522                                 if ($this->compressed_size >= $this->min_compressed_size)
    8523                                 {
    8524                                         // Set the original filename to the given string
    8525                                         $this->filename = substr($this->compressed_data, $this->position, $len);
    8526                                         $this->position += $len + 1;
    8527                                 }
    8528                                 else
    8529                                 {
    8530                                         return false;
    8531                                 }
    8532                         }
    8533 
    8534                         // Parse the FCOMMENT
    8535                         if ($this->flags & 16)
    8536                         {
    8537                                 // Get the length of the comment
    8538                                 $len = strcspn($this->compressed_data, "\x00", $this->position);
    8539 
    8540                                 // Check the length of the string is still valid
    8541                                 $this->min_compressed_size += $len + 1;
    8542                                 if ($this->compressed_size >= $this->min_compressed_size)
    8543                                 {
    8544                                         // Set the original comment to the given string
    8545                                         $this->comment = substr($this->compressed_data, $this->position, $len);
    8546                                         $this->position += $len + 1;
    8547                                 }
    8548                                 else
    8549                                 {
    8550                                         return false;
    8551                                 }
    8552                         }
    8553 
    8554                         // Parse the FHCRC
    8555                         if ($this->flags & 2)
    8556                         {
    8557                                 // Check the length of the string is still valid
    8558                                 $this->min_compressed_size += $len + 2;
    8559                                 if ($this->compressed_size >= $this->min_compressed_size)
    8560                                 {
    8561                                         // Read the CRC
    8562                                         $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
    8563 
    8564                                         // Check the CRC matches
    8565                                         if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
    8566                                         {
    8567                                                 $this->position += 2;
    8568                                         }
    8569                                         else
    8570                                         {
    8571                                                 return false;
    8572                                         }
    8573                                 }
    8574                                 else
    8575                                 {
    8576                                         return false;
    8577                                 }
    8578                         }
    8579 
    8580                         // Decompress the actual data
    8581                         if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
    8582                         {
    8583                                 return false;
    8584                         }
    8585                         else
    8586                         {
    8587                                 $this->position = $this->compressed_size - 8;
    8588                         }
    8589 
    8590                         // Check CRC of data
    8591                         $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
    8592                         $this->position += 4;
    8593                         /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
    8594                         {
    8595                                 return false;
    8596                         }*/
    8597 
    8598                         // Check ISIZE of data
    8599                         $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
    8600                         $this->position += 4;
    8601                         if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
    8602                         {
    8603                                 return false;
    8604                         }
    8605 
    8606                         // Wow, against all odds, we've actually got a valid gzip string
    8607                         return true;
    8608                 }
    8609                 else
    8610                 {
    8611                         return false;
    8612                 }
    8613         }
    8614 }
    8615 
    8616 class SimplePie_Cache
    8617 {
    8618         /**
    8619          * Don't call the constructor. Please.
    8620          *
    8621          * @access private
    8622          */
    8623         function SimplePie_Cache()
    8624         {
    8625                 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
    8626         }
    8627 
    8628         /**
    8629          * Create a new SimplePie_Cache object
    8630          *
    8631          * @static
    8632          * @access public
    8633          */
    8634         function create($location, $filename, $extension)
    8635         {
    8636                 $location_iri =& new SimplePie_IRI($location);
    8637                 switch ($location_iri->get_scheme())
    8638                 {
    8639                         case 'mysql':
    8640                                 if (extension_loaded('mysql'))
    8641                                 {
    8642                                         return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
    8643                                 }
    8644                                 break;
    8645 
    8646                         default:
    8647                                 return new SimplePie_Cache_File($location, $filename, $extension);
    8648                 }
    8649         }
    8650 }
    8651 
    8652 class SimplePie_Cache_File
    8653 {
    8654         var $location;
    8655         var $filename;
    8656         var $extension;
    8657         var $name;
    8658 
    8659         function SimplePie_Cache_File($location, $filename, $extension)
    8660         {
    8661                 $this->location = $location;
    8662                 $this->filename = $filename;
    8663                 $this->extension = $extension;
    8664                 $this->name = "$this->location/$this->filename.$this->extension";
    8665         }
    8666 
    8667         function save($data)
    8668         {
    8669                 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
    8670                 {
    8671                         if (is_a($data, 'SimplePie'))
    8672                         {
    8673                                 $data = $data->data;
    8674                         }
    8675 
    8676                         $data = serialize($data);
    8677 
    8678                         if (function_exists('file_put_contents'))
    8679                         {
    8680                                 return (bool) file_put_contents($this->name, $data);
    8681                         }
    8682                         else
    8683                         {
    8684                                 $fp = fopen($this->name, 'wb');
    8685                                 if ($fp)
    8686                                 {
    8687                                         fwrite($fp, $data);
    8688                                         fclose($fp);
    8689                                         return true;
    8690                                 }
    8691                         }
    8692                 }
    8693                 return false;
    8694         }
    8695 
    8696         function load()
    8697         {
    8698                 if (file_exists($this->name) && is_readable($this->name))
    8699                 {
    8700                         return unserialize(file_get_contents($this->name));
    8701                 }
    8702                 return false;
    8703         }
    8704 
    8705         function mtime()
    8706         {
    8707                 if (file_exists($this->name))
    8708                 {
    8709                         return filemtime($this->name);
    8710                 }
    8711                 return false;
    8712         }
    8713 
    8714         function touch()
    8715         {
    8716                 if (file_exists($this->name))
    8717                 {
    8718                         return touch($this->name);
    8719                 }
    8720                 return false;
    8721         }
    8722 
    8723         function unlink()
    8724         {
    8725                 if (file_exists($this->name))
    8726                 {
    8727                         return unlink($this->name);
    8728                 }
    8729                 return false;
    8730         }
    8731 }
    8732 
    8733 class SimplePie_Cache_DB
    8734 {
    8735         function prepare_simplepie_object_for_cache($data)
    8736         {
    8737                 $items = $data->get_items();
    8738                 $items_by_id = array();
    8739 
    8740                 if (!empty($items))
    8741                 {
    8742                         foreach ($items as $item)
    8743                         {
    8744                                 $items_by_id[$item->get_id()] = $item;
    8745                         }
    8746 
    8747                         if (count($items_by_id) !== count($items))
    8748                         {
    8749                                 $items_by_id = array();
    8750                                 foreach ($items as $item)
    8751                                 {
    8752                                         $items_by_id[$item->get_id(true)] = $item;
    8753                                 }
    8754                         }
    8755 
    8756                         if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
    8757                         {
    8758                                 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
    8759                         }
    8760                         elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
    8761                         {
    8762                                 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
    8763                         }
    8764                         elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
    8765                         {
    8766                                 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
    8767                         }
    8768                         elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
    8769                         {
    8770                                 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
    8771                         }
    8772                         else
    8773                         {
    8774                                 $channel = null;
    8775                         }
    8776 
    8777                         if ($channel !== null)
    8778                         {
    8779                                 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
    8780                                 {
    8781                                         unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
    8782                                 }
    8783                                 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
    8784                                 {
    8785                                         unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
    8786                                 }
    8787                                 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
    8788                                 {
    8789                                         unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
    8790                                 }
    8791                                 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
    8792                                 {
    8793                                         unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
    8794                                 }
    8795                                 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
    8796                                 {
    8797                                         unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
    8798                                 }
    8799                         }
    8800                         if (isset($data->data['items']))
    8801                         {
    8802                                 unset($data->data['items']);
    8803                         }
    8804                         if (isset($data->data['ordered_items']))
    8805                         {
    8806                                 unset($data->data['ordered_items']);
    8807                         }
    8808                 }
    8809                 return array(serialize($data->data), $items_by_id);
    8810         }
    8811 }
    8812 
    8813 class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
    8814 {
    8815         var $mysql;
    8816         var $options;
    8817         var $id;
    8818 
    8819         function SimplePie_Cache_MySQL($mysql_location, $name, $extension)
    8820         {
    8821                 $host = $mysql_location->get_host();
    8822                 if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
    8823                 {
    8824                         $server = ':' . substr($host, 5, -1);
    8825                 }
    8826                 else
    8827                 {
    8828                         $server = $host;
    8829                         if ($mysql_location->get_port() !== null)
    8830                         {
    8831                                 $server .= ':' . $mysql_location->get_port();
    8832                         }
    8833                 }
    8834 
    8835                 if (strpos($mysql_location->get_userinfo(), ':') !== false)
    8836                 {
    8837                         list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
    8838                 }
    8839                 else
    8840                 {
    8841                         $username = $mysql_location->get_userinfo();
    8842                         $password = null;
    8843                 }
    8844 
    8845                 if ($this->mysql = mysql_connect($server, $username, $password))
    8846                 {
    8847                         $this->id = $name . $extension;
    8848                         $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());
    8849                         if (!isset($this->options['prefix'][0]))
    8850                         {
    8851                                 $this->options['prefix'][0] = '';
    8852                         }
    8853 
    8854                         if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
    8855                                 && mysql_query('SET NAMES utf8')
    8856                                 && ($query = mysql_unbuffered_query('SHOW TABLES')))
    8857                         {
    8858                                 $db = array();
    8859                                 while ($row = mysql_fetch_row($query))
    8860                                 {
    8861                                         $db[] = $row[0];
    8862                                 }
    8863 
    8864                                 if (!in_array($this->options['prefix'][0] . 'cache_data', $db))
    8865                                 {
    8866                                         if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))'))
    8867                                         {
    8868                                                 $this->mysql = null;
    8869                                         }
    8870                                 }
    8871 
    8872                                 if (!in_array($this->options['prefix'][0] . 'items', $db))
    8873                                 {
    8874                                         if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'))
    8875                                         {
    8876                                                 $this->mysql = null;
    8877                                         }
    8878                                 }
    8879                         }
    8880                         else
    8881                         {
    8882                                 $this->mysql = null;
    8883                         }
    8884                 }
    8885         }
    8886 
    8887         function save($data)
    8888         {
    8889                 if ($this->mysql)
    8890                 {
    8891                         $feed_id = "'" . mysql_real_escape_string($this->id) . "'";
    8892 
    8893                         if (is_a($data, 'SimplePie'))
    8894                         {
    8895                                 if (SIMPLEPIE_PHP5)
    8896                                 {
    8897                                         // This keyword needs to defy coding standards for PHP4 compatibility
    8898                                         $data = clone($data);
    8899                                 }
    8900 
    8901                                 $prepared = $this->prepare_simplepie_object_for_cache($data);
    8902 
    8903                                 if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
    8904                                 {
    8905                                         if (mysql_num_rows($query))
    8906                                         {
    8907                                                 $items = count($prepared[1]);
    8908                                                 if ($items)
    8909                                                 {
    8910                                                         $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
    8911                                                 }
    8912                                                 else
    8913                                                 {
    8914                                                         $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
    8915                                                 }
    8916 
    8917                                                 if (!mysql_query($sql, $this->mysql))
    8918                                                 {
    8919                                                         return false;
    8920                                                 }
    8921                                         }
    8922                                         elseif (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql))
    8923                                         {
    8924                                                 return false;
    8925                                         }
    8926 
    8927                                         $ids = array_keys($prepared[1]);
    8928                                         if (!empty($ids))
    8929                                         {
    8930                                                 foreach ($ids as $id)
    8931                                                 {
    8932                                                         $database_ids[] = mysql_real_escape_string($id);
    8933                                                 }
    8934 
    8935                                                 if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql))
    8936                                                 {
    8937                                                         $existing_ids = array();
    8938                                                         while ($row = mysql_fetch_row($query))
    8939                                                         {
    8940                                                                 $existing_ids[] = $row[0];
    8941                                                         }
    8942 
    8943                                                         $new_ids = array_diff($ids, $existing_ids);
    8944 
    8945                                                         foreach ($new_ids as $new_id)
    8946                                                         {
    8947                                                                 if (!($date = $prepared[1][$new_id]->get_date('U')))
    8948                                                                 {
    8949                                                                         $date = time();
    8950                                                                 }
    8951 
    8952                                                                 if (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data)) . '\', ' . $date . ')', $this->mysql))
    8953                                                                 {
    8954                                                                         return false;
    8955                                                                 }
    8956                                                         }
    8957                                                         return true;
    8958                                                 }
    8959                                         }
    8960                                         else
    8961                                         {
    8962                                                 return true;
    8963                                         }
    8964                                 }
    8965                         }
    8966                         elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
    8967                         {
    8968                                 if (mysql_num_rows($query))
    8969                                 {
    8970                                         if (mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql))
    8971                                         {
    8972                                                 return true;
    8973                                         }
    8974                                 }
    8975                                 elseif (mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql))
    8976                                 {
    8977                                         return true;
    8978                                 }
    8979                         }
    8980                 }
    8981                 return false;
    8982         }
    8983 
    8984         function load()
    8985         {
    8986                 if ($this->mysql && ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
    8987                 {
    8988                         $data = unserialize($row[1]);
    8989 
    8990                         if (isset($this->options['items'][0]))
    8991                         {
    8992                                 $items = (int) $this->options['items'][0];
    8993                         }
    8994                         else
    8995                         {
    8996                                 $items = (int) $row[0];
    8997                         }
    8998 
    8999                         if ($items !== 0)
    9000                         {
    9001                                 if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
    9002                                 {
    9003                                         $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
    9004                                 }
    9005                                 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
    9006                                 {
    9007                                         $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
    9008                                 }
    9009                                 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
    9010                                 {
    9011                                         $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
    9012                                 }
    9013                                 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
    9014                                 {
    9015                                         $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
    9016                                 }
    9017                                 else
    9018                                 {
    9019                                         $feed = null;
    9020                                 }
    9021 
    9022                                 if ($feed !== null)
    9023                                 {
    9024                                         $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';
    9025                                         if ($items > 0)
    9026                                         {
    9027                                                 $sql .= ' LIMIT ' . $items;
    9028                                         }
    9029 
    9030                                         if ($query = mysql_unbuffered_query($sql, $this->mysql))
    9031                                         {
    9032                                                 while ($row = mysql_fetch_row($query))
    9033                                                 {
    9034                                                         $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);
    9035                                                 }
    9036                                         }
    9037                                         else
    9038                                         {
    9039                                                 return false;
    9040                                         }
    9041                                 }
    9042                         }
    9043                         return $data;
    9044                 }
    9045                 return false;
    9046         }
    9047 
    9048         function mtime()
    9049         {
    9050                 if ($this->mysql && ($query = mysql_query('SELECT `mtime` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
    9051                 {
    9052                         return $row[0];
    9053                 }
    9054                 else
    9055                 {
    9056                         return false;
    9057                 }
    9058         }
    9059 
    9060         function touch()
    9061         {
    9062                 if ($this->mysql && ($query = mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && mysql_affected_rows($this->mysql))
    9063                 {
    9064                         return true;
    9065                 }
    9066                 else
    9067                 {
    9068                         return false;
    9069                 }
    9070         }
    9071 
    9072         function unlink()
    9073         {
    9074                 if ($this->mysql && ($query = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($query2 = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)))
    9075                 {
    9076                         return true;
    9077                 }
    9078                 else
    9079                 {
    9080                         return false;
    9081                 }
    9082         }
    9083 }
    9084 
    9085 class SimplePie_Misc
    9086 {
    9087         function time_hms($seconds)
    9088         {
    9089                 $time = '';
    9090 
    9091                 $hours = floor($seconds / 3600);
    9092                 $remainder = $seconds % 3600;
    9093                 if ($hours > 0)
    9094                 {
    9095                         $time .= $hours.':';
    9096                 }
    9097 
    9098                 $minutes = floor($remainder / 60);
    9099                 $seconds = $remainder % 60;
    9100                 if ($minutes < 10 && $hours > 0)
    9101                 {
    9102                         $minutes = '0' . $minutes;
    9103                 }
    9104                 if ($seconds < 10)
    9105                 {
    9106                         $seconds = '0' . $seconds;
    9107                 }
    9108 
    9109                 $time .= $minutes.':';
    9110                 $time .= $seconds;
    9111 
    9112                 return $time;
    9113         }
    9114 
    9115         function absolutize_url($relative, $base)
    9116         {
    9117                 $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
    9118                 return $iri->get_iri();
    9119         }
    9120 
    9121         function remove_dot_segments($input)
    9122         {
    9123                 $output = '';
    9124                 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
    9125                 {
    9126                         // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
    9127                         if (strpos($input, '../') === 0)
    9128                         {
    9129                                 $input = substr($input, 3);
    9130                         }
    9131                         elseif (strpos($input, './') === 0)
    9132                         {
    9133                                 $input = substr($input, 2);
    9134                         }
    9135                         // 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,
    9136                         elseif (strpos($input, '/./') === 0)
    9137                         {
    9138                                 $input = substr_replace($input, '/', 0, 3);
    9139                         }
    9140                         elseif ($input === '/.')
    9141                         {
    9142                                 $input = '/';
    9143                         }
    9144                         // 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,
    9145                         elseif (strpos($input, '/../') === 0)
    9146                         {
    9147                                 $input = substr_replace($input, '/', 0, 4);
    9148                                 $output = substr_replace($output, '', strrpos($output, '/'));
    9149                         }
    9150                         elseif ($input === '/..')
    9151                         {
    9152                                 $input = '/';
    9153                                 $output = substr_replace($output, '', strrpos($output, '/'));
    9154                         }
    9155                         // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
    9156                         elseif ($input === '.' || $input === '..')
    9157                         {
    9158                                 $input = '';
    9159                         }
    9160                         // 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
    9161                         elseif (($pos = strpos($input, '/', 1)) !== false)
    9162                         {
    9163                                 $output .= substr($input, 0, $pos);
    9164                                 $input = substr_replace($input, '', 0, $pos);
    9165                         }
    9166                         else
    9167                         {
    9168                                 $output .= $input;
    9169                                 $input = '';
    9170                         }
    9171                 }
    9172                 return $output . $input;
    9173         }
    9174 
    9175         function get_element($realname, $string)
    9176         {
    9177                 $return = array();
    9178                 $name = preg_quote($realname, '/');
    9179                 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
    9180                 {
    9181                         for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
    9182                         {
    9183                                 $return[$i]['tag'] = $realname;
    9184                                 $return[$i]['full'] = $matches[$i][0][0];
    9185                                 $return[$i]['offset'] = $matches[$i][0][1];
    9186                                 if (strlen($matches[$i][3][0]) <= 2)
    9187                                 {
    9188                                         $return[$i]['self_closing'] = true;
    9189                                 }
    9190                                 else
    9191                                 {
    9192                                         $return[$i]['self_closing'] = false;
    9193                                         $return[$i]['content'] = $matches[$i][4][0];
    9194                                 }
    9195                                 $return[$i]['attribs'] = array();
    9196                                 if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
    9197                                 {
    9198                                         for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
    9199                                         {
    9200                                                 if (count($attribs[$j]) === 2)
    9201                                                 {
    9202                                                         $attribs[$j][2] = $attribs[$j][1];
    9203                                                 }
    9204                                                 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
    9205                                         }
    9206                                 }
    9207                         }
    9208                 }
    9209                 return $return;
    9210         }
    9211 
    9212         function element_implode($element)
    9213         {
    9214                 $full = "<$element[tag]";
    9215                 foreach ($element['attribs'] as $key => $value)
    9216                 {
    9217                         $key = strtolower($key);
    9218                         $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
    9219                 }
    9220                 if ($element['self_closing'])
    9221                 {
    9222                         $full .= ' />';
    9223                 }
    9224                 else
    9225                 {
    9226                         $full .= ">$element[content]</$element[tag]>";
    9227                 }
    9228                 return $full;
    9229         }
    9230 
    9231         function error($message, $level, $file, $line)
    9232         {
    9233                 if ((ini_get('error_reporting') & $level) > 0)
    9234                 {
    9235                         switch ($level)
    9236                         {
    9237                                 case E_USER_ERROR:
    9238                                         $note = 'PHP Error';
    9239                                         break;
    9240                                 case E_USER_WARNING:
    9241                                         $note = 'PHP Warning';
    9242                                         break;
    9243                                 case E_USER_NOTICE:
    9244                                         $note = 'PHP Notice';
    9245                                         break;
    9246                                 default:
    9247                                         $note = 'Unknown Error';
    9248                                         break;
    9249                         }
    9250 
    9251                         $log_error = true;
    9252                         if (!function_exists('error_log'))
    9253                         {
    9254                                 $log_error = false;
    9255                         }
    9256 
    9257                         $log_file = @ini_get('error_log');
    9258                         if (!empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file))
    9259                         {
    9260                                 $log_error = false;
    9261                         }
    9262 
    9263                         if ($log_error)
    9264                         {
    9265                                 @error_log("$note: $message in $file on line $line", 0);
    9266                         }
    9267                 }
    9268 
    9269                 return $message;
    9270         }
    9271 
    9272         /**
    9273          * If a file has been cached, retrieve and display it.
    9274          *
    9275          * This is most useful for caching images (get_favicon(), etc.),
    9276          * however it works for all cached files.  This WILL NOT display ANY
    9277          * file/image/page/whatever, but rather only display what has already
    9278          * been cached by SimplePie.
    9279          *
    9280          * @access public
    9281          * @see SimplePie::get_favicon()
    9282          * @param str $identifier_url URL that is used to identify the content.
    9283          * This may or may not be the actual URL of the live content.
    9284          * @param str $cache_location Location of SimplePie's cache.  Defaults
    9285          * to './cache'.
    9286          * @param str $cache_extension The file extension that the file was
    9287          * cached with.  Defaults to 'spc'.
    9288          * @param str $cache_class Name of the cache-handling class being used
    9289          * in SimplePie.  Defaults to 'SimplePie_Cache', and should be left
    9290          * as-is unless you've overloaded the class.
    9291          * @param str $cache_name_function Obsolete. Exists for backwards
    9292          * compatibility reasons only.
    9293          */
    9294         function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
    9295         {
    9296                 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
    9297 
    9298                 if ($file = $cache->load())
    9299                 {
    9300                         if (isset($file['headers']['content-type']))
    9301                         {
    9302                                 header('Content-type:' . $file['headers']['content-type']);
    9303                         }
    9304                         else
    9305                         {
    9306                                 header('Content-type: application/octet-stream');
    9307                         }
    9308                         header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
    9309                         echo $file['body'];
    9310                         exit;
    9311                 }
    9312 
    9313                 die('Cached file for ' . $identifier_url . ' cannot be found.');
    9314         }
    9315 
    9316         function fix_protocol($url, $http = 1)
    9317         {
    9318                 $url = SimplePie_Misc::normalize_url($url);
    9319                 $parsed = SimplePie_Misc::parse_url($url);
    9320                 if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
    9321                 {
    9322                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
    9323                 }
    9324 
    9325                 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
    9326                 {
    9327                         return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
    9328                 }
    9329 
    9330                 if ($http === 2 && $parsed['scheme'] !== '')
    9331                 {
    9332                         return "feed:$url";
    9333                 }
    9334                 elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
    9335                 {
    9336                         return substr_replace($url, 'podcast', 0, 4);
    9337                 }
    9338                 elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
    9339                 {
    9340                         return substr_replace($url, 'itpc', 0, 4);
    9341                 }
    9342                 else
    9343                 {
    9344                         return $url;
    9345                 }
    9346         }
    9347 
    9348         function parse_url($url)
    9349         {
    9350                 $iri =& new SimplePie_IRI($url);
    9351                 return array(
    9352                         'scheme' => (string) $iri->get_scheme(),
    9353                         'authority' => (string) $iri->get_authority(),
    9354                         'path' => (string) $iri->get_path(),
    9355                         'query' => (string) $iri->get_query(),
    9356                         'fragment' => (string) $iri->get_fragment()
    9357                 );
    9358         }
    9359 
    9360         function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
    9361         {
    9362                 $iri =& new SimplePie_IRI('');
    9363                 $iri->set_scheme($scheme);
    9364                 $iri->set_authority($authority);
    9365                 $iri->set_path($path);
    9366                 $iri->set_query($query);
    9367                 $iri->set_fragment($fragment);
    9368                 return $iri->get_iri();
    9369         }
    9370 
    9371         function normalize_url($url)
    9372         {
    9373                 $iri =& new SimplePie_IRI($url);
    9374                 return $iri->get_iri();
    9375         }
    9376 
    9377         function percent_encoding_normalization($match)
    9378         {
    9379                 $integer = hexdec($match[1]);
    9380                 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
    9381                 {
    9382                         return chr($integer);
    9383                 }
    9384                 else
    9385                 {
    9386                         return strtoupper($match[0]);
    9387                 }
    9388         }
    9389 
    9390         /**
    9391          * Remove bad UTF-8 bytes
    9392          *
    9393          * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
    9394          * FAQ: Multilingual Forms (modified to include full ASCII range)
    9395          *
    9396          * @author Geoffrey Sneddon
    9397          * @see http://www.w3.org/International/questions/qa-forms-utf-8
    9398          * @param string $str String to remove bad UTF-8 bytes from
    9399          * @return string UTF-8 string
    9400          */
    9401         function utf8_bad_replace($str)
    9402         {
    9403                 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
    9404                 {
    9405                         return $return;
    9406                 }
    9407                 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
    9408                 {
    9409                         return $return;
    9410                 }
    9411                 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))
    9412                 {
    9413                         return implode("\xEF\xBF\xBD", $matches[0]);
    9414                 }
    9415                 elseif ($str !== '')
    9416                 {
    9417                         return "\xEF\xBF\xBD";
    9418                 }
    9419                 else
    9420                 {
    9421                         return '';
    9422                 }
    9423         }
    9424 
    9425         /**
    9426          * Converts a Windows-1252 encoded string to a UTF-8 encoded string
    9427          *
    9428          * @static
    9429          * @access public
    9430          * @param string $string Windows-1252 encoded string
    9431          * @return string UTF-8 encoded string
    9432          */
    9433         function windows_1252_to_utf8($string)
    9434         {
    9435                 static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
    9436 
    9437                 return strtr($string, $convert_table);
    9438         }
    9439 
    9440         function change_encoding($data, $input, $output)
    9441         {
    9442                 $input = SimplePie_Misc::encoding($input);
    9443                 $output = SimplePie_Misc::encoding($output);
    9444 
    9445                 // We fail to fail on non US-ASCII bytes
    9446                 if ($input === 'US-ASCII')
    9447                 {
    9448                         static $non_ascii_octects = '';
    9449                         if (!$non_ascii_octects)
    9450                         {
    9451                                 for ($i = 0x80; $i <= 0xFF; $i++)
    9452                                 {
    9453                                         $non_ascii_octects .= chr($i);
    9454                                 }
    9455                         }
    9456                         $data = substr($data, 0, strcspn($data, $non_ascii_octects));
    9457                 }
    9458 
    9459                 // This is first, as behaviour of this is completely predictable
    9460                 if ($input === 'windows-1252' && $output === 'UTF-8')
    9461                 {
    9462                         return SimplePie_Misc::windows_1252_to_utf8($data);
    9463                 }
    9464                 // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
    9465                 elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && in_array($input, mb_list_encodings()) && ($return = @mb_convert_encoding($data, $output, $input)))
    9466                 {
    9467                         return $return;
    9468                 }
    9469                 // This is last, as behaviour of this varies with OS userland and PHP version
    9470                 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
    9471                 {
    9472                         return $return;
    9473                 }
    9474                 // If we can't do anything, just fail
    9475                 else
    9476                 {
    9477                         return false;
    9478                 }
    9479         }
    9480 
    9481         /**
    9482          * Normalize an encoding name
    9483          *
    9484          * This is automatically generated by create.php
    9485          *
    9486          * To generate it, run `php create.php` on the command line, and copy the
    9487          * output to replace this function.
    9488          *
    9489          * @param string $charset Character set to standardise
    9490          * @return string Standardised name
    9491          */
    9492         function encoding($charset)
    9493         {
    9494                 // Normalization from UTS #22
    9495                 switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
    9496                 {
    9497                         case 'adobestandardencoding':
    9498                         case 'csadobestandardencoding':
    9499                                 return 'Adobe-Standard-Encoding';
    9500 
    9501                         case 'adobesymbolencoding':
    9502                         case 'cshppsmath':
    9503                                 return 'Adobe-Symbol-Encoding';
    9504 
    9505                         case 'ami1251':
    9506                         case 'amiga1251':
    9507                                 return 'Amiga-1251';
    9508 
    9509                         case 'ansix31101983':
    9510                         case 'csat5001983':
    9511                         case 'csiso99naplps':
    9512                         case 'isoir99':
    9513                         case 'naplps':
    9514                                 return 'ANSI_X3.110-1983';
    9515 
    9516                         case 'arabic7':
    9517                         case 'asmo449':
    9518                         case 'csiso89asmo449':
    9519                         case 'iso9036':
    9520                         case 'isoir89':
    9521                                 return 'ASMO_449';
    9522 
    9523                         case 'big5':
    9524                         case 'csbig5':
    9525                                 return 'Big5';
    9526 
    9527                         case 'big5hkscs':
    9528                                 return 'Big5-HKSCS';
    9529 
    9530                         case 'bocu1':
    9531                         case 'csbocu1':
    9532                                 return 'BOCU-1';
    9533 
    9534                         case 'brf':
    9535                         case 'csbrf':
    9536                                 return 'BRF';
    9537 
    9538                         case 'bs4730':
    9539                         case 'csiso4unitedkingdom':
    9540                         case 'gb':
    9541                         case 'iso646gb':
    9542                         case 'isoir4':
    9543                         case 'uk':
    9544                                 return 'BS_4730';
    9545 
    9546                         case 'bsviewdata':
    9547                         case 'csiso47bsviewdata':
    9548                         case 'isoir47':
    9549                                 return 'BS_viewdata';
    9550 
    9551                         case 'cesu8':
    9552                         case 'cscesu8':
    9553                                 return 'CESU-8';
    9554 
    9555                         case 'ca':
    9556                         case 'csa71':
    9557                         case 'csaz243419851':
    9558                         case 'csiso121canadian1':
    9559                         case 'iso646ca':
    9560                         case 'isoir121':
    9561                                 return 'CSA_Z243.4-1985-1';
    9562 
    9563                         case 'csa72':
    9564                         case 'csaz243419852':
    9565                         case 'csiso122canadian2':
    9566                         case 'iso646ca2':
    9567                         case 'isoir122':
    9568                                 return 'CSA_Z243.4-1985-2';
    9569 
    9570                         case 'csaz24341985gr':
    9571                         case 'csiso123csaz24341985gr':
    9572                         case 'isoir123':
    9573                                 return 'CSA_Z243.4-1985-gr';
    9574 
    9575                         case 'csiso139csn369103':
    9576                         case 'csn369103':
    9577                         case 'isoir139':
    9578                                 return 'CSN_369103';
    9579 
    9580                         case 'csdecmcs':
    9581                         case 'dec':
    9582                         case 'decmcs':
    9583                                 return 'DEC-MCS';
    9584 
    9585                         case 'csiso21german':
    9586                         case 'de':
    9587                         case 'din66003':
    9588                         case 'iso646de':
    9589                         case 'isoir21':
    9590                                 return 'DIN_66003';
    9591 
    9592                         case 'csdkus':
    9593                         case 'dkus':
    9594                                 return 'dk-us';
    9595 
    9596                         case 'csiso646danish':
    9597                         case 'dk':
    9598                         case 'ds2089':
    9599                         case 'iso646dk':
    9600                                 return 'DS_2089';
    9601 
    9602                         case 'csibmebcdicatde':
    9603                         case 'ebcdicatde':
    9604                                 return 'EBCDIC-AT-DE';
    9605 
    9606                         case 'csebcdicatdea':
    9607                         case 'ebcdicatdea':
    9608                                 return 'EBCDIC-AT-DE-A';
    9609 
    9610                         case 'csebcdiccafr':
    9611                         case 'ebcdiccafr':
    9612                                 return 'EBCDIC-CA-FR';
    9613 
    9614                         case 'csebcdicdkno':
    9615                         case 'ebcdicdkno':
    9616                                 return 'EBCDIC-DK-NO';
    9617 
    9618                         case 'csebcdicdknoa':
    9619                         case 'ebcdicdknoa':
    9620                                 return 'EBCDIC-DK-NO-A';
    9621 
    9622                         case 'csebcdices':
    9623                         case 'ebcdices':
    9624                                 return 'EBCDIC-ES';
    9625 
    9626                         case 'csebcdicesa':
    9627                         case 'ebcdicesa':
    9628                                 return 'EBCDIC-ES-A';
    9629 
    9630                         case 'csebcdicess':
    9631                         case 'ebcdicess':
    9632                                 return 'EBCDIC-ES-S';
    9633 
    9634                         case 'csebcdicfise':
    9635                         case 'ebcdicfise':
    9636                                 return 'EBCDIC-FI-SE';
    9637 
    9638                         case 'csebcdicfisea':
    9639                         case 'ebcdicfisea':
    9640                                 return 'EBCDIC-FI-SE-A';
    9641 
    9642                         case 'csebcdicfr':
    9643                         case 'ebcdicfr':
    9644                                 return 'EBCDIC-FR';
    9645 
    9646                         case 'csebcdicit':
    9647                         case 'ebcdicit':
    9648                                 return 'EBCDIC-IT';
    9649 
    9650                         case 'csebcdicpt':
    9651                         case 'ebcdicpt':
    9652                                 return 'EBCDIC-PT';
    9653 
    9654                         case 'csebcdicuk':
    9655                         case 'ebcdicuk':
    9656                                 return 'EBCDIC-UK';
    9657 
    9658                         case 'csebcdicus':
    9659                         case 'ebcdicus':
    9660                                 return 'EBCDIC-US';
    9661 
    9662                         case 'csiso111ecmacyrillic':
    9663                         case 'ecmacyrillic':
    9664                         case 'isoir111':
    9665                         case 'koi8e':
    9666                                 return 'ECMA-cyrillic';
    9667 
    9668                         case 'csiso17spanish':
    9669                         case 'es':
    9670                         case 'iso646es':
    9671                         case 'isoir17':
    9672                                 return 'ES';
    9673 
    9674                         case 'csiso85spanish2':
    9675                         case 'es2':
    9676                         case 'iso646es2':
    9677                         case 'isoir85':
    9678                                 return 'ES2';
    9679 
    9680                         case 'cseucpkdfmtjapanese':
    9681                         case 'eucjp':
    9682                         case 'extendedunixcodepackedformatforjapanese':
    9683                                 return 'EUC-JP';
    9684 
    9685                         case 'cseucfixwidjapanese':
    9686                         case 'extendedunixcodefixedwidthforjapanese':
    9687                                 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
    9688 
    9689                         case 'gb18030':
    9690                                 return 'GB18030';
    9691 
    9692                         case 'chinese':
    9693                         case 'cp936':
    9694                         case 'csgb2312':
    9695                         case 'csiso58gb231280':
    9696                         case 'gb2312':
    9697                         case 'gb231280':
    9698                         case 'gbk':
    9699                         case 'isoir58':
    9700                         case 'ms936':
    9701                         case 'windows936':
    9702                                 return 'GBK';
    9703 
    9704                         case 'cn':
    9705                         case 'csiso57gb1988':
    9706                         case 'gb198880':
    9707                         case 'iso646cn':
    9708                         case 'isoir57':
    9709                                 return 'GB_1988-80';
    9710 
    9711                         case 'csiso153gost1976874':
    9712                         case 'gost1976874':
    9713                         case 'isoir153':
    9714                         case 'stsev35888':
    9715                                 return 'GOST_19768-74';
    9716 
    9717                         case 'csiso150':
    9718                         case 'csiso150greekccitt':
    9719                         case 'greekccitt':
    9720                         case 'isoir150':
    9721                                 return 'greek-ccitt';
    9722 
    9723                         case 'csiso88greek7':
    9724                         case 'greek7':
    9725                         case 'isoir88':
    9726                                 return 'greek7';
    9727 
    9728                         case 'csiso18greek7old':
    9729                         case 'greek7old':
    9730                         case 'isoir18':
    9731                                 return 'greek7-old';
    9732 
    9733                         case 'cshpdesktop':
    9734                         case 'hpdesktop':
    9735                                 return 'HP-DeskTop';
    9736 
    9737                         case 'cshplegal':
    9738                         case 'hplegal':
    9739                                 return 'HP-Legal';
    9740 
    9741                         case 'cshpmath8':
    9742                         case 'hpmath8':
    9743                                 return 'HP-Math8';
    9744 
    9745                         case 'cshppifont':
    9746                         case 'hppifont':
    9747                                 return 'HP-Pi-font';
    9748 
    9749                         case 'cshproman8':
    9750                         case 'hproman8':
    9751                         case 'r8':
    9752                         case 'roman8':
    9753                                 return 'hp-roman8';
    9754 
    9755                         case 'hzgb2312':
    9756                                 return 'HZ-GB-2312';
    9757 
    9758                         case 'csibmsymbols':
    9759                         case 'ibmsymbols':
    9760                                 return 'IBM-Symbols';
    9761 
    9762                         case 'csibmthai':
    9763                         case 'ibmthai':
    9764                                 return 'IBM-Thai';
    9765 
    9766                         case 'cp37':
    9767                         case 'csibm37':
    9768                         case 'ebcdiccpca':
    9769                         case 'ebcdiccpnl':
    9770                         case 'ebcdiccpus':
    9771                         case 'ebcdiccpwt':
    9772                         case 'ibm37':
    9773                                 return 'IBM037';
    9774 
    9775                         case 'cp38':
    9776                         case 'csibm38':
    9777                         case 'ebcdicint':
    9778                         case 'ibm38':
    9779                                 return 'IBM038';
    9780 
    9781                         case 'cp273':
    9782                         case 'csibm273':
    9783                         case 'ibm273':
    9784                                 return 'IBM273';
    9785 
    9786                         case 'cp274':
    9787                         case 'csibm274':
    9788                         case 'ebcdicbe':
    9789                         case 'ibm274':
    9790                                 return 'IBM274';
    9791 
    9792                         case 'cp275':
    9793                         case 'csibm275':
    9794                         case 'ebcdicbr':
    9795                         case 'ibm275':
    9796                                 return 'IBM275';
    9797 
    9798                         case 'csibm277':
    9799                         case 'ebcdiccpdk':
    9800                         case 'ebcdiccpno':
    9801                         case 'ibm277':
    9802                                 return 'IBM277';
    9803 
    9804                         case 'cp278':
    9805                         case 'csibm278':
    9806                         case 'ebcdiccpfi':
    9807                         case 'ebcdiccpse':
    9808                         case 'ibm278':
    9809                                 return 'IBM278';
    9810 
    9811                         case 'cp280':
    9812                         case 'csibm280':
    9813                         case 'ebcdiccpit':
    9814                         case 'ibm280':
    9815                                 return 'IBM280';
    9816 
    9817                         case 'cp281':
    9818                         case 'csibm281':
    9819                         case 'ebcdicjpe':
    9820                         case 'ibm281':
    9821                                 return 'IBM281';
    9822 
    9823                         case 'cp284':
    9824                         case 'csibm284':
    9825                         case 'ebcdiccpes':
    9826                         case 'ibm284':
    9827                                 return 'IBM284';
    9828 
    9829                         case 'cp285':
    9830                         case 'csibm285':
    9831                         case 'ebcdiccpgb':
    9832                         case 'ibm285':
    9833                                 return 'IBM285';
    9834 
    9835                         case 'cp290':
    9836                         case 'csibm290':
    9837                         case 'ebcdicjpkana':
    9838                         case 'ibm290':
    9839                                 return 'IBM290';
    9840 
    9841                         case 'cp297':
    9842                         case 'csibm297':
    9843                         case 'ebcdiccpfr':
    9844                         case 'ibm297':
    9845                                 return 'IBM297';
    9846 
    9847                         case 'cp420':
    9848                         case 'csibm420':
    9849                         case 'ebcdiccpar1':
    9850                         case 'ibm420':
    9851                                 return 'IBM420';
    9852 
    9853                         case 'cp423':
    9854                         case 'csibm423':
    9855                         case 'ebcdiccpgr':
    9856                         case 'ibm423':
    9857                                 return 'IBM423';
    9858 
    9859                         case 'cp424':
    9860                         case 'csibm424':
    9861                         case 'ebcdiccphe':
    9862                         case 'ibm424':
    9863                                 return 'IBM424';
    9864 
    9865                         case '437':
    9866                         case 'cp437':
    9867                         case 'cspc8codepage437':
    9868                         case 'ibm437':
    9869                                 return 'IBM437';
    9870 
    9871                         case 'cp500':
    9872                         case 'csibm500':
    9873                         case 'ebcdiccpbe':
    9874                         case 'ebcdiccpch':
    9875                         case 'ibm500':
    9876                                 return 'IBM500';
    9877 
    9878                         case 'cp775':
    9879                         case 'cspc775baltic':
    9880                         case 'ibm775':
    9881                                 return 'IBM775';
    9882 
    9883                         case '850':
    9884                         case 'cp850':
    9885                         case 'cspc850multilingual':
    9886                         case 'ibm850':
    9887                                 return 'IBM850';
    9888 
    9889                         case '851':
    9890                         case 'cp851':
    9891                         case 'csibm851':
    9892                         case 'ibm851':
    9893                                 return 'IBM851';
    9894 
    9895                         case '852':
    9896                         case 'cp852':
    9897                         case 'cspcp852':
    9898                         case 'ibm852':
    9899                                 return 'IBM852';
    9900 
    9901                         case '855':
    9902                         case 'cp855':
    9903                         case 'csibm855':
    9904                         case 'ibm855':
    9905                                 return 'IBM855';
    9906 
    9907                         case '857':
    9908                         case 'cp857':
    9909                         case 'csibm857':
    9910                         case 'ibm857':
    9911                                 return 'IBM857';
    9912 
    9913                         case 'ccsid858':
    9914                         case 'cp858':
    9915                         case 'ibm858':
    9916                         case 'pcmultilingual850euro':
    9917                                 return 'IBM00858';
    9918 
    9919                         case '860':
    9920                         case 'cp860':
    9921                         case 'csibm860':
    9922                         case 'ibm860':
    9923                                 return 'IBM860';
    9924 
    9925                         case '861':
    9926                         case 'cp861':
    9927                         case 'cpis':
    9928                         case 'csibm861':
    9929                         case 'ibm861':
    9930                                 return 'IBM861';
    9931 
    9932                         case '862':
    9933                         case 'cp862':
    9934                         case 'cspc862latinhebrew':
    9935                         case 'ibm862':
    9936                                 return 'IBM862';
    9937 
    9938                         case '863':
    9939                         case 'cp863':
    9940                         case 'csibm863':
    9941                         case 'ibm863':
    9942                                 return 'IBM863';
    9943 
    9944                         case 'cp864':
    9945                         case 'csibm864':
    9946                         case 'ibm864':
    9947                                 return 'IBM864';
    9948 
    9949                         case '865':
    9950                         case 'cp865':
    9951                         case 'csibm865':
    9952                         case 'ibm865':
    9953                                 return 'IBM865';
    9954 
    9955                         case '866':
    9956                         case 'cp866':
    9957                         case 'csibm866':
    9958                         case 'ibm866':
    9959                                 return 'IBM866';
    9960 
    9961                         case 'cp868':
    9962                         case 'cpar':
    9963                         case 'csibm868':
    9964                         case 'ibm868':
    9965                                 return 'IBM868';
    9966 
    9967                         case '869':
    9968                         case 'cp869':
    9969                         case 'cpgr':
    9970                         case 'csibm869':
    9971                         case 'ibm869':
    9972                                 return 'IBM869';
    9973 
    9974                         case 'cp870':
    9975                         case 'csibm870':
    9976                         case 'ebcdiccproece':
    9977                         case 'ebcdiccpyu':
    9978                         case 'ibm870':
    9979                                 return 'IBM870';
    9980 
    9981                         case 'cp871':
    9982                         case 'csibm871':
    9983                         case 'ebcdiccpis':
    9984                         case 'ibm871':
    9985                                 return 'IBM871';
    9986 
    9987                         case 'cp880':
    9988                         case 'csibm880':
    9989                         case 'ebcdiccyrillic':
    9990                         case 'ibm880':
    9991                                 return 'IBM880';
    9992 
    9993                         case 'cp891':
    9994                         case 'csibm891':
    9995                         case 'ibm891':
    9996                                 return 'IBM891';
    9997 
    9998                         case 'cp903':
    9999                         case 'csibm903':
    10000                         case 'ibm903':
    10001                                 return 'IBM903';
    10002 
    10003                         case '904':
    10004                         case 'cp904':
    10005                         case 'csibbm904':
    10006                         case 'ibm904':
    10007                                 return 'IBM904';
    10008 
    10009                         case 'cp905':
    10010                         case 'csibm905':
    10011                         case 'ebcdiccptr':
    10012                         case 'ibm905':
    10013                                 return 'IBM905';
    10014 
    10015                         case 'cp918':
    10016                         case 'csibm918':
    10017                         case 'ebcdiccpar2':
    10018                         case 'ibm918':
    10019                                 return 'IBM918';
    10020 
    10021                         case 'ccsid924':
    10022                         case 'cp924':
    10023                         case 'ebcdiclatin9euro':
    10024                         case 'ibm924':
    10025                                 return 'IBM00924';
    10026 
    10027                         case 'cp1026':
    10028                         case 'csibm1026':
    10029                         case 'ibm1026':
    10030                                 return 'IBM1026';
    10031 
    10032                         case 'ibm1047':
    10033                                 return 'IBM1047';
    10034 
    10035                         case 'ccsid1140':
    10036                         case 'cp1140':
    10037                         case 'ebcdicus37euro':
    10038                         case 'ibm1140':
    10039                                 return 'IBM01140';
    10040 
    10041                         case 'ccsid1141':
    10042                         case 'cp1141':
    10043                         case 'ebcdicde273euro':
    10044                         case 'ibm1141':
    10045                                 return 'IBM01141';
    10046 
    10047                         case 'ccsid1142':
    10048                         case 'cp1142':
    10049                         case 'ebcdicdk277euro':
    10050                         case 'ebcdicno277euro':
    10051                         case 'ibm1142':
    10052                                 return 'IBM01142';
    10053 
    10054                         case 'ccsid1143':
    10055                         case 'cp1143':
    10056                         case 'ebcdicfi278euro':
    10057                         case 'ebcdicse278euro':
    10058                         case 'ibm1143':
    10059                                 return 'IBM01143';
    10060 
    10061                         case 'ccsid1144':
    10062                         case 'cp1144':
    10063                         case 'ebcdicit280euro':
    10064                         case 'ibm1144':
    10065                                 return 'IBM01144';
    10066 
    10067                         case 'ccsid1145':
    10068                         case 'cp1145':
    10069                         case 'ebcdices284euro':
    10070                         case 'ibm1145':
    10071                                 return 'IBM01145';
    10072 
    10073                         case 'ccsid1146':
    10074                         case 'cp1146':
    10075                         case 'ebcdicgb285euro':
    10076                         case 'ibm1146':
    10077                                 return 'IBM01146';
    10078 
    10079                         case 'ccsid1147':
    10080                         case 'cp1147':
    10081                         case 'ebcdicfr297euro':
    10082                         case 'ibm1147':
    10083                                 return 'IBM01147';
    10084 
    10085                         case 'ccsid1148':
    10086                         case 'cp1148':
    10087                         case 'ebcdicinternational500euro':
    10088                         case 'ibm1148':
    10089                                 return 'IBM01148';
    10090 
    10091                         case 'ccsid1149':
    10092                         case 'cp1149':
    10093                         case 'ebcdicis871euro':
    10094                         case 'ibm1149':
    10095                                 return 'IBM01149';
    10096 
    10097                         case 'csiso143iecp271':
    10098                         case 'iecp271':
    10099                         case 'isoir143':
    10100                                 return 'IEC_P27-1';
    10101 
    10102                         case 'csiso49inis':
    10103                         case 'inis':
    10104                         case 'isoir49':
    10105                                 return 'INIS';
    10106 
    10107                         case 'csiso50inis8':
    10108                         case 'inis8':
    10109                         case 'isoir50':
    10110                                 return 'INIS-8';
    10111 
    10112                         case 'csiso51iniscyrillic':
    10113                         case 'iniscyrillic':
    10114                         case 'isoir51':
    10115                                 return 'INIS-cyrillic';
    10116 
    10117                         case 'csinvariant':
    10118                         case 'invariant':
    10119                                 return 'INVARIANT';
    10120 
    10121                         case 'iso2022cn':
    10122                                 return 'ISO-2022-CN';
    10123 
    10124                         case 'iso2022cnext':
    10125                                 return 'ISO-2022-CN-EXT';
    10126 
    10127                         case 'csiso2022jp':
    10128                         case 'iso2022jp':
    10129                                 return 'ISO-2022-JP';
    10130 
    10131                         case 'csiso2022jp2':
    10132                         case 'iso2022jp2':
    10133                                 return 'ISO-2022-JP-2';
    10134 
    10135                         case 'csiso2022kr':
    10136                         case 'iso2022kr':
    10137                                 return 'ISO-2022-KR';
    10138 
    10139                         case 'cswindows30latin1':
    10140                         case 'iso88591windows30latin1':
    10141                                 return 'ISO-8859-1-Windows-3.0-Latin-1';
    10142 
    10143                         case 'cswindows31latin1':
    10144                         case 'iso88591windows31latin1':
    10145                                 return 'ISO-8859-1-Windows-3.1-Latin-1';
    10146 
    10147                         case 'csisolatin2':
    10148                         case 'iso88592':
    10149                         case 'iso885921987':
    10150                         case 'isoir101':
    10151                         case 'l2':
    10152                         case 'latin2':
    10153                                 return 'ISO-8859-2';
    10154 
    10155                         case 'cswindows31latin2':
    10156                         case 'iso88592windowslatin2':
    10157                                 return 'ISO-8859-2-Windows-Latin-2';
    10158 
    10159                         case 'csisolatin3':
    10160                         case 'iso88593':
    10161                         case 'iso885931988':
    10162                         case 'isoir109':
    10163                         case 'l3':
    10164                         case 'latin3':
    10165                                 return 'ISO-8859-3';
    10166 
    10167                         case 'csisolatin4':
    10168                         case 'iso88594':
    10169                         case 'iso885941988':
    10170                         case 'isoir110':
    10171                         case 'l4':
    10172                         case 'latin4':
    10173                                 return 'ISO-8859-4';
    10174 
    10175                         case 'csisolatincyrillic':
    10176                         case 'cyrillic':
    10177                         case 'iso88595':
    10178                         case 'iso885951988':
    10179                         case 'isoir144':
    10180                                 return 'ISO-8859-5';
    10181 
    10182                         case 'arabic':
    10183                         case 'asmo708':
    10184                         case 'csisolatinarabic':
    10185                         case 'ecma114':
    10186                         case 'iso88596':
    10187                         case 'iso885961987':
    10188                         case 'isoir127':
    10189                                 return 'ISO-8859-6';
    10190 
    10191                         case 'csiso88596e':
    10192                         case 'iso88596e':
    10193                                 return 'ISO-8859-6-E';
    10194 
    10195                         case 'csiso88596i':
    10196                         case 'iso88596i':
    10197                                 return 'ISO-8859-6-I';
    10198 
    10199                         case 'csisolatingreek':
    10200                         case 'ecma118':
    10201                         case 'elot928':
    10202                         case 'greek':
    10203                         case 'greek8':
    10204                         case 'iso88597':
    10205                         case 'iso885971987':
    10206                         case 'isoir126':
    10207                                 return 'ISO-8859-7';
    10208 
    10209                         case 'csisolatinhebrew':
    10210                         case 'hebrew':
    10211                         case 'iso88598':
    10212                         case 'iso885981988':
    10213                         case 'isoir138':
    10214                                 return 'ISO-8859-8';
    10215 
    10216                         case 'csiso88598e':
    10217                         case 'iso88598e':
    10218                                 return 'ISO-8859-8-E';
    10219 
    10220                         case 'csiso88598i':
    10221                         case 'iso88598i':
    10222                                 return 'ISO-8859-8-I';
    10223 
    10224                         case 'cswindows31latin5':
    10225                         case 'iso88599windowslatin5':
    10226                                 return 'ISO-8859-9-Windows-Latin-5';
    10227 
    10228                         case 'csisolatin6':
    10229                         case 'iso885910':
    10230                         case 'iso8859101992':
    10231                         case 'isoir157':
    10232                         case 'l6':
    10233                         case 'latin6':
    10234                                 return 'ISO-8859-10';
    10235 
    10236                         case 'iso885913':
    10237                                 return 'ISO-8859-13';
    10238 
    10239                         case 'iso885914':
    10240                         case 'iso8859141998':
    10241                         case 'isoceltic':
    10242                         case 'isoir199':
    10243                         case 'l8':
    10244                         case 'latin8':
    10245                                 return 'ISO-8859-14';
    10246 
    10247                         case 'iso885915':
    10248                         case 'latin9':
    10249                                 return 'ISO-8859-15';
    10250 
    10251                         case 'iso885916':
    10252                         case 'iso8859162001':
    10253                         case 'isoir226':
    10254                         case 'l10':
    10255                         case 'latin10':
    10256                                 return 'ISO-8859-16';
    10257 
    10258                         case 'iso10646j1':
    10259                                 return 'ISO-10646-J-1';
    10260 
    10261                         case 'csunicode':
    10262                         case 'iso10646ucs2':
    10263                                 return 'ISO-10646-UCS-2';
    10264 
    10265                         case 'csucs4':
    10266                         case 'iso10646ucs4':
    10267                                 return 'ISO-10646-UCS-4';
    10268 
    10269                         case 'csunicodeascii':
    10270                         case 'iso10646ucsbasic':
    10271                                 return 'ISO-10646-UCS-Basic';
    10272 
    10273                         case 'csunicodelatin1':
    10274                         case 'iso10646':
    10275                         case 'iso10646unicodelatin1':
    10276                                 return 'ISO-10646-Unicode-Latin1';
    10277 
    10278                         case 'csiso10646utf1':
    10279                         case 'iso10646utf1':
    10280                                 return 'ISO-10646-UTF-1';
    10281 
    10282                         case 'csiso115481':
    10283                         case 'iso115481':
    10284                         case 'isotr115481':
    10285                                 return 'ISO-11548-1';
    10286 
    10287                         case 'csiso90':
    10288                         case 'isoir90':
    10289                                 return 'iso-ir-90';
    10290 
    10291                         case 'csunicodeibm1261':
    10292                         case 'isounicodeibm1261':
    10293                                 return 'ISO-Unicode-IBM-1261';
    10294 
    10295                         case 'csunicodeibm1264':
    10296                         case 'isounicodeibm1264':
    10297                                 return 'ISO-Unicode-IBM-1264';
    10298 
    10299                         case 'csunicodeibm1265':
    10300                         case 'isounicodeibm1265':
    10301                                 return 'ISO-Unicode-IBM-1265';
    10302 
    10303                         case 'csunicodeibm1268':
    10304                         case 'isounicodeibm1268':
    10305                                 return 'ISO-Unicode-IBM-1268';
    10306 
    10307                         case 'csunicodeibm1276':
    10308                         case 'isounicodeibm1276':
    10309                                 return 'ISO-Unicode-IBM-1276';
    10310 
    10311                         case 'csiso646basic1983':
    10312                         case 'iso646basic1983':
    10313                         case 'ref':
    10314                                 return 'ISO_646.basic:1983';
    10315 
    10316                         case 'csiso2intlrefversion':
    10317                         case 'irv':
    10318                         case 'iso646irv1983':
    10319                         case 'isoir2':
    10320                                 return 'ISO_646.irv:1983';
    10321 
    10322                         case 'csiso2033':
    10323                         case 'e13b':
    10324                         case 'iso20331983':
    10325                         case 'isoir98':
    10326                                 return 'ISO_2033-1983';
    10327 
    10328                         case 'csiso5427cyrillic':
    10329                         case 'iso5427':
    10330                         case 'isoir37':
    10331                                 return 'ISO_5427';
    10332 
    10333                         case 'iso5427cyrillic1981':
    10334                         case 'iso54271981':
    10335                         case 'isoir54':
    10336                                 return 'ISO_5427:1981';
    10337 
    10338                         case 'csiso5428greek':
    10339                         case 'iso54281980':
    10340                         case 'isoir55':
    10341                                 return 'ISO_5428:1980';
    10342 
    10343                         case 'csiso6937add':
    10344                         case 'iso6937225':
    10345                         case 'isoir152':
    10346                                 return 'ISO_6937-2-25';
    10347 
    10348                         case 'csisotextcomm':
    10349                         case 'iso69372add':
    10350                         case 'isoir142':
    10351                                 return 'ISO_6937-2-add';
    10352 
    10353                         case 'csiso8859supp':
    10354                         case 'iso8859supp':
    10355                         case 'isoir154':
    10356                         case 'latin125':
    10357                                 return 'ISO_8859-supp';
    10358 
    10359                         case 'csiso10367box':
    10360                         case 'iso10367box':
    10361                         case 'isoir155':
    10362                                 return 'ISO_10367-box';
    10363 
    10364                         case 'csiso15italian':
    10365                         case 'iso646it':
    10366                         case 'isoir15':
    10367                         case 'it':
    10368                                 return 'IT';
    10369 
    10370                         case 'csiso13jisc6220jp':
    10371                         case 'isoir13':
    10372                         case 'jisc62201969':
    10373                         case 'jisc62201969jp':
    10374                         case 'katakana':
    10375                         case 'x2017':
    10376                                 return 'JIS_C6220-1969-jp';
    10377 
    10378                         case 'csiso14jisc6220ro':
    10379                         case 'iso646jp':
    10380                         case 'isoir14':
    10381                         case 'jisc62201969ro':
    10382                         case 'jp':
    10383                                 return 'JIS_C6220-1969-ro';
    10384 
    10385                         case 'csiso42jisc62261978':
    10386                         case 'isoir42':
    10387                         case 'jisc62261978':
    10388                                 return 'JIS_C6226-1978';
    10389 
    10390                         case 'csiso87jisx208':
    10391                         case 'isoir87':
    10392                         case 'jisc62261983':
    10393                         case 'jisx2081983':
    10394                         case 'x208':
    10395                                 return 'JIS_C6226-1983';
    10396 
    10397                         case 'csiso91jisc62291984a':
    10398                         case 'isoir91':
    10399                         case 'jisc62291984a':
    10400                         case 'jpocra':
    10401                                 return 'JIS_C6229-1984-a';
    10402 
    10403                         case 'csiso92jisc62991984b':
    10404                         case 'iso646jpocrb':
    10405                         case 'isoir92':
    10406                         case 'jisc62291984b':
    10407                         case 'jpocrb':
    10408                                 return 'JIS_C6229-1984-b';
    10409 
    10410                         case 'csiso93jis62291984badd':
    10411                         case 'isoir93':
    10412                         case 'jisc62291984badd':
    10413                         case 'jpocrbadd':
    10414                                 return 'JIS_C6229-1984-b-add';
    10415 
    10416                         case 'csiso94jis62291984hand':
    10417                         case 'isoir94':
    10418                         case 'jisc62291984hand':
    10419                         case 'jpocrhand':
    10420                                 return 'JIS_C6229-1984-hand';
    10421 
    10422                         case 'csiso95jis62291984handadd':
    10423                         case 'isoir95':
    10424                         case 'jisc62291984handadd':
    10425                         case 'jpocrhandadd':
    10426                                 return 'JIS_C6229-1984-hand-add';
    10427 
    10428                         case 'csiso96jisc62291984kana':
    10429                         case 'isoir96':
    10430                         case 'jisc62291984kana':
    10431                                 return 'JIS_C6229-1984-kana';
    10432 
    10433                         case 'csjisencoding':
    10434                         case 'jisencoding':
    10435                                 return 'JIS_Encoding';
    10436 
    10437                         case 'cshalfwidthkatakana':
    10438                         case 'jisx201':
    10439                         case 'x201':
    10440                                 return 'JIS_X0201';
    10441 
    10442                         case 'csiso159jisx2121990':
    10443                         case 'isoir159':
    10444                         case 'jisx2121990':
    10445                         case 'x212':
    10446                                 return 'JIS_X0212-1990';
    10447 
    10448                         case 'csiso141jusib1002':
    10449                         case 'iso646yu':
    10450                         case 'isoir141':
    10451                         case 'js':
    10452                         case 'jusib1002':
    10453                         case 'yu':
    10454                                 return 'JUS_I.B1.002';
    10455 
    10456                         case 'csiso147macedonian':
    10457                         case 'isoir147':
    10458                         case 'jusib1003mac':
    10459                         case 'macedonian':
    10460                                 return 'JUS_I.B1.003-mac';
    10461 
    10462                         case 'csiso146serbian':
    10463                         case 'isoir146':
    10464                         case 'jusib1003serb':
    10465                         case 'serbian':
    10466                                 return 'JUS_I.B1.003-serb';
    10467 
    10468                         case 'koi7switched':
    10469                                 return 'KOI7-switched';
    10470 
    10471                         case 'cskoi8r':
    10472                         case 'koi8r':
    10473                                 return 'KOI8-R';
    10474 
    10475                         case 'koi8u':
    10476                                 return 'KOI8-U';
    10477 
    10478                         case 'csksc5636':
    10479                         case 'iso646kr':
    10480                         case 'ksc5636':
    10481                                 return 'KSC5636';
    10482 
    10483                         case 'cskz1048':
    10484                         case 'kz1048':
    10485                         case 'rk1048':
    10486                         case 'strk10482002':
    10487                                 return 'KZ-1048';
    10488 
    10489                         case 'csiso19latingreek':
    10490                         case 'isoir19':
    10491                         case 'latingreek':
    10492                                 return 'latin-greek';
    10493 
    10494                         case 'csiso27latingreek1':
    10495                         case 'isoir27':
    10496                         case 'latingreek1':
    10497                                 return 'Latin-greek-1';
    10498 
    10499                         case 'csiso158lap':
    10500                         case 'isoir158':
    10501                         case 'lap':
    10502                         case 'latinlap':
    10503                                 return 'latin-lap';
    10504 
    10505                         case 'csmacintosh':
    10506                         case 'mac':
    10507                         case 'macintosh':
    10508                                 return 'macintosh';
    10509 
    10510                         case 'csmicrosoftpublishing':
    10511                         case 'microsoftpublishing':
    10512                                 return 'Microsoft-Publishing';
    10513 
    10514                         case 'csmnem':
    10515                         case 'mnem':
    10516                                 return 'MNEM';
    10517 
    10518                         case 'csmnemonic':
    10519                         case 'mnemonic':
    10520                                 return 'MNEMONIC';
    10521 
    10522                         case 'csiso86hungarian':
    10523                         case 'hu':
    10524                         case 'iso646hu':
    10525                         case 'isoir86':
    10526                         case 'msz77953':
    10527                                 return 'MSZ_7795.3';
    10528 
    10529                         case 'csnatsdano':
    10530                         case 'isoir91':
    10531                         case 'natsdano':
    10532                                 return 'NATS-DANO';
    10533 
    10534                         case 'csnatsdanoadd':
    10535                         case 'isoir92':
    10536                         case 'natsdanoadd':
    10537                                 return 'NATS-DANO-ADD';
    10538 
    10539                         case 'csnatssefi':
    10540                         case 'isoir81':
    10541                         case 'natssefi':
    10542                                 return 'NATS-SEFI';
    10543 
    10544                         case 'csnatssefiadd':
    10545                         case 'isoir82':
    10546                         case 'natssefiadd':
    10547                                 return 'NATS-SEFI-ADD';
    10548 
    10549                         case 'csiso151cuba':
    10550                         case 'cuba':
    10551                         case 'iso646cu':
    10552                         case 'isoir151':
    10553                         case 'ncnc1081':
    10554                                 return 'NC_NC00-10:81';
    10555 
    10556                         case 'csiso69french':
    10557                         case 'fr':
    10558                         case 'iso646fr':
    10559                         case 'isoir69':
    10560                         case 'nfz62010':
    10561                                 return 'NF_Z_62-010';
    10562 
    10563                         case 'csiso25french':
    10564                         case 'iso646fr1':
    10565                         case 'isoir25':
    10566                         case 'nfz620101973':
    10567                                 return 'NF_Z_62-010_(1973)';
    10568 
    10569                         case 'csiso60danishnorwegian':
    10570                         case 'csiso60norwegian1':
    10571                         case 'iso646no':
    10572                         case 'isoir60':
    10573                         case 'no':
    10574                         case 'ns45511':
    10575                                 return 'NS_4551-1';
    10576 
    10577                         case 'csiso61norwegian2':
    10578                         case 'iso646no2':
    10579                         case 'isoir61':
    10580                         case 'no2':
    10581                         case 'ns45512':
    10582                                 return 'NS_4551-2';
    10583 
    10584                         case 'osdebcdicdf3irv':
    10585                                 return 'OSD_EBCDIC_DF03_IRV';
    10586 
    10587                         case 'osdebcdicdf41':
    10588                                 return 'OSD_EBCDIC_DF04_1';
    10589 
    10590                         case 'osdebcdicdf415':
    10591                                 return 'OSD_EBCDIC_DF04_15';
    10592 
    10593                         case 'cspc8danishnorwegian':
    10594                         case 'pc8danishnorwegian':
    10595                                 return 'PC8-Danish-Norwegian';
    10596 
    10597                         case 'cspc8turkish':
    10598                         case 'pc8turkish':
    10599                                 return 'PC8-Turkish';
    10600 
    10601                         case 'csiso16portuguese':
    10602                         case 'iso646pt':
    10603                         case 'isoir16':
    10604                         case 'pt':
    10605                                 return 'PT';
    10606 
    10607                         case 'csiso84portuguese2':
    10608                         case 'iso646pt2':
    10609                         case 'isoir84':
    10610                         case 'pt2':
    10611                                 return 'PT2';
    10612 
    10613                         case 'cp154':
    10614                         case 'csptcp154':
    10615                         case 'cyrillicasian':
    10616                         case 'pt154':
    10617                         case 'ptcp154':
    10618                                 return 'PTCP154';
    10619 
    10620                         case 'scsu':
    10621                                 return 'SCSU';
    10622 
    10623                         case 'csiso10swedish':
    10624                         case 'fi':
    10625                         case 'iso646fi':
    10626                         case 'iso646se':
    10627                         case 'isoir10':
    10628                         case 'se':
    10629                         case 'sen850200b':
    10630                                 return 'SEN_850200_B';
    10631 
    10632                         case 'csiso11swedishfornames':
    10633                         case 'iso646se2':
    10634                         case 'isoir11':
    10635                         case 'se2':
    10636                         case 'sen850200c':
    10637                                 return 'SEN_850200_C';
    10638 
    10639                         case 'csiso102t617bit':
    10640                         case 'isoir102':
    10641                         case 't617bit':
    10642                                 return 'T.61-7bit';
    10643 
    10644                         case 'csiso103t618bit':
    10645                         case 'isoir103':
    10646                         case 't61':
    10647                         case 't618bit':
    10648                                 return 'T.61-8bit';
    10649 
    10650                         case 'csiso128t101g2':
    10651                         case 'isoir128':
    10652                         case 't101g2':
    10653                                 return 'T.101-G2';
    10654 
    10655                         case 'cstscii':
    10656                         case 'tscii':
    10657                                 return 'TSCII';
    10658 
    10659                         case 'csunicode11':
    10660                         case 'unicode11':
    10661                                 return 'UNICODE-1-1';
    10662 
    10663                         case 'csunicode11utf7':
    10664                         case 'unicode11utf7':
    10665                                 return 'UNICODE-1-1-UTF-7';
    10666 
    10667                         case 'csunknown8bit':
    10668                         case 'unknown8bit':
    10669                                 return 'UNKNOWN-8BIT';
    10670 
    10671                         case 'ansix341968':
    10672                         case 'ansix341986':
    10673                         case 'ascii':
    10674                         case 'cp367':
    10675                         case 'csascii':
    10676                         case 'ibm367':
    10677                         case 'iso646irv1991':
    10678                         case 'iso646us':
    10679                         case 'isoir6':
    10680                         case 'us':
    10681                         case 'usascii':
    10682                                 return 'US-ASCII';
    10683 
    10684                         case 'csusdk':
    10685                         case 'usdk':
    10686                                 return 'us-dk';
    10687 
    10688                         case 'utf7':
    10689                                 return 'UTF-7';
    10690 
    10691                         case 'utf8':
    10692                                 return 'UTF-8';
    10693 
    10694                         case 'utf16':
    10695                                 return 'UTF-16';
    10696 
    10697                         case 'utf16be':
    10698                                 return 'UTF-16BE';
    10699 
    10700                         case 'utf16le':
    10701                                 return 'UTF-16LE';
    10702 
    10703                         case 'utf32':
    10704                                 return 'UTF-32';
    10705 
    10706                         case 'utf32be':
    10707                                 return 'UTF-32BE';
    10708 
    10709                         case 'utf32le':
    10710                                 return 'UTF-32LE';
    10711 
    10712                         case 'csventurainternational':
    10713                         case 'venturainternational':
    10714                                 return 'Ventura-International';
    10715 
    10716                         case 'csventuramath':
    10717                         case 'venturamath':
    10718                                 return 'Ventura-Math';
    10719 
    10720                         case 'csventuraus':
    10721                         case 'venturaus':
    10722                                 return 'Ventura-US';
    10723 
    10724                         case 'csiso70videotexsupp1':
    10725                         case 'isoir70':
    10726                         case 'videotexsuppl':
    10727                                 return 'videotex-suppl';
    10728 
    10729                         case 'csviqr':
    10730                         case 'viqr':
    10731                                 return 'VIQR';
    10732 
    10733                         case 'csviscii':
    10734                         case 'viscii':
    10735                                 return 'VISCII';
    10736 
    10737                         case 'csshiftjis':
    10738                         case 'cswindows31j':
    10739                         case 'mskanji':
    10740                         case 'shiftjis':
    10741                         case 'windows31j':
    10742                                 return 'Windows-31J';
    10743 
    10744                         case 'iso885911':
    10745                         case 'tis620':
    10746                                 return 'windows-874';
    10747 
    10748                         case 'cseuckr':
    10749                         case 'csksc56011987':
    10750                         case 'euckr':
    10751                         case 'isoir149':
    10752                         case 'korean':
    10753                         case 'ksc5601':
    10754                         case 'ksc56011987':
    10755                         case 'ksc56011989':
    10756                         case 'windows949':
    10757                                 return 'windows-949';
    10758 
    10759                         case 'windows1250':
    10760                                 return 'windows-1250';
    10761 
    10762                         case 'windows1251':
    10763                                 return 'windows-1251';
    10764 
    10765                         case 'cp819':
    10766                         case 'csisolatin1':
    10767                         case 'ibm819':
    10768                         case 'iso88591':
    10769                         case 'iso885911987':
    10770                         case 'isoir100':
    10771                         case 'l1':
    10772                         case 'latin1':
    10773                         case 'windows1252':
    10774                                 return 'windows-1252';
    10775 
    10776                         case 'windows1253':
    10777                                 return 'windows-1253';
    10778 
    10779                         case 'csisolatin5':
    10780                         case 'iso88599':
    10781                         case 'iso885991989':
    10782                         case 'isoir148':
    10783                         case 'l5':
    10784                         case 'latin5':
    10785                         case 'windows1254':
    10786                                 return 'windows-1254';
    10787 
    10788                         case 'windows1255':
    10789                                 return 'windows-1255';
    10790 
    10791                         case 'windows1256':
    10792                                 return 'windows-1256';
    10793 
    10794                         case 'windows1257':
    10795                                 return 'windows-1257';
    10796 
    10797                         case 'windows1258':
    10798                                 return 'windows-1258';
    10799 
    10800                         default:
    10801                                 return $charset;
    10802                 }
    10803         }
    10804 
    10805         function get_curl_version()
    10806         {
    10807                 if (is_array($curl = curl_version()))
    10808                 {
    10809                         $curl = $curl['version'];
    10810                 }
    10811                 elseif (substr($curl, 0, 5) === 'curl/')
    10812                 {
    10813                         $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
    10814                 }
    10815                 elseif (substr($curl, 0, 8) === 'libcurl/')
    10816                 {
    10817                         $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
    10818                 }
    10819                 else
    10820                 {
    10821                         $curl = 0;
    10822                 }
    10823                 return $curl;
    10824         }
    10825 
    10826         function is_subclass_of($class1, $class2)
    10827         {
    10828                 if (func_num_args() !== 2)
    10829                 {
    10830                         trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
    10831                 }
    10832                 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
    10833                 {
    10834                         return is_subclass_of($class1, $class2);
    10835                 }
    10836                 elseif (is_string($class1) && is_string($class2))
    10837                 {
    10838                         if (class_exists($class1))
    10839                         {
    10840                                 if (class_exists($class2))
    10841                                 {
    10842                                         $class2 = strtolower($class2);
    10843                                         while ($class1 = strtolower(get_parent_class($class1)))
    10844                                         {
    10845                                                 if ($class1 === $class2)
    10846                                                 {
    10847                                                         return true;
    10848                                                 }
    10849                                         }
    10850                                 }
    10851                         }
    10852                         else
    10853                         {
    10854                                 trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
    10855                         }
    10856                 }
    10857                 return false;
    10858         }
    10859 
    10860         /**
    10861          * Strip HTML comments
    10862          *
    10863          * @access public
    10864          * @param string $data Data to strip comments from
    10865          * @return string Comment stripped string
    10866          */
    10867         function strip_comments($data)
    10868         {
    10869                 $output = '';
    10870                 while (($start = strpos($data, '<!--')) !== false)
    10871                 {
    10872                         $output .= substr($data, 0, $start);
    10873                         if (($end = strpos($data, '-->', $start)) !== false)
    10874                         {
    10875                                 $data = substr_replace($data, '', 0, $end + 3);
    10876                         }
    10877                         else
    10878                         {
    10879                                 $data = '';
    10880                         }
    10881                 }
    10882                 return $output . $data;
    10883         }
    10884 
    10885         function parse_date($dt)
    10886         {
    10887                 $parser = SimplePie_Parse_Date::get();
    10888                 return $parser->parse($dt);
    10889         }
    10890 
    10891         /**
    10892          * Decode HTML entities
    10893          *
    10894          * @static
    10895          * @access public
    10896          * @param string $data Input data
    10897          * @return string Output data
    10898          */
    10899         function entities_decode($data)
    10900         {
    10901                 $decoder =& new SimplePie_Decode_HTML_Entities($data);
    10902                 return $decoder->parse();
    10903         }
    10904 
    10905         /**
    10906          * Remove RFC822 comments
    10907          *
    10908          * @access public
    10909          * @param string $data Data to strip comments from
    10910          * @return string Comment stripped string
    10911          */
    10912         function uncomment_rfc822($string)
    10913         {
    10914                 $string = (string) $string;
    10915                 $position = 0;
    10916                 $length = strlen($string);
    10917                 $depth = 0;
    10918 
    10919                 $output = '';
    10920 
    10921                 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
    10922                 {
    10923                         $output .= substr($string, $position, $pos - $position);
    10924                         $position = $pos + 1;
    10925                         if ($string[$pos - 1] !== '\\')
    10926                         {
    10927                                 $depth++;
    10928                                 while ($depth && $position < $length)
    10929                                 {
    10930                                         $position += strcspn($string, '()', $position);
    10931                                         if ($string[$position - 1] === '\\')
    10932                                         {
    10933                                                 $position++;
    10934                                                 continue;
    10935                                         }
    10936                                         elseif (isset($string[$position]))
    10937                                         {
    10938                                                 switch ($string[$position])
    10939                                                 {
    10940                                                         case '(':
    10941                                                                 $depth++;
    10942                                                                 break;
    10943 
    10944                                                         case ')':
    10945                                                                 $depth--;
    10946                                                                 break;
    10947                                                 }
    10948                                                 $position++;
    10949                                         }
    10950                                         else
    10951                                         {
    10952                                                 break;
    10953                                         }
    10954                                 }
    10955                         }
    10956                         else
    10957                         {
    10958                                 $output .= '(';
    10959                         }
    10960                 }
    10961                 $output .= substr($string, $position);
    10962 
    10963                 return $output;
    10964         }
    10965 
    10966         function parse_mime($mime)
    10967         {
    10968                 if (($pos = strpos($mime, ';')) === false)
    10969                 {
    10970                         return trim($mime);
    10971                 }
    10972                 else
    10973                 {
    10974                         return trim(substr($mime, 0, $pos));
    10975                 }
    10976         }
    10977 
    10978         function htmlspecialchars_decode($string, $quote_style)
    10979         {
    10980                 if (function_exists('htmlspecialchars_decode'))
    10981                 {
    10982                         return htmlspecialchars_decode($string, $quote_style);
    10983                 }
    10984                 else
    10985                 {
    10986                         return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
    10987                 }
    10988         }
    10989 
    10990         function atom_03_construct_type($attribs)
    10991         {
    10992                 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
    10993                 {
    10994                         $mode = SIMPLEPIE_CONSTRUCT_BASE64;
    10995                 }
    10996                 else
    10997                 {
    10998                         $mode = SIMPLEPIE_CONSTRUCT_NONE;
    10999                 }
    11000                 if (isset($attribs['']['type']))
    11001                 {
    11002                         switch (strtolower(trim($attribs['']['type'])))
    11003                         {
    11004                                 case 'text':
    11005                                 case 'text/plain':
    11006                                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
    11007 
    11008                                 case 'html':
    11009                                 case 'text/html':
    11010                                         return SIMPLEPIE_CONSTRUCT_HTML | $mode;
    11011 
    11012                                 case 'xhtml':
    11013                                 case 'application/xhtml+xml':
    11014                                         return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
    11015 
    11016                                 default:
    11017                                         return SIMPLEPIE_CONSTRUCT_NONE | $mode;
    11018                         }
    11019                 }
    11020                 else
    11021                 {
    11022                         return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
    11023                 }
    11024         }
    11025 
    11026         function atom_10_construct_type($attribs)
    11027         {
    11028                 if (isset($attribs['']['type']))
    11029                 {
    11030                         switch (strtolower(trim($attribs['']['type'])))
    11031                         {
    11032                                 case 'text':
    11033                                         return SIMPLEPIE_CONSTRUCT_TEXT;
    11034 
    11035                                 case 'html':
    11036                                         return SIMPLEPIE_CONSTRUCT_HTML;
    11037 
    11038                                 case 'xhtml':
    11039                                         return SIMPLEPIE_CONSTRUCT_XHTML;
    11040 
    11041                                 default:
    11042                                         return SIMPLEPIE_CONSTRUCT_NONE;
    11043                         }
    11044                 }
    11045                 return SIMPLEPIE_CONSTRUCT_TEXT;
    11046         }
    11047 
    11048         function atom_10_content_construct_type($attribs)
    11049         {
    11050                 if (isset($attribs['']['type']))
    11051                 {
    11052                         $type = strtolower(trim($attribs['']['type']));
    11053                         switch ($type)
    11054                         {
    11055                                 case 'text':
    11056                                         return SIMPLEPIE_CONSTRUCT_TEXT;
    11057 
    11058                                 case 'html':
    11059                                         return SIMPLEPIE_CONSTRUCT_HTML;
    11060 
    11061                                 case 'xhtml':
    11062                                         return SIMPLEPIE_CONSTRUCT_XHTML;
    11063                         }
    11064                         if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
    11065                         {
    11066                                 return SIMPLEPIE_CONSTRUCT_NONE;
    11067                         }
    11068                         else
    11069                         {
    11070                                 return SIMPLEPIE_CONSTRUCT_BASE64;
    11071                         }
    11072                 }
    11073                 else
    11074                 {
    11075                         return SIMPLEPIE_CONSTRUCT_TEXT;
    11076                 }
    11077         }
    11078 
    11079         function is_isegment_nz_nc($string)
    11080         {
    11081                 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);
    11082         }
    11083 
    11084         function space_seperated_tokens($string)
    11085         {
    11086                 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
    11087                 $string_length = strlen($string);
    11088 
    11089                 $position = strspn($string, $space_characters);
    11090                 $tokens = array();
    11091 
    11092                 while ($position < $string_length)
    11093                 {
    11094                         $len = strcspn($string, $space_characters, $position);
    11095                         $tokens[] = substr($string, $position, $len);
    11096                         $position += $len;
    11097                         $position += strspn($string, $space_characters, $position);
    11098                 }
    11099 
    11100                 return $tokens;
    11101         }
    11102 
    11103         function array_unique($array)
    11104         {
    11105                 if (version_compare(PHP_VERSION, '5.2', '>='))
    11106                 {
    11107                         return array_unique($array);
    11108                 }
    11109                 else
    11110                 {
    11111                         $array = (array) $array;
    11112                         $new_array = array();
    11113                         $new_array_strings = array();
    11114                         foreach ($array as $key => $value)
    11115                         {
    11116                                 if (is_object($value))
    11117                                 {
    11118                                         if (method_exists($value, '__toString'))
    11119                                         {
    11120                                                 $cmp = $value->__toString();
    11121                                         }
    11122                                         else
    11123                                         {
    11124                                                 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
    11125                                         }
    11126                                 }
    11127                                 elseif (is_array($value))
    11128                                 {
    11129                                         $cmp = (string) reset($value);
    11130                                 }
    11131                                 else
    11132                                 {
    11133                                         $cmp = (string) $value;
    11134                                 }
    11135                                 if (!in_array($cmp, $new_array_strings))
    11136                                 {
    11137                                         $new_array[$key] = $value;
    11138                                         $new_array_strings[] = $cmp;
    11139                                 }
    11140                         }
    11141                         return $new_array;
    11142                 }
    11143         }
    11144 
    11145         /**
    11146          * Converts a unicode codepoint to a UTF-8 character
    11147          *
    11148          * @static
    11149          * @access public
    11150          * @param int $codepoint Unicode codepoint
    11151          * @return string UTF-8 character
    11152          */
    11153         function codepoint_to_utf8($codepoint)
    11154         {
    11155                 $codepoint = (int) $codepoint;
    11156                 if ($codepoint < 0)
    11157                 {
    11158                         return false;
    11159                 }
    11160                 else if ($codepoint <= 0x7f)
    11161                 {
    11162                         return chr($codepoint);
    11163                 }
    11164                 else if ($codepoint <= 0x7ff)
    11165                 {
    11166                         return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
    11167                 }
    11168                 else if ($codepoint <= 0xffff)
    11169                 {
    11170                         return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
    11171                 }
    11172                 else if ($codepoint <= 0x10ffff)
    11173                 {
    11174                         return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
    11175                 }
    11176                 else
    11177                 {
    11178                         // U+FFFD REPLACEMENT CHARACTER
    11179                         return "\xEF\xBF\xBD";
    11180                 }
    11181         }
    11182 
    11183         /**
    11184          * Re-implementation of PHP 5's stripos()
    11185          *
    11186          * Returns the numeric position of the first occurrence of needle in the
    11187          * haystack string.
    11188          *
    11189          * @static
    11190          * @access string
    11191          * @param object $haystack
    11192          * @param string $needle Note that the needle may be a string of one or more
    11193          *     characters. If needle is not a string, it is converted to an integer
    11194          *     and applied as the ordinal value of a character.
    11195          * @param int $offset The optional offset parameter allows you to specify which
    11196          *     character in haystack to start searching. The position returned is still
    11197          *     relative to the beginning of haystack.
    11198          * @return bool If needle is not found, stripos() will return boolean false.
    11199          */
    11200         function stripos($haystack, $needle, $offset = 0)
    11201         {
    11202                 if (function_exists('stripos'))
    11203                 {
    11204                         return stripos($haystack, $needle, $offset);
    11205                 }
    11206                 else
    11207                 {
    11208                         if (is_string($needle))
    11209                         {
    11210                                 $needle = strtolower($needle);
    11211                         }
    11212                         elseif (is_int($needle) || is_bool($needle) || is_double($needle))
    11213                         {
    11214                                 $needle = strtolower(chr($needle));
    11215                         }
    11216                         else
    11217                         {
    11218                                 trigger_error('needle is not a string or an integer', E_USER_WARNING);
    11219                                 return false;
    11220                         }
    11221 
    11222                         return strpos(strtolower($haystack), $needle, $offset);
    11223                 }
    11224         }
    11225 
    11226         /**
    11227          * Similar to parse_str()
    11228          *
    11229          * Returns an associative array of name/value pairs, where the value is an
    11230          * array of values that have used the same name
    11231          *
    11232          * @static
    11233          * @access string
    11234          * @param string $str The input string.
    11235          * @return array
    11236          */
    11237         function parse_str($str)
    11238         {
    11239                 $return = array();
    11240                 $str = explode('&', $str);
    11241 
    11242                 foreach ($str as $section)
    11243                 {
    11244                         if (strpos($section, '=') !== false)
    11245                         {
    11246                                 list($name, $value) = explode('=', $section, 2);
    11247                                 $return[urldecode($name)][] = urldecode($value);
    11248                         }
    11249                         else
    11250                         {
    11251                                 $return[urldecode($section)][] = null;
    11252                         }
    11253                 }
    11254 
    11255                 return $return;
    11256         }
    11257 
    11258         /**
    11259          * Detect XML encoding, as per XML 1.0 Appendix F.1
    11260          *
    11261          * @todo Add support for EBCDIC
    11262          * @param string $data XML data
    11263          * @return array Possible encodings
    11264          */
    11265         function xml_encoding($data)
    11266         {
    11267                 // UTF-32 Big Endian BOM
    11268                 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
    11269                 {
    11270                         $encoding[] = 'UTF-32BE';
    11271                 }
    11272                 // UTF-32 Little Endian BOM
    11273                 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
    11274                 {
    11275                         $encoding[] = 'UTF-32LE';
    11276                 }
    11277                 // UTF-16 Big Endian BOM
    11278                 elseif (substr($data, 0, 2) === "\xFE\xFF")
    11279                 {
    11280                         $encoding[] = 'UTF-16BE';
    11281                 }
    11282                 // UTF-16 Little Endian BOM
    11283                 elseif (substr($data, 0, 2) === "\xFF\xFE")
    11284                 {
    11285                         $encoding[] = 'UTF-16LE';
    11286                 }
    11287                 // UTF-8 BOM
    11288                 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
    11289                 {
    11290                         $encoding[] = 'UTF-8';
    11291                 }
    11292                 // UTF-32 Big Endian Without BOM
    11293                 elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
    11294                 {
    11295                         if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
    11296                         {
    11297                                 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
    11298                                 if ($parser->parse())
    11299                                 {
    11300                                         $encoding[] = $parser->encoding;
    11301                                 }
    11302                         }
    11303                         $encoding[] = 'UTF-32BE';
    11304                 }
    11305                 // UTF-32 Little Endian Without BOM
    11306                 elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
    11307                 {
    11308                         if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
    11309                         {
    11310                                 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
    11311                                 if ($parser->parse())
    11312                                 {
    11313                                         $encoding[] = $parser->encoding;
    11314                                 }
    11315                         }
    11316                         $encoding[] = 'UTF-32LE';
    11317                 }
    11318                 // UTF-16 Big Endian Without BOM
    11319                 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
    11320                 {
    11321                         if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
    11322                         {
    11323                                 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
    11324                                 if ($parser->parse())
    11325                                 {
    11326                                         $encoding[] = $parser->encoding;
    11327                                 }
    11328                         }
    11329                         $encoding[] = 'UTF-16BE';
    11330                 }
    11331                 // UTF-16 Little Endian Without BOM
    11332                 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
    11333                 {
    11334                         if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
    11335                         {
    11336                                 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
    11337                                 if ($parser->parse())
    11338                                 {
    11339                                         $encoding[] = $parser->encoding;
    11340                                 }
    11341                         }
    11342                         $encoding[] = 'UTF-16LE';
    11343                 }
    11344                 // US-ASCII (or superset)
    11345                 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
    11346                 {
    11347                         if ($pos = strpos($data, "\x3F\x3E"))
    11348                         {
    11349                                 $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
    11350                                 if ($parser->parse())
    11351                                 {
    11352                                         $encoding[] = $parser->encoding;
    11353                                 }
    11354                         }
    11355                         $encoding[] = 'UTF-8';
    11356                 }
    11357                 // Fallback to UTF-8
    11358                 else
    11359                 {
    11360                         $encoding[] = 'UTF-8';
    11361                 }
    11362                 return $encoding;
    11363         }
    11364 
    11365         function output_javascript()
    11366         {
    11367                 if (function_exists('ob_gzhandler'))
    11368                 {
    11369                         ob_start('ob_gzhandler');
    11370                 }
    11371                 header('Content-type: text/javascript; charset: UTF-8');
    11372                 header('Cache-Control: must-revalidate');
    11373                 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
    11374                 ?>
    11375 function embed_odeo(link) {
    11376         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>');
    11377 }
    11378 
    11379 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
    11380         if (placeholder != '') {
    11381                 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>');
    11382         }
    11383         else {
    11384                 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>');
    11385         }
    11386 }
    11387 
    11388 function embed_flash(bgcolor, width, height, link, loop, type) {
    11389         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>');
    11390 }
    11391 
    11392 function embed_flv(width, height, link, placeholder, loop, player) {
    11393         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>');
    11394 }
    11395 
    11396 function embed_wmedia(width, height, link) {
    11397         document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
    11398 }
    11399                 <?php
    11400         }
    11401 
    11402 
    11403 
    11404         /**
    11405          * Format debugging information
    11406          */
    11407         function debug($sp)
    11408         {
    11409                 $info = 'SimplePie ' . SIMPLEPIE_VERSION . ' Build ' . SIMPLEPIE_BUILD . "\n";
    11410                 $info .= 'PHP ' . PHP_VERSION . "\n";
    11411                 if ($sp->error() !== null)
    11412                 {
    11413                         $info .= 'Error occurred: ' . $sp->error() . "\n";
    11414                 }
    11415                 else
    11416                 {
    11417                         $info .= "No error found.\n";
    11418                 }
    11419                 $info .= "Extensions:\n";
    11420                 $extensions = array('pcre', 'curl', 'zlib', 'mbstring', 'iconv', 'xmlreader', 'xml');
    11421                 foreach ($extensions as $ext)
    11422                 {
    11423                         if (extension_loaded($ext))
    11424                         {
    11425                                 $info .= "    $ext loaded\n";
    11426                                 switch ($ext)
    11427                                 {
    11428                                         case 'pcre':
    11429                                                 $info .= '      Version ' . PCRE_VERSION . "\n";
    11430                                                 break;
    11431                                         case 'curl':
    11432                                                 $version = curl_version();
    11433                                                 $info .= '      Version ' . $version['version'] . "\n";
    11434                                                 break;
    11435                                         case 'mbstring':
    11436                                                 $info .= '      Overloading: ' . mb_get_info('func_overload') . "\n";
    11437                                                 break;
    11438                                         case 'iconv':
    11439                                                 $info .= '      Version ' . ICONV_VERSION . "\n";
    11440                                                 break;
    11441                                         case 'xml':
    11442                                                 $info .= '      Version ' . LIBXML_DOTTED_VERSION . "\n";
    11443                                                 break;
    11444                                 }
    11445                         }
    11446                         else
    11447                         {
    11448                                 $info .= "    $ext not loaded\n";
    11449                         }
    11450                 }
    11451                 return $info;
    11452         }
    11453 }
    11454 
    11455 /**
    11456  * Decode HTML Entities
    11457  *
    11458  * This implements HTML5 as of revision 967 (2007-06-28)
    11459  *
    11460  * @package SimplePie
    11461  */
    11462 class SimplePie_Decode_HTML_Entities
    11463 {
    11464         /**
    11465          * Data to be parsed
    11466          *
    11467          * @access private
    11468          * @var string
    11469          */
    11470         var $data = '';
    11471 
    11472         /**
    11473          * Currently consumed bytes
    11474          *
    11475          * @access private
    11476          * @var string
    11477          */
    11478         var $consumed = '';
    11479 
    11480         /**
    11481          * Position of the current byte being parsed
    11482          *
    11483          * @access private
    11484          * @var int
    11485          */
    11486         var $position = 0;
    11487 
    11488         /**
    11489          * Create an instance of the class with the input data
    11490          *
    11491          * @access public
    11492          * @param string $data Input data
    11493          */
    11494         function SimplePie_Decode_HTML_Entities($data)
    11495         {
    11496                 $this->data = $data;
    11497         }
    11498 
    11499         /**
    11500          * Parse the input data
    11501          *
    11502          * @access public
    11503          * @return string Output data
    11504          */
    11505         function parse()
    11506         {
    11507                 while (($this->position = strpos($this->data, '&', $this->position)) !== false)
    11508                 {
    11509                         $this->consume();
    11510                         $this->entity();
    11511                         $this->consumed = '';
    11512                 }
    11513                 return $this->data;
    11514         }
    11515 
    11516         /**
    11517          * Consume the next byte
    11518          *
    11519          * @access private
    11520          * @return mixed The next byte, or false, if there is no more data
    11521          */
    11522         function consume()
    11523         {
    11524                 if (isset($this->data[$this->position]))
    11525                 {
    11526                         $this->consumed .= $this->data[$this->position];
    11527                         return $this->data[$this->position++];
    11528                 }
    11529                 else
    11530                 {
    11531                         return false;
    11532                 }
    11533         }
    11534 
    11535         /**
    11536          * Consume a range of characters
    11537          *
    11538          * @access private
    11539          * @param string $chars Characters to consume
    11540          * @return mixed A series of characters that match the range, or false
    11541          */
    11542         function consume_range($chars)
    11543         {
    11544                 if ($len = strspn($this->data, $chars, $this->position))
    11545                 {
    11546                         $data = substr($this->data, $this->position, $len);
    11547                         $this->consumed .= $data;
    11548                         $this->position += $len;
    11549                         return $data;
    11550                 }
    11551                 else
    11552                 {
    11553                         return false;
    11554                 }
    11555         }
    11556 
    11557         /**
    11558          * Unconsume one byte
    11559          *
    11560          * @access private
    11561          */
    11562         function unconsume()
    11563         {
    11564                 $this->consumed = substr($this->consumed, 0, -1);
    11565                 $this->position--;
    11566         }
    11567 
    11568         /**
    11569          * Decode an entity
    11570          *
    11571          * @access private
    11572          */
    11573         function entity()
    11574         {
    11575                 switch ($this->consume())
    11576                 {
    11577                         case "\x09":
    11578                         case "\x0A":
    11579                         case "\x0B":
    11580                         case "\x0B":
    11581                         case "\x0C":
    11582                         case "\x20":
    11583                         case "\x3C":
    11584                         case "\x26":
    11585                         case false:
    11586                                 break;
    11587 
    11588                         case "\x23":
    11589                                 switch ($this->consume())
    11590                                 {
    11591                                         case "\x78":
    11592                                         case "\x58":
    11593                                                 $range = '0123456789ABCDEFabcdef';
    11594                                                 $hex = true;
    11595                                                 break;
    11596 
    11597                                         default:
    11598                                                 $range = '0123456789';
    11599                                                 $hex = false;
    11600                                                 $this->unconsume();
    11601                                                 break;
    11602                                 }
    11603 
    11604                                 if ($codepoint = $this->consume_range($range))
    11605                                 {
    11606                                         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");
    11607 
    11608                                         if ($hex)
    11609                                         {
    11610                                                 $codepoint = hexdec($codepoint);
    11611                                         }
    11612                                         else
    11613                                         {
    11614                                                 $codepoint = intval($codepoint);
    11615                                         }
    11616 
    11617                                         if (isset($windows_1252_specials[$codepoint]))
    11618                                         {
    11619                                                 $replacement = $windows_1252_specials[$codepoint];
    11620                                         }
    11621                                         else
    11622                                         {
    11623                                                 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
    11624                                         }
    11625 
    11626                                         if (!in_array($this->consume(), array(';', false), true))
    11627                                         {
    11628                                                 $this->unconsume();
    11629                                         }
    11630 
    11631                                         $consumed_length = strlen($this->consumed);
    11632                                         $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
    11633                                         $this->position += strlen($replacement) - $consumed_length;
    11634                                 }
    11635                                 break;
    11636 
    11637                         default:
    11638                                 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");
    11639 
    11640                                 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
    11641                                 {
    11642                                         $consumed = substr($this->consumed, 1);
    11643                                         if (isset($entities[$consumed]))
    11644                                         {
    11645                                                 $match = $consumed;
    11646                                         }
    11647                                 }
    11648 
    11649                                 if ($match !== null)
    11650                                 {
    11651                                         $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
    11652                                         $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
    11653                                 }
    11654                                 break;
    11655                 }
    11656         }
    11657 }
    11658 
    11659 /**
    11660  * IRI parser/serialiser
    11661  *
    11662  * @package SimplePie
    11663  */
    11664 class SimplePie_IRI
    11665 {
    11666         /**
    11667          * Scheme
    11668          *
    11669          * @access private
    11670          * @var string
    11671          */
    11672         var $scheme;
    11673 
    11674         /**
    11675          * User Information
    11676          *
    11677          * @access private
    11678          * @var string
    11679          */
    11680         var $userinfo;
    11681 
    11682         /**
    11683          * Host
    11684          *
    11685          * @access private
    11686          * @var string
    11687          */
    11688         var $host;
    11689 
    11690         /**
    11691          * Port
    11692          *
    11693          * @access private
    11694          * @var string
    11695          */
    11696         var $port;
    11697 
    11698         /**
    11699          * Path
    11700          *
    11701          * @access private
    11702          * @var string
    11703          */
    11704         var $path;
    11705 
    11706         /**
    11707          * Query
    11708          *
    11709          * @access private
    11710          * @var string
    11711          */
    11712         var $query;
    11713 
    11714         /**
    11715          * Fragment
    11716          *
    11717          * @access private
    11718          * @var string
    11719          */
    11720         var $fragment;
    11721 
    11722         /**
    11723          * Whether the object represents a valid IRI
    11724          *
    11725          * @access private
    11726          * @var array
    11727          */
    11728         var $valid = array();
    11729 
    11730         /**
    11731          * Return the entire IRI when you try and read the object as a string
    11732          *
    11733          * @access public
    11734          * @return string
    11735          */
    11736         function __toString()
    11737         {
    11738                 return $this->get_iri();
    11739         }
    11740 
    11741         /**
    11742          * Create a new IRI object, from a specified string
    11743          *
    11744          * @access public
    11745          * @param string $iri
    11746          * @return SimplePie_IRI
    11747          */
    11748         function SimplePie_IRI($iri)
    11749         {
    11750                 $iri = (string) $iri;
    11751                 if ($iri !== '')
    11752                 {
    11753                         $parsed = $this->parse_iri($iri);
    11754                         $this->set_scheme($parsed['scheme']);
    11755                         $this->set_authority($parsed['authority']);
    11756                         $this->set_path($parsed['path']);
    11757                         $this->set_query($parsed['query']);
    11758                         $this->set_fragment($parsed['fragment']);
    11759                 }
    11760         }
    11761 
    11762         /**
    11763          * Create a new IRI object by resolving a relative IRI
    11764          *
    11765          * @static
    11766          * @access public
    11767          * @param SimplePie_IRI $base Base IRI
    11768          * @param string $relative Relative IRI
    11769          * @return SimplePie_IRI
    11770          */
    11771         function absolutize($base, $relative)
    11772         {
    11773                 $relative = (string) $relative;
    11774                 if ($relative !== '')
    11775                 {
    11776                         $relative =& new SimplePie_IRI($relative);
    11777                         if ($relative->get_scheme() !== null)
    11778                         {
    11779                                 $target = $relative;
    11780                         }
    11781                         elseif ($base->get_iri() !== null)
    11782                         {
    11783                                 if ($relative->get_authority() !== null)
    11784                                 {
    11785                                         $target = $relative;
    11786                                         $target->set_scheme($base->get_scheme());
    11787                                 }
    11788                                 else
    11789                                 {
    11790                                         $target =& new SimplePie_IRI('');
    11791                                         $target->set_scheme($base->get_scheme());
    11792                                         $target->set_userinfo($base->get_userinfo());
    11793                                         $target->set_host($base->get_host());
    11794                                         $target->set_port($base->get_port());
    11795                                         if ($relative->get_path() !== null)
    11796                                         {
    11797                                                 if (strpos($relative->get_path(), '/') === 0)
    11798                                                 {
    11799                                                         $target->set_path($relative->get_path());
    11800                                                 }
    11801                                                 elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
    11802                                                 {
    11803                                                         $target->set_path('/' . $relative->get_path());
    11804                                                 }
    11805                                                 elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
    11806                                                 {
    11807                                                         $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
    11808                                                 }
    11809                                                 else
    11810                                                 {
    11811                                                         $target->set_path($relative->get_path());
    11812                                                 }
    11813                                                 $target->set_query($relative->get_query());
    11814                                         }
    11815                                         else
    11816                                         {
    11817                                                 $target->set_path($base->get_path());
    11818                                                 if ($relative->get_query() !== null)
    11819                                                 {
    11820                                                         $target->set_query($relative->get_query());
    11821                                                 }
    11822                                                 elseif ($base->get_query() !== null)
    11823                                                 {
    11824                                                         $target->set_query($base->get_query());
    11825                                                 }
    11826                                         }
    11827                                 }
    11828                                 $target->set_fragment($relative->get_fragment());
    11829                         }
    11830                         else
    11831                         {
    11832                                 // No base URL, just return the relative URL
    11833                                 $target = $relative;
    11834                         }
    11835                 }
    11836                 else
    11837                 {
    11838                         $target = $base;
    11839                 }
    11840                 return $target;
    11841         }
    11842 
    11843         /**
    11844          * Parse an IRI into scheme/authority/path/query/fragment segments
    11845          *
    11846          * @access private
    11847          * @param string $iri
    11848          * @return array
    11849          */
    11850         function parse_iri($iri)
    11851         {
    11852                 preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
    11853                 for ($i = count($match); $i <= 9; $i++)
    11854                 {
    11855                         $match[$i] = '';
    11856                 }
    11857                 return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
    11858         }
    11859 
    11860         /**
    11861          * Remove dot segments from a path
    11862          *
    11863          * @access private
    11864          * @param string $input
    11865          * @return string
    11866          */
    11867         function remove_dot_segments($input)
    11868         {
    11869                 $output = '';
    11870                 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
    11871                 {
    11872                         // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
    11873                         if (strpos($input, '../') === 0)
    11874                         {
    11875                                 $input = substr($input, 3);
    11876                         }
    11877                         elseif (strpos($input, './') === 0)
    11878                         {
    11879                                 $input = substr($input, 2);
    11880                         }
    11881                         // 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,
    11882                         elseif (strpos($input, '/./') === 0)
    11883                         {
    11884                                 $input = substr_replace($input, '/', 0, 3);
    11885                         }
    11886                         elseif ($input === '/.')
    11887                         {
    11888                                 $input = '/';
    11889                         }
    11890                         // 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,
    11891                         elseif (strpos($input, '/../') === 0)
    11892                         {
    11893                                 $input = substr_replace($input, '/', 0, 4);
    11894                                 $output = substr_replace($output, '', strrpos($output, '/'));
    11895                         }
    11896                         elseif ($input === '/..')
    11897                         {
    11898                                 $input = '/';
    11899                                 $output = substr_replace($output, '', strrpos($output, '/'));
    11900                         }
    11901                         // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
    11902                         elseif ($input === '.' || $input === '..')
    11903                         {
    11904                                 $input = '';
    11905                         }
    11906                         // 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
    11907                         elseif (($pos = strpos($input, '/', 1)) !== false)
    11908                         {
    11909                                 $output .= substr($input, 0, $pos);
    11910                                 $input = substr_replace($input, '', 0, $pos);
    11911                         }
    11912                         else
    11913                         {
    11914                                 $output .= $input;
    11915                                 $input = '';
    11916                         }
    11917                 }
    11918                 return $output . $input;
    11919         }
    11920 
    11921         /**
    11922          * Replace invalid character with percent encoding
    11923          *
    11924          * @param string $string Input string
    11925          * @param string $valid_chars Valid characters
    11926          * @param int $case Normalise case
    11927          * @return string
    11928          */
    11929         function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE, $iprivate = false)
    11930         {
    11931                 // Normalize as many pct-encoded sections as possible
    11932                 $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array(&$this, 'remove_iunreserved_percent_encoded'), $string);
    11933 
    11934                 // Replace invalid percent characters
    11935                 $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
    11936 
    11937                 // Add unreserved and % to $valid_chars (the latter is safe because all
    11938                 // pct-encoded sections are now valid).
    11939                 $valid_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
    11940 
    11941                 // Now replace any bytes that aren't allowed with their pct-encoded versions
    11942                 $position = 0;
    11943                 $strlen = strlen($string);
    11944                 while (($position += strspn($string, $valid_chars, $position)) < $strlen)
    11945                 {
    11946                         $value = ord($string[$position]);
    11947 
    11948                         // Start position
    11949                         $start = $position;
    11950 
    11951                         // By default we are valid
    11952                         $valid = true;
    11953 
    11954                         // No one byte sequences are valid due to the while.
    11955                         // Two byte sequence:
    11956                         if (($value & 0xE0) === 0xC0)
    11957                         {
    11958                                 $character = ($value & 0x1F) << 6;
    11959                                 $length = 2;
    11960                                 $remaining = 1;
    11961                         }
    11962                         // Three byte sequence:
    11963                         elseif (($value & 0xF0) === 0xE0)
    11964                         {
    11965                                 $character = ($value & 0x0F) << 12;
    11966                                 $length = 3;
    11967                                 $remaining = 2;
    11968                         }
    11969                         // Four byte sequence:
    11970                         elseif (($value & 0xF8) === 0xF0)
    11971                         {
    11972                                 $character = ($value & 0x07) << 18;
    11973                                 $length = 4;
    11974                                 $remaining = 3;
    11975                         }
    11976                         // Invalid byte:
    11977                         else
    11978                         {
    11979                                 $valid = false;
    11980                                 $length = 1;
    11981                                 $remaining = 0;
    11982                         }
    11983 
    11984                         if ($remaining)
    11985                         {
    11986                                 if ($position + $length <= $strlen)
    11987                                 {
    11988                                         for ($position++; $remaining; $position++)
    11989                                         {
    11990                                                 $value = ord($string[$position]);
    11991 
    11992                                                 // Check that the byte is valid, then add it to the character:
    11993                                                 if (($value & 0xC0) === 0x80)
    11994                                                 {
    11995                                                         $character |= ($value & 0x3F) << (--$remaining * 6);
    11996                                                 }
    11997                                                 // If it is invalid, count the sequence as invalid and reprocess the current byte:
    11998                                                 else
    11999                                                 {
    12000                                                         $valid = false;
    12001                                                         $position--;
    12002                                                         break;
    12003                                                 }
    12004                                         }
    12005                                 }
    12006                                 else
    12007                                 {
    12008                                         $position = $strlen - 1;
    12009                                         $valid = false;
    12010                                 }
    12011                         }
    12012 
    12013                         // Percent encode anything invalid or not in ucschar
    12014                         if (
    12015                                 // Invalid sequences
    12016                                 !$valid
    12017                                 // Non-shortest form sequences are invalid
    12018                                 || $length > 1 && $character <= 0x7F
    12019                                 || $length > 2 && $character <= 0x7FF
    12020                                 || $length > 3 && $character <= 0xFFFF
    12021                                 // Outside of range of ucschar codepoints
    12022                                 // Noncharacters
    12023                                 || ($character & 0xFFFE) === 0xFFFE
    12024                                 || $character >= 0xFDD0 && $character <= 0xFDEF
    12025                                 || (
    12026                                         // Everything else not in ucschar
    12027                                            $character > 0xD7FF && $character < 0xF900
    12028                                         || $character < 0xA0
    12029                                         || $character > 0xEFFFD
    12030                                 )
    12031                                 && (
    12032                                         // Everything not in iprivate, if it applies
    12033                                            !$iprivate
    12034                                         || $character < 0xE000
    12035                                         || $character > 0x10FFFD
    12036                                 )
    12037                         )
    12038                         {
    12039                                 // If we were a character, pretend we weren't, but rather an error.
    12040                                 if ($valid)
    12041                                         $position--;
    12042 
    12043                                 for ($j = $start; $j <= $position; $j++)
    12044                                 {
    12045                                         $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
    12046                                         $j += 2;
    12047                                         $position += 2;
    12048                                         $strlen += 2;
    12049                                 }
    12050                         }
    12051                 }
    12052 
    12053                 // Normalise case
    12054                 if ($case & SIMPLEPIE_LOWERCASE)
    12055                 {
    12056                         $string = strtolower($string);
    12057                 }
    12058                 elseif ($case & SIMPLEPIE_UPPERCASE)
    12059                 {
    12060                         $string = strtoupper($string);
    12061                 }
    12062 
    12063                 return $string;
    12064         }
    12065 
    12066         /**
    12067          * Callback function for preg_replace_callback.
    12068          *
    12069          * Removes sequences of percent encoded bytes that represent UTF-8
    12070          * encoded characters in iunreserved
    12071          *
    12072          * @access private
    12073          * @param array $match PCRE match
    12074          * @return string Replacement
    12075          */
    12076         function remove_iunreserved_percent_encoded($match)
    12077         {
    12078                 // As we just have valid percent encoded sequences we can just explode
    12079                 // and ignore the first member of the returned array (an empty string).
    12080                 $bytes = explode('%', $match[0]);
    12081 
    12082                 // Initialize the new string (this is what will be returned) and that
    12083                 // there are no bytes remaining in the current sequence (unsurprising
    12084                 // at the first byte!).
    12085                 $string = '';
    12086                 $remaining = 0;
    12087 
    12088                 // Loop over each and every byte, and set $value to its value
    12089                 for ($i = 1, $len = count($bytes); $i < $len; $i++)
    12090                 {
    12091                         $value = hexdec($bytes[$i]);
    12092 
    12093                         // If we're the first byte of sequence:
    12094                         if (!$remaining)
    12095                         {
    12096                                 // Start position
    12097                                 $start = $i;
    12098 
    12099                                 // By default we are valid
    12100                                 $valid = true;
    12101 
    12102                                 // One byte sequence:
    12103                                 if ($value <= 0x7F)
    12104                                 {
    12105                                         $character = $value;
    12106                                         $length = 1;
    12107                                 }
    12108                                 // Two byte sequence:
    12109                                 elseif (($value & 0xE0) === 0xC0)
    12110                                 {
    12111                                         $character = ($value & 0x1F) << 6;
    12112                                         $length = 2;
    12113                                         $remaining = 1;
    12114                                 }
    12115                                 // Three byte sequence:
    12116                                 elseif (($value & 0xF0) === 0xE0)
    12117                                 {
    12118                                         $character = ($value & 0x0F) << 12;
    12119                                         $length = 3;
    12120                                         $remaining = 2;
    12121                                 }
    12122                                 // Four byte sequence:
    12123                                 elseif (($value & 0xF8) === 0xF0)
    12124                                 {
    12125                                         $character = ($value & 0x07) << 18;
    12126                                         $length = 4;
    12127                                         $remaining = 3;
    12128                                 }
    12129                                 // Invalid byte:
    12130                                 else
    12131                                 {
    12132                                         $valid = false;
    12133                                         $remaining = 0;
    12134                                 }
    12135                         }
    12136                         // Continuation byte:
    12137                         else
    12138                         {
    12139                                 // Check that the byte is valid, then add it to the character:
    12140                                 if (($value & 0xC0) === 0x80)
    12141                                 {
    12142                                         $remaining--;
    12143                                         $character |= ($value & 0x3F) << ($remaining * 6);
    12144                                 }
    12145                                 // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
    12146                                 else
    12147                                 {
    12148                                         $valid = false;
    12149                                         $remaining = 0;
    12150                                         $i--;
    12151                                 }
    12152                         }
    12153 
    12154                         // If we've reached the end of the current byte sequence, append it to Unicode::$data
    12155                         if (!$remaining)
    12156                         {
    12157                                 // Percent encode anything invalid or not in iunreserved
    12158                                 if (
    12159                                         // Invalid sequences
    12160                                         !$valid
    12161                                         // Non-shortest form sequences are invalid
    12162                                         || $length > 1 && $character <= 0x7F
    12163                                         || $length > 2 && $character <= 0x7FF
    12164                                         || $length > 3 && $character <= 0xFFFF
    12165                                         // Outside of range of iunreserved codepoints
    12166                                         || $character < 0x2D
    12167                                         || $character > 0xEFFFD
    12168                                         // Noncharacters
    12169                                         || ($character & 0xFFFE) === 0xFFFE
    12170                                         || $character >= 0xFDD0 && $character <= 0xFDEF
    12171                                         // Everything else not in iunreserved (this is all BMP)
    12172                                         || $character === 0x2F
    12173                                         || $character > 0x39 && $character < 0x41
    12174                                         || $character > 0x5A && $character < 0x61
    12175                                         || $character > 0x7A && $character < 0x7E
    12176                                         || $character > 0x7E && $character < 0xA0
    12177                                         || $character > 0xD7FF && $character < 0xF900
    12178                                 )
    12179                                 {
    12180                                         for ($j = $start; $j <= $i; $j++)
    12181                                         {
    12182                                                 $string .= '%' . strtoupper($bytes[$j]);
    12183                                         }
    12184                                 }
    12185                                 else
    12186                                 {
    12187                                         for ($j = $start; $j <= $i; $j++)
    12188                                         {
    12189                                                 $string .= chr(hexdec($bytes[$j]));
    12190                                         }
    12191                                 }
    12192                         }
    12193                 }
    12194 
    12195                 // If we have any bytes left over they are invalid (i.e., we are
    12196                 // mid-way through a multi-byte sequence)
    12197                 if ($remaining)
    12198                 {
    12199                         for ($j = $start; $j < $len; $j++)
    12200                         {
    12201                                 $string .= '%' . strtoupper($bytes[$j]);
    12202                         }
    12203                 }
    12204 
    12205                 return $string;
    12206         }
    12207 
    12208         /**
    12209          * Check if the object represents a valid IRI
    12210          *
    12211          * @access public
    12212          * @return bool
    12213          */
    12214         function is_valid()
    12215         {
    12216                 return array_sum($this->valid) === count($this->valid);
    12217         }
    12218 
    12219         /**
    12220          * Set the scheme. Returns true on success, false on failure (if there are
    12221          * any invalid characters).
    12222          *
    12223          * @access public
    12224          * @param string $scheme
    12225          * @return bool
    12226          */
    12227         function set_scheme($scheme)
    12228         {
    12229                 if ($scheme === null || $scheme === '')
    12230                 {
    12231                         $this->scheme = null;
    12232                 }
    12233                 else
    12234                 {
    12235                         $len = strlen($scheme);
    12236                         switch (true)
    12237                         {
    12238                                 case $len > 1:
    12239                                         if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
    12240                                         {
    12241                                                 $this->scheme = null;
    12242                                                 $this->valid[__FUNCTION__] = false;
    12243                                                 return false;
    12244                                         }
    12245 
    12246                                 case $len > 0:
    12247                                         if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
    12248                                         {
    12249                                                 $this->scheme = null;
    12250                                                 $this->valid[__FUNCTION__] = false;
    12251                                                 return false;
    12252                                         }
    12253                         }
    12254                         $this->scheme = strtolower($scheme);
    12255                 }
    12256                 $this->valid[__FUNCTION__] = true;
    12257                 return true;
    12258         }
    12259 
    12260         /**
    12261          * Set the authority. Returns true on success, false on failure (if there are
    12262          * any invalid characters).
    12263          *
    12264          * @access public
    12265          * @param string $authority
    12266          * @return bool
    12267          */
    12268         function set_authority($authority)
    12269         {
    12270                 if (($userinfo_end = strrpos($authority, '@')) !== false)
    12271                 {
    12272                         $userinfo = substr($authority, 0, $userinfo_end);
    12273                         $authority = substr($authority, $userinfo_end + 1);
    12274                 }
    12275                 else
    12276                 {
    12277                         $userinfo = null;
    12278                 }
    12279 
    12280                 if (($port_start = strpos($authority, ':')) !== false)
    12281                 {
    12282                         $port = substr($authority, $port_start + 1);
    12283                         $authority = substr($authority, 0, $port_start);
    12284                 }
    12285                 else
    12286                 {
    12287                         $port = null;
    12288                 }
    12289 
    12290                 return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
    12291         }
    12292 
    12293         /**
    12294          * Set the userinfo.
    12295          *
    12296          * @access public
    12297          * @param string $userinfo
    12298          * @return bool
    12299          */
    12300         function set_userinfo($userinfo)
    12301         {
    12302                 if ($userinfo === null || $userinfo === '')
    12303                 {
    12304                         $this->userinfo = null;
    12305                 }
    12306                 else
    12307                 {
    12308                         $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
    12309                 }
    12310                 $this->valid[__FUNCTION__] = true;
    12311                 return true;
    12312         }
    12313 
    12314         /**
    12315          * Set the host. Returns true on success, false on failure (if there are
    12316          * any invalid characters).
    12317          *
    12318          * @access public
    12319          * @param string $host
    12320          * @return bool
    12321          */
    12322         function set_host($host)
    12323         {
    12324                 if ($host === null || $host === '')
    12325                 {
    12326                         $this->host = null;
    12327                         $this->valid[__FUNCTION__] = true;
    12328                         return true;
    12329                 }
    12330                 elseif ($host[0] === '[' && substr($host, -1) === ']')
    12331                 {
    12332                         if (SimplePie_Net_IPv6::checkIPv6(substr($host, 1, -1)))
    12333                         {
    12334                                 $this->host = $host;
    12335                                 $this->valid[__FUNCTION__] = true;
    12336                                 return true;
    12337                         }
    12338                         else
    12339                         {
    12340                                 $this->host = null;
    12341                                 $this->valid[__FUNCTION__] = false;
    12342                                 return false;
    12343                         }
    12344                 }
    12345                 else
    12346                 {
    12347                         $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
    12348                         $this->valid[__FUNCTION__] = true;
    12349                         return true;
    12350                 }
    12351         }
    12352 
    12353         /**
    12354          * Set the port. Returns true on success, false on failure (if there are
    12355          * any invalid characters).
    12356          *
    12357          * @access public
    12358          * @param string $port
    12359          * @return bool
    12360          */
    12361         function set_port($port)
    12362         {
    12363                 if ($port === null || $port === '')
    12364                 {
    12365                         $this->port = null;
    12366                         $this->valid[__FUNCTION__] = true;
    12367                         return true;
    12368                 }
    12369                 elseif (strspn($port, '0123456789') === strlen($port))
    12370                 {
    12371                         $this->port = (int) $port;
    12372                         $this->valid[__FUNCTION__] = true;
    12373                         return true;
    12374                 }
    12375                 else
    12376                 {
    12377                         $this->port = null;
    12378                         $this->valid[__FUNCTION__] = false;
    12379                         return false;
    12380                 }
    12381         }
    12382 
    12383         /**
    12384          * Set the path.
    12385          *
    12386          * @access public
    12387          * @param string $path
    12388          * @return bool
    12389          */
    12390         function set_path($path)
    12391         {
    12392                 if ($path === null || $path === '')
    12393                 {
    12394                         $this->path = null;
    12395                         $this->valid[__FUNCTION__] = true;
    12396                         return true;
    12397                 }
    12398                 elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
    12399                 {
    12400                         $this->path = null;
    12401                         $this->valid[__FUNCTION__] = false;
    12402                         return false;
    12403                 }
    12404                 else
    12405                 {
    12406                         $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
    12407                         if ($this->scheme !== null)
    12408                         {
    12409                                 $this->path = $this->remove_dot_segments($this->path);
    12410                         }
    12411                         $this->valid[__FUNCTION__] = true;
    12412                         return true;
    12413                 }
    12414         }
    12415 
    12416         /**
    12417          * Set the query.
    12418          *
    12419          * @access public
    12420          * @param string $query
    12421          * @return bool
    12422          */
    12423         function set_query($query)
    12424         {
    12425                 if ($query === null || $query === '')
    12426                 {
    12427                         $this->query = null;
    12428                 }
    12429                 else
    12430                 {
    12431                         $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?&=');
    12432                 }
    12433                 $this->valid[__FUNCTION__] = true;
    12434                 return true;
    12435         }
    12436 
    12437         /**
    12438          * Set the fragment.
    12439          *
    12440          * @access public
    12441          * @param string $fragment
    12442          * @return bool
    12443          */
    12444         function set_fragment($fragment)
    12445         {
    12446                 if ($fragment === null || $fragment === '')
    12447                 {
    12448                         $this->fragment = null;
    12449                 }
    12450                 else
    12451                 {
    12452                         $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
    12453                 }
    12454                 $this->valid[__FUNCTION__] = true;
    12455                 return true;
    12456         }
    12457 
    12458         /**
    12459          * Get the complete IRI
    12460          *
    12461          * @access public
    12462          * @return string
    12463          */
    12464         function get_iri()
    12465         {
    12466                 $iri = '';
    12467                 if ($this->scheme !== null)
    12468                 {
    12469                         $iri .= $this->scheme . ':';
    12470                 }
    12471                 if (($authority = $this->get_authority()) !== null)
    12472                 {
    12473                         $iri .= '//' . $authority;
    12474                 }
    12475                 if ($this->path !== null)
    12476                 {
    12477                         $iri .= $this->path;
    12478                 }
    12479                 if ($this->query !== null)
    12480                 {
    12481                         $iri .= '?' . $this->query;
    12482                 }
    12483                 if ($this->fragment !== null)
    12484                 {
    12485                         $iri .= '#' . $this->fragment;
    12486                 }
    12487 
    12488                 if ($iri !== '')
    12489                 {
    12490                         return $iri;
    12491                 }
    12492                 else
    12493                 {
    12494                         return null;
    12495                 }
    12496         }
    12497 
    12498         /**
    12499          * Get the scheme
    12500          *
    12501          * @access public
    12502          * @return string
    12503          */
    12504         function get_scheme()
    12505         {
    12506                 return $this->scheme;
    12507         }
    12508 
    12509         /**
    12510          * Get the complete authority
    12511          *
    12512          * @access public
    12513          * @return string
    12514          */
    12515         function get_authority()
    12516         {
    12517                 $authority = '';
    12518                 if ($this->userinfo !== null)
    12519                 {
    12520                         $authority .= $this->userinfo . '@';
    12521                 }
    12522                 if ($this->host !== null)
    12523                 {
    12524                         $authority .= $this->host;
    12525                 }
    12526                 if ($this->port !== null)
    12527                 {
    12528                         $authority .= ':' . $this->port;
    12529                 }
    12530 
    12531                 if ($authority !== '')
    12532                 {
    12533                         return $authority;
    12534                 }
    12535                 else
    12536                 {
    12537                         return null;
    12538                 }
    12539         }
    12540 
    12541         /**
    12542          * Get the user information
    12543          *
    12544          * @access public
    12545          * @return string
    12546          */
    12547         function get_userinfo()
    12548         {
    12549                 return $this->userinfo;
    12550         }
    12551 
    12552         /**
    12553          * Get the host
    12554          *
    12555          * @access public
    12556          * @return string
    12557          */
    12558         function get_host()
    12559         {
    12560                 return $this->host;
    12561         }
    12562 
    12563         /**
    12564          * Get the port
    12565          *
    12566          * @access public
    12567          * @return string
    12568          */
    12569         function get_port()
    12570         {
    12571                 return $this->port;
    12572         }
    12573 
    12574         /**
    12575          * Get the path
    12576          *
    12577          * @access public
    12578          * @return string
    12579          */
    12580         function get_path()
    12581         {
    12582                 return $this->path;
    12583         }
    12584 
    12585         /**
    12586          * Get the query
    12587          *
    12588          * @access public
    12589          * @return string
    12590          */
    12591         function get_query()
    12592         {
    12593                 return $this->query;
    12594         }
    12595 
    12596         /**
    12597          * Get the fragment
    12598          *
    12599          * @access public
    12600          * @return string
    12601          */
    12602         function get_fragment()
    12603         {
    12604                 return $this->fragment;
    12605         }
    12606 }
    12607 
    12608 /**
    12609  * Class to validate and to work with IPv6 addresses.
    12610  *
    12611  * @package SimplePie
    12612  * @copyright 2003-2005 The PHP Group
    12613  * @license http://www.opensource.org/licenses/bsd-license.php
    12614  * @link http://pear.php.net/package/Net_IPv6
    12615  * @author Alexander Merz <alexander.merz@web.de>
    12616  * @author elfrink at introweb dot nl
    12617  * @author Josh Peck <jmp at joshpeck dot org>
    12618  * @author Geoffrey Sneddon <geoffers@gmail.com>
    12619  */
    12620 class SimplePie_Net_IPv6
    12621 {
    12622         /**
    12623          * Removes a possible existing netmask specification of an IP address.
    12624          *
    12625          * @param string $ip the (compressed) IP as Hex representation
    12626          * @return string the IP the without netmask
    12627          * @since 1.1.0
    12628          * @access public
    12629          * @static
    12630          */
    12631         function removeNetmaskSpec($ip)
    12632         {
    12633                 if (strpos($ip, '/') !== false)
    12634                 {
    12635                         list($addr, $nm) = explode('/', $ip);
    12636                 }
    12637                 else
    12638                 {
    12639                         $addr = $ip;
    12640                 }
    12641                 return $addr;
    12642         }
    12643 
    12644         /**
    12645          * Uncompresses an IPv6 address
    12646          *
    12647          * RFC 2373 allows you to compress zeros in an address to '::'. This
    12648          * function expects an valid IPv6 address and expands the '::' to
    12649          * the required zeros.
    12650          *
    12651          * Example:      FF01::101      ->      FF01:0:0:0:0:0:0:101
    12652          *                       ::1            ->      0:0:0:0:0:0:0:1
    12653          *
    12654          * @access public
    12655          * @static
    12656          * @param string $ip a valid IPv6-address (hex format)
    12657          * @return string the uncompressed IPv6-address (hex format)
    12658          */
    12659         function Uncompress($ip)
    12660         {
    12661                 $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
    12662                 $c1 = -1;
    12663                 $c2 = -1;
    12664                 if (strpos($ip, '::') !== false)
    12665                 {
    12666                         list($ip1, $ip2) = explode('::', $ip);
    12667                         if ($ip1 === '')
    12668                         {
    12669                                 $c1 = -1;
    12670                         }
    12671                         else
    12672                         {
    12673                                 $pos = 0;
    12674                                 if (($pos = substr_count($ip1, ':')) > 0)
    12675                                 {
    12676                                         $c1 = $pos;
    12677                                 }
    12678                                 else
    12679                                 {
    12680                                         $c1 = 0;
    12681                                 }
    12682                         }
    12683                         if ($ip2 === '')
    12684                         {
    12685                                 $c2 = -1;
    12686                         }
    12687                         else
    12688                         {
    12689                                 $pos = 0;
    12690                                 if (($pos = substr_count($ip2, ':')) > 0)
    12691                                 {
    12692                                         $c2 = $pos;
    12693                                 }
    12694                                 else
    12695                                 {
    12696                                         $c2 = 0;
    12697                                 }
    12698                         }
    12699                         if (strstr($ip2, '.'))
    12700                         {
    12701                                 $c2++;
    12702                         }
    12703                         // ::
    12704                         if ($c1 === -1 && $c2 === -1)
    12705                         {
    12706                                 $uip = '0:0:0:0:0:0:0:0';
    12707                         }
    12708                         // ::xxx
    12709                         else if ($c1 === -1)
    12710                         {
    12711                                 $fill = str_repeat('0:', 7 - $c2);
    12712                                 $uip =  str_replace('::', $fill, $uip);
    12713                         }
    12714                         // xxx::
    12715                         else if ($c2 === -1)
    12716                         {
    12717                                 $fill = str_repeat(':0', 7 - $c1);
    12718                                 $uip =  str_replace('::', $fill, $uip);
    12719                         }
    12720                         // xxx::xxx
    12721                         else
    12722                         {
    12723                                 $fill = str_repeat(':0:', 6 - $c2 - $c1);
    12724                                 $uip =  str_replace('::', $fill, $uip);
    12725                                 $uip =  str_replace('::', ':', $uip);
    12726                         }
    12727                 }
    12728                 return $uip;
    12729         }
    12730 
    12731         /**
    12732          * Splits an IPv6 address into the IPv6 and a possible IPv4 part
    12733          *
    12734          * RFC 2373 allows you to note the last two parts of an IPv6 address as
    12735          * an IPv4 compatible address
    12736          *
    12737          * Example:      0:0:0:0:0:0:13.1.68.3
    12738          *                       0:0:0:0:0:FFFF:129.144.52.38
    12739          *
    12740          * @access public
    12741          * @static
    12742          * @param string $ip a valid IPv6-address (hex format)
    12743          * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
    12744          */
    12745         function SplitV64($ip)
    12746         {
    12747                 $ip = SimplePie_Net_IPv6::Uncompress($ip);
    12748                 if (strstr($ip, '.'))
    12749                 {
    12750                         $pos = strrpos($ip, ':');
    12751                         $ip[$pos] = '_';
    12752                         $ipPart = explode('_', $ip);
    12753                         return $ipPart;
    12754                 }
    12755                 else
    12756                 {
    12757                         return array($ip, '');
    12758                 }
    12759         }
    12760 
    12761         /**
    12762          * Checks an IPv6 address
    12763          *
    12764          * Checks if the given IP is IPv6-compatible
    12765          *
    12766          * @access public
    12767          * @static
    12768          * @param string $ip a valid IPv6-address
    12769          * @return bool true if $ip is an IPv6 address
    12770          */
    12771         function checkIPv6($ip)
    12772         {
    12773                 $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
    12774                 $count = 0;
    12775                 if (!empty($ipPart[0]))
    12776                 {
    12777                         $ipv6 = explode(':', $ipPart[0]);
    12778                         for ($i = 0; $i < count($ipv6); $i++)
    12779                         {
    12780                                 $dec = hexdec($ipv6[$i]);
    12781                                 $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
    12782                                 if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
    12783                                 {
    12784                                         $count++;
    12785                                 }
    12786                         }
    12787                         if ($count === 8)
    12788                         {
    12789                                 return true;
    12790                         }
    12791                         elseif ($count === 6 && !empty($ipPart[1]))
    12792                         {
    12793                                 $ipv4 = explode('.', $ipPart[1]);
    12794                                 $count = 0;
    12795                                 foreach ($ipv4 as $ipv4_part)
    12796                                 {
    12797                                         if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
    12798                                         {
    12799                                                 $count++;
    12800                                         }
    12801                                 }
    12802                                 if ($count === 4)
    12803                                 {
    12804                                         return true;
    12805                                 }
    12806                         }
    12807                         else
    12808                         {
    12809                                 return false;
    12810                         }
    12811 
    12812                 }
    12813                 else
    12814                 {
    12815                         return false;
    12816                 }
    12817         }
    12818 }
    12819 
    12820 /**
    12821  * Date Parser
    12822  *
    12823  * @package SimplePie
    12824  */
    12825 class SimplePie_Parse_Date
    12826 {
    12827         /**
    12828          * Input data
    12829          *
    12830          * @access protected
    12831          * @var string
    12832          */
    12833         var $date;
    12834 
    12835         /**
    12836          * List of days, calendar day name => ordinal day number in the week
    12837          *
    12838          * @access protected
    12839          * @var array
    12840          */
    12841         var $day = array(
    12842                 // English
    12843                 'mon' => 1,
    12844                 'monday' => 1,
    12845                 'tue' => 2,
    12846                 'tuesday' => 2,
    12847                 'wed' => 3,
    12848                 'wednesday' => 3,
    12849                 'thu' => 4,
    12850                 'thursday' => 4,
    12851                 'fri' => 5,
    12852                 'friday' => 5,
    12853                 'sat' => 6,
    12854                 'saturday' => 6,
    12855                 'sun' => 7,
    12856                 'sunday' => 7,
    12857                 // Dutch
    12858                 'maandag' => 1,
    12859                 'dinsdag' => 2,
    12860                 'woensdag' => 3,
    12861                 'donderdag' => 4,
    12862                 'vrijdag' => 5,
    12863                 'zaterdag' => 6,
    12864                 'zondag' => 7,
    12865                 // French
    12866                 'lundi' => 1,
    12867                 'mardi' => 2,
    12868                 'mercredi' => 3,
    12869                 'jeudi' => 4,
    12870                 'vendredi' => 5,
    12871                 'samedi' => 6,
    12872                 'dimanche' => 7,
    12873                 // German
    12874                 'montag' => 1,
    12875                 'dienstag' => 2,
    12876                 'mittwoch' => 3,
    12877                 'donnerstag' => 4,
    12878                 'freitag' => 5,
    12879                 'samstag' => 6,
    12880                 'sonnabend' => 6,
    12881                 'sonntag' => 7,
    12882                 // Italian
    12883                 'lunedì' => 1,
    12884                 'martedì' => 2,
    12885                 'mercoledì' => 3,
    12886                 'giovedì' => 4,
    12887                 'venerdì' => 5,
    12888                 'sabato' => 6,
    12889                 'domenica' => 7,
    12890                 // Spanish
    12891                 'lunes' => 1,
    12892                 'martes' => 2,
    12893                 'miércoles' => 3,
    12894                 'jueves' => 4,
    12895                 'viernes' => 5,
    12896                 'sábado' => 6,
    12897                 'domingo' => 7,
    12898                 // Finnish
    12899                 'maanantai' => 1,
    12900                 'tiistai' => 2,
    12901                 'keskiviikko' => 3,
    12902                 'torstai' => 4,
    12903                 'perjantai' => 5,
    12904                 'lauantai' => 6,
    12905                 'sunnuntai' => 7,
    12906                 // Hungarian
    12907                 'hétfő' => 1,
    12908                 'kedd' => 2,
    12909                 'szerda' => 3,
    12910                 'csütörtok' => 4,
    12911                 'péntek' => 5,
    12912                 'szombat' => 6,
    12913                 'vasárnap' => 7,
    12914                 // Greek
    12915                 'Δευ' => 1,
    12916                 'Τρι' => 2,
    12917                 'Τετ' => 3,
    12918                 'Πεμ' => 4,
    12919                 'Παρ' => 5,
    12920                 'Σαβ' => 6,
    12921                 'Κυρ' => 7,
    12922         );
    12923 
    12924         /**
    12925          * List of months, calendar month name => calendar month number
    12926          *
    12927          * @access protected
    12928          * @var array
    12929          */
    12930         var $month = array(
    12931                 // English
    12932                 'jan' => 1,
    12933                 'january' => 1,
    12934                 'feb' => 2,
    12935                 'february' => 2,
    12936                 'mar' => 3,
    12937                 'march' => 3,
    12938                 'apr' => 4,
    12939                 'april' => 4,
    12940                 'may' => 5,
    12941                 // No long form of May
    12942                 'jun' => 6,
    12943                 'june' => 6,
    12944                 'jul' => 7,
    12945                 'july' => 7,
    12946                 'aug' => 8,
    12947                 'august' => 8,
    12948                 'sep' => 9,
    12949                 'september' => 8,
    12950                 'oct' => 10,
    12951                 'october' => 10,
    12952                 'nov' => 11,
    12953                 'november' => 11,
    12954                 'dec' => 12,
    12955                 'december' => 12,
    12956                 // Dutch
    12957                 'januari' => 1,
    12958                 'februari' => 2,
    12959                 'maart' => 3,
    12960                 'april' => 4,
    12961                 'mei' => 5,
    12962                 'juni' => 6,
    12963                 'juli' => 7,
    12964                 'augustus' => 8,
    12965                 'september' => 9,
    12966                 'oktober' => 10,
    12967                 'november' => 11,
    12968                 'december' => 12,
    12969                 // French
    12970                 'janvier' => 1,
    12971                 'février' => 2,
    12972                 'mars' => 3,
    12973                 'avril' => 4,
    12974                 'mai' => 5,
    12975                 'juin' => 6,
    12976                 'juillet' => 7,
    12977                 'août' => 8,
    12978                 'septembre' => 9,
    12979                 'octobre' => 10,
    12980                 'novembre' => 11,
    12981                 'décembre' => 12,
    12982                 // German
    12983                 'januar' => 1,
    12984                 'februar' => 2,
    12985                 'märz' => 3,
    12986                 'april' => 4,
    12987                 'mai' => 5,
    12988                 'juni' => 6,
    12989                 'juli' => 7,
    12990                 'august' => 8,
    12991                 'september' => 9,
    12992                 'oktober' => 10,
    12993                 'november' => 11,
    12994                 'dezember' => 12,
    12995                 // Italian
    12996                 'gennaio' => 1,
    12997                 'febbraio' => 2,
    12998                 'marzo' => 3,
    12999                 'aprile' => 4,
    13000                 'maggio' => 5,
    13001                 'giugno' => 6,
    13002                 'luglio' => 7,
    13003                 'agosto' => 8,
    13004                 'settembre' => 9,
    13005                 'ottobre' => 10,
    13006                 'novembre' => 11,
    13007                 'dicembre' => 12,
    13008                 // Spanish
    13009                 'enero' => 1,
    13010                 'febrero' => 2,
    13011                 'marzo' => 3,
    13012                 'abril' => 4,
    13013                 'mayo' => 5,
    13014                 'junio' => 6,
    13015                 'julio' => 7,
    13016                 'agosto' => 8,
    13017                 'septiembre' => 9,
    13018                 'setiembre' => 9,
    13019                 'octubre' => 10,
    13020                 'noviembre' => 11,
    13021                 'diciembre' => 12,
    13022                 // Finnish
    13023                 'tammikuu' => 1,
    13024                 'helmikuu' => 2,
    13025                 'maaliskuu' => 3,
    13026                 'huhtikuu' => 4,
    13027                 'toukokuu' => 5,
    13028                 'kesäkuu' => 6,
    13029                 'heinäkuu' => 7,
    13030                 'elokuu' => 8,
    13031                 'suuskuu' => 9,
    13032                 'lokakuu' => 10,
    13033                 'marras' => 11,
    13034                 'joulukuu' => 12,
    13035                 // Hungarian
    13036                 'január' => 1,
    13037                 'február' => 2,
    13038                 'március' => 3,
    13039                 'április' => 4,
    13040                 'május' => 5,
    13041                 'június' => 6,
    13042                 'július' => 7,
    13043                 'augusztus' => 8,
    13044                 'szeptember' => 9,
    13045                 'október' => 10,
    13046                 'november' => 11,
    13047                 'december' => 12,
    13048                 // Greek
    13049                 'Ιαν' => 1,
    13050                 'Φεβ' => 2,
    13051                 'Μάώ' => 3,
    13052                 'Μαώ' => 3,
    13053                 'Απρ' => 4,
    13054                 'Μάι' => 5,
    13055                 'Μαϊ' => 5,
    13056                 'Μαι' => 5,
    13057                 'Ιούν' => 6,
    13058                 'Ιον' => 6,
    13059                 'Ιούλ' => 7,
    13060                 'Ιολ' => 7,
    13061                 'Αύγ' => 8,
    13062                 'Αυγ' => 8,
    13063                 'Σεπ' => 9,
    13064                 'Οκτ' => 10,
    13065                 'Νοέ' => 11,
    13066                 'Δεκ' => 12,
    13067         );
    13068 
    13069         /**
    13070          * List of timezones, abbreviation => offset from UTC
    13071          *
    13072          * @access protected
    13073          * @var array
    13074          */
    13075         var $timezone = array(
    13076                 'ACDT' => 37800,
    13077                 'ACIT' => 28800,
    13078                 'ACST' => 34200,
    13079                 'ACT' => -18000,
    13080                 'ACWDT' => 35100,
    13081                 'ACWST' => 31500,
    13082                 'AEDT' => 39600,
    13083                 'AEST' => 36000,
    13084                 'AFT' => 16200,
    13085                 'AKDT' => -28800,
    13086                 'AKST' => -32400,
    13087                 'AMDT' => 18000,
    13088                 'AMT' => -14400,
    13089                 'ANAST' => 46800,
    13090                 'ANAT' => 43200,
    13091                 'ART' => -10800,
    13092                 'AZOST' => -3600,
    13093                 'AZST' => 18000,
    13094                 'AZT' => 14400,
    13095                 'BIOT' => 21600,
    13096                 'BIT' => -43200,
    13097                 'BOT' => -14400,
    13098                 'BRST' => -7200,
    13099                 'BRT' => -10800,
    13100                 'BST' => 3600,
    13101                 'BTT' => 21600,
    13102                 'CAST' => 18000,
    13103                 'CAT' => 7200,
    13104                 'CCT' => 23400,
    13105                 'CDT' => -18000,
    13106                 'CEDT' => 7200,
    13107                 'CET' => 3600,
    13108                 'CGST' => -7200,
    13109                 'CGT' => -10800,
    13110                 'CHADT' => 49500,
    13111                 'CHAST' => 45900,
    13112                 'CIST' => -28800,
    13113                 'CKT' => -36000,
    13114                 'CLDT' => -10800,
    13115                 'CLST' => -14400,
    13116                 'COT' => -18000,
    13117                 'CST' => -21600,
    13118                 'CVT' => -3600,
    13119                 'CXT' => 25200,
    13120                 'DAVT' => 25200,
    13121                 'DTAT' => 36000,
    13122                 'EADT' => -18000,
    13123                 'EAST' => -21600,
    13124                 'EAT' => 10800,
    13125                 'ECT' => -18000,
    13126                 'EDT' => -14400,
    13127                 'EEST' => 10800,
    13128                 'EET' => 7200,
    13129                 'EGT' => -3600,
    13130                 'EKST' => 21600,
    13131                 'EST' => -18000,
    13132                 'FJT' => 43200,
    13133                 'FKDT' => -10800,
    13134                 'FKST' => -14400,
    13135                 'FNT' => -7200,
    13136                 'GALT' => -21600,
    13137                 'GEDT' => 14400,
    13138                 'GEST' => 10800,
    13139                 'GFT' => -10800,
    13140                 'GILT' => 43200,
    13141                 'GIT' => -32400,
    13142                 'GST' => 14400,
    13143                 'GST' => -7200,
    13144                 'GYT' => -14400,
    13145                 'HAA' => -10800,
    13146                 'HAC' => -18000,
    13147                 'HADT' => -32400,
    13148                 'HAE' => -14400,
    13149                 'HAP' => -25200,
    13150                 'HAR' => -21600,
    13151                 'HAST' => -36000,
    13152                 'HAT' => -9000,
    13153                 'HAY' => -28800,
    13154                 'HKST' => 28800,
    13155                 'HMT' => 18000,
    13156                 'HNA' => -14400,
    13157                 'HNC' => -21600,
    13158                 'HNE' => -18000,
    13159                 'HNP' => -28800,
    13160                 'HNR' => -25200,
    13161                 'HNT' => -12600,
    13162                 'HNY' => -32400,
    13163                 'IRDT' => 16200,
    13164                 'IRKST' => 32400,
    13165                 'IRKT' => 28800,
    13166                 'IRST' => 12600,
    13167                 'JFDT' => -10800,
    13168                 'JFST' => -14400,
    13169                 'JST' => 32400,
    13170                 'KGST' => 21600,
    13171                 'KGT' => 18000,
    13172                 'KOST' => 39600,
    13173                 'KOVST' => 28800,
    13174                 'KOVT' => 25200,
    13175                 'KRAST' => 28800,
    13176                 'KRAT' => 25200,
    13177                 'KST' => 32400,
    13178                 'LHDT' => 39600,
    13179                 'LHST' => 37800,
    13180                 'LINT' => 50400,
    13181                 'LKT' => 21600,
    13182                 'MAGST' => 43200,
    13183                 'MAGT' => 39600,
    13184                 'MAWT' => 21600,
    13185                 'MDT' => -21600,
    13186                 'MESZ' => 7200,
    13187                 'MEZ' => 3600,
    13188                 'MHT' => 43200,
    13189                 'MIT' => -34200,
    13190                 'MNST' => 32400,
    13191                 'MSDT' => 14400,
    13192                 'MSST' => 10800,
    13193                 'MST' => -25200,
    13194                 'MUT' => 14400,
    13195                 'MVT' => 18000,
    13196                 'MYT' => 28800,
    13197                 'NCT' => 39600,
    13198                 'NDT' => -9000,
    13199                 'NFT' => 41400,
    13200                 'NMIT' => 36000,
    13201                 'NOVST' => 25200,
    13202                 'NOVT' => 21600,
    13203                 'NPT' => 20700,
    13204                 'NRT' => 43200,
    13205                 'NST' => -12600,
    13206                 'NUT' => -39600,
    13207                 'NZDT' => 46800,
    13208                 'NZST' => 43200,
    13209                 'OMSST' => 25200,
    13210                 'OMST' => 21600,
    13211                 'PDT' => -25200,
    13212                 'PET' => -18000,
    13213                 'PETST' => 46800,
    13214                 'PETT' => 43200,
    13215                 'PGT' => 36000,
    13216                 'PHOT' => 46800,
    13217                 'PHT' => 28800,
    13218                 'PKT' => 18000,
    13219                 'PMDT' => -7200,
    13220                 'PMST' => -10800,
    13221                 'PONT' => 39600,
    13222                 'PST' => -28800,
    13223                 'PWT' => 32400,
    13224                 'PYST' => -10800,
    13225                 'PYT' => -14400,
    13226                 'RET' => 14400,
    13227                 'ROTT' => -10800,
    13228                 'SAMST' => 18000,
    13229                 'SAMT' => 14400,
    13230                 'SAST' => 7200,
    13231                 'SBT' => 39600,
    13232                 'SCDT' => 46800,
    13233                 'SCST' => 43200,
    13234                 'SCT' => 14400,
    13235                 'SEST' => 3600,
    13236                 'SGT' => 28800,
    13237                 'SIT' => 28800,
    13238                 'SRT' => -10800,
    13239                 'SST' => -39600,
    13240                 'SYST' => 10800,
    13241                 'SYT' => 7200,
    13242                 'TFT' => 18000,
    13243                 'THAT' => -36000,
    13244                 'TJT' => 18000,
    13245                 'TKT' => -36000,
    13246                 'TMT' => 18000,
    13247                 'TOT' => 46800,
    13248                 'TPT' => 32400,
    13249                 'TRUT' => 36000,
    13250                 'TVT' => 43200,
    13251                 'TWT' => 28800,
    13252                 'UYST' => -7200,
    13253                 'UYT' => -10800,
    13254                 'UZT' => 18000,
    13255                 'VET' => -14400,
    13256                 'VLAST' => 39600,
    13257                 'VLAT' => 36000,
    13258                 'VOST' => 21600,
    13259                 'VUT' => 39600,
    13260                 'WAST' => 7200,
    13261                 'WAT' => 3600,
    13262                 'WDT' => 32400,
    13263                 'WEST' => 3600,
    13264                 'WFT' => 43200,
    13265                 'WIB' => 25200,
    13266                 'WIT' => 32400,
    13267                 'WITA' => 28800,
    13268                 'WKST' => 18000,
    13269                 'WST' => 28800,
    13270                 'YAKST' => 36000,
    13271                 'YAKT' => 32400,
    13272                 'YAPT' => 36000,
    13273                 'YEKST' => 21600,
    13274                 'YEKT' => 18000,
    13275         );
    13276 
    13277         /**
    13278          * Cached PCRE for SimplePie_Parse_Date::$day
    13279          *
    13280          * @access protected
    13281          * @var string
    13282          */
    13283         var $day_pcre;
    13284 
    13285         /**
    13286          * Cached PCRE for SimplePie_Parse_Date::$month
    13287          *
    13288          * @access protected
    13289          * @var string
    13290          */
    13291         var $month_pcre;
    13292 
    13293         /**
    13294          * Array of user-added callback methods
    13295          *
    13296          * @access private
    13297          * @var array
    13298          */
    13299         var $built_in = array();
    13300 
    13301         /**
    13302          * Array of user-added callback methods
    13303          *
    13304          * @access private
    13305          * @var array
    13306          */
    13307         var $user = array();
    13308 
    13309         /**
    13310          * Create new SimplePie_Parse_Date object, and set self::day_pcre,
    13311          * self::month_pcre, and self::built_in
    13312          *
    13313          * @access private
    13314          */
    13315         function SimplePie_Parse_Date()
    13316         {
    13317                 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
    13318                 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
    13319 
    13320                 static $cache;
    13321                 if (!isset($cache[get_class($this)]))
    13322                 {
    13323                         $all_methods = get_class_methods($this);
    13324 
    13325                         foreach ($all_methods as $method)
    13326                         {
    13327                                 if (strtolower(substr($method, 0, 5)) === 'date_')
    13328                                 {
    13329                                         $cache[get_class($this)][] = $method;
    13330                                 }
    13331                         }
    13332                 }
    13333 
    13334                 foreach ($cache[get_class($this)] as $method)
    13335                 {
    13336                         $this->built_in[] = $method;
    13337                 }
    13338         }
    13339 
    13340         /**
    13341          * Get the object
    13342          *
    13343          * @access public
    13344          */
    13345         function get()
    13346         {
    13347                 static $object;
    13348                 if (!$object)
    13349                 {
    13350                         $object =& new SimplePie_Parse_Date;
    13351                 }
    13352                 return $object;
    13353         }
    13354 
    13355         /**
    13356          * Parse a date
    13357          *
    13358          * @final
    13359          * @access public
    13360          * @param string $date Date to parse
    13361          * @return int Timestamp corresponding to date string, or false on failure
    13362          */
    13363         function parse($date)
    13364         {
    13365                 foreach ($this->user as $method)
    13366                 {
    13367                         if (($returned = call_user_func($method, $date)) !== false)
    13368                         {
    13369                                 return $returned;
    13370                         }
    13371                 }
    13372 
    13373                 foreach ($this->built_in as $method)
    13374                 {
    13375                         if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
    13376                         {
    13377                                 return $returned;
    13378                         }
    13379                 }
    13380 
    13381                 return false;
    13382         }
    13383 
    13384         /**
    13385          * Add a callback method to parse a date
    13386          *
    13387          * @final
    13388          * @access public
    13389          * @param callback $callback
    13390          */
    13391         function add_callback($callback)
    13392         {
    13393                 if (is_callable($callback))
    13394                 {
    13395                         $this->user[] = $callback;
    13396                 }
    13397                 else
    13398                 {
    13399                         trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
    13400                 }
    13401         }
    13402 
    13403         /**
    13404          * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
    13405          * well as allowing any of upper or lower case "T", horizontal tabs, or
    13406          * spaces to be used as the time seperator (including more than one))
    13407          *
    13408          * @access protected
    13409          * @return int Timestamp
    13410          */
    13411         function date_w3cdtf($date)
    13412         {
    13413                 static $pcre;
    13414                 if (!$pcre)
    13415                 {
    13416                         $year = '([0-9]{4})';
    13417                         $month = $day = $hour = $minute = $second = '([0-9]{2})';
    13418                         $decimal = '([0-9]*)';
    13419                         $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
    13420                         $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
    13421                 }
    13422                 if (preg_match($pcre, $date, $match))
    13423                 {
    13424                         /*
    13425                         Capturing subpatterns:
    13426                         1: Year
    13427                         2: Month
    13428                         3: Day
    13429                         4: Hour
    13430                         5: Minute
    13431                         6: Second
    13432                         7: Decimal fraction of a second
    13433                         8: Zulu
    13434                         9: Timezone ±
    13435                         10: Timezone hours
    13436                         11: Timezone minutes
    13437                         */
    13438 
    13439                         // Fill in empty matches
    13440                         for ($i = count($match); $i <= 3; $i++)
    13441                         {
    13442                                 $match[$i] = '1';
    13443                         }
    13444 
    13445                         for ($i = count($match); $i <= 7; $i++)
    13446                         {
    13447                                 $match[$i] = '0';
    13448                         }
    13449 
    13450                         // Numeric timezone
    13451                         if (isset($match[9]) && $match[9] !== '')
    13452                         {
    13453                                 $timezone = $match[10] * 3600;
    13454                                 $timezone += $match[11] * 60;
    13455                                 if ($match[9] === '-')
    13456                                 {
    13457                                         $timezone = 0 - $timezone;
    13458                                 }
    13459                         }
    13460                         else
    13461                         {
    13462                                 $timezone = 0;
    13463                         }
    13464 
    13465                         // Convert the number of seconds to an integer, taking decimals into account
    13466                         $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
    13467 
    13468                         return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
    13469                 }
    13470                 else
    13471                 {
    13472                         return false;
    13473                 }
    13474         }
    13475 
    13476         /**
    13477          * Remove RFC822 comments
    13478          *
    13479          * @access protected
    13480          * @param string $data Data to strip comments from
    13481          * @return string Comment stripped string
    13482          */
    13483         function remove_rfc2822_comments($string)
    13484         {
    13485                 $string = (string) $string;
    13486                 $position = 0;
    13487                 $length = strlen($string);
    13488                 $depth = 0;
    13489 
    13490                 $output = '';
    13491 
    13492                 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
    13493                 {
    13494                         $output .= substr($string, $position, $pos - $position);
    13495                         $position = $pos + 1;
    13496                         if ($string[$pos - 1] !== '\\')
    13497                         {
    13498                                 $depth++;
    13499                                 while ($depth && $position < $length)
    13500                                 {
    13501                                         $position += strcspn($string, '()', $position);
    13502                                         if ($string[$position - 1] === '\\')
    13503                                         {
    13504                                                 $position++;
    13505                                                 continue;
    13506                                         }
    13507                                         elseif (isset($string[$position]))
    13508                                         {
    13509                                                 switch ($string[$position])
    13510                                                 {
    13511                                                         case '(':
    13512                                                                 $depth++;
    13513                                                                 break;
    13514 
    13515                                                         case ')':
    13516                                                                 $depth--;
    13517                                                                 break;
    13518                                                 }
    13519                                                 $position++;
    13520                                         }
    13521                                         else
    13522                                         {
    13523                                                 break;
    13524                                         }
    13525                                 }
    13526                         }
    13527                         else
    13528                         {
    13529                                 $output .= '(';
    13530                         }
    13531                 }
    13532                 $output .= substr($string, $position);
    13533 
    13534                 return $output;
    13535         }
    13536 
    13537         /**
    13538          * Parse RFC2822's date format
    13539          *
    13540          * @access protected
    13541          * @return int Timestamp
    13542          */
    13543         function date_rfc2822($date)
    13544         {
    13545                 static $pcre;
    13546                 if (!$pcre)
    13547                 {
    13548                         $wsp = '[\x09\x20]';
    13549                         $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
    13550                         $optional_fws = $fws . '?';
    13551                         $day_name = $this->day_pcre;
    13552                         $month = $this->month_pcre;
    13553                         $day = '([0-9]{1,2})';
    13554                         $hour = $minute = $second = '([0-9]{2})';
    13555                         $year = '([0-9]{2,4})';
    13556                         $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
    13557                         $character_zone = '([A-Z]{1,5})';
    13558                         $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
    13559                         $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
    13560                 }
    13561                 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
    13562                 {
    13563                         /*
    13564                         Capturing subpatterns:
    13565                         1: Day name
    13566                         2: Day
    13567                         3: Month
    13568                         4: Year
    13569                         5: Hour
    13570                         6: Minute
    13571                         7: Second
    13572                         8: Timezone ±
    13573                         9: Timezone hours
    13574                         10: Timezone minutes
    13575                         11: Alphabetic timezone
    13576                         */
    13577 
    13578                         // Find the month number
    13579                         $month = $this->month[strtolower($match[3])];
    13580 
    13581                         // Numeric timezone
    13582                         if ($match[8] !== '')
    13583                         {
    13584                                 $timezone = $match[9] * 3600;
    13585                                 $timezone += $match[10] * 60;
    13586                                 if ($match[8] === '-')
    13587                                 {
    13588                                         $timezone = 0 - $timezone;
    13589                                 }
    13590                         }
    13591                         // Character timezone
    13592                         elseif (isset($this->timezone[strtoupper($match[11])]))
    13593                         {
    13594                                 $timezone = $this->timezone[strtoupper($match[11])];
    13595                         }
    13596                         // Assume everything else to be -0000
    13597                         else
    13598                         {
    13599                                 $timezone = 0;
    13600                         }
    13601 
    13602                         // Deal with 2/3 digit years
    13603                         if ($match[4] < 50)
    13604                         {
    13605                                 $match[4] += 2000;
    13606                         }
    13607                         elseif ($match[4] < 1000)
    13608                         {
    13609                                 $match[4] += 1900;
    13610                         }
    13611 
    13612                         // Second is optional, if it is empty set it to zero
    13613                         if ($match[7] !== '')
    13614                         {
    13615                                 $second = $match[7];
    13616                         }
    13617                         else
    13618                         {
    13619                                 $second = 0;
    13620                         }
    13621 
    13622                         return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
    13623                 }
    13624                 else
    13625                 {
    13626                         return false;
    13627                 }
    13628         }
    13629 
    13630         /**
    13631          * Parse RFC850's date format
    13632          *
    13633          * @access protected
    13634          * @return int Timestamp
    13635          */
    13636         function date_rfc850($date)
    13637         {
    13638                 static $pcre;
    13639                 if (!$pcre)
    13640                 {
    13641                         $space = '[\x09\x20]+';
    13642                         $day_name = $this->day_pcre;
    13643                         $month = $this->month_pcre;
    13644                         $day = '([0-9]{1,2})';
    13645                         $year = $hour = $minute = $second = '([0-9]{2})';
    13646                         $zone = '([A-Z]{1,5})';
    13647                         $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
    13648                 }
    13649                 if (preg_match($pcre, $date, $match))
    13650                 {
    13651                         /*
    13652                         Capturing subpatterns:
    13653                         1: Day name
    13654                         2: Day
    13655                         3: Month
    13656                         4: Year
    13657                         5: Hour
    13658                         6: Minute
    13659                         7: Second
    13660                         8: Timezone
    13661                         */
    13662 
    13663                         // Month
    13664                         $month = $this->month[strtolower($match[3])];
    13665 
    13666                         // Character timezone
    13667                         if (isset($this->timezone[strtoupper($match[8])]))
    13668                         {
    13669                                 $timezone = $this->timezone[strtoupper($match[8])];
    13670                         }
    13671                         // Assume everything else to be -0000
    13672                         else
    13673                         {
    13674                                 $timezone = 0;
    13675                         }
    13676 
    13677                         // Deal with 2 digit year
    13678                         if ($match[4] < 50)
    13679                         {
    13680                                 $match[4] += 2000;
    13681                         }
    13682                         else
    13683                         {
    13684                                 $match[4] += 1900;
    13685                         }
    13686 
    13687                         return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
    13688                 }
    13689                 else
    13690                 {
    13691                         return false;
    13692                 }
    13693         }
    13694 
    13695         /**
    13696          * Parse C99's asctime()'s date format
    13697          *
    13698          * @access protected
    13699          * @return int Timestamp
    13700          */
    13701         function date_asctime($date)
    13702         {
    13703                 static $pcre;
    13704                 if (!$pcre)
    13705                 {
    13706                         $space = '[\x09\x20]+';
    13707                         $wday_name = $this->day_pcre;
    13708                         $mon_name = $this->month_pcre;
    13709                         $day = '([0-9]{1,2})';
    13710                         $hour = $sec = $min = '([0-9]{2})';
    13711                         $year = '([0-9]{4})';
    13712                         $terminator = '\x0A?\x00?';
    13713                         $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
    13714                 }
    13715                 if (preg_match($pcre, $date, $match))
    13716                 {
    13717                         /*
    13718                         Capturing subpatterns:
    13719                         1: Day name
    13720                         2: Month
    13721                         3: Day
    13722                         4: Hour
    13723                         5: Minute
    13724                         6: Second
    13725                         7: Year
    13726                         */
    13727 
    13728                         $month = $this->month[strtolower($match[2])];
    13729                         return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
    13730                 }
    13731                 else
    13732                 {
    13733                         return false;
    13734                 }
    13735         }
    13736 
    13737         /**
    13738          * Parse dates using strtotime()
    13739          *
    13740          * @access protected
    13741          * @return int Timestamp
    13742          */
    13743         function date_strtotime($date)
    13744         {
    13745                 $strtotime = strtotime($date);
    13746                 if ($strtotime === -1 || $strtotime === false)
    13747                 {
    13748                         return false;
    13749                 }
    13750                 else
    13751                 {
    13752                         return $strtotime;
    13753                 }
    13754         }
    13755 }
    13756 
    13757 /**
    13758  * Content-type sniffing
    13759  *
    13760  * @package SimplePie
    13761  */
    13762 class SimplePie_Content_Type_Sniffer
    13763 {
    13764         /**
    13765          * File object
    13766          *
    13767          * @var SimplePie_File
    13768          * @access private
    13769          */
    13770         var $file;
    13771 
    13772         /**
    13773          * Create an instance of the class with the input file
    13774          *
    13775          * @access public
    13776          * @param SimplePie_Content_Type_Sniffer $file Input file
    13777          */
    13778         function SimplePie_Content_Type_Sniffer($file)
    13779         {
    13780                 $this->file = $file;
    13781         }
    13782 
    13783         /**
    13784          * Get the Content-Type of the specified file
    13785          *
    13786          * @access public
    13787          * @return string Actual Content-Type
    13788          */
    13789         function get_type()
    13790         {
    13791                 if (isset($this->file->headers['content-type']))
    13792                 {
    13793                         if (!isset($this->file->headers['content-encoding'])
    13794                                 && ($this->file->headers['content-type'] === 'text/plain'
    13795                                         || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
    13796                                         || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
    13797                         {
    13798                                 return $this->text_or_binary();
    13799                         }
    13800 
    13801                         if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
    13802                         {
    13803                                 $official = substr($this->file->headers['content-type'], 0, $pos);
    13804                         }
    13805                         else
    13806                         {
    13807                                 $official = $this->file->headers['content-type'];
    13808                         }
    13809                         $official = strtolower($official);
    13810 
    13811                         if ($official === 'unknown/unknown'
    13812                                 || $official === 'application/unknown')
    13813                         {
    13814                                 return $this->unknown();
    13815                         }
    13816                         elseif (substr($official, -4) === '+xml'
    13817                                 || $official === 'text/xml'
    13818                                 || $official === 'application/xml')
    13819                         {
    13820                                 return $official;
    13821                         }
    13822                         elseif (substr($official, 0, 6) === 'image/')
    13823                         {
    13824                                 if ($return = $this->image())
    13825                                 {
    13826                                         return $return;
    13827                                 }
    13828                                 else
    13829                                 {
    13830                                         return $official;
    13831                                 }
    13832                         }
    13833                         elseif ($official === 'text/html')
    13834                         {
    13835                                 return $this->feed_or_html();
    13836                         }
    13837                         else
    13838                         {
    13839                                 return $official;
    13840                         }
    13841                 }
    13842                 else
    13843                 {
    13844                         return $this->unknown();
    13845                 }
    13846         }
    13847 
    13848         /**
    13849          * Sniff text or binary
    13850          *
    13851          * @access private
    13852          * @return string Actual Content-Type
    13853          */
    13854         function text_or_binary()
    13855         {
    13856                 if (substr($this->file->body, 0, 2) === "\xFE\xFF"
    13857                         || substr($this->file->body, 0, 2) === "\xFF\xFE"
    13858                         || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
    13859                         || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
    13860                 {
    13861                         return 'text/plain';
    13862                 }
    13863                 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
    13864                 {
    13865                         return 'application/octect-stream';
    13866                 }
    13867                 else
    13868                 {
    13869                         return 'text/plain';
    13870                 }
    13871         }
    13872 
    13873         /**
    13874          * Sniff unknown
    13875          *
    13876          * @access private
    13877          * @return string Actual Content-Type
    13878          */
    13879         function unknown()
    13880         {
    13881                 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
    13882                 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
    13883                         || strtolower(substr($this->file->body, $ws, 5)) === '<html'
    13884                         || strtolower(substr($this->file->body, $ws, 7)) === '<script')
    13885                 {
    13886                         return 'text/html';
    13887                 }
    13888                 elseif (substr($this->file->body, 0, 5) === '%PDF-')
    13889                 {
    13890                         return 'application/pdf';
    13891                 }
    13892                 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
    13893                 {
    13894                         return 'application/postscript';
    13895                 }
    13896                 elseif (substr($this->file->body, 0, 6) === 'GIF87a'
    13897                         || substr($this->file->body, 0, 6) === 'GIF89a')
    13898                 {
    13899                         return 'image/gif';
    13900                 }
    13901                 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
    13902                 {
    13903                         return 'image/png';
    13904                 }
    13905                 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
    13906                 {
    13907                         return 'image/jpeg';
    13908                 }
    13909                 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
    13910                 {
    13911                         return 'image/bmp';
    13912                 }
    13913                 else
    13914                 {
    13915                         return $this->text_or_binary();
    13916                 }
    13917         }
    13918 
    13919         /**
    13920          * Sniff images
    13921          *
    13922          * @access private
    13923          * @return string Actual Content-Type
    13924          */
    13925         function image()
    13926         {
    13927                 if (substr($this->file->body, 0, 6) === 'GIF87a'
    13928                         || substr($this->file->body, 0, 6) === 'GIF89a')
    13929                 {
    13930                         return 'image/gif';
    13931                 }
    13932                 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
    13933                 {
    13934                         return 'image/png';
    13935                 }
    13936                 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
    13937                 {
    13938                         return 'image/jpeg';
    13939                 }
    13940                 elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
    13941                 {
    13942                         return 'image/bmp';
    13943                 }
    13944                 else
    13945                 {
    13946                         return false;
    13947                 }
    13948         }
    13949 
    13950         /**
    13951          * Sniff HTML
    13952          *
    13953          * @access private
    13954          * @return string Actual Content-Type
    13955          */
    13956         function feed_or_html()
    13957         {
    13958                 $len = strlen($this->file->body);
    13959                 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
    13960 
    13961                 while ($pos < $len)
    13962                 {
    13963                         switch ($this->file->body[$pos])
    13964                         {
    13965                                 case "\x09":
    13966                                 case "\x0A":
    13967                                 case "\x0D":
    13968                                 case "\x20":
    13969                                         $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
    13970                                         continue 2;
    13971 
    13972                                 case '<':
    13973                                         $pos++;
    13974                                         break;
    13975 
    13976                                 default:
    13977                                         return 'text/html';
    13978                         }
    13979 
    13980                         if (substr($this->file->body, $pos, 3) === '!--')
    13981                         {
    13982                                 $pos += 3;
    13983                                 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
    13984                                 {
    13985                                         $pos += 3;
    13986                                 }
    13987                                 else
    13988                                 {
    13989                                         return 'text/html';
    13990                                 }
    13991                         }
    13992                         elseif (substr($this->file->body, $pos, 1) === '!')
    13993                         {
    13994                                 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
    13995                                 {
    13996                                         $pos++;
    13997                                 }
    13998                                 else
    13999                                 {
    14000                                         return 'text/html';
    14001                                 }
    14002                         }
    14003                         elseif (substr($this->file->body, $pos, 1) === '?')
    14004                         {
    14005                                 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
    14006                                 {
    14007                                         $pos += 2;
    14008                                 }
    14009                                 else
    14010                                 {
    14011                                         return 'text/html';
    14012                                 }
    14013                         }
    14014                         elseif (substr($this->file->body, $pos, 3) === 'rss'
    14015                                 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
    14016                         {
    14017                                 return 'application/rss+xml';
    14018                         }
    14019                         elseif (substr($this->file->body, $pos, 4) === 'feed')
    14020                         {
    14021                                 return 'application/atom+xml';
    14022                         }
    14023                         else
    14024                         {
    14025                                 return 'text/html';
    14026                         }
    14027                 }
    14028 
    14029                 return 'text/html';
    14030         }
    14031 }
    14032 
    14033 /**
    14034  * Parses the XML Declaration
    14035  *
    14036  * @package SimplePie
    14037  */
    14038 class SimplePie_XML_Declaration_Parser
    14039 {
    14040         /**
    14041          * XML Version
    14042          *
    14043          * @access public
    14044          * @var string
    14045          */
    14046         var $version = '1.0';
    14047 
    14048         /**
    14049          * Encoding
    14050          *
    14051          * @access public
    14052          * @var string
    14053          */
    14054         var $encoding = 'UTF-8';
    14055 
    14056         /**
    14057          * Standalone
    14058          *
    14059          * @access public
    14060          * @var bool
    14061          */
    14062         var $standalone = false;
    14063 
    14064         /**
    14065          * Current state of the state machine
    14066          *
    14067          * @access private
    14068          * @var string
    14069          */
    14070         var $state = 'before_version_name';
    14071 
    14072         /**
    14073          * Input data
    14074          *
    14075          * @access private
    14076          * @var string
    14077          */
    14078         var $data = '';
    14079 
    14080         /**
    14081          * Input data length (to avoid calling strlen() everytime this is needed)
    14082          *
    14083          * @access private
    14084          * @var int
    14085          */
    14086         var $data_length = 0;
    14087 
    14088         /**
    14089          * Current position of the pointer
    14090          *
    14091          * @var int
    14092          * @access private
    14093          */
    14094         var $position = 0;
    14095 
    14096         /**
    14097          * Create an instance of the class with the input data
    14098          *
    14099          * @access public
    14100          * @param string $data Input data
    14101          */
    14102         function SimplePie_XML_Declaration_Parser($data)
    14103         {
    14104                 $this->data = $data;
    14105                 $this->data_length = strlen($this->data);
    14106         }
    14107 
    14108         /**
    14109          * Parse the input data
    14110          *
    14111          * @access public
    14112          * @return bool true on success, false on failure
    14113          */
    14114         function parse()
    14115         {
    14116                 while ($this->state && $this->state !== 'emit' && $this->has_data())
    14117                 {
    14118                         $state = $this->state;
    14119                         $this->$state();
    14120                 }
    14121                 $this->data = '';
    14122                 if ($this->state === 'emit')
    14123                 {
    14124                         return true;
    14125                 }
    14126                 else
    14127                 {
    14128                         $this->version = '';
    14129                         $this->encoding = '';
    14130                         $this->standalone = '';
    14131                         return false;
    14132                 }
    14133         }
    14134 
    14135         /**
    14136          * Check whether there is data beyond the pointer
    14137          *
    14138          * @access private
    14139          * @return bool true if there is further data, false if not
    14140          */
    14141         function has_data()
    14142         {
    14143                 return (bool) ($this->position < $this->data_length);
    14144         }
    14145 
    14146         /**
    14147          * Advance past any whitespace
    14148          *
    14149          * @return int Number of whitespace characters passed
    14150          */
    14151         function skip_whitespace()
    14152         {
    14153                 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
    14154                 $this->position += $whitespace;
    14155                 return $whitespace;
    14156         }
    14157 
    14158         /**
    14159          * Read value
    14160          */
    14161         function get_value()
    14162         {
    14163                 $quote = substr($this->data, $this->position, 1);
    14164                 if ($quote === '"' || $quote === "'")
    14165                 {
    14166                         $this->position++;
    14167                         $len = strcspn($this->data, $quote, $this->position);
    14168                         if ($this->has_data())
    14169                         {
    14170                                 $value = substr($this->data, $this->position, $len);
    14171                                 $this->position += $len + 1;
    14172                                 return $value;
    14173                         }
    14174                 }
    14175                 return false;
    14176         }
    14177 
    14178         function before_version_name()
    14179         {
    14180                 if ($this->skip_whitespace())
    14181                 {
    14182                         $this->state = 'version_name';
    14183                 }
    14184                 else
    14185                 {
    14186                         $this->state = false;
    14187                 }
    14188         }
    14189 
    14190         function version_name()
    14191         {
    14192                 if (substr($this->data, $this->position, 7) === 'version')
    14193                 {
    14194                         $this->position += 7;
    14195                         $this->skip_whitespace();
    14196                         $this->state = 'version_equals';
    14197                 }
    14198                 else
    14199                 {
    14200                         $this->state = false;
    14201                 }
    14202         }
    14203 
    14204         function version_equals()
    14205         {
    14206                 if (substr($this->data, $this->position, 1) === '=')
    14207                 {
    14208                         $this->position++;
    14209                         $this->skip_whitespace();
    14210                         $this->state = 'version_value';
    14211                 }
    14212                 else
    14213                 {
    14214                         $this->state = false;
    14215                 }
    14216         }
    14217 
    14218         function version_value()
    14219         {
    14220                 if ($this->version = $this->get_value())
    14221                 {
    14222                         $this->skip_whitespace();
    14223                         if ($this->has_data())
    14224                         {
    14225                                 $this->state = 'encoding_name';
    14226                         }
    14227                         else
    14228                         {
    14229                                 $this->state = 'emit';
    14230                         }
    14231                 }
    14232                 else
    14233                 {
    14234                         $this->state = false;
    14235                 }
    14236         }
    14237 
    14238         function encoding_name()
    14239         {
    14240                 if (substr($this->data, $this->position, 8) === 'encoding')
    14241                 {
    14242                         $this->position += 8;
    14243                         $this->skip_whitespace();
    14244                         $this->state = 'encoding_equals';
    14245                 }
    14246                 else
    14247                 {
    14248                         $this->state = 'standalone_name';
    14249                 }
    14250         }
    14251 
    14252         function encoding_equals()
    14253         {
    14254                 if (substr($this->data, $this->position, 1) === '=')
    14255                 {
    14256                         $this->position++;
    14257                         $this->skip_whitespace();
    14258                         $this->state = 'encoding_value';
    14259                 }
    14260                 else
    14261                 {
    14262                         $this->state = false;
    14263                 }
    14264         }
    14265 
    14266         function encoding_value()
    14267         {
    14268                 if ($this->encoding = $this->get_value())
    14269                 {
    14270                         $this->skip_whitespace();
    14271                         if ($this->has_data())
    14272                         {
    14273                                 $this->state = 'standalone_name';
    14274                         }
    14275                         else
    14276                         {
    14277                                 $this->state = 'emit';
    14278                         }
    14279                 }
    14280                 else
    14281                 {
    14282                         $this->state = false;
    14283                 }
    14284         }
    14285 
    14286         function standalone_name()
    14287         {
    14288                 if (substr($this->data, $this->position, 10) === 'standalone')
    14289                 {
    14290                         $this->position += 10;
    14291                         $this->skip_whitespace();
    14292                         $this->state = 'standalone_equals';
    14293                 }
    14294                 else
    14295                 {
    14296                         $this->state = false;
    14297                 }
    14298         }
    14299 
    14300         function standalone_equals()
    14301         {
    14302                 if (substr($this->data, $this->position, 1) === '=')
    14303                 {
    14304                         $this->position++;
    14305                         $this->skip_whitespace();
    14306                         $this->state = 'standalone_value';
    14307                 }
    14308                 else
    14309                 {
    14310                         $this->state = false;
    14311                 }
    14312         }
    14313 
    14314         function standalone_value()
    14315         {
    14316                 if ($standalone = $this->get_value())
    14317                 {
    14318                         switch ($standalone)
    14319                         {
    14320                                 case 'yes':
    14321                                         $this->standalone = true;
    14322                                         break;
    14323 
    14324                                 case 'no':
    14325                                         $this->standalone = false;
    14326                                         break;
    14327 
    14328                                 default:
    14329                                         $this->state = false;
    14330                                         return;
    14331                         }
    14332 
    14333                         $this->skip_whitespace();
    14334                         if ($this->has_data())
    14335                         {
    14336                                 $this->state = false;
    14337                         }
    14338                         else
    14339                         {
    14340                                 $this->state = 'emit';
    14341                         }
    14342                 }
    14343                 else
    14344                 {
    14345                         $this->state = false;
    14346                 }
    14347         }
    14348 }
    14349 
    14350 class SimplePie_Locator
    14351 {
    14352         var $useragent;
    14353         var $timeout;
    14354         var $file;
    14355         var $local = array();
    14356         var $elsewhere = array();
    14357         var $file_class = 'SimplePie_File';
    14358         var $cached_entities = array();
    14359         var $http_base;
    14360         var $base;
    14361         var $base_location = 0;
    14362         var $checked_feeds = 0;
    14363         var $max_checked_feeds = 10;
    14364         var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
    14365 
    14366         function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
    14367         {
    14368                 $this->file =& $file;
    14369                 $this->file_class = $file_class;
    14370                 $this->useragent = $useragent;
    14371                 $this->timeout = $timeout;
    14372                 $this->max_checked_feeds = $max_checked_feeds;
    14373                 $this->content_type_sniffer_class = $content_type_sniffer_class;
    14374         }
    14375 
    14376         function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
    14377         {
    14378                 if ($this->is_feed($this->file))
    14379                 {
    14380                         return $this->file;
    14381                 }
    14382 
    14383                 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
    14384                 {
    14385                         $sniffer =& new $this->content_type_sniffer_class($this->file);
    14386                         if ($sniffer->get_type() !== 'text/html')
    14387                         {
    14388                                 return null;
    14389                         }
    14390                 }
    14391 
    14392                 if ($type & ~SIMPLEPIE_LOCATOR_NONE)
    14393                 {
    14394                         $this->get_base();
    14395                 }
    14396 
    14397                 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
    14398                 {
    14399                         return $working[0];
    14400                 }
    14401 
    14402                 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
    14403                 {
    14404                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
    14405                         {
    14406                                 return $working;
    14407                         }
    14408 
    14409                         if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
    14410                         {
    14411                                 return $working;
    14412                         }
    14413 
    14414                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
    14415                         {
    14416                                 return $working;
    14417                         }
    14418 
    14419                         if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
    14420                         {
    14421                                 return $working;
    14422                         }
    14423                 }
    14424                 return null;
    14425         }
    14426 
    14427         function is_feed(&$file)
    14428         {
    14429                 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
    14430                 {
    14431                         $sniffer =& new $this->content_type_sniffer_class($file);
    14432                         $sniffed = $sniffer->get_type();
    14433                         if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
    14434                         {
    14435                                 return true;
    14436                         }
    14437                         else
    14438                         {
    14439                                 return false;
    14440                         }
    14441                 }
    14442                 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
    14443                 {
    14444                         return true;
    14445                 }
    14446                 else
    14447                 {
    14448                         return false;
    14449                 }
    14450         }
    14451 
    14452         function get_base()
    14453         {
    14454                 $this->http_base = $this->file->url;
    14455                 $this->base = $this->http_base;
    14456                 $elements = SimplePie_Misc::get_element('base', $this->file->body);
    14457                 foreach ($elements as $element)
    14458                 {
    14459                         if ($element['attribs']['href']['data'] !== '')
    14460                         {
    14461                                 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
    14462                                 $this->base_location = $element['offset'];
    14463                                 break;
    14464                         }
    14465                 }
    14466         }
    14467 
    14468         function autodiscovery()
    14469         {
    14470                 $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));
    14471                 $done = array();
    14472                 $feeds = array();
    14473                 foreach ($links as $link)
    14474                 {
    14475                         if ($this->checked_feeds === $this->max_checked_feeds)
    14476                         {
    14477                                 break;
    14478                         }
    14479                         if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
    14480                         {
    14481                                 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
    14482 
    14483                                 if ($this->base_location < $link['offset'])
    14484                                 {
    14485                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
    14486                                 }
    14487                                 else
    14488                                 {
    14489                                         $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
    14490                                 }
    14491 
    14492                                 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'))) && !isset($feeds[$href]))
    14493                                 {
    14494                                         $this->checked_feeds++;
    14495                                         $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
    14496                                         if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
    14497                                         {
    14498                                                 $feeds[$href] = $feed;
    14499                                         }
    14500                                 }
    14501                                 $done[] = $href;
    14502                         }
    14503                 }
    14504 
    14505                 if (!empty($feeds))
    14506                 {
    14507                         return array_values($feeds);
    14508                 }
    14509                 else {
    14510                         return null;
    14511                 }
    14512         }
    14513 
    14514         function get_links()
    14515         {
    14516                 $links = SimplePie_Misc::get_element('a', $this->file->body);
    14517                 foreach ($links as $link)
    14518                 {
    14519                         if (isset($link['attribs']['href']['data']))
    14520                         {
    14521                                 $href = trim($link['attribs']['href']['data']);
    14522                                 $parsed = SimplePie_Misc::parse_url($href);
    14523                                 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
    14524                                 {
    14525                                         if ($this->base_location < $link['offset'])
    14526                                         {
    14527                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
    14528                                         }
    14529                                         else
    14530                                         {
    14531                                                 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
    14532                                         }
    14533 
    14534                                         $current = SimplePie_Misc::parse_url($this->file->url);
    14535 
    14536                                         if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
    14537                                         {
    14538                                                 $this->local[] = $href;
    14539                                         }
    14540                                         else
    14541                                         {
    14542                                                 $this->elsewhere[] = $href;
    14543                                         }
    14544                                 }
    14545                         }
    14546                 }
    14547                 $this->local = array_unique($this->local);
    14548                 $this->elsewhere = array_unique($this->elsewhere);
    14549                 if (!empty($this->local) || !empty($this->elsewhere))
    14550                 {
    14551                         return true;
    14552                 }
    14553                 return null;
    14554         }
    14555 
    14556         function extension(&$array)
    14557         {
    14558                 foreach ($array as $key => $value)
    14559                 {
    14560                         if ($this->checked_feeds === $this->max_checked_feeds)
    14561                         {
    14562                                 break;
    14563                         }
    14564                         if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
    14565                         {
    14566                                 $this->checked_feeds++;
    14567                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
    14568                                 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
    14569                                 {
    14570                                         return $feed;
    14571                                 }
    14572                                 else
    14573                                 {
    14574                                         unset($array[$key]);
    14575                                 }
    14576                         }
    14577                 }
    14578                 return null;
    14579         }
    14580 
    14581         function body(&$array)
    14582         {
    14583                 foreach ($array as $key => $value)
    14584                 {
    14585                         if ($this->checked_feeds === $this->max_checked_feeds)
    14586                         {
    14587                                 break;
    14588                         }
    14589                         if (preg_match('/(rss|rdf|atom|xml)/i', $value))
    14590                         {
    14591                                 $this->checked_feeds++;
    14592                                 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
    14593                                 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
    14594                                 {
    14595                                         return $feed;
    14596                                 }
    14597                                 else
    14598                                 {
    14599                                         unset($array[$key]);
    14600                                 }
    14601                         }
    14602                 }
    14603                 return null;
    14604         }
    14605 }
    14606 
    14607 class SimplePie_Parser
    14608 {
    14609         var $error_code;
    14610         var $error_string;
    14611         var $current_line;
    14612         var $current_column;
    14613         var $current_byte;
    14614         var $separator = ' ';
    14615         var $namespace = array('');
    14616         var $element = array('');
    14617         var $xml_base = array('');
    14618         var $xml_base_explicit = array(false);
    14619         var $xml_lang = array('');
    14620         var $data = array();
    14621         var $datas = array(array());
    14622         var $current_xhtml_construct = -1;
    14623         var $encoding;
    14624 
    14625         function parse(&$data, $encoding)
    14626         {
    14627                 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
    14628                 if (strtoupper($encoding) === 'US-ASCII')
    14629                 {
    14630                         $this->encoding = 'UTF-8';
    14631                 }
    14632                 else
    14633                 {
    14634                         $this->encoding = $encoding;
    14635                 }
    14636 
    14637                 // Strip BOM:
    14638                 // UTF-32 Big Endian BOM
    14639                 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
    14640                 {
    14641                         $data = substr($data, 4);
    14642                 }
    14643                 // UTF-32 Little Endian BOM
    14644                 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
    14645                 {
    14646                         $data = substr($data, 4);
    14647                 }
    14648                 // UTF-16 Big Endian BOM
    14649                 elseif (substr($data, 0, 2) === "\xFE\xFF")
    14650                 {
    14651                         $data = substr($data, 2);
    14652                 }
    14653                 // UTF-16 Little Endian BOM
    14654                 elseif (substr($data, 0, 2) === "\xFF\xFE")
    14655                 {
    14656                         $data = substr($data, 2);
    14657                 }
    14658                 // UTF-8 BOM
    14659                 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
    14660                 {
    14661                         $data = substr($data, 3);
    14662                 }
    14663 
    14664                 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
    14665                 {
    14666                         $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
    14667                         if ($declaration->parse())
    14668                         {
    14669                                 $data = substr($data, $pos + 2);
    14670                                 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
    14671                         }
    14672                         else
    14673                         {
    14674                                 $this->error_string = 'SimplePie bug! Please report this!';
    14675                                 return false;
    14676                         }
    14677                 }
    14678 
    14679                 $return = true;
    14680 
    14681                 static $xml_is_sane = null;
    14682                 if ($xml_is_sane === null)
    14683                 {
    14684                         $parser_check = xml_parser_create();
    14685                         xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
    14686                         xml_parser_free($parser_check);
    14687                         $xml_is_sane = isset($values[0]['value']);
    14688                 }
    14689 
    14690                 // Create the parser
    14691                 if ($xml_is_sane)
    14692                 {
    14693                         $xml = xml_parser_create_ns($this->encoding, $this->separator);
    14694                         xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
    14695                         xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
    14696                         xml_set_object($xml, $this);
    14697                         xml_set_character_data_handler($xml, 'cdata');
    14698                         xml_set_element_handler($xml, 'tag_open', 'tag_close');
    14699 
    14700                         // Parse!
    14701                         if (!xml_parse($xml, $data, true))
    14702                         {
    14703                                 $this->error_code = xml_get_error_code($xml);
    14704                                 $this->error_string = xml_error_string($this->error_code);
    14705                                 $return = false;
    14706                         }
    14707                         $this->current_line = xml_get_current_line_number($xml);
    14708                         $this->current_column = xml_get_current_column_number($xml);
    14709                         $this->current_byte = xml_get_current_byte_index($xml);
    14710                         xml_parser_free($xml);
    14711                         return $return;
    14712                 }
    14713                 else
    14714                 {
    14715                         libxml_clear_errors();
    14716                         $xml =& new XMLReader();
    14717                         $xml->xml($data);
    14718                         while (@$xml->read())
    14719                         {
    14720                                 switch ($xml->nodeType)
    14721                                 {
    14722 
    14723                                         case constant('XMLReader::END_ELEMENT'):
    14724                                                 if ($xml->namespaceURI !== '')
    14725                                                 {
    14726                                                         $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
    14727                                                 }
    14728                                                 else
    14729                                                 {
    14730                                                         $tagName = $xml->localName;
    14731                                                 }
    14732                                                 $this->tag_close(null, $tagName);
    14733                                                 break;
    14734                                         case constant('XMLReader::ELEMENT'):
    14735                                                 $empty = $xml->isEmptyElement;
    14736                                                 if ($xml->namespaceURI !== '')
    14737                                                 {
    14738                                                         $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
    14739                                                 }
    14740                                                 else
    14741                                                 {
    14742                                                         $tagName = $xml->localName;
    14743                                                 }
    14744                                                 $attributes = array();
    14745                                                 while ($xml->moveToNextAttribute())
    14746                                                 {
    14747                                                         if ($xml->namespaceURI !== '')
    14748                                                         {
    14749                                                                 $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
    14750                                                         }
    14751                                                         else
    14752                                                         {
    14753                                                                 $attrName = $xml->localName;
    14754                                                         }
    14755                                                         $attributes[$attrName] = $xml->value;
    14756                                                 }
    14757                                                 $this->tag_open(null, $tagName, $attributes);
    14758                                                 if ($empty)
    14759                                                 {
    14760                                                         $this->tag_close(null, $tagName);
    14761                                                 }
    14762                                                 break;
    14763                                         case constant('XMLReader::TEXT'):
    14764 
    14765                                         case constant('XMLReader::CDATA'):
    14766                                                 $this->cdata(null, $xml->value);
    14767                                                 break;
    14768                                 }
    14769                         }
    14770                         if ($error = libxml_get_last_error())
    14771                         {
    14772                                 $this->error_code = $error->code;
    14773                                 $this->error_string = $error->message;
    14774                                 $this->current_line = $error->line;
    14775                                 $this->current_column = $error->column;
    14776                                 return false;
    14777                         }
    14778                         else
    14779                         {
    14780                                 return true;
    14781                         }
    14782                 }
    14783         }
    14784 
    14785         function get_error_code()
    14786         {
    14787                 return $this->error_code;
    14788         }
    14789 
    14790         function get_error_string()
    14791         {
    14792                 return $this->error_string;
    14793         }
    14794 
    14795         function get_current_line()
    14796         {
    14797                 return $this->current_line;
    14798         }
    14799 
    14800         function get_current_column()
    14801         {
    14802                 return $this->current_column;
    14803         }
    14804 
    14805         function get_current_byte()
    14806         {
    14807                 return $this->current_byte;
    14808         }
    14809 
    14810         function get_data()
    14811         {
    14812                 return $this->data;
    14813         }
    14814 
    14815         function tag_open($parser, $tag, $attributes)
    14816         {
    14817                 list($this->namespace[], $this->element[]) = $this->split_ns($tag);
    14818 
    14819                 $attribs = array();
    14820                 foreach ($attributes as $name => $value)
    14821                 {
    14822                         list($attrib_namespace, $attribute) = $this->split_ns($name);
    14823                         $attribs[$attrib_namespace][$attribute] = $value;
    14824                 }
    14825 
    14826                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
    14827                 {
    14828                         $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
    14829                         $this->xml_base_explicit[] = true;
    14830                 }
    14831                 else
    14832                 {
    14833                         $this->xml_base[] = end($this->xml_base);
    14834                         $this->xml_base_explicit[] = end($this->xml_base_explicit);
    14835                 }
    14836 
    14837                 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
    14838                 {
    14839                         $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
    14840                 }
    14841                 else
    14842                 {
    14843                         $this->xml_lang[] = end($this->xml_lang);
    14844                 }
    14845 
    14846                 if ($this->current_xhtml_construct >= 0)
    14847                 {
    14848                         $this->current_xhtml_construct++;
    14849                         if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
    14850                         {
    14851                                 $this->data['data'] .= '<' . end($this->element);
    14852                                 if (isset($attribs['']))
    14853                                 {
    14854                                         foreach ($attribs[''] as $name => $value)
    14855                                         {
    14856                                                 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
    14857                                         }
    14858                                 }
    14859                                 $this->data['data'] .= '>';
    14860                         }
    14861                 }
    14862                 else
    14863                 {
    14864                         $this->datas[] =& $this->data;
    14865                         $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
    14866                         $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));
    14867                         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')
    14868                         || (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'))
    14869                         {
    14870                                 $this->current_xhtml_construct = 0;
    14871                         }
    14872                 }
    14873         }
    14874 
    14875         function cdata($parser, $cdata)
    14876         {
    14877                 if ($this->current_xhtml_construct >= 0)
    14878                 {
    14879                         $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
    14880                 }
    14881                 else
    14882                 {
    14883                         $this->data['data'] .= $cdata;
    14884                 }
    14885         }
    14886 
    14887         function tag_close($parser, $tag)
    14888         {
    14889                 if ($this->current_xhtml_construct >= 0)
    14890                 {
    14891                         $this->current_xhtml_construct--;
    14892                         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')))
    14893                         {
    14894                                 $this->data['data'] .= '</' . end($this->element) . '>';
    14895                         }
    14896                 }
    14897                 if ($this->current_xhtml_construct === -1)
    14898                 {
    14899                         $this->data =& $this->datas[count($this->datas) - 1];
    14900                         array_pop($this->datas);
    14901                 }
    14902 
    14903                 array_pop($this->element);
    14904                 array_pop($this->namespace);
    14905                 array_pop($this->xml_base);
    14906                 array_pop($this->xml_base_explicit);
    14907                 array_pop($this->xml_lang);
    14908         }
    14909 
    14910         function split_ns($string)
    14911         {
    14912                 static $cache = array();
    14913                 if (!isset($cache[$string]))
    14914                 {
    14915                         if ($pos = strpos($string, $this->separator))
    14916                         {
    14917                                 static $separator_length;
    14918                                 if (!$separator_length)
    14919                                 {
    14920                                         $separator_length = strlen($this->separator);
    14921                                 }
    14922                                 $namespace = substr($string, 0, $pos);
    14923                                 $local_name = substr($string, $pos + $separator_length);
    14924                                 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
    14925                                 {
    14926                                         $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
    14927                                 }
    14928 
    14929                                 // Normalize the Media RSS namespaces
    14930                                 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG)
    14931                                 {
    14932                                         $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
    14933                                 }
    14934                                 $cache[$string] = array($namespace, $local_name);
    14935                         }
    14936                         else
    14937                         {
    14938                                 $cache[$string] = array('', $string);
    14939                         }
    14940                 }
    14941                 return $cache[$string];
    14942         }
    14943 }
    14944 
    14945 /**
    14946  * @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 shorten a string while preserving HTML tags
    14947  */
    14948 class SimplePie_Sanitize
    14949 {
    14950         // Private vars
    14951         var $base;
    14952 
    14953         // Options
    14954         var $remove_div = true;
    14955         var $image_handler = '';
    14956         var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
    14957         var $encode_instead_of_strip = false;
    14958         var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
    14959         var $strip_comments = false;
    14960         var $output_encoding = 'UTF-8';
    14961         var $enable_cache = true;
    14962         var $cache_location = './cache';
    14963         var $cache_name_function = 'md5';
    14964         var $cache_class = 'SimplePie_Cache';
    14965         var $file_class = 'SimplePie_File';
    14966         var $timeout = 10;
    14967         var $useragent = '';
    14968         var $force_fsockopen = false;
    14969 
    14970         var $replace_url_attributes = array(
    14971                 'a' => 'href',
    14972                 'area' => 'href',
    14973                 'blockquote' => 'cite',
    14974                 'del' => 'cite',
    14975                 'form' => 'action',
    14976                 'img' => array('longdesc', 'src'),
    14977                 'input' => 'src',
    14978                 'ins' => 'cite',
    14979                 'q' => 'cite'
    14980         );
    14981 
    14982         function remove_div($enable = true)
    14983         {
    14984                 $this->remove_div = (bool) $enable;
    14985         }
    14986 
    14987         function set_image_handler($page = false)
    14988         {
    14989                 if ($page)
    14990                 {
    14991                         $this->image_handler = (string) $page;
    14992                 }
    14993                 else
    14994                 {
    14995                         $this->image_handler = false;
    14996                 }
    14997         }
    14998 
    14999         function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
    15000         {
    15001                 if (isset($enable_cache))
    15002                 {
    15003                         $this->enable_cache = (bool) $enable_cache;
    15004                 }
    15005 
    15006                 if ($cache_location)
    15007                 {
    15008                         $this->cache_location = (string) $cache_location;
    15009                 }
    15010 
    15011                 if ($cache_name_function)
    15012                 {
    15013                         $this->cache_name_function = (string) $cache_name_function;
    15014                 }
    15015 
    15016                 if ($cache_class)
    15017                 {
    15018                         $this->cache_class = (string) $cache_class;
    15019                 }
    15020         }
    15021 
    15022         function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
    15023         {
    15024                 if ($file_class)
    15025                 {
    15026                         $this->file_class = (string) $file_class;
    15027                 }
    15028 
    15029                 if ($timeout)
    15030                 {
    15031                         $this->timeout = (string) $timeout;
    15032                 }
    15033 
    15034                 if ($useragent)
    15035                 {
    15036                         $this->useragent = (string) $useragent;
    15037                 }
    15038 
    15039                 if ($force_fsockopen)
    15040                 {
    15041                         $this->force_fsockopen = (string) $force_fsockopen;
    15042                 }
    15043         }
    15044 
    15045         function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
    15046         {
    15047                 if ($tags)
    15048                 {
    15049                         if (is_array($tags))
    15050                         {
    15051                                 $this->strip_htmltags = $tags;
    15052                         }
    15053                         else
    15054                         {
    15055                                 $this->strip_htmltags = explode(',', $tags);
    15056                         }
    15057                 }
    15058                 else
    15059                 {
    15060                         $this->strip_htmltags = false;
    15061                 }
    15062         }
    15063 
    15064         function encode_instead_of_strip($encode = false)
    15065         {
    15066                 $this->encode_instead_of_strip = (bool) $encode;
    15067         }
    15068 
    15069         function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
    15070         {
    15071                 if ($attribs)
    15072                 {
    15073                         if (is_array($attribs))
    15074                         {
    15075                                 $this->strip_attributes = $attribs;
    15076                         }
    15077                         else
    15078                         {
    15079                                 $this->strip_attributes = explode(',', $attribs);
    15080                         }
    15081                 }
    15082                 else
    15083                 {
    15084                         $this->strip_attributes = false;
    15085                 }
    15086         }
    15087 
    15088         function strip_comments($strip = false)
    15089         {
    15090                 $this->strip_comments = (bool) $strip;
    15091         }
    15092 
    15093         function set_output_encoding($encoding = 'UTF-8')
    15094         {
    15095                 $this->output_encoding = (string) $encoding;
    15096         }
    15097 
    15098         /**
    15099          * Set element/attribute key/value pairs of HTML attributes
    15100          * containing URLs that need to be resolved relative to the feed
    15101          *
    15102          * @access public
    15103          * @since 1.0
    15104          * @param array $element_attribute Element/attribute key/value pairs
    15105          */
    15106         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'))
    15107         {
    15108                 $this->replace_url_attributes = (array) $element_attribute;
    15109         }
    15110 
    15111         function sanitize($data, $type, $base = '')
    15112         {
    15113                 $data = trim($data);
    15114                 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
    15115                 {
    15116                         if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
    15117                         {
    15118                                 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
    15119                                 {
    15120                                         $type |= SIMPLEPIE_CONSTRUCT_HTML;
    15121                                 }
    15122                                 else
    15123                                 {
    15124                                         $type |= SIMPLEPIE_CONSTRUCT_TEXT;
    15125                                 }
    15126                         }
    15127 
    15128                         if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
    15129                         {
    15130                                 $data = base64_decode($data);
    15131                         }
    15132 
    15133                         if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
    15134                         {
    15135                                 if ($this->remove_div)
    15136                                 {
    15137                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
    15138                                         $data = preg_replace('/<\/div>$/', '', $data);
    15139                                 }
    15140                                 else
    15141                                 {
    15142                                         $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
    15143                                 }
    15144                         }
    15145 
    15146                         if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
    15147                         {
    15148                                 // Strip comments
    15149                                 if ($this->strip_comments)
    15150                                 {
    15151                                         $data = SimplePie_Misc::strip_comments($data);
    15152                                 }
    15153 
    15154                                 // Strip out HTML tags and attributes that might cause various security problems.
    15155                                 // Based on recommendations by Mark Pilgrim at:
    15156                                 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
    15157                                 if ($this->strip_htmltags)
    15158                                 {
    15159                                         foreach ($this->strip_htmltags as $tag)
    15160                                         {
    15161                                                 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
    15162                                                 while (preg_match($pcre, $data))
    15163                                                 {
    15164                                                         $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
    15165                                                 }
    15166                                         }
    15167                                 }
    15168 
    15169                                 if ($this->strip_attributes)
    15170                                 {
    15171                                         foreach ($this->strip_attributes as $attrib)
    15172                                         {
    15173                                                 $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);
    15174                                         }
    15175                                 }
    15176 
    15177                                 // Replace relative URLs
    15178                                 $this->base = $base;
    15179                                 foreach ($this->replace_url_attributes as $element => $attributes)
    15180                                 {
    15181                                         $data = $this->replace_urls($data, $element, $attributes);
    15182                                 }
    15183 
    15184                                 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
    15185                                 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
    15186                                 {
    15187                                         $images = SimplePie_Misc::get_element('img', $data);
    15188                                         foreach ($images as $img)
    15189                                         {
    15190                                                 if (isset($img['attribs']['src']['data']))
    15191                                                 {
    15192                                                         $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
    15193                                                         $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
    15194 
    15195                                                         if ($cache->load())
    15196                                                         {
    15197                                                                 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
    15198                                                                 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
    15199                                                         }
    15200                                                         else
    15201                                                         {
    15202                                                                 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
    15203                                                                 $headers = $file->headers;
    15204 
    15205                                                                 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
    15206                                                                 {
    15207                                                                         if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
    15208                                                                         {
    15209                                                                                 $img['attribs']['src']['data'] = $this->image_handler . $image_url;
    15210                                                                                 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
    15211                                                                         }
    15212                                                                         else
    15213                                                                         {
    15214                                                                                 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
    15215                                                                         }
    15216                                                                 }
    15217                                                         }
    15218                                                 }
    15219                                         }
    15220                                 }
    15221 
    15222                                 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
    15223                                 $data = trim($data);
    15224                         }
    15225 
    15226                         if ($type & SIMPLEPIE_CONSTRUCT_IRI)
    15227                         {
    15228                                 $data = SimplePie_Misc::absolutize_url($data, $base);
    15229                         }
    15230 
    15231                         if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
    15232                         {
    15233                                 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
    15234                         }
    15235 
    15236                         if ($this->output_encoding !== 'UTF-8')
    15237                         {
    15238                                 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
    15239                         }
    15240                 }
    15241                 return $data;
    15242         }
    15243 
    15244         function replace_urls($data, $tag, $attributes)
    15245         {
    15246                 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
    15247                 {
    15248                         $elements = SimplePie_Misc::get_element($tag, $data);
    15249                         foreach ($elements as $element)
    15250                         {
    15251                                 if (is_array($attributes))
    15252                                 {
    15253                                         foreach ($attributes as $attribute)
    15254                                         {
    15255                                                 if (isset($element['attribs'][$attribute]['data']))
    15256                                                 {
    15257                                                         $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
    15258                                                         $new_element = SimplePie_Misc::element_implode($element);
    15259                                                         $data = str_replace($element['full'], $new_element, $data);
    15260                                                         $element['full'] = $new_element;
    15261                                                 }
    15262                                         }
    15263                                 }
    15264                                 elseif (isset($element['attribs'][$attributes]['data']))
    15265                                 {
    15266                                         $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
    15267                                         $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
    15268                                 }
    15269                         }
    15270                 }
    15271                 return $data;
    15272         }
    15273 
    15274         function do_strip_htmltags($match)
    15275         {
    15276                 if ($this->encode_instead_of_strip)
    15277                 {
    15278                         if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
    15279                         {
    15280                                 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
    15281                                 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
    15282                                 return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
    15283                         }
    15284                         else
    15285                         {
    15286                                 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
    15287                         }
    15288                 }
    15289                 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
    15290                 {
    15291                         return $match[4];
    15292                 }
    15293                 else
    15294                 {
    15295                         return '';
    15296                 }
    15297         }
    15298 }
    152993038endif;
    15300 ?>
Note: See TracChangeset for help on using the changeset viewer.