WordPress.org

Make WordPress Core

Changeset 21644


Ignore:
Timestamp:
08/28/2012 05:24:33 PM (9 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