[ Index ]

WordPress Cross Reference

title

Body

[close]

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

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


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu