[ Index ]

PHP Cross Reference of phpwcms V1.5.0 _r431 (28.01.12)

title

Body

[close]

/include/inc_ext/SimplePie/ -> simplepie.inc.php (source)

   1  <?php
   2  /**
   3   * SimplePie
   4   *
   5   * A PHP-Based RSS and Atom Feed Framework.
   6   * Takes the hard work out of managing a complete RSS/Atom solution.
   7   *
   8   * Copyright (c) 2004-2011, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
   9   * All rights reserved.
  10   *
  11   * Redistribution and use in source and binary forms, with or without modification, are
  12   * permitted provided that the following conditions are met:
  13   *
  14   *     * Redistributions of source code must retain the above copyright notice, this list of
  15   *       conditions and the following disclaimer.
  16   *
  17   *     * Redistributions in binary form must reproduce the above copyright notice, this list
  18   *       of conditions and the following disclaimer in the documentation and/or other materials
  19   *       provided with the distribution.
  20   *
  21   *     * Neither the name of the SimplePie Team nor the names of its contributors may be used
  22   *       to endorse or promote products derived from this software without specific prior
  23   *       written permission.
  24   *
  25   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
  26   * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  27   * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
  28   * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  29   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  30   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  31   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  32   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  33   * POSSIBILITY OF SUCH DAMAGE.
  34   *
  35   * @package SimplePie
  36   * @version 1.2.1
  37   * @copyright 2004-2011 Ryan Parman, Geoffrey Sneddon, Ryan McCue
  38   * @author Ryan Parman
  39   * @author Geoffrey Sneddon
  40   * @author Ryan McCue
  41   * @link http://simplepie.org/ SimplePie
  42   * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums
  43   * @license http://www.opensource.org/licenses/bsd-license.php BSD License
  44   * @todo phpDoc comments
  45   */
  46  
  47  /**
  48   * SimplePie Name
  49   */
  50  define('SIMPLEPIE_NAME', 'SimplePie');
  51  
  52  /**
  53   * SimplePie Version
  54   */
  55  define('SIMPLEPIE_VERSION', '1.2.1-dev');
  56  
  57  /**
  58   * SimplePie Build
  59   */
  60  define('SIMPLEPIE_BUILD', '20111015034325');
  61  
  62  /**
  63   * SimplePie Website URL
  64   */
  65  define('SIMPLEPIE_URL', 'http://simplepie.org');
  66  
  67  /**
  68   * SimplePie Useragent
  69   * @see SimplePie::set_useragent()
  70   */
  71  define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
  72  
  73  /**
  74   * SimplePie Linkback
  75   */
  76  define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
  77  
  78  /**
  79   * No Autodiscovery
  80   * @see SimplePie::set_autodiscovery_level()
  81   */
  82  define('SIMPLEPIE_LOCATOR_NONE', 0);
  83  
  84  /**
  85   * Feed Link Element Autodiscovery
  86   * @see SimplePie::set_autodiscovery_level()
  87   */
  88  define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
  89  
  90  /**
  91   * Local Feed Extension Autodiscovery
  92   * @see SimplePie::set_autodiscovery_level()
  93   */
  94  define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
  95  
  96  /**
  97   * Local Feed Body Autodiscovery
  98   * @see SimplePie::set_autodiscovery_level()
  99   */
 100  define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
 101  
 102  /**
 103   * Remote Feed Extension Autodiscovery
 104   * @see SimplePie::set_autodiscovery_level()
 105   */
 106  define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
 107  
 108  /**
 109   * Remote Feed Body Autodiscovery
 110   * @see SimplePie::set_autodiscovery_level()
 111   */
 112  define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
 113  
 114  /**
 115   * All Feed Autodiscovery
 116   * @see SimplePie::set_autodiscovery_level()
 117   */
 118  define('SIMPLEPIE_LOCATOR_ALL', 31);
 119  
 120  /**
 121   * No known feed type
 122   */
 123  define('SIMPLEPIE_TYPE_NONE', 0);
 124  
 125  /**
 126   * RSS 0.90
 127   */
 128  define('SIMPLEPIE_TYPE_RSS_090', 1);
 129  
 130  /**
 131   * RSS 0.91 (Netscape)
 132   */
 133  define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
 134  
 135  /**
 136   * RSS 0.91 (Userland)
 137   */
 138  define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
 139  
 140  /**
 141   * RSS 0.91 (both Netscape and Userland)
 142   */
 143  define('SIMPLEPIE_TYPE_RSS_091', 6);
 144  
 145  /**
 146   * RSS 0.92
 147   */
 148  define('SIMPLEPIE_TYPE_RSS_092', 8);
 149  
 150  /**
 151   * RSS 0.93
 152   */
 153  define('SIMPLEPIE_TYPE_RSS_093', 16);
 154  
 155  /**
 156   * RSS 0.94
 157   */
 158  define('SIMPLEPIE_TYPE_RSS_094', 32);
 159  
 160  /**
 161   * RSS 1.0
 162   */
 163  define('SIMPLEPIE_TYPE_RSS_10', 64);
 164  
 165  /**
 166   * RSS 2.0
 167   */
 168  define('SIMPLEPIE_TYPE_RSS_20', 128);
 169  
 170  /**
 171   * RDF-based RSS
 172   */
 173  define('SIMPLEPIE_TYPE_RSS_RDF', 65);
 174  
 175  /**
 176   * Non-RDF-based RSS (truly intended as syndication format)
 177   */
 178  define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
 179  
 180  /**
 181   * All RSS
 182   */
 183  define('SIMPLEPIE_TYPE_RSS_ALL', 255);
 184  
 185  /**
 186   * Atom 0.3
 187   */
 188  define('SIMPLEPIE_TYPE_ATOM_03', 256);
 189  
 190  /**
 191   * Atom 1.0
 192   */
 193  define('SIMPLEPIE_TYPE_ATOM_10', 512);
 194  
 195  /**
 196   * All Atom
 197   */
 198  define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
 199  
 200  /**
 201   * All feed types
 202   */
 203  define('SIMPLEPIE_TYPE_ALL', 1023);
 204  
 205  /**
 206   * No construct
 207   */
 208  define('SIMPLEPIE_CONSTRUCT_NONE', 0);
 209  
 210  /**
 211   * Text construct
 212   */
 213  define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
 214  
 215  /**
 216   * HTML construct
 217   */
 218  define('SIMPLEPIE_CONSTRUCT_HTML', 2);
 219  
 220  /**
 221   * XHTML construct
 222   */
 223  define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
 224  
 225  /**
 226   * base64-encoded construct
 227   */
 228  define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
 229  
 230  /**
 231   * IRI construct
 232   */
 233  define('SIMPLEPIE_CONSTRUCT_IRI', 16);
 234  
 235  /**
 236   * A construct that might be HTML
 237   */
 238  define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
 239  
 240  /**
 241   * All constructs
 242   */
 243  define('SIMPLEPIE_CONSTRUCT_ALL', 63);
 244  
 245  /**
 246   * Don't change case
 247   */
 248  define('SIMPLEPIE_SAME_CASE', 1);
 249  
 250  /**
 251   * Change to lowercase
 252   */
 253  define('SIMPLEPIE_LOWERCASE', 2);
 254  
 255  /**
 256   * Change to uppercase
 257   */
 258  define('SIMPLEPIE_UPPERCASE', 4);
 259  
 260  /**
 261   * PCRE for HTML attributes
 262   */
 263  define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
 264  
 265  /**
 266   * PCRE for XML attributes
 267   */
 268  define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
 269  
 270  /**
 271   * XML Namespace
 272   */
 273  define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
 274  
 275  /**
 276   * Atom 1.0 Namespace
 277   */
 278  define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
 279  
 280  /**
 281   * Atom 0.3 Namespace
 282   */
 283  define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
 284  
 285  /**
 286   * RDF Namespace
 287   */
 288  define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
 289  
 290  /**
 291   * RSS 0.90 Namespace
 292   */
 293  define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
 294  
 295  /**
 296   * RSS 1.0 Namespace
 297   */
 298  define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
 299  
 300  /**
 301   * RSS 1.0 Content Module Namespace
 302   */
 303  define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
 304  
 305  /**
 306   * RSS 2.0 Namespace
 307   * (Stupid, I know, but I'm certain it will confuse people less with support.)
 308   */
 309  define('SIMPLEPIE_NAMESPACE_RSS_20', '');
 310  
 311  /**
 312   * DC 1.0 Namespace
 313   */
 314  define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
 315  
 316  /**
 317   * DC 1.1 Namespace
 318   */
 319  define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
 320  
 321  /**
 322   * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
 323   */
 324  define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
 325  
 326  /**
 327   * GeoRSS Namespace
 328   */
 329  define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
 330  
 331  /**
 332   * Media RSS Namespace
 333   */
 334  define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
 335  
 336  /**
 337   * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec.
 338   */
 339  define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
 340  
 341  /**
 342   * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5.
 343   */
 344  define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss');
 345  
 346  /**
 347   * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace.
 348   */
 349  define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/');
 350  
 351  /**
 352   * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace.
 353   */
 354  define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss');
 355  
 356  /**
 357   * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL.
 358   */
 359  define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/');
 360  
 361  /**
 362   * iTunes RSS Namespace
 363   */
 364  define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
 365  
 366  /**
 367   * XHTML Namespace
 368   */
 369  define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
 370  
 371  /**
 372   * IANA Link Relations Registry
 373   */
 374  define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
 375  
 376  /**
 377   * Whether we're running on PHP5
 378   */
 379  define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>='));
 380  
 381  /**
 382   * No file source
 383   */
 384  define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
 385  
 386  /**
 387   * Remote file source
 388   */
 389  define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
 390  
 391  /**
 392   * Local file source
 393   */
 394  define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
 395  
 396  /**
 397   * fsockopen() file source
 398   */
 399  define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
 400  
 401  /**
 402   * cURL file source
 403   */
 404  define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
 405  
 406  /**
 407   * file_get_contents() file source
 408   */
 409  define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
 410  
 411  /**
 412   * SimplePie
 413   *
 414   * @package SimplePie
 415   */
 416  class SimplePie
 417  {
 418      /**
 419       * @var array Raw data
 420       * @access private
 421       */
 422      var $data = array();
 423  
 424      /**
 425       * @var mixed Error string
 426       * @access private
 427       */
 428      var $error;
 429  
 430      /**
 431       * @var object Instance of SimplePie_Sanitize (or other class)
 432       * @see SimplePie::set_sanitize_class()
 433       * @access private
 434       */
 435      var $sanitize;
 436  
 437      /**
 438       * @var string SimplePie Useragent
 439       * @see SimplePie::set_useragent()
 440       * @access private
 441       */
 442      var $useragent = SIMPLEPIE_USERAGENT;
 443  
 444      /**
 445       * @var string Feed URL
 446       * @see SimplePie::set_feed_url()
 447       * @access private
 448       */
 449      var $feed_url;
 450  
 451      /**
 452       * @var object Instance of SimplePie_File to use as a feed
 453       * @see SimplePie::set_file()
 454       * @access private
 455       */
 456      var $file;
 457  
 458      /**
 459       * @var string Raw feed data
 460       * @see SimplePie::set_raw_data()
 461       * @access private
 462       */
 463      var $raw_data;
 464  
 465      /**
 466       * @var int Timeout for fetching remote files
 467       * @see SimplePie::set_timeout()
 468       * @access private
 469       */
 470      var $timeout = 10;
 471  
 472      /**
 473       * @var bool Forces fsockopen() to be used for remote files instead
 474       * of cURL, even if a new enough version is installed
 475       * @see SimplePie::force_fsockopen()
 476       * @access private
 477       */
 478      var $force_fsockopen = false;
 479  
 480      /**
 481       * @var bool Force the given data/URL to be treated as a feed no matter what
 482       * it appears like
 483       * @see SimplePie::force_feed()
 484       * @access private
 485       */
 486      var $force_feed = false;
 487  
 488      /**
 489       * @var bool Enable/Disable XML dump
 490       * @see SimplePie::enable_xml_dump()
 491       * @access private
 492       */
 493      var $xml_dump = false;
 494  
 495      /**
 496       * @var bool Enable/Disable Caching
 497       * @see SimplePie::enable_cache()
 498       * @access private
 499       */
 500      var $cache = true;
 501  
 502      /**
 503       * @var int Cache duration (in seconds)
 504       * @see SimplePie::set_cache_duration()
 505       * @access private
 506       */
 507      var $cache_duration = 3600;
 508  
 509      /**
 510       * @var int Auto-discovery cache duration (in seconds)
 511       * @see SimplePie::set_autodiscovery_cache_duration()
 512       * @access private
 513       */
 514      var $autodiscovery_cache_duration = 604800; // 7 Days.
 515  
 516      /**
 517       * @var string Cache location (relative to executing script)
 518       * @see SimplePie::set_cache_location()
 519       * @access private
 520       */
 521      var $cache_location = './cache';
 522  
 523      /**
 524       * @var string Function that creates the cache filename
 525       * @see SimplePie::set_cache_name_function()
 526       * @access private
 527       */
 528      var $cache_name_function = 'md5';
 529  
 530      /**
 531       * @var bool Reorder feed by date descending
 532       * @see SimplePie::enable_order_by_date()
 533       * @access private
 534       */
 535      var $order_by_date = true;
 536  
 537      /**
 538       * @var mixed Force input encoding to be set to the follow value
 539       * (false, or anything type-cast to false, disables this feature)
 540       * @see SimplePie::set_input_encoding()
 541       * @access private
 542       */
 543      var $input_encoding = false;
 544  
 545      /**
 546       * @var int Feed Autodiscovery Level
 547       * @see SimplePie::set_autodiscovery_level()
 548       * @access private
 549       */
 550      var $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
 551  
 552      /**
 553       * @var string Class used for caching feeds
 554       * @see SimplePie::set_cache_class()
 555       * @access private
 556       */
 557      var $cache_class = 'SimplePie_Cache';
 558  
 559      /**
 560       * @var string Class used for locating feeds
 561       * @see SimplePie::set_locator_class()
 562       * @access private
 563       */
 564      var $locator_class = 'SimplePie_Locator';
 565  
 566      /**
 567       * @var string Class used for parsing feeds
 568       * @see SimplePie::set_parser_class()
 569       * @access private
 570       */
 571      var $parser_class = 'SimplePie_Parser';
 572  
 573      /**
 574       * @var string Class used for fetching feeds
 575       * @see SimplePie::set_file_class()
 576       * @access private
 577       */
 578      var $file_class = 'SimplePie_File';
 579  
 580      /**
 581       * @var string Class used for items
 582       * @see SimplePie::set_item_class()
 583       * @access private
 584       */
 585      var $item_class = 'SimplePie_Item';
 586  
 587      /**
 588       * @var string Class used for authors
 589       * @see SimplePie::set_author_class()
 590       * @access private
 591       */
 592      var $author_class = 'SimplePie_Author';
 593  
 594      /**
 595       * @var string Class used for categories
 596       * @see SimplePie::set_category_class()
 597       * @access private
 598       */
 599      var $category_class = 'SimplePie_Category';
 600  
 601      /**
 602       * @var string Class used for enclosures
 603       * @see SimplePie::set_enclosures_class()
 604       * @access private
 605       */
 606      var $enclosure_class = 'SimplePie_Enclosure';
 607  
 608      /**
 609       * @var string Class used for Media RSS <media:text> captions
 610       * @see SimplePie::set_caption_class()
 611       * @access private
 612       */
 613      var $caption_class = 'SimplePie_Caption';
 614  
 615      /**
 616       * @var string Class used for Media RSS <media:copyright>
 617       * @see SimplePie::set_copyright_class()
 618       * @access private
 619       */
 620      var $copyright_class = 'SimplePie_Copyright';
 621  
 622      /**
 623       * @var string Class used for Media RSS <media:credit>
 624       * @see SimplePie::set_credit_class()
 625       * @access private
 626       */
 627      var $credit_class = 'SimplePie_Credit';
 628  
 629      /**
 630       * @var string Class used for Media RSS <media:rating>
 631       * @see SimplePie::set_rating_class()
 632       * @access private
 633       */
 634      var $rating_class = 'SimplePie_Rating';
 635  
 636      /**
 637       * @var string Class used for Media RSS <media:restriction>
 638       * @see SimplePie::set_restriction_class()
 639       * @access private
 640       */
 641      var $restriction_class = 'SimplePie_Restriction';
 642  
 643      /**
 644       * @var string Class used for content-type sniffing
 645       * @see SimplePie::set_content_type_sniffer_class()
 646       * @access private
 647       */
 648      var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
 649  
 650      /**
 651       * @var string Class used for item sources.
 652       * @see SimplePie::set_source_class()
 653       * @access private
 654       */
 655      var $source_class = 'SimplePie_Source';
 656  
 657      /**
 658       * @var mixed Set javascript query string parameter (false, or
 659       * anything type-cast to false, disables this feature)
 660       * @see SimplePie::set_javascript()
 661       * @access private
 662       */
 663      var $javascript = 'js';
 664  
 665      /**
 666       * @var int Maximum number of feeds to check with autodiscovery
 667       * @see SimplePie::set_max_checked_feeds()
 668       * @access private
 669       */
 670      var $max_checked_feeds = 10;
 671  
 672      /**
 673       * @var array All the feeds found during the autodiscovery process
 674       * @see SimplePie::get_all_discovered_feeds()
 675       * @access private
 676       */
 677      var $all_discovered_feeds = array();
 678  
 679      /**
 680       * @var string Web-accessible path to the handler_favicon.php file.
 681       * @see SimplePie::set_favicon_handler()
 682       * @access private
 683       */
 684      var $favicon_handler = '';
 685  
 686      /**
 687       * @var string Web-accessible path to the handler_image.php file.
 688       * @see SimplePie::set_image_handler()
 689       * @access private
 690       */
 691      var $image_handler = '';
 692  
 693      /**
 694       * @var array Stores the URLs when multiple feeds are being initialized.
 695       * @see SimplePie::set_feed_url()
 696       * @access private
 697       */
 698      var $multifeed_url = array();
 699  
 700      /**
 701       * @var array Stores SimplePie objects when multiple feeds initialized.
 702       * @access private
 703       */
 704      var $multifeed_objects = array();
 705  
 706      /**
 707       * @var array Stores the get_object_vars() array for use with multifeeds.
 708       * @see SimplePie::set_feed_url()
 709       * @access private
 710       */
 711      var $config_settings = null;
 712  
 713      /**
 714       * @var integer Stores the number of items to return per-feed with multifeeds.
 715       * @see SimplePie::set_item_limit()
 716       * @access private
 717       */
 718      var $item_limit = 0;
 719  
 720      /**
 721       * @var array Stores the default attributes to be stripped by strip_attributes().
 722       * @see SimplePie::strip_attributes()
 723       * @access private
 724       */
 725      var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
 726  
 727      /**
 728       * @var array Stores the default tags to be stripped by strip_htmltags().
 729       * @see SimplePie::strip_htmltags()
 730       * @access private
 731       */
 732      var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
 733  
 734      /**
 735       * The SimplePie class contains feed level data and options
 736       *
 737       * There are two ways that you can create a new SimplePie object. The first
 738       * is by passing a feed URL as a parameter to the SimplePie constructor
 739       * (as well as optionally setting the cache location and cache expiry). This
 740       * will initialise the whole feed with all of the default settings, and you
 741       * can begin accessing methods and properties immediately.
 742       *
 743       * The second way is to create the SimplePie object with no parameters
 744       * at all. This will enable you to set configuration options. After setting
 745       * them, you must initialise the feed using $feed->init(). At that point the
 746       * object's methods and properties will be available to you. This format is
 747       * what is used throughout this documentation.
 748       *
 749       * @access public
 750       * @since 1.0 Preview Release
 751       * @param string $feed_url This is the URL you want to parse.
 752       * @param string $cache_location This is where you want the cache to be stored.
 753       * @param int $cache_duration This is the number of seconds that you want to store the cache file for.
 754       */
 755  	function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null)
 756      {
 757          // Other objects, instances created here so we can set options on them
 758          $this->sanitize = new SimplePie_Sanitize;
 759  
 760          // Set options if they're passed to the constructor
 761          if ($cache_location !== null)
 762          {
 763              $this->set_cache_location($cache_location);
 764          }
 765  
 766          if ($cache_duration !== null)
 767          {
 768              $this->set_cache_duration($cache_duration);
 769          }
 770  
 771          // Only init the script if we're passed a feed URL
 772          if ($feed_url !== null)
 773          {
 774              $this->set_feed_url($feed_url);
 775              $this->init();
 776          }
 777      }
 778  
 779      /**
 780       * Used for converting object to a string
 781       */
 782  	function __toString()
 783      {
 784          return md5(serialize($this->data));
 785      }
 786  
 787      /**
 788       * Remove items that link back to this before destroying this object
 789       */
 790  	function __destruct()
 791      {
 792          if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
 793          {
 794              if (!empty($this->data['items']))
 795              {
 796                  foreach ($this->data['items'] as $item)
 797                  {
 798                      $item->__destruct();
 799                  }
 800                  unset($item, $this->data['items']);
 801              }
 802              if (!empty($this->data['ordered_items']))
 803              {
 804                  foreach ($this->data['ordered_items'] as $item)
 805                  {
 806                      $item->__destruct();
 807                  }
 808                  unset($item, $this->data['ordered_items']);
 809              }
 810          }
 811      }
 812  
 813      /**
 814       * Force the given data/URL to be treated as a feed no matter what it
 815       * appears like
 816       *
 817       * @access public
 818       * @since 1.1
 819       * @param bool $enable Force the given data/URL to be treated as a feed
 820       */
 821  	function force_feed($enable = false)
 822      {
 823          $this->force_feed = (bool) $enable;
 824      }
 825  
 826      /**
 827       * This is the URL of the feed you want to parse.
 828       *
 829       * This allows you to enter the URL of the feed you want to parse, or the
 830       * website you want to try to use auto-discovery on. This takes priority
 831       * over any set raw data.
 832       *
 833       * You can set multiple feeds to mash together by passing an array instead
 834       * of a string for the $url. Remember that with each additional feed comes
 835       * additional processing and resources.
 836       *
 837       * @access public
 838       * @since 1.0 Preview Release
 839       * @param mixed $url This is the URL (or array of URLs) that you want to parse.
 840       * @see SimplePie::set_raw_data()
 841       */
 842  	function set_feed_url($url)
 843      {
 844          if (is_array($url))
 845          {
 846              $this->multifeed_url = array();
 847              foreach ($url as $value)
 848              {
 849                  $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1);
 850              }
 851          }
 852          else
 853          {
 854              $this->feed_url = SimplePie_Misc::fix_protocol($url, 1);
 855          }
 856      }
 857  
 858      /**
 859       * Provides an instance of SimplePie_File to use as a feed
 860       *
 861       * @access public
 862       * @param object &$file Instance of SimplePie_File (or subclass)
 863       * @return bool True on success, false on failure
 864       */
 865  	function set_file(&$file)
 866      {
 867          if (is_a($file, 'SimplePie_File'))
 868          {
 869              $this->feed_url = $file->url;
 870              $this->file =& $file;
 871              return true;
 872          }
 873          return false;
 874      }
 875  
 876      /**
 877       * Allows you to use a string of RSS/Atom data instead of a remote feed.
 878       *
 879       * If you have a feed available as a string in PHP, you can tell SimplePie
 880       * to parse that data string instead of a remote feed. Any set feed URL
 881       * takes precedence.
 882       *
 883       * @access public
 884       * @since 1.0 Beta 3
 885       * @param string $data RSS or Atom data as a string.
 886       * @see SimplePie::set_feed_url()
 887       */
 888  	function set_raw_data($data)
 889      {
 890          $this->raw_data = $data;
 891      }
 892  
 893      /**
 894       * Allows you to override the default timeout for fetching remote feeds.
 895       *
 896       * This allows you to change the maximum time the feed's server to respond
 897       * and send the feed back.
 898       *
 899       * @access public
 900       * @since 1.0 Beta 3
 901       * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
 902       */
 903  	function set_timeout($timeout = 10)
 904      {
 905          $this->timeout = (int) $timeout;
 906      }
 907  
 908      /**
 909       * Forces SimplePie to use fsockopen() instead of the preferred cURL
 910       * functions.
 911       *
 912       * @access public
 913       * @since 1.0 Beta 3
 914       * @param bool $enable Force fsockopen() to be used
 915       */
 916  	function force_fsockopen($enable = false)
 917      {
 918          $this->force_fsockopen = (bool) $enable;
 919      }
 920  
 921      /**
 922       * Outputs the raw XML content of the feed, after it has gone through
 923       * SimplePie's filters.
 924       *
 925       * Used only for debugging, this function will output the XML content as
 926       * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up
 927       * before trying to parse it. Many parts of the feed are re-written in
 928       * memory, and in the end, you have a parsable feed. XML dump shows you the
 929       * actual XML that SimplePie tries to parse, which may or may not be very
 930       * different from the original feed.
 931       *
 932       * @access public
 933       * @since 1.0 Preview Release
 934       * @param bool $enable Enable XML dump
 935       */
 936  	function enable_xml_dump($enable = false)
 937      {
 938          $this->xml_dump = (bool) $enable;
 939      }
 940  
 941      /**
 942       * Enables/disables caching in SimplePie.
 943       *
 944       * This option allows you to disable caching all-together in SimplePie.
 945       * However, disabling the cache can lead to longer load times.
 946       *
 947       * @access public
 948       * @since 1.0 Preview Release
 949       * @param bool $enable Enable caching
 950       */
 951  	function enable_cache($enable = true)
 952      {
 953          $this->cache = (bool) $enable;
 954      }
 955  
 956      /**
 957       * Set the length of time (in seconds) that the contents of a feed
 958       * will be cached.
 959       *
 960       * @access public
 961       * @param int $seconds The feed content cache duration.
 962       */
 963  	function set_cache_duration($seconds = 3600)
 964      {
 965          $this->cache_duration = (int) $seconds;
 966      }
 967  
 968      /**
 969       * Set the length of time (in seconds) that the autodiscovered feed
 970       * URL will be cached.
 971       *
 972       * @access public
 973       * @param int $seconds The autodiscovered feed URL cache duration.
 974       */
 975  	function set_autodiscovery_cache_duration($seconds = 604800)
 976      {
 977          $this->autodiscovery_cache_duration = (int) $seconds;
 978      }
 979  
 980      /**
 981       * Set the file system location where the cached files should be stored.
 982       *
 983       * @access public
 984       * @param string $location The file system location.
 985       */
 986  	function set_cache_location($location = './cache')
 987      {
 988          $this->cache_location = (string) $location;
 989      }
 990  
 991      /**
 992       * Determines whether feed items should be sorted into reverse chronological order.
 993       *
 994       * @access public
 995       * @param bool $enable Sort as reverse chronological order.
 996       */
 997  	function enable_order_by_date($enable = true)
 998      {
 999          $this->order_by_date = (bool) $enable;
1000      }
1001  
1002      /**
1003       * Allows you to override the character encoding reported by the feed.
1004       *
1005       * @access public
1006       * @param string $encoding Character encoding.
1007       */
1008  	function set_input_encoding($encoding = false)
1009      {
1010          if ($encoding)
1011          {
1012              $this->input_encoding = (string) $encoding;
1013          }
1014          else
1015          {
1016              $this->input_encoding = false;
1017          }
1018      }
1019  
1020      /**
1021       * Set how much feed autodiscovery to do
1022       *
1023       * @access public
1024       * @see SIMPLEPIE_LOCATOR_NONE
1025       * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
1026       * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
1027       * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
1028       * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
1029       * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
1030       * @see SIMPLEPIE_LOCATOR_ALL
1031       * @param int $level Feed Autodiscovery Level (level can be a
1032       * combination of the above constants, see bitwise OR operator)
1033       */
1034  	function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
1035      {
1036          $this->autodiscovery = (int) $level;
1037      }
1038  
1039      /**
1040       * Allows you to change which class SimplePie uses for caching.
1041       * Useful when you are overloading or extending SimplePie's default classes.
1042       *
1043       * @access public
1044       * @param string $class Name of custom class.
1045       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1046       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1047       */
1048  	function set_cache_class($class = 'SimplePie_Cache')
1049      {
1050          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache'))
1051          {
1052              $this->cache_class = $class;
1053              return true;
1054          }
1055          return false;
1056      }
1057  
1058      /**
1059       * Allows you to change which class SimplePie uses for auto-discovery.
1060       * Useful when you are overloading or extending SimplePie's default classes.
1061       *
1062       * @access public
1063       * @param string $class Name of custom class.
1064       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1065       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1066       */
1067  	function set_locator_class($class = 'SimplePie_Locator')
1068      {
1069          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator'))
1070          {
1071              $this->locator_class = $class;
1072              return true;
1073          }
1074          return false;
1075      }
1076  
1077      /**
1078       * Allows you to change which class SimplePie uses for XML parsing.
1079       * Useful when you are overloading or extending SimplePie's default classes.
1080       *
1081       * @access public
1082       * @param string $class Name of custom class.
1083       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1084       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1085       */
1086  	function set_parser_class($class = 'SimplePie_Parser')
1087      {
1088          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser'))
1089          {
1090              $this->parser_class = $class;
1091              return true;
1092          }
1093          return false;
1094      }
1095  
1096      /**
1097       * Allows you to change which class SimplePie uses for remote file fetching.
1098       * Useful when you are overloading or extending SimplePie's default classes.
1099       *
1100       * @access public
1101       * @param string $class Name of custom class.
1102       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1103       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1104       */
1105  	function set_file_class($class = 'SimplePie_File')
1106      {
1107          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File'))
1108          {
1109              $this->file_class = $class;
1110              return true;
1111          }
1112          return false;
1113      }
1114  
1115      /**
1116       * Allows you to change which class SimplePie uses for data sanitization.
1117       * Useful when you are overloading or extending SimplePie's default classes.
1118       *
1119       * @access public
1120       * @param string $class Name of custom class.
1121       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1122       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1123       */
1124  	function set_sanitize_class($class = 'SimplePie_Sanitize')
1125      {
1126          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize'))
1127          {
1128              $this->sanitize = new $class();
1129              return true;
1130          }
1131          return false;
1132      }
1133  
1134      /**
1135       * Allows you to change which class SimplePie uses for handling feed items.
1136       * Useful when you are overloading or extending SimplePie's default classes.
1137       *
1138       * @access public
1139       * @param string $class Name of custom class.
1140       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1141       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1142       */
1143  	function set_item_class($class = 'SimplePie_Item')
1144      {
1145          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item'))
1146          {
1147              $this->item_class = $class;
1148              return true;
1149          }
1150          return false;
1151      }
1152  
1153      /**
1154       * Allows you to change which class SimplePie uses for handling author data.
1155       * Useful when you are overloading or extending SimplePie's default classes.
1156       *
1157       * @access public
1158       * @param string $class Name of custom class.
1159       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1160       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1161       */
1162  	function set_author_class($class = 'SimplePie_Author')
1163      {
1164          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author'))
1165          {
1166              $this->author_class = $class;
1167              return true;
1168          }
1169          return false;
1170      }
1171  
1172      /**
1173       * Allows you to change which class SimplePie uses for handling category data.
1174       * Useful when you are overloading or extending SimplePie's default classes.
1175       *
1176       * @access public
1177       * @param string $class Name of custom class.
1178       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1179       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1180       */
1181  	function set_category_class($class = 'SimplePie_Category')
1182      {
1183          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category'))
1184          {
1185              $this->category_class = $class;
1186              return true;
1187          }
1188          return false;
1189      }
1190  
1191      /**
1192       * Allows you to change which class SimplePie uses for feed enclosures.
1193       * Useful when you are overloading or extending SimplePie's default classes.
1194       *
1195       * @access public
1196       * @param string $class Name of custom class.
1197       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1198       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1199       */
1200  	function set_enclosure_class($class = 'SimplePie_Enclosure')
1201      {
1202          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure'))
1203          {
1204              $this->enclosure_class = $class;
1205              return true;
1206          }
1207          return false;
1208      }
1209  
1210      /**
1211       * Allows you to change which class SimplePie uses for <media:text> captions
1212       * Useful when you are overloading or extending SimplePie's default classes.
1213       *
1214       * @access public
1215       * @param string $class Name of custom class.
1216       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1217       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1218       */
1219  	function set_caption_class($class = 'SimplePie_Caption')
1220      {
1221          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption'))
1222          {
1223              $this->caption_class = $class;
1224              return true;
1225          }
1226          return false;
1227      }
1228  
1229      /**
1230       * Allows you to change which class SimplePie uses for <media:copyright>
1231       * Useful when you are overloading or extending SimplePie's default classes.
1232       *
1233       * @access public
1234       * @param string $class Name of custom class.
1235       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1236       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1237       */
1238  	function set_copyright_class($class = 'SimplePie_Copyright')
1239      {
1240          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright'))
1241          {
1242              $this->copyright_class = $class;
1243              return true;
1244          }
1245          return false;
1246      }
1247  
1248      /**
1249       * Allows you to change which class SimplePie uses for <media:credit>
1250       * Useful when you are overloading or extending SimplePie's default classes.
1251       *
1252       * @access public
1253       * @param string $class Name of custom class.
1254       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1255       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1256       */
1257  	function set_credit_class($class = 'SimplePie_Credit')
1258      {
1259          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit'))
1260          {
1261              $this->credit_class = $class;
1262              return true;
1263          }
1264          return false;
1265      }
1266  
1267      /**
1268       * Allows you to change which class SimplePie uses for <media:rating>
1269       * Useful when you are overloading or extending SimplePie's default classes.
1270       *
1271       * @access public
1272       * @param string $class Name of custom class.
1273       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1274       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1275       */
1276  	function set_rating_class($class = 'SimplePie_Rating')
1277      {
1278          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating'))
1279          {
1280              $this->rating_class = $class;
1281              return true;
1282          }
1283          return false;
1284      }
1285  
1286      /**
1287       * Allows you to change which class SimplePie uses for <media:restriction>
1288       * Useful when you are overloading or extending SimplePie's default classes.
1289       *
1290       * @access public
1291       * @param string $class Name of custom class.
1292       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1293       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1294       */
1295  	function set_restriction_class($class = 'SimplePie_Restriction')
1296      {
1297          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction'))
1298          {
1299              $this->restriction_class = $class;
1300              return true;
1301          }
1302          return false;
1303      }
1304  
1305      /**
1306       * Allows you to change which class SimplePie uses for content-type sniffing.
1307       * Useful when you are overloading or extending SimplePie's default classes.
1308       *
1309       * @access public
1310       * @param string $class Name of custom class.
1311       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1312       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1313       */
1314  	function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
1315      {
1316          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer'))
1317          {
1318              $this->content_type_sniffer_class = $class;
1319              return true;
1320          }
1321          return false;
1322      }
1323  
1324      /**
1325       * Allows you to change which class SimplePie uses item sources.
1326       * Useful when you are overloading or extending SimplePie's default classes.
1327       *
1328       * @access public
1329       * @param string $class Name of custom class.
1330       * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation
1331       * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
1332       */
1333  	function set_source_class($class = 'SimplePie_Source')
1334      {
1335          if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source'))
1336          {
1337              $this->source_class = $class;
1338              return true;
1339          }
1340          return false;
1341      }
1342  
1343      /**
1344       * Allows you to override the default user agent string.
1345       *
1346       * @access public
1347       * @param string $ua New user agent string.
1348       */
1349  	function set_useragent($ua = SIMPLEPIE_USERAGENT)
1350      {
1351          $this->useragent = (string) $ua;
1352      }
1353  
1354      /**
1355       * Set callback function to create cache filename with
1356       *
1357       * @access public
1358       * @param mixed $function Callback function
1359       */
1360  	function set_cache_name_function($function = 'md5')
1361      {
1362          if (is_callable($function))
1363          {
1364              $this->cache_name_function = $function;
1365          }
1366      }
1367  
1368      /**
1369       * Set javascript query string parameter
1370       *
1371       * @access public
1372       * @param mixed $get Javascript query string parameter
1373       */
1374  	function set_javascript($get = 'js')
1375      {
1376          if ($get)
1377          {
1378              $this->javascript = (string) $get;
1379          }
1380          else
1381          {
1382              $this->javascript = false;
1383          }
1384      }
1385  
1386      /**
1387       * Set options to make SP as fast as possible.  Forgoes a
1388       * substantial amount of data sanitization in favor of speed.
1389       *
1390       * @access public
1391       * @param bool $set Whether to set them or not
1392       */
1393  	function set_stupidly_fast($set = false)
1394      {
1395          if ($set)
1396          {
1397              $this->enable_order_by_date(false);
1398              $this->remove_div(false);
1399              $this->strip_comments(false);
1400              $this->strip_htmltags(false);
1401              $this->strip_attributes(false);
1402              $this->set_image_handler(false);
1403          }
1404      }
1405  
1406      /**
1407       * Set maximum number of feeds to check with autodiscovery
1408       *
1409       * @access public
1410       * @param int $max Maximum number of feeds to check
1411       */
1412  	function set_max_checked_feeds($max = 10)
1413      {
1414          $this->max_checked_feeds = (int) $max;
1415      }
1416  
1417  	function remove_div($enable = true)
1418      {
1419          $this->sanitize->remove_div($enable);
1420      }
1421  
1422  	function strip_htmltags($tags = '', $encode = null)
1423      {
1424          if ($tags === '')
1425          {
1426              $tags = $this->strip_htmltags;
1427          }
1428          $this->sanitize->strip_htmltags($tags);
1429          if ($encode !== null)
1430          {
1431              $this->sanitize->encode_instead_of_strip($tags);
1432          }
1433      }
1434  
1435  	function encode_instead_of_strip($enable = true)
1436      {
1437          $this->sanitize->encode_instead_of_strip($enable);
1438      }
1439  
1440  	function strip_attributes($attribs = '')
1441      {
1442          if ($attribs === '')
1443          {
1444              $attribs = $this->strip_attributes;
1445          }
1446          $this->sanitize->strip_attributes($attribs);
1447      }
1448  
1449  	function set_output_encoding($encoding = 'UTF-8')
1450      {
1451          $this->sanitize->set_output_encoding($encoding);
1452      }
1453  
1454  	function strip_comments($strip = false)
1455      {
1456          $this->sanitize->strip_comments($strip);
1457      }
1458  
1459      /**
1460       * Set element/attribute key/value pairs of HTML attributes
1461       * containing URLs that need to be resolved relative to the feed
1462       *
1463       * @access public
1464       * @since 1.0
1465       * @param array $element_attribute Element/attribute key/value pairs
1466       */
1467  	function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
1468      {
1469          $this->sanitize->set_url_replacements($element_attribute);
1470      }
1471  
1472      /**
1473       * Set the handler to enable the display of cached favicons.
1474       *
1475       * @access public
1476       * @param str $page Web-accessible path to the handler_favicon.php file.
1477       * @param str $qs The query string that the value should be passed to.
1478       */
1479  	function set_favicon_handler($page = false, $qs = 'i')
1480      {
1481          if ($page !== false)
1482          {
1483              $this->favicon_handler = $page . '?' . $qs . '=';
1484          }
1485          else
1486          {
1487              $this->favicon_handler = '';
1488          }
1489      }
1490  
1491      /**
1492       * Set the handler to enable the display of cached images.
1493       *
1494       * @access public
1495       * @param str $page Web-accessible path to the handler_image.php file.
1496       * @param str $qs The query string that the value should be passed to.
1497       */
1498  	function set_image_handler($page = false, $qs = 'i')
1499      {
1500          if ($page !== false)
1501          {
1502              $this->sanitize->set_image_handler($page . '?' . $qs . '=');
1503          }
1504          else
1505          {
1506              $this->image_handler = '';
1507          }
1508      }
1509  
1510      /**
1511       * Set the limit for items returned per-feed with multifeeds.
1512       *
1513       * @access public
1514       * @param integer $limit The maximum number of items to return.
1515       */
1516  	function set_item_limit($limit = 0)
1517      {
1518          $this->item_limit = (int) $limit;
1519      }
1520  
1521  	function init()
1522      {
1523          // Check absolute bare minimum requirements.
1524          if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre'))
1525          {
1526              return false;
1527          }
1528          // 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.
1529          elseif (!extension_loaded('xmlreader'))
1530          {
1531              static $xml_is_sane = null;
1532              if ($xml_is_sane === null)
1533              {
1534                  $parser_check = xml_parser_create();
1535                  xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
1536                  xml_parser_free($parser_check);
1537                  $xml_is_sane = isset($values[0]['value']);
1538              }
1539              if (!$xml_is_sane)
1540              {
1541                  return false;
1542              }
1543          }
1544  
1545          if (isset($_GET[$this->javascript]))
1546          {
1547              SimplePie_Misc::output_javascript();
1548              exit;
1549          }
1550  
1551          // Pass whatever was set with config options over to the sanitizer.
1552          $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class);
1553          $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen);
1554  
1555          if ($this->feed_url !== null || $this->raw_data !== null)
1556          {
1557              $this->error = null;
1558              $this->data = array();
1559              $this->multifeed_objects = array();
1560              $cache = false;
1561  
1562              if ($this->feed_url !== null)
1563              {
1564                  $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url);
1565                  // Decide whether to enable caching
1566                  if ($this->cache && $parsed_feed_url['scheme'] !== '')
1567                  {
1568                      $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc');
1569                  }
1570                  // If it's enabled and we don't want an XML dump, use the cache
1571                  if ($cache && !$this->xml_dump)
1572                  {
1573                      // Load the Cache
1574                      $this->data = $cache->load();
1575                      if (!empty($this->data))
1576                      {
1577                          // If the cache is for an outdated build of SimplePie
1578                          if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
1579                          {
1580                              $cache->unlink();
1581                              $this->data = array();
1582                          }
1583                          // If we've hit a collision just rerun it with caching disabled
1584                          elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
1585                          {
1586                              $cache = false;
1587                              $this->data = array();
1588                          }
1589                          // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
1590                          elseif (isset($this->data['feed_url']))
1591                          {
1592                              // If the autodiscovery cache is still valid use it.
1593                              if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
1594                              {
1595                                  // Do not need to do feed autodiscovery yet.
1596                                  if ($this->data['feed_url'] === $this->data['url'])
1597                                  {
1598                                      $cache->unlink();
1599                                      $this->data = array();
1600                                  }
1601                                  else
1602                                  {
1603                                      $this->set_feed_url($this->data['feed_url']);
1604                                      return $this->init();
1605                                  }
1606                              }
1607                          }
1608                          // Check if the cache has been updated
1609                          elseif ($cache->mtime() + $this->cache_duration < time())
1610                          {
1611                              // If we have last-modified and/or etag set
1612                              if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
1613                              {
1614                                  $headers = array();
1615                                  if (isset($this->data['headers']['last-modified']))
1616                                  {
1617                                      $headers['if-modified-since'] = $this->data['headers']['last-modified'];
1618                                  }
1619                                  if (isset($this->data['headers']['etag']))
1620                                  {
1621                                      $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"';
1622                                  }
1623                                  $file = new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen);
1624                                  if ($file->success)
1625                                  {
1626                                      if ($file->status_code === 304)
1627                                      {
1628                                          $cache->touch();
1629                                          return true;
1630                                      }
1631                                      else
1632                                      {
1633                                          $headers = $file->headers;
1634                                      }
1635                                  }
1636                                  else
1637                                  {
1638                                      unset($file);
1639                                  }
1640                              }
1641                          }
1642                          // If the cache is still valid, just return true
1643                          else
1644                          {
1645                              return true;
1646                          }
1647                      }
1648                      // If the cache is empty, delete it
1649                      else
1650                      {
1651                          $cache->unlink();
1652                          $this->data = array();
1653                      }
1654                  }
1655                  // 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.
1656                  if (!isset($file))
1657                  {
1658                      if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url)
1659                      {
1660                          $file =& $this->file;
1661                      }
1662                      else
1663                      {
1664                          $file = new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen);
1665                      }
1666                  }
1667                  // If the file connection has an error, set SimplePie::error to that and quit
1668                  if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
1669                  {
1670                      $this->error = $file->error;
1671                      if (!empty($this->data))
1672                      {
1673                          return true;
1674                      }
1675                      else
1676                      {
1677                          return false;
1678                      }
1679                  }
1680  
1681                  if (!$this->force_feed)
1682                  {
1683                      // Check if the supplied URL is a feed, if it isn't, look for it.
1684                      $locate = new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class);
1685                      if (!$locate->is_feed($file))
1686                      {
1687                          // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
1688                          unset($file);
1689                          if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds))
1690                          {
1691                              if ($cache)
1692                              {
1693                                  $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
1694                                  if (!$cache->save($this))
1695                                  {
1696                                      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);
1697                                  }
1698                                  $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc');
1699                              }
1700                              $this->feed_url = $file->url;
1701                          }
1702                          else
1703                          {
1704                              $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.";
1705                              SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1706                              return false;
1707                          }
1708                      }
1709                      $locate = null;
1710                  }
1711  
1712                  $headers = $file->headers;
1713                  $data = $file->body;
1714                  $sniffer = new $this->content_type_sniffer_class($file);
1715                  $sniffed = $sniffer->get_type();
1716              }
1717              else
1718              {
1719                  $data = $this->raw_data;
1720              }
1721  
1722              // Set up array of possible encodings
1723              $encodings = array();
1724  
1725              // First check to see if input has been overridden.
1726              if ($this->input_encoding !== false)
1727              {
1728                  $encodings[] = $this->input_encoding;
1729              }
1730  
1731              $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
1732              $text_types = array('text/xml', 'text/xml-external-parsed-entity');
1733  
1734              // RFC 3023 (only applies to sniffed content)
1735              if (isset($sniffed))
1736              {
1737                  if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
1738                  {
1739                      if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1740                      {
1741                          $encodings[] = strtoupper($charset[1]);
1742                      }
1743                      $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1744                      $encodings[] = 'UTF-8';
1745                  }
1746                  elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
1747                  {
1748                      if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
1749                      {
1750                          $encodings[] = $charset[1];
1751                      }
1752                      $encodings[] = 'US-ASCII';
1753                  }
1754                  // Text MIME-type default
1755                  elseif (substr($sniffed, 0, 5) === 'text/')
1756                  {
1757                      $encodings[] = 'US-ASCII';
1758                  }
1759              }
1760  
1761              // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
1762              $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data));
1763              $encodings[] = 'UTF-8';
1764              $encodings[] = 'ISO-8859-1';
1765  
1766              // There's no point in trying an encoding twice
1767              $encodings = array_unique($encodings);
1768  
1769              // If we want the XML, just output that with the most likely encoding and quit
1770              if ($this->xml_dump)
1771              {
1772                  header('Content-type: text/xml; charset=' . $encodings[0]);
1773                  echo $data;
1774                  exit;
1775              }
1776  
1777              // Loop through each possible encoding, till we return something, or run out of possibilities
1778              foreach ($encodings as $encoding)
1779              {
1780                  // Change the encoding to UTF-8 (as we always use UTF-8 internally)
1781                  if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8'))
1782                  {
1783                      // Create new parser
1784                      $parser = new $this->parser_class();
1785  
1786                      // If it's parsed fine
1787                      if ($parser->parse($utf8_data, 'UTF-8'))
1788                      {
1789                          $this->data = $parser->get_data();
1790                          if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE)
1791                          {
1792                              if (isset($headers))
1793                              {
1794                                  $this->data['headers'] = $headers;
1795                              }
1796                              $this->data['build'] = SIMPLEPIE_BUILD;
1797  
1798                              // Cache the file if caching is enabled
1799                              if ($cache && !$cache->save($this))
1800                              {
1801                                  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);
1802                              }
1803                              return true;
1804                          }
1805                          else
1806                          {
1807                              $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed.";
1808                              SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1809                              return false;
1810                          }
1811                      }
1812                  }
1813              }
1814              if (isset($parser))
1815              {
1816                  // We have an error, just set SimplePie_Misc::error to it and quit
1817                  $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());
1818              }
1819              else
1820              {
1821                  $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.';
1822              }
1823              SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__);
1824              return false;
1825          }
1826          elseif (!empty($this->multifeed_url))
1827          {
1828              $i = 0;
1829              $success = 0;
1830              $this->multifeed_objects = array();
1831              foreach ($this->multifeed_url as $url)
1832              {
1833                  if (SIMPLEPIE_PHP5)
1834                  {
1835                      // This keyword needs to defy coding standards for PHP4 compatibility
1836                      $this->multifeed_objects[$i] = clone($this);
1837                  }
1838                  else
1839                  {
1840                      $this->multifeed_objects[$i] = $this;
1841                  }
1842                  $this->multifeed_objects[$i]->set_feed_url($url);
1843                  $success |= $this->multifeed_objects[$i]->init();
1844                  $i++;
1845              }
1846              return (bool) $success;
1847          }
1848          else
1849          {
1850              return false;
1851          }
1852      }
1853  
1854      /**
1855       * Return the error message for the occured error
1856       *
1857       * @access public
1858       * @return string Error message
1859       */
1860  	function error()
1861      {
1862          return $this->error;
1863      }
1864  
1865  	function get_encoding()
1866      {
1867          return $this->sanitize->output_encoding;
1868      }
1869  
1870  	function handle_content_type($mime = 'text/html')
1871      {
1872          if (!headers_sent())
1873          {
1874              $header = "Content-type: $mime;";
1875              if ($this->get_encoding())
1876              {
1877                  $header .= ' charset=' . $this->get_encoding();
1878              }
1879              else
1880              {
1881                  $header .= ' charset=UTF-8';
1882              }
1883              header($header);
1884          }
1885      }
1886  
1887  	function get_type()
1888      {
1889          if (!isset($this->data['type']))
1890          {
1891              $this->data['type'] = SIMPLEPIE_TYPE_ALL;
1892              if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
1893              {
1894                  $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
1895              }
1896              elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
1897              {
1898                  $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
1899              }
1900              elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
1901              {
1902                  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
1903                  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
1904                  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
1905                  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
1906                  {
1907                      $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
1908                  }
1909                  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
1910                  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
1911                  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
1912                  || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
1913                  {
1914                      $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
1915                  }
1916              }
1917              elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
1918              {
1919                  $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
1920                  if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1921                  {
1922                      switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
1923                      {
1924                          case '0.91':
1925                              $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
1926                              if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1927                              {
1928                                  switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
1929                                  {
1930                                      case '0':
1931                                          $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
1932                                          break;
1933  
1934                                      case '24':
1935                                          $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
1936                                          break;
1937                                  }
1938                              }
1939                              break;
1940  
1941                          case '0.92':
1942                              $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
1943                              break;
1944  
1945                          case '0.93':
1946                              $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
1947                              break;
1948  
1949                          case '0.94':
1950                              $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
1951                              break;
1952  
1953                          case '2.0':
1954                              $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
1955                              break;
1956                      }
1957                  }
1958              }
1959              else
1960              {
1961                  $this->data['type'] = SIMPLEPIE_TYPE_NONE;
1962              }
1963          }
1964          return $this->data['type'];
1965      }
1966  
1967      /**
1968       * Returns the URL for the favicon of the feed's website.
1969       *
1970       * @todo Cache atom:icon
1971       * @access public
1972       * @since 1.0
1973       */
1974  	function get_favicon()
1975      {
1976          if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
1977          {
1978              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
1979          }
1980          elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url))
1981          {
1982              $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url);
1983  
1984              if ($this->cache && $this->favicon_handler)
1985              {
1986                  $favicon_filename = call_user_func($this->cache_name_function, $favicon);
1987                  $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi');
1988  
1989                  if ($cache->load())
1990                  {
1991                      return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
1992                  }
1993                  else
1994                  {
1995                      $file = new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
1996  
1997                      if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0)
1998                      {
1999                          $sniffer = new $this->content_type_sniffer_class($file);
2000                          if (substr($sniffer->get_type(), 0, 6) === 'image/')
2001                          {
2002                              if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
2003                              {
2004                                  return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI);
2005                              }
2006                              else
2007                              {
2008                                  trigger_error("$cache->name is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
2009                                  return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2010                              }
2011                          }
2012                          // not an image
2013                          else
2014                          {
2015                              return false;
2016                          }
2017                      }
2018                  }
2019              }
2020              else
2021              {
2022                  return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI);
2023              }
2024          }
2025          return false;
2026      }
2027  
2028      /**
2029       * @todo If we have a perm redirect we should return the new URL
2030       * @todo When we make the above change, let's support <itunes:new-feed-url> as well
2031       * @todo Also, |atom:link|@rel=self
2032       */
2033  	function subscribe_url()
2034      {
2035          if ($this->feed_url !== null)
2036          {
2037              return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI);
2038          }
2039          else
2040          {
2041              return null;
2042          }
2043      }
2044  
2045  	function subscribe_feed()
2046      {
2047          if ($this->feed_url !== null)
2048          {
2049              return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2050          }
2051          else
2052          {
2053              return null;
2054          }
2055      }
2056  
2057  	function subscribe_outlook()
2058      {
2059          if ($this->feed_url !== null)
2060          {
2061              return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI);
2062          }
2063          else
2064          {
2065              return null;
2066          }
2067      }
2068  
2069  	function subscribe_podcast()
2070      {
2071          if ($this->feed_url !== null)
2072          {
2073              return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI);
2074          }
2075          else
2076          {
2077              return null;
2078          }
2079      }
2080  
2081  	function subscribe_itunes()
2082      {
2083          if ($this->feed_url !== null)
2084          {
2085              return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI);
2086          }
2087          else
2088          {
2089              return null;
2090          }
2091      }
2092  
2093      /**
2094       * Creates the subscribe_* methods' return data
2095       *
2096       * @access private
2097       * @param string $feed_url String to prefix to the feed URL
2098       * @param string $site_url String to prefix to the site URL (and
2099       * suffix to the feed URL)
2100       * @return mixed URL if feed exists, false otherwise
2101       */
2102  	function subscribe_service($feed_url, $site_url = null)
2103      {
2104          if ($this->subscribe_url())
2105          {
2106              $return = $feed_url . rawurlencode($this->feed_url);
2107              if ($site_url !== null && $this->get_link() !== null)
2108              {
2109                  $return .= $site_url . rawurlencode($this->get_link());
2110              }
2111              return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
2112          }
2113          else
2114          {
2115              return null;
2116          }
2117      }
2118  
2119  	function subscribe_aol()
2120      {
2121          return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url=');
2122      }
2123  
2124  	function subscribe_bloglines()
2125      {
2126          return $this->subscribe_service('http://www.bloglines.com/sub/');
2127      }
2128  
2129  	function subscribe_eskobo()
2130      {
2131          return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage=');
2132      }
2133  
2134  	function subscribe_feedfeeds()
2135      {
2136          return $this->subscribe_service('http://www.feedfeeds.com/add?feed=');
2137      }
2138  
2139  	function subscribe_feedster()
2140      {
2141          return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl=');
2142      }
2143  
2144  	function subscribe_google()
2145      {
2146          return $this->subscribe_service('http://fusion.google.com/add?feedurl=');
2147      }
2148  
2149  	function subscribe_gritwire()
2150      {
2151          return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl=');
2152      }
2153  
2154  	function subscribe_msn()
2155      {
2156          return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru=');
2157      }
2158  
2159  	function subscribe_netvibes()
2160      {
2161          return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url=');
2162      }
2163  
2164  	function subscribe_newsburst()
2165      {
2166          return $this->subscribe_service('http://www.newsburst.com/Source/?add=');
2167      }
2168  
2169  	function subscribe_newsgator()
2170      {
2171          return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url=');
2172      }
2173  
2174  	function subscribe_odeo()
2175      {
2176          return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed=');
2177      }
2178  
2179  	function subscribe_podnova()
2180      {
2181          return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url=');
2182      }
2183  
2184  	function subscribe_rojo()
2185      {
2186          return $this->subscribe_service('http://www.rojo.com/add-subscription?resource=');
2187      }
2188  
2189  	function subscribe_yahoo()
2190      {
2191          return $this->subscribe_service('http://add.my.yahoo.com/rss?url=');
2192      }
2193  
2194  	function get_feed_tags($namespace, $tag)
2195      {
2196          $type = $this->get_type();
2197          if ($type & SIMPLEPIE_TYPE_ATOM_10)
2198          {
2199              if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
2200              {
2201                  return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
2202              }
2203          }
2204          if ($type & SIMPLEPIE_TYPE_ATOM_03)
2205          {
2206              if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
2207              {
2208                  return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
2209              }
2210          }
2211          if ($type & SIMPLEPIE_TYPE_RSS_RDF)
2212          {
2213              if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
2214              {
2215                  return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
2216              }
2217          }
2218          if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2219          {
2220              if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
2221              {
2222                  return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
2223              }
2224          }
2225          return null;
2226      }
2227  
2228  	function get_channel_tags($namespace, $tag)
2229      {
2230          $type = $this->get_type();
2231          if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
2232          {
2233              if ($return = $this->get_feed_tags($namespace, $tag))
2234              {
2235                  return $return;
2236              }
2237          }
2238          if ($type & SIMPLEPIE_TYPE_RSS_10)
2239          {
2240              if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
2241              {
2242                  if (isset($channel[0]['child'][$namespace][$tag]))
2243                  {
2244                      return $channel[0]['child'][$namespace][$tag];
2245                  }
2246              }
2247          }
2248          if ($type & SIMPLEPIE_TYPE_RSS_090)
2249          {
2250              if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
2251              {
2252                  if (isset($channel[0]['child'][$namespace][$tag]))
2253                  {
2254                      return $channel[0]['child'][$namespace][$tag];
2255                  }
2256              }
2257          }
2258          if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2259          {
2260              if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
2261              {
2262                  if (isset($channel[0]['child'][$namespace][$tag]))
2263                  {
2264                      return $channel[0]['child'][$namespace][$tag];
2265                  }
2266              }
2267          }
2268          return null;
2269      }
2270  
2271  	function get_image_tags($namespace, $tag)
2272      {
2273          $type = $this->get_type();
2274          if ($type & SIMPLEPIE_TYPE_RSS_10)
2275          {
2276              if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
2277              {
2278                  if (isset($image[0]['child'][$namespace][$tag]))
2279                  {
2280                      return $image[0]['child'][$namespace][$tag];
2281                  }
2282              }
2283          }
2284          if ($type & SIMPLEPIE_TYPE_RSS_090)
2285          {
2286              if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
2287              {
2288                  if (isset($image[0]['child'][$namespace][$tag]))
2289                  {
2290                      return $image[0]['child'][$namespace][$tag];
2291                  }
2292              }
2293          }
2294          if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
2295          {
2296              if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
2297              {
2298                  if (isset($image[0]['child'][$namespace][$tag]))
2299                  {
2300                      return $image[0]['child'][$namespace][$tag];
2301                  }
2302              }
2303          }
2304          return null;
2305      }
2306  
2307  	function get_base($element = array())
2308      {
2309          if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
2310          {
2311              return $element['xml_base'];
2312          }
2313          elseif ($this->get_link() !== null)
2314          {
2315              return $this->get_link();
2316          }
2317          else
2318          {
2319              return $this->subscribe_url();
2320          }
2321      }
2322  
2323  	function sanitize($data, $type, $base = '')
2324      {
2325          return $this->sanitize->sanitize($data, $type, $base);
2326      }
2327  
2328  	function get_title()
2329      {
2330          if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
2331          {
2332              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2333          }
2334          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
2335          {
2336              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2337          }
2338          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2339          {
2340              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2341          }
2342          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2343          {
2344              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2345          }
2346          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2347          {
2348              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2349          }
2350          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2351          {
2352              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2353          }
2354          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2355          {
2356              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2357          }
2358          else
2359          {
2360              return null;
2361          }
2362      }
2363  
2364  	function get_category($key = 0)
2365      {
2366          $categories = $this->get_categories();
2367          if (isset($categories[$key]))
2368          {
2369              return $categories[$key];
2370          }
2371          else
2372          {
2373              return null;
2374          }
2375      }
2376  
2377  	function get_categories()
2378      {
2379          $categories = array();
2380  
2381          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
2382          {
2383              $term = null;
2384              $scheme = null;
2385              $label = null;
2386              if (isset($category['attribs']['']['term']))
2387              {
2388                  $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
2389              }
2390              if (isset($category['attribs']['']['scheme']))
2391              {
2392                  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
2393              }
2394              if (isset($category['attribs']['']['label']))
2395              {
2396                  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
2397              }
2398              $categories[] = new $this->category_class($term, $scheme, $label);
2399          }
2400          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
2401          {
2402              // This is really the label, but keep this as the term also for BC.
2403              // Label will also work on retrieving because that falls back to term.
2404              $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2405              if (isset($category['attribs']['']['domain']))
2406              {
2407                  $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
2408              }
2409              else
2410              {
2411                  $scheme = null;
2412              }
2413              $categories[] = new $this->category_class($term, $scheme, null);
2414          }
2415          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
2416          {
2417              $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2418          }
2419          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
2420          {
2421              $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2422          }
2423  
2424          if (!empty($categories))
2425          {
2426              return SimplePie_Misc::array_unique($categories);
2427          }
2428          else
2429          {
2430              return null;
2431          }
2432      }
2433  
2434  	function get_author($key = 0)
2435      {
2436          $authors = $this->get_authors();
2437          if (isset($authors[$key]))
2438          {
2439              return $authors[$key];
2440          }
2441          else
2442          {
2443              return null;
2444          }
2445      }
2446  
2447  	function get_authors()
2448      {
2449          $authors = array();
2450          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
2451          {
2452              $name = null;
2453              $uri = null;
2454              $email = null;
2455              if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2456              {
2457                  $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2458              }
2459              if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2460              {
2461                  $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]));
2462              }
2463              if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2464              {
2465                  $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2466              }
2467              if ($name !== null || $email !== null || $uri !== null)
2468              {
2469                  $authors[] = new $this->author_class($name, $uri, $email);
2470              }
2471          }
2472          if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
2473          {
2474              $name = null;
2475              $url = null;
2476              $email = null;
2477              if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2478              {
2479                  $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2480              }
2481              if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2482              {
2483                  $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]));
2484              }
2485              if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2486              {
2487                  $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2488              }
2489              if ($name !== null || $email !== null || $url !== null)
2490              {
2491                  $authors[] = new $this->author_class($name, $url, $email);
2492              }
2493          }
2494          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
2495          {
2496              $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2497          }
2498          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
2499          {
2500              $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2501          }
2502          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
2503          {
2504              $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
2505          }
2506  
2507          if (!empty($authors))
2508          {
2509              return SimplePie_Misc::array_unique($authors);
2510          }
2511          else
2512          {
2513              return null;
2514          }
2515      }
2516  
2517  	function get_contributor($key = 0)
2518      {
2519          $contributors = $this->get_contributors();
2520          if (isset($contributors[$key]))
2521          {
2522              return $contributors[$key];
2523          }
2524          else
2525          {
2526              return null;
2527          }
2528      }
2529  
2530  	function get_contributors()
2531      {
2532          $contributors = array();
2533          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
2534          {
2535              $name = null;
2536              $uri = null;
2537              $email = null;
2538              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
2539              {
2540                  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2541              }
2542              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
2543              {
2544                  $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]));
2545              }
2546              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
2547              {
2548                  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2549              }
2550              if ($name !== null || $email !== null || $uri !== null)
2551              {
2552                  $contributors[] = new $this->author_class($name, $uri, $email);
2553              }
2554          }
2555          foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
2556          {
2557              $name = null;
2558              $url = null;
2559              $email = null;
2560              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
2561              {
2562                  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2563              }
2564              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
2565              {
2566                  $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]));
2567              }
2568              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
2569              {
2570                  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2571              }
2572              if ($name !== null || $email !== null || $url !== null)
2573              {
2574                  $contributors[] = new $this->author_class($name, $url, $email);
2575              }
2576          }
2577  
2578          if (!empty($contributors))
2579          {
2580              return SimplePie_Misc::array_unique($contributors);
2581          }
2582          else
2583          {
2584              return null;
2585          }
2586      }
2587  
2588  	function get_link($key = 0, $rel = 'alternate')
2589      {
2590          $links = $this->get_links($rel);
2591          if (isset($links[$key]))
2592          {
2593              return $links[$key];
2594          }
2595          else
2596          {
2597              return null;
2598          }
2599      }
2600  
2601      /**
2602       * Added for parity between the parent-level and the item/entry-level.
2603       */
2604  	function get_permalink()
2605      {
2606          return $this->get_link(0);
2607      }
2608  
2609  	function get_links($rel = 'alternate')
2610      {
2611          if (!isset($this->data['links']))
2612          {
2613              $this->data['links'] = array();
2614              if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
2615              {
2616                  foreach ($links as $link)
2617                  {
2618                      if (isset($link['attribs']['']['href']))
2619                      {
2620                          $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2621                          $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2622                      }
2623                  }
2624              }
2625              if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
2626              {
2627                  foreach ($links as $link)
2628                  {
2629                      if (isset($link['attribs']['']['href']))
2630                      {
2631                          $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
2632                          $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
2633  
2634                      }
2635                  }
2636              }
2637              if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2638              {
2639                  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2640              }
2641              if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2642              {
2643                  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2644              }
2645              if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2646              {
2647                  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
2648              }
2649  
2650              $keys = array_keys($this->data['links']);
2651              foreach ($keys as $key)
2652              {
2653                  if (SimplePie_Misc::is_isegment_nz_nc($key))
2654                  {
2655                      if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
2656                      {
2657                          $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
2658                          $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
2659                      }
2660                      else
2661                      {
2662                          $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
2663                      }
2664                  }
2665                  elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
2666                  {
2667                      $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
2668                  }
2669                  $this->data['links'][$key] = array_unique($this->data['links'][$key]);
2670              }
2671          }
2672  
2673          if (isset($this->data['links'][$rel]))
2674          {
2675              return $this->data['links'][$rel];
2676          }
2677          else
2678          {
2679              return null;
2680          }
2681      }
2682  
2683  	function get_all_discovered_feeds()
2684      {
2685          return $this->all_discovered_feeds;
2686      }
2687  
2688  	function get_description()
2689      {
2690          if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
2691          {
2692              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2693          }
2694          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
2695          {
2696              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2697          }
2698          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
2699          {
2700              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2701          }
2702          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
2703          {
2704              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
2705          }
2706          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
2707          {
2708              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2709          }
2710          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
2711          {
2712              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2713          }
2714          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
2715          {
2716              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2717          }
2718          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
2719          {
2720              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2721          }
2722          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
2723          {
2724              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
2725          }
2726          else
2727          {
2728              return null;
2729          }
2730      }
2731  
2732  	function get_copyright()
2733      {
2734          if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
2735          {
2736              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2737          }
2738          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
2739          {
2740              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
2741          }
2742          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
2743          {
2744              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2745          }
2746          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
2747          {
2748              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2749          }
2750          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
2751          {
2752              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2753          }
2754          else
2755          {
2756              return null;
2757          }
2758      }
2759  
2760  	function get_language()
2761      {
2762          if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
2763          {
2764              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2765          }
2766          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
2767          {
2768              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2769          }
2770          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
2771          {
2772              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2773          }
2774          elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
2775          {
2776              return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2777          }
2778          elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
2779          {
2780              return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2781          }
2782          elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
2783          {
2784              return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
2785          }
2786          elseif (isset($this->data['headers']['content-language']))
2787          {
2788              return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
2789          }
2790          else
2791          {
2792              return null;
2793          }
2794      }
2795  
2796  	function get_latitude()
2797      {
2798          
2799          if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
2800          {
2801              return (float) $return[0]['data'];
2802          }
2803          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))
2804          {
2805              return (float) $match[1];
2806          }
2807          else
2808          {
2809              return null;
2810          }
2811      }
2812  
2813  	function get_longitude()
2814      {
2815          if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
2816          {
2817              return (float) $return[0]['data'];
2818          }
2819          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
2820          {
2821              return (float) $return[0]['data'];
2822          }
2823          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))
2824          {
2825              return (float) $match[2];
2826          }
2827          else
2828          {
2829              return null;
2830          }
2831      }
2832  
2833  	function get_image_title()
2834      {
2835          if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
2836          {
2837              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2838          }
2839          elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
2840          {
2841              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2842          }
2843          elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
2844          {
2845              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2846          }
2847          elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
2848          {
2849              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2850          }
2851          elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
2852          {
2853              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
2854          }
2855          else
2856          {
2857              return null;
2858          }
2859      }
2860  
2861  	function get_image_url()
2862      {
2863          if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
2864          {
2865              return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
2866          }
2867          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
2868          {
2869              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2870          }
2871          elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
2872          {
2873              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2874          }
2875          elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
2876          {
2877              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2878          }
2879          elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
2880          {
2881              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2882          }
2883          elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2884          {
2885              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2886          }
2887          else
2888          {
2889              return null;
2890          }
2891      }
2892  
2893  	function get_image_link()
2894      {
2895          if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
2896          {
2897              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2898          }
2899          elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
2900          {
2901              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2902          }
2903          elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
2904          {
2905              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
2906          }
2907          else
2908          {
2909              return null;
2910          }
2911      }
2912  
2913  	function get_image_width()
2914      {
2915          if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
2916          {
2917              return round($return[0]['data']);
2918          }
2919          elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2920          {
2921              return 88.0;
2922          }
2923          else
2924          {
2925              return null;
2926          }
2927      }
2928  
2929  	function get_image_height()
2930      {
2931          if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
2932          {
2933              return round($return[0]['data']);
2934          }
2935          elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
2936          {
2937              return 31.0;
2938          }
2939          else
2940          {
2941              return null;
2942          }
2943      }
2944  
2945  	function get_item_quantity($max = 0)
2946      {
2947          $max = (int) $max;
2948          $qty = count($this->get_items());
2949          if ($max === 0)
2950          {
2951              return $qty;
2952          }
2953          else
2954          {
2955              return ($qty > $max) ? $max : $qty;
2956          }
2957      }
2958  
2959  	function get_item($key = 0)
2960      {
2961          $items = $this->get_items();
2962          if (isset($items[$key]))
2963          {
2964              return $items[$key];
2965          }
2966          else
2967          {
2968              return null;
2969          }
2970      }
2971  
2972  	function get_items($start = 0, $end = 0)
2973      {
2974          if (!isset($this->data['items']))
2975          {
2976              if (!empty($this->multifeed_objects))
2977              {
2978                  $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
2979              }
2980              else
2981              {
2982                  $this->data['items'] = array();
2983                  if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
2984                  {
2985                      $keys = array_keys($items);
2986                      foreach ($keys as $key)
2987                      {
2988                          $this->data['items'][] = new $this->item_class($this, $items[$key]);
2989                      }
2990                  }
2991                  if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
2992                  {
2993                      $keys = array_keys($items);
2994                      foreach ($keys as $key)
2995                      {
2996                          $this->data['items'][] = new $this->item_class($this, $items[$key]);
2997                      }
2998                  }
2999                  if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
3000                  {
3001                      $keys = array_keys($items);
3002                      foreach ($keys as $key)
3003                      {
3004                          $this->data['items'][] = new $this->item_class($this, $items[$key]);
3005                      }
3006                  }
3007                  if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
3008                  {
3009                      $keys = array_keys($items);
3010                      foreach ($keys as $key)
3011                      {
3012                          $this->data['items'][] = new $this->item_class($this, $items[$key]);
3013                      }
3014                  }
3015                  if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
3016                  {
3017                      $keys = array_keys($items);
3018                      foreach ($keys as $key)
3019                      {
3020                          $this->data['items'][] = new $this->item_class($this, $items[$key]);
3021                      }
3022                  }
3023              }
3024          }
3025  
3026          if (!empty($this->data['items']))
3027          {
3028              // If we want to order it by date, check if all items have a date, and then sort it
3029              if ($this->order_by_date && empty($this->multifeed_objects))
3030              {
3031                  if (!isset($this->data['ordered_items']))
3032                  {
3033                      $do_sort = true;
3034                      foreach ($this->data['items'] as $item)
3035                      {
3036                          if (!$item->get_date('U'))
3037                          {
3038                              $do_sort = false;
3039                              break;
3040                          }
3041                      }
3042                      $item = null;
3043                      $this->data['ordered_items'] = $this->data['items'];
3044                      if ($do_sort)
3045                      {
3046                          usort($this->data['ordered_items'], array(&$this, 'sort_items'));
3047                      }
3048                  }
3049                  $items = $this->data['ordered_items'];
3050              }
3051              else
3052              {
3053                  $items = $this->data['items'];
3054              }
3055  
3056              // Slice the data as desired
3057              if ($end === 0)
3058              {
3059                  return array_slice($items, $start);
3060              }
3061              else
3062              {
3063                  return array_slice($items, $start, $end);
3064              }
3065          }
3066          else
3067          {
3068              return array();
3069          }
3070      }
3071  
3072      /**
3073       * @static
3074       */
3075  	function sort_items($a, $b)
3076      {
3077          return $a->get_date('U') <= $b->get_date('U');
3078      }
3079  
3080      /**
3081       * @static
3082       */
3083  	function merge_items($urls, $start = 0, $end = 0, $limit = 0)
3084      {
3085          if (is_array($urls) && sizeof($urls) > 0)
3086          {
3087              $items = array();
3088              foreach ($urls as $arg)
3089              {
3090                  if (is_a($arg, 'SimplePie'))
3091                  {
3092                      $items = array_merge($items, $arg->get_items(0, $limit));
3093                  }
3094                  else
3095                  {
3096                      trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
3097                  }
3098              }
3099  
3100              $do_sort = true;
3101              foreach ($items as $item)
3102              {
3103                  if (!$item->get_date('U'))
3104                  {
3105                      $do_sort = false;
3106                      break;
3107                  }
3108              }
3109              $item = null;
3110              if ($do_sort)
3111              {
3112                  usort($items, array('SimplePie', 'sort_items'));
3113              }
3114  
3115              if ($end === 0)
3116              {
3117                  return array_slice($items, $start);
3118              }
3119              else
3120              {
3121                  return array_slice($items, $start, $end);
3122              }
3123          }
3124          else
3125          {
3126              trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
3127              return array();
3128          }
3129      }
3130  }
3131  
3132  class SimplePie_Item
3133  {
3134      var $feed;
3135      var $data = array();
3136  
3137  	function SimplePie_Item($feed, $data)
3138      {
3139          $this->feed = $feed;
3140          $this->data = $data;
3141      }
3142  
3143  	function __toString()
3144      {
3145          return md5(serialize($this->data));
3146      }
3147  
3148      /**
3149       * Remove items that link back to this before destroying this object
3150       */
3151  	function __destruct()
3152      {
3153          if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode'))
3154          {
3155              unset($this->feed);
3156          }
3157      }
3158  
3159  	function get_item_tags($namespace, $tag)
3160      {
3161          if (isset($this->data['child'][$namespace][$tag]))
3162          {
3163              return $this->data['child'][$namespace][$tag];
3164          }
3165          else
3166          {
3167              return null;
3168          }
3169      }
3170  
3171  	function get_base($element = array())
3172      {
3173          return $this->feed->get_base($element);
3174      }
3175  
3176  	function sanitize($data, $type, $base = '')
3177      {
3178          return $this->feed->sanitize($data, $type, $base);
3179      }
3180  
3181  	function get_feed()
3182      {
3183          return $this->feed;
3184      }
3185  
3186  	function get_id($hash = false)
3187      {
3188          if (!$hash)
3189          {
3190              if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
3191              {
3192                  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3193              }
3194              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
3195              {
3196                  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3197              }
3198              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3199              {
3200                  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3201              }
3202              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
3203              {
3204                  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3205              }
3206              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
3207              {
3208                  return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3209              }
3210              elseif (($return = $this->get_permalink()) !== null)
3211              {
3212                  return $return;
3213              }
3214              elseif (($return = $this->get_title()) !== null)
3215              {
3216                  return $return;
3217              }
3218          }
3219          if ($this->get_permalink() !== null || $this->get_title() !== null)
3220          {
3221              return md5($this->get_permalink() . $this->get_title());
3222          }
3223          else
3224          {
3225              return md5(serialize($this->data));
3226          }
3227      }
3228  
3229  	function get_title()
3230      {
3231          if (!isset($this->data['title']))
3232          {
3233              if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
3234              {
3235                  $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3236              }
3237              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
3238              {
3239                  $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3240              }
3241              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
3242              {
3243                  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3244              }
3245              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
3246              {
3247                  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3248              }
3249              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
3250              {
3251                  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3252              }
3253              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
3254              {
3255                  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3256              }
3257              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
3258              {
3259                  $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3260              }
3261              else
3262              {
3263                  $this->data['title'] = null;
3264              }
3265          }
3266          return $this->data['title'];
3267      }
3268  
3269  	function get_description($description_only = false)
3270      {
3271          if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary'))
3272          {
3273              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3274          }
3275          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary'))
3276          {
3277              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3278          }
3279          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
3280          {
3281              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
3282          }
3283          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
3284          {
3285              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3286          }
3287          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
3288          {
3289              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3290          }
3291          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
3292          {
3293              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3294          }
3295          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
3296          {
3297              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3298          }
3299          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
3300          {
3301              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3302          }
3303          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
3304          {
3305              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML);
3306          }
3307  
3308          elseif (!$description_only)
3309          {
3310              return $this->get_content(true);
3311          }
3312          else
3313          {
3314              return null;
3315          }
3316      }
3317  
3318  	function get_content($content_only = false)
3319      {
3320          if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content'))
3321          {
3322              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3323          }
3324          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content'))
3325          {
3326              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3327          }
3328          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded'))
3329          {
3330              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
3331          }
3332          elseif (!$content_only)
3333          {
3334              return $this->get_description(true);
3335          }
3336          else
3337          {
3338              return null;
3339          }
3340      }
3341  
3342  	function get_category($key = 0)
3343      {
3344          $categories = $this->get_categories();
3345          if (isset($categories[$key]))
3346          {
3347              return $categories[$key];
3348          }
3349          else
3350          {
3351              return null;
3352          }
3353      }
3354  
3355  	function get_categories()
3356      {
3357          $categories = array();
3358  
3359          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
3360          {
3361              $term = null;
3362              $scheme = null;
3363              $label = null;
3364              if (isset($category['attribs']['']['term']))
3365              {
3366                  $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
3367              }
3368              if (isset($category['attribs']['']['scheme']))
3369              {
3370                  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3371              }
3372              if (isset($category['attribs']['']['label']))
3373              {
3374                  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3375              }
3376              $categories[] = new $this->feed->category_class($term, $scheme, $label);
3377          }
3378          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
3379          {
3380              // This is really the label, but keep this as the term also for BC.
3381              // Label will also work on retrieving because that falls back to term.
3382              $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3383              if (isset($category['attribs']['']['domain']))
3384              {
3385                  $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
3386              }
3387              else
3388              {
3389                  $scheme = null;
3390              }
3391              $categories[] = new $this->feed->category_class($term, $scheme, null);
3392          }
3393          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
3394          {
3395              $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3396          }
3397          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
3398          {
3399              $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3400          }
3401  
3402          if (!empty($categories))
3403          {
3404              return SimplePie_Misc::array_unique($categories);
3405          }
3406          else
3407          {
3408              return null;
3409          }
3410      }
3411  
3412  	function get_author($key = 0)
3413      {
3414          $authors = $this->get_authors();
3415          if (isset($authors[$key]))
3416          {
3417              return $authors[$key];
3418          }
3419          else
3420          {
3421              return null;
3422          }
3423      }
3424  
3425  	function get_contributor($key = 0)
3426      {
3427          $contributors = $this->get_contributors();
3428          if (isset($contributors[$key]))
3429          {
3430              return $contributors[$key];
3431          }
3432          else
3433          {
3434              return null;
3435          }
3436      }
3437  
3438  	function get_contributors()
3439      {
3440          $contributors = array();
3441          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
3442          {
3443              $name = null;
3444              $uri = null;
3445              $email = null;
3446              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3447              {
3448                  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3449              }
3450              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3451              {
3452                  $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]));
3453              }
3454              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3455              {
3456                  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3457              }
3458              if ($name !== null || $email !== null || $uri !== null)
3459              {
3460                  $contributors[] = new $this->feed->author_class($name, $uri, $email);
3461              }
3462          }
3463          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
3464          {
3465              $name = null;
3466              $url = null;
3467              $email = null;
3468              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3469              {
3470                  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3471              }
3472              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3473              {
3474                  $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]));
3475              }
3476              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3477              {
3478                  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3479              }
3480              if ($name !== null || $email !== null || $url !== null)
3481              {
3482                  $contributors[] = new $this->feed->author_class($name, $url, $email);
3483              }
3484          }
3485  
3486          if (!empty($contributors))
3487          {
3488              return SimplePie_Misc::array_unique($contributors);
3489          }
3490          else
3491          {
3492              return null;
3493          }
3494      }
3495  
3496  	function get_authors()
3497      {
3498          $authors = array();
3499          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
3500          {
3501              $name = null;
3502              $uri = null;
3503              $email = null;
3504              if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
3505              {
3506                  $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3507              }
3508              if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
3509              {
3510                  $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]));
3511              }
3512              if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
3513              {
3514                  $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3515              }
3516              if ($name !== null || $email !== null || $uri !== null)
3517              {
3518                  $authors[] = new $this->feed->author_class($name, $uri, $email);
3519              }
3520          }
3521          if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
3522          {
3523              $name = null;
3524              $url = null;
3525              $email = null;
3526              if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
3527              {
3528                  $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3529              }
3530              if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
3531              {
3532                  $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]));
3533              }
3534              if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
3535              {
3536                  $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3537              }
3538              if ($name !== null || $email !== null || $url !== null)
3539              {
3540                  $authors[] = new $this->feed->author_class($name, $url, $email);
3541              }
3542          }
3543          if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
3544          {
3545              $authors[] = new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
3546          }
3547          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
3548          {
3549              $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3550          }
3551          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
3552          {
3553              $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3554          }
3555          foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
3556          {
3557              $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
3558          }
3559  
3560          if (!empty($authors))
3561          {
3562              return SimplePie_Misc::array_unique($authors);
3563          }
3564          elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
3565          {
3566              return $authors;
3567          }
3568          elseif ($authors = $this->feed->get_authors())
3569          {
3570              return $authors;
3571          }
3572          else
3573          {
3574              return null;
3575          }
3576      }
3577  
3578  	function get_copyright()
3579      {
3580          if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
3581          {
3582              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
3583          }
3584          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
3585          {
3586              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3587          }
3588          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
3589          {
3590              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3591          }
3592          else
3593          {
3594              return null;
3595          }
3596      }
3597  
3598  	function get_date($date_format = 'j F Y, g:i a')
3599      {
3600          if (!isset($this->data['date']))
3601          {
3602              if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
3603              {
3604                  $this->data['date']['raw'] = $return[0]['data'];
3605              }
3606              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
3607              {
3608                  $this->data['date']['raw'] = $return[0]['data'];
3609              }
3610              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
3611              {
3612                  $this->data['date']['raw'] = $return[0]['data'];
3613              }
3614              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
3615              {
3616                  $this->data['date']['raw'] = $return[0]['data'];
3617              }
3618              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
3619              {
3620                  $this->data['date']['raw'] = $return[0]['data'];
3621              }
3622              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
3623              {
3624                  $this->data['date']['raw'] = $return[0]['data'];
3625              }
3626              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
3627              {
3628                  $this->data['date']['raw'] = $return[0]['data'];
3629              }
3630              elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
3631              {
3632                  $this->data['date']['raw'] = $return[0]['data'];
3633              }
3634  
3635              if (!empty($this->data['date']['raw']))
3636              {
3637                  $parser = SimplePie_Parse_Date::get();
3638                  $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
3639              }
3640              else
3641              {
3642                  $this->data['date'] = null;
3643              }
3644          }
3645          if ($this->data['date'])
3646          {
3647              $date_format = (string) $date_format;
3648              switch ($date_format)
3649              {
3650                  case '':
3651                      return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
3652  
3653                  case 'U':
3654                      return $this->data['date']['parsed'];
3655  
3656                  default:
3657                      return date($date_format, $this->data['date']['parsed']);
3658              }
3659          }
3660          else
3661          {
3662              return null;
3663          }
3664      }
3665  
3666  	function get_local_date($date_format = '%c')
3667      {
3668          if (!$date_format)
3669          {
3670              return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
3671          }
3672          elseif (($date = $this->get_date('U')) !== null && $date !== false)
3673          {
3674              return strftime($date_format, $date);
3675          }
3676          else
3677          {
3678              return null;
3679          }
3680      }
3681  
3682  	function get_permalink()
3683      {
3684          $link = $this->get_link();
3685          $enclosure = $this->get_enclosure(0);
3686          if ($link !== null)
3687          {
3688              return $link;
3689          }
3690          elseif ($enclosure !== null)
3691          {
3692              return $enclosure->get_link();
3693          }
3694          else
3695          {
3696              return null;
3697          }
3698      }
3699  
3700  	function get_link($key = 0, $rel = 'alternate')
3701      {
3702          $links = $this->get_links($rel);
3703          if ($links[$key] !== null)
3704          {
3705              return $links[$key];
3706          }
3707          else
3708          {
3709              return null;
3710          }
3711      }
3712  
3713  	function get_links($rel = 'alternate')
3714      {
3715          if (!isset($this->data['links']))
3716          {
3717              $this->data['links'] = array();
3718              foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
3719              {
3720                  if (isset($link['attribs']['']['href']))
3721                  {
3722                      $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3723                      $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3724  
3725                  }
3726              }
3727              foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
3728              {
3729                  if (isset($link['attribs']['']['href']))
3730                  {
3731                      $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
3732                      $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
3733                  }
3734              }
3735              if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
3736              {
3737                  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3738              }
3739              if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
3740              {
3741                  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3742              }
3743              if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
3744              {
3745                  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3746              }
3747              if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
3748              {
3749                  if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
3750                  {
3751                      $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
3752                  }
3753              }
3754  
3755              $keys = array_keys($this->data['links']);
3756              foreach ($keys as $key)
3757              {
3758                  if (SimplePie_Misc::is_isegment_nz_nc($key))
3759                  {
3760                      if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
3761                      {
3762                          $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
3763                          $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
3764                      }
3765                      else
3766                      {
3767                          $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
3768                      }
3769                  }
3770                  elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
3771                  {
3772                      $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
3773                  }
3774                  $this->data['links'][$key] = array_unique($this->data['links'][$key]);
3775              }
3776          }
3777          if (isset($this->data['links'][$rel]))
3778          {
3779              return $this->data['links'][$rel];
3780          }
3781          else
3782          {
3783              return null;
3784          }
3785      }
3786  
3787      /**
3788       * @todo Add ability to prefer one type of content over another (in a media group).
3789       */
3790  	function get_enclosure($key = 0, $prefer = null)
3791      {
3792          $enclosures = $this->get_enclosures();
3793          if (isset($enclosures[$key]))
3794          {
3795              return $enclosures[$key];
3796          }
3797          else
3798          {
3799              return null;
3800          }
3801      }
3802  
3803      /**
3804       * Grabs all available enclosures (podcasts, etc.)
3805       *
3806       * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
3807       *
3808       * At this point, we're pretty much assuming that all enclosures for an item are the same content.  Anything else is too complicated to properly support.
3809       *
3810       * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
3811       * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists).
3812       */
3813  	function get_enclosures()
3814      {
3815          if (!isset($this->data['enclosures']))
3816          {
3817              $this->data['enclosures'] = array();
3818  
3819              // Elements
3820              $captions_parent = null;
3821              $categories_parent = null;
3822              $copyrights_parent = null;
3823              $credits_parent = null;
3824              $description_parent = null;
3825              $duration_parent = null;
3826              $hashes_parent = null;
3827              $keywords_parent = null;
3828              $player_parent = null;
3829              $ratings_parent = null;
3830              $restrictions_parent = null;
3831              $thumbnails_parent = null;
3832              $title_parent = null;
3833  
3834              // Let's do the channel and item-level ones first, and just re-use them if we need to.
3835              $parent = $this->get_feed();
3836  
3837              // CAPTIONS
3838              if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3839              {
3840                  foreach ($captions as $caption)
3841                  {
3842                      $caption_type = null;
3843                      $caption_lang = null;
3844                      $caption_startTime = null;
3845                      $caption_endTime = null;
3846                      $caption_text = null;
3847                      if (isset($caption['attribs']['']['type']))
3848                      {
3849                          $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3850                      }
3851                      if (isset($caption['attribs']['']['lang']))
3852                      {
3853                          $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3854                      }
3855                      if (isset($caption['attribs']['']['start']))
3856                      {
3857                          $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3858                      }
3859                      if (isset($caption['attribs']['']['end']))
3860                      {
3861                          $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3862                      }
3863                      if (isset($caption['data']))
3864                      {
3865                          $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3866                      }
3867                      $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3868                  }
3869              }
3870              elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
3871              {
3872                  foreach ($captions as $caption)
3873                  {
3874                      $caption_type = null;
3875                      $caption_lang = null;
3876                      $caption_startTime = null;
3877                      $caption_endTime = null;
3878                      $caption_text = null;
3879                      if (isset($caption['attribs']['']['type']))
3880                      {
3881                          $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
3882                      }
3883                      if (isset($caption['attribs']['']['lang']))
3884                      {
3885                          $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
3886                      }
3887                      if (isset($caption['attribs']['']['start']))
3888                      {
3889                          $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
3890                      }
3891                      if (isset($caption['attribs']['']['end']))
3892                      {
3893                          $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
3894                      }
3895                      if (isset($caption['data']))
3896                      {
3897                          $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3898                      }
3899                      $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
3900                  }
3901              }
3902              if (is_array($captions_parent))
3903              {
3904                  $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent));
3905              }
3906  
3907              // CATEGORIES
3908              foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3909              {
3910                  $term = null;
3911                  $scheme = null;
3912                  $label = null;
3913                  if (isset($category['data']))
3914                  {
3915                      $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3916                  }
3917                  if (isset($category['attribs']['']['scheme']))
3918                  {
3919                      $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3920                  }
3921                  else
3922                  {
3923                      $scheme = 'http://search.yahoo.com/mrss/category_schema';
3924                  }
3925                  if (isset($category['attribs']['']['label']))
3926                  {
3927                      $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3928                  }
3929                  $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3930              }
3931              foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
3932              {
3933                  $term = null;
3934                  $scheme = null;
3935                  $label = null;
3936                  if (isset($category['data']))
3937                  {
3938                      $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3939                  }
3940                  if (isset($category['attribs']['']['scheme']))
3941                  {
3942                      $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
3943                  }
3944                  else
3945                  {
3946                      $scheme = 'http://search.yahoo.com/mrss/category_schema';
3947                  }
3948                  if (isset($category['attribs']['']['label']))
3949                  {
3950                      $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
3951                  }
3952                  $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3953              }
3954              foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
3955              {
3956                  $term = null;
3957                  $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
3958                  $label = null;
3959                  if (isset($category['attribs']['']['text']))
3960                  {
3961                      $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3962                  }
3963                  $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3964  
3965                  if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
3966                  {
3967                      foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
3968                      {
3969                          if (isset($subcategory['attribs']['']['text']))
3970                          {
3971                              $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
3972                          }
3973                          $categories_parent[] = new $this->feed->category_class($term, $scheme, $label);
3974                      }
3975                  }
3976              }
3977              if (is_array($categories_parent))
3978              {
3979                  $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent));
3980              }
3981  
3982              // COPYRIGHT
3983              if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3984              {
3985                  $copyright_url = null;
3986                  $copyright_label = null;
3987                  if (isset($copyright[0]['attribs']['']['url']))
3988                  {
3989                      $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
3990                  }
3991                  if (isset($copyright[0]['data']))
3992                  {
3993                      $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
3994                  }
3995                  $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
3996              }
3997              elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
3998              {
3999                  $copyright_url = null;
4000                  $copyright_label = null;
4001                  if (isset($copyright[0]['attribs']['']['url']))
4002                  {
4003                      $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4004                  }
4005                  if (isset($copyright[0]['data']))
4006                  {
4007                      $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4008                  }
4009                  $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label);
4010              }
4011  
4012              // CREDITS
4013              if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
4014              {
4015                  foreach ($credits as $credit)
4016                  {
4017                      $credit_role = null;
4018                      $credit_scheme = null;
4019                      $credit_name = null;
4020                      if (isset($credit['attribs']['']['role']))
4021                      {
4022                          $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4023                      }
4024                      if (isset($credit['attribs']['']['scheme']))
4025                      {
4026                          $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4027                      }
4028                      else
4029                      {
4030                          $credit_scheme = 'urn:ebu';
4031                      }
4032                      if (isset($credit['data']))
4033                      {
4034                          $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4035                      }
4036                      $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4037                  }
4038              }
4039              elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
4040              {
4041                  foreach ($credits as $credit)
4042                  {
4043                      $credit_role = null;
4044                      $credit_scheme = null;
4045                      $credit_name = null;
4046                      if (isset($credit['attribs']['']['role']))
4047                      {
4048                          $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4049                      }
4050                      if (isset($credit['attribs']['']['scheme']))
4051                      {
4052                          $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4053                      }
4054                      else
4055                      {
4056                          $credit_scheme = 'urn:ebu';
4057                      }
4058                      if (isset($credit['data']))
4059                      {
4060                          $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4061                      }
4062                      $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4063                  }
4064              }
4065              if (is_array($credits_parent))
4066              {
4067                  $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent));
4068              }
4069  
4070              // DESCRIPTION
4071              if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4072              {
4073                  if (isset($description_parent[0]['data']))
4074                  {
4075                      $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4076                  }
4077              }
4078              elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
4079              {
4080                  if (isset($description_parent[0]['data']))
4081                  {
4082                      $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4083                  }
4084              }
4085  
4086              // DURATION
4087              if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
4088              {
4089                  $seconds = null;
4090                  $minutes = null;
4091                  $hours = null;
4092                  if (isset($duration_parent[0]['data']))
4093                  {
4094                      $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4095                      if (sizeof($temp) > 0)
4096                      {
4097                          $seconds = (int) array_pop($temp);
4098                      }
4099                      if (sizeof($temp) > 0)
4100                      {
4101                          $minutes = (int) array_pop($temp);
4102                          $seconds += $minutes * 60;
4103                      }
4104                      if (sizeof($temp) > 0)
4105                      {
4106                          $hours = (int) array_pop($temp);
4107                          $seconds += $hours * 3600;
4108                      }
4109                      unset($temp);
4110                      $duration_parent = $seconds;
4111                  }
4112              }
4113  
4114              // HASHES
4115              if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4116              {
4117                  foreach ($hashes_iterator as $hash)
4118                  {
4119                      $value = null;
4120                      $algo = null;
4121                      if (isset($hash['data']))
4122                      {
4123                          $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4124                      }
4125                      if (isset($hash['attribs']['']['algo']))
4126                      {
4127                          $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4128                      }
4129                      else
4130                      {
4131                          $algo = 'md5';
4132                      }
4133                      $hashes_parent[] = $algo.':'.$value;
4134                  }
4135              }
4136              elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
4137              {
4138                  foreach ($hashes_iterator as $hash)
4139                  {
4140                      $value = null;
4141                      $algo = null;
4142                      if (isset($hash['data']))
4143                      {
4144                          $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4145                      }
4146                      if (isset($hash['attribs']['']['algo']))
4147                      {
4148                          $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4149                      }
4150                      else
4151                      {
4152                          $algo = 'md5';
4153                      }
4154                      $hashes_parent[] = $algo.':'.$value;
4155                  }
4156              }
4157              if (is_array($hashes_parent))
4158              {
4159                  $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent));
4160              }
4161  
4162              // KEYWORDS
4163              if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4164              {
4165                  if (isset($keywords[0]['data']))
4166                  {
4167                      $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4168                      foreach ($temp as $word)
4169                      {
4170                          $keywords_parent[] = trim($word);
4171                      }
4172                  }
4173                  unset($temp);
4174              }
4175              elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4176              {
4177                  if (isset($keywords[0]['data']))
4178                  {
4179                      $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4180                      foreach ($temp as $word)
4181                      {
4182                          $keywords_parent[] = trim($word);
4183                      }
4184                  }
4185                  unset($temp);
4186              }
4187              elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
4188              {
4189                  if (isset($keywords[0]['data']))
4190                  {
4191                      $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4192                      foreach ($temp as $word)
4193                      {
4194                          $keywords_parent[] = trim($word);
4195                      }
4196                  }
4197                  unset($temp);
4198              }
4199              elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
4200              {
4201                  if (isset($keywords[0]['data']))
4202                  {
4203                      $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4204                      foreach ($temp as $word)
4205                      {
4206                          $keywords_parent[] = trim($word);
4207                      }
4208                  }
4209                  unset($temp);
4210              }
4211              if (is_array($keywords_parent))
4212              {
4213                  $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent));
4214              }
4215  
4216              // PLAYER
4217              if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4218              {
4219                  if (isset($player_parent[0]['attribs']['']['url']))
4220                  {
4221                      $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4222                  }
4223              }
4224              elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
4225              {
4226                  if (isset($player_parent[0]['attribs']['']['url']))
4227                  {
4228                      $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4229                  }
4230              }
4231  
4232              // RATINGS
4233              if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4234              {
4235                  foreach ($ratings as $rating)
4236                  {
4237                      $rating_scheme = null;
4238                      $rating_value = null;
4239                      if (isset($rating['attribs']['']['scheme']))
4240                      {
4241                          $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4242                      }
4243                      else
4244                      {
4245                          $rating_scheme = 'urn:simple';
4246                      }
4247                      if (isset($rating['data']))
4248                      {
4249                          $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4250                      }
4251                      $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4252                  }
4253              }
4254              elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4255              {
4256                  foreach ($ratings as $rating)
4257                  {
4258                      $rating_scheme = 'urn:itunes';
4259                      $rating_value = null;
4260                      if (isset($rating['data']))
4261                      {
4262                          $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4263                      }
4264                      $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4265                  }
4266              }
4267              elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
4268              {
4269                  foreach ($ratings as $rating)
4270                  {
4271                      $rating_scheme = null;
4272                      $rating_value = null;
4273                      if (isset($rating['attribs']['']['scheme']))
4274                      {
4275                          $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4276                      }
4277                      else
4278                      {
4279                          $rating_scheme = 'urn:simple';
4280                      }
4281                      if (isset($rating['data']))
4282                      {
4283                          $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4284                      }
4285                      $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4286                  }
4287              }
4288              elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
4289              {
4290                  foreach ($ratings as $rating)
4291                  {
4292                      $rating_scheme = 'urn:itunes';
4293                      $rating_value = null;
4294                      if (isset($rating['data']))
4295                      {
4296                          $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4297                      }
4298                      $ratings_parent[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4299                  }
4300              }
4301              if (is_array($ratings_parent))
4302              {
4303                  $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent));
4304              }
4305  
4306              // RESTRICTIONS
4307              if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4308              {
4309                  foreach ($restrictions as $restriction)
4310                  {
4311                      $restriction_relationship = null;
4312                      $restriction_type = null;
4313                      $restriction_value = null;
4314                      if (isset($restriction['attribs']['']['relationship']))
4315                      {
4316                          $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4317                      }
4318                      if (isset($restriction['attribs']['']['type']))
4319                      {
4320                          $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4321                      }
4322                      if (isset($restriction['data']))
4323                      {
4324                          $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4325                      }
4326                      $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4327                  }
4328              }
4329              elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4330              {
4331                  foreach ($restrictions as $restriction)
4332                  {
4333                      $restriction_relationship = 'allow';
4334                      $restriction_type = null;
4335                      $restriction_value = 'itunes';
4336                      if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4337                      {
4338                          $restriction_relationship = 'deny';
4339                      }
4340                      $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4341                  }
4342              }
4343              elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
4344              {
4345                  foreach ($restrictions as $restriction)
4346                  {
4347                      $restriction_relationship = null;
4348                      $restriction_type = null;
4349                      $restriction_value = null;
4350                      if (isset($restriction['attribs']['']['relationship']))
4351                      {
4352                          $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4353                      }
4354                      if (isset($restriction['attribs']['']['type']))
4355                      {
4356                          $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4357                      }
4358                      if (isset($restriction['data']))
4359                      {
4360                          $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4361                      }
4362                      $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4363                  }
4364              }
4365              elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
4366              {
4367                  foreach ($restrictions as $restriction)
4368                  {
4369                      $restriction_relationship = 'allow';
4370                      $restriction_type = null;
4371                      $restriction_value = 'itunes';
4372                      if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
4373                      {
4374                          $restriction_relationship = 'deny';
4375                      }
4376                      $restrictions_parent[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4377                  }
4378              }
4379              if (is_array($restrictions_parent))
4380              {
4381                  $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent));
4382              }
4383  
4384              // THUMBNAILS
4385              if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4386              {
4387                  foreach ($thumbnails as $thumbnail)
4388                  {
4389                      if (isset($thumbnail['attribs']['']['url']))
4390                      {
4391                          $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4392                      }
4393                  }
4394              }
4395              elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
4396              {
4397                  foreach ($thumbnails as $thumbnail)
4398                  {
4399                      if (isset($thumbnail['attribs']['']['url']))
4400                      {
4401                          $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4402                      }
4403                  }
4404              }
4405  
4406              // TITLES
4407              if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4408              {
4409                  if (isset($title_parent[0]['data']))
4410                  {
4411                      $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4412                  }
4413              }
4414              elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
4415              {
4416                  if (isset($title_parent[0]['data']))
4417                  {
4418                      $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4419                  }
4420              }
4421  
4422              // Clear the memory
4423              unset($parent);
4424  
4425              // Attributes
4426              $bitrate = null;
4427              $channels = null;
4428              $duration = null;
4429              $expression = null;
4430              $framerate = null;
4431              $height = null;
4432              $javascript = null;
4433              $lang = null;
4434              $length = null;
4435              $medium = null;
4436              $samplingrate = null;
4437              $type = null;
4438              $url = null;
4439              $width = null;
4440  
4441              // Elements
4442              $captions = null;
4443              $categories = null;
4444              $copyrights = null;
4445              $credits = null;
4446              $description = null;
4447              $hashes = null;
4448              $keywords = null;
4449              $player = null;
4450              $ratings = null;
4451              $restrictions = null;
4452              $thumbnails = null;
4453              $title = null;
4454  
4455              // If we have media:group tags, loop through them.
4456              foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
4457              {
4458                  if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
4459                  {
4460                      // If we have media:content tags, loop through them.
4461                      foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
4462                      {
4463                          if (isset($content['attribs']['']['url']))
4464                          {
4465                              // Attributes
4466                              $bitrate = null;
4467                              $channels = null;
4468                              $duration = null;
4469                              $expression = null;
4470                              $framerate = null;
4471                              $height = null;
4472                              $javascript = null;
4473                              $lang = null;
4474                              $length = null;
4475                              $medium = null;
4476                              $samplingrate = null;
4477                              $type = null;
4478                              $url = null;
4479                              $width = null;
4480  
4481                              // Elements
4482                              $captions = null;
4483                              $categories = null;
4484                              $copyrights = null;
4485                              $credits = null;
4486                              $description = null;
4487                              $hashes = null;
4488                              $keywords = null;
4489                              $player = null;
4490                              $ratings = null;
4491                              $restrictions = null;
4492                              $thumbnails = null;
4493                              $title = null;
4494  
4495                              // Start checking the attributes of media:content
4496                              if (isset($content['attribs']['']['bitrate']))
4497                              {
4498                                  $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4499                              }
4500                              if (isset($content['attribs']['']['channels']))
4501                              {
4502                                  $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
4503                              }
4504                              if (isset($content['attribs']['']['duration']))
4505                              {
4506                                  $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
4507                              }
4508                              else
4509                              {
4510                                  $duration = $duration_parent;
4511                              }
4512                              if (isset($content['attribs']['']['expression']))
4513                              {
4514                                  $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
4515                              }
4516                              if (isset($content['attribs']['']['framerate']))
4517                              {
4518                                  $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
4519                              }
4520                              if (isset($content['attribs']['']['height']))
4521                              {
4522                                  $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
4523                              }
4524                              if (isset($content['attribs']['']['lang']))
4525                              {
4526                                  $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4527                              }
4528                              if (isset($content['attribs']['']['fileSize']))
4529                              {
4530                                  $length = ceil($content['attribs']['']['fileSize']);
4531                              }
4532                              if (isset($content['attribs']['']['medium']))
4533                              {
4534                                  $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
4535                              }
4536                              if (isset($content['attribs']['']['samplingrate']))
4537                              {
4538                                  $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
4539                              }
4540                              if (isset($content['attribs']['']['type']))
4541                              {
4542                                  $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4543                              }
4544                              if (isset($content['attribs']['']['width']))
4545                              {
4546                                  $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
4547                              }
4548                              $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4549  
4550                              // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
4551  
4552                              // CAPTIONS
4553                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4554                              {
4555                                  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4556                                  {
4557                                      $caption_type = null;
4558                                      $caption_lang = null;
4559                                      $caption_startTime = null;
4560                                      $caption_endTime = null;
4561                                      $caption_text = null;
4562                                      if (isset($caption['attribs']['']['type']))
4563                                      {
4564                                          $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4565                                      }
4566                                      if (isset($caption['attribs']['']['lang']))
4567                                      {
4568                                          $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4569                                      }
4570                                      if (isset($caption['attribs']['']['start']))
4571                                      {
4572                                          $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4573                                      }
4574                                      if (isset($caption['attribs']['']['end']))
4575                                      {
4576                                          $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4577                                      }
4578                                      if (isset($caption['data']))
4579                                      {
4580                                          $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4581                                      }
4582                                      $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4583                                  }
4584                                  if (is_array($captions))
4585                                  {
4586                                      $captions = array_values(SimplePie_Misc::array_unique($captions));
4587                                  }
4588                              }
4589                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
4590                              {
4591                                  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
4592                                  {
4593                                      $caption_type = null;
4594                                      $caption_lang = null;
4595                                      $caption_startTime = null;
4596                                      $caption_endTime = null;
4597                                      $caption_text = null;
4598                                      if (isset($caption['attribs']['']['type']))
4599                                      {
4600                                          $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4601                                      }
4602                                      if (isset($caption['attribs']['']['lang']))
4603                                      {
4604                                          $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
4605                                      }
4606                                      if (isset($caption['attribs']['']['start']))
4607                                      {
4608                                          $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
4609                                      }
4610                                      if (isset($caption['attribs']['']['end']))
4611                                      {
4612                                          $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
4613                                      }
4614                                      if (isset($caption['data']))
4615                                      {
4616                                          $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4617                                      }
4618                                      $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
4619                                  }
4620                                  if (is_array($captions))
4621                                  {
4622                                      $captions = array_values(SimplePie_Misc::array_unique($captions));
4623                                  }
4624                              }
4625                              else
4626                              {
4627                                  $captions = $captions_parent;
4628                              }
4629  
4630                              // CATEGORIES
4631                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4632                              {
4633                                  foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4634                                  {
4635                                      $term = null;
4636                                      $scheme = null;
4637                                      $label = null;
4638                                      if (isset($category['data']))
4639                                      {
4640                                          $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4641                                      }
4642                                      if (isset($category['attribs']['']['scheme']))
4643                                      {
4644                                          $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4645                                      }
4646                                      else
4647                                      {
4648                                          $scheme = 'http://search.yahoo.com/mrss/category_schema';
4649                                      }
4650                                      if (isset($category['attribs']['']['label']))
4651                                      {
4652                                          $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4653                                      }
4654                                      $categories[] = new $this->feed->category_class($term, $scheme, $label);
4655                                  }
4656                              }
4657                              if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
4658                              {
4659                                  foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
4660                                  {
4661                                      $term = null;
4662                                      $scheme = null;
4663                                      $label = null;
4664                                      if (isset($category['data']))
4665                                      {
4666                                          $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4667                                      }
4668                                      if (isset($category['attribs']['']['scheme']))
4669                                      {
4670                                          $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4671                                      }
4672                                      else
4673                                      {
4674                                          $scheme = 'http://search.yahoo.com/mrss/category_schema';
4675                                      }
4676                                      if (isset($category['attribs']['']['label']))
4677                                      {
4678                                          $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
4679                                      }
4680                                      $categories[] = new $this->feed->category_class($term, $scheme, $label);
4681                                  }
4682                              }
4683                              if (is_array($categories) && is_array($categories_parent))
4684                              {
4685                                  $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
4686                              }
4687                              elseif (is_array($categories))
4688                              {
4689                                  $categories = array_values(SimplePie_Misc::array_unique($categories));
4690                              }
4691                              elseif (is_array($categories_parent))
4692                              {
4693                                  $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
4694                              }
4695  
4696                              // COPYRIGHTS
4697                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4698                              {
4699                                  $copyright_url = null;
4700                                  $copyright_label = null;
4701                                  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4702                                  {
4703                                      $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4704                                  }
4705                                  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4706                                  {
4707                                      $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4708                                  }
4709                                  $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4710                              }
4711                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
4712                              {
4713                                  $copyright_url = null;
4714                                  $copyright_label = null;
4715                                  if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
4716                                  {
4717                                      $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
4718                                  }
4719                                  if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
4720                                  {
4721                                      $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4722                                  }
4723                                  $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
4724                              }
4725                              else
4726                              {
4727                                  $copyrights = $copyrights_parent;
4728                              }
4729  
4730                              // CREDITS
4731                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4732                              {
4733                                  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4734                                  {
4735                                      $credit_role = null;
4736                                      $credit_scheme = null;
4737                                      $credit_name = null;
4738                                      if (isset($credit['attribs']['']['role']))
4739                                      {
4740                                          $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4741                                      }
4742                                      if (isset($credit['attribs']['']['scheme']))
4743                                      {
4744                                          $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4745                                      }
4746                                      else
4747                                      {
4748                                          $credit_scheme = 'urn:ebu';
4749                                      }
4750                                      if (isset($credit['data']))
4751                                      {
4752                                          $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4753                                      }
4754                                      $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4755                                  }
4756                                  if (is_array($credits))
4757                                  {
4758                                      $credits = array_values(SimplePie_Misc::array_unique($credits));
4759                                  }
4760                              }
4761                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
4762                              {
4763                                  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
4764                                  {
4765                                      $credit_role = null;
4766                                      $credit_scheme = null;
4767                                      $credit_name = null;
4768                                      if (isset($credit['attribs']['']['role']))
4769                                      {
4770                                          $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
4771                                      }
4772                                      if (isset($credit['attribs']['']['scheme']))
4773                                      {
4774                                          $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4775                                      }
4776                                      else
4777                                      {
4778                                          $credit_scheme = 'urn:ebu';
4779                                      }
4780                                      if (isset($credit['data']))
4781                                      {
4782                                          $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4783                                      }
4784                                      $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
4785                                  }
4786                                  if (is_array($credits))
4787                                  {
4788                                      $credits = array_values(SimplePie_Misc::array_unique($credits));
4789                                  }
4790                              }
4791                              else
4792                              {
4793                                  $credits = $credits_parent;
4794                              }
4795  
4796                              // DESCRIPTION
4797                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4798                              {
4799                                  $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4800                              }
4801                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
4802                              {
4803                                  $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4804                              }
4805                              else
4806                              {
4807                                  $description = $description_parent;
4808                              }
4809  
4810                              // HASHES
4811                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4812                              {
4813                                  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4814                                  {
4815                                      $value = null;
4816                                      $algo = null;
4817                                      if (isset($hash['data']))
4818                                      {
4819                                          $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4820                                      }
4821                                      if (isset($hash['attribs']['']['algo']))
4822                                      {
4823                                          $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4824                                      }
4825                                      else
4826                                      {
4827                                          $algo = 'md5';
4828                                      }
4829                                      $hashes[] = $algo.':'.$value;
4830                                  }
4831                                  if (is_array($hashes))
4832                                  {
4833                                      $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4834                                  }
4835                              }
4836                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
4837                              {
4838                                  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
4839                                  {
4840                                      $value = null;
4841                                      $algo = null;
4842                                      if (isset($hash['data']))
4843                                      {
4844                                          $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4845                                      }
4846                                      if (isset($hash['attribs']['']['algo']))
4847                                      {
4848                                          $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
4849                                      }
4850                                      else
4851                                      {
4852                                          $algo = 'md5';
4853                                      }
4854                                      $hashes[] = $algo.':'.$value;
4855                                  }
4856                                  if (is_array($hashes))
4857                                  {
4858                                      $hashes = array_values(SimplePie_Misc::array_unique($hashes));
4859                                  }
4860                              }
4861                              else
4862                              {
4863                                  $hashes = $hashes_parent;
4864                              }
4865  
4866                              // KEYWORDS
4867                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4868                              {
4869                                  if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4870                                  {
4871                                      $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4872                                      foreach ($temp as $word)
4873                                      {
4874                                          $keywords[] = trim($word);
4875                                      }
4876                                      unset($temp);
4877                                  }
4878                                  if (is_array($keywords))
4879                                  {
4880                                      $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4881                                  }
4882                              }
4883                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
4884                              {
4885                                  if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
4886                                  {
4887                                      $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
4888                                      foreach ($temp as $word)
4889                                      {
4890                                          $keywords[] = trim($word);
4891                                      }
4892                                      unset($temp);
4893                                  }
4894                                  if (is_array($keywords))
4895                                  {
4896                                      $keywords = array_values(SimplePie_Misc::array_unique($keywords));
4897                                  }
4898                              }
4899                              else
4900                              {
4901                                  $keywords = $keywords_parent;
4902                              }
4903  
4904                              // PLAYER
4905                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4906                              {
4907                                  $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4908                              }
4909                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
4910                              {
4911                                  $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
4912                              }
4913                              else
4914                              {
4915                                  $player = $player_parent;
4916                              }
4917  
4918                              // RATINGS
4919                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4920                              {
4921                                  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4922                                  {
4923                                      $rating_scheme = null;
4924                                      $rating_value = null;
4925                                      if (isset($rating['attribs']['']['scheme']))
4926                                      {
4927                                          $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4928                                      }
4929                                      else
4930                                      {
4931                                          $rating_scheme = 'urn:simple';
4932                                      }
4933                                      if (isset($rating['data']))
4934                                      {
4935                                          $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4936                                      }
4937                                      $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4938                                  }
4939                                  if (is_array($ratings))
4940                                  {
4941                                      $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4942                                  }
4943                              }
4944                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
4945                              {
4946                                  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
4947                                  {
4948                                      $rating_scheme = null;
4949                                      $rating_value = null;
4950                                      if (isset($rating['attribs']['']['scheme']))
4951                                      {
4952                                          $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
4953                                      }
4954                                      else
4955                                      {
4956                                          $rating_scheme = 'urn:simple';
4957                                      }
4958                                      if (isset($rating['data']))
4959                                      {
4960                                          $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4961                                      }
4962                                      $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
4963                                  }
4964                                  if (is_array($ratings))
4965                                  {
4966                                      $ratings = array_values(SimplePie_Misc::array_unique($ratings));
4967                                  }
4968                              }
4969                              else
4970                              {
4971                                  $ratings = $ratings_parent;
4972                              }
4973  
4974                              // RESTRICTIONS
4975                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
4976                              {
4977                                  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
4978                                  {
4979                                      $restriction_relationship = null;
4980                                      $restriction_type = null;
4981                                      $restriction_value = null;
4982                                      if (isset($restriction['attribs']['']['relationship']))
4983                                      {
4984                                          $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
4985                                      }
4986                                      if (isset($restriction['attribs']['']['type']))
4987                                      {
4988                                          $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
4989                                      }
4990                                      if (isset($restriction['data']))
4991                                      {
4992                                          $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
4993                                      }
4994                                      $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
4995                                  }
4996                                  if (is_array($restrictions))
4997                                  {
4998                                      $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
4999                                  }
5000                              }
5001                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5002                              {
5003                                  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5004                                  {
5005                                      $restriction_relationship = null;
5006                                      $restriction_type = null;
5007                                      $restriction_value = null;
5008                                      if (isset($restriction['attribs']['']['relationship']))
5009                                      {
5010                                          $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5011                                      }
5012                                      if (isset($restriction['attribs']['']['type']))
5013                                      {
5014                                          $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5015                                      }
5016                                      if (isset($restriction['data']))
5017                                      {
5018                                          $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5019                                      }
5020                                      $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5021                                  }
5022                                  if (is_array($restrictions))
5023                                  {
5024                                      $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5025                                  }
5026                              }
5027                              else
5028                              {
5029                                  $restrictions = $restrictions_parent;
5030                              }
5031  
5032                              // THUMBNAILS
5033                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5034                              {
5035                                  foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5036                                  {
5037                                      $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5038                                  }
5039                                  if (is_array($thumbnails))
5040                                  {
5041                                      $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5042                                  }
5043                              }
5044                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5045                              {
5046                                  foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5047                                  {
5048                                      $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5049                                  }
5050                                  if (is_array($thumbnails))
5051                                  {
5052                                      $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5053                                  }
5054                              }
5055                              else
5056                              {
5057                                  $thumbnails = $thumbnails_parent;
5058                              }
5059  
5060                              // TITLES
5061                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5062                              {
5063                                  $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5064                              }
5065                              elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5066                              {
5067                                  $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5068                              }
5069                              else
5070                              {
5071                                  $title = $title_parent;
5072                              }
5073  
5074                              $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
5075                          }
5076                      }
5077                  }
5078              }
5079  
5080              // If we have standalone media:content tags, loop through them.
5081              if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
5082              {
5083                  foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
5084                  {
5085                      if (isset($content['attribs']['']['url']) || isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5086                      {
5087                          // Attributes
5088                          $bitrate = null;
5089                          $channels = null;
5090                          $duration = null;
5091                          $expression = null;
5092                          $framerate = null;
5093                          $height = null;
5094                          $javascript = null;
5095                          $lang = null;
5096                          $length = null;
5097                          $medium = null;
5098                          $samplingrate = null;
5099                          $type = null;
5100                          $url = null;
5101                          $width = null;
5102  
5103                          // Elements
5104                          $captions = null;
5105                          $categories = null;
5106                          $copyrights = null;
5107                          $credits = null;
5108                          $description = null;
5109                          $hashes = null;
5110                          $keywords = null;
5111                          $player = null;
5112                          $ratings = null;
5113                          $restrictions = null;
5114                          $thumbnails = null;
5115                          $title = null;
5116  
5117                          // Start checking the attributes of media:content
5118                          if (isset($content['attribs']['']['bitrate']))
5119                          {
5120                              $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5121                          }
5122                          if (isset($content['attribs']['']['channels']))
5123                          {
5124                              $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
5125                          }
5126                          if (isset($content['attribs']['']['duration']))
5127                          {
5128                              $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
5129                          }
5130                          else
5131                          {
5132                              $duration = $duration_parent;
5133                          }
5134                          if (isset($content['attribs']['']['expression']))
5135                          {
5136                              $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
5137                          }
5138                          if (isset($content['attribs']['']['framerate']))
5139                          {
5140                              $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
5141                          }
5142                          if (isset($content['attribs']['']['height']))
5143                          {
5144                              $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
5145                          }
5146                          if (isset($content['attribs']['']['lang']))
5147                          {
5148                              $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5149                          }
5150                          if (isset($content['attribs']['']['fileSize']))
5151                          {
5152                              $length = ceil($content['attribs']['']['fileSize']);
5153                          }
5154                          if (isset($content['attribs']['']['medium']))
5155                          {
5156                              $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
5157                          }
5158                          if (isset($content['attribs']['']['samplingrate']))
5159                          {
5160                              $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
5161                          }
5162                          if (isset($content['attribs']['']['type']))
5163                          {
5164                              $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5165                          }
5166                          if (isset($content['attribs']['']['width']))
5167                          {
5168                              $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
5169                          }
5170                          if (isset($content['attribs']['']['url']))
5171                          {
5172                              $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5173                          }
5174                          // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
5175  
5176                          // CAPTIONS
5177                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
5178                          {
5179                              foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
5180                              {
5181                                  $caption_type = null;
5182                                  $caption_lang = null;
5183                                  $caption_startTime = null;
5184                                  $caption_endTime = null;
5185                                  $caption_text = null;
5186                                  if (isset($caption['attribs']['']['type']))
5187                                  {
5188                                      $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5189                                  }
5190                                  if (isset($caption['attribs']['']['lang']))
5191                                  {
5192                                      $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
5193                                  }
5194                                  if (isset($caption['attribs']['']['start']))
5195                                  {
5196                                      $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
5197                                  }
5198                                  if (isset($caption['attribs']['']['end']))
5199                                  {
5200                                      $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
5201                                  }
5202                                  if (isset($caption['data']))
5203                                  {
5204                                      $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5205                                  }
5206                                  $captions[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text);
5207                              }
5208                              if (is_array($captions))
5209                              {
5210                                  $captions = array_values(SimplePie_Misc::array_unique($captions));
5211                              }
5212                          }
5213                          else
5214                          {
5215                              $captions = $captions_parent;
5216                          }
5217  
5218                          // CATEGORIES
5219                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
5220                          {
5221                              foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
5222                              {
5223                                  $term = null;
5224                                  $scheme = null;
5225                                  $label = null;
5226                                  if (isset($category['data']))
5227                                  {
5228                                      $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5229                                  }
5230                                  if (isset($category['attribs']['']['scheme']))
5231                                  {
5232                                      $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5233                                  }
5234                                  else
5235                                  {
5236                                      $scheme = 'http://search.yahoo.com/mrss/category_schema';
5237                                  }
5238                                  if (isset($category['attribs']['']['label']))
5239                                  {
5240                                      $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5241                                  }
5242                                  $categories[] = new $this->feed->category_class($term, $scheme, $label);
5243                              }
5244                          }
5245                          if (is_array($categories) && is_array($categories_parent))
5246                          {
5247                              $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent)));
5248                          }
5249                          elseif (is_array($categories))
5250                          {
5251                              $categories = array_values(SimplePie_Misc::array_unique($categories));
5252                          }
5253                          elseif (is_array($categories_parent))
5254                          {
5255                              $categories = array_values(SimplePie_Misc::array_unique($categories_parent));
5256                          }
5257                          else
5258                          {
5259                              $categories = null;
5260                          }
5261  
5262                          // COPYRIGHTS
5263                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
5264                          {
5265                              $copyright_url = null;
5266                              $copyright_label = null;
5267                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
5268                              {
5269                                  $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
5270                              }
5271                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
5272                              {
5273                                  $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5274                              }
5275                              $copyrights = new $this->feed->copyright_class($copyright_url, $copyright_label);
5276                          }
5277                          else
5278                          {
5279                              $copyrights = $copyrights_parent;
5280                          }
5281  
5282                          // CREDITS
5283                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
5284                          {
5285                              foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
5286                              {
5287                                  $credit_role = null;
5288                                  $credit_scheme = null;
5289                                  $credit_name = null;
5290                                  if (isset($credit['attribs']['']['role']))
5291                                  {
5292                                      $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
5293                                  }
5294                                  if (isset($credit['attribs']['']['scheme']))
5295                                  {
5296                                      $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5297                                  }
5298                                  else
5299                                  {
5300                                      $credit_scheme = 'urn:ebu';
5301                                  }
5302                                  if (isset($credit['data']))
5303                                  {
5304                                      $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5305                                  }
5306                                  $credits[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name);
5307                              }
5308                              if (is_array($credits))
5309                              {
5310                                  $credits = array_values(SimplePie_Misc::array_unique($credits));
5311                              }
5312                          }
5313                          else
5314                          {
5315                              $credits = $credits_parent;
5316                          }
5317  
5318                          // DESCRIPTION
5319                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
5320                          {
5321                              $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5322                          }
5323                          else
5324                          {
5325                              $description = $description_parent;
5326                          }
5327  
5328                          // HASHES
5329                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
5330                          {
5331                              foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
5332                              {
5333                                  $value = null;
5334                                  $algo = null;
5335                                  if (isset($hash['data']))
5336                                  {
5337                                      $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5338                                  }
5339                                  if (isset($hash['attribs']['']['algo']))
5340                                  {
5341                                      $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
5342                                  }
5343                                  else
5344                                  {
5345                                      $algo = 'md5';
5346                                  }
5347                                  $hashes[] = $algo.':'.$value;
5348                              }
5349                              if (is_array($hashes))
5350                              {
5351                                  $hashes = array_values(SimplePie_Misc::array_unique($hashes));
5352                              }
5353                          }
5354                          else
5355                          {
5356                              $hashes = $hashes_parent;
5357                          }
5358  
5359                          // KEYWORDS
5360                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
5361                          {
5362                              if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
5363                              {
5364                                  $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
5365                                  foreach ($temp as $word)
5366                                  {
5367                                      $keywords[] = trim($word);
5368                                  }
5369                                  unset($temp);
5370                              }
5371                              if (is_array($keywords))
5372                              {
5373                                  $keywords = array_values(SimplePie_Misc::array_unique($keywords));
5374                              }
5375                          }
5376                          else
5377                          {
5378                              $keywords = $keywords_parent;
5379                          }
5380  
5381                          // PLAYER
5382                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
5383                          {
5384                              $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5385                          }
5386                          else
5387                          {
5388                              $player = $player_parent;
5389                          }
5390  
5391                          // RATINGS
5392                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
5393                          {
5394                              foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
5395                              {
5396                                  $rating_scheme = null;
5397                                  $rating_value = null;
5398                                  if (isset($rating['attribs']['']['scheme']))
5399                                  {
5400                                      $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5401                                  }
5402                                  else
5403                                  {
5404                                      $rating_scheme = 'urn:simple';
5405                                  }
5406                                  if (isset($rating['data']))
5407                                  {
5408                                      $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5409                                  }
5410                                  $ratings[] = new $this->feed->rating_class($rating_scheme, $rating_value);
5411                              }
5412                              if (is_array($ratings))
5413                              {
5414                                  $ratings = array_values(SimplePie_Misc::array_unique($ratings));
5415                              }
5416                          }
5417                          else
5418                          {
5419                              $ratings = $ratings_parent;
5420                          }
5421  
5422                          // RESTRICTIONS
5423                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
5424                          {
5425                              foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
5426                              {
5427                                  $restriction_relationship = null;
5428                                  $restriction_type = null;
5429                                  $restriction_value = null;
5430                                  if (isset($restriction['attribs']['']['relationship']))
5431                                  {
5432                                      $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
5433                                  }
5434                                  if (isset($restriction['attribs']['']['type']))
5435                                  {
5436                                      $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5437                                  }
5438                                  if (isset($restriction['data']))
5439                                  {
5440                                      $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5441                                  }
5442                                  $restrictions[] = new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value);
5443                              }
5444                              if (is_array($restrictions))
5445                              {
5446                                  $restrictions = array_values(SimplePie_Misc::array_unique($restrictions));
5447                              }
5448                          }
5449                          else
5450                          {
5451                              $restrictions = $restrictions_parent;
5452                          }
5453  
5454                          // THUMBNAILS
5455                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
5456                          {
5457                              foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
5458                              {
5459                                  $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
5460                              }
5461                              if (is_array($thumbnails))
5462                              {
5463                                  $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails));
5464                              }
5465                          }
5466                          else
5467                          {
5468                              $thumbnails = $thumbnails_parent;
5469                          }
5470  
5471                          // TITLES
5472                          if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
5473                          {
5474                              $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5475                          }
5476                          else
5477                          {
5478                              $title = $title_parent;
5479                          }
5480  
5481                          $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width);
5482                      }
5483                  }
5484              }
5485  
5486              foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
5487              {
5488                  if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5489                  {
5490                      // Attributes
5491                      $bitrate = null;
5492                      $channels = null;
5493                      $duration = null;
5494                      $expression = null;
5495                      $framerate = null;
5496                      $height = null;
5497                      $javascript = null;
5498                      $lang = null;
5499                      $length = null;
5500                      $medium = null;
5501                      $samplingrate = null;
5502                      $type = null;
5503                      $url = null;
5504                      $width = null;
5505  
5506                      $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5507                      if (isset($link['attribs']['']['type']))
5508                      {
5509                          $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5510                      }
5511                      if (isset($link['attribs']['']['length']))
5512                      {
5513                          $length = ceil($link['attribs']['']['length']);
5514                      }
5515  
5516                      // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5517                      $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5518                  }
5519              }
5520  
5521              foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
5522              {
5523                  if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
5524                  {
5525                      // Attributes
5526                      $bitrate = null;
5527                      $channels = null;
5528                      $duration = null;
5529                      $expression = null;
5530                      $framerate = null;
5531                      $height = null;
5532                      $javascript = null;
5533                      $lang = null;
5534                      $length = null;
5535                      $medium = null;
5536                      $samplingrate = null;
5537                      $type = null;
5538                      $url = null;
5539                      $width = null;
5540  
5541                      $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
5542                      if (isset($link['attribs']['']['type']))
5543                      {
5544                          $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5545                      }
5546                      if (isset($link['attribs']['']['length']))
5547                      {
5548                          $length = ceil($link['attribs']['']['length']);
5549                      }
5550  
5551                      // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5552                      $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5553                  }
5554              }
5555  
5556              if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
5557              {
5558                  if (isset($enclosure[0]['attribs']['']['url']))
5559                  {
5560                      // Attributes
5561                      $bitrate = null;
5562                      $channels = null;
5563                      $duration = null;
5564                      $expression = null;
5565                      $framerate = null;
5566                      $height = null;
5567                      $javascript = null;
5568                      $lang = null;
5569                      $length = null;
5570                      $medium = null;
5571                      $samplingrate = null;
5572                      $type = null;
5573                      $url = null;
5574                      $width = null;
5575  
5576                      $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
5577                      if (isset($enclosure[0]['attribs']['']['type']))
5578                      {
5579                          $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
5580                      }
5581                      if (isset($enclosure[0]['attribs']['']['length']))
5582                      {
5583                          $length = ceil($enclosure[0]['attribs']['']['length']);
5584                      }
5585  
5586                      // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5587                      $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5588                  }
5589              }
5590  
5591              if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width))
5592              {
5593                  // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
5594                  $this->data['enclosures'][] = new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width);
5595              }
5596  
5597              $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures']));
5598          }
5599          if (!empty($this->data['enclosures']))
5600          {
5601              return $this->data['enclosures'];
5602          }
5603          else
5604          {
5605              return null;
5606          }
5607      }
5608  
5609  	function get_latitude()
5610      {
5611          if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
5612          {
5613              return (float) $return[0]['data'];
5614          }
5615          elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
5616          {
5617              return (float) $match[1];
5618          }
5619          else
5620          {
5621              return null;
5622          }
5623      }
5624  
5625  	function get_longitude()
5626      {
5627          if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
5628          {
5629              return (float) $return[0]['data'];
5630          }
5631          elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
5632          {
5633              return (float) $return[0]['data'];
5634          }
5635          elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
5636          {
5637              return (float) $match[2];
5638          }
5639          else
5640          {
5641              return null;
5642          }
5643      }
5644  
5645  	function get_source()
5646      {
5647          if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
5648          {
5649              return new $this->feed->source_class($this, $return[0]);
5650          }
5651          else
5652          {
5653              return null;
5654          }
5655      }
5656  
5657      /**
5658       * Creates the add_to_* methods' return data
5659       *
5660       * @access private
5661       * @param string $item_url String to prefix to the item permalink
5662       * @param string $title_url String to prefix to the item title
5663       * (and suffix to the item permalink)
5664       * @return mixed URL if feed exists, false otherwise
5665       */
5666  	function add_to_service($item_url, $title_url = null, $summary_url = null)
5667      {
5668          if ($this->get_permalink() !== null)
5669          {
5670              $return = $item_url . rawurlencode($this->get_permalink());
5671              if ($title_url !== null && $this->get_title() !== null)
5672              {
5673                  $return .= $title_url . rawurlencode($this->get_title());
5674              }
5675              if ($summary_url !== null && $this->get_description() !== null)
5676              {
5677                  $return .= $summary_url . rawurlencode($this->get_description());
5678              }
5679              return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI);
5680          }
5681          else
5682          {
5683              return null;
5684          }
5685      }
5686  
5687  	function add_to_blinklist()
5688      {
5689          return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title=');
5690      }
5691  
5692  	function add_to_blogmarks()
5693      {
5694          return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title=');
5695      }
5696  
5697  	function add_to_delicious()
5698      {
5699          return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title=');
5700      }
5701  
5702  	function add_to_digg()
5703      {
5704          return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext=');
5705      }
5706  
5707  	function add_to_furl()
5708      {
5709          return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t=');
5710      }
5711  
5712  	function add_to_magnolia()
5713      {
5714          return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title=');
5715      }
5716  
5717  	function add_to_myweb20()
5718      {
5719          return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t=');
5720      }
5721  
5722  	function add_to_newsvine()
5723      {
5724          return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h=');
5725      }
5726  
5727  	function add_to_reddit()
5728      {
5729          return $this->add_to_service('http://reddit.com/submit?url=', '&title=');
5730      }
5731  
5732  	function add_to_segnalo()
5733      {
5734          return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title=');
5735      }
5736  
5737  	function add_to_simpy()
5738      {
5739          return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title=');
5740      }
5741  
5742  	function add_to_spurl()
5743      {
5744          return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title=');
5745      }
5746  
5747  	function add_to_wists()
5748      {
5749          return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title=');
5750      }
5751  
5752  	function search_technorati()
5753      {
5754          return $this->add_to_service('http://www.technorati.com/search/');
5755      }
5756  }
5757  
5758  class SimplePie_Source
5759  {
5760      var $item;
5761      var $data = array();
5762  
5763  	function SimplePie_Source($item, $data)
5764      {
5765          $this->item = $item;
5766          $this->data = $data;
5767      }
5768  
5769  	function __toString()
5770      {
5771          return md5(serialize($this->data));
5772      }
5773  
5774  	function get_source_tags($namespace, $tag)
5775      {
5776          if (isset($this->data['child'][$namespace][$tag]))
5777          {
5778              return $this->data['child'][$namespace][$tag];
5779          }
5780          else
5781          {
5782              return null;
5783          }
5784      }
5785  
5786  	function get_base($element = array())
5787      {
5788          return $this->item->get_base($element);
5789      }
5790  
5791  	function sanitize($data, $type, $base = '')
5792      {
5793          return $this->item->sanitize($data, $type, $base);
5794      }
5795  
5796  	function get_item()
5797      {
5798          return $this->item;
5799      }
5800  
5801  	function get_title()
5802      {
5803          if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
5804          {
5805              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5806          }
5807          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
5808          {
5809              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
5810          }
5811          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
5812          {
5813              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5814          }
5815          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
5816          {
5817              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5818          }
5819          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
5820          {
5821              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
5822          }
5823          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
5824          {
5825              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5826          }
5827          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
5828          {
5829              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5830          }
5831          else
5832          {
5833              return null;
5834          }
5835      }
5836  
5837  	function get_category($key = 0)
5838      {
5839          $categories = $this->get_categories();
5840          if (isset($categories[$key]))
5841          {
5842              return $categories[$key];
5843          }
5844          else
5845          {
5846              return null;
5847          }
5848      }
5849  
5850  	function get_categories()
5851      {
5852          $categories = array();
5853  
5854          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
5855          {
5856              $term = null;
5857              $scheme = null;
5858              $label = null;
5859              if (isset($category['attribs']['']['term']))
5860              {
5861                  $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
5862              }
5863              if (isset($category['attribs']['']['scheme']))
5864              {
5865                  $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
5866              }
5867              if (isset($category['attribs']['']['label']))
5868              {
5869                  $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
5870              }
5871              $categories[] = new $this->item->feed->category_class($term, $scheme, $label);
5872          }
5873          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
5874          {
5875              // This is really the label, but keep this as the term also for BC.
5876              // Label will also work on retrieving because that falls back to term.
5877              $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5878              if (isset($category['attribs']['']['domain']))
5879              {
5880                  $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
5881              }
5882              else
5883              {
5884                  $scheme = null;
5885              }
5886              $categories[] = new $this->item->feed->category_class($term, $scheme, null);
5887          }
5888          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
5889          {
5890              $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5891          }
5892          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
5893          {
5894              $categories[] = new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5895          }
5896  
5897          if (!empty($categories))
5898          {
5899              return SimplePie_Misc::array_unique($categories);
5900          }
5901          else
5902          {
5903              return null;
5904          }
5905      }
5906  
5907  	function get_author($key = 0)
5908      {
5909          $authors = $this->get_authors();
5910          if (isset($authors[$key]))
5911          {
5912              return $authors[$key];
5913          }
5914          else
5915          {
5916              return null;
5917          }
5918      }
5919  
5920  	function get_authors()
5921      {
5922          $authors = array();
5923          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
5924          {
5925              $name = null;
5926              $uri = null;
5927              $email = null;
5928              if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
5929              {
5930                  $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5931              }
5932              if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
5933              {
5934                  $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]));
5935              }
5936              if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
5937              {
5938                  $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5939              }
5940              if ($name !== null || $email !== null || $uri !== null)
5941              {
5942                  $authors[] = new $this->item->feed->author_class($name, $uri, $email);
5943              }
5944          }
5945          if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
5946          {
5947              $name = null;
5948              $url = null;
5949              $email = null;
5950              if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
5951              {
5952                  $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5953              }
5954              if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
5955              {
5956                  $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]));
5957              }
5958              if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
5959              {
5960                  $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
5961              }
5962              if ($name !== null || $email !== null || $url !== null)
5963              {
5964                  $authors[] = new $this->item->feed->author_class($name, $url, $email);
5965              }
5966          }
5967          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
5968          {
5969              $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5970          }
5971          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
5972          {
5973              $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5974          }
5975          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
5976          {
5977              $authors[] = new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null);
5978          }
5979  
5980          if (!empty($authors))
5981          {
5982              return SimplePie_Misc::array_unique($authors);
5983          }
5984          else
5985          {
5986              return null;
5987          }
5988      }
5989  
5990  	function get_contributor($key = 0)
5991      {
5992          $contributors = $this->get_contributors();
5993          if (isset($contributors[$key]))
5994          {
5995              return $contributors[$key];
5996          }
5997          else
5998          {
5999              return null;
6000          }
6001      }
6002  
6003  	function get_contributors()
6004      {
6005          $contributors = array();
6006          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
6007          {
6008              $name = null;
6009              $uri = null;
6010              $email = null;
6011              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
6012              {
6013                  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6014              }
6015              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
6016              {
6017                  $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]));
6018              }
6019              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
6020              {
6021                  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6022              }
6023              if ($name !== null || $email !== null || $uri !== null)
6024              {
6025                  $contributors[] = new $this->item->feed->author_class($name, $uri, $email);
6026              }
6027          }
6028          foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
6029          {
6030              $name = null;
6031              $url = null;
6032              $email = null;
6033              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
6034              {
6035                  $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6036              }
6037              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
6038              {
6039                  $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]));
6040              }
6041              if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
6042              {
6043                  $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6044              }
6045              if ($name !== null || $email !== null || $url !== null)
6046              {
6047                  $contributors[] = new $this->item->feed->author_class($name, $url, $email);
6048              }
6049          }
6050  
6051          if (!empty($contributors))
6052          {
6053              return SimplePie_Misc::array_unique($contributors);
6054          }
6055          else
6056          {
6057              return null;
6058          }
6059      }
6060  
6061  	function get_link($key = 0, $rel = 'alternate')
6062      {
6063          $links = $this->get_links($rel);
6064          if (isset($links[$key]))
6065          {
6066              return $links[$key];
6067          }
6068          else
6069          {
6070              return null;
6071          }
6072      }
6073  
6074      /**
6075       * Added for parity between the parent-level and the item/entry-level.
6076       */
6077  	function get_permalink()
6078      {
6079          return $this->get_link(0);
6080      }
6081  
6082  	function get_links($rel = 'alternate')
6083      {
6084          if (!isset($this->data['links']))
6085          {
6086              $this->data['links'] = array();
6087              if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
6088              {
6089                  foreach ($links as $link)
6090                  {
6091                      if (isset($link['attribs']['']['href']))
6092                      {
6093                          $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6094                          $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6095                      }
6096                  }
6097              }
6098              if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
6099              {
6100                  foreach ($links as $link)
6101                  {
6102                      if (isset($link['attribs']['']['href']))
6103                      {
6104                          $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
6105                          $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
6106  
6107                      }
6108                  }
6109              }
6110              if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
6111              {
6112                  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6113              }
6114              if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
6115              {
6116                  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6117              }
6118              if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
6119              {
6120                  $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
6121              }
6122  
6123              $keys = array_keys($this->data['links']);
6124              foreach ($keys as $key)
6125              {
6126                  if (SimplePie_Misc::is_isegment_nz_nc($key))
6127                  {
6128                      if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
6129                      {
6130                          $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
6131                          $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
6132                      }
6133                      else
6134                      {
6135                          $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
6136                      }
6137                  }
6138                  elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
6139                  {
6140                      $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
6141                  }
6142                  $this->data['links'][$key] = array_unique($this->data['links'][$key]);
6143              }
6144          }
6145  
6146          if (isset($this->data['links'][$rel]))
6147          {
6148              return $this->data['links'][$rel];
6149          }
6150          else
6151          {
6152              return null;
6153          }
6154      }
6155  
6156  	function get_description()
6157      {
6158          if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
6159          {
6160              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6161          }
6162          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
6163          {
6164              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6165          }
6166          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
6167          {
6168              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6169          }
6170          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
6171          {
6172              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6173          }
6174          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
6175          {
6176              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
6177          }
6178          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
6179          {
6180              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6181          }
6182          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
6183          {
6184              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6185          }
6186          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
6187          {
6188              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6189          }
6190          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
6191          {
6192              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
6193          }
6194          else
6195          {
6196              return null;
6197          }
6198      }
6199  
6200  	function get_copyright()
6201      {
6202          if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
6203          {
6204              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6205          }
6206          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
6207          {
6208              return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0]));
6209          }
6210          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
6211          {
6212              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6213          }
6214          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
6215          {
6216              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6217          }
6218          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
6219          {
6220              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6221          }
6222          else
6223          {
6224              return null;
6225          }
6226      }
6227  
6228  	function get_language()
6229      {
6230          if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
6231          {
6232              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6233          }
6234          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
6235          {
6236              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6237          }
6238          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
6239          {
6240              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
6241          }
6242          elseif (isset($this->data['xml_lang']))
6243          {
6244              return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
6245          }
6246          else
6247          {
6248              return null;
6249          }
6250      }
6251  
6252  	function get_latitude()
6253      {
6254          if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
6255          {
6256              return (float) $return[0]['data'];
6257          }
6258          elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
6259          {
6260              return (float) $match[1];
6261          }
6262          else
6263          {
6264              return null;
6265          }
6266      }
6267  
6268  	function get_longitude()
6269      {
6270          if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
6271          {
6272              return (float) $return[0]['data'];
6273          }
6274          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
6275          {
6276              return (float) $return[0]['data'];
6277          }
6278          elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
6279          {
6280              return (float) $match[2];
6281          }
6282          else
6283          {
6284              return null;
6285          }
6286      }
6287  
6288  	function get_image_url()
6289      {
6290          if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
6291          {
6292              return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
6293          }
6294          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
6295          {
6296              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6297          }
6298          elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
6299          {
6300              return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
6301          }
6302          else
6303          {
6304              return null;
6305          }
6306      }
6307  }
6308  
6309  class SimplePie_Author
6310  {
6311      var $name;
6312      var $link;
6313      var $email;
6314  
6315      // Constructor, used to input the data
6316  	function SimplePie_Author($name = null, $link = null, $email = null)
6317      {
6318          $this->name = $name;
6319          $this->link = $link;
6320          $this->email = $email;
6321      }
6322  
6323  	function __toString()
6324      {
6325          // There is no $this->data here
6326          return md5(serialize($this));
6327      }
6328  
6329  	function get_name()
6330      {
6331          if ($this->name !== null)
6332          {
6333              return $this->name;
6334          }
6335          else
6336          {
6337              return null;
6338          }
6339      }
6340  
6341  	function get_link()
6342      {
6343          if ($this->link !== null)
6344          {
6345              return $this->link;
6346          }
6347          else
6348          {
6349              return null;
6350          }
6351      }
6352  
6353  	function get_email()
6354      {
6355          if ($this->email !== null)
6356          {
6357              return $this->email;
6358          }
6359          else
6360          {
6361              return null;
6362          }
6363      }
6364  }
6365  
6366  class SimplePie_Category
6367  {
6368      var $term;
6369      var $scheme;
6370      var $label;
6371  
6372      // Constructor, used to input the data
6373  	function SimplePie_Category($term = null, $scheme = null, $label = null)
6374      {
6375          $this->term = $term;
6376          $this->scheme = $scheme;
6377          $this->label = $label;
6378      }
6379  
6380  	function __toString()
6381      {
6382          // There is no $this->data here
6383          return md5(serialize($this));
6384      }
6385  
6386  	function get_term()
6387      {
6388          if ($this->term !== null)
6389          {
6390              return $this->term;
6391          }
6392          else
6393          {
6394              return null;
6395          }
6396      }
6397  
6398  	function get_scheme()
6399      {
6400          if ($this->scheme !== null)
6401          {
6402              return $this->scheme;
6403          }
6404          else
6405          {
6406              return null;
6407          }
6408      }
6409  
6410  	function get_label()
6411      {
6412          if ($this->label !== null)
6413          {
6414              return $this->label;
6415          }
6416          else
6417          {
6418              return $this->get_term();
6419          }
6420      }
6421  }
6422  
6423  class SimplePie_Enclosure
6424  {
6425      var $bitrate;
6426      var $captions;
6427      var $categories;
6428      var $channels;
6429      var $copyright;
6430      var $credits;
6431      var $description;
6432      var $duration;
6433      var $expression;
6434      var $framerate;
6435      var $handler;
6436      var $hashes;
6437      var $height;
6438      var $javascript;
6439      var $keywords;
6440      var $lang;
6441      var $length;
6442      var $link;
6443      var $medium;
6444      var $player;
6445      var $ratings;
6446      var $restrictions;
6447      var $samplingrate;
6448      var $thumbnails;
6449      var $title;
6450      var $type;
6451      var $width;
6452  
6453      // Constructor, used to input the data
6454  	function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
6455      {
6456          $this->bitrate = $bitrate;
6457          $this->captions = $captions;
6458          $this->categories = $categories;
6459          $this->channels = $channels;
6460          $this->copyright = $copyright;
6461          $this->credits = $credits;
6462          $this->description = $description;
6463          $this->duration = $duration;
6464          $this->expression = $expression;
6465          $this->framerate = $framerate;
6466          $this->hashes = $hashes;
6467          $this->height = $height;
6468          $this->javascript = $javascript;
6469          $this->keywords = $keywords;
6470          $this->lang = $lang;
6471          $this->length = $length;
6472          $this->link = $link;
6473          $this->medium = $medium;
6474          $this->player = $player;
6475          $this->ratings = $ratings;
6476          $this->restrictions = $restrictions;
6477          $this->samplingrate = $samplingrate;
6478          $this->thumbnails = $thumbnails;
6479          $this->title = $title;
6480          $this->type = $type;
6481          $this->width = $width;
6482          if (class_exists('idna_convert'))
6483          {
6484              $idn = new idna_convert();
6485              $parsed = SimplePie_Misc::parse_url($link);
6486              $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
6487          }
6488          $this->handler = $this->get_handler(); // Needs to load last
6489      }
6490  
6491  	function __toString()
6492      {
6493          // There is no $this->data here
6494          return md5(serialize($this));
6495      }
6496  
6497  	function get_bitrate()
6498      {
6499          if ($this->bitrate !== null)
6500          {
6501              return $this->bitrate;
6502          }
6503          else
6504          {
6505              return null;
6506          }
6507      }
6508  
6509  	function get_caption($key = 0)
6510      {
6511          $captions = $this->get_captions();
6512          if (isset($captions[$key]))
6513          {
6514              return $captions[$key];
6515          }
6516          else
6517          {
6518              return null;
6519          }
6520      }
6521  
6522  	function get_captions()
6523      {
6524          if ($this->captions !== null)
6525          {
6526              return $this->captions;
6527          }
6528          else
6529          {
6530              return null;
6531          }
6532      }
6533  
6534  	function get_category($key = 0)
6535      {
6536          $categories = $this->get_categories();
6537          if (isset($categories[$key]))
6538          {
6539              return $categories[$key];
6540          }
6541          else
6542          {
6543              return null;
6544          }
6545      }
6546  
6547  	function get_categories()
6548      {
6549          if ($this->categories !== null)
6550          {
6551              return $this->categories;
6552          }
6553          else
6554          {
6555              return null;
6556          }
6557      }
6558  
6559  	function get_channels()
6560      {
6561          if ($this->channels !== null)
6562          {
6563              return $this->channels;
6564          }
6565          else
6566          {
6567              return null;
6568          }
6569      }
6570  
6571  	function get_copyright()
6572      {
6573          if ($this->copyright !== null)
6574          {
6575              return $this->copyright;
6576          }
6577          else
6578          {
6579              return null;
6580          }
6581      }
6582  
6583  	function get_credit($key = 0)
6584      {
6585          $credits = $this->get_credits();
6586          if (isset($credits[$key]))
6587          {
6588              return $credits[$key];
6589          }
6590          else
6591          {
6592              return null;
6593          }
6594      }
6595  
6596  	function get_credits()
6597      {
6598          if ($this->credits !== null)
6599          {
6600              return $this->credits;
6601          }
6602          else
6603          {
6604              return null;
6605          }
6606      }
6607  
6608  	function get_description()
6609      {
6610          if ($this->description !== null)
6611          {
6612              return $this->description;
6613          }
6614          else
6615          {
6616              return null;
6617          }
6618      }
6619  
6620  	function get_duration($convert = false)
6621      {
6622          if ($this->duration !== null)
6623          {
6624              if ($convert)
6625              {
6626                  $time = SimplePie_Misc::time_hms($this->duration);
6627                  return $time;
6628              }
6629              else
6630              {
6631                  return $this->duration;
6632              }
6633          }
6634          else
6635          {
6636              return null;
6637          }
6638      }
6639  
6640  	function get_expression()
6641      {
6642          if ($this->expression !== null)
6643          {
6644              return $this->expression;
6645          }
6646          else
6647          {
6648              return 'full';
6649          }
6650      }
6651  
6652  	function get_extension()
6653      {
6654          if ($this->link !== null)
6655          {
6656              $url = SimplePie_Misc::parse_url($this->link);
6657              if ($url['path'] !== '')
6658              {
6659                  return pathinfo($url['path'], PATHINFO_EXTENSION);
6660              }
6661          }
6662          return null;
6663      }
6664  
6665  	function get_framerate()
6666      {
6667          if ($this->framerate !== null)
6668          {
6669              return $this->framerate;
6670          }
6671          else
6672          {
6673              return null;
6674          }
6675      }
6676  
6677  	function get_handler()
6678      {
6679          return $this->get_real_type(true);
6680      }
6681  
6682  	function get_hash($key = 0)
6683      {
6684          $hashes = $this->get_hashes();
6685          if (isset($hashes[$key]))
6686          {
6687              return $hashes[$key];
6688          }
6689          else
6690          {
6691              return null;
6692          }
6693      }
6694  
6695  	function get_hashes()
6696      {
6697          if ($this->hashes !== null)
6698          {
6699              return $this->hashes;
6700          }
6701          else
6702          {
6703              return null;
6704          }
6705      }
6706  
6707  	function get_height()
6708      {
6709          if ($this->height !== null)
6710          {
6711              return $this->height;
6712          }
6713          else
6714          {
6715              return null;
6716          }
6717      }
6718  
6719  	function get_language()
6720      {
6721          if ($this->lang !== null)
6722          {
6723              return $this->lang;
6724          }
6725          else
6726          {
6727              return null;
6728          }
6729      }
6730  
6731  	function get_keyword($key = 0)
6732      {
6733          $keywords = $this->get_keywords();
6734          if (isset($keywords[$key]))
6735          {
6736              return $keywords[$key];
6737          }
6738          else
6739          {
6740              return null;
6741          }
6742      }
6743  
6744  	function get_keywords()
6745      {
6746          if ($this->keywords !== null)
6747          {
6748              return $this->keywords;
6749          }
6750          else
6751          {
6752              return null;
6753          }
6754      }
6755  
6756  	function get_length()
6757      {
6758          if ($this->length !== null)
6759          {
6760              return $this->length;
6761          }
6762          else
6763          {
6764              return null;
6765          }
6766      }
6767  
6768  	function get_link()
6769      {
6770          if ($this->link !== null)
6771          {
6772              return urldecode($this->link);
6773          }
6774          else
6775          {
6776              return null;
6777          }
6778      }
6779  
6780  	function get_medium()
6781      {
6782          if ($this->medium !== null)
6783          {
6784              return $this->medium;
6785          }
6786          else
6787          {
6788              return null;
6789          }
6790      }
6791  
6792  	function get_player()
6793      {
6794          if ($this->player !== null)
6795          {
6796              return $this->player;
6797          }
6798          else
6799          {
6800              return null;
6801          }
6802      }
6803  
6804  	function get_rating($key = 0)
6805      {
6806          $ratings = $this->get_ratings();
6807          if (isset($ratings[$key]))
6808          {
6809              return $ratings[$key];
6810          }
6811          else
6812          {
6813              return null;
6814          }
6815      }
6816  
6817  	function get_ratings()
6818      {
6819          if ($this->ratings !== null)
6820          {
6821              return $this->ratings;
6822          }
6823          else
6824          {
6825              return null;
6826          }
6827      }
6828  
6829  	function get_restriction($key = 0)
6830      {
6831          $restrictions = $this->get_restrictions();
6832          if (isset($restrictions[$key]))
6833          {
6834              return $restrictions[$key];
6835          }
6836          else
6837          {
6838              return null;
6839          }
6840      }
6841  
6842  	function get_restrictions()
6843      {
6844          if ($this->restrictions !== null)
6845          {
6846              return $this->restrictions;
6847          }
6848          else
6849          {
6850              return null;
6851          }
6852      }
6853  
6854  	function get_sampling_rate()
6855      {
6856          if ($this->samplingrate !== null)
6857          {
6858              return $this->samplingrate;
6859          }
6860          else
6861          {
6862              return null;
6863          }
6864      }
6865  
6866  	function get_size()
6867      {
6868          $length = $this->get_length();
6869          if ($length !== null)
6870          {
6871              return round($length/1048576, 2);
6872          }
6873          else
6874          {
6875              return null;
6876          }
6877      }
6878  
6879  	function get_thumbnail($key = 0)
6880      {
6881          $thumbnails = $this->get_thumbnails();
6882          if (isset($thumbnails[$key]))
6883          {
6884              return $thumbnails[$key];
6885          }
6886          else
6887          {
6888              return null;
6889          }
6890      }
6891  
6892  	function get_thumbnails()
6893      {
6894          if ($this->thumbnails !== null)
6895          {
6896              return $this->thumbnails;
6897          }
6898          else
6899          {
6900              return null;
6901          }
6902      }
6903  
6904  	function get_title()
6905      {
6906          if ($this->title !== null)
6907          {
6908              return $this->title;
6909          }
6910          else
6911          {
6912              return null;
6913          }
6914      }
6915  
6916  	function get_type()
6917      {
6918          if ($this->type !== null)
6919          {
6920              return $this->type;
6921          }
6922          else
6923          {
6924              return null;
6925          }
6926      }
6927  
6928  	function get_width()
6929      {
6930          if ($this->width !== null)
6931          {
6932              return $this->width;
6933          }
6934          else
6935          {
6936              return null;
6937          }
6938      }
6939  
6940  	function native_embed($options='')
6941      {
6942          return $this->embed($options, true);
6943      }
6944  
6945      /**
6946       * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
6947       */
6948  	function embed($options = '', $native = false)
6949      {
6950          // Set up defaults
6951          $audio = '';
6952          $video = '';
6953          $alt = '';
6954          $altclass = '';
6955          $loop = 'false';
6956          $width = 'auto';
6957          $height = 'auto';
6958          $bgcolor = '#ffffff';
6959          $mediaplayer = '';
6960          $widescreen = false;
6961          $handler = $this->get_handler();
6962          $type = $this->get_real_type();
6963  
6964          // Process options and reassign values as necessary
6965          if (is_array($options))
6966          {
6967              extract($options);
6968          }
6969          else
6970          {
6971              $options = explode(',', $options);
6972              foreach($options as $option)
6973              {
6974                  $opt = explode(':', $option, 2);
6975                  if (isset($opt[0], $opt[1]))
6976                  {
6977                      $opt[0] = trim($opt[0]);
6978                      $opt[1] = trim($opt[1]);
6979                      switch ($opt[0])
6980                      {
6981                          case 'audio':
6982                              $audio = $opt[1];
6983                              break;
6984  
6985                          case 'video':
6986                              $video = $opt[1];
6987                              break;
6988  
6989                          case 'alt':
6990                              $alt = $opt[1];
6991                              break;
6992  
6993                          case 'altclass':
6994                              $altclass = $opt[1];
6995                              break;
6996  
6997                          case 'loop':
6998                              $loop = $opt[1];
6999                              break;
7000  
7001                          case 'width':
7002                              $width = $opt[1];
7003                              break;
7004  
7005                          case 'height':
7006                              $height = $opt[1];
7007                              break;
7008  
7009                          case 'bgcolor':
7010                              $bgcolor = $opt[1];
7011                              break;
7012  
7013                          case 'mediaplayer':
7014                              $mediaplayer = $opt[1];
7015                              break;
7016  
7017                          case 'widescreen':
7018                              $widescreen = $opt[1];
7019                              break;
7020                      }
7021                  }
7022              }
7023          }
7024  
7025          $mime = explode('/', $type, 2);
7026          $mime = $mime[0];
7027  
7028          // Process values for 'auto'
7029          if ($width === 'auto')
7030          {
7031              if ($mime === 'video')
7032              {
7033                  if ($height === 'auto')
7034                  {
7035                      $width = 480;
7036                  }
7037                  elseif ($widescreen)
7038                  {
7039                      $width = round((intval($height)/9)*16);
7040                  }
7041                  else
7042                  {
7043                      $width = round((intval($height)/3)*4);
7044                  }
7045              }
7046              else
7047              {
7048                  $width = '100%';
7049              }
7050          }
7051  
7052          if ($height === 'auto')
7053          {
7054              if ($mime === 'audio')
7055              {
7056                  $height = 0;
7057              }
7058              elseif ($mime === 'video')
7059              {
7060                  if ($width === 'auto')
7061                  {
7062                      if ($widescreen)
7063                      {
7064                          $height = 270;
7065                      }
7066                      else
7067                      {
7068                          $height = 360;
7069                      }
7070                  }
7071                  elseif ($widescreen)
7072                  {
7073                      $height = round((intval($width)/16)*9);
7074                  }
7075                  else
7076                  {
7077                      $height = round((intval($width)/4)*3);
7078                  }
7079              }
7080              else
7081              {
7082                  $height = 376;
7083              }
7084          }
7085          elseif ($mime === 'audio')
7086          {
7087              $height = 0;
7088          }
7089  
7090          // Set proper placeholder value
7091          if ($mime === 'audio')
7092          {
7093              $placeholder = $audio;
7094          }
7095          elseif ($mime === 'video')
7096          {
7097              $placeholder = $video;
7098          }
7099  
7100          $embed = '';
7101  
7102          // Make sure the JS library is included
7103          if (!$native)
7104          {
7105              static $javascript_outputted = null;
7106              if (!$javascript_outputted && $this->javascript)
7107              {
7108                  $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>';
7109                  $javascript_outputted = true;
7110              }
7111          }
7112  
7113          // Odeo Feed MP3's
7114          if ($handler === 'odeo')
7115          {
7116              if ($native)
7117              {
7118                  $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url=' . $this->get_link() . '"></embed>';
7119              }
7120              else
7121              {
7122                  $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>';
7123              }
7124          }
7125  
7126          // Flash
7127          elseif ($handler === 'flash')
7128          {
7129              if ($native)
7130              {
7131                  $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
7132              }
7133              else
7134              {
7135                  $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
7136              }
7137          }
7138  
7139          // Flash Media Player file types.
7140          // Preferred handler for MP3 file types.
7141          elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
7142          {
7143              $height += 20;
7144              if ($native)
7145              {
7146                  $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
7147              }
7148              else
7149              {
7150                  $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
7151              }
7152          }
7153  
7154          // QuickTime 7 file types.  Need to test with QuickTime 6.
7155          // Only handle MP3's if the Flash Media Player is not present.
7156          elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
7157          {
7158              $height += 16;
7159              if ($native)
7160              {
7161                  if ($placeholder !== '')
7162                  {
7163                      $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
7164                  }
7165                  else
7166                  {
7167                      $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
7168                  }
7169              }
7170              else
7171              {
7172                  $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
7173              }
7174          }
7175  
7176          // Windows Media
7177          elseif ($handler === 'wmedia')
7178          {
7179              $height += 45;
7180              if ($native)
7181              {
7182                  $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
7183              }
7184              else
7185              {
7186                  $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
7187              }
7188          }
7189  
7190          // Everything else
7191          else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
7192  
7193          return $embed;
7194      }
7195  
7196  	function get_real_type($find_handler = false)
7197      {
7198          // If it's Odeo, let's get it out of the way.
7199          if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com')
7200          {
7201              return 'odeo';
7202          }
7203  
7204          // Mime-types by handler.
7205          $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
7206          $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
7207          $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
7208          $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
7209          $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
7210  
7211          if ($this->get_type() !== null)
7212          {
7213              $type = strtolower($this->type);
7214          }
7215          else
7216          {
7217              $type = null;
7218          }
7219  
7220          // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
7221          if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
7222          {
7223              switch (strtolower($this->get_extension()))
7224              {
7225                  // Audio mime-types
7226                  case 'aac':
7227                  case 'adts':
7228                      $type = 'audio/acc';
7229                      break;
7230  
7231                  case 'aif':
7232                  case 'aifc':
7233                  case 'aiff':
7234                  case 'cdda':
7235                      $type = 'audio/aiff';
7236                      break;
7237  
7238                  case 'bwf':
7239                      $type = 'audio/wav';
7240                      break;
7241  
7242                  case 'kar':
7243                  case 'mid':
7244                  case 'midi':
7245                  case 'smf':
7246                      $type = 'audio/midi';
7247                      break;
7248  
7249                  case 'm4a':
7250                      $type = 'audio/x-m4a';
7251                      break;
7252  
7253                  case 'mp3':
7254                  case 'swa':
7255                      $type = 'audio/mp3';
7256                      break;
7257  
7258                  case 'wav':
7259                      $type = 'audio/wav';
7260                      break;
7261  
7262                  case 'wax':
7263                      $type = 'audio/x-ms-wax';
7264                      break;
7265  
7266                  case 'wma':
7267                      $type = 'audio/x-ms-wma';
7268                      break;
7269  
7270                  // Video mime-types
7271                  case '3gp':
7272                  case '3gpp':
7273                      $type = 'video/3gpp';
7274                      break;
7275  
7276                  case '3g2':
7277                  case '3gp2':
7278                      $type = 'video/3gpp2';
7279                      break;
7280  
7281                  case 'asf':
7282                      $type = 'video/x-ms-asf';
7283                      break;
7284  
7285                  case 'flv':
7286                      $type = 'video/x-flv';
7287                      break;
7288  
7289                  case 'm1a':
7290                  case 'm1s':
7291                  case 'm1v':
7292                  case 'm15':
7293                  case 'm75':
7294                  case 'mp2':
7295                  case 'mpa':
7296                  case 'mpeg':
7297                  case 'mpg':
7298                  case 'mpm':
7299                  case 'mpv':
7300                      $type = 'video/mpeg';
7301                      break;
7302  
7303                  case 'm4v':
7304                      $type = 'video/x-m4v';
7305                      break;
7306  
7307                  case 'mov':
7308                  case 'qt':
7309                      $type = 'video/quicktime';
7310                      break;
7311  
7312                  case 'mp4':
7313                  case 'mpg4':
7314                      $type = 'video/mp4';
7315                      break;
7316  
7317                  case 'sdv':
7318                      $type = 'video/sd-video';
7319                      break;
7320  
7321                  case 'wm':
7322                      $type = 'video/x-ms-wm';
7323                      break;
7324  
7325                  case 'wmv':
7326                      $type = 'video/x-ms-wmv';
7327                      break;
7328  
7329                  case 'wvx':
7330                      $type = 'video/x-ms-wvx';
7331                      break;
7332  
7333                  // Flash mime-types
7334                  case 'spl':
7335                      $type = 'application/futuresplash';
7336                      break;
7337  
7338                  case 'swf':
7339                      $type = 'application/x-shockwave-flash';
7340                      break;
7341              }
7342          }
7343  
7344          if ($find_handler)
7345          {
7346              if (in_array($type, $types_flash))
7347              {
7348                  return 'flash';
7349              }
7350              elseif (in_array($type, $types_fmedia))
7351              {
7352                  return 'fmedia';
7353              }
7354              elseif (in_array($type, $types_quicktime))
7355              {
7356                  return 'quicktime';
7357              }
7358              elseif (in_array($type, $types_wmedia))
7359              {
7360                  return 'wmedia';
7361              }
7362              elseif (in_array($type, $types_mp3))
7363              {
7364                  return 'mp3';
7365              }
7366              else
7367              {
7368                  return null;
7369              }
7370          }
7371          else
7372          {
7373              return $type;
7374          }
7375      }
7376  }
7377  
7378  class SimplePie_Caption
7379  {
7380      var $type;
7381      var $lang;
7382      var $startTime;
7383      var $endTime;
7384      var $text;
7385  
7386      // Constructor, used to input the data
7387  	function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
7388      {
7389          $this->type = $type;
7390          $this->lang = $lang;
7391          $this->startTime = $startTime;
7392          $this->endTime = $endTime;
7393          $this->text = $text;
7394      }
7395  
7396  	function __toString()
7397      {
7398          // There is no $this->data here
7399          return md5(serialize($this));
7400      }
7401  
7402  	function get_endtime()
7403      {
7404          if ($this->endTime !== null)
7405          {
7406              return $this->endTime;
7407          }
7408          else
7409          {
7410              return null;
7411          }
7412      }
7413  
7414  	function get_language()
7415      {
7416          if ($this->lang !== null)
7417          {
7418              return $this->lang;
7419          }
7420          else
7421          {
7422              return null;
7423          }
7424      }
7425  
7426  	function get_starttime()
7427      {
7428          if ($this->startTime !== null)
7429          {
7430              return $this->startTime;
7431          }
7432          else
7433          {
7434              return null;
7435          }
7436      }
7437  
7438  	function get_text()
7439      {
7440          if ($this->text !== null)
7441          {
7442              return $this->text;
7443          }
7444          else
7445          {
7446              return null;
7447          }
7448      }
7449  
7450  	function get_type()
7451      {
7452          if ($this->type !== null)
7453          {
7454              return $this->type;
7455          }
7456          else
7457          {
7458              return null;
7459          }
7460      }
7461  }
7462  
7463  class SimplePie_Credit
7464  {
7465      var $role;
7466      var $scheme;
7467      var $name;
7468  
7469      // Constructor, used to input the data
7470  	function SimplePie_Credit($role = null, $scheme = null, $name = null)
7471      {
7472          $this->role = $role;
7473          $this->scheme = $scheme;
7474          $this->name = $name;
7475      }
7476  
7477  	function __toString()
7478      {
7479          // There is no $this->data here
7480          return md5(serialize($this));
7481      }
7482  
7483  	function get_role()
7484      {
7485          if ($this->role !== null)
7486          {
7487              return $this->role;
7488          }
7489          else
7490          {
7491              return null;
7492          }
7493      }
7494  
7495  	function get_scheme()
7496      {
7497          if ($this->scheme !== null)
7498          {
7499              return $this->scheme;
7500          }
7501          else
7502          {
7503              return null;
7504          }
7505      }
7506  
7507  	function get_name()
7508      {
7509          if ($this->name !== null)
7510          {
7511              return $this->name;
7512          }
7513          else
7514          {
7515              return null;
7516          }
7517      }
7518  }
7519  
7520  class SimplePie_Copyright
7521  {
7522      var $url;
7523      var $label;
7524  
7525      // Constructor, used to input the data
7526  	function SimplePie_Copyright($url = null, $label = null)
7527      {
7528          $this->url = $url;
7529          $this->label = $label;
7530      }
7531  
7532  	function __toString()
7533      {
7534          // There is no $this->data here
7535          return md5(serialize($this));
7536      }
7537  
7538  	function get_url()
7539      {
7540          if ($this->url !== null)
7541          {
7542              return $this->url;
7543          }
7544          else
7545          {
7546              return null;
7547          }
7548      }
7549  
7550  	function get_attribution()
7551      {
7552          if ($this->label !== null)
7553          {
7554              return $this->label;
7555          }
7556          else
7557          {
7558              return null;
7559          }
7560      }
7561  }
7562  
7563  class SimplePie_Rating
7564  {
7565      var $scheme;
7566      var $value;
7567  
7568      // Constructor, used to input the data
7569  	function SimplePie_Rating($scheme = null, $value = null)
7570      {
7571          $this->scheme = $scheme;
7572          $this->value = $value;
7573      }
7574  
7575  	function __toString()
7576      {
7577          // There is no $this->data here
7578          return md5(serialize($this));
7579      }
7580  
7581  	function get_scheme()
7582      {
7583          if ($this->scheme !== null)
7584          {
7585              return $this->scheme;
7586          }
7587          else
7588          {
7589              return null;
7590          }
7591      }
7592  
7593  	function get_value()
7594      {
7595          if ($this->value !== null)
7596          {
7597              return $this->value;
7598          }
7599          else
7600          {
7601              return null;
7602          }
7603      }
7604  }
7605  
7606  class SimplePie_Restriction
7607  {
7608      var $relationship;
7609      var $type;
7610      var $value;
7611  
7612      // Constructor, used to input the data
7613  	function SimplePie_Restriction($relationship = null, $type = null, $value = null)
7614      {
7615          $this->relationship = $relationship;
7616          $this->type = $type;
7617          $this->value = $value;
7618      }
7619  
7620  	function __toString()
7621      {
7622          // There is no $this->data here
7623          return md5(serialize($this));
7624      }
7625  
7626  	function get_relationship()
7627      {
7628          if ($this->relationship !== null)
7629          {
7630              return $this->relationship;
7631          }
7632          else
7633          {
7634              return null;
7635          }
7636      }
7637  
7638  	function get_type()
7639      {
7640          if ($this->type !== null)
7641          {
7642              return $this->type;
7643          }
7644          else
7645          {
7646              return null;
7647          }
7648      }
7649  
7650  	function get_value()
7651      {
7652          if ($this->value !== null)
7653          {
7654              return $this->value;
7655          }
7656          else
7657          {
7658              return null;
7659          }
7660      }
7661  }
7662  
7663  /**
7664   * @todo Move to properly supporting RFC2616 (HTTP/1.1)
7665   */
7666  class SimplePie_File
7667  {
7668      var $url;
7669      var $useragent;
7670      var $success = true;
7671      var $headers = array();
7672      var $body;
7673      var $status_code;
7674      var $redirects = 0;
7675      var $error;
7676      var $method = SIMPLEPIE_FILE_SOURCE_NONE;
7677  
7678  	function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
7679      {
7680          if (class_exists('idna_convert'))
7681          {
7682              $idn = new idna_convert();
7683              $parsed = SimplePie_Misc::parse_url($url);
7684              $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
7685          }
7686          $this->url = $url;
7687          $this->useragent = $useragent;
7688          if (preg_match('/^http(s)?:\/\//i', $url))
7689          {
7690              if ($useragent === null)
7691              {
7692                  $useragent = ini_get('user_agent');
7693                  $this->useragent = $useragent;
7694              }
7695              if (!is_array($headers))
7696              {
7697                  $headers = array();
7698              }
7699              if (!$force_fsockopen && function_exists('curl_exec'))
7700              {
7701                  $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
7702                  $fp = curl_init();
7703                  $headers2 = array();
7704                  foreach ($headers as $key => $value)
7705                  {
7706                      $headers2[] = "$key: $value";
7707                  }
7708                  if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
7709                  {
7710                      curl_setopt($fp, CURLOPT_ENCODING, '');
7711                  }
7712                  curl_setopt($fp, CURLOPT_URL, $url);
7713                  curl_setopt($fp, CURLOPT_HEADER, 1);
7714                  curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
7715                  curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
7716                  curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
7717                  curl_setopt($fp, CURLOPT_REFERER, $url);
7718                  curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
7719                  curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
7720                  if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
7721                  {
7722                      curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
7723                      curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
7724                  }
7725  
7726                  $this->headers = curl_exec($fp);
7727                  if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
7728                  {
7729                      curl_setopt($fp, CURLOPT_ENCODING, 'none');
7730                      $this->headers = curl_exec($fp);
7731                  }
7732                  if (curl_errno($fp))
7733                  {
7734                      $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
7735                      $this->success = false;
7736                  }
7737                  else
7738                  {
7739                      $info = curl_getinfo($fp);
7740                      curl_close($fp);
7741                      $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1);
7742                      $this->headers = array_pop($this->headers);
7743                      $parser = new SimplePie_HTTP_Parser($this->headers);
7744                      if ($parser->parse())
7745                      {
7746                          $this->headers = $parser->headers;
7747                          $this->body = $parser->body;
7748                          $this->status_code = $parser->status_code;
7749                          if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7750                          {
7751                              $this->redirects++;
7752                              $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7753                              return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7754                          }
7755                      }
7756                  }
7757              }
7758              else
7759              {
7760                  $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
7761                  $url_parts = parse_url($url);
7762                  if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
7763                  {
7764                      $url_parts['host'] = 'ssl://'.$url_parts['host'];
7765                      $url_parts['port'] = 443;
7766                  }
7767                  if (!isset($url_parts['port']))
7768                  {
7769                      $url_parts['port'] = 80;
7770                  }
7771                  $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout);
7772                  if (!$fp)
7773                  {
7774                      $this->error = 'fsockopen error: ' . $errstr;
7775                      $this->success = false;
7776                  }
7777                  else
7778                  {
7779                      stream_set_timeout($fp, $timeout);
7780                      if (isset($url_parts['path']))
7781                      {
7782                          if (isset($url_parts['query']))
7783                          {
7784                              $get = $url_parts['path'].'?'.$url_parts['query'];
7785                          }
7786                          else
7787                          {
7788                              $get = $url_parts['path'];
7789                          }
7790                      }
7791                      else
7792                      {
7793                          $get = '/';
7794                      }
7795                      $out = "GET $get HTTP/1.0\r\n";
7796                      $out .= "Host: $url_parts[host]\r\n";
7797                      $out .= "User-Agent: $useragent\r\n";
7798                      if (extension_loaded('zlib'))
7799                      {
7800                          $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
7801                      }
7802  
7803                      if (isset($url_parts['user']) && isset($url_parts['pass']))
7804                      {
7805                          $out .= "Authorization: Basic " . base64_encode($url_parts['user'].':'.$url_parts['pass']) . "\r\n";
7806                      }
7807                      foreach ($headers as $key => $value)
7808                      {
7809                          $out .= "$key: $value\r\n";
7810                      }
7811                      $out .= "Connection: Close\r\n\r\n";
7812                      fwrite($fp, $out);
7813  
7814                      $info = stream_get_meta_data($fp);
7815  
7816                      $this->headers = '';
7817                      while (!$info['eof'] && !$info['timed_out'])
7818                      {
7819                          $this->headers .= fread($fp, 1160);
7820                          $info = stream_get_meta_data($fp);
7821                      }
7822                      if (!$info['timed_out'])
7823                      {
7824                          $parser = new SimplePie_HTTP_Parser($this->headers);
7825                          if ($parser->parse())
7826                          {
7827                              $this->headers = $parser->headers;
7828                              $this->body = $parser->body;
7829                              $this->status_code = $parser->status_code;
7830                              if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
7831                              {
7832                                  $this->redirects++;
7833                                  $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
7834                                  return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
7835                              }
7836                              if (isset($this->headers['content-encoding']))
7837                              {
7838                                  // Hey, we act dumb elsewhere, so let's do that here too
7839                                  switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
7840                                  {
7841                                      case 'gzip':
7842                                      case 'x-gzip':
7843                                          $decoder = new SimplePie_gzdecode($this->body);
7844                                          if (!$decoder->parse())
7845                                          {
7846                                              $this->error = 'Unable to decode HTTP "gzip" stream';
7847                                              $this->success = false;
7848                                          }
7849                                          else
7850                                          {
7851                                              $this->body = $decoder->data;
7852                                          }
7853                                          break;
7854  
7855                                      case 'deflate':
7856                                          if (($body = gzuncompress($this->body)) === false)
7857                                          {
7858                                              if (($body = gzinflate($this->body)) === false)
7859                                              {
7860                                                  $this->error = 'Unable to decode HTTP "deflate" stream';
7861                                                  $this->success = false;
7862                                              }
7863                                          }
7864                                          $this->body = $body;
7865                                          break;
7866  
7867                                      default:
7868                                          $this->error = 'Unknown content coding';
7869                                          $this->success = false;
7870                                  }
7871                              }
7872                          }
7873                      }
7874                      else
7875                      {
7876                          $this->error = 'fsocket timed out';
7877                          $this->success = false;
7878                      }
7879                      fclose($fp);
7880                  }
7881              }
7882          }
7883          else
7884          {
7885              $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
7886              if (!$this->body = file_get_contents($url))
7887              {
7888                  $this->error = 'file_get_contents could not read the file';
7889                  $this->success = false;
7890              }
7891          }
7892      }
7893  }
7894  
7895  /**
7896   * HTTP Response Parser
7897   *
7898   * @package SimplePie
7899   */
7900  class SimplePie_HTTP_Parser
7901  {
7902      /**
7903       * HTTP Version
7904       *
7905       * @access public
7906       * @var float
7907       */
7908      var $http_version = 0.0;
7909  
7910      /**
7911       * Status code
7912       *
7913       * @access public
7914       * @var int
7915       */
7916      var $status_code = 0;
7917  
7918      /**
7919       * Reason phrase
7920       *
7921       * @access public
7922       * @var string
7923       */
7924      var $reason = '';
7925  
7926      /**
7927       * Key/value pairs of the headers
7928       *
7929       * @access public
7930       * @var array
7931       */
7932      var $headers = array();
7933  
7934      /**
7935       * Body of the response
7936       *
7937       * @access public
7938       * @var string
7939       */
7940      var $body = '';
7941  
7942      /**
7943       * Current state of the state machine
7944       *
7945       * @access private
7946       * @var string
7947       */
7948      var $state = 'http_version';
7949  
7950      /**
7951       * Input data
7952       *
7953       * @access private
7954       * @var string
7955       */
7956      var $data = '';
7957  
7958      /**
7959       * Input data length (to avoid calling strlen() everytime this is needed)
7960       *
7961       * @access private
7962       * @var int
7963       */
7964      var $data_length = 0;
7965  
7966      /**
7967       * Current position of the pointer
7968       *
7969       * @var int
7970       * @access private
7971       */
7972      var $position = 0;
7973  
7974      /**
7975       * Name of the hedaer currently being parsed
7976       *
7977       * @access private
7978       * @var string
7979       */
7980      var $name = '';
7981  
7982      /**
7983       * Value of the hedaer currently being parsed
7984       *
7985       * @access private
7986       * @var string
7987       */
7988      var $value = '';
7989  
7990      /**
7991       * Create an instance of the class with the input data
7992       *
7993       * @access public
7994       * @param string $data Input data
7995       */
7996  	function SimplePie_HTTP_Parser($data)
7997      {
7998          $this->data = $data;
7999          $this->data_length = strlen($this->data);
8000      }
8001  
8002      /**
8003       * Parse the input data
8004       *
8005       * @access public
8006       * @return bool true on success, false on failure
8007       */
8008  	function parse()
8009      {
8010          while ($this->state && $this->state !== 'emit' && $this->has_data())
8011          {
8012              $state = $this->state;
8013              $this->$state();
8014          }
8015          $this->data = '';
8016          if ($this->state === 'emit' || $this->state === 'body')
8017          {
8018              return true;
8019          }
8020          else
8021          {
8022              $this->http_version = '';
8023              $this->status_code = '';
8024              $this->reason = '';
8025              $this->headers = array();
8026              $this->body = '';
8027              return false;
8028          }
8029      }
8030  
8031      /**
8032       * Check whether there is data beyond the pointer
8033       *
8034       * @access private
8035       * @return bool true if there is further data, false if not
8036       */
8037  	function has_data()
8038      {
8039          return (bool) ($this->position < $this->data_length);
8040      }
8041  
8042      /**
8043       * See if the next character is LWS
8044       *
8045       * @access private
8046       * @return bool true if the next character is LWS, false if not
8047       */
8048  	function is_linear_whitespace()
8049      {
8050          return (bool) ($this->data[$this->position] === "\x09"
8051              || $this->data[$this->position] === "\x20"
8052              || ($this->data[$this->position] === "\x0A"
8053                  && isset($this->data[$this->position + 1])
8054                  && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
8055      }
8056  
8057      /**
8058       * Parse the HTTP version
8059       *
8060       * @access private
8061       */
8062  	function http_version()
8063      {
8064          if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
8065          {
8066              $len = strspn($this->data, '0123456789.', 5);
8067              $this->http_version = substr($this->data, 5, $len);
8068              $this->position += 5 + $len;
8069              if (substr_count($this->http_version, '.') <= 1)
8070              {
8071                  $this->http_version = (float) $this->http_version;
8072                  $this->position += strspn($this->data, "\x09\x20", $this->position);
8073                  $this->state = 'status';
8074              }
8075              else
8076              {
8077                  $this->state = false;
8078              }
8079          }
8080          else
8081          {
8082              $this->state = false;
8083          }
8084      }
8085  
8086      /**
8087       * Parse the status code
8088       *
8089       * @access private
8090       */
8091  	function status()
8092      {
8093          if ($len = strspn($this->data, '0123456789', $this->position))
8094          {
8095              $this->status_code = (int) substr($this->data, $this->position, $len);
8096              $this->position += $len;
8097              $this->state = 'reason';
8098          }
8099          else
8100          {
8101              $this->state = false;
8102          }
8103      }
8104  
8105      /**
8106       * Parse the reason phrase
8107       *
8108       * @access private
8109       */
8110  	function reason()
8111      {
8112          $len = strcspn($this->data, "\x0A", $this->position);
8113          $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
8114          $this->position += $len + 1;
8115          $this->state = 'new_line';
8116      }
8117  
8118      /**
8119       * Deal with a new line, shifting data around as needed
8120       *
8121       * @access private
8122       */
8123  	function new_line()
8124      {
8125          $this->value = trim($this->value, "\x0D\x20");
8126          if ($this->name !== '' && $this->value !== '')
8127          {
8128              $this->name = strtolower($this->name);
8129              if (isset($this->headers[$this->name]))
8130              {
8131                  $this->headers[$this->name] .= ', ' . $this->value;
8132              }
8133              else
8134              {
8135                  $this->headers[$this->name] = $this->value;
8136              }
8137          }
8138          $this->name = '';
8139          $this->value = '';
8140          if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
8141          {
8142              $this->position += 2;
8143              $this->state = 'body';
8144          }
8145          elseif ($this->data[$this->position] === "\x0A")
8146          {
8147              $this->position++;
8148              $this->state = 'body';
8149          }
8150          else
8151          {
8152              $this->state = 'name';
8153          }
8154      }
8155  
8156      /**
8157       * Parse a header name
8158       *
8159       * @access private
8160       */
8161  	function name()
8162      {
8163          $len = strcspn($this->data, "\x0A:", $this->position);
8164          if (isset($this->data[$this->position + $len]))
8165          {
8166              if ($this->data[$this->position + $len] === "\x0A")
8167              {
8168                  $this->position += $len;
8169                  $this->state = 'new_line';
8170              }
8171              else
8172              {
8173                  $this->name = substr($this->data, $this->position, $len);
8174                  $this->position += $len + 1;
8175                  $this->state = 'value';
8176              }
8177          }
8178          else
8179          {
8180              $this->state = false;
8181          }
8182      }
8183  
8184      /**
8185       * Parse LWS, replacing consecutive LWS characters with a single space
8186       *
8187       * @access private
8188       */
8189  	function linear_whitespace()
8190      {
8191          do
8192          {
8193              if (substr($this->data, $this->position, 2) === "\x0D\x0A")
8194              {
8195                  $this->position += 2;
8196              }
8197              elseif ($this->data[$this->position] === "\x0A")
8198              {
8199                  $this->position++;
8200              }
8201              $this->position += strspn($this->data, "\x09\x20", $this->position);
8202          } while ($this->has_data() && $this->is_linear_whitespace());
8203          $this->value .= "\x20";
8204      }
8205  
8206      /**
8207       * See what state to move to while within non-quoted header values
8208       *
8209       * @access private
8210       */
8211  	function value()
8212      {
8213          if ($this->is_linear_whitespace())
8214          {
8215              $this->linear_whitespace();
8216          }
8217          else
8218          {
8219              switch ($this->data[$this->position])
8220              {
8221                  case '"':
8222                      $this->position++;
8223                      $this->state = 'quote';
8224                      break;
8225  
8226                  case "\x0A":
8227                      $this->position++;
8228                      $this->state = 'new_line';
8229                      break;
8230  
8231                  default:
8232                      $this->state = 'value_char';
8233                      break;
8234              }
8235          }
8236      }
8237  
8238      /**
8239       * Parse a header value while outside quotes
8240       *
8241       * @access private
8242       */
8243  	function value_char()
8244      {
8245          $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
8246          $this->value .= substr($this->data, $this->position, $len);
8247          $this->position += $len;
8248          $this->state = 'value';
8249      }
8250  
8251      /**
8252       * See what state to move to while within quoted header values
8253       *
8254       * @access private
8255       */
8256  	function quote()
8257      {
8258          if ($this->is_linear_whitespace())
8259          {
8260              $this->linear_whitespace();
8261          }
8262          else
8263          {
8264              switch ($this->data[$this->position])
8265              {
8266                  case '"':
8267                      $this->position++;
8268                      $this->state = 'value';
8269                      break;
8270  
8271                  case "\x0A":
8272                      $this->position++;
8273                      $this->state = 'new_line';
8274                      break;
8275  
8276                  case '\\':
8277                      $this->position++;
8278                      $this->state = 'quote_escaped';
8279                      break;
8280  
8281                  default:
8282                      $this->state = 'quote_char';
8283                      break;
8284              }
8285          }
8286      }
8287  
8288      /**
8289       * Parse a header value while within quotes
8290       *
8291       * @access private
8292       */
8293  	function quote_char()
8294      {
8295          $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
8296          $this->value .= substr($this->data, $this->position, $len);
8297          $this->position += $len;
8298          $this->state = 'value';
8299      }
8300  
8301      /**
8302       * Parse an escaped character within quotes
8303       *
8304       * @access private
8305       */
8306  	function quote_escaped()
8307      {
8308          $this->value .= $this->data[$this->position];
8309          $this->position++;
8310          $this->state = 'quote';
8311      }
8312  
8313      /**
8314       * Parse the body
8315       *
8316       * @access private
8317       */
8318  	function body()
8319      {
8320          $this->body = substr($this->data, $this->position);
8321          $this->state = 'emit';
8322      }
8323  }
8324  
8325  /**
8326   * gzdecode
8327   *
8328   * @package SimplePie
8329   */
8330  class SimplePie_gzdecode
8331  {
8332      /**
8333       * Compressed data
8334       *
8335       * @access private
8336       * @see gzdecode::$data
8337       */
8338      var $compressed_data;
8339  
8340      /**
8341       * Size of compressed data
8342       *
8343       * @access private
8344       */
8345      var $compressed_size;
8346  
8347      /**
8348       * Minimum size of a valid gzip string
8349       *
8350       * @access private
8351       */
8352      var $min_compressed_size = 18;
8353  
8354      /**
8355       * Current position of pointer
8356       *
8357       * @access private
8358       */
8359      var $position = 0;
8360  
8361      /**
8362       * Flags (FLG)
8363       *
8364       * @access private
8365       */
8366      var $flags;
8367  
8368      /**
8369       * Uncompressed data
8370       *
8371       * @access public
8372       * @see gzdecode::$compressed_data
8373       */
8374      var $data;
8375  
8376      /**
8377       * Modified time
8378       *
8379       * @access public
8380       */
8381      var $MTIME;
8382  
8383      /**
8384       * Extra Flags
8385       *
8386       * @access public
8387       */
8388      var $XFL;
8389  
8390      /**
8391       * Operating System
8392       *
8393       * @access public
8394       */
8395      var $OS;
8396  
8397      /**
8398       * Subfield ID 1
8399       *
8400       * @access public
8401       * @see gzdecode::$extra_field
8402       * @see gzdecode::$SI2
8403       */
8404      var $SI1;
8405  
8406      /**
8407       * Subfield ID 2
8408       *
8409       * @access public
8410       * @see gzdecode::$extra_field
8411       * @see gzdecode::$SI1
8412       */
8413      var $SI2;
8414  
8415      /**
8416       * Extra field content
8417       *
8418       * @access public
8419       * @see gzdecode::$SI1
8420       * @see gzdecode::$SI2
8421       */
8422      var $extra_field;
8423  
8424      /**
8425       * Original filename
8426       *
8427       * @access public
8428       */
8429      var $filename;
8430  
8431      /**
8432       * Human readable comment
8433       *
8434       * @access public
8435       */
8436      var $comment;
8437  
8438      /**
8439       * Don't allow anything to be set
8440       *
8441       * @access public
8442       */
8443  	function __set($name, $value)
8444      {
8445          trigger_error("Cannot write property $name", E_USER_ERROR);
8446      }
8447  
8448      /**
8449       * Set the compressed string and related properties
8450       *
8451       * @access public
8452       */
8453  	function SimplePie_gzdecode($data)
8454      {
8455          $this->compressed_data = $data;
8456          $this->compressed_size = strlen($data);
8457      }
8458  
8459      /**
8460       * Decode the GZIP stream
8461       *
8462       * @access public
8463       */
8464  	function parse()
8465      {
8466          if ($this->compressed_size >= $this->min_compressed_size)
8467          {
8468              // Check ID1, ID2, and CM
8469              if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
8470              {
8471                  return false;
8472              }
8473  
8474              // Get the FLG (FLaGs)
8475              $this->flags = ord($this->compressed_data[3]);
8476  
8477              // FLG bits above (1 << 4) are reserved
8478              if ($this->flags > 0x1F)
8479              {
8480                  return false;
8481              }
8482  
8483              // Advance the pointer after the above
8484              $this->position += 4;
8485  
8486              // MTIME
8487              $mtime = substr($this->compressed_data, $this->position, 4);
8488              // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
8489              if (current(unpack('S', "\x00\x01")) === 1)
8490              {
8491                  $mtime = strrev($mtime);
8492              }
8493              $this->MTIME = current(unpack('l', $mtime));
8494              $this->position += 4;
8495  
8496              // Get the XFL (eXtra FLags)
8497              $this->XFL = ord($this->compressed_data[$this->position++]);
8498  
8499              // Get the OS (Operating System)
8500              $this->OS = ord($this->compressed_data[$this->position++]);
8501  
8502              // Parse the FEXTRA
8503              if ($this->flags & 4)
8504              {
8505                  // Read subfield IDs
8506                  $this->SI1 = $this->compressed_data[$this->position++];
8507                  $this->SI2 = $this->compressed_data[$this->position++];
8508  
8509                  // SI2 set to zero is reserved for future use
8510                  if ($this->SI2 === "\x00")
8511                  {
8512                      return false;
8513                  }
8514  
8515                  // Get the length of the extra field
8516                  $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8517                  $this->position += 2;
8518  
8519                  // Check the length of the string is still valid
8520                  $this->min_compressed_size += $len + 4;
8521                  if ($this->compressed_size >= $this->min_compressed_size)
8522                  {
8523                      // Set the extra field to the given data
8524                      $this->extra_field = substr($this->compressed_data, $this->position, $len);
8525                      $this->position += $len;
8526                  }
8527                  else
8528                  {
8529                      return false;
8530                  }
8531              }
8532  
8533              // Parse the FNAME
8534              if ($this->flags & 8)
8535              {
8536                  // Get the length of the filename
8537                  $len = strcspn($this->compressed_data, "\x00", $this->position);
8538  
8539                  // Check the length of the string is still valid
8540                  $this->min_compressed_size += $len + 1;
8541                  if ($this->compressed_size >= $this->min_compressed_size)
8542                  {
8543                      // Set the original filename to the given string
8544                      $this->filename = substr($this->compressed_data, $this->position, $len);
8545                      $this->position += $len + 1;
8546                  }
8547                  else
8548                  {
8549                      return false;
8550                  }
8551              }
8552  
8553              // Parse the FCOMMENT
8554              if ($this->flags & 16)
8555              {
8556                  // Get the length of the comment
8557                  $len = strcspn($this->compressed_data, "\x00", $this->position);
8558  
8559                  // Check the length of the string is still valid
8560                  $this->min_compressed_size += $len + 1;
8561                  if ($this->compressed_size >= $this->min_compressed_size)
8562                  {
8563                      // Set the original comment to the given string
8564                      $this->comment = substr($this->compressed_data, $this->position, $len);
8565                      $this->position += $len + 1;
8566                  }
8567                  else
8568                  {
8569                      return false;
8570                  }
8571              }
8572  
8573              // Parse the FHCRC
8574              if ($this->flags & 2)
8575              {
8576                  // Check the length of the string is still valid
8577                  $this->min_compressed_size += $len + 2;
8578                  if ($this->compressed_size >= $this->min_compressed_size)
8579                  {
8580                      // Read the CRC
8581                      $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
8582  
8583                      // Check the CRC matches
8584                      if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
8585                      {
8586                          $this->position += 2;
8587                      }
8588                      else
8589                      {
8590                          return false;
8591                      }
8592                  }
8593                  else
8594                  {
8595                      return false;
8596                  }
8597              }
8598  
8599              // Decompress the actual data
8600              if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
8601              {
8602                  return false;
8603              }
8604              else
8605              {
8606                  $this->position = $this->compressed_size - 8;
8607              }
8608  
8609              // Check CRC of data
8610              $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8611              $this->position += 4;
8612              /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
8613              {
8614                  return false;
8615              }*/
8616  
8617              // Check ISIZE of data
8618              $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
8619              $this->position += 4;
8620              if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
8621              {
8622                  return false;
8623              }
8624  
8625              // Wow, against all odds, we've actually got a valid gzip string
8626              return true;
8627          }
8628          else
8629          {
8630              return false;
8631          }
8632      }
8633  }
8634  
8635  class SimplePie_Cache
8636  {
8637      /**
8638       * Don't call the constructor. Please.
8639       *
8640       * @access private
8641       */
8642  	function SimplePie_Cache()
8643      {
8644          trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR);
8645      }
8646  
8647      /**
8648       * Create a new SimplePie_Cache object
8649       *
8650       * @static
8651       * @access public
8652       */
8653  	function create($location, $filename, $extension)
8654      {
8655          $location_iri = new SimplePie_IRI($location);
8656          switch ($location_iri->get_scheme())
8657          {
8658              case 'mysql':
8659                  if (extension_loaded('mysql'))
8660                  {
8661                      return new SimplePie_Cache_MySQL($location_iri, $filename, $extension);
8662                  }
8663                  break;
8664  
8665              default:
8666                  return new SimplePie_Cache_File($location, $filename, $extension);
8667          }
8668      }
8669  }
8670  
8671  class SimplePie_Cache_File
8672  {
8673      var $location;
8674      var $filename;
8675      var $extension;
8676      var $name;
8677  
8678  	function SimplePie_Cache_File($location, $filename, $extension)
8679      {
8680          $this->location = $location;
8681          $this->filename = $filename;
8682          $this->extension = $extension;
8683          $this->name = "$this->location/$this->filename.$this->extension";
8684      }
8685  
8686  	function save($data)
8687      {
8688          if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location))
8689          {
8690              if (is_a($data, 'SimplePie'))
8691              {
8692                  $data = $data->data;
8693              }
8694  
8695              $data = serialize($data);
8696  
8697              if (function_exists('file_put_contents'))
8698              {
8699                  return (bool) file_put_contents($this->name, $data);
8700              }
8701              else
8702              {
8703                  $fp = fopen($this->name, 'wb');
8704                  if ($fp)
8705                  {
8706                      fwrite($fp, $data);
8707                      fclose($fp);
8708                      return true;
8709                  }
8710              }
8711          }
8712          return false;
8713      }
8714  
8715  	function load()
8716      {
8717          if (file_exists($this->name) && is_readable($this->name))
8718          {
8719              return unserialize(file_get_contents($this->name));
8720          }
8721          return false;
8722      }
8723  
8724  	function mtime()
8725      {
8726          if (file_exists($this->name))
8727          {
8728              return filemtime($this->name);
8729          }
8730          return false;
8731      }
8732  
8733  	function touch()
8734      {
8735          if (file_exists($this->name))
8736          {
8737              return touch($this->name);
8738          }
8739          return false;
8740      }
8741  
8742  	function unlink()
8743      {
8744          if (file_exists($this->name))
8745          {
8746              return unlink($this->name);
8747          }
8748          return false;
8749      }
8750  }
8751  
8752  class SimplePie_Cache_DB
8753  {
8754  	function prepare_simplepie_object_for_cache($data)
8755      {
8756          $items = $data->get_items();
8757          $items_by_id = array();
8758  
8759          if (!empty($items))
8760          {
8761              foreach ($items as $item)
8762              {
8763                  $items_by_id[$item->get_id()] = $item;
8764              }
8765  
8766              if (count($items_by_id) !== count($items))
8767              {
8768                  $items_by_id = array();
8769                  foreach ($items as $item)
8770                  {
8771                      $items_by_id[$item->get_id(true)] = $item;
8772                  }
8773              }
8774  
8775              if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
8776              {
8777                  $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
8778              }
8779              elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
8780              {
8781                  $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
8782              }
8783              elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
8784              {
8785                  $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
8786              }
8787              elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
8788              {
8789                  $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
8790              }
8791              else
8792              {
8793                  $channel = null;
8794              }
8795  
8796              if ($channel !== null)
8797              {
8798                  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
8799                  {
8800                      unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
8801                  }
8802                  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
8803                  {
8804                      unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
8805                  }
8806                  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
8807                  {
8808                      unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
8809                  }
8810                  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
8811                  {
8812                      unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
8813                  }
8814                  if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
8815                  {
8816                      unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
8817                  }
8818              }
8819              if (isset($data->data['items']))
8820              {
8821                  unset($data->data['items']);
8822              }
8823              if (isset($data->data['ordered_items']))
8824              {
8825                  unset($data->data['ordered_items']);
8826              }
8827          }
8828          return array(serialize($data->data), $items_by_id);
8829      }
8830  }
8831  
8832  class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
8833  {
8834      var $mysql;
8835      var $options;
8836      var $id;
8837  
8838  	function SimplePie_Cache_MySQL($mysql_location, $name, $extension)
8839      {
8840          $host = $mysql_location->get_host();
8841          if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')')
8842          {
8843              $server = ':' . substr($host, 5, -1);
8844          }
8845          else
8846          {
8847              $server = $host;
8848              if ($mysql_location->get_port() !== null)
8849              {
8850                  $server .= ':' . $mysql_location->get_port();
8851              }
8852          }
8853  
8854          if (strpos($mysql_location->get_userinfo(), ':') !== false)
8855          {
8856              list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2);
8857          }
8858          else
8859          {
8860              $username = $mysql_location->get_userinfo();
8861              $password = null;
8862          }
8863  
8864          if ($this->mysql = mysql_connect($server, $username, $password))
8865          {
8866              $this->id = $name . $extension;
8867              $this->options = SimplePie_Misc::parse_str($mysql_location->get_query());
8868              if (!isset($this->options['prefix'][0]))
8869              {
8870                  $this->options['prefix'][0] = '';
8871              }
8872  
8873              if (mysql_select_db(ltrim($mysql_location->get_path(), '/'))
8874                  && mysql_query('SET NAMES utf8')
8875                  && ($query = mysql_unbuffered_query('SHOW TABLES')))
8876              {
8877                  $db = array();
8878                  while ($row = mysql_fetch_row($query))
8879                  {
8880                      $db[] = $row[0];
8881                  }
8882  
8883                  if (!in_array($this->options['prefix'][0] . 'cache_data', $db))
8884                  {
8885                      if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))'))
8886                      {
8887                          $this->mysql = null;
8888                      }
8889                  }
8890  
8891                  if (!in_array($this->options['prefix'][0] . 'items', $db))
8892                  {
8893                      if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))'))
8894                      {
8895                          $this->mysql = null;
8896                      }
8897                  }
8898              }
8899              else
8900              {
8901                  $this->mysql = null;
8902              }
8903          }
8904      }
8905  
8906  	function save($data)
8907      {
8908          if ($this->mysql)
8909          {
8910              $feed_id = "'" . mysql_real_escape_string($this->id) . "'";
8911  
8912              if (is_a($data, 'SimplePie'))
8913              {
8914                  if (SIMPLEPIE_PHP5)
8915                  {
8916                      // This keyword needs to defy coding standards for PHP4 compatibility
8917                      $data = clone($data);
8918                  }
8919  
8920                  $prepared = $this->prepare_simplepie_object_for_cache($data);
8921  
8922                  if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
8923                  {
8924                      if (mysql_num_rows($query))
8925                      {
8926                          $items = count($prepared[1]);
8927                          if ($items)
8928                          {
8929                              $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8930                          }
8931                          else
8932                          {
8933                              $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id;
8934                          }
8935  
8936                          if (!mysql_query($sql, $this->mysql))
8937                          {
8938                              return false;
8939                          }
8940                      }
8941                      elseif (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql))
8942                      {
8943                          return false;
8944                      }
8945  
8946                      $ids = array_keys($prepared[1]);
8947                      if (!empty($ids))
8948                      {
8949                          foreach ($ids as $id)
8950                          {
8951                              $database_ids[] = mysql_real_escape_string($id);
8952                          }
8953  
8954                          if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql))
8955                          {
8956                              $existing_ids = array();
8957                              while ($row = mysql_fetch_row($query))
8958                              {
8959                                  $existing_ids[] = $row[0];
8960                              }
8961  
8962                              $new_ids = array_diff($ids, $existing_ids);
8963  
8964                              foreach ($new_ids as $new_id)
8965                              {
8966                                  if (!($date = $prepared[1][$new_id]->get_date('U')))
8967                                  {
8968                                      $date = time();
8969                                  }
8970  
8971                                  if (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data)) . '\', ' . $date . ')', $this->mysql))
8972                                  {
8973                                      return false;
8974                                  }
8975                              }
8976                              return true;
8977                          }
8978                      }
8979                      else
8980                      {
8981                          return true;
8982                      }
8983                  }
8984              }
8985              elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql))
8986              {
8987                  if (mysql_num_rows($query))
8988                  {
8989                      if (mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql))
8990                      {
8991                          return true;
8992                      }
8993                  }
8994                  elseif (mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql))
8995                  {
8996                      return true;
8997                  }
8998              }
8999          }
9000          return false;
9001      }
9002  
9003  	function load()
9004      {
9005          if ($this->mysql && ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
9006          {
9007              $data = unserialize($row[1]);
9008  
9009              if (isset($this->options['items'][0]))
9010              {
9011                  $items = (int) $this->options['items'][0];
9012              }
9013              else
9014              {
9015                  $items = (int) $row[0];
9016              }
9017  
9018              if ($items !== 0)
9019              {
9020                  if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
9021                  {
9022                      $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
9023                  }
9024                  elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
9025                  {
9026                      $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
9027                  }
9028                  elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
9029                  {
9030                      $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
9031                  }
9032                  elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
9033                  {
9034                      $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
9035                  }
9036                  else
9037                  {
9038                      $feed = null;
9039                  }
9040  
9041                  if ($feed !== null)
9042                  {
9043                      $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC';
9044                      if ($items > 0)
9045                      {
9046                          $sql .= ' LIMIT ' . $items;
9047                      }
9048  
9049                      if ($query = mysql_unbuffered_query($sql, $this->mysql))
9050                      {
9051                          while ($row = mysql_fetch_row($query))
9052                          {
9053                              $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]);
9054                          }
9055                      }
9056                      else
9057                      {
9058                          return false;
9059                      }
9060                  }
9061              }
9062              return $data;
9063          }
9064          return false;
9065      }
9066  
9067  	function mtime()
9068      {
9069          if ($this->mysql && ($query = mysql_query('SELECT `mtime` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query)))
9070          {
9071              return $row[0];
9072          }
9073          else
9074          {
9075              return false;
9076          }
9077      }
9078  
9079  	function touch()
9080      {
9081          if ($this->mysql && ($query = mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && mysql_affected_rows($this->mysql))
9082          {
9083              return true;
9084          }
9085          else
9086          {
9087              return false;
9088          }
9089      }
9090  
9091  	function unlink()
9092      {
9093          if ($this->mysql && ($query = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($query2 = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)))
9094          {
9095              return true;
9096          }
9097          else
9098          {
9099              return false;
9100          }
9101      }
9102  }
9103  
9104  class SimplePie_Misc
9105  {
9106  	function time_hms($seconds)
9107      {
9108          $time = '';
9109  
9110          $hours = floor($seconds / 3600);
9111          $remainder = $seconds % 3600;
9112          if ($hours > 0)
9113          {
9114              $time .= $hours.':';
9115          }
9116  
9117          $minutes = floor($remainder / 60);
9118          $seconds = $remainder % 60;
9119          if ($minutes < 10 && $hours > 0)
9120          {
9121              $minutes = '0' . $minutes;
9122          }
9123          if ($seconds < 10)
9124          {
9125              $seconds = '0' . $seconds;
9126          }
9127  
9128          $time .= $minutes.':';
9129          $time .= $seconds;
9130  
9131          return $time;
9132      }
9133  
9134  	function absolutize_url($relative, $base)
9135      {
9136          $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
9137          return $iri->get_iri();
9138      }
9139  
9140  	function remove_dot_segments($input)
9141      {
9142          $output = '';
9143          while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
9144          {
9145              // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
9146              if (strpos($input, '../') === 0)
9147              {
9148                  $input = substr($input, 3);
9149              }
9150              elseif (strpos($input, './') === 0)
9151              {
9152                  $input = substr($input, 2);
9153              }
9154              // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
9155              elseif (strpos($input, '/./') === 0)
9156              {
9157                  $input = substr_replace($input, '/', 0, 3);
9158              }
9159              elseif ($input === '/.')
9160              {
9161                  $input = '/';
9162              }
9163              // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
9164              elseif (strpos($input, '/../') === 0)
9165              {
9166                  $input = substr_replace($input, '/', 0, 4);
9167                  $output = substr_replace($output, '', strrpos($output, '/'));
9168              }
9169              elseif ($input === '/..')
9170              {
9171                  $input = '/';
9172                  $output = substr_replace($output, '', strrpos($output, '/'));
9173              }
9174              // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
9175              elseif ($input === '.' || $input === '..')
9176              {
9177                  $input = '';
9178              }
9179              // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
9180              elseif (($pos = strpos($input, '/', 1)) !== false)
9181              {
9182                  $output .= substr($input, 0, $pos);
9183                  $input = substr_replace($input, '', 0, $pos);
9184              }
9185              else
9186              {
9187                  $output .= $input;
9188                  $input = '';
9189              }
9190          }
9191          return $output . $input;
9192      }
9193  
9194  	function get_element($realname, $string)
9195      {
9196          $return = array();
9197          $name = preg_quote($realname, '/');
9198          if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
9199          {
9200              for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
9201              {
9202                  $return[$i]['tag'] = $realname;
9203                  $return[$i]['full'] = $matches[$i][0][0];
9204                  $return[$i]['offset'] = $matches[$i][0][1];
9205                  if (strlen($matches[$i][3][0]) <= 2)
9206                  {
9207                      $return[$i]['self_closing'] = true;
9208                  }
9209                  else
9210                  {
9211                      $return[$i]['self_closing'] = false;
9212                      $return[$i]['content'] = $matches[$i][4][0];
9213                  }
9214                  $return[$i]['attribs'] = array();
9215                  if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
9216                  {
9217                      for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
9218                      {
9219                          if (count($attribs[$j]) === 2)
9220                          {
9221                              $attribs[$j][2] = $attribs[$j][1];
9222                          }
9223                          $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8');
9224                      }
9225                  }
9226              }
9227          }
9228          return $return;
9229      }
9230  
9231  	function element_implode($element)
9232      {
9233          $full = "<$element[tag]";
9234          foreach ($element['attribs'] as $key => $value)
9235          {
9236              $key = strtolower($key);
9237              $full .= " $key=\"" . htmlspecialchars($value['data']) . '"';
9238          }
9239          if ($element['self_closing'])
9240          {
9241              $full .= ' />';
9242          }
9243          else
9244          {
9245              $full .= ">$element[content]</$element[tag]>";
9246          }
9247          return $full;
9248      }
9249  
9250  	function error($message, $level, $file, $line)
9251      {
9252          if ((ini_get('error_reporting') & $level) > 0)
9253          {
9254              switch ($level)
9255              {
9256                  case E_USER_ERROR:
9257                      $note = 'PHP Error';
9258                      break;
9259                  case E_USER_WARNING:
9260                      $note = 'PHP Warning';
9261                      break;
9262                  case E_USER_NOTICE:
9263                      $note = 'PHP Notice';
9264                      break;
9265                  default:
9266                      $note = 'Unknown Error';
9267                      break;
9268              }
9269  
9270              $log_error = true;
9271              if (!function_exists('error_log'))
9272              {
9273                  $log_error = false;
9274              }
9275  
9276              $log_file = @ini_get('error_log');
9277              if (!empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file))
9278              {
9279                  $log_error = false;
9280              }
9281  
9282              if ($log_error)
9283              {
9284                  @error_log("$note: $message in $file on line $line", 0);
9285              }
9286          }
9287  
9288          return $message;
9289      }
9290  
9291      /**
9292       * If a file has been cached, retrieve and display it.
9293       *
9294       * This is most useful for caching images (get_favicon(), etc.),
9295       * however it works for all cached files.  This WILL NOT display ANY
9296       * file/image/page/whatever, but rather only display what has already
9297       * been cached by SimplePie.
9298       *
9299       * @access public
9300       * @see SimplePie::get_favicon()
9301       * @param str $identifier_url URL that is used to identify the content.
9302       * This may or may not be the actual URL of the live content.
9303       * @param str $cache_location Location of SimplePie's cache.  Defaults
9304       * to './cache'.
9305       * @param str $cache_extension The file extension that the file was
9306       * cached with.  Defaults to 'spc'.
9307       * @param str $cache_class Name of the cache-handling class being used
9308       * in SimplePie.  Defaults to 'SimplePie_Cache', and should be left
9309       * as-is unless you've overloaded the class.
9310       * @param str $cache_name_function Obsolete. Exists for backwards
9311       * compatibility reasons only.
9312       */
9313  	function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
9314      {
9315          $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
9316  
9317          if ($file = $cache->load())
9318          {
9319              if (isset($file['headers']['content-type']))
9320              {
9321                  header('Content-type:' . $file['headers']['content-type']);
9322              }
9323              else
9324              {
9325                  header('Content-type: application/octet-stream');
9326              }
9327              header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
9328              echo $file['body'];
9329              exit;
9330          }
9331  
9332          die('Cached file for ' . $identifier_url . ' cannot be found.');
9333      }
9334  
9335  	function fix_protocol($url, $http = 1)
9336      {
9337          $url = SimplePie_Misc::normalize_url($url);
9338          $parsed = SimplePie_Misc::parse_url($url);
9339          if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
9340          {
9341              return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
9342          }
9343  
9344          if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
9345          {
9346              return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
9347          }
9348  
9349          if ($http === 2 && $parsed['scheme'] !== '')
9350          {
9351              return "feed:$url";
9352          }
9353          elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
9354          {
9355              return substr_replace($url, 'podcast', 0, 4);
9356          }
9357          elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
9358          {
9359              return substr_replace($url, 'itpc', 0, 4);
9360          }
9361          else
9362          {
9363              return $url;
9364          }
9365      }
9366  
9367  	function parse_url($url)
9368      {
9369          $iri = new SimplePie_IRI($url);
9370          return array(
9371              'scheme' => (string) $iri->get_scheme(),
9372              'authority' => (string) $iri->get_authority(),
9373              'path' => (string) $iri->get_path(),
9374              'query' => (string) $iri->get_query(),
9375              'fragment' => (string) $iri->get_fragment()
9376          );
9377      }
9378  
9379  	function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
9380      {
9381          $iri = new SimplePie_IRI('');
9382          $iri->set_scheme($scheme);
9383          $iri->set_authority($authority);
9384          $iri->set_path($path);
9385          $iri->set_query($query);
9386          $iri->set_fragment($fragment);
9387          return $iri->get_iri();
9388      }
9389  
9390  	function normalize_url($url)
9391      {
9392          $iri = new SimplePie_IRI($url);
9393          return $iri->get_iri();
9394      }
9395  
9396  	function percent_encoding_normalization($match)
9397      {
9398          $integer = hexdec($match[1]);
9399          if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
9400          {
9401              return chr($integer);
9402          }
9403          else
9404          {
9405              return strtoupper($match[0]);
9406          }
9407      }
9408  
9409      /**
9410       * Remove bad UTF-8 bytes
9411       *
9412       * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9413       * FAQ: Multilingual Forms (modified to include full ASCII range)
9414       *
9415       * @author Geoffrey Sneddon
9416       * @see http://www.w3.org/International/questions/qa-forms-utf-8
9417       * @param string $str String to remove bad UTF-8 bytes from
9418       * @return string UTF-8 string
9419       */
9420  	function utf8_bad_replace($str)
9421      {
9422          if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9423          {
9424              return $return;
9425          }
9426          elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9427          {
9428              return $return;
9429          }
9430          elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches))
9431          {
9432              return implode("\xEF\xBF\xBD", $matches[0]);
9433          }
9434          elseif ($str !== '')
9435          {
9436              return "\xEF\xBF\xBD";
9437          }
9438          else
9439          {
9440              return '';
9441          }
9442      }
9443  
9444      /**
9445       * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9446       *
9447       * @static
9448       * @access public
9449       * @param string $string Windows-1252 encoded string
9450       * @return string UTF-8 encoded string
9451       */
9452  	function windows_1252_to_utf8($string)
9453      {
9454          static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
9455  
9456          return strtr($string, $convert_table);
9457      }
9458  
9459  	function change_encoding($data, $input, $output)
9460      {
9461          $input = SimplePie_Misc::encoding($input);
9462          $output = SimplePie_Misc::encoding($output);
9463  
9464          // We fail to fail on non US-ASCII bytes
9465          if ($input === 'US-ASCII')
9466          {
9467              static $non_ascii_octects = '';
9468              if (!$non_ascii_octects)
9469              {
9470                  for ($i = 0x80; $i <= 0xFF; $i++)
9471                  {
9472                      $non_ascii_octects .= chr($i);
9473                  }
9474              }
9475              $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9476          }
9477  
9478          // This is first, as behaviour of this is completely predictable
9479          if ($input === 'windows-1252' && $output === 'UTF-8')
9480          {
9481              return SimplePie_Misc::windows_1252_to_utf8($data);
9482          }
9483          // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
9484          elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && in_array($input, mb_list_encodings()) && ($return = @mb_convert_encoding($data, $output, $input)))
9485          {
9486              return $return;
9487          }
9488          // This is last, as behaviour of this varies with OS userland and PHP version
9489          elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9490          {
9491              return $return;
9492          }
9493          // If we can't do anything, just fail
9494          else
9495          {
9496              return false;
9497          }
9498      }
9499  
9500      /**
9501       * Normalize an encoding name
9502       *
9503       * This is automatically generated by create.php
9504       *
9505       * To generate it, run `php create.php` on the command line, and copy the
9506       * output to replace this function.
9507       *
9508       * @param string $charset Character set to standardise
9509       * @return string Standardised name
9510       */
9511  	function encoding($charset)
9512      {
9513          // Normalization from UTS #22
9514          switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
9515          {
9516              case 'adobestandardencoding':
9517              case 'csadobestandardencoding':
9518                  return 'Adobe-Standard-Encoding';
9519  
9520              case 'adobesymbolencoding':
9521              case 'cshppsmath':
9522                  return 'Adobe-Symbol-Encoding';
9523  
9524              case 'ami1251':
9525              case 'amiga1251':
9526                  return 'Amiga-1251';
9527  
9528              case 'ansix31101983':
9529              case 'csat5001983':
9530              case 'csiso99naplps':
9531              case 'isoir99':
9532              case 'naplps':
9533                  return 'ANSI_X3.110-1983';
9534  
9535              case 'arabic7':
9536              case 'asmo449':
9537              case 'csiso89asmo449':
9538              case 'iso9036':
9539              case 'isoir89':
9540                  return 'ASMO_449';
9541  
9542              case 'big5':
9543              case 'csbig5':
9544                  return 'Big5';
9545  
9546              case 'big5hkscs':
9547                  return 'Big5-HKSCS';
9548  
9549              case 'bocu1':
9550              case 'csbocu1':
9551                  return 'BOCU-1';
9552  
9553              case 'brf':
9554              case 'csbrf':
9555                  return 'BRF';
9556  
9557              case 'bs4730':
9558              case 'csiso4unitedkingdom':
9559              case 'gb':
9560              case 'iso646gb':
9561              case 'isoir4':
9562              case 'uk':
9563                  return 'BS_4730';
9564  
9565              case 'bsviewdata':
9566              case 'csiso47bsviewdata':
9567              case 'isoir47':
9568                  return 'BS_viewdata';
9569  
9570              case 'cesu8':
9571              case 'cscesu8':
9572                  return 'CESU-8';
9573  
9574              case 'ca':
9575              case 'csa71':
9576              case 'csaz243419851':
9577              case 'csiso121canadian1':
9578              case 'iso646ca':
9579              case 'isoir121':
9580                  return 'CSA_Z243.4-1985-1';
9581  
9582              case 'csa72':
9583              case 'csaz243419852':
9584              case 'csiso122canadian2':
9585              case 'iso646ca2':
9586              case 'isoir122':
9587                  return 'CSA_Z243.4-1985-2';
9588  
9589              case 'csaz24341985gr':
9590              case 'csiso123csaz24341985gr':
9591              case 'isoir123':
9592                  return 'CSA_Z243.4-1985-gr';
9593  
9594              case 'csiso139csn369103':
9595              case 'csn369103':
9596              case 'isoir139':
9597                  return 'CSN_369103';
9598  
9599              case 'csdecmcs':
9600              case 'dec':
9601              case 'decmcs':
9602                  return 'DEC-MCS';
9603  
9604              case 'csiso21german':
9605              case 'de':
9606              case 'din66003':
9607              case 'iso646de':
9608              case 'isoir21':
9609                  return 'DIN_66003';
9610  
9611              case 'csdkus':
9612              case 'dkus':
9613                  return 'dk-us';
9614  
9615              case 'csiso646danish':
9616              case 'dk':
9617              case 'ds2089':
9618              case 'iso646dk':
9619                  return 'DS_2089';
9620  
9621              case 'csibmebcdicatde':
9622              case 'ebcdicatde':
9623                  return 'EBCDIC-AT-DE';
9624  
9625              case 'csebcdicatdea':
9626              case 'ebcdicatdea':
9627                  return 'EBCDIC-AT-DE-A';
9628  
9629              case 'csebcdiccafr':
9630              case 'ebcdiccafr':
9631                  return 'EBCDIC-CA-FR';
9632  
9633              case 'csebcdicdkno':
9634              case 'ebcdicdkno':
9635                  return 'EBCDIC-DK-NO';
9636  
9637              case 'csebcdicdknoa':
9638              case 'ebcdicdknoa':
9639                  return 'EBCDIC-DK-NO-A';
9640  
9641              case 'csebcdices':
9642              case 'ebcdices':
9643                  return 'EBCDIC-ES';
9644  
9645              case 'csebcdicesa':
9646              case 'ebcdicesa':
9647                  return 'EBCDIC-ES-A';
9648  
9649              case 'csebcdicess':
9650              case 'ebcdicess':
9651                  return 'EBCDIC-ES-S';
9652  
9653              case 'csebcdicfise':
9654              case 'ebcdicfise':
9655                  return 'EBCDIC-FI-SE';
9656  
9657              case 'csebcdicfisea':
9658              case 'ebcdicfisea':
9659                  return 'EBCDIC-FI-SE-A';
9660  
9661              case 'csebcdicfr':
9662              case 'ebcdicfr':
9663                  return 'EBCDIC-FR';
9664  
9665              case 'csebcdicit':
9666              case 'ebcdicit':
9667                  return 'EBCDIC-IT';
9668  
9669              case 'csebcdicpt':
9670              case 'ebcdicpt':
9671                  return 'EBCDIC-PT';
9672  
9673              case 'csebcdicuk':
9674              case 'ebcdicuk':
9675                  return 'EBCDIC-UK';
9676  
9677              case 'csebcdicus':
9678              case 'ebcdicus':
9679                  return 'EBCDIC-US';
9680  
9681              case 'csiso111ecmacyrillic':
9682              case 'ecmacyrillic':
9683              case 'isoir111':
9684              case 'koi8e':
9685                  return 'ECMA-cyrillic';
9686  
9687              case 'csiso17spanish':
9688              case 'es':
9689              case 'iso646es':
9690              case 'isoir17':
9691                  return 'ES';
9692  
9693              case 'csiso85spanish2':
9694              case 'es2':
9695              case 'iso646es2':
9696              case 'isoir85':
9697                  return 'ES2';
9698  
9699              case 'cseucpkdfmtjapanese':
9700              case 'eucjp':
9701              case 'extendedunixcodepackedformatforjapanese':
9702                  return 'EUC-JP';
9703  
9704              case 'cseucfixwidjapanese':
9705              case 'extendedunixcodefixedwidthforjapanese':
9706                  return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9707  
9708              case 'gb18030':
9709                  return 'GB18030';
9710  
9711              case 'chinese':
9712              case 'cp936':
9713              case 'csgb2312':
9714              case 'csiso58gb231280':
9715              case 'gb2312':
9716              case 'gb231280':
9717              case 'gbk':
9718              case 'isoir58':
9719              case 'ms936':
9720              case 'windows936':
9721                  return 'GBK';
9722  
9723              case 'cn':
9724              case 'csiso57gb1988':
9725              case 'gb198880':
9726              case 'iso646cn':
9727              case 'isoir57':
9728                  return 'GB_1988-80';
9729  
9730              case 'csiso153gost1976874':
9731              case 'gost1976874':
9732              case 'isoir153':
9733              case 'stsev35888':
9734                  return 'GOST_19768-74';
9735  
9736              case 'csiso150':
9737              case 'csiso150greekccitt':
9738              case 'greekccitt':
9739              case 'isoir150':
9740                  return 'greek-ccitt';
9741  
9742              case 'csiso88greek7':
9743              case 'greek7':
9744              case 'isoir88':
9745                  return 'greek7';
9746  
9747              case 'csiso18greek7old':
9748              case 'greek7old':
9749              case 'isoir18':
9750                  return 'greek7-old';
9751  
9752              case 'cshpdesktop':
9753              case 'hpdesktop':
9754                  return 'HP-DeskTop';
9755  
9756              case 'cshplegal':
9757              case 'hplegal':
9758                  return 'HP-Legal';
9759  
9760              case 'cshpmath8':
9761              case 'hpmath8':
9762                  return 'HP-Math8';
9763  
9764              case 'cshppifont':
9765              case 'hppifont':
9766                  return 'HP-Pi-font';
9767  
9768              case 'cshproman8':
9769              case 'hproman8':
9770              case 'r8':
9771              case 'roman8':
9772                  return 'hp-roman8';
9773  
9774              case 'hzgb2312':
9775                  return 'HZ-GB-2312';
9776  
9777              case 'csibmsymbols':
9778              case 'ibmsymbols':
9779                  return 'IBM-Symbols';
9780  
9781              case 'csibmthai':
9782              case 'ibmthai':
9783                  return 'IBM-Thai';
9784  
9785              case 'cp37':
9786              case 'csibm37':
9787              case 'ebcdiccpca':
9788              case 'ebcdiccpnl':
9789              case 'ebcdiccpus':
9790              case 'ebcdiccpwt':
9791              case 'ibm37':
9792                  return 'IBM037';
9793  
9794              case 'cp38':
9795              case 'csibm38':
9796              case 'ebcdicint':
9797              case 'ibm38':
9798                  return 'IBM038';
9799  
9800              case 'cp273':
9801              case 'csibm273':
9802              case 'ibm273':
9803                  return 'IBM273';
9804  
9805              case 'cp274':
9806              case 'csibm274':
9807              case 'ebcdicbe':
9808              case 'ibm274':
9809                  return 'IBM274';
9810  
9811              case 'cp275':
9812              case 'csibm275':
9813              case 'ebcdicbr':
9814              case 'ibm275':
9815                  return 'IBM275';
9816  
9817              case 'csibm277':
9818              case 'ebcdiccpdk':
9819              case 'ebcdiccpno':
9820              case 'ibm277':
9821                  return 'IBM277';
9822  
9823              case 'cp278':
9824              case 'csibm278':
9825              case 'ebcdiccpfi':
9826              case 'ebcdiccpse':
9827              case 'ibm278':
9828                  return 'IBM278';
9829  
9830              case 'cp280':
9831              case 'csibm280':
9832              case 'ebcdiccpit':
9833              case 'ibm280':
9834                  return 'IBM280';
9835  
9836              case 'cp281':
9837              case 'csibm281':
9838              case 'ebcdicjpe':
9839              case 'ibm281':
9840                  return 'IBM281';
9841  
9842              case 'cp284':
9843              case 'csibm284':
9844              case 'ebcdiccpes':
9845              case 'ibm284':
9846                  return 'IBM284';
9847  
9848              case 'cp285':
9849              case 'csibm285':
9850              case 'ebcdiccpgb':
9851              case 'ibm285':
9852                  return 'IBM285';
9853  
9854              case 'cp290':
9855              case 'csibm290':
9856              case 'ebcdicjpkana':
9857              case 'ibm290':
9858                  return 'IBM290';
9859  
9860              case 'cp297':
9861              case 'csibm297':
9862              case 'ebcdiccpfr':
9863              case 'ibm297':
9864                  return 'IBM297';
9865  
9866              case 'cp420':
9867              case 'csibm420':
9868              case 'ebcdiccpar1':
9869              case 'ibm420':
9870                  return 'IBM420';
9871  
9872              case 'cp423':
9873              case 'csibm423':
9874              case 'ebcdiccpgr':
9875              case 'ibm423':
9876                  return 'IBM423';
9877  
9878              case 'cp424':
9879              case 'csibm424':
9880              case 'ebcdiccphe':
9881              case 'ibm424':
9882                  return 'IBM424';
9883  
9884              case '437':
9885              case 'cp437':
9886              case 'cspc8codepage437':
9887              case 'ibm437':
9888                  return 'IBM437';
9889  
9890              case 'cp500':
9891              case 'csibm500':
9892              case 'ebcdiccpbe':
9893              case 'ebcdiccpch':
9894              case 'ibm500':
9895                  return 'IBM500';
9896  
9897              case 'cp775':
9898              case 'cspc775baltic':
9899              case 'ibm775':
9900                  return 'IBM775';
9901  
9902              case '850':
9903              case 'cp850':
9904              case 'cspc850multilingual':
9905              case 'ibm850':
9906                  return 'IBM850';
9907  
9908              case '851':
9909              case 'cp851':
9910              case 'csibm851':
9911              case 'ibm851':
9912                  return 'IBM851';
9913  
9914              case '852':
9915              case 'cp852':
9916              case 'cspcp852':
9917              case 'ibm852':
9918                  return 'IBM852';
9919  
9920              case '855':
9921              case 'cp855':
9922              case 'csibm855':
9923              case 'ibm855':
9924                  return 'IBM855';
9925  
9926              case '857':
9927              case 'cp857':
9928              case 'csibm857':
9929              case 'ibm857':
9930                  return 'IBM857';
9931  
9932              case 'ccsid858':
9933              case 'cp858':
9934              case 'ibm858':
9935              case 'pcmultilingual850euro':
9936                  return 'IBM00858';
9937  
9938              case '860':
9939              case 'cp860':
9940              case 'csibm860':
9941              case 'ibm860':
9942                  return 'IBM860';
9943  
9944              case '861':
9945              case 'cp861':
9946              case 'cpis':
9947              case 'csibm861':
9948              case 'ibm861':
9949                  return 'IBM861';
9950  
9951              case '862':
9952              case 'cp862':
9953              case 'cspc862latinhebrew':
9954              case 'ibm862':
9955                  return 'IBM862';
9956  
9957              case '863':
9958              case 'cp863':
9959              case 'csibm863':
9960              case 'ibm863':
9961                  return 'IBM863';
9962  
9963              case 'cp864':
9964              case 'csibm864':
9965              case 'ibm864':
9966                  return 'IBM864';
9967  
9968              case '865':
9969              case 'cp865':
9970              case 'csibm865':
9971              case 'ibm865':
9972                  return 'IBM865';
9973  
9974              case '866':
9975              case 'cp866':
9976              case 'csibm866':
9977              case 'ibm866':
9978                  return 'IBM866';
9979  
9980              case 'cp868':
9981              case 'cpar':
9982              case 'csibm868':
9983              case 'ibm868':
9984                  return 'IBM868';
9985  
9986              case '869':
9987              case 'cp869':
9988              case 'cpgr':
9989              case 'csibm869':
9990              case 'ibm869':
9991                  return 'IBM869';
9992  
9993              case 'cp870':
9994              case 'csibm870':
9995              case 'ebcdiccproece':
9996              case 'ebcdiccpyu':
9997              case 'ibm870':
9998                  return 'IBM870';
9999  
10000              case 'cp871':
10001              case 'csibm871':
10002              case 'ebcdiccpis':
10003              case 'ibm871':
10004                  return 'IBM871';
10005  
10006              case 'cp880':
10007              case 'csibm880':
10008              case 'ebcdiccyrillic':
10009              case 'ibm880':
10010                  return 'IBM880';
10011  
10012              case 'cp891':
10013              case 'csibm891':
10014              case 'ibm891':
10015                  return 'IBM891';
10016  
10017              case 'cp903':
10018              case 'csibm903':
10019              case 'ibm903':
10020                  return 'IBM903';
10021  
10022              case '904':
10023              case 'cp904':
10024              case 'csibbm904':
10025              case 'ibm904':
10026                  return 'IBM904';
10027  
10028              case 'cp905':
10029              case 'csibm905':
10030              case 'ebcdiccptr':
10031              case 'ibm905':
10032                  return 'IBM905';
10033  
10034              case 'cp918':
10035              case 'csibm918':
10036              case 'ebcdiccpar2':
10037              case 'ibm918':
10038                  return 'IBM918';
10039  
10040              case 'ccsid924':
10041              case 'cp924':
10042              case 'ebcdiclatin9euro':
10043              case 'ibm924':
10044                  return 'IBM00924';
10045  
10046              case 'cp1026':
10047              case 'csibm1026':
10048              case 'ibm1026':
10049                  return 'IBM1026';
10050  
10051              case 'ibm1047':
10052                  return 'IBM1047';
10053  
10054              case 'ccsid1140':
10055              case 'cp1140':
10056              case 'ebcdicus37euro':
10057              case 'ibm1140':
10058                  return 'IBM01140';
10059  
10060              case 'ccsid1141':
10061              case 'cp1141':
10062              case 'ebcdicde273euro':
10063              case 'ibm1141':
10064                  return 'IBM01141';
10065  
10066              case 'ccsid1142':
10067              case 'cp1142':
10068              case 'ebcdicdk277euro':
10069              case 'ebcdicno277euro':
10070              case 'ibm1142':
10071                  return 'IBM01142';
10072  
10073              case 'ccsid1143':
10074              case 'cp1143':
10075              case 'ebcdicfi278euro':
10076              case 'ebcdicse278euro':
10077              case 'ibm1143':
10078                  return 'IBM01143';
10079  
10080              case 'ccsid1144':
10081              case 'cp1144':
10082              case 'ebcdicit280euro':
10083              case 'ibm1144':
10084                  return 'IBM01144';
10085  
10086              case 'ccsid1145':
10087              case 'cp1145':
10088              case 'ebcdices284euro':
10089              case 'ibm1145':
10090                  return 'IBM01145';
10091  
10092              case 'ccsid1146':
10093              case 'cp1146':
10094              case 'ebcdicgb285euro':
10095              case 'ibm1146':
10096                  return 'IBM01146';
10097  
10098              case 'ccsid1147':
10099              case 'cp1147':
10100              case 'ebcdicfr297euro':
10101              case 'ibm1147':
10102                  return 'IBM01147';
10103  
10104              case 'ccsid1148':
10105              case 'cp1148':
10106              case 'ebcdicinternational500euro':
10107              case 'ibm1148':
10108                  return 'IBM01148';
10109  
10110              case 'ccsid1149':
10111              case 'cp1149':
10112              case 'ebcdicis871euro':
10113              case 'ibm1149':
10114                  return 'IBM01149';
10115  
10116              case 'csiso143iecp271':
10117              case 'iecp271':
10118              case 'isoir143':
10119                  return 'IEC_P27-1';
10120  
10121              case 'csiso49inis':
10122              case 'inis':
10123              case 'isoir49':
10124                  return 'INIS';
10125  
10126              case 'csiso50inis8':
10127              case 'inis8':
10128              case 'isoir50':
10129                  return 'INIS-8';
10130  
10131              case 'csiso51iniscyrillic':
10132              case 'iniscyrillic':
10133              case 'isoir51':
10134                  return 'INIS-cyrillic';
10135  
10136              case 'csinvariant':
10137              case 'invariant':
10138                  return 'INVARIANT';
10139  
10140              case 'iso2022cn':
10141                  return 'ISO-2022-CN';
10142  
10143              case 'iso2022cnext':
10144                  return 'ISO-2022-CN-EXT';
10145  
10146              case 'csiso2022jp':
10147              case 'iso2022jp':
10148                  return 'ISO-2022-JP';
10149  
10150              case 'csiso2022jp2':
10151              case 'iso2022jp2':
10152                  return 'ISO-2022-JP-2';
10153  
10154              case 'csiso2022kr':
10155              case 'iso2022kr':
10156                  return 'ISO-2022-KR';
10157  
10158              case 'cswindows30latin1':
10159              case 'iso88591windows30latin1':
10160                  return 'ISO-8859-1-Windows-3.0-Latin-1';
10161  
10162              case 'cswindows31latin1':
10163              case 'iso88591windows31latin1':
10164                  return 'ISO-8859-1-Windows-3.1-Latin-1';
10165  
10166              case 'csisolatin2':
10167              case 'iso88592':
10168              case 'iso885921987':
10169              case 'isoir101':
10170              case 'l2':
10171              case 'latin2':
10172                  return 'ISO-8859-2';
10173  
10174              case 'cswindows31latin2':
10175              case 'iso88592windowslatin2':
10176                  return 'ISO-8859-2-Windows-Latin-2';
10177  
10178              case 'csisolatin3':
10179              case 'iso88593':
10180              case 'iso885931988':
10181              case 'isoir109':
10182              case 'l3':
10183              case 'latin3':
10184                  return 'ISO-8859-3';
10185  
10186              case 'csisolatin4':
10187              case 'iso88594':
10188              case 'iso885941988':
10189              case 'isoir110':
10190              case 'l4':
10191              case 'latin4':
10192                  return 'ISO-8859-4';
10193  
10194              case 'csisolatincyrillic':
10195              case 'cyrillic':
10196              case 'iso88595':
10197              case 'iso885951988':
10198              case 'isoir144':
10199                  return 'ISO-8859-5';
10200  
10201              case 'arabic':
10202              case 'asmo708':
10203              case 'csisolatinarabic':
10204              case 'ecma114':
10205              case 'iso88596':
10206              case 'iso885961987':
10207              case 'isoir127':
10208                  return 'ISO-8859-6';
10209  
10210              case 'csiso88596e':
10211              case 'iso88596e':
10212                  return 'ISO-8859-6-E';
10213  
10214              case 'csiso88596i':
10215              case 'iso88596i':
10216                  return 'ISO-8859-6-I';
10217  
10218              case 'csisolatingreek':
10219              case 'ecma118':
10220              case 'elot928':
10221              case 'greek':
10222              case 'greek8':
10223              case 'iso88597':
10224              case 'iso885971987':
10225              case 'isoir126':
10226                  return 'ISO-8859-7';
10227  
10228              case 'csisolatinhebrew':
10229              case 'hebrew':
10230              case 'iso88598':
10231              case 'iso885981988':
10232              case 'isoir138':
10233                  return 'ISO-8859-8';
10234  
10235              case 'csiso88598e':
10236              case 'iso88598e':
10237                  return 'ISO-8859-8-E';
10238  
10239              case 'csiso88598i':
10240              case 'iso88598i':
10241                  return 'ISO-8859-8-I';
10242  
10243              case 'cswindows31latin5':
10244              case 'iso88599windowslatin5':
10245                  return 'ISO-8859-9-Windows-Latin-5';
10246  
10247              case 'csisolatin6':
10248              case 'iso885910':
10249              case 'iso8859101992':
10250              case 'isoir157':
10251              case 'l6':
10252              case 'latin6':
10253                  return 'ISO-8859-10';
10254  
10255              case 'iso885913':
10256                  return 'ISO-8859-13';
10257  
10258              case 'iso885914':
10259              case 'iso8859141998':
10260              case 'isoceltic':
10261              case 'isoir199':
10262              case 'l8':
10263              case 'latin8':
10264                  return 'ISO-8859-14';
10265  
10266              case 'iso885915':
10267              case 'latin9':
10268                  return 'ISO-8859-15';
10269  
10270              case 'iso885916':
10271              case 'iso8859162001':
10272              case 'isoir226':
10273              case 'l10':
10274              case 'latin10':
10275                  return 'ISO-8859-16';
10276  
10277              case 'iso10646j1':
10278                  return 'ISO-10646-J-1';
10279  
10280              case 'csunicode':
10281              case 'iso10646ucs2':
10282                  return 'ISO-10646-UCS-2';
10283  
10284              case 'csucs4':
10285              case 'iso10646ucs4':
10286                  return 'ISO-10646-UCS-4';
10287  
10288              case 'csunicodeascii':
10289              case 'iso10646ucsbasic':
10290                  return 'ISO-10646-UCS-Basic';
10291  
10292              case 'csunicodelatin1':
10293              case 'iso10646':
10294              case 'iso10646unicodelatin1':
10295                  return 'ISO-10646-Unicode-Latin1';
10296  
10297              case 'csiso10646utf1':
10298              case 'iso10646utf1':
10299                  return 'ISO-10646-UTF-1';
10300  
10301              case 'csiso115481':
10302              case 'iso115481':
10303              case 'isotr115481':
10304                  return 'ISO-11548-1';
10305  
10306              case 'csiso90':
10307              case 'isoir90':
10308                  return 'iso-ir-90';
10309  
10310              case 'csunicodeibm1261':
10311              case 'isounicodeibm1261':
10312                  return 'ISO-Unicode-IBM-1261';
10313  
10314              case 'csunicodeibm1264':
10315              case 'isounicodeibm1264':
10316                  return 'ISO-Unicode-IBM-1264';
10317  
10318              case 'csunicodeibm1265':
10319              case 'isounicodeibm1265':
10320                  return 'ISO-Unicode-IBM-1265';
10321  
10322              case 'csunicodeibm1268':
10323              case 'isounicodeibm1268':
10324                  return 'ISO-Unicode-IBM-1268';
10325  
10326              case 'csunicodeibm1276':
10327              case 'isounicodeibm1276':
10328                  return 'ISO-Unicode-IBM-1276';
10329  
10330              case 'csiso646basic1983':
10331              case 'iso646basic1983':
10332              case 'ref':
10333                  return 'ISO_646.basic:1983';
10334  
10335              case 'csiso2intlrefversion':
10336              case 'irv':
10337              case 'iso646irv1983':
10338              case 'isoir2':
10339                  return 'ISO_646.irv:1983';
10340  
10341              case 'csiso2033':
10342              case 'e13b':
10343              case 'iso20331983':
10344              case 'isoir98':
10345                  return 'ISO_2033-1983';
10346  
10347              case 'csiso5427cyrillic':
10348              case 'iso5427':
10349              case 'isoir37':
10350                  return 'ISO_5427';
10351  
10352              case 'iso5427cyrillic1981':
10353              case 'iso54271981':
10354              case 'isoir54':
10355                  return 'ISO_5427:1981';
10356  
10357              case 'csiso5428greek':
10358              case 'iso54281980':
10359              case 'isoir55':
10360                  return 'ISO_5428:1980';
10361  
10362              case 'csiso6937add':
10363              case 'iso6937225':
10364              case 'isoir152':
10365                  return 'ISO_6937-2-25';
10366  
10367              case 'csisotextcomm':
10368              case 'iso69372add':
10369              case 'isoir142':
10370                  return 'ISO_6937-2-add';
10371  
10372              case 'csiso8859supp':
10373              case 'iso8859supp':
10374              case 'isoir154':
10375              case 'latin125':
10376                  return 'ISO_8859-supp';
10377  
10378              case 'csiso10367box':
10379              case 'iso10367box':
10380              case 'isoir155':
10381                  return 'ISO_10367-box';
10382  
10383              case 'csiso15italian':
10384              case 'iso646it':
10385              case 'isoir15':
10386              case 'it':
10387                  return 'IT';
10388  
10389              case 'csiso13jisc6220jp':
10390              case 'isoir13':
10391              case 'jisc62201969':
10392              case 'jisc62201969jp':
10393              case 'katakana':
10394              case 'x2017':
10395                  return 'JIS_C6220-1969-jp';
10396  
10397              case 'csiso14jisc6220ro':
10398              case 'iso646jp':
10399              case 'isoir14':
10400              case 'jisc62201969ro':
10401              case 'jp':
10402                  return 'JIS_C6220-1969-ro';
10403  
10404              case 'csiso42jisc62261978':
10405              case 'isoir42':
10406              case 'jisc62261978':
10407                  return 'JIS_C6226-1978';
10408  
10409              case 'csiso87jisx208':
10410              case 'isoir87':
10411              case 'jisc62261983':
10412              case 'jisx2081983':
10413              case 'x208':
10414                  return 'JIS_C6226-1983';
10415  
10416              case 'csiso91jisc62291984a':
10417              case 'isoir91':
10418              case 'jisc62291984a':
10419              case 'jpocra':
10420                  return 'JIS_C6229-1984-a';
10421  
10422              case 'csiso92jisc62991984b':
10423              case 'iso646jpocrb':
10424              case 'isoir92':
10425              case 'jisc62291984b':
10426              case 'jpocrb':
10427                  return 'JIS_C6229-1984-b';
10428  
10429              case 'csiso93jis62291984badd':
10430              case 'isoir93':
10431              case 'jisc62291984badd':
10432              case 'jpocrbadd':
10433                  return 'JIS_C6229-1984-b-add';
10434  
10435              case 'csiso94jis62291984hand':
10436              case 'isoir94':
10437              case 'jisc62291984hand':
10438              case 'jpocrhand':
10439                  return 'JIS_C6229-1984-hand';
10440  
10441              case 'csiso95jis62291984handadd':
10442              case 'isoir95':
10443              case 'jisc62291984handadd':
10444              case 'jpocrhandadd':
10445                  return 'JIS_C6229-1984-hand-add';
10446  
10447              case 'csiso96jisc62291984kana':
10448              case 'isoir96':
10449              case 'jisc62291984kana':
10450                  return 'JIS_C6229-1984-kana';
10451  
10452              case 'csjisencoding':
10453              case 'jisencoding':
10454                  return 'JIS_Encoding';
10455  
10456              case 'cshalfwidthkatakana':
10457              case 'jisx201':
10458              case 'x201':
10459                  return 'JIS_X0201';
10460  
10461              case 'csiso159jisx2121990':
10462              case 'isoir159':
10463              case 'jisx2121990':
10464              case 'x212':
10465                  return 'JIS_X0212-1990';
10466  
10467              case 'csiso141jusib1002':
10468              case 'iso646yu':
10469              case 'isoir141':
10470              case 'js':
10471              case 'jusib1002':
10472              case 'yu':
10473                  return 'JUS_I.B1.002';
10474  
10475              case 'csiso147macedonian':
10476              case 'isoir147':
10477              case 'jusib1003mac':
10478              case 'macedonian':
10479                  return 'JUS_I.B1.003-mac';
10480  
10481              case 'csiso146serbian':
10482              case 'isoir146':
10483              case 'jusib1003serb':
10484              case 'serbian':
10485                  return 'JUS_I.B1.003-serb';
10486  
10487              case 'koi7switched':
10488                  return 'KOI7-switched';
10489  
10490              case 'cskoi8r':
10491              case 'koi8r':
10492                  return 'KOI8-R';
10493  
10494              case 'koi8u':
10495                  return 'KOI8-U';
10496  
10497              case 'csksc5636':
10498              case 'iso646kr':
10499              case 'ksc5636':
10500                  return 'KSC5636';
10501  
10502              case 'cskz1048':
10503              case 'kz1048':
10504              case 'rk1048':
10505              case 'strk10482002':
10506                  return 'KZ-1048';
10507  
10508              case 'csiso19latingreek':
10509              case 'isoir19':
10510              case 'latingreek':
10511                  return 'latin-greek';
10512  
10513              case 'csiso27latingreek1':
10514              case 'isoir27':
10515              case 'latingreek1':
10516                  return 'Latin-greek-1';
10517  
10518              case 'csiso158lap':
10519              case 'isoir158':
10520              case 'lap':
10521              case 'latinlap':
10522                  return 'latin-lap';
10523  
10524              case 'csmacintosh':
10525              case 'mac':
10526              case 'macintosh':
10527                  return 'macintosh';
10528  
10529              case 'csmicrosoftpublishing':
10530              case 'microsoftpublishing':
10531                  return 'Microsoft-Publishing';
10532  
10533              case 'csmnem':
10534              case 'mnem':
10535                  return 'MNEM';
10536  
10537              case 'csmnemonic':
10538              case 'mnemonic':
10539                  return 'MNEMONIC';
10540  
10541              case 'csiso86hungarian':
10542              case 'hu':
10543              case 'iso646hu':
10544              case 'isoir86':
10545              case 'msz77953':
10546                  return 'MSZ_7795.3';
10547  
10548              case 'csnatsdano':
10549              case 'isoir91':
10550              case 'natsdano':
10551                  return 'NATS-DANO';
10552  
10553              case 'csnatsdanoadd':
10554              case 'isoir92':
10555              case 'natsdanoadd':
10556                  return 'NATS-DANO-ADD';
10557  
10558              case 'csnatssefi':
10559              case 'isoir81':
10560              case 'natssefi':
10561                  return 'NATS-SEFI';
10562  
10563              case 'csnatssefiadd':
10564              case 'isoir82':
10565              case 'natssefiadd':
10566                  return 'NATS-SEFI-ADD';
10567  
10568              case 'csiso151cuba':
10569              case 'cuba':
10570              case 'iso646cu':
10571              case 'isoir151':
10572              case 'ncnc1081':
10573                  return 'NC_NC00-10:81';
10574  
10575              case 'csiso69french':
10576              case 'fr':
10577              case 'iso646fr':
10578              case 'isoir69':
10579              case 'nfz62010':
10580                  return 'NF_Z_62-010';
10581  
10582              case 'csiso25french':
10583              case 'iso646fr1':
10584              case 'isoir25':
10585              case 'nfz620101973':
10586                  return 'NF_Z_62-010_(1973)';
10587  
10588              case 'csiso60danishnorwegian':
10589              case 'csiso60norwegian1':
10590              case 'iso646no':
10591              case 'isoir60':
10592              case 'no':
10593              case 'ns45511':
10594                  return 'NS_4551-1';
10595  
10596              case 'csiso61norwegian2':
10597              case 'iso646no2':
10598              case 'isoir61':
10599              case 'no2':
10600              case 'ns45512':
10601                  return 'NS_4551-2';
10602  
10603              case 'osdebcdicdf3irv':
10604                  return 'OSD_EBCDIC_DF03_IRV';
10605  
10606              case 'osdebcdicdf41':
10607                  return 'OSD_EBCDIC_DF04_1';
10608  
10609              case 'osdebcdicdf415':
10610                  return 'OSD_EBCDIC_DF04_15';
10611  
10612              case 'cspc8danishnorwegian':
10613              case 'pc8danishnorwegian':
10614                  return 'PC8-Danish-Norwegian';
10615  
10616              case 'cspc8turkish':
10617              case 'pc8turkish':
10618                  return 'PC8-Turkish';
10619  
10620              case 'csiso16portuguese':
10621              case 'iso646pt':
10622              case 'isoir16':
10623              case 'pt':
10624                  return 'PT';
10625  
10626              case 'csiso84portuguese2':
10627              case 'iso646pt2':
10628              case 'isoir84':
10629              case 'pt2':
10630                  return 'PT2';
10631  
10632              case 'cp154':
10633              case 'csptcp154':
10634              case 'cyrillicasian':
10635              case 'pt154':
10636              case 'ptcp154':
10637                  return 'PTCP154';
10638  
10639              case 'scsu':
10640                  return 'SCSU';
10641  
10642              case 'csiso10swedish':
10643              case 'fi':
10644              case 'iso646fi':
10645              case 'iso646se':
10646              case 'isoir10':
10647              case 'se':
10648              case 'sen850200b':
10649                  return 'SEN_850200_B';
10650  
10651              case 'csiso11swedishfornames':
10652              case 'iso646se2':
10653              case 'isoir11':
10654              case 'se2':
10655              case 'sen850200c':
10656                  return 'SEN_850200_C';
10657  
10658              case 'csiso102t617bit':
10659              case 'isoir102':
10660              case 't617bit':
10661                  return 'T.61-7bit';
10662  
10663              case 'csiso103t618bit':
10664              case 'isoir103':
10665              case 't61':
10666              case 't618bit':
10667                  return 'T.61-8bit';
10668  
10669              case 'csiso128t101g2':
10670              case 'isoir128':
10671              case 't101g2':
10672                  return 'T.101-G2';
10673  
10674              case 'cstscii':
10675              case 'tscii':
10676                  return 'TSCII';
10677  
10678              case 'csunicode11':
10679              case 'unicode11':
10680                  return 'UNICODE-1-1';
10681  
10682              case 'csunicode11utf7':
10683              case 'unicode11utf7':
10684                  return 'UNICODE-1-1-UTF-7';
10685  
10686              case 'csunknown8bit':
10687              case 'unknown8bit':
10688                  return 'UNKNOWN-8BIT';
10689  
10690              case 'ansix341968':
10691              case 'ansix341986':
10692              case 'ascii':
10693              case 'cp367':
10694              case 'csascii':
10695              case 'ibm367':
10696              case 'iso646irv1991':
10697              case 'iso646us':
10698              case 'isoir6':
10699              case 'us':
10700              case 'usascii':
10701                  return 'US-ASCII';
10702  
10703              case 'csusdk':
10704              case 'usdk':
10705                  return 'us-dk';
10706  
10707              case 'utf7':
10708                  return 'UTF-7';
10709  
10710              case 'utf8':
10711                  return 'UTF-8';
10712  
10713              case 'utf16':
10714                  return 'UTF-16';
10715  
10716              case 'utf16be':
10717                  return 'UTF-16BE';
10718  
10719              case 'utf16le':
10720                  return 'UTF-16LE';
10721  
10722              case 'utf32':
10723                  return 'UTF-32';
10724  
10725              case 'utf32be':
10726                  return 'UTF-32BE';
10727  
10728              case 'utf32le':
10729                  return 'UTF-32LE';
10730  
10731              case 'csventurainternational':
10732              case 'venturainternational':
10733                  return 'Ventura-International';
10734  
10735              case 'csventuramath':
10736              case 'venturamath':
10737                  return 'Ventura-Math';
10738  
10739              case 'csventuraus':
10740              case 'venturaus':
10741                  return 'Ventura-US';
10742  
10743              case 'csiso70videotexsupp1':
10744              case 'isoir70':
10745              case 'videotexsuppl':
10746                  return 'videotex-suppl';
10747  
10748              case 'csviqr':
10749              case 'viqr':
10750                  return 'VIQR';
10751  
10752              case 'csviscii':
10753              case 'viscii':
10754                  return 'VISCII';
10755  
10756              case 'csshiftjis':
10757              case 'cswindows31j':
10758              case 'mskanji':
10759              case 'shiftjis':
10760              case 'windows31j':
10761                  return 'Windows-31J';
10762  
10763              case 'iso885911':
10764              case 'tis620':
10765                  return 'windows-874';
10766  
10767              case 'cseuckr':
10768              case 'csksc56011987':
10769              case 'euckr':
10770              case 'isoir149':
10771              case 'korean':
10772              case 'ksc5601':
10773              case 'ksc56011987':
10774              case 'ksc56011989':
10775              case 'windows949':
10776                  return 'windows-949';
10777  
10778              case 'windows1250':
10779                  return 'windows-1250';
10780  
10781              case 'windows1251':
10782                  return 'windows-1251';
10783  
10784              case 'cp819':
10785              case 'csisolatin1':
10786              case 'ibm819':
10787              case 'iso88591':
10788              case 'iso885911987':
10789              case 'isoir100':
10790              case 'l1':
10791              case 'latin1':
10792              case 'windows1252':
10793                  return 'windows-1252';
10794  
10795              case 'windows1253':
10796                  return 'windows-1253';
10797  
10798              case 'csisolatin5':
10799              case 'iso88599':
10800              case 'iso885991989':
10801              case 'isoir148':
10802              case 'l5':
10803              case 'latin5':
10804              case 'windows1254':
10805                  return 'windows-1254';
10806  
10807              case 'windows1255':
10808                  return 'windows-1255';
10809  
10810              case 'windows1256':
10811                  return 'windows-1256';
10812  
10813              case 'windows1257':
10814                  return 'windows-1257';
10815  
10816              case 'windows1258':
10817                  return 'windows-1258';
10818  
10819              default:
10820                  return $charset;
10821          }
10822      }
10823  
10824  	function get_curl_version()
10825      {
10826          if (is_array($curl = curl_version()))
10827          {
10828              $curl = $curl['version'];
10829          }
10830          elseif (substr($curl, 0, 5) === 'curl/')
10831          {
10832              $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10833          }
10834          elseif (substr($curl, 0, 8) === 'libcurl/')
10835          {
10836              $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10837          }
10838          else
10839          {
10840              $curl = 0;
10841          }
10842          return $curl;
10843      }
10844  
10845  	function is_subclass_of($class1, $class2)
10846      {
10847          if (func_num_args() !== 2)
10848          {
10849              trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10850          }
10851          elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10852          {
10853              return is_subclass_of($class1, $class2);
10854          }
10855          elseif (is_string($class1) && is_string($class2))
10856          {
10857              if (class_exists($class1))
10858              {
10859                  if (class_exists($class2))
10860                  {
10861                      $class2 = strtolower($class2);
10862                      while ($class1 = strtolower(get_parent_class($class1)))
10863                      {
10864                          if ($class1 === $class2)
10865                          {
10866                              return true;
10867                          }
10868                      }
10869                  }
10870              }
10871              else
10872              {
10873                  trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10874              }
10875          }
10876          return false;
10877      }
10878  
10879      /**
10880       * Strip HTML comments
10881       *
10882       * @access public
10883       * @param string $data Data to strip comments from
10884       * @return string Comment stripped string
10885       */
10886  	function strip_comments($data)
10887      {
10888          $output = '';
10889          while (($start = strpos($data, '<!--')) !== false)
10890          {
10891              $output .= substr($data, 0, $start);
10892              if (($end = strpos($data, '-->', $start)) !== false)
10893              {
10894                  $data = substr_replace($data, '', 0, $end + 3);
10895              }
10896              else
10897              {
10898                  $data = '';
10899              }
10900          }
10901          return $output . $data;
10902      }
10903  
10904  	function parse_date($dt)
10905      {
10906          $parser = SimplePie_Parse_Date::get();
10907          return $parser->parse($dt);
10908      }
10909  
10910      /**
10911       * Decode HTML entities
10912       *
10913       * @static
10914       * @access public
10915       * @param string $data Input data
10916       * @return string Output data
10917       */
10918  	function entities_decode($data)
10919      {
10920          $decoder = new SimplePie_Decode_HTML_Entities($data);
10921          return $decoder->parse();
10922      }
10923  
10924      /**
10925       * Remove RFC822 comments
10926       *
10927       * @access public
10928       * @param string $data Data to strip comments from
10929       * @return string Comment stripped string
10930       */
10931  	function uncomment_rfc822($string)
10932      {
10933          $string = (string) $string;
10934          $position = 0;
10935          $length = strlen($string);
10936          $depth = 0;
10937  
10938          $output = '';
10939  
10940          while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10941          {
10942              $output .= substr($string, $position, $pos - $position);
10943              $position = $pos + 1;
10944              if ($string[$pos - 1] !== '\\')
10945              {
10946                  $depth++;
10947                  while ($depth && $position < $length)
10948                  {
10949                      $position += strcspn($string, '()', $position);
10950                      if ($string[$position - 1] === '\\')
10951                      {
10952                          $position++;
10953                          continue;
10954                      }
10955                      elseif (isset($string[$position]))
10956                      {
10957                          switch ($string[$position])
10958                          {
10959                              case '(':
10960                                  $depth++;
10961                                  break;
10962  
10963                              case ')':
10964                                  $depth--;
10965                                  break;
10966                          }
10967                          $position++;
10968                      }
10969                      else
10970                      {
10971                          break;
10972                      }
10973                  }
10974              }
10975              else
10976              {
10977                  $output .= '(';
10978              }
10979          }
10980          $output .= substr($string, $position);
10981  
10982          return $output;
10983      }
10984  
10985  	function parse_mime($mime)
10986      {
10987          if (($pos = strpos($mime, ';')) === false)
10988          {
10989              return trim($mime);
10990          }
10991          else
10992          {
10993              return trim(substr($mime, 0, $pos));
10994          }
10995      }
10996  
10997  	function htmlspecialchars_decode($string, $quote_style)
10998      {
10999          if (function_exists('htmlspecialchars_decode'))
11000          {
11001              return htmlspecialchars_decode($string, $quote_style);
11002          }
11003          else
11004          {
11005              return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
11006          }
11007      }
11008  
11009  	function atom_03_construct_type($attribs)
11010      {
11011          if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
11012          {
11013              $mode = SIMPLEPIE_CONSTRUCT_BASE64;
11014          }
11015          else
11016          {
11017              $mode = SIMPLEPIE_CONSTRUCT_NONE;
11018          }
11019          if (isset($attribs['']['type']))
11020          {
11021              switch (strtolower(trim($attribs['']['type'])))
11022              {
11023                  case 'text':
11024                  case 'text/plain':
11025                      return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
11026  
11027                  case 'html':
11028                  case 'text/html':
11029                      return SIMPLEPIE_CONSTRUCT_HTML | $mode;
11030  
11031                  case 'xhtml':
11032                  case 'application/xhtml+xml':
11033                      return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
11034  
11035                  default:
11036                      return SIMPLEPIE_CONSTRUCT_NONE | $mode;
11037              }
11038          }
11039          else
11040          {
11041              return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
11042          }
11043      }
11044  
11045  	function atom_10_construct_type($attribs)
11046      {
11047          if (isset($attribs['']['type']))
11048          {
11049              switch (strtolower(trim($attribs['']['type'])))
11050              {
11051                  case 'text':
11052                      return SIMPLEPIE_CONSTRUCT_TEXT;
11053  
11054                  case 'html':
11055                      return SIMPLEPIE_CONSTRUCT_HTML;
11056  
11057                  case 'xhtml':
11058                      return SIMPLEPIE_CONSTRUCT_XHTML;
11059  
11060                  default:
11061                      return SIMPLEPIE_CONSTRUCT_NONE;
11062              }
11063          }
11064          return SIMPLEPIE_CONSTRUCT_TEXT;
11065      }
11066  
11067  	function atom_10_content_construct_type($attribs)
11068      {
11069          if (isset($attribs['']['type']))
11070          {
11071              $type = strtolower(trim($attribs['']['type']));
11072              switch ($type)
11073              {
11074                  case 'text':
11075                      return SIMPLEPIE_CONSTRUCT_TEXT;
11076  
11077                  case 'html':
11078                      return SIMPLEPIE_CONSTRUCT_HTML;
11079  
11080                  case 'xhtml':
11081                      return SIMPLEPIE_CONSTRUCT_XHTML;
11082              }
11083              if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
11084              {
11085                  return SIMPLEPIE_CONSTRUCT_NONE;
11086              }
11087              else
11088              {
11089                  return SIMPLEPIE_CONSTRUCT_BASE64;
11090              }
11091          }
11092          else
11093          {
11094              return SIMPLEPIE_CONSTRUCT_TEXT;
11095          }
11096      }
11097  
11098  	function is_isegment_nz_nc($string)
11099      {
11100          return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
11101      }
11102  
11103  	function space_seperated_tokens($string)
11104      {
11105          $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
11106          $string_length = strlen($string);
11107  
11108          $position = strspn($string, $space_characters);
11109          $tokens = array();
11110  
11111          while ($position < $string_length)
11112          {
11113              $len = strcspn($string, $space_characters, $position);
11114              $tokens[] = substr($string, $position, $len);
11115              $position += $len;
11116              $position += strspn($string, $space_characters, $position);
11117          }
11118  
11119          return $tokens;
11120      }
11121  
11122  	function array_unique($array)
11123      {
11124          if (version_compare(PHP_VERSION, '5.2', '>='))
11125          {
11126              return array_unique($array);
11127          }
11128          else
11129          {
11130              $array = (array) $array;
11131              $new_array = array();
11132              $new_array_strings = array();
11133              foreach ($array as $key => $value)
11134              {
11135                  if (is_object($value))
11136                  {
11137                      if (method_exists($value, '__toString'))
11138                      {
11139                          $cmp = $value->__toString();
11140                      }
11141                      else
11142                      {
11143                          trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
11144                      }
11145                  }
11146                  elseif (is_array($value))
11147                  {
11148                      $cmp = (string) reset($value);
11149                  }
11150                  else
11151                  {
11152                      $cmp = (string) $value;
11153                  }
11154                  if (!in_array($cmp, $new_array_strings))
11155                  {
11156                      $new_array[$key] = $value;
11157                      $new_array_strings[] = $cmp;
11158                  }
11159              }
11160              return $new_array;
11161          }
11162      }
11163  
11164      /**
11165       * Converts a unicode codepoint to a UTF-8 character
11166       *
11167       * @static
11168       * @access public
11169       * @param int $codepoint Unicode codepoint
11170       * @return string UTF-8 character
11171       */
11172  	function codepoint_to_utf8($codepoint)
11173      {
11174          $codepoint = (int) $codepoint;
11175          if ($codepoint < 0)
11176          {
11177              return false;
11178          }
11179          else if ($codepoint <= 0x7f)
11180          {
11181              return chr($codepoint);
11182          }
11183          else if ($codepoint <= 0x7ff)
11184          {
11185              return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
11186          }
11187          else if ($codepoint <= 0xffff)
11188          {
11189              return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11190          }
11191          else if ($codepoint <= 0x10ffff)
11192          {
11193              return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11194          }
11195          else
11196          {
11197              // U+FFFD REPLACEMENT CHARACTER
11198              return "\xEF\xBF\xBD";
11199          }
11200      }
11201  
11202      /**
11203       * Re-implementation of PHP 5's stripos()
11204       *
11205       * Returns the numeric position of the first occurrence of needle in the
11206       * haystack string.
11207       *
11208       * @static
11209       * @access string
11210       * @param object $haystack
11211       * @param string $needle Note that the needle may be a string of one or more
11212       *     characters. If needle is not a string, it is converted to an integer
11213       *     and applied as the ordinal value of a character.
11214       * @param int $offset The optional offset parameter allows you to specify which
11215       *     character in haystack to start searching. The position returned is still
11216       *     relative to the beginning of haystack.
11217       * @return bool If needle is not found, stripos() will return boolean false.
11218       */
11219  	function stripos($haystack, $needle, $offset = 0)
11220      {
11221          if (function_exists('stripos'))
11222          {
11223              return stripos($haystack, $needle, $offset);
11224          }
11225          else
11226          {
11227              if (is_string($needle))
11228              {
11229                  $needle = strtolower($needle);
11230              }
11231              elseif (is_int($needle) || is_bool($needle) || is_double($needle))
11232              {
11233                  $needle = strtolower(chr($needle));
11234              }
11235              else
11236              {
11237                  trigger_error('needle is not a string or an integer', E_USER_WARNING);
11238                  return false;
11239              }
11240  
11241              return strpos(strtolower($haystack), $needle, $offset);
11242          }
11243      }
11244  
11245      /**
11246       * Similar to parse_str()
11247       *
11248       * Returns an associative array of name/value pairs, where the value is an
11249       * array of values that have used the same name
11250       *
11251       * @static
11252       * @access string
11253       * @param string $str The input string.
11254       * @return array
11255       */
11256  	function parse_str($str)
11257      {
11258          $return = array();
11259          $str = explode('&', $str);
11260  
11261          foreach ($str as $section)
11262          {
11263              if (strpos($section, '=') !== false)
11264              {
11265                  list($name, $value) = explode('=', $section, 2);
11266                  $return[urldecode($name)][] = urldecode($value);
11267              }
11268              else
11269              {
11270                  $return[urldecode($section)][] = null;
11271              }
11272          }
11273  
11274          return $return;
11275      }
11276  
11277      /**
11278       * Detect XML encoding, as per XML 1.0 Appendix F.1
11279       *
11280       * @todo Add support for EBCDIC
11281       * @param string $data XML data
11282       * @return array Possible encodings
11283       */
11284  	function xml_encoding($data)
11285      {
11286          // UTF-32 Big Endian BOM
11287          if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
11288          {
11289              $encoding[] = 'UTF-32BE';
11290          }
11291          // UTF-32 Little Endian BOM
11292          elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
11293          {
11294              $encoding[] = 'UTF-32LE';
11295          }
11296          // UTF-16 Big Endian BOM
11297          elseif (substr($data, 0, 2) === "\xFE\xFF")
11298          {
11299              $encoding[] = 'UTF-16BE';
11300          }
11301          // UTF-16 Little Endian BOM
11302          elseif (substr($data, 0, 2) === "\xFF\xFE")
11303          {
11304              $encoding[] = 'UTF-16LE';
11305          }
11306          // UTF-8 BOM
11307          elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
11308          {
11309              $encoding[] = 'UTF-8';
11310          }
11311          // UTF-32 Big Endian Without BOM
11312          elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
11313          {
11314              if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
11315              {
11316                  $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
11317                  if ($parser->parse())
11318                  {
11319                      $encoding[] = $parser->encoding;
11320                  }
11321              }
11322              $encoding[] = 'UTF-32BE';
11323          }
11324          // UTF-32 Little Endian Without BOM
11325          elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
11326          {
11327              if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
11328              {
11329                  $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
11330                  if ($parser->parse())
11331                  {
11332                      $encoding[] = $parser->encoding;
11333                  }
11334              }
11335              $encoding[] = 'UTF-32LE';
11336          }
11337          // UTF-16 Big Endian Without BOM
11338          elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
11339          {
11340              if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
11341              {
11342                  $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
11343                  if ($parser->parse())
11344                  {
11345                      $encoding[] = $parser->encoding;
11346                  }
11347              }
11348              $encoding[] = 'UTF-16BE';
11349          }
11350          // UTF-16 Little Endian Without BOM
11351          elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
11352          {
11353              if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
11354              {
11355                  $parser = new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
11356                  if ($parser->parse())
11357                  {
11358                      $encoding[] = $parser->encoding;
11359                  }
11360              }
11361              $encoding[] = 'UTF-16LE';
11362          }
11363          // US-ASCII (or superset)
11364          elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11365          {
11366              if ($pos = strpos($data, "\x3F\x3E"))
11367              {
11368                  $parser = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11369                  if ($parser->parse())
11370                  {
11371                      $encoding[] = $parser->encoding;
11372                  }
11373              }
11374              $encoding[] = 'UTF-8';
11375          }
11376          // Fallback to UTF-8
11377          else
11378          {
11379              $encoding[] = 'UTF-8';
11380          }
11381          return $encoding;
11382      }
11383  
11384  	function output_javascript()
11385      {
11386          if (function_exists('ob_gzhandler'))
11387          {
11388              ob_start('ob_gzhandler');
11389          }
11390          header('Content-type: text/javascript; charset: UTF-8');
11391          header('Cache-Control: must-revalidate');
11392          header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
11393          ?>
11394  function embed_odeo(link) {
11395      document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');
11396  }
11397  
11398  function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
11399      if (placeholder != '') {
11400          document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
11401      }
11402      else {
11403          document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
11404      }
11405  }
11406  
11407  function embed_flash(bgcolor, width, height, link, loop, type) {
11408      document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');
11409  }
11410  
11411  function embed_flv(width, height, link, placeholder, loop, player) {
11412      document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');
11413  }
11414  
11415  function embed_wmedia(width, height, link) {
11416      document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
11417  }
11418          <?php
11419      }
11420  
11421  
11422  
11423      /**
11424       * Format debugging information
11425       */
11426  	function debug($sp)
11427      {
11428          $info = 'SimplePie ' . SIMPLEPIE_VERSION . ' Build ' . SIMPLEPIE_BUILD . "\n";
11429          $info .= 'PHP ' . PHP_VERSION . "\n";
11430          if ($sp->error() !== null)
11431          {
11432              $info .= 'Error occurred: ' . $sp->error() . "\n";
11433          }
11434          else
11435          {
11436              $info .= "No error found.\n";
11437          }
11438          $info .= "Extensions:\n";
11439          $extensions = array('pcre', 'curl', 'zlib', 'mbstring', 'iconv', 'xmlreader', 'xml');
11440          foreach ($extensions as $ext)
11441          {
11442              if (extension_loaded($ext))
11443              {
11444                  $info .= "    $ext loaded\n";
11445                  switch ($ext)
11446                  {
11447                      case 'pcre':
11448                          $info .= '      Version ' . PCRE_VERSION . "\n";
11449                          break;
11450                      case 'curl':
11451                          $version = curl_version();
11452                          $info .= '      Version ' . $version['version'] . "\n";
11453                          break;
11454                      case 'mbstring':
11455                          $info .= '      Overloading: ' . mb_get_info('func_overload') . "\n";
11456                          break;
11457                      case 'iconv':
11458                          $info .= '      Version ' . ICONV_VERSION . "\n";
11459                          break;
11460                      case 'xml':
11461                          $info .= '      Version ' . LIBXML_DOTTED_VERSION . "\n";
11462                          break;
11463                  }
11464              }
11465              else
11466              {
11467                  $info .= "    $ext not loaded\n";
11468              }
11469          }
11470          return $info;
11471      }
11472  }
11473  
11474  /**
11475   * Decode HTML Entities
11476   *
11477   * This implements HTML5 as of revision 967 (2007-06-28)
11478   *
11479   * @package SimplePie
11480   */
11481  class SimplePie_Decode_HTML_Entities
11482  {
11483      /**
11484       * Data to be parsed
11485       *
11486       * @access private
11487       * @var string
11488       */
11489      var $data = '';
11490  
11491      /**
11492       * Currently consumed bytes
11493       *
11494       * @access private
11495       * @var string
11496       */
11497      var $consumed = '';
11498  
11499      /**
11500       * Position of the current byte being parsed
11501       *
11502       * @access private
11503       * @var int
11504       */
11505      var $position = 0;
11506  
11507      /**
11508       * Create an instance of the class with the input data
11509       *
11510       * @access public
11511       * @param string $data Input data
11512       */
11513  	function SimplePie_Decode_HTML_Entities($data)
11514      {
11515          $this->data = $data;
11516      }
11517  
11518      /**
11519       * Parse the input data
11520       *
11521       * @access public
11522       * @return string Output data
11523       */
11524  	function parse()
11525      {
11526          while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11527          {
11528              $this->consume();
11529              $this->entity();
11530              $this->consumed = '';
11531          }
11532          return $this->data;
11533      }
11534  
11535      /**
11536       * Consume the next byte
11537       *
11538       * @access private
11539       * @return mixed The next byte, or false, if there is no more data
11540       */
11541  	function consume()
11542      {
11543          if (isset($this->data[$this->position]))
11544          {
11545              $this->consumed .= $this->data[$this->position];
11546              return $this->data[$this->position++];
11547          }
11548          else
11549          {
11550              return false;
11551          }
11552      }
11553  
11554      /**
11555       * Consume a range of characters
11556       *
11557       * @access private
11558       * @param string $chars Characters to consume
11559       * @return mixed A series of characters that match the range, or false
11560       */
11561  	function consume_range($chars)
11562      {
11563          if ($len = strspn($this->data, $chars, $this->position))
11564          {
11565              $data = substr($this->data, $this->position, $len);
11566              $this->consumed .= $data;
11567              $this->position += $len;
11568              return $data;
11569          }
11570          else
11571          {
11572              return false;
11573          }
11574      }
11575  
11576      /**
11577       * Unconsume one byte
11578       *
11579       * @access private
11580       */
11581  	function unconsume()
11582      {
11583          $this->consumed = substr($this->consumed, 0, -1);
11584          $this->position--;
11585      }
11586  
11587      /**
11588       * Decode an entity
11589       *
11590       * @access private
11591       */
11592  	function entity()
11593      {
11594          switch ($this->consume())
11595          {
11596              case "\x09":
11597              case "\x0A":
11598              case "\x0B":
11599              case "\x0B":
11600              case "\x0C":
11601              case "\x20":
11602              case "\x3C":
11603              case "\x26":
11604              case false:
11605                  break;
11606  
11607              case "\x23":
11608                  switch ($this->consume())
11609                  {
11610                      case "\x78":
11611                      case "\x58":
11612                          $range = '0123456789ABCDEFabcdef';
11613                          $hex = true;
11614                          break;
11615  
11616                      default:
11617                          $range = '0123456789';
11618                          $hex = false;
11619                          $this->unconsume();
11620                          break;
11621                  }
11622  
11623                  if ($codepoint = $this->consume_range($range))
11624                  {
11625                      static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
11626  
11627                      if ($hex)
11628                      {
11629                          $codepoint = hexdec($codepoint);
11630                      }
11631                      else
11632                      {
11633                          $codepoint = intval($codepoint);
11634                      }
11635  
11636                      if (isset($windows_1252_specials[$codepoint]))
11637                      {
11638                          $replacement = $windows_1252_specials[$codepoint];
11639                      }
11640                      else
11641                      {
11642                          $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11643                      }
11644  
11645                      if (!in_array($this->consume(), array(';', false), true))
11646                      {
11647                          $this->unconsume();
11648                      }
11649  
11650                      $consumed_length = strlen($this->consumed);
11651                      $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11652                      $this->position += strlen($replacement) - $consumed_length;
11653                  }
11654                  break;
11655  
11656              default:
11657                  static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C");
11658  
11659                  for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11660                  {
11661                      $consumed = substr($this->consumed, 1);
11662                      if (isset($entities[$consumed]))
11663                      {
11664                          $match = $consumed;
11665                      }
11666                  }
11667  
11668                  if ($match !== null)
11669                  {
11670                       $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11671                      $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11672                  }
11673                  break;
11674          }
11675      }
11676  }
11677  
11678  /**
11679   * IRI parser/serialiser
11680   *
11681   * @package SimplePie
11682   */
11683  class SimplePie_IRI
11684  {
11685      /**
11686       * Scheme
11687       *
11688       * @access private
11689       * @var string
11690       */
11691      var $scheme;
11692  
11693      /**
11694       * User Information
11695       *
11696       * @access private
11697       * @var string
11698       */
11699      var $userinfo;
11700  
11701      /**
11702       * Host
11703       *
11704       * @access private
11705       * @var string
11706       */
11707      var $host;
11708  
11709      /**
11710       * Port
11711       *
11712       * @access private
11713       * @var string
11714       */
11715      var $port;
11716  
11717      /**
11718       * Path
11719       *
11720       * @access private
11721       * @var string
11722       */
11723      var $path;
11724  
11725      /**
11726       * Query
11727       *
11728       * @access private
11729       * @var string
11730       */
11731      var $query;
11732  
11733      /**
11734       * Fragment
11735       *
11736       * @access private
11737       * @var string
11738       */
11739      var $fragment;
11740  
11741      /**
11742       * Whether the object represents a valid IRI
11743       *
11744       * @access private
11745       * @var array
11746       */
11747      var $valid = array();
11748  
11749      /**
11750       * Return the entire IRI when you try and read the object as a string
11751       *
11752       * @access public
11753       * @return string
11754       */
11755  	function __toString()
11756      {
11757          return $this->get_iri();
11758      }
11759  
11760      /**
11761       * Create a new IRI object, from a specified string
11762       *
11763       * @access public
11764       * @param string $iri
11765       * @return SimplePie_IRI
11766       */
11767  	function SimplePie_IRI($iri)
11768      {
11769          $iri = (string) $iri;
11770          if ($iri !== '')
11771          {
11772              $parsed = $this->parse_iri($iri);
11773              $this->set_scheme($parsed['scheme']);
11774              $this->set_authority($parsed['authority']);
11775              $this->set_path($parsed['path']);
11776              $this->set_query($parsed['query']);
11777              $this->set_fragment($parsed['fragment']);
11778          }
11779      }
11780  
11781      /**
11782       * Create a new IRI object by resolving a relative IRI
11783       *
11784       * @static
11785       * @access public
11786       * @param SimplePie_IRI $base Base IRI
11787       * @param string $relative Relative IRI
11788       * @return SimplePie_IRI
11789       */
11790  	function absolutize($base, $relative)
11791      {
11792          $relative = (string) $relative;
11793          if ($relative !== '')
11794          {
11795              $relative = new SimplePie_IRI($relative);
11796              if ($relative->get_scheme() !== null)
11797              {
11798                  $target = $relative;
11799              }
11800              elseif ($base->get_iri() !== null)
11801              {
11802                  if ($relative->get_authority() !== null)
11803                  {
11804                      $target = $relative;
11805                      $target->set_scheme($base->get_scheme());
11806                  }
11807                  else
11808                  {
11809                      $target = new SimplePie_IRI('');
11810                      $target->set_scheme($base->get_scheme());
11811                      $target->set_userinfo($base->get_userinfo());
11812                      $target->set_host($base->get_host());
11813                      $target->set_port($base->get_port());
11814                      if ($relative->get_path() !== null)
11815                      {
11816                          if (strpos($relative->get_path(), '/') === 0)
11817                          {
11818                              $target->set_path($relative->get_path());
11819                          }
11820                          elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
11821                          {
11822                              $target->set_path('/' . $relative->get_path());
11823                          }
11824                          elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
11825                          {
11826                              $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
11827                          }
11828                          else
11829                          {
11830                              $target->set_path($relative->get_path());
11831                          }
11832                          $target->set_query($relative->get_query());
11833                      }
11834                      else
11835                      {
11836                          $target->set_path($base->get_path());
11837                          if ($relative->get_query() !== null)
11838                          {
11839                              $target->set_query($relative->get_query());
11840                          }
11841                          elseif ($base->get_query() !== null)
11842                          {
11843                              $target->set_query($base->get_query());
11844                          }
11845                      }
11846                  }
11847                  $target->set_fragment($relative->get_fragment());
11848              }
11849              else
11850              {
11851                  // No base URL, just return the relative URL
11852                  $target = $relative;
11853              }
11854          }
11855          else
11856          {
11857              $target = $base;
11858          }
11859          return $target;
11860      }
11861  
11862      /**
11863       * Parse an IRI into scheme/authority/path/query/fragment segments
11864       *
11865       * @access private
11866       * @param string $iri
11867       * @return array
11868       */
11869  	function parse_iri($iri)
11870      {
11871          preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
11872          for ($i = count($match); $i <= 9; $i++)
11873          {
11874              $match[$i] = '';
11875          }
11876          return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
11877      }
11878  
11879      /**
11880       * Remove dot segments from a path
11881       *
11882       * @access private
11883       * @param string $input
11884       * @return string
11885       */
11886  	function remove_dot_segments($input)
11887      {
11888          $output = '';
11889          while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
11890          {
11891              // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
11892              if (strpos($input, '../') === 0)
11893              {
11894                  $input = substr($input, 3);
11895              }
11896              elseif (strpos($input, './') === 0)
11897              {
11898                  $input = substr($input, 2);
11899              }
11900              // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
11901              elseif (strpos($input, '/./') === 0)
11902              {
11903                  $input = substr_replace($input, '/', 0, 3);
11904              }
11905              elseif ($input === '/.')
11906              {
11907                  $input = '/';
11908              }
11909              // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
11910              elseif (strpos($input, '/../') === 0)
11911              {
11912                  $input = substr_replace($input, '/', 0, 4);
11913                  $output = substr_replace($output, '', strrpos($output, '/'));
11914              }
11915              elseif ($input === '/..')
11916              {
11917                  $input = '/';
11918                  $output = substr_replace($output, '', strrpos($output, '/'));
11919              }
11920              // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
11921              elseif ($input === '.' || $input === '..')
11922              {
11923                  $input = '';
11924              }
11925              // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
11926              elseif (($pos = strpos($input, '/', 1)) !== false)
11927              {
11928                  $output .= substr($input, 0, $pos);
11929                  $input = substr_replace($input, '', 0, $pos);
11930              }
11931              else
11932              {
11933                  $output .= $input;
11934                  $input = '';
11935              }
11936          }
11937          return $output . $input;
11938      }
11939  
11940      /**
11941       * Replace invalid character with percent encoding
11942       *
11943       * @param string $string Input string
11944       * @param string $valid_chars Valid characters
11945       * @param int $case Normalise case
11946       * @return string
11947       */
11948  	function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE, $iprivate = false)
11949      {
11950          // Normalize as many pct-encoded sections as possible
11951          $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array(&$this, 'remove_iunreserved_percent_encoded'), $string);
11952  
11953          // Replace invalid percent characters
11954          $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
11955  
11956          // Add unreserved and % to $valid_chars (the latter is safe because all
11957          // pct-encoded sections are now valid).
11958          $valid_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
11959  
11960          // Now replace any bytes that aren't allowed with their pct-encoded versions
11961          $position = 0;
11962          $strlen = strlen($string);
11963          while (($position += strspn($string, $valid_chars, $position)) < $strlen)
11964          {
11965              $value = ord($string[$position]);
11966  
11967              // Start position
11968              $start = $position;
11969  
11970              // By default we are valid
11971              $valid = true;
11972  
11973              // No one byte sequences are valid due to the while.
11974              // Two byte sequence:
11975              if (($value & 0xE0) === 0xC0)
11976              {
11977                  $character = ($value & 0x1F) << 6;
11978                  $length = 2;
11979                  $remaining = 1;
11980              }
11981              // Three byte sequence:
11982              elseif (($value & 0xF0) === 0xE0)
11983              {
11984                  $character = ($value & 0x0F) << 12;
11985                  $length = 3;
11986                  $remaining = 2;
11987              }
11988              // Four byte sequence:
11989              elseif (($value & 0xF8) === 0xF0)
11990              {
11991                  $character = ($value & 0x07) << 18;
11992                  $length = 4;
11993                  $remaining = 3;
11994              }
11995              // Invalid byte:
11996              else
11997              {
11998                  $valid = false;
11999                  $length = 1;
12000                  $remaining = 0;
12001              }
12002  
12003              if ($remaining)
12004              {
12005                  if ($position + $length <= $strlen)
12006                  {
12007                      for ($position++; $remaining; $position++)
12008                      {
12009                          $value = ord($string[$position]);
12010  
12011                          // Check that the byte is valid, then add it to the character:
12012                          if (($value & 0xC0) === 0x80)
12013                          {
12014                              $character |= ($value & 0x3F) << (--$remaining * 6);
12015                          }
12016                          // If it is invalid, count the sequence as invalid and reprocess the current byte:
12017                          else
12018                          {
12019                              $valid = false;
12020                              $position--;
12021                              break;
12022                          }
12023                      }
12024                  }
12025                  else
12026                  {
12027                      $position = $strlen - 1;
12028                      $valid = false;
12029                  }
12030              }
12031  
12032              // Percent encode anything invalid or not in ucschar
12033              if (
12034                  // Invalid sequences
12035                  !$valid
12036                  // Non-shortest form sequences are invalid
12037                  || $length > 1 && $character <= 0x7F
12038                  || $length > 2 && $character <= 0x7FF
12039                  || $length > 3 && $character <= 0xFFFF
12040                  // Outside of range of ucschar codepoints
12041                  // Noncharacters
12042                  || ($character & 0xFFFE) === 0xFFFE
12043                  || $character >= 0xFDD0 && $character <= 0xFDEF
12044                  || (
12045                      // Everything else not in ucschar
12046                         $character > 0xD7FF && $character < 0xF900
12047                      || $character < 0xA0
12048                      || $character > 0xEFFFD
12049                  )
12050                  && (
12051                      // Everything not in iprivate, if it applies
12052                         !$iprivate
12053                      || $character < 0xE000
12054                      || $character > 0x10FFFD
12055                  )
12056              )
12057              {
12058                  // If we were a character, pretend we weren't, but rather an error.
12059                  if ($valid)
12060                      $position--;
12061  
12062                  for ($j = $start; $j <= $position; $j++)
12063                  {
12064                      $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
12065                      $j += 2;
12066                      $position += 2;
12067                      $strlen += 2;
12068                  }
12069              }
12070          }
12071  
12072          // Normalise case
12073          if ($case & SIMPLEPIE_LOWERCASE)
12074          {
12075              $string = strtolower($string);
12076          }
12077          elseif ($case & SIMPLEPIE_UPPERCASE)
12078          {
12079              $string = strtoupper($string);
12080          }
12081  
12082          return $string;
12083      }
12084  
12085      /**
12086       * Callback function for preg_replace_callback.
12087       *
12088       * Removes sequences of percent encoded bytes that represent UTF-8
12089       * encoded characters in iunreserved
12090       *
12091       * @access private
12092       * @param array $match PCRE match
12093       * @return string Replacement
12094       */
12095  	function remove_iunreserved_percent_encoded($match)
12096      {
12097          // As we just have valid percent encoded sequences we can just explode
12098          // and ignore the first member of the returned array (an empty string).
12099          $bytes = explode('%', $match[0]);
12100  
12101          // Initialize the new string (this is what will be returned) and that
12102          // there are no bytes remaining in the current sequence (unsurprising
12103          // at the first byte!).
12104          $string = '';
12105          $remaining = 0;
12106  
12107          // Loop over each and every byte, and set $value to its value
12108          for ($i = 1, $len = count($bytes); $i < $len; $i++)
12109          {
12110              $value = hexdec($bytes[$i]);
12111  
12112              // If we're the first byte of sequence:
12113              if (!$remaining)
12114              {
12115                  // Start position
12116                  $start = $i;
12117  
12118                  // By default we are valid
12119                  $valid = true;
12120  
12121                  // One byte sequence:
12122                  if ($value <= 0x7F)
12123                  {
12124                      $character = $value;
12125                      $length = 1;
12126                  }
12127                  // Two byte sequence:
12128                  elseif (($value & 0xE0) === 0xC0)
12129                  {
12130                      $character = ($value & 0x1F) << 6;
12131                      $length = 2;
12132                      $remaining = 1;
12133                  }
12134                  // Three byte sequence:
12135                  elseif (($value & 0xF0) === 0xE0)
12136                  {
12137                      $character = ($value & 0x0F) << 12;
12138                      $length = 3;
12139                      $remaining = 2;
12140                  }
12141                  // Four byte sequence:
12142                  elseif (($value & 0xF8) === 0xF0)
12143                  {
12144                      $character = ($value & 0x07) << 18;
12145                      $length = 4;
12146                      $remaining = 3;
12147                  }
12148                  // Invalid byte:
12149                  else
12150                  {
12151                      $valid = false;
12152                      $remaining = 0;
12153                  }
12154              }
12155              // Continuation byte:
12156              else
12157              {
12158                  // Check that the byte is valid, then add it to the character:
12159                  if (($value & 0xC0) === 0x80)
12160                  {
12161                      $remaining--;
12162                      $character |= ($value & 0x3F) << ($remaining * 6);
12163                  }
12164                  // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
12165                  else
12166                  {
12167                      $valid = false;
12168                      $remaining = 0;
12169                      $i--;
12170                  }
12171              }
12172  
12173              // If we've reached the end of the current byte sequence, append it to Unicode::$data
12174              if (!$remaining)
12175              {
12176                  // Percent encode anything invalid or not in iunreserved
12177                  if (
12178                      // Invalid sequences
12179                      !$valid
12180                      // Non-shortest form sequences are invalid
12181                      || $length > 1 && $character <= 0x7F
12182                      || $length > 2 && $character <= 0x7FF
12183                      || $length > 3 && $character <= 0xFFFF
12184                      // Outside of range of iunreserved codepoints
12185                      || $character < 0x2D
12186                      || $character > 0xEFFFD
12187                      // Noncharacters
12188                      || ($character & 0xFFFE) === 0xFFFE
12189                      || $character >= 0xFDD0 && $character <= 0xFDEF
12190                      // Everything else not in iunreserved (this is all BMP)
12191                      || $character === 0x2F
12192                      || $character > 0x39 && $character < 0x41
12193                      || $character > 0x5A && $character < 0x61
12194                      || $character > 0x7A && $character < 0x7E
12195                      || $character > 0x7E && $character < 0xA0
12196                      || $character > 0xD7FF && $character < 0xF900
12197                  )
12198                  {
12199                      for ($j = $start; $j <= $i; $j++)
12200                      {
12201                          $string .= '%' . strtoupper($bytes[$j]);
12202                      }
12203                  }
12204                  else
12205                  {
12206                      for ($j = $start; $j <= $i; $j++)
12207                      {
12208                          $string .= chr(hexdec($bytes[$j]));
12209                      }
12210                  }
12211              }
12212          }
12213  
12214          // If we have any bytes left over they are invalid (i.e., we are
12215          // mid-way through a multi-byte sequence)
12216          if ($remaining)
12217          {
12218              for ($j = $start; $j < $len; $j++)
12219              {
12220                  $string .= '%' . strtoupper($bytes[$j]);
12221              }
12222          }
12223  
12224          return $string;
12225      }
12226  
12227      /**
12228       * Check if the object represents a valid IRI
12229       *
12230       * @access public
12231       * @return bool
12232       */
12233  	function is_valid()
12234      {
12235          return array_sum($this->valid) === count($this->valid);
12236      }
12237  
12238      /**
12239       * Set the scheme. Returns true on success, false on failure (if there are
12240       * any invalid characters).
12241       *
12242       * @access public
12243       * @param string $scheme
12244       * @return bool
12245       */
12246  	function set_scheme($scheme)
12247      {
12248          if ($scheme === null || $scheme === '')
12249          {
12250              $this->scheme = null;
12251          }
12252          else
12253          {
12254              $len = strlen($scheme);
12255              switch (true)
12256              {
12257                  case $len > 1:
12258                      if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
12259                      {
12260                          $this->scheme = null;
12261                          $this->valid[__FUNCTION__] = false;
12262                          return false;
12263                      }
12264  
12265                  case $len > 0:
12266                      if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
12267                      {
12268                          $this->scheme = null;
12269                          $this->valid[__FUNCTION__] = false;
12270                          return false;
12271                      }
12272              }
12273              $this->scheme = strtolower($scheme);
12274          }
12275          $this->valid[__FUNCTION__] = true;
12276          return true;
12277      }
12278  
12279      /**
12280       * Set the authority. Returns true on success, false on failure (if there are
12281       * any invalid characters).
12282       *
12283       * @access public
12284       * @param string $authority
12285       * @return bool
12286       */
12287  	function set_authority($authority)
12288      {
12289          if (($userinfo_end = strrpos($authority, '@')) !== false)
12290          {
12291              $userinfo = substr($authority, 0, $userinfo_end);
12292              $authority = substr($authority, $userinfo_end + 1);
12293          }
12294          else
12295          {
12296              $userinfo = null;
12297          }
12298  
12299          if (($port_start = strpos($authority, ':')) !== false)
12300          {
12301              $port = substr($authority, $port_start + 1);
12302              $authority = substr($authority, 0, $port_start);
12303          }
12304          else
12305          {
12306              $port = null;
12307          }
12308  
12309          return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
12310      }
12311  
12312      /**
12313       * Set the userinfo.
12314       *
12315       * @access public
12316       * @param string $userinfo
12317       * @return bool
12318       */
12319  	function set_userinfo($userinfo)
12320      {
12321          if ($userinfo === null || $userinfo === '')
12322          {
12323              $this->userinfo = null;
12324          }
12325          else
12326          {
12327              $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
12328          }
12329          $this->valid[__FUNCTION__] = true;
12330          return true;
12331      }
12332  
12333      /**
12334       * Set the host. Returns true on success, false on failure (if there are
12335       * any invalid characters).
12336       *
12337       * @access public
12338       * @param string $host
12339       * @return bool
12340       */
12341  	function set_host($host)
12342      {
12343          if ($host === null || $host === '')
12344          {
12345              $this->host = null;
12346              $this->valid[__FUNCTION__] = true;
12347              return true;
12348          }
12349          elseif ($host[0] === '[' && substr($host, -1) === ']')
12350          {
12351              if (Net_IPv6::checkIPv6(substr($host, 1, -1)))
12352              {
12353                  $this->host = $host;
12354                  $this->valid[__FUNCTION__] = true;
12355                  return true;
12356              }
12357              else
12358              {
12359                  $this->host = null;
12360                  $this->valid[__FUNCTION__] = false;
12361                  return false;
12362              }
12363          }
12364          else
12365          {
12366              $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
12367              $this->valid[__FUNCTION__] = true;
12368              return true;
12369          }
12370      }
12371  
12372      /**
12373       * Set the port. Returns true on success, false on failure (if there are
12374       * any invalid characters).
12375       *
12376       * @access public
12377       * @param string $port
12378       * @return bool
12379       */
12380  	function set_port($port)
12381      {
12382          if ($port === null || $port === '')
12383          {
12384              $this->port = null;
12385              $this->valid[__FUNCTION__] = true;
12386              return true;
12387          }
12388          elseif (strspn($port, '0123456789') === strlen($port))
12389          {
12390              $this->port = (int) $port;
12391              $this->valid[__FUNCTION__] = true;
12392              return true;
12393          }
12394          else
12395          {
12396              $this->port = null;
12397              $this->valid[__FUNCTION__] = false;
12398              return false;
12399          }
12400      }
12401  
12402      /**
12403       * Set the path.
12404       *
12405       * @access public
12406       * @param string $path
12407       * @return bool
12408       */
12409  	function set_path($path)
12410      {
12411          if ($path === null || $path === '')
12412          {
12413              $this->path = null;
12414              $this->valid[__FUNCTION__] = true;
12415              return true;
12416          }
12417          elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
12418          {
12419              $this->path = null;
12420              $this->valid[__FUNCTION__] = false;
12421              return false;
12422          }
12423          else
12424          {
12425              $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
12426              if ($this->scheme !== null)
12427              {
12428                  $this->path = $this->remove_dot_segments($this->path);
12429              }
12430              $this->valid[__FUNCTION__] = true;
12431              return true;
12432          }
12433      }
12434  
12435      /**
12436       * Set the query.
12437       *
12438       * @access public
12439       * @param string $query
12440       * @return bool
12441       */
12442  	function set_query($query)
12443      {
12444          if ($query === null || $query === '')
12445          {
12446              $this->query = null;
12447          }
12448          else
12449          {
12450              $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?&=');
12451          }
12452          $this->valid[__FUNCTION__] = true;
12453          return true;
12454      }
12455  
12456      /**
12457       * Set the fragment.
12458       *
12459       * @access public
12460       * @param string $fragment
12461       * @return bool
12462       */
12463  	function set_fragment($fragment)
12464      {
12465          if ($fragment === null || $fragment === '')
12466          {
12467              $this->fragment = null;
12468          }
12469          else
12470          {
12471              $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
12472          }
12473          $this->valid[__FUNCTION__] = true;
12474          return true;
12475      }
12476  
12477      /**
12478       * Get the complete IRI
12479       *
12480       * @access public
12481       * @return string
12482       */
12483  	function get_iri()
12484      {
12485          $iri = '';
12486          if ($this->scheme !== null)
12487          {
12488              $iri .= $this->scheme . ':';
12489          }
12490          if (($authority = $this->get_authority()) !== null)
12491          {
12492              $iri .= '//' . $authority;
12493          }
12494          if ($this->path !== null)
12495          {
12496              $iri .= $this->path;
12497          }
12498          if ($this->query !== null)
12499          {
12500              $iri .= '?' . $this->query;
12501          }
12502          if ($this->fragment !== null)
12503          {
12504              $iri .= '#' . $this->fragment;
12505          }
12506  
12507          if ($iri !== '')
12508          {
12509              return $iri;
12510          }
12511          else
12512          {
12513              return null;
12514          }
12515      }
12516  
12517      /**
12518       * Get the scheme
12519       *
12520       * @access public
12521       * @return string
12522       */
12523  	function get_scheme()
12524      {
12525          return $this->scheme;
12526      }
12527  
12528      /**
12529       * Get the complete authority
12530       *
12531       * @access public
12532       * @return string
12533       */
12534  	function get_authority()
12535      {
12536          $authority = '';
12537          if ($this->userinfo !== null)
12538          {
12539              $authority .= $this->userinfo . '@';
12540          }
12541          if ($this->host !== null)
12542          {
12543              $authority .= $this->host;
12544          }
12545          if ($this->port !== null)
12546          {
12547              $authority .= ':' . $this->port;
12548          }
12549  
12550          if ($authority !== '')
12551          {
12552              return $authority;
12553          }
12554          else
12555          {
12556              return null;
12557          }
12558      }
12559  
12560      /**
12561       * Get the user information
12562       *
12563       * @access public
12564       * @return string
12565       */
12566  	function get_userinfo()
12567      {
12568          return $this->userinfo;
12569      }
12570  
12571      /**
12572       * Get the host
12573       *
12574       * @access public
12575       * @return string
12576       */
12577  	function get_host()
12578      {
12579          return $this->host;
12580      }
12581  
12582      /**
12583       * Get the port
12584       *
12585       * @access public
12586       * @return string
12587       */
12588  	function get_port()
12589      {
12590          return $this->port;
12591      }
12592  
12593      /**
12594       * Get the path
12595       *
12596       * @access public
12597       * @return string
12598       */
12599  	function get_path()
12600      {
12601          return $this->path;
12602      }
12603  
12604      /**
12605       * Get the query
12606       *
12607       * @access public
12608       * @return string
12609       */
12610  	function get_query()
12611      {
12612          return $this->query;
12613      }
12614  
12615      /**
12616       * Get the fragment
12617       *
12618       * @access public
12619       * @return string
12620       */
12621  	function get_fragment()
12622      {
12623          return $this->fragment;
12624      }
12625  }
12626  
12627  /**
12628   * Class to validate and to work with IPv6 addresses.
12629   *
12630   * @package SimplePie
12631   * @copyright 2003-2005 The PHP Group
12632   * @license http://www.opensource.org/licenses/bsd-license.php
12633   * @link http://pear.php.net/package/Net_IPv6
12634   * @author Alexander Merz <alexander.merz@web.de>
12635   * @author elfrink at introweb dot nl
12636   * @author Josh Peck <jmp at joshpeck dot org>
12637   * @author Geoffrey Sneddon <geoffers@gmail.com>
12638   */
12639  class SimplePie_Net_IPv6
12640  {
12641      /**
12642       * Removes a possible existing netmask specification of an IP address.
12643       *
12644       * @param string $ip the (compressed) IP as Hex representation
12645       * @return string the IP the without netmask
12646       * @since 1.1.0
12647       * @access public
12648       * @static
12649       */
12650  	function removeNetmaskSpec($ip)
12651      {
12652          if (strpos($ip, '/') !== false)
12653          {
12654              list($addr, $nm) = explode('/', $ip);
12655          }
12656          else
12657          {
12658              $addr = $ip;
12659          }
12660          return $addr;
12661      }
12662  
12663      /**
12664       * Uncompresses an IPv6 address
12665       *
12666       * RFC 2373 allows you to compress zeros in an address to '::'. This
12667       * function expects an valid IPv6 address and expands the '::' to
12668       * the required zeros.
12669       *
12670       * Example:     FF01::101    ->    FF01:0:0:0:0:0:0:101
12671       *             ::1        ->    0:0:0:0:0:0:0:1
12672       *
12673       * @access public
12674       * @static
12675       * @param string $ip a valid IPv6-address (hex format)
12676       * @return string the uncompressed IPv6-address (hex format)
12677       */
12678  	function Uncompress($ip)
12679      {
12680          $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
12681          $c1 = -1;
12682          $c2 = -1;
12683          if (strpos($ip, '::') !== false)
12684          {
12685              list($ip1, $ip2) = explode('::', $ip);
12686              if ($ip1 === '')
12687              {
12688                  $c1 = -1;
12689              }
12690              else
12691              {
12692                  $pos = 0;
12693                  if (($pos = substr_count($ip1, ':')) > 0)
12694                  {
12695                      $c1 = $pos;
12696                  }
12697                  else
12698                  {
12699                      $c1 = 0;
12700                  }
12701              }
12702              if ($ip2 === '')
12703              {
12704                  $c2 = -1;
12705              }
12706              else
12707              {
12708                  $pos = 0;
12709                  if (($pos = substr_count($ip2, ':')) > 0)
12710                  {
12711                      $c2 = $pos;
12712                  }
12713                  else
12714                  {
12715                      $c2 = 0;
12716                  }
12717              }
12718              if (strstr($ip2, '.'))
12719              {
12720                  $c2++;
12721              }
12722              // ::
12723              if ($c1 === -1 && $c2 === -1)
12724              {
12725                  $uip = '0:0:0:0:0:0:0:0';
12726              }
12727              // ::xxx
12728              else if ($c1 === -1)
12729              {
12730                  $fill = str_repeat('0:', 7 - $c2);
12731                  $uip =    str_replace('::', $fill, $uip);
12732              }
12733              // xxx::
12734              else if ($c2 === -1)
12735              {
12736                  $fill = str_repeat(':0', 7 - $c1);
12737                  $uip =    str_replace('::', $fill, $uip);
12738              }
12739              // xxx::xxx
12740              else
12741              {
12742                  $fill = str_repeat(':0:', 6 - $c2 - $c1);
12743                  $uip =    str_replace('::', $fill, $uip);
12744                  $uip =    str_replace('::', ':', $uip);
12745              }
12746          }
12747          return $uip;
12748      }
12749  
12750      /**
12751       * Splits an IPv6 address into the IPv6 and a possible IPv4 part
12752       *
12753       * RFC 2373 allows you to note the last two parts of an IPv6 address as
12754       * an IPv4 compatible address
12755       *
12756       * Example:     0:0:0:0:0:0:13.1.68.3
12757       *             0:0:0:0:0:FFFF:129.144.52.38
12758       *
12759       * @access public
12760       * @static
12761       * @param string $ip a valid IPv6-address (hex format)
12762       * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
12763       */
12764  	function SplitV64($ip)
12765      {
12766          $ip = SimplePie_Net_IPv6::Uncompress($ip);
12767          if (strstr($ip, '.'))
12768          {
12769              $pos = strrpos($ip, ':');
12770              $ip[$pos] = '_';
12771              $ipPart = explode('_', $ip);
12772              return $ipPart;
12773          }
12774          else
12775          {
12776              return array($ip, '');
12777          }
12778      }
12779  
12780      /**
12781       * Checks an IPv6 address
12782       *
12783       * Checks if the given IP is IPv6-compatible
12784       *
12785       * @access public
12786       * @static
12787       * @param string $ip a valid IPv6-address
12788       * @return bool true if $ip is an IPv6 address
12789       */
12790  	function checkIPv6($ip)
12791      {
12792          $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
12793          $count = 0;
12794          if (!empty($ipPart[0]))
12795          {
12796              $ipv6 = explode(':', $ipPart[0]);
12797              for ($i = 0; $i < count($ipv6); $i++)
12798              {
12799                  $dec = hexdec($ipv6[$i]);
12800                  $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
12801                  if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
12802                  {
12803                      $count++;
12804                  }
12805              }
12806              if ($count === 8)
12807              {
12808                  return true;
12809              }
12810              elseif ($count === 6 && !empty($ipPart[1]))
12811              {
12812                  $ipv4 = explode('.', $ipPart[1]);
12813                  $count = 0;
12814                  foreach ($ipv4 as $ipv4_part)
12815                  {
12816                      if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
12817                      {
12818                          $count++;
12819                      }
12820                  }
12821                  if ($count === 4)
12822                  {
12823                      return true;
12824                  }
12825              }
12826              else
12827              {
12828                  return false;
12829              }
12830  
12831          }
12832          else
12833          {
12834              return false;
12835          }
12836      }
12837  }
12838  
12839  /**
12840   * Date Parser
12841   *
12842   * @package SimplePie
12843   */
12844  class SimplePie_Parse_Date
12845  {
12846      /**
12847       * Input data
12848       *
12849       * @access protected
12850       * @var string
12851       */
12852      var $date;
12853  
12854      /**
12855       * List of days, calendar day name => ordinal day number in the week
12856       *
12857       * @access protected
12858       * @var array
12859       */
12860      var $day = array(
12861          // English
12862          'mon' => 1,
12863          'monday' => 1,
12864          'tue' => 2,
12865          'tuesday' => 2,
12866          'wed' => 3,
12867          'wednesday' => 3,
12868          'thu' => 4,
12869          'thursday' => 4,
12870          'fri' => 5,
12871          'friday' => 5,
12872          'sat' => 6,
12873          'saturday' => 6,
12874          'sun' => 7,
12875          'sunday' => 7,
12876          // Dutch
12877          'maandag' => 1,
12878          'dinsdag' => 2,
12879          'woensdag' => 3,
12880          'donderdag' => 4,
12881          'vrijdag' => 5,
12882          'zaterdag' => 6,
12883          'zondag' => 7,
12884          // French
12885          'lundi' => 1,
12886          'mardi' => 2,
12887          'mercredi' => 3,
12888          'jeudi' => 4,
12889          'vendredi' => 5,
12890          'samedi' => 6,
12891          'dimanche' => 7,
12892          // German
12893          'montag' => 1,
12894          'dienstag' => 2,
12895          'mittwoch' => 3,
12896          'donnerstag' => 4,
12897          'freitag' => 5,
12898          'samstag' => 6,
12899          'sonnabend' => 6,
12900          'sonntag' => 7,
12901          // Italian
12902          'lunedì' => 1,
12903          'martedì' => 2,
12904          'mercoledì' => 3,
12905          'giovedì' => 4,
12906          'venerdì' => 5,
12907          'sabato' => 6,
12908          'domenica' => 7,
12909          // Spanish
12910          'lunes' => 1,
12911          'martes' => 2,
12912          'miércoles' => 3,
12913          'jueves' => 4,
12914          'viernes' => 5,
12915          'sábado' => 6,
12916          'domingo' => 7,
12917          // Finnish
12918          'maanantai' => 1,
12919          'tiistai' => 2,
12920          'keskiviikko' => 3,
12921          'torstai' => 4,
12922          'perjantai' => 5,
12923          'lauantai' => 6,
12924          'sunnuntai' => 7,
12925          // Hungarian
12926          'hétfő' => 1,
12927          'kedd' => 2,
12928          'szerda' => 3,
12929          'csütörtok' => 4,
12930          'péntek' => 5,
12931          'szombat' => 6,
12932          'vasárnap' => 7,
12933          // Greek
12934          'Δευ' => 1,
12935          'Τρι' => 2,
12936          'Τετ' => 3,
12937          'Πεμ' => 4,
12938          'Παρ' => 5,
12939          'Σαβ' => 6,
12940          'Κυρ' => 7,
12941      );
12942  
12943      /**
12944       * List of months, calendar month name => calendar month number
12945       *
12946       * @access protected
12947       * @var array
12948       */
12949      var $month = array(
12950          // English
12951          'jan' => 1,
12952          'january' => 1,
12953          'feb' => 2,
12954          'february' => 2,
12955          'mar' => 3,
12956          'march' => 3,
12957          'apr' => 4,
12958          'april' => 4,
12959          'may' => 5,
12960          // No long form of May
12961          'jun' => 6,
12962          'june' => 6,
12963          'jul' => 7,
12964          'july' => 7,
12965          'aug' => 8,
12966          'august' => 8,
12967          'sep' => 9,
12968          'september' => 8,
12969          'oct' => 10,
12970          'october' => 10,
12971          'nov' => 11,
12972          'november' => 11,
12973          'dec' => 12,
12974          'december' => 12,
12975          // Dutch
12976          'januari' => 1,
12977          'februari' => 2,
12978          'maart' => 3,
12979          'april' => 4,
12980          'mei' => 5,
12981          'juni' => 6,
12982          'juli' => 7,
12983          'augustus' => 8,
12984          'september' => 9,
12985          'oktober' => 10,
12986          'november' => 11,
12987          'december' => 12,
12988          // French
12989          'janvier' => 1,
12990          'février' => 2,
12991          'mars' => 3,
12992          'avril' => 4,
12993          'mai' => 5,
12994          'juin' => 6,
12995          'juillet' => 7,
12996          'août' => 8,
12997          'septembre' => 9,
12998          'octobre' => 10,
12999          'novembre' => 11,
13000          'décembre' => 12,
13001          // German
13002          'januar' => 1,
13003          'februar' => 2,
13004          'märz' => 3,
13005          'april' => 4,
13006          'mai' => 5,
13007          'juni' => 6,
13008          'juli' => 7,
13009          'august' => 8,
13010          'september' => 9,
13011          'oktober' => 10,
13012          'november' => 11,
13013          'dezember' => 12,
13014          // Italian
13015          'gennaio' => 1,
13016          'febbraio' => 2,
13017          'marzo' => 3,
13018          'aprile' => 4,
13019          'maggio' => 5,
13020          'giugno' => 6,
13021          'luglio' => 7,
13022          'agosto' => 8,
13023          'settembre' => 9,
13024          'ottobre' => 10,
13025          'novembre' => 11,
13026          'dicembre' => 12,
13027          // Spanish
13028          'enero' => 1,
13029          'febrero' => 2,
13030          'marzo' => 3,
13031          'abril' => 4,
13032          'mayo' => 5,
13033          'junio' => 6,
13034          'julio' => 7,
13035          'agosto' => 8,
13036          'septiembre' => 9,
13037          'setiembre' => 9,
13038          'octubre' => 10,
13039          'noviembre' => 11,
13040          'diciembre' => 12,
13041          // Finnish
13042          'tammikuu' => 1,
13043          'helmikuu' => 2,
13044          'maaliskuu' => 3,
13045          'huhtikuu' => 4,
13046          'toukokuu' => 5,
13047          'kesäkuu' => 6,
13048          'heinäkuu' => 7,
13049          'elokuu' => 8,
13050          'suuskuu' => 9,
13051          'lokakuu' => 10,
13052          'marras' => 11,
13053          'joulukuu' => 12,
13054          // Hungarian
13055          'január' => 1,
13056          'február' => 2,
13057          'március' => 3,
13058          'április' => 4,
13059          'május' => 5,
13060          'június' => 6,
13061          'július' => 7,
13062          'augusztus' => 8,
13063          'szeptember' => 9,
13064          'október' => 10,
13065          'november' => 11,
13066          'december' => 12,
13067          // Greek
13068          'Ιαν' => 1,
13069          'Φεβ' => 2,
13070          'Μάώ' => 3,
13071          'Μαώ' => 3,
13072          'Απρ' => 4,
13073          'Μάι' => 5,
13074          'Μαϊ' => 5,
13075          'Μαι' => 5,
13076          'Ιούν' => 6,
13077          'Ιον' => 6,
13078          'Ιούλ' => 7,
13079          'Ιολ' => 7,
13080          'Αύγ' => 8,
13081          'Αυγ' => 8,
13082          'Σεπ' => 9,
13083          'Οκτ' => 10,
13084          'Νοέ' => 11,
13085          'Δεκ' => 12,
13086      );
13087  
13088      /**
13089       * List of timezones, abbreviation => offset from UTC
13090       *
13091       * @access protected
13092       * @var array
13093       */
13094      var $timezone = array(
13095          'ACDT' => 37800,
13096          'ACIT' => 28800,
13097          'ACST' => 34200,
13098          'ACT' => -18000,
13099          'ACWDT' => 35100,
13100          'ACWST' => 31500,
13101          'AEDT' => 39600,
13102          'AEST' => 36000,
13103          'AFT' => 16200,
13104          'AKDT' => -28800,
13105          'AKST' => -32400,
13106          'AMDT' => 18000,
13107          'AMT' => -14400,
13108          'ANAST' => 46800,
13109          'ANAT' => 43200,
13110          'ART' => -10800,
13111          'AZOST' => -3600,
13112          'AZST' => 18000,
13113          'AZT' => 14400,
13114          'BIOT' => 21600,
13115          'BIT' => -43200,
13116          'BOT' => -14400,
13117          'BRST' => -7200,
13118          'BRT' => -10800,
13119          'BST' => 3600,
13120          'BTT' => 21600,
13121          'CAST' => 18000,
13122          'CAT' => 7200,
13123          'CCT' => 23400,
13124          'CDT' => -18000,
13125          'CEDT' => 7200,
13126          'CET' => 3600,
13127          'CGST' => -7200,
13128          'CGT' => -10800,
13129          'CHADT' => 49500,
13130          'CHAST' => 45900,
13131          'CIST' => -28800,
13132          'CKT' => -36000,
13133          'CLDT' => -10800,
13134          'CLST' => -14400,
13135          'COT' => -18000,
13136          'CST' => -21600,
13137          'CVT' => -3600,
13138          'CXT' => 25200,
13139          'DAVT' => 25200,
13140          'DTAT' => 36000,
13141          'EADT' => -18000,
13142          'EAST' => -21600,
13143          'EAT' => 10800,
13144          'ECT' => -18000,
13145          'EDT' => -14400,
13146          'EEST' => 10800,
13147          'EET' => 7200,
13148          'EGT' => -3600,
13149          'EKST' => 21600,
13150          'EST' => -18000,
13151          'FJT' => 43200,
13152          'FKDT' => -10800,
13153          'FKST' => -14400,
13154          'FNT' => -7200,
13155          'GALT' => -21600,
13156          'GEDT' => 14400,
13157          'GEST' => 10800,
13158          'GFT' => -10800,
13159          'GILT' => 43200,
13160          'GIT' => -32400,
13161          'GST' => 14400,
13162          'GST' => -7200,
13163          'GYT' => -14400,
13164          'HAA' => -10800,
13165          'HAC' => -18000,
13166          'HADT' => -32400,
13167          'HAE' => -14400,
13168          'HAP' => -25200,
13169          'HAR' => -21600,
13170          'HAST' => -36000,
13171          'HAT' => -9000,
13172          'HAY' => -28800,
13173          'HKST' => 28800,
13174          'HMT' => 18000,
13175          'HNA' => -14400,
13176          'HNC' => -21600,
13177          'HNE' => -18000,
13178          'HNP' => -28800,
13179          'HNR' => -25200,
13180          'HNT' => -12600,
13181          'HNY' => -32400,
13182          'IRDT' => 16200,
13183          'IRKST' => 32400,
13184          'IRKT' => 28800,
13185          'IRST' => 12600,
13186          'JFDT' => -10800,
13187          'JFST' => -14400,
13188          'JST' => 32400,
13189          'KGST' => 21600,
13190          'KGT' => 18000,
13191          'KOST' => 39600,
13192          'KOVST' => 28800,
13193          'KOVT' => 25200,
13194          'KRAST' => 28800,
13195          'KRAT' => 25200,
13196          'KST' => 32400,
13197          'LHDT' => 39600,
13198          'LHST' => 37800,
13199          'LINT' => 50400,
13200          'LKT' => 21600,
13201          'MAGST' => 43200,
13202          'MAGT' => 39600,
13203          'MAWT' => 21600,
13204          'MDT' => -21600,
13205          'MESZ' => 7200,
13206          'MEZ' => 3600,
13207          'MHT' => 43200,
13208          'MIT' => -34200,
13209          'MNST' => 32400,
13210          'MSDT' => 14400,
13211          'MSST' => 10800,
13212          'MST' => -25200,
13213          'MUT' => 14400,
13214          'MVT' => 18000,
13215          'MYT' => 28800,
13216          'NCT' => 39600,
13217          'NDT' => -9000,
13218          'NFT' => 41400,
13219          'NMIT' => 36000,
13220          'NOVST' => 25200,
13221          'NOVT' => 21600,
13222          'NPT' => 20700,
13223          'NRT' => 43200,
13224          'NST' => -12600,
13225          'NUT' => -39600,
13226          'NZDT' => 46800,
13227          'NZST' => 43200,
13228          'OMSST' => 25200,
13229          'OMST' => 21600,
13230          'PDT' => -25200,
13231          'PET' => -18000,
13232          'PETST' => 46800,
13233          'PETT' => 43200,
13234          'PGT' => 36000,
13235          'PHOT' => 46800,
13236          'PHT' => 28800,
13237          'PKT' => 18000,
13238          'PMDT' => -7200,
13239          'PMST' => -10800,
13240          'PONT' => 39600,
13241          'PST' => -28800,
13242          'PWT' => 32400,
13243          'PYST' => -10800,
13244          'PYT' => -14400,
13245          'RET' => 14400,
13246          'ROTT' => -10800,
13247          'SAMST' => 18000,
13248          'SAMT' => 14400,
13249          'SAST' => 7200,
13250          'SBT' => 39600,
13251          'SCDT' => 46800,
13252          'SCST' => 43200,
13253          'SCT' => 14400,
13254          'SEST' => 3600,
13255          'SGT' => 28800,
13256          'SIT' => 28800,
13257          'SRT' => -10800,
13258          'SST' => -39600,
13259          'SYST' => 10800,
13260          'SYT' => 7200,
13261          'TFT' => 18000,
13262          'THAT' => -36000,
13263          'TJT' => 18000,
13264          'TKT' => -36000,
13265          'TMT' => 18000,
13266          'TOT' => 46800,
13267          'TPT' => 32400,
13268          'TRUT' => 36000,
13269          'TVT' => 43200,
13270          'TWT' => 28800,
13271          'UYST' => -7200,
13272          'UYT' => -10800,
13273          'UZT' => 18000,
13274          'VET' => -14400,
13275          'VLAST' => 39600,
13276          'VLAT' => 36000,
13277          'VOST' => 21600,
13278          'VUT' => 39600,
13279          'WAST' => 7200,
13280          'WAT' => 3600,
13281          'WDT' => 32400,
13282          'WEST' => 3600,
13283          'WFT' => 43200,
13284          'WIB' => 25200,
13285          'WIT' => 32400,
13286          'WITA' => 28800,
13287          'WKST' => 18000,
13288          'WST' => 28800,
13289          'YAKST' => 36000,
13290          'YAKT' => 32400,
13291          'YAPT' => 36000,
13292          'YEKST' => 21600,
13293          'YEKT' => 18000,
13294      );
13295  
13296      /**
13297       * Cached PCRE for SimplePie_Parse_Date::$day
13298       *
13299       * @access protected
13300       * @var string
13301       */
13302      var $day_pcre;
13303  
13304      /**
13305       * Cached PCRE for SimplePie_Parse_Date::$month
13306       *
13307       * @access protected
13308       * @var string
13309       */
13310      var $month_pcre;
13311  
13312      /**
13313       * Array of user-added callback methods
13314       *
13315       * @access private
13316       * @var array
13317       */
13318      var $built_in = array();
13319  
13320      /**
13321       * Array of user-added callback methods
13322       *
13323       * @access private
13324       * @var array
13325       */
13326      var $user = array();
13327  
13328      /**
13329       * Create new SimplePie_Parse_Date object, and set self::day_pcre,
13330       * self::month_pcre, and self::built_in
13331       *
13332       * @access private
13333       */
13334  	function SimplePie_Parse_Date()
13335      {
13336          $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
13337          $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
13338  
13339          static $cache;
13340          if (!isset($cache[get_class($this)]))
13341          {
13342              $all_methods = get_class_methods($this);
13343  
13344              foreach ($all_methods as $method)
13345              {
13346                  if (strtolower(substr($method, 0, 5)) === 'date_')
13347                  {
13348                      $cache[get_class($this)][] = $method;
13349                  }
13350              }
13351          }
13352  
13353          foreach ($cache[get_class($this)] as $method)
13354          {
13355              $this->built_in[] = $method;
13356          }
13357      }
13358  
13359      /**
13360       * Get the object
13361       *
13362       * @access public
13363       */
13364  	function get()
13365      {
13366          static $object;
13367          if (!$object)
13368          {
13369              $object = new SimplePie_Parse_Date;
13370          }
13371          return $object;
13372      }
13373  
13374      /**
13375       * Parse a date
13376       *
13377       * @final
13378       * @access public
13379       * @param string $date Date to parse
13380       * @return int Timestamp corresponding to date string, or false on failure
13381       */
13382  	function parse($date)
13383      {
13384          foreach ($this->user as $method)
13385          {
13386              if (($returned = call_user_func($method, $date)) !== false)
13387              {
13388                  return $returned;
13389              }
13390          }
13391  
13392          foreach ($this->built_in as $method)
13393          {
13394              if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
13395              {
13396                  return $returned;
13397              }
13398          }
13399  
13400          return false;
13401      }
13402  
13403      /**
13404       * Add a callback method to parse a date
13405       *
13406       * @final
13407       * @access public
13408       * @param callback $callback
13409       */
13410  	function add_callback($callback)
13411      {
13412          if (is_callable($callback))
13413          {
13414              $this->user[] = $callback;
13415          }
13416          else
13417          {
13418              trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
13419          }
13420      }
13421  
13422      /**
13423       * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
13424       * well as allowing any of upper or lower case "T", horizontal tabs, or
13425       * spaces to be used as the time seperator (including more than one))
13426       *
13427       * @access protected
13428       * @return int Timestamp
13429       */
13430  	function date_w3cdtf($date)
13431      {
13432          static $pcre;
13433          if (!$pcre)
13434          {
13435              $year = '([0-9]{4})';
13436              $month = $day = $hour = $minute = $second = '([0-9]{2})';
13437              $decimal = '([0-9]*)';
13438              $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
13439              $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
13440          }
13441          if (preg_match($pcre, $date, $match))
13442          {
13443              /*
13444              Capturing subpatterns:
13445              1: Year
13446              2: Month
13447              3: Day
13448              4: Hour
13449              5: Minute
13450              6: Second
13451              7: Decimal fraction of a second
13452              8: Zulu
13453              9: Timezone ±
13454              10: Timezone hours
13455              11: Timezone minutes
13456              */
13457  
13458              // Fill in empty matches
13459              for ($i = count($match); $i <= 3; $i++)
13460              {
13461                  $match[$i] = '1';
13462              }
13463  
13464              for ($i = count($match); $i <= 7; $i++)
13465              {
13466                  $match[$i] = '0';
13467              }
13468  
13469              // Numeric timezone
13470              if (isset($match[9]) && $match[9] !== '')
13471              {
13472                  $timezone = $match[10] * 3600;
13473                  $timezone += $match[11] * 60;
13474                  if ($match[9] === '-')
13475                  {
13476                      $timezone = 0 - $timezone;
13477                  }
13478              }
13479              else
13480              {
13481                  $timezone = 0;
13482              }
13483  
13484              // Convert the number of seconds to an integer, taking decimals into account
13485              $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
13486  
13487              return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
13488          }
13489          else
13490          {
13491              return false;
13492          }
13493      }
13494  
13495      /**
13496       * Remove RFC822 comments
13497       *
13498       * @access protected
13499       * @param string $data Data to strip comments from
13500       * @return string Comment stripped string
13501       */
13502  	function remove_rfc2822_comments($string)
13503      {
13504          $string = (string) $string;
13505          $position = 0;
13506          $length = strlen($string);
13507          $depth = 0;
13508  
13509          $output = '';
13510  
13511          while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
13512          {
13513              $output .= substr($string, $position, $pos - $position);
13514              $position = $pos + 1;
13515              if ($string[$pos - 1] !== '\\')
13516              {
13517                  $depth++;
13518                  while ($depth && $position < $length)
13519                  {
13520                      $position += strcspn($string, '()', $position);
13521                      if ($string[$position - 1] === '\\')
13522                      {
13523                          $position++;
13524                          continue;
13525                      }
13526                      elseif (isset($string[$position]))
13527                      {
13528                          switch ($string[$position])
13529                          {
13530                              case '(':
13531                                  $depth++;
13532                                  break;
13533  
13534                              case ')':
13535                                  $depth--;
13536                                  break;
13537                          }
13538                          $position++;
13539                      }
13540                      else
13541                      {
13542                          break;
13543                      }
13544                  }
13545              }
13546              else
13547              {
13548                  $output .= '(';
13549              }
13550          }
13551          $output .= substr($string, $position);
13552  
13553          return $output;
13554      }
13555  
13556      /**
13557       * Parse RFC2822's date format
13558       *
13559       * @access protected
13560       * @return int Timestamp
13561       */
13562  	function date_rfc2822($date)
13563      {
13564          static $pcre;
13565          if (!$pcre)
13566          {
13567              $wsp = '[\x09\x20]';
13568              $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
13569              $optional_fws = $fws . '?';
13570              $day_name = $this->day_pcre;
13571              $month = $this->month_pcre;
13572              $day = '([0-9]{1,2})';
13573              $hour = $minute = $second = '([0-9]{2})';
13574              $year = '([0-9]{2,4})';
13575              $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
13576              $character_zone = '([A-Z]{1,5})';
13577              $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
13578              $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
13579          }
13580          if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
13581          {
13582              /*
13583              Capturing subpatterns:
13584              1: Day name
13585              2: Day
13586              3: Month
13587              4: Year
13588              5: Hour
13589              6: Minute
13590              7: Second
13591              8: Timezone ±
13592              9: Timezone hours
13593              10: Timezone minutes
13594              11: Alphabetic timezone
13595              */
13596  
13597              // Find the month number
13598              $month = $this->month[strtolower($match[3])];
13599  
13600              // Numeric timezone
13601              if ($match[8] !== '')
13602              {
13603                  $timezone = $match[9] * 3600;
13604                  $timezone += $match[10] * 60;
13605                  if ($match[8] === '-')
13606                  {
13607                      $timezone = 0 - $timezone;
13608                  }
13609              }
13610              // Character timezone
13611              elseif (isset($this->timezone[strtoupper($match[11])]))
13612              {
13613                  $timezone = $this->timezone[strtoupper($match[11])];
13614              }
13615              // Assume everything else to be -0000
13616              else
13617              {
13618                  $timezone = 0;
13619              }
13620  
13621              // Deal with 2/3 digit years
13622              if ($match[4] < 50)
13623              {
13624                  $match[4] += 2000;
13625              }
13626              elseif ($match[4] < 1000)
13627              {
13628                  $match[4] += 1900;
13629              }
13630  
13631              // Second is optional, if it is empty set it to zero
13632              if ($match[7] !== '')
13633              {
13634                  $second = $match[7];
13635              }
13636              else
13637              {
13638                  $second = 0;
13639              }
13640  
13641              return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
13642          }
13643          else
13644          {
13645              return false;
13646          }
13647      }
13648  
13649      /**
13650       * Parse RFC850's date format
13651       *
13652       * @access protected
13653       * @return int Timestamp
13654       */
13655  	function date_rfc850($date)
13656      {
13657          static $pcre;
13658          if (!$pcre)
13659          {
13660              $space = '[\x09\x20]+';
13661              $day_name = $this->day_pcre;
13662              $month = $this->month_pcre;
13663              $day = '([0-9]{1,2})';
13664              $year = $hour = $minute = $second = '([0-9]{2})';
13665              $zone = '([A-Z]{1,5})';
13666              $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
13667          }
13668          if (preg_match($pcre, $date, $match))
13669          {
13670              /*
13671              Capturing subpatterns:
13672              1: Day name
13673              2: Day
13674              3: Month
13675              4: Year
13676              5: Hour
13677              6: Minute
13678              7: Second
13679              8: Timezone
13680              */
13681  
13682              // Month
13683              $month = $this->month[strtolower($match[3])];
13684  
13685              // Character timezone
13686              if (isset($this->timezone[strtoupper($match[8])]))
13687              {
13688                  $timezone = $this->timezone[strtoupper($match[8])];
13689              }
13690              // Assume everything else to be -0000
13691              else
13692              {
13693                  $timezone = 0;
13694              }
13695  
13696              // Deal with 2 digit year
13697              if ($match[4] < 50)
13698              {
13699                  $match[4] += 2000;
13700              }
13701              else
13702              {
13703                  $match[4] += 1900;
13704              }
13705  
13706              return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
13707          }
13708          else
13709          {
13710              return false;
13711          }
13712      }
13713  
13714      /**
13715       * Parse C99's asctime()'s date format
13716       *
13717       * @access protected
13718       * @return int Timestamp
13719       */
13720  	function date_asctime($date)
13721      {
13722          static $pcre;
13723          if (!$pcre)
13724          {
13725              $space = '[\x09\x20]+';
13726              $wday_name = $this->day_pcre;
13727              $mon_name = $this->month_pcre;
13728              $day = '([0-9]{1,2})';
13729              $hour = $sec = $min = '([0-9]{2})';
13730              $year = '([0-9]{4})';
13731              $terminator = '\x0A?\x00?';
13732              $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
13733          }
13734          if (preg_match($pcre, $date, $match))
13735          {
13736              /*
13737              Capturing subpatterns:
13738              1: Day name
13739              2: Month
13740              3: Day
13741              4: Hour
13742              5: Minute
13743              6: Second
13744              7: Year
13745              */
13746  
13747              $month = $this->month[strtolower($match[2])];
13748              return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
13749          }
13750          else
13751          {
13752              return false;
13753          }
13754      }
13755  
13756      /**
13757       * Parse dates using strtotime()
13758       *
13759       * @access protected
13760       * @return int Timestamp
13761       */
13762  	function date_strtotime($date)
13763      {
13764          $strtotime = strtotime($date);
13765          if ($strtotime === -1 || $strtotime === false)
13766          {
13767              return false;
13768          }
13769          else
13770          {
13771              return $strtotime;
13772          }
13773      }
13774  }
13775  
13776  /**
13777   * Content-type sniffing
13778   *
13779   * @package SimplePie
13780   */
13781  class SimplePie_Content_Type_Sniffer
13782  {
13783      /**
13784       * File object
13785       *
13786       * @var SimplePie_File
13787       * @access private
13788       */
13789      var $file;
13790  
13791      /**
13792       * Create an instance of the class with the input file
13793       *
13794       * @access public
13795       * @param SimplePie_Content_Type_Sniffer $file Input file
13796       */
13797  	function SimplePie_Content_Type_Sniffer($file)
13798      {
13799          $this->file = $file;
13800      }
13801  
13802      /**
13803       * Get the Content-Type of the specified file
13804       *
13805       * @access public
13806       * @return string Actual Content-Type
13807       */
13808  	function get_type()
13809      {
13810          if (isset($this->file->headers['content-type']))
13811          {
13812              if (!isset($this->file->headers['content-encoding'])
13813                  && ($this->file->headers['content-type'] === 'text/plain'
13814                      || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
13815                      || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
13816              {
13817                  return $this->text_or_binary();
13818              }
13819  
13820              if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
13821              {
13822                  $official = substr($this->file->headers['content-type'], 0, $pos);
13823              }
13824              else
13825              {
13826                  $official = $this->file->headers['content-type'];
13827              }
13828              $official = strtolower($official);
13829  
13830              if ($official === 'unknown/unknown'
13831                  || $official === 'application/unknown')
13832              {
13833                  return $this->unknown();
13834              }
13835              elseif (substr($official, -4) === '+xml'
13836                  || $official === 'text/xml'
13837                  || $official === 'application/xml')
13838              {
13839                  return $official;
13840              }
13841              elseif (substr($official, 0, 6) === 'image/')
13842              {
13843                  if ($return = $this->image())
13844                  {
13845                      return $return;
13846                  }
13847                  else
13848                  {
13849                      return $official;
13850                  }
13851              }
13852              elseif ($official === 'text/html')
13853              {
13854                  return $this->feed_or_html();
13855              }
13856              else
13857              {
13858                  return $official;
13859              }
13860          }
13861          else
13862          {
13863              return $this->unknown();
13864          }
13865      }
13866  
13867      /**
13868       * Sniff text or binary
13869       *
13870       * @access private
13871       * @return string Actual Content-Type
13872       */
13873  	function text_or_binary()
13874      {
13875          if (substr($this->file->body, 0, 2) === "\xFE\xFF"
13876              || substr($this->file->body, 0, 2) === "\xFF\xFE"
13877              || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
13878              || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
13879          {
13880              return 'text/plain';
13881          }
13882          elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
13883          {
13884              return 'application/octect-stream';
13885          }
13886          else
13887          {
13888              return 'text/plain';
13889          }
13890      }
13891  
13892      /**
13893       * Sniff unknown
13894       *
13895       * @access private
13896       * @return string Actual Content-Type
13897       */
13898  	function unknown()
13899      {
13900          $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
13901          if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
13902              || strtolower(substr($this->file->body, $ws, 5)) === '<html'
13903              || strtolower(substr($this->file->body, $ws, 7)) === '<script')
13904          {
13905              return 'text/html';
13906          }
13907          elseif (substr($this->file->body, 0, 5) === '%PDF-')
13908          {
13909              return 'application/pdf';
13910          }
13911          elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
13912          {
13913              return 'application/postscript';
13914          }
13915          elseif (substr($this->file->body, 0, 6) === 'GIF87a'
13916              || substr($this->file->body, 0, 6) === 'GIF89a')
13917          {
13918              return 'image/gif';
13919          }
13920          elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13921          {
13922              return 'image/png';
13923          }
13924          elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13925          {
13926              return 'image/jpeg';
13927          }
13928          elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13929          {
13930              return 'image/bmp';
13931          }
13932          else
13933          {
13934              return $this->text_or_binary();
13935          }
13936      }
13937  
13938      /**
13939       * Sniff images
13940       *
13941       * @access private
13942       * @return string Actual Content-Type
13943       */
13944  	function image()
13945      {
13946          if (substr($this->file->body, 0, 6) === 'GIF87a'
13947              || substr($this->file->body, 0, 6) === 'GIF89a')
13948          {
13949              return 'image/gif';
13950          }
13951          elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13952          {
13953              return 'image/png';
13954          }
13955          elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13956          {
13957              return 'image/jpeg';
13958          }
13959          elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13960          {
13961              return 'image/bmp';
13962          }
13963          else
13964          {
13965              return false;
13966          }
13967      }
13968  
13969      /**
13970       * Sniff HTML
13971       *
13972       * @access private
13973       * @return string Actual Content-Type
13974       */
13975  	function feed_or_html()
13976      {
13977          $len = strlen($this->file->body);
13978          $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
13979  
13980          while ($pos < $len)
13981          {
13982              switch ($this->file->body[$pos])
13983              {
13984                  case "\x09":
13985                  case "\x0A":
13986                  case "\x0D":
13987                  case "\x20":
13988                      $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
13989                      continue 2;
13990  
13991                  case '<':
13992                      $pos++;
13993                      break;
13994  
13995                  default:
13996                      return 'text/html';
13997              }
13998  
13999              if (substr($this->file->body, $pos, 3) === '!--')
14000              {
14001                  $pos += 3;
14002                  if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
14003                  {
14004                      $pos += 3;
14005                  }
14006                  else
14007                  {
14008                      return 'text/html';
14009                  }
14010              }
14011              elseif (substr($this->file->body, $pos, 1) === '!')
14012              {
14013                  if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
14014                  {
14015                      $pos++;
14016                  }
14017                  else
14018                  {
14019                      return 'text/html';
14020                  }
14021              }
14022              elseif (substr($this->file->body, $pos, 1) === '?')
14023              {
14024                  if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
14025                  {
14026                      $pos += 2;
14027                  }
14028                  else
14029                  {
14030                      return 'text/html';
14031                  }
14032              }
14033              elseif (substr($this->file->body, $pos, 3) === 'rss'
14034                  || substr($this->file->body, $pos, 7) === 'rdf:RDF')
14035              {
14036                  return 'application/rss+xml';
14037              }
14038              elseif (substr($this->file->body, $pos, 4) === 'feed')
14039              {
14040                  return 'application/atom+xml';
14041              }
14042              else
14043              {
14044                  return 'text/html';
14045              }
14046          }
14047  
14048          return 'text/html';
14049      }
14050  }
14051  
14052  /**
14053   * Parses the XML Declaration
14054   *
14055   * @package SimplePie
14056   */
14057  class SimplePie_XML_Declaration_Parser
14058  {
14059      /**
14060       * XML Version
14061       *
14062       * @access public
14063       * @var string
14064       */
14065      var $version = '1.0';
14066  
14067      /**
14068       * Encoding
14069       *
14070       * @access public
14071       * @var string
14072       */
14073      var $encoding = 'UTF-8';
14074  
14075      /**
14076       * Standalone
14077       *
14078       * @access public
14079       * @var bool
14080       */
14081      var $standalone = false;
14082  
14083      /**
14084       * Current state of the state machine
14085       *
14086       * @access private
14087       * @var string
14088       */
14089      var $state = 'before_version_name';
14090  
14091      /**
14092       * Input data
14093       *
14094       * @access private
14095       * @var string
14096       */
14097      var $data = '';
14098  
14099      /**
14100       * Input data length (to avoid calling strlen() everytime this is needed)
14101       *
14102       * @access private
14103       * @var int
14104       */
14105      var $data_length = 0;
14106  
14107      /**
14108       * Current position of the pointer
14109       *
14110       * @var int
14111       * @access private
14112       */
14113      var $position = 0;
14114  
14115      /**
14116       * Create an instance of the class with the input data
14117       *
14118       * @access public
14119       * @param string $data Input data
14120       */
14121  	function SimplePie_XML_Declaration_Parser($data)
14122      {
14123          $this->data = $data;
14124          $this->data_length = strlen($this->data);
14125      }
14126  
14127      /**
14128       * Parse the input data
14129       *
14130       * @access public
14131       * @return bool true on success, false on failure
14132       */
14133  	function parse()
14134      {
14135          while ($this->state && $this->state !== 'emit' && $this->has_data())
14136          {
14137              $state = $this->state;
14138              $this->$state();
14139          }
14140          $this->data = '';
14141          if ($this->state === 'emit')
14142          {
14143              return true;
14144          }
14145          else
14146          {
14147              $this->version = '';
14148              $this->encoding = '';
14149              $this->standalone = '';
14150              return false;
14151          }
14152      }
14153  
14154      /**
14155       * Check whether there is data beyond the pointer
14156       *
14157       * @access private
14158       * @return bool true if there is further data, false if not
14159       */
14160  	function has_data()
14161      {
14162          return (bool) ($this->position < $this->data_length);
14163      }
14164  
14165      /**
14166       * Advance past any whitespace
14167       *
14168       * @return int Number of whitespace characters passed
14169       */
14170  	function skip_whitespace()
14171      {
14172          $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
14173          $this->position += $whitespace;
14174          return $whitespace;
14175      }
14176  
14177      /**
14178       * Read value
14179       */
14180  	function get_value()
14181      {
14182          $quote = substr($this->data, $this->position, 1);
14183          if ($quote === '"' || $quote === "'")
14184          {
14185              $this->position++;
14186              $len = strcspn($this->data, $quote, $this->position);
14187              if ($this->has_data())
14188              {
14189                  $value = substr($this->data, $this->position, $len);
14190                  $this->position += $len + 1;
14191                  return $value;
14192              }
14193          }
14194          return false;
14195      }
14196  
14197  	function before_version_name()
14198      {
14199          if ($this->skip_whitespace())
14200          {
14201              $this->state = 'version_name';
14202          }
14203          else
14204          {
14205              $this->state = false;
14206          }
14207      }
14208  
14209  	function version_name()
14210      {
14211          if (substr($this->data, $this->position, 7) === 'version')
14212          {
14213              $this->position += 7;
14214              $this->skip_whitespace();
14215              $this->state = 'version_equals';
14216          }
14217          else
14218          {
14219              $this->state = false;
14220          }
14221      }
14222  
14223  	function version_equals()
14224      {
14225          if (substr($this->data, $this->position, 1) === '=')
14226          {
14227              $this->position++;
14228              $this->skip_whitespace();
14229              $this->state = 'version_value';
14230          }
14231          else
14232          {
14233              $this->state = false;
14234          }
14235      }
14236  
14237  	function version_value()
14238      {
14239          if ($this->version = $this->get_value())
14240          {
14241              $this->skip_whitespace();
14242              if ($this->has_data())
14243              {
14244                  $this->state = 'encoding_name';
14245              }
14246              else
14247              {
14248                  $this->state = 'emit';
14249              }
14250          }
14251          else
14252          {
14253              $this->state = false;
14254          }
14255      }
14256  
14257  	function encoding_name()
14258      {
14259          if (substr($this->data, $this->position, 8) === 'encoding')
14260          {
14261              $this->position += 8;
14262              $this->skip_whitespace();
14263              $this->state = 'encoding_equals';
14264          }
14265          else
14266          {
14267              $this->state = 'standalone_name';
14268          }
14269      }
14270  
14271  	function encoding_equals()
14272      {
14273          if (substr($this->data, $this->position, 1) === '=')
14274          {
14275              $this->position++;
14276              $this->skip_whitespace();
14277              $this->state = 'encoding_value';
14278          }
14279          else
14280          {
14281              $this->state = false;
14282          }
14283      }
14284  
14285  	function encoding_value()
14286      {
14287          if ($this->encoding = $this->get_value())
14288          {
14289              $this->skip_whitespace();
14290              if ($this->has_data())
14291              {
14292                  $this->state = 'standalone_name';
14293              }
14294              else
14295              {
14296                  $this->state = 'emit';
14297              }
14298          }
14299          else
14300          {
14301              $this->state = false;
14302          }
14303      }
14304  
14305  	function standalone_name()
14306      {
14307          if (substr($this->data, $this->position, 10) === 'standalone')
14308          {
14309              $this->position += 10;
14310              $this->skip_whitespace();
14311              $this->state = 'standalone_equals';
14312          }
14313          else
14314          {
14315              $this->state = false;
14316          }
14317      }
14318  
14319  	function standalone_equals()
14320      {
14321          if (substr($this->data, $this->position, 1) === '=')
14322          {
14323              $this->position++;
14324              $this->skip_whitespace();
14325              $this->state = 'standalone_value';
14326          }
14327          else
14328          {
14329              $this->state = false;
14330          }
14331      }
14332  
14333  	function standalone_value()
14334      {
14335          if ($standalone = $this->get_value())
14336          {
14337              switch ($standalone)
14338              {
14339                  case 'yes':
14340                      $this->standalone = true;
14341                      break;
14342  
14343                  case 'no':
14344                      $this->standalone = false;
14345                      break;
14346  
14347                  default:
14348                      $this->state = false;
14349                      return;
14350              }
14351  
14352              $this->skip_whitespace();
14353              if ($this->has_data())
14354              {
14355                  $this->state = false;
14356              }
14357              else
14358              {
14359                  $this->state = 'emit';
14360              }
14361          }
14362          else
14363          {
14364              $this->state = false;
14365          }
14366      }
14367  }
14368  
14369  class SimplePie_Locator
14370  {
14371      var $useragent;
14372      var $timeout;
14373      var $file;
14374      var $local = array();
14375      var $elsewhere = array();
14376      var $file_class = 'SimplePie_File';
14377      var $cached_entities = array();
14378      var $http_base;
14379      var $base;
14380      var $base_location = 0;
14381      var $checked_feeds = 0;
14382      var $max_checked_feeds = 10;
14383      var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
14384  
14385  	function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
14386      {
14387          $this->file =& $file;
14388          $this->file_class = $file_class;
14389          $this->useragent = $useragent;
14390          $this->timeout = $timeout;
14391          $this->max_checked_feeds = $max_checked_feeds;
14392          $this->content_type_sniffer_class = $content_type_sniffer_class;
14393      }
14394  
14395  	function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
14396      {
14397          if ($this->is_feed($this->file))
14398          {
14399              return $this->file;
14400          }
14401  
14402          if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14403          {
14404              $sniffer = new $this->content_type_sniffer_class($this->file);
14405              if ($sniffer->get_type() !== 'text/html')
14406              {
14407                  return null;
14408              }
14409          }
14410  
14411          if ($type & ~SIMPLEPIE_LOCATOR_NONE)
14412          {
14413              $this->get_base();
14414          }
14415  
14416          if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
14417          {
14418              return $working[0];
14419          }
14420  
14421          if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
14422          {
14423              if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
14424              {
14425                  return $working;
14426              }
14427  
14428              if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
14429              {
14430                  return $working;
14431              }
14432  
14433              if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
14434              {
14435                  return $working;
14436              }
14437  
14438              if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
14439              {
14440                  return $working;
14441              }
14442          }
14443          return null;
14444      }
14445  
14446  	function is_feed(&$file)
14447      {
14448          if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14449          {
14450              $sniffer = new $this->content_type_sniffer_class($file);
14451              $sniffed = $sniffer->get_type();
14452              if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
14453              {
14454                  return true;
14455              }
14456              else
14457              {
14458                  return false;
14459              }
14460          }
14461          elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
14462          {
14463              return true;
14464          }
14465          else
14466          {
14467              return false;
14468          }
14469      }
14470  
14471  	function get_base()
14472      {
14473          $this->http_base = $this->file->url;
14474          $this->base = $this->http_base;
14475          $elements = SimplePie_Misc::get_element('base', $this->file->body);
14476          foreach ($elements as $element)
14477          {
14478              if ($element['attribs']['href']['data'] !== '')
14479              {
14480                  $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
14481                  $this->base_location = $element['offset'];
14482                  break;
14483              }
14484          }
14485      }
14486  
14487  	function autodiscovery()
14488      {
14489          $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body));
14490          $done = array();
14491          $feeds = array();
14492          foreach ($links as $link)
14493          {
14494              if ($this->checked_feeds === $this->max_checked_feeds)
14495              {
14496                  break;
14497              }
14498              if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
14499              {
14500                  $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
14501  
14502                  if ($this->base_location < $link['offset'])
14503                  {
14504                      $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14505                  }
14506                  else
14507                  {
14508                      $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14509                  }
14510  
14511                  if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
14512                  {
14513                      $this->checked_feeds++;
14514                      $feed = new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
14515                      if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
14516                      {
14517                          $feeds[$href] = $feed;
14518                      }
14519                  }
14520                  $done[] = $href;
14521              }
14522          }
14523  
14524          if (!empty($feeds))
14525          {
14526              return array_values($feeds);
14527          }
14528          else {
14529              return null;
14530          }
14531      }
14532  
14533  	function get_links()
14534      {
14535          $links = SimplePie_Misc::get_element('a', $this->file->body);
14536          foreach ($links as $link)
14537          {
14538              if (isset($link['attribs']['href']['data']))
14539              {
14540                  $href = trim($link['attribs']['href']['data']);
14541                  $parsed = SimplePie_Misc::parse_url($href);
14542                  if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
14543                  {
14544                      if ($this->base_location < $link['offset'])
14545                      {
14546                          $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14547                      }
14548                      else
14549                      {
14550                          $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14551                      }
14552  
14553                      $current = SimplePie_Misc::parse_url($this->file->url);
14554  
14555                      if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
14556                      {
14557                          $this->local[] = $href;
14558                      }
14559                      else
14560                      {
14561                          $this->elsewhere[] = $href;
14562                      }
14563                  }
14564              }
14565          }
14566          $this->local = array_unique($this->local);
14567          $this->elsewhere = array_unique($this->elsewhere);
14568          if (!empty($this->local) || !empty($this->elsewhere))
14569          {
14570              return true;
14571          }
14572          return null;
14573      }
14574  
14575  	function extension(&$array)
14576      {
14577          foreach ($array as $key => $value)
14578          {
14579              if ($this->checked_feeds === $this->max_checked_feeds)
14580              {
14581                  break;
14582              }
14583              if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
14584              {
14585                  $this->checked_feeds++;
14586                  $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14587                  if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
14588                  {
14589                      return $feed;
14590                  }
14591                  else
14592                  {
14593                      unset($array[$key]);
14594                  }
14595              }
14596          }
14597          return null;
14598      }
14599  
14600  	function body(&$array)
14601      {
14602          foreach ($array as $key => $value)
14603          {
14604              if ($this->checked_feeds === $this->max_checked_feeds)
14605              {
14606                  break;
14607              }
14608              if (preg_match('/(rss|rdf|atom|xml)/i', $value))
14609              {
14610                  $this->checked_feeds++;
14611                  $feed = new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14612                  if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
14613                  {
14614                      return $feed;
14615                  }
14616                  else
14617                  {
14618                      unset($array[$key]);
14619                  }
14620              }
14621          }
14622          return null;
14623      }
14624  }
14625  
14626  class SimplePie_Parser
14627  {
14628      var $error_code;
14629      var $error_string;
14630      var $current_line;
14631      var $current_column;
14632      var $current_byte;
14633      var $separator = ' ';
14634      var $namespace = array('');
14635      var $element = array('');
14636      var $xml_base = array('');
14637      var $xml_base_explicit = array(false);
14638      var $xml_lang = array('');
14639      var $data = array();
14640      var $datas = array(array());
14641      var $current_xhtml_construct = -1;
14642      var $encoding;
14643  
14644  	function parse(&$data, $encoding)
14645      {
14646          // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
14647          if (strtoupper($encoding) === 'US-ASCII')
14648          {
14649              $this->encoding = 'UTF-8';
14650          }
14651          else
14652          {
14653              $this->encoding = $encoding;
14654          }
14655  
14656          // Strip BOM:
14657          // UTF-32 Big Endian BOM
14658          if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
14659          {
14660              $data = substr($data, 4);
14661          }
14662          // UTF-32 Little Endian BOM
14663          elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
14664          {
14665              $data = substr($data, 4);
14666          }
14667          // UTF-16 Big Endian BOM
14668          elseif (substr($data, 0, 2) === "\xFE\xFF")
14669          {
14670              $data = substr($data, 2);
14671          }
14672          // UTF-16 Little Endian BOM
14673          elseif (substr($data, 0, 2) === "\xFF\xFE")
14674          {
14675              $data = substr($data, 2);
14676          }
14677          // UTF-8 BOM
14678          elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
14679          {
14680              $data = substr($data, 3);
14681          }
14682  
14683          if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
14684          {
14685              $declaration = new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
14686              if ($declaration->parse())
14687              {
14688                  $data = substr($data, $pos + 2);
14689                  $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
14690              }
14691              else
14692              {
14693                  $this->error_string = 'SimplePie bug! Please report this!';
14694                  return false;
14695              }
14696          }
14697  
14698          $return = true;
14699  
14700          static $xml_is_sane = null;
14701          if ($xml_is_sane === null)
14702          {
14703              $parser_check = xml_parser_create();
14704              xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
14705              xml_parser_free($parser_check);
14706              $xml_is_sane = isset($values[0]['value']);
14707          }
14708  
14709          // Create the parser
14710          if ($xml_is_sane)
14711          {
14712              $xml = xml_parser_create_ns($this->encoding, $this->separator);
14713              xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
14714              xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
14715              xml_set_object($xml, $this);
14716              xml_set_character_data_handler($xml, 'cdata');
14717              xml_set_element_handler($xml, 'tag_open', 'tag_close');
14718  
14719              // Parse!
14720              if (!xml_parse($xml, $data, true))
14721              {
14722                  $this->error_code = xml_get_error_code($xml);
14723                  $this->error_string = xml_error_string($this->error_code);
14724                  $return = false;
14725              }
14726              $this->current_line = xml_get_current_line_number($xml);
14727              $this->current_column = xml_get_current_column_number($xml);
14728              $this->current_byte = xml_get_current_byte_index($xml);
14729              xml_parser_free($xml);
14730              return $return;
14731          }
14732          else
14733          {
14734              libxml_clear_errors();
14735              $xml = new XMLReader();
14736              $xml->xml($data);
14737              while (@$xml->read())
14738              {
14739                  switch ($xml->nodeType)
14740                  {
14741  
14742                      case constant('XMLReader::END_ELEMENT'):
14743                          if ($xml->namespaceURI !== '')
14744                          {
14745                              $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
14746                          }
14747                          else
14748                          {
14749                              $tagName = $xml->localName;
14750                          }
14751                          $this->tag_close(null, $tagName);
14752                          break;
14753                      case constant('XMLReader::ELEMENT'):
14754                          $empty = $xml->isEmptyElement;
14755                          if ($xml->namespaceURI !== '')
14756                          {
14757                              $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
14758                          }
14759                          else
14760                          {
14761                              $tagName = $xml->localName;
14762                          }
14763                          $attributes = array();
14764                          while ($xml->moveToNextAttribute())
14765                          {
14766                              if ($xml->namespaceURI !== '')
14767                              {
14768                                  $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
14769                              }
14770                              else
14771                              {
14772                                  $attrName = $xml->localName;
14773                              }
14774                              $attributes[$attrName] = $xml->value;
14775                          }
14776                          $this->tag_open(null, $tagName, $attributes);
14777                          if ($empty)
14778                          {
14779                              $this->tag_close(null, $tagName);
14780                          }
14781                          break;
14782                      case constant('XMLReader::TEXT'):
14783  
14784                      case constant('XMLReader::CDATA'):
14785                          $this->cdata(null, $xml->value);
14786                          break;
14787                  }
14788              }
14789              if ($error = libxml_get_last_error())
14790              {
14791                  $this->error_code = $error->code;
14792                  $this->error_string = $error->message;
14793                  $this->current_line = $error->line;
14794                  $this->current_column = $error->column;
14795                  return false;
14796              }
14797              else
14798              {
14799                  return true;
14800              }
14801          }
14802      }
14803  
14804  	function get_error_code()
14805      {
14806          return $this->error_code;
14807      }
14808  
14809  	function get_error_string()
14810      {
14811          return $this->error_string;
14812      }
14813  
14814  	function get_current_line()
14815      {
14816          return $this->current_line;
14817      }
14818  
14819  	function get_current_column()
14820      {
14821          return $this->current_column;
14822      }
14823  
14824  	function get_current_byte()
14825      {
14826          return $this->current_byte;
14827      }
14828  
14829  	function get_data()
14830      {
14831          return $this->data;
14832      }
14833  
14834  	function tag_open($parser, $tag, $attributes)
14835      {
14836          list($this->namespace[], $this->element[]) = $this->split_ns($tag);
14837  
14838          $attribs = array();
14839          foreach ($attributes as $name => $value)
14840          {
14841              list($attrib_namespace, $attribute) = $this->split_ns($name);
14842              $attribs[$attrib_namespace][$attribute] = $value;
14843          }
14844  
14845          if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
14846          {
14847              $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
14848              $this->xml_base_explicit[] = true;
14849          }
14850          else
14851          {
14852              $this->xml_base[] = end($this->xml_base);
14853              $this->xml_base_explicit[] = end($this->xml_base_explicit);
14854          }
14855  
14856          if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
14857          {
14858              $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
14859          }
14860          else
14861          {
14862              $this->xml_lang[] = end($this->xml_lang);
14863          }
14864  
14865          if ($this->current_xhtml_construct >= 0)
14866          {
14867              $this->current_xhtml_construct++;
14868              if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
14869              {
14870                  $this->data['data'] .= '<' . end($this->element);
14871                  if (isset($attribs['']))
14872                  {
14873                      foreach ($attribs[''] as $name => $value)
14874                      {
14875                          $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
14876                      }
14877                  }
14878                  $this->data['data'] .= '>';
14879              }
14880          }
14881          else
14882          {
14883              $this->datas[] =& $this->data;
14884              $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
14885              $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));
14886              if ((end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml')
14887              || (end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml'))
14888              {
14889                  $this->current_xhtml_construct = 0;
14890              }
14891          }
14892      }
14893  
14894  	function cdata($parser, $cdata)
14895      {
14896          if ($this->current_xhtml_construct >= 0)
14897          {
14898              $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
14899          }
14900          else
14901          {
14902              $this->data['data'] .= $cdata;
14903          }
14904      }
14905  
14906  	function tag_close($parser, $tag)
14907      {
14908          if ($this->current_xhtml_construct >= 0)
14909          {
14910              $this->current_xhtml_construct--;
14911              if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))
14912              {
14913                  $this->data['data'] .= '</' . end($this->element) . '>';
14914              }
14915          }
14916          if ($this->current_xhtml_construct === -1)
14917          {
14918              $this->data =& $this->datas[count($this->datas) - 1];
14919              array_pop($this->datas);
14920          }
14921  
14922          array_pop($this->element);
14923          array_pop($this->namespace);
14924          array_pop($this->xml_base);
14925          array_pop($this->xml_base_explicit);
14926          array_pop($this->xml_lang);
14927      }
14928  
14929  	function split_ns($string)
14930      {
14931          static $cache = array();
14932          if (!isset($cache[$string]))
14933          {
14934              if ($pos = strpos($string, $this->separator))
14935              {
14936                  static $separator_length;
14937                  if (!$separator_length)
14938                  {
14939                      $separator_length = strlen($this->separator);
14940                  }
14941                  $namespace = substr($string, 0, $pos);
14942                  $local_name = substr($string, $pos + $separator_length);
14943                  if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
14944                  {
14945                      $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
14946                  }
14947  
14948                  // Normalize the Media RSS namespaces
14949                  if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG ||
14950                      $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2 ||
14951                      $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3 ||
14952                      $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4 ||
14953                      $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5 )
14954                  {
14955                      $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
14956                  }
14957                  $cache[$string] = array($namespace, $local_name);
14958              }
14959              else
14960              {
14961                  $cache[$string] = array('', $string);
14962              }
14963          }
14964          return $cache[$string];
14965      }
14966  }
14967  
14968  /**
14969   * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
14970   */
14971  class SimplePie_Sanitize
14972  {
14973      // Private vars
14974      var $base;
14975  
14976      // Options
14977      var $remove_div = true;
14978      var $image_handler = '';
14979      var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
14980      var $encode_instead_of_strip = false;
14981      var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
14982      var $strip_comments = false;
14983      var $output_encoding = 'UTF-8';
14984      var $enable_cache = true;
14985      var $cache_location = './cache';
14986      var $cache_name_function = 'md5';
14987      var $cache_class = 'SimplePie_Cache';
14988      var $file_class = 'SimplePie_File';
14989      var $timeout = 10;
14990      var $useragent = '';
14991      var $force_fsockopen = false;
14992  
14993      var $replace_url_attributes = array(
14994          'a' => 'href',
14995          'area' => 'href',
14996          'blockquote' => 'cite',
14997          'del' => 'cite',
14998          'form' => 'action',
14999          'img' => array('longdesc', 'src'),
15000          'input' => 'src',
15001          'ins' => 'cite',
15002          'q' => 'cite'
15003      );
15004  
15005  	function remove_div($enable = true)
15006      {
15007          $this->remove_div = (bool) $enable;
15008      }
15009  
15010  	function set_image_handler($page = false)
15011      {
15012          if ($page)
15013          {
15014              $this->image_handler = (string) $page;
15015          }
15016          else
15017          {
15018              $this->image_handler = false;
15019          }
15020      }
15021  
15022  	function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
15023      {
15024          if (isset($enable_cache))
15025          {
15026              $this->enable_cache = (bool) $enable_cache;
15027          }
15028  
15029          if ($cache_location)
15030          {
15031              $this->cache_location = (string) $cache_location;
15032          }
15033  
15034          if ($cache_name_function)
15035          {
15036              $this->cache_name_function = (string) $cache_name_function;
15037          }
15038  
15039          if ($cache_class)
15040          {
15041              $this->cache_class = (string) $cache_class;
15042          }
15043      }
15044  
15045  	function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
15046      {
15047          if ($file_class)
15048          {
15049              $this->file_class = (string) $file_class;
15050          }
15051  
15052          if ($timeout)
15053          {
15054              $this->timeout = (string) $timeout;
15055          }
15056  
15057          if ($useragent)
15058          {
15059              $this->useragent = (string) $useragent;
15060          }
15061  
15062          if ($force_fsockopen)
15063          {
15064              $this->force_fsockopen = (string) $force_fsockopen;
15065          }
15066      }
15067  
15068  	function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
15069      {
15070          if ($tags)
15071          {
15072              if (is_array($tags))
15073              {
15074                  $this->strip_htmltags = $tags;
15075              }
15076              else
15077              {
15078                  $this->strip_htmltags = explode(',', $tags);
15079              }
15080          }
15081          else
15082          {
15083              $this->strip_htmltags = false;
15084          }
15085      }
15086  
15087  	function encode_instead_of_strip($encode = false)
15088      {
15089          $this->encode_instead_of_strip = (bool) $encode;
15090      }
15091  
15092  	function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
15093      {
15094          if ($attribs)
15095          {
15096              if (is_array($attribs))
15097              {
15098                  $this->strip_attributes = $attribs;
15099              }
15100              else
15101              {
15102                  $this->strip_attributes = explode(',', $attribs);
15103              }
15104          }
15105          else
15106          {
15107              $this->strip_attributes = false;
15108          }
15109      }
15110  
15111  	function strip_comments($strip = false)
15112      {
15113          $this->strip_comments = (bool) $strip;
15114      }
15115  
15116  	function set_output_encoding($encoding = 'UTF-8')
15117      {
15118          $this->output_encoding = (string) $encoding;
15119      }
15120  
15121      /**
15122       * Set element/attribute key/value pairs of HTML attributes
15123       * containing URLs that need to be resolved relative to the feed
15124       *
15125       * @access public
15126       * @since 1.0
15127       * @param array $element_attribute Element/attribute key/value pairs
15128       */
15129  	function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite'))
15130      {
15131          $this->replace_url_attributes = (array) $element_attribute;
15132      }
15133  
15134  	function sanitize($data, $type, $base = '')
15135      {
15136          $data = trim($data);
15137          if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
15138          {
15139              if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
15140              {
15141                  if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
15142                  {
15143                      $type |= SIMPLEPIE_CONSTRUCT_HTML;
15144                  }
15145                  else
15146                  {
15147                      $type |= SIMPLEPIE_CONSTRUCT_TEXT;
15148                  }
15149              }
15150  
15151              if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
15152              {
15153                  $data = base64_decode($data);
15154              }
15155  
15156              if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
15157              {
15158                  if ($this->remove_div)
15159                  {
15160                      $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
15161                      $data = preg_replace('/<\/div>$/', '', $data);
15162                  }
15163                  else
15164                  {
15165                      $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
15166                  }
15167              }
15168  
15169              if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
15170              {
15171                  // Strip comments
15172                  if ($this->strip_comments)
15173                  {
15174                      $data = SimplePie_Misc::strip_comments($data);
15175                  }
15176  
15177                  // Strip out HTML tags and attributes that might cause various security problems.
15178                  // Based on recommendations by Mark Pilgrim at:
15179                  // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
15180                  if ($this->strip_htmltags)
15181                  {
15182                      foreach ($this->strip_htmltags as $tag)
15183                      {
15184                          $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
15185                          while (preg_match($pcre, $data))
15186                          {
15187                              $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
15188                          }
15189                      }
15190                  }
15191  
15192                  if ($this->strip_attributes)
15193                  {
15194                      foreach ($this->strip_attributes as $attrib)
15195                      {
15196                          $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data);
15197                      }
15198                  }
15199  
15200                  // Replace relative URLs
15201                  $this->base = $base;
15202                  foreach ($this->replace_url_attributes as $element => $attributes)
15203                  {
15204                      $data = $this->replace_urls($data, $element, $attributes);
15205                  }
15206  
15207                  // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
15208                  if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
15209                  {
15210                      $images = SimplePie_Misc::get_element('img', $data);
15211                      foreach ($images as $img)
15212                      {
15213                          if (isset($img['attribs']['src']['data']))
15214                          {
15215                              $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
15216                              $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
15217  
15218                              if ($cache->load())
15219                              {
15220                                  $img['attribs']['src']['data'] = $this->image_handler . $image_url;
15221                                  $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
15222                              }
15223                              else
15224                              {
15225                                  $file = new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
15226                                  $headers = $file->headers;
15227  
15228                                  if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
15229                                  {
15230                                      if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
15231                                      {
15232                                          $img['attribs']['src']['data'] = $this->image_handler . $image_url;
15233                                          $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
15234                                      }
15235                                      else
15236                                      {
15237                                          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);
15238                                      }
15239                                  }
15240                              }
15241                          }
15242                      }
15243                  }
15244  
15245                  // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
15246                  $data = trim($data);
15247              }
15248  
15249              if ($type & SIMPLEPIE_CONSTRUCT_IRI)
15250              {
15251                  $data = SimplePie_Misc::absolutize_url($data, $base);
15252              }
15253  
15254              if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
15255              {
15256                  $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
15257              }
15258  
15259              if ($this->output_encoding !== 'UTF-8')
15260              {
15261                  $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
15262              }
15263          }
15264          return $data;
15265      }
15266  
15267  	function replace_urls($data, $tag, $attributes)
15268      {
15269          if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
15270          {
15271              $elements = SimplePie_Misc::get_element($tag, $data);
15272              foreach ($elements as $element)
15273              {
15274                  if (is_array($attributes))
15275                  {
15276                      foreach ($attributes as $attribute)
15277                      {
15278                          if (isset($element['attribs'][$attribute]['data']))
15279                          {
15280                              $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
15281                              $new_element = SimplePie_Misc::element_implode($element);
15282                              $data = str_replace($element['full'], $new_element, $data);
15283                              $element['full'] = $new_element;
15284                          }
15285                      }
15286                  }
15287                  elseif (isset($element['attribs'][$attributes]['data']))
15288                  {
15289                      $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
15290                      $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
15291                  }
15292              }
15293          }
15294          return $data;
15295      }
15296  
15297  	function do_strip_htmltags($match)
15298      {
15299          if ($this->encode_instead_of_strip)
15300          {
15301              if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
15302              {
15303                  $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
15304                  $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
15305                  return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
15306              }
15307              else
15308              {
15309                  return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
15310              }
15311          }
15312          elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
15313          {
15314              return $match[4];
15315          }
15316          else
15317          {
15318              return '';
15319          }
15320      }
15321  }
15322  
15323  ?>


Generated: Sun Jan 29 16:31:14 2012 Cross-referenced by PHPXref 0.7.1