[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

/wp-includes/ -> class-simplepie.php (source)

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