[ Index ]

PHP Cross Reference of phpwcms V1.4.7 _r403 (01.11.10)

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-2010, 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.3-dev
  37   * @copyright 2004-2010 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.3-dev');
  56  
  57  /**
  58   * SimplePie Build
  59   */
  60  define('SIMPLEPIE_BUILD', '20101003193300');
  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                  $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          return $message;
9288      }
9289  
9290      /**
9291       * If a file has been cached, retrieve and display it.
9292       *
9293       * This is most useful for caching images (get_favicon(), etc.),
9294       * however it works for all cached files.  This WILL NOT display ANY
9295       * file/image/page/whatever, but rather only display what has already
9296       * been cached by SimplePie.
9297       *
9298       * @access public
9299       * @see SimplePie::get_favicon()
9300       * @param str $identifier_url URL that is used to identify the content.
9301       * This may or may not be the actual URL of the live content.
9302       * @param str $cache_location Location of SimplePie's cache.  Defaults
9303       * to './cache'.
9304       * @param str $cache_extension The file extension that the file was
9305       * cached with.  Defaults to 'spc'.
9306       * @param str $cache_class Name of the cache-handling class being used
9307       * in SimplePie.  Defaults to 'SimplePie_Cache', and should be left
9308       * as-is unless you've overloaded the class.
9309       * @param str $cache_name_function Obsolete. Exists for backwards
9310       * compatibility reasons only.
9311       */
9312  	function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5')
9313      {
9314          $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension);
9315  
9316          if ($file = $cache->load())
9317          {
9318              if (isset($file['headers']['content-type']))
9319              {
9320                  header('Content-type:' . $file['headers']['content-type']);
9321              }
9322              else
9323              {
9324                  header('Content-type: application/octet-stream');
9325              }
9326              header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
9327              echo $file['body'];
9328              exit;
9329          }
9330  
9331          die('Cached file for ' . $identifier_url . ' cannot be found.');
9332      }
9333  
9334  	function fix_protocol($url, $http = 1)
9335      {
9336          $url = SimplePie_Misc::normalize_url($url);
9337          $parsed = SimplePie_Misc::parse_url($url);
9338          if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
9339          {
9340              return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
9341          }
9342  
9343          if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
9344          {
9345              return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
9346          }
9347  
9348          if ($http === 2 && $parsed['scheme'] !== '')
9349          {
9350              return "feed:$url";
9351          }
9352          elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
9353          {
9354              return substr_replace($url, 'podcast', 0, 4);
9355          }
9356          elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
9357          {
9358              return substr_replace($url, 'itpc', 0, 4);
9359          }
9360          else
9361          {
9362              return $url;
9363          }
9364      }
9365  
9366  	function parse_url($url)
9367      {
9368          $iri =& new SimplePie_IRI($url);
9369          return array(
9370              'scheme' => (string) $iri->get_scheme(),
9371              'authority' => (string) $iri->get_authority(),
9372              'path' => (string) $iri->get_path(),
9373              'query' => (string) $iri->get_query(),
9374              'fragment' => (string) $iri->get_fragment()
9375          );
9376      }
9377  
9378  	function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
9379      {
9380          $iri =& new SimplePie_IRI('');
9381          $iri->set_scheme($scheme);
9382          $iri->set_authority($authority);
9383          $iri->set_path($path);
9384          $iri->set_query($query);
9385          $iri->set_fragment($fragment);
9386          return $iri->get_iri();
9387      }
9388  
9389  	function normalize_url($url)
9390      {
9391          $iri =& new SimplePie_IRI($url);
9392          return $iri->get_iri();
9393      }
9394  
9395  	function percent_encoding_normalization($match)
9396      {
9397          $integer = hexdec($match[1]);
9398          if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
9399          {
9400              return chr($integer);
9401          }
9402          else
9403          {
9404              return strtoupper($match[0]);
9405          }
9406      }
9407  
9408      /**
9409       * Remove bad UTF-8 bytes
9410       *
9411       * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C
9412       * FAQ: Multilingual Forms (modified to include full ASCII range)
9413       *
9414       * @author Geoffrey Sneddon
9415       * @see http://www.w3.org/International/questions/qa-forms-utf-8
9416       * @param string $str String to remove bad UTF-8 bytes from
9417       * @return string UTF-8 string
9418       */
9419  	function utf8_bad_replace($str)
9420      {
9421          if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str)))
9422          {
9423              return $return;
9424          }
9425          elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8')))
9426          {
9427              return $return;
9428          }
9429          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))
9430          {
9431              return implode("\xEF\xBF\xBD", $matches[0]);
9432          }
9433          elseif ($str !== '')
9434          {
9435              return "\xEF\xBF\xBD";
9436          }
9437          else
9438          {
9439              return '';
9440          }
9441      }
9442  
9443      /**
9444       * Converts a Windows-1252 encoded string to a UTF-8 encoded string
9445       *
9446       * @static
9447       * @access public
9448       * @param string $string Windows-1252 encoded string
9449       * @return string UTF-8 encoded string
9450       */
9451  	function windows_1252_to_utf8($string)
9452      {
9453          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");
9454  
9455          return strtr($string, $convert_table);
9456      }
9457  
9458  	function change_encoding($data, $input, $output)
9459      {
9460          $input = SimplePie_Misc::encoding($input);
9461          $output = SimplePie_Misc::encoding($output);
9462  
9463          // We fail to fail on non US-ASCII bytes
9464          if ($input === 'US-ASCII')
9465          {
9466              static $non_ascii_octects = '';
9467              if (!$non_ascii_octects)
9468              {
9469                  for ($i = 0x80; $i <= 0xFF; $i++)
9470                  {
9471                      $non_ascii_octects .= chr($i);
9472                  }
9473              }
9474              $data = substr($data, 0, strcspn($data, $non_ascii_octects));
9475          }
9476  
9477          // This is first, as behaviour of this is completely predictable
9478          if ($input === 'windows-1252' && $output === 'UTF-8')
9479          {
9480              return SimplePie_Misc::windows_1252_to_utf8($data);
9481          }
9482          // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
9483          elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && ($return = @mb_convert_encoding($data, $output, $input)))
9484          {
9485              return $return;
9486          }
9487          // This is last, as behaviour of this varies with OS userland and PHP version
9488          elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data)))
9489          {
9490              return $return;
9491          }
9492          // If we can't do anything, just fail
9493          else
9494          {
9495              return false;
9496          }
9497      }
9498  
9499      /**
9500       * Normalize an encoding name
9501       *
9502       * This is automatically generated by create.php
9503       *
9504       * To generate it, run `php create.php` on the command line, and copy the
9505       * output to replace this function.
9506       *
9507       * @param string $charset Character set to standardise
9508       * @return string Standardised name
9509       */
9510  	function encoding($charset)
9511      {
9512          // Normalization from UTS #22
9513          switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
9514          {
9515              case 'adobestandardencoding':
9516              case 'csadobestandardencoding':
9517                  return 'Adobe-Standard-Encoding';
9518  
9519              case 'adobesymbolencoding':
9520              case 'cshppsmath':
9521                  return 'Adobe-Symbol-Encoding';
9522  
9523              case 'ami1251':
9524              case 'amiga1251':
9525                  return 'Amiga-1251';
9526  
9527              case 'ansix31101983':
9528              case 'csat5001983':
9529              case 'csiso99naplps':
9530              case 'isoir99':
9531              case 'naplps':
9532                  return 'ANSI_X3.110-1983';
9533  
9534              case 'arabic7':
9535              case 'asmo449':
9536              case 'csiso89asmo449':
9537              case 'iso9036':
9538              case 'isoir89':
9539                  return 'ASMO_449';
9540  
9541              case 'big5':
9542              case 'csbig5':
9543                  return 'Big5';
9544  
9545              case 'big5hkscs':
9546                  return 'Big5-HKSCS';
9547  
9548              case 'bocu1':
9549              case 'csbocu1':
9550                  return 'BOCU-1';
9551  
9552              case 'brf':
9553              case 'csbrf':
9554                  return 'BRF';
9555  
9556              case 'bs4730':
9557              case 'csiso4unitedkingdom':
9558              case 'gb':
9559              case 'iso646gb':
9560              case 'isoir4':
9561              case 'uk':
9562                  return 'BS_4730';
9563  
9564              case 'bsviewdata':
9565              case 'csiso47bsviewdata':
9566              case 'isoir47':
9567                  return 'BS_viewdata';
9568  
9569              case 'cesu8':
9570              case 'cscesu8':
9571                  return 'CESU-8';
9572  
9573              case 'ca':
9574              case 'csa71':
9575              case 'csaz243419851':
9576              case 'csiso121canadian1':
9577              case 'iso646ca':
9578              case 'isoir121':
9579                  return 'CSA_Z243.4-1985-1';
9580  
9581              case 'csa72':
9582              case 'csaz243419852':
9583              case 'csiso122canadian2':
9584              case 'iso646ca2':
9585              case 'isoir122':
9586                  return 'CSA_Z243.4-1985-2';
9587  
9588              case 'csaz24341985gr':
9589              case 'csiso123csaz24341985gr':
9590              case 'isoir123':
9591                  return 'CSA_Z243.4-1985-gr';
9592  
9593              case 'csiso139csn369103':
9594              case 'csn369103':
9595              case 'isoir139':
9596                  return 'CSN_369103';
9597  
9598              case 'csdecmcs':
9599              case 'dec':
9600              case 'decmcs':
9601                  return 'DEC-MCS';
9602  
9603              case 'csiso21german':
9604              case 'de':
9605              case 'din66003':
9606              case 'iso646de':
9607              case 'isoir21':
9608                  return 'DIN_66003';
9609  
9610              case 'csdkus':
9611              case 'dkus':
9612                  return 'dk-us';
9613  
9614              case 'csiso646danish':
9615              case 'dk':
9616              case 'ds2089':
9617              case 'iso646dk':
9618                  return 'DS_2089';
9619  
9620              case 'csibmebcdicatde':
9621              case 'ebcdicatde':
9622                  return 'EBCDIC-AT-DE';
9623  
9624              case 'csebcdicatdea':
9625              case 'ebcdicatdea':
9626                  return 'EBCDIC-AT-DE-A';
9627  
9628              case 'csebcdiccafr':
9629              case 'ebcdiccafr':
9630                  return 'EBCDIC-CA-FR';
9631  
9632              case 'csebcdicdkno':
9633              case 'ebcdicdkno':
9634                  return 'EBCDIC-DK-NO';
9635  
9636              case 'csebcdicdknoa':
9637              case 'ebcdicdknoa':
9638                  return 'EBCDIC-DK-NO-A';
9639  
9640              case 'csebcdices':
9641              case 'ebcdices':
9642                  return 'EBCDIC-ES';
9643  
9644              case 'csebcdicesa':
9645              case 'ebcdicesa':
9646                  return 'EBCDIC-ES-A';
9647  
9648              case 'csebcdicess':
9649              case 'ebcdicess':
9650                  return 'EBCDIC-ES-S';
9651  
9652              case 'csebcdicfise':
9653              case 'ebcdicfise':
9654                  return 'EBCDIC-FI-SE';
9655  
9656              case 'csebcdicfisea':
9657              case 'ebcdicfisea':
9658                  return 'EBCDIC-FI-SE-A';
9659  
9660              case 'csebcdicfr':
9661              case 'ebcdicfr':
9662                  return 'EBCDIC-FR';
9663  
9664              case 'csebcdicit':
9665              case 'ebcdicit':
9666                  return 'EBCDIC-IT';
9667  
9668              case 'csebcdicpt':
9669              case 'ebcdicpt':
9670                  return 'EBCDIC-PT';
9671  
9672              case 'csebcdicuk':
9673              case 'ebcdicuk':
9674                  return 'EBCDIC-UK';
9675  
9676              case 'csebcdicus':
9677              case 'ebcdicus':
9678                  return 'EBCDIC-US';
9679  
9680              case 'csiso111ecmacyrillic':
9681              case 'ecmacyrillic':
9682              case 'isoir111':
9683              case 'koi8e':
9684                  return 'ECMA-cyrillic';
9685  
9686              case 'csiso17spanish':
9687              case 'es':
9688              case 'iso646es':
9689              case 'isoir17':
9690                  return 'ES';
9691  
9692              case 'csiso85spanish2':
9693              case 'es2':
9694              case 'iso646es2':
9695              case 'isoir85':
9696                  return 'ES2';
9697  
9698              case 'cseucpkdfmtjapanese':
9699              case 'eucjp':
9700              case 'extendedunixcodepackedformatforjapanese':
9701                  return 'EUC-JP';
9702  
9703              case 'cseucfixwidjapanese':
9704              case 'extendedunixcodefixedwidthforjapanese':
9705                  return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
9706  
9707              case 'gb18030':
9708                  return 'GB18030';
9709  
9710              case 'chinese':
9711              case 'cp936':
9712              case 'csgb2312':
9713              case 'csiso58gb231280':
9714              case 'gb2312':
9715              case 'gb231280':
9716              case 'gbk':
9717              case 'isoir58':
9718              case 'ms936':
9719              case 'windows936':
9720                  return 'GBK';
9721  
9722              case 'cn':
9723              case 'csiso57gb1988':
9724              case 'gb198880':
9725              case 'iso646cn':
9726              case 'isoir57':
9727                  return 'GB_1988-80';
9728  
9729              case 'csiso153gost1976874':
9730              case 'gost1976874':
9731              case 'isoir153':
9732              case 'stsev35888':
9733                  return 'GOST_19768-74';
9734  
9735              case 'csiso150':
9736              case 'csiso150greekccitt':
9737              case 'greekccitt':
9738              case 'isoir150':
9739                  return 'greek-ccitt';
9740  
9741              case 'csiso88greek7':
9742              case 'greek7':
9743              case 'isoir88':
9744                  return 'greek7';
9745  
9746              case 'csiso18greek7old':
9747              case 'greek7old':
9748              case 'isoir18':
9749                  return 'greek7-old';
9750  
9751              case 'cshpdesktop':
9752              case 'hpdesktop':
9753                  return 'HP-DeskTop';
9754  
9755              case 'cshplegal':
9756              case 'hplegal':
9757                  return 'HP-Legal';
9758  
9759              case 'cshpmath8':
9760              case 'hpmath8':
9761                  return 'HP-Math8';
9762  
9763              case 'cshppifont':
9764              case 'hppifont':
9765                  return 'HP-Pi-font';
9766  
9767              case 'cshproman8':
9768              case 'hproman8':
9769              case 'r8':
9770              case 'roman8':
9771                  return 'hp-roman8';
9772  
9773              case 'hzgb2312':
9774                  return 'HZ-GB-2312';
9775  
9776              case 'csibmsymbols':
9777              case 'ibmsymbols':
9778                  return 'IBM-Symbols';
9779  
9780              case 'csibmthai':
9781              case 'ibmthai':
9782                  return 'IBM-Thai';
9783  
9784              case 'cp37':
9785              case 'csibm37':
9786              case 'ebcdiccpca':
9787              case 'ebcdiccpnl':
9788              case 'ebcdiccpus':
9789              case 'ebcdiccpwt':
9790              case 'ibm37':
9791                  return 'IBM037';
9792  
9793              case 'cp38':
9794              case 'csibm38':
9795              case 'ebcdicint':
9796              case 'ibm38':
9797                  return 'IBM038';
9798  
9799              case 'cp273':
9800              case 'csibm273':
9801              case 'ibm273':
9802                  return 'IBM273';
9803  
9804              case 'cp274':
9805              case 'csibm274':
9806              case 'ebcdicbe':
9807              case 'ibm274':
9808                  return 'IBM274';
9809  
9810              case 'cp275':
9811              case 'csibm275':
9812              case 'ebcdicbr':
9813              case 'ibm275':
9814                  return 'IBM275';
9815  
9816              case 'csibm277':
9817              case 'ebcdiccpdk':
9818              case 'ebcdiccpno':
9819              case 'ibm277':
9820                  return 'IBM277';
9821  
9822              case 'cp278':
9823              case 'csibm278':
9824              case 'ebcdiccpfi':
9825              case 'ebcdiccpse':
9826              case 'ibm278':
9827                  return 'IBM278';
9828  
9829              case 'cp280':
9830              case 'csibm280':
9831              case 'ebcdiccpit':
9832              case 'ibm280':
9833                  return 'IBM280';
9834  
9835              case 'cp281':
9836              case 'csibm281':
9837              case 'ebcdicjpe':
9838              case 'ibm281':
9839                  return 'IBM281';
9840  
9841              case 'cp284':
9842              case 'csibm284':
9843              case 'ebcdiccpes':
9844              case 'ibm284':
9845                  return 'IBM284';
9846  
9847              case 'cp285':
9848              case 'csibm285':
9849              case 'ebcdiccpgb':
9850              case 'ibm285':
9851                  return 'IBM285';
9852  
9853              case 'cp290':
9854              case 'csibm290':
9855              case 'ebcdicjpkana':
9856              case 'ibm290':
9857                  return 'IBM290';
9858  
9859              case 'cp297':
9860              case 'csibm297':
9861              case 'ebcdiccpfr':
9862              case 'ibm297':
9863                  return 'IBM297';
9864  
9865              case 'cp420':
9866              case 'csibm420':
9867              case 'ebcdiccpar1':
9868              case 'ibm420':
9869                  return 'IBM420';
9870  
9871              case 'cp423':
9872              case 'csibm423':
9873              case 'ebcdiccpgr':
9874              case 'ibm423':
9875                  return 'IBM423';
9876  
9877              case 'cp424':
9878              case 'csibm424':
9879              case 'ebcdiccphe':
9880              case 'ibm424':
9881                  return 'IBM424';
9882  
9883              case '437':
9884              case 'cp437':
9885              case 'cspc8codepage437':
9886              case 'ibm437':
9887                  return 'IBM437';
9888  
9889              case 'cp500':
9890              case 'csibm500':
9891              case 'ebcdiccpbe':
9892              case 'ebcdiccpch':
9893              case 'ibm500':
9894                  return 'IBM500';
9895  
9896              case 'cp775':
9897              case 'cspc775baltic':
9898              case 'ibm775':
9899                  return 'IBM775';
9900  
9901              case '850':
9902              case 'cp850':
9903              case 'cspc850multilingual':
9904              case 'ibm850':
9905                  return 'IBM850';
9906  
9907              case '851':
9908              case 'cp851':
9909              case 'csibm851':
9910              case 'ibm851':
9911                  return 'IBM851';
9912  
9913              case '852':
9914              case 'cp852':
9915              case 'cspcp852':
9916              case 'ibm852':
9917                  return 'IBM852';
9918  
9919              case '855':
9920              case 'cp855':
9921              case 'csibm855':
9922              case 'ibm855':
9923                  return 'IBM855';
9924  
9925              case '857':
9926              case 'cp857':
9927              case 'csibm857':
9928              case 'ibm857':
9929                  return 'IBM857';
9930  
9931              case 'ccsid858':
9932              case 'cp858':
9933              case 'ibm858':
9934              case 'pcmultilingual850euro':
9935                  return 'IBM00858';
9936  
9937              case '860':
9938              case 'cp860':
9939              case 'csibm860':
9940              case 'ibm860':
9941                  return 'IBM860';
9942  
9943              case '861':
9944              case 'cp861':
9945              case 'cpis':
9946              case 'csibm861':
9947              case 'ibm861':
9948                  return 'IBM861';
9949  
9950              case '862':
9951              case 'cp862':
9952              case 'cspc862latinhebrew':
9953              case 'ibm862':
9954                  return 'IBM862';
9955  
9956              case '863':
9957              case 'cp863':
9958              case 'csibm863':
9959              case 'ibm863':
9960                  return 'IBM863';
9961  
9962              case 'cp864':
9963              case 'csibm864':
9964              case 'ibm864':
9965                  return 'IBM864';
9966  
9967              case '865':
9968              case 'cp865':
9969              case 'csibm865':
9970              case 'ibm865':
9971                  return 'IBM865';
9972  
9973              case '866':
9974              case 'cp866':
9975              case 'csibm866':
9976              case 'ibm866':
9977                  return 'IBM866';
9978  
9979              case 'cp868':
9980              case 'cpar':
9981              case 'csibm868':
9982              case 'ibm868':
9983                  return 'IBM868';
9984  
9985              case '869':
9986              case 'cp869':
9987              case 'cpgr':
9988              case 'csibm869':
9989              case 'ibm869':
9990                  return 'IBM869';
9991  
9992              case 'cp870':
9993              case 'csibm870':
9994              case 'ebcdiccproece':
9995              case 'ebcdiccpyu':
9996              case 'ibm870':
9997                  return 'IBM870';
9998  
9999              case 'cp871':
10000              case 'csibm871':
10001              case 'ebcdiccpis':
10002              case 'ibm871':
10003                  return 'IBM871';
10004  
10005              case 'cp880':
10006              case 'csibm880':
10007              case 'ebcdiccyrillic':
10008              case 'ibm880':
10009                  return 'IBM880';
10010  
10011              case 'cp891':
10012              case 'csibm891':
10013              case 'ibm891':
10014                  return 'IBM891';
10015  
10016              case 'cp903':
10017              case 'csibm903':
10018              case 'ibm903':
10019                  return 'IBM903';
10020  
10021              case '904':
10022              case 'cp904':
10023              case 'csibbm904':
10024              case 'ibm904':
10025                  return 'IBM904';
10026  
10027              case 'cp905':
10028              case 'csibm905':
10029              case 'ebcdiccptr':
10030              case 'ibm905':
10031                  return 'IBM905';
10032  
10033              case 'cp918':
10034              case 'csibm918':
10035              case 'ebcdiccpar2':
10036              case 'ibm918':
10037                  return 'IBM918';
10038  
10039              case 'ccsid924':
10040              case 'cp924':
10041              case 'ebcdiclatin9euro':
10042              case 'ibm924':
10043                  return 'IBM00924';
10044  
10045              case 'cp1026':
10046              case 'csibm1026':
10047              case 'ibm1026':
10048                  return 'IBM1026';
10049  
10050              case 'ibm1047':
10051                  return 'IBM1047';
10052  
10053              case 'ccsid1140':
10054              case 'cp1140':
10055              case 'ebcdicus37euro':
10056              case 'ibm1140':
10057                  return 'IBM01140';
10058  
10059              case 'ccsid1141':
10060              case 'cp1141':
10061              case 'ebcdicde273euro':
10062              case 'ibm1141':
10063                  return 'IBM01141';
10064  
10065              case 'ccsid1142':
10066              case 'cp1142':
10067              case 'ebcdicdk277euro':
10068              case 'ebcdicno277euro':
10069              case 'ibm1142':
10070                  return 'IBM01142';
10071  
10072              case 'ccsid1143':
10073              case 'cp1143':
10074              case 'ebcdicfi278euro':
10075              case 'ebcdicse278euro':
10076              case 'ibm1143':
10077                  return 'IBM01143';
10078  
10079              case 'ccsid1144':
10080              case 'cp1144':
10081              case 'ebcdicit280euro':
10082              case 'ibm1144':
10083                  return 'IBM01144';
10084  
10085              case 'ccsid1145':
10086              case 'cp1145':
10087              case 'ebcdices284euro':
10088              case 'ibm1145':
10089                  return 'IBM01145';
10090  
10091              case 'ccsid1146':
10092              case 'cp1146':
10093              case 'ebcdicgb285euro':
10094              case 'ibm1146':
10095                  return 'IBM01146';
10096  
10097              case 'ccsid1147':
10098              case 'cp1147':
10099              case 'ebcdicfr297euro':
10100              case 'ibm1147':
10101                  return 'IBM01147';
10102  
10103              case 'ccsid1148':
10104              case 'cp1148':
10105              case 'ebcdicinternational500euro':
10106              case 'ibm1148':
10107                  return 'IBM01148';
10108  
10109              case 'ccsid1149':
10110              case 'cp1149':
10111              case 'ebcdicis871euro':
10112              case 'ibm1149':
10113                  return 'IBM01149';
10114  
10115              case 'csiso143iecp271':
10116              case 'iecp271':
10117              case 'isoir143':
10118                  return 'IEC_P27-1';
10119  
10120              case 'csiso49inis':
10121              case 'inis':
10122              case 'isoir49':
10123                  return 'INIS';
10124  
10125              case 'csiso50inis8':
10126              case 'inis8':
10127              case 'isoir50':
10128                  return 'INIS-8';
10129  
10130              case 'csiso51iniscyrillic':
10131              case 'iniscyrillic':
10132              case 'isoir51':
10133                  return 'INIS-cyrillic';
10134  
10135              case 'csinvariant':
10136              case 'invariant':
10137                  return 'INVARIANT';
10138  
10139              case 'iso2022cn':
10140                  return 'ISO-2022-CN';
10141  
10142              case 'iso2022cnext':
10143                  return 'ISO-2022-CN-EXT';
10144  
10145              case 'csiso2022jp':
10146              case 'iso2022jp':
10147                  return 'ISO-2022-JP';
10148  
10149              case 'csiso2022jp2':
10150              case 'iso2022jp2':
10151                  return 'ISO-2022-JP-2';
10152  
10153              case 'csiso2022kr':
10154              case 'iso2022kr':
10155                  return 'ISO-2022-KR';
10156  
10157              case 'cswindows30latin1':
10158              case 'iso88591windows30latin1':
10159                  return 'ISO-8859-1-Windows-3.0-Latin-1';
10160  
10161              case 'cswindows31latin1':
10162              case 'iso88591windows31latin1':
10163                  return 'ISO-8859-1-Windows-3.1-Latin-1';
10164  
10165              case 'csisolatin2':
10166              case 'iso88592':
10167              case 'iso885921987':
10168              case 'isoir101':
10169              case 'l2':
10170              case 'latin2':
10171                  return 'ISO-8859-2';
10172  
10173              case 'cswindows31latin2':
10174              case 'iso88592windowslatin2':
10175                  return 'ISO-8859-2-Windows-Latin-2';
10176  
10177              case 'csisolatin3':
10178              case 'iso88593':
10179              case 'iso885931988':
10180              case 'isoir109':
10181              case 'l3':
10182              case 'latin3':
10183                  return 'ISO-8859-3';
10184  
10185              case 'csisolatin4':
10186              case 'iso88594':
10187              case 'iso885941988':
10188              case 'isoir110':
10189              case 'l4':
10190              case 'latin4':
10191                  return 'ISO-8859-4';
10192  
10193              case 'csisolatincyrillic':
10194              case 'cyrillic':
10195              case 'iso88595':
10196              case 'iso885951988':
10197              case 'isoir144':
10198                  return 'ISO-8859-5';
10199  
10200              case 'arabic':
10201              case 'asmo708':
10202              case 'csisolatinarabic':
10203              case 'ecma114':
10204              case 'iso88596':
10205              case 'iso885961987':
10206              case 'isoir127':
10207                  return 'ISO-8859-6';
10208  
10209              case 'csiso88596e':
10210              case 'iso88596e':
10211                  return 'ISO-8859-6-E';
10212  
10213              case 'csiso88596i':
10214              case 'iso88596i':
10215                  return 'ISO-8859-6-I';
10216  
10217              case 'csisolatingreek':
10218              case 'ecma118':
10219              case 'elot928':
10220              case 'greek':
10221              case 'greek8':
10222              case 'iso88597':
10223              case 'iso885971987':
10224              case 'isoir126':
10225                  return 'ISO-8859-7';
10226  
10227              case 'csisolatinhebrew':
10228              case 'hebrew':
10229              case 'iso88598':
10230              case 'iso885981988':
10231              case 'isoir138':
10232                  return 'ISO-8859-8';
10233  
10234              case 'csiso88598e':
10235              case 'iso88598e':
10236                  return 'ISO-8859-8-E';
10237  
10238              case 'csiso88598i':
10239              case 'iso88598i':
10240                  return 'ISO-8859-8-I';
10241  
10242              case 'cswindows31latin5':
10243              case 'iso88599windowslatin5':
10244                  return 'ISO-8859-9-Windows-Latin-5';
10245  
10246              case 'csisolatin6':
10247              case 'iso885910':
10248              case 'iso8859101992':
10249              case 'isoir157':
10250              case 'l6':
10251              case 'latin6':
10252                  return 'ISO-8859-10';
10253  
10254              case 'iso885913':
10255                  return 'ISO-8859-13';
10256  
10257              case 'iso885914':
10258              case 'iso8859141998':
10259              case 'isoceltic':
10260              case 'isoir199':
10261              case 'l8':
10262              case 'latin8':
10263                  return 'ISO-8859-14';
10264  
10265              case 'iso885915':
10266              case 'latin9':
10267                  return 'ISO-8859-15';
10268  
10269              case 'iso885916':
10270              case 'iso8859162001':
10271              case 'isoir226':
10272              case 'l10':
10273              case 'latin10':
10274                  return 'ISO-8859-16';
10275  
10276              case 'iso10646j1':
10277                  return 'ISO-10646-J-1';
10278  
10279              case 'csunicode':
10280              case 'iso10646ucs2':
10281                  return 'ISO-10646-UCS-2';
10282  
10283              case 'csucs4':
10284              case 'iso10646ucs4':
10285                  return 'ISO-10646-UCS-4';
10286  
10287              case 'csunicodeascii':
10288              case 'iso10646ucsbasic':
10289                  return 'ISO-10646-UCS-Basic';
10290  
10291              case 'csunicodelatin1':
10292              case 'iso10646':
10293              case 'iso10646unicodelatin1':
10294                  return 'ISO-10646-Unicode-Latin1';
10295  
10296              case 'csiso10646utf1':
10297              case 'iso10646utf1':
10298                  return 'ISO-10646-UTF-1';
10299  
10300              case 'csiso115481':
10301              case 'iso115481':
10302              case 'isotr115481':
10303                  return 'ISO-11548-1';
10304  
10305              case 'csiso90':
10306              case 'isoir90':
10307                  return 'iso-ir-90';
10308  
10309              case 'csunicodeibm1261':
10310              case 'isounicodeibm1261':
10311                  return 'ISO-Unicode-IBM-1261';
10312  
10313              case 'csunicodeibm1264':
10314              case 'isounicodeibm1264':
10315                  return 'ISO-Unicode-IBM-1264';
10316  
10317              case 'csunicodeibm1265':
10318              case 'isounicodeibm1265':
10319                  return 'ISO-Unicode-IBM-1265';
10320  
10321              case 'csunicodeibm1268':
10322              case 'isounicodeibm1268':
10323                  return 'ISO-Unicode-IBM-1268';
10324  
10325              case 'csunicodeibm1276':
10326              case 'isounicodeibm1276':
10327                  return 'ISO-Unicode-IBM-1276';
10328  
10329              case 'csiso646basic1983':
10330              case 'iso646basic1983':
10331              case 'ref':
10332                  return 'ISO_646.basic:1983';
10333  
10334              case 'csiso2intlrefversion':
10335              case 'irv':
10336              case 'iso646irv1983':
10337              case 'isoir2':
10338                  return 'ISO_646.irv:1983';
10339  
10340              case 'csiso2033':
10341              case 'e13b':
10342              case 'iso20331983':
10343              case 'isoir98':
10344                  return 'ISO_2033-1983';
10345  
10346              case 'csiso5427cyrillic':
10347              case 'iso5427':
10348              case 'isoir37':
10349                  return 'ISO_5427';
10350  
10351              case 'iso5427cyrillic1981':
10352              case 'iso54271981':
10353              case 'isoir54':
10354                  return 'ISO_5427:1981';
10355  
10356              case 'csiso5428greek':
10357              case 'iso54281980':
10358              case 'isoir55':
10359                  return 'ISO_5428:1980';
10360  
10361              case 'csiso6937add':
10362              case 'iso6937225':
10363              case 'isoir152':
10364                  return 'ISO_6937-2-25';
10365  
10366              case 'csisotextcomm':
10367              case 'iso69372add':
10368              case 'isoir142':
10369                  return 'ISO_6937-2-add';
10370  
10371              case 'csiso8859supp':
10372              case 'iso8859supp':
10373              case 'isoir154':
10374              case 'latin125':
10375                  return 'ISO_8859-supp';
10376  
10377              case 'csiso10367box':
10378              case 'iso10367box':
10379              case 'isoir155':
10380                  return 'ISO_10367-box';
10381  
10382              case 'csiso15italian':
10383              case 'iso646it':
10384              case 'isoir15':
10385              case 'it':
10386                  return 'IT';
10387  
10388              case 'csiso13jisc6220jp':
10389              case 'isoir13':
10390              case 'jisc62201969':
10391              case 'jisc62201969jp':
10392              case 'katakana':
10393              case 'x2017':
10394                  return 'JIS_C6220-1969-jp';
10395  
10396              case 'csiso14jisc6220ro':
10397              case 'iso646jp':
10398              case 'isoir14':
10399              case 'jisc62201969ro':
10400              case 'jp':
10401                  return 'JIS_C6220-1969-ro';
10402  
10403              case 'csiso42jisc62261978':
10404              case 'isoir42':
10405              case 'jisc62261978':
10406                  return 'JIS_C6226-1978';
10407  
10408              case 'csiso87jisx208':
10409              case 'isoir87':
10410              case 'jisc62261983':
10411              case 'jisx2081983':
10412              case 'x208':
10413                  return 'JIS_C6226-1983';
10414  
10415              case 'csiso91jisc62291984a':
10416              case 'isoir91':
10417              case 'jisc62291984a':
10418              case 'jpocra':
10419                  return 'JIS_C6229-1984-a';
10420  
10421              case 'csiso92jisc62991984b':
10422              case 'iso646jpocrb':
10423              case 'isoir92':
10424              case 'jisc62291984b':
10425              case 'jpocrb':
10426                  return 'JIS_C6229-1984-b';
10427  
10428              case 'csiso93jis62291984badd':
10429              case 'isoir93':
10430              case 'jisc62291984badd':
10431              case 'jpocrbadd':
10432                  return 'JIS_C6229-1984-b-add';
10433  
10434              case 'csiso94jis62291984hand':
10435              case 'isoir94':
10436              case 'jisc62291984hand':
10437              case 'jpocrhand':
10438                  return 'JIS_C6229-1984-hand';
10439  
10440              case 'csiso95jis62291984handadd':
10441              case 'isoir95':
10442              case 'jisc62291984handadd':
10443              case 'jpocrhandadd':
10444                  return 'JIS_C6229-1984-hand-add';
10445  
10446              case 'csiso96jisc62291984kana':
10447              case 'isoir96':
10448              case 'jisc62291984kana':
10449                  return 'JIS_C6229-1984-kana';
10450  
10451              case 'csjisencoding':
10452              case 'jisencoding':
10453                  return 'JIS_Encoding';
10454  
10455              case 'cshalfwidthkatakana':
10456              case 'jisx201':
10457              case 'x201':
10458                  return 'JIS_X0201';
10459  
10460              case 'csiso159jisx2121990':
10461              case 'isoir159':
10462              case 'jisx2121990':
10463              case 'x212':
10464                  return 'JIS_X0212-1990';
10465  
10466              case 'csiso141jusib1002':
10467              case 'iso646yu':
10468              case 'isoir141':
10469              case 'js':
10470              case 'jusib1002':
10471              case 'yu':
10472                  return 'JUS_I.B1.002';
10473  
10474              case 'csiso147macedonian':
10475              case 'isoir147':
10476              case 'jusib1003mac':
10477              case 'macedonian':
10478                  return 'JUS_I.B1.003-mac';
10479  
10480              case 'csiso146serbian':
10481              case 'isoir146':
10482              case 'jusib1003serb':
10483              case 'serbian':
10484                  return 'JUS_I.B1.003-serb';
10485  
10486              case 'koi7switched':
10487                  return 'KOI7-switched';
10488  
10489              case 'cskoi8r':
10490              case 'koi8r':
10491                  return 'KOI8-R';
10492  
10493              case 'koi8u':
10494                  return 'KOI8-U';
10495  
10496              case 'csksc5636':
10497              case 'iso646kr':
10498              case 'ksc5636':
10499                  return 'KSC5636';
10500  
10501              case 'cskz1048':
10502              case 'kz1048':
10503              case 'rk1048':
10504              case 'strk10482002':
10505                  return 'KZ-1048';
10506  
10507              case 'csiso19latingreek':
10508              case 'isoir19':
10509              case 'latingreek':
10510                  return 'latin-greek';
10511  
10512              case 'csiso27latingreek1':
10513              case 'isoir27':
10514              case 'latingreek1':
10515                  return 'Latin-greek-1';
10516  
10517              case 'csiso158lap':
10518              case 'isoir158':
10519              case 'lap':
10520              case 'latinlap':
10521                  return 'latin-lap';
10522  
10523              case 'csmacintosh':
10524              case 'mac':
10525              case 'macintosh':
10526                  return 'macintosh';
10527  
10528              case 'csmicrosoftpublishing':
10529              case 'microsoftpublishing':
10530                  return 'Microsoft-Publishing';
10531  
10532              case 'csmnem':
10533              case 'mnem':
10534                  return 'MNEM';
10535  
10536              case 'csmnemonic':
10537              case 'mnemonic':
10538                  return 'MNEMONIC';
10539  
10540              case 'csiso86hungarian':
10541              case 'hu':
10542              case 'iso646hu':
10543              case 'isoir86':
10544              case 'msz77953':
10545                  return 'MSZ_7795.3';
10546  
10547              case 'csnatsdano':
10548              case 'isoir91':
10549              case 'natsdano':
10550                  return 'NATS-DANO';
10551  
10552              case 'csnatsdanoadd':
10553              case 'isoir92':
10554              case 'natsdanoadd':
10555                  return 'NATS-DANO-ADD';
10556  
10557              case 'csnatssefi':
10558              case 'isoir81':
10559              case 'natssefi':
10560                  return 'NATS-SEFI';
10561  
10562              case 'csnatssefiadd':
10563              case 'isoir82':
10564              case 'natssefiadd':
10565                  return 'NATS-SEFI-ADD';
10566  
10567              case 'csiso151cuba':
10568              case 'cuba':
10569              case 'iso646cu':
10570              case 'isoir151':
10571              case 'ncnc1081':
10572                  return 'NC_NC00-10:81';
10573  
10574              case 'csiso69french':
10575              case 'fr':
10576              case 'iso646fr':
10577              case 'isoir69':
10578              case 'nfz62010':
10579                  return 'NF_Z_62-010';
10580  
10581              case 'csiso25french':
10582              case 'iso646fr1':
10583              case 'isoir25':
10584              case 'nfz620101973':
10585                  return 'NF_Z_62-010_(1973)';
10586  
10587              case 'csiso60danishnorwegian':
10588              case 'csiso60norwegian1':
10589              case 'iso646no':
10590              case 'isoir60':
10591              case 'no':
10592              case 'ns45511':
10593                  return 'NS_4551-1';
10594  
10595              case 'csiso61norwegian2':
10596              case 'iso646no2':
10597              case 'isoir61':
10598              case 'no2':
10599              case 'ns45512':
10600                  return 'NS_4551-2';
10601  
10602              case 'osdebcdicdf3irv':
10603                  return 'OSD_EBCDIC_DF03_IRV';
10604  
10605              case 'osdebcdicdf41':
10606                  return 'OSD_EBCDIC_DF04_1';
10607  
10608              case 'osdebcdicdf415':
10609                  return 'OSD_EBCDIC_DF04_15';
10610  
10611              case 'cspc8danishnorwegian':
10612              case 'pc8danishnorwegian':
10613                  return 'PC8-Danish-Norwegian';
10614  
10615              case 'cspc8turkish':
10616              case 'pc8turkish':
10617                  return 'PC8-Turkish';
10618  
10619              case 'csiso16portuguese':
10620              case 'iso646pt':
10621              case 'isoir16':
10622              case 'pt':
10623                  return 'PT';
10624  
10625              case 'csiso84portuguese2':
10626              case 'iso646pt2':
10627              case 'isoir84':
10628              case 'pt2':
10629                  return 'PT2';
10630  
10631              case 'cp154':
10632              case 'csptcp154':
10633              case 'cyrillicasian':
10634              case 'pt154':
10635              case 'ptcp154':
10636                  return 'PTCP154';
10637  
10638              case 'scsu':
10639                  return 'SCSU';
10640  
10641              case 'csiso10swedish':
10642              case 'fi':
10643              case 'iso646fi':
10644              case 'iso646se':
10645              case 'isoir10':
10646              case 'se':
10647              case 'sen850200b':
10648                  return 'SEN_850200_B';
10649  
10650              case 'csiso11swedishfornames':
10651              case 'iso646se2':
10652              case 'isoir11':
10653              case 'se2':
10654              case 'sen850200c':
10655                  return 'SEN_850200_C';
10656  
10657              case 'csiso102t617bit':
10658              case 'isoir102':
10659              case 't617bit':
10660                  return 'T.61-7bit';
10661  
10662              case 'csiso103t618bit':
10663              case 'isoir103':
10664              case 't61':
10665              case 't618bit':
10666                  return 'T.61-8bit';
10667  
10668              case 'csiso128t101g2':
10669              case 'isoir128':
10670              case 't101g2':
10671                  return 'T.101-G2';
10672  
10673              case 'cstscii':
10674              case 'tscii':
10675                  return 'TSCII';
10676  
10677              case 'csunicode11':
10678              case 'unicode11':
10679                  return 'UNICODE-1-1';
10680  
10681              case 'csunicode11utf7':
10682              case 'unicode11utf7':
10683                  return 'UNICODE-1-1-UTF-7';
10684  
10685              case 'csunknown8bit':
10686              case 'unknown8bit':
10687                  return 'UNKNOWN-8BIT';
10688  
10689              case 'ansix341968':
10690              case 'ansix341986':
10691              case 'ascii':
10692              case 'cp367':
10693              case 'csascii':
10694              case 'ibm367':
10695              case 'iso646irv1991':
10696              case 'iso646us':
10697              case 'isoir6':
10698              case 'us':
10699              case 'usascii':
10700                  return 'US-ASCII';
10701  
10702              case 'csusdk':
10703              case 'usdk':
10704                  return 'us-dk';
10705  
10706              case 'utf7':
10707                  return 'UTF-7';
10708  
10709              case 'utf8':
10710                  return 'UTF-8';
10711  
10712              case 'utf16':
10713                  return 'UTF-16';
10714  
10715              case 'utf16be':
10716                  return 'UTF-16BE';
10717  
10718              case 'utf16le':
10719                  return 'UTF-16LE';
10720  
10721              case 'utf32':
10722                  return 'UTF-32';
10723  
10724              case 'utf32be':
10725                  return 'UTF-32BE';
10726  
10727              case 'utf32le':
10728                  return 'UTF-32LE';
10729  
10730              case 'csventurainternational':
10731              case 'venturainternational':
10732                  return 'Ventura-International';
10733  
10734              case 'csventuramath':
10735              case 'venturamath':
10736                  return 'Ventura-Math';
10737  
10738              case 'csventuraus':
10739              case 'venturaus':
10740                  return 'Ventura-US';
10741  
10742              case 'csiso70videotexsupp1':
10743              case 'isoir70':
10744              case 'videotexsuppl':
10745                  return 'videotex-suppl';
10746  
10747              case 'csviqr':
10748              case 'viqr':
10749                  return 'VIQR';
10750  
10751              case 'csviscii':
10752              case 'viscii':
10753                  return 'VISCII';
10754  
10755              case 'csshiftjis':
10756              case 'cswindows31j':
10757              case 'mskanji':
10758              case 'shiftjis':
10759              case 'windows31j':
10760                  return 'Windows-31J';
10761  
10762              case 'iso885911':
10763              case 'tis620':
10764                  return 'windows-874';
10765  
10766              case 'cseuckr':
10767              case 'csksc56011987':
10768              case 'euckr':
10769              case 'isoir149':
10770              case 'korean':
10771              case 'ksc5601':
10772              case 'ksc56011987':
10773              case 'ksc56011989':
10774              case 'windows949':
10775                  return 'windows-949';
10776  
10777              case 'windows1250':
10778                  return 'windows-1250';
10779  
10780              case 'windows1251':
10781                  return 'windows-1251';
10782  
10783              case 'cp819':
10784              case 'csisolatin1':
10785              case 'ibm819':
10786              case 'iso88591':
10787              case 'iso885911987':
10788              case 'isoir100':
10789              case 'l1':
10790              case 'latin1':
10791              case 'windows1252':
10792                  return 'windows-1252';
10793  
10794              case 'windows1253':
10795                  return 'windows-1253';
10796  
10797              case 'csisolatin5':
10798              case 'iso88599':
10799              case 'iso885991989':
10800              case 'isoir148':
10801              case 'l5':
10802              case 'latin5':
10803              case 'windows1254':
10804                  return 'windows-1254';
10805  
10806              case 'windows1255':
10807                  return 'windows-1255';
10808  
10809              case 'windows1256':
10810                  return 'windows-1256';
10811  
10812              case 'windows1257':
10813                  return 'windows-1257';
10814  
10815              case 'windows1258':
10816                  return 'windows-1258';
10817  
10818              default:
10819                  return $charset;
10820          }
10821      }
10822  
10823  	function get_curl_version()
10824      {
10825          if (is_array($curl = curl_version()))
10826          {
10827              $curl = $curl['version'];
10828          }
10829          elseif (substr($curl, 0, 5) === 'curl/')
10830          {
10831              $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
10832          }
10833          elseif (substr($curl, 0, 8) === 'libcurl/')
10834          {
10835              $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
10836          }
10837          else
10838          {
10839              $curl = 0;
10840          }
10841          return $curl;
10842      }
10843  
10844  	function is_subclass_of($class1, $class2)
10845      {
10846          if (func_num_args() !== 2)
10847          {
10848              trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING);
10849          }
10850          elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1))
10851          {
10852              return is_subclass_of($class1, $class2);
10853          }
10854          elseif (is_string($class1) && is_string($class2))
10855          {
10856              if (class_exists($class1))
10857              {
10858                  if (class_exists($class2))
10859                  {
10860                      $class2 = strtolower($class2);
10861                      while ($class1 = strtolower(get_parent_class($class1)))
10862                      {
10863                          if ($class1 === $class2)
10864                          {
10865                              return true;
10866                          }
10867                      }
10868                  }
10869              }
10870              else
10871              {
10872                  trigger_error('Unknown class passed as parameter', E_USER_WARNNG);
10873              }
10874          }
10875          return false;
10876      }
10877  
10878      /**
10879       * Strip HTML comments
10880       *
10881       * @access public
10882       * @param string $data Data to strip comments from
10883       * @return string Comment stripped string
10884       */
10885  	function strip_comments($data)
10886      {
10887          $output = '';
10888          while (($start = strpos($data, '<!--')) !== false)
10889          {
10890              $output .= substr($data, 0, $start);
10891              if (($end = strpos($data, '-->', $start)) !== false)
10892              {
10893                  $data = substr_replace($data, '', 0, $end + 3);
10894              }
10895              else
10896              {
10897                  $data = '';
10898              }
10899          }
10900          return $output . $data;
10901      }
10902  
10903  	function parse_date($dt)
10904      {
10905          $parser = SimplePie_Parse_Date::get();
10906          return $parser->parse($dt);
10907      }
10908  
10909      /**
10910       * Decode HTML entities
10911       *
10912       * @static
10913       * @access public
10914       * @param string $data Input data
10915       * @return string Output data
10916       */
10917  	function entities_decode($data)
10918      {
10919          $decoder =& new SimplePie_Decode_HTML_Entities($data);
10920          return $decoder->parse();
10921      }
10922  
10923      /**
10924       * Remove RFC822 comments
10925       *
10926       * @access public
10927       * @param string $data Data to strip comments from
10928       * @return string Comment stripped string
10929       */
10930  	function uncomment_rfc822($string)
10931      {
10932          $string = (string) $string;
10933          $position = 0;
10934          $length = strlen($string);
10935          $depth = 0;
10936  
10937          $output = '';
10938  
10939          while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
10940          {
10941              $output .= substr($string, $position, $pos - $position);
10942              $position = $pos + 1;
10943              if ($string[$pos - 1] !== '\\')
10944              {
10945                  $depth++;
10946                  while ($depth && $position < $length)
10947                  {
10948                      $position += strcspn($string, '()', $position);
10949                      if ($string[$position - 1] === '\\')
10950                      {
10951                          $position++;
10952                          continue;
10953                      }
10954                      elseif (isset($string[$position]))
10955                      {
10956                          switch ($string[$position])
10957                          {
10958                              case '(':
10959                                  $depth++;
10960                                  break;
10961  
10962                              case ')':
10963                                  $depth--;
10964                                  break;
10965                          }
10966                          $position++;
10967                      }
10968                      else
10969                      {
10970                          break;
10971                      }
10972                  }
10973              }
10974              else
10975              {
10976                  $output .= '(';
10977              }
10978          }
10979          $output .= substr($string, $position);
10980  
10981          return $output;
10982      }
10983  
10984  	function parse_mime($mime)
10985      {
10986          if (($pos = strpos($mime, ';')) === false)
10987          {
10988              return trim($mime);
10989          }
10990          else
10991          {
10992              return trim(substr($mime, 0, $pos));
10993          }
10994      }
10995  
10996  	function htmlspecialchars_decode($string, $quote_style)
10997      {
10998          if (function_exists('htmlspecialchars_decode'))
10999          {
11000              return htmlspecialchars_decode($string, $quote_style);
11001          }
11002          else
11003          {
11004              return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
11005          }
11006      }
11007  
11008  	function atom_03_construct_type($attribs)
11009      {
11010          if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
11011          {
11012              $mode = SIMPLEPIE_CONSTRUCT_BASE64;
11013          }
11014          else
11015          {
11016              $mode = SIMPLEPIE_CONSTRUCT_NONE;
11017          }
11018          if (isset($attribs['']['type']))
11019          {
11020              switch (strtolower(trim($attribs['']['type'])))
11021              {
11022                  case 'text':
11023                  case 'text/plain':
11024                      return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
11025  
11026                  case 'html':
11027                  case 'text/html':
11028                      return SIMPLEPIE_CONSTRUCT_HTML | $mode;
11029  
11030                  case 'xhtml':
11031                  case 'application/xhtml+xml':
11032                      return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
11033  
11034                  default:
11035                      return SIMPLEPIE_CONSTRUCT_NONE | $mode;
11036              }
11037          }
11038          else
11039          {
11040              return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
11041          }
11042      }
11043  
11044  	function atom_10_construct_type($attribs)
11045      {
11046          if (isset($attribs['']['type']))
11047          {
11048              switch (strtolower(trim($attribs['']['type'])))
11049              {
11050                  case 'text':
11051                      return SIMPLEPIE_CONSTRUCT_TEXT;
11052  
11053                  case 'html':
11054                      return SIMPLEPIE_CONSTRUCT_HTML;
11055  
11056                  case 'xhtml':
11057                      return SIMPLEPIE_CONSTRUCT_XHTML;
11058  
11059                  default:
11060                      return SIMPLEPIE_CONSTRUCT_NONE;
11061              }
11062          }
11063          return SIMPLEPIE_CONSTRUCT_TEXT;
11064      }
11065  
11066  	function atom_10_content_construct_type($attribs)
11067      {
11068          if (isset($attribs['']['type']))
11069          {
11070              $type = strtolower(trim($attribs['']['type']));
11071              switch ($type)
11072              {
11073                  case 'text':
11074                      return SIMPLEPIE_CONSTRUCT_TEXT;
11075  
11076                  case 'html':
11077                      return SIMPLEPIE_CONSTRUCT_HTML;
11078  
11079                  case 'xhtml':
11080                      return SIMPLEPIE_CONSTRUCT_XHTML;
11081              }
11082              if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
11083              {
11084                  return SIMPLEPIE_CONSTRUCT_NONE;
11085              }
11086              else
11087              {
11088                  return SIMPLEPIE_CONSTRUCT_BASE64;
11089              }
11090          }
11091          else
11092          {
11093              return SIMPLEPIE_CONSTRUCT_TEXT;
11094          }
11095      }
11096  
11097  	function is_isegment_nz_nc($string)
11098      {
11099          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);
11100      }
11101  
11102  	function space_seperated_tokens($string)
11103      {
11104          $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
11105          $string_length = strlen($string);
11106  
11107          $position = strspn($string, $space_characters);
11108          $tokens = array();
11109  
11110          while ($position < $string_length)
11111          {
11112              $len = strcspn($string, $space_characters, $position);
11113              $tokens[] = substr($string, $position, $len);
11114              $position += $len;
11115              $position += strspn($string, $space_characters, $position);
11116          }
11117  
11118          return $tokens;
11119      }
11120  
11121  	function array_unique($array)
11122      {
11123          if (version_compare(PHP_VERSION, '5.2', '>='))
11124          {
11125              return array_unique($array);
11126          }
11127          else
11128          {
11129              $array = (array) $array;
11130              $new_array = array();
11131              $new_array_strings = array();
11132              foreach ($array as $key => $value)
11133              {
11134                  if (is_object($value))
11135                  {
11136                      if (method_exists($value, '__toString'))
11137                      {
11138                          $cmp = $value->__toString();
11139                      }
11140                      else
11141                      {
11142                          trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR);
11143                      }
11144                  }
11145                  elseif (is_array($value))
11146                  {
11147                      $cmp = (string) reset($value);
11148                  }
11149                  else
11150                  {
11151                      $cmp = (string) $value;
11152                  }
11153                  if (!in_array($cmp, $new_array_strings))
11154                  {
11155                      $new_array[$key] = $value;
11156                      $new_array_strings[] = $cmp;
11157                  }
11158              }
11159              return $new_array;
11160          }
11161      }
11162  
11163      /**
11164       * Converts a unicode codepoint to a UTF-8 character
11165       *
11166       * @static
11167       * @access public
11168       * @param int $codepoint Unicode codepoint
11169       * @return string UTF-8 character
11170       */
11171  	function codepoint_to_utf8($codepoint)
11172      {
11173          $codepoint = (int) $codepoint;
11174          if ($codepoint < 0)
11175          {
11176              return false;
11177          }
11178          else if ($codepoint <= 0x7f)
11179          {
11180              return chr($codepoint);
11181          }
11182          else if ($codepoint <= 0x7ff)
11183          {
11184              return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
11185          }
11186          else if ($codepoint <= 0xffff)
11187          {
11188              return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11189          }
11190          else if ($codepoint <= 0x10ffff)
11191          {
11192              return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
11193          }
11194          else
11195          {
11196              // U+FFFD REPLACEMENT CHARACTER
11197              return "\xEF\xBF\xBD";
11198          }
11199      }
11200  
11201      /**
11202       * Re-implementation of PHP 5's stripos()
11203       *
11204       * Returns the numeric position of the first occurrence of needle in the
11205       * haystack string.
11206       *
11207       * @static
11208       * @access string
11209       * @param object $haystack
11210       * @param string $needle Note that the needle may be a string of one or more
11211       *     characters. If needle is not a string, it is converted to an integer
11212       *     and applied as the ordinal value of a character.
11213       * @param int $offset The optional offset parameter allows you to specify which
11214       *     character in haystack to start searching. The position returned is still
11215       *     relative to the beginning of haystack.
11216       * @return bool If needle is not found, stripos() will return boolean false.
11217       */
11218  	function stripos($haystack, $needle, $offset = 0)
11219      {
11220          if (function_exists('stripos'))
11221          {
11222              return stripos($haystack, $needle, $offset);
11223          }
11224          else
11225          {
11226              if (is_string($needle))
11227              {
11228                  $needle = strtolower($needle);
11229              }
11230              elseif (is_int($needle) || is_bool($needle) || is_double($needle))
11231              {
11232                  $needle = strtolower(chr($needle));
11233              }
11234              else
11235              {
11236                  trigger_error('needle is not a string or an integer', E_USER_WARNING);
11237                  return false;
11238              }
11239  
11240              return strpos(strtolower($haystack), $needle, $offset);
11241          }
11242      }
11243  
11244      /**
11245       * Similar to parse_str()
11246       *
11247       * Returns an associative array of name/value pairs, where the value is an
11248       * array of values that have used the same name
11249       *
11250       * @static
11251       * @access string
11252       * @param string $str The input string.
11253       * @return array
11254       */
11255  	function parse_str($str)
11256      {
11257          $return = array();
11258          $str = explode('&', $str);
11259  
11260          foreach ($str as $section)
11261          {
11262              if (strpos($section, '=') !== false)
11263              {
11264                  list($name, $value) = explode('=', $section, 2);
11265                  $return[urldecode($name)][] = urldecode($value);
11266              }
11267              else
11268              {
11269                  $return[urldecode($section)][] = null;
11270              }
11271          }
11272  
11273          return $return;
11274      }
11275  
11276      /**
11277       * Detect XML encoding, as per XML 1.0 Appendix F.1
11278       *
11279       * @todo Add support for EBCDIC
11280       * @param string $data XML data
11281       * @return array Possible encodings
11282       */
11283  	function xml_encoding($data)
11284      {
11285          // UTF-32 Big Endian BOM
11286          if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
11287          {
11288              $encoding[] = 'UTF-32BE';
11289          }
11290          // UTF-32 Little Endian BOM
11291          elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
11292          {
11293              $encoding[] = 'UTF-32LE';
11294          }
11295          // UTF-16 Big Endian BOM
11296          elseif (substr($data, 0, 2) === "\xFE\xFF")
11297          {
11298              $encoding[] = 'UTF-16BE';
11299          }
11300          // UTF-16 Little Endian BOM
11301          elseif (substr($data, 0, 2) === "\xFF\xFE")
11302          {
11303              $encoding[] = 'UTF-16LE';
11304          }
11305          // UTF-8 BOM
11306          elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
11307          {
11308              $encoding[] = 'UTF-8';
11309          }
11310          // UTF-32 Big Endian Without BOM
11311          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")
11312          {
11313              if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
11314              {
11315                  $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8'));
11316                  if ($parser->parse())
11317                  {
11318                      $encoding[] = $parser->encoding;
11319                  }
11320              }
11321              $encoding[] = 'UTF-32BE';
11322          }
11323          // UTF-32 Little Endian Without BOM
11324          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")
11325          {
11326              if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
11327              {
11328                  $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8'));
11329                  if ($parser->parse())
11330                  {
11331                      $encoding[] = $parser->encoding;
11332                  }
11333              }
11334              $encoding[] = 'UTF-32LE';
11335          }
11336          // UTF-16 Big Endian Without BOM
11337          elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
11338          {
11339              if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
11340              {
11341                  $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8'));
11342                  if ($parser->parse())
11343                  {
11344                      $encoding[] = $parser->encoding;
11345                  }
11346              }
11347              $encoding[] = 'UTF-16BE';
11348          }
11349          // UTF-16 Little Endian Without BOM
11350          elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
11351          {
11352              if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
11353              {
11354                  $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8'));
11355                  if ($parser->parse())
11356                  {
11357                      $encoding[] = $parser->encoding;
11358                  }
11359              }
11360              $encoding[] = 'UTF-16LE';
11361          }
11362          // US-ASCII (or superset)
11363          elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
11364          {
11365              if ($pos = strpos($data, "\x3F\x3E"))
11366              {
11367                  $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
11368                  if ($parser->parse())
11369                  {
11370                      $encoding[] = $parser->encoding;
11371                  }
11372              }
11373              $encoding[] = 'UTF-8';
11374          }
11375          // Fallback to UTF-8
11376          else
11377          {
11378              $encoding[] = 'UTF-8';
11379          }
11380          return $encoding;
11381      }
11382  
11383  	function output_javascript()
11384      {
11385          if (function_exists('ob_gzhandler'))
11386          {
11387              ob_start('ob_gzhandler');
11388          }
11389          header('Content-type: text/javascript; charset: UTF-8');
11390          header('Cache-Control: must-revalidate');
11391          header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
11392          ?>
11393  function embed_odeo(link) {
11394      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>');
11395  }
11396  
11397  function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
11398      if (placeholder != '') {
11399          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>');
11400      }
11401      else {
11402          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>');
11403      }
11404  }
11405  
11406  function embed_flash(bgcolor, width, height, link, loop, type) {
11407      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>');
11408  }
11409  
11410  function embed_flv(width, height, link, placeholder, loop, player) {
11411      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>');
11412  }
11413  
11414  function embed_wmedia(width, height, link) {
11415      document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
11416  }
11417          <?php
11418      }
11419  }
11420  
11421  /**
11422   * Decode HTML Entities
11423   *
11424   * This implements HTML5 as of revision 967 (2007-06-28)
11425   *
11426   * @package SimplePie
11427   */
11428  class SimplePie_Decode_HTML_Entities
11429  {
11430      /**
11431       * Data to be parsed
11432       *
11433       * @access private
11434       * @var string
11435       */
11436      var $data = '';
11437  
11438      /**
11439       * Currently consumed bytes
11440       *
11441       * @access private
11442       * @var string
11443       */
11444      var $consumed = '';
11445  
11446      /**
11447       * Position of the current byte being parsed
11448       *
11449       * @access private
11450       * @var int
11451       */
11452      var $position = 0;
11453  
11454      /**
11455       * Create an instance of the class with the input data
11456       *
11457       * @access public
11458       * @param string $data Input data
11459       */
11460  	function SimplePie_Decode_HTML_Entities($data)
11461      {
11462          $this->data = $data;
11463      }
11464  
11465      /**
11466       * Parse the input data
11467       *
11468       * @access public
11469       * @return string Output data
11470       */
11471  	function parse()
11472      {
11473          while (($this->position = strpos($this->data, '&', $this->position)) !== false)
11474          {
11475              $this->consume();
11476              $this->entity();
11477              $this->consumed = '';
11478          }
11479          return $this->data;
11480      }
11481  
11482      /**
11483       * Consume the next byte
11484       *
11485       * @access private
11486       * @return mixed The next byte, or false, if there is no more data
11487       */
11488  	function consume()
11489      {
11490          if (isset($this->data[$this->position]))
11491          {
11492              $this->consumed .= $this->data[$this->position];
11493              return $this->data[$this->position++];
11494          }
11495          else
11496          {
11497              return false;
11498          }
11499      }
11500  
11501      /**
11502       * Consume a range of characters
11503       *
11504       * @access private
11505       * @param string $chars Characters to consume
11506       * @return mixed A series of characters that match the range, or false
11507       */
11508  	function consume_range($chars)
11509      {
11510          if ($len = strspn($this->data, $chars, $this->position))
11511          {
11512              $data = substr($this->data, $this->position, $len);
11513              $this->consumed .= $data;
11514              $this->position += $len;
11515              return $data;
11516          }
11517          else
11518          {
11519              return false;
11520          }
11521      }
11522  
11523      /**
11524       * Unconsume one byte
11525       *
11526       * @access private
11527       */
11528  	function unconsume()
11529      {
11530          $this->consumed = substr($this->consumed, 0, -1);
11531          $this->position--;
11532      }
11533  
11534      /**
11535       * Decode an entity
11536       *
11537       * @access private
11538       */
11539  	function entity()
11540      {
11541          switch ($this->consume())
11542          {
11543              case "\x09":
11544              case "\x0A":
11545              case "\x0B":
11546              case "\x0B":
11547              case "\x0C":
11548              case "\x20":
11549              case "\x3C":
11550              case "\x26":
11551              case false:
11552                  break;
11553  
11554              case "\x23":
11555                  switch ($this->consume())
11556                  {
11557                      case "\x78":
11558                      case "\x58":
11559                          $range = '0123456789ABCDEFabcdef';
11560                          $hex = true;
11561                          break;
11562  
11563                      default:
11564                          $range = '0123456789';
11565                          $hex = false;
11566                          $this->unconsume();
11567                          break;
11568                  }
11569  
11570                  if ($codepoint = $this->consume_range($range))
11571                  {
11572                      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");
11573  
11574                      if ($hex)
11575                      {
11576                          $codepoint = hexdec($codepoint);
11577                      }
11578                      else
11579                      {
11580                          $codepoint = intval($codepoint);
11581                      }
11582  
11583                      if (isset($windows_1252_specials[$codepoint]))
11584                      {
11585                          $replacement = $windows_1252_specials[$codepoint];
11586                      }
11587                      else
11588                      {
11589                          $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
11590                      }
11591  
11592                      if (!in_array($this->consume(), array(';', false), true))
11593                      {
11594                          $this->unconsume();
11595                      }
11596  
11597                      $consumed_length = strlen($this->consumed);
11598                      $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
11599                      $this->position += strlen($replacement) - $consumed_length;
11600                  }
11601                  break;
11602  
11603              default:
11604                  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");
11605  
11606                  for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
11607                  {
11608                      $consumed = substr($this->consumed, 1);
11609                      if (isset($entities[$consumed]))
11610                      {
11611                          $match = $consumed;
11612                      }
11613                  }
11614  
11615                  if ($match !== null)
11616                  {
11617                       $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
11618                      $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
11619                  }
11620                  break;
11621          }
11622      }
11623  }
11624  
11625  /**
11626   * IRI parser/serialiser
11627   *
11628   * @package SimplePie
11629   */
11630  class SimplePie_IRI
11631  {
11632      /**
11633       * Scheme
11634       *
11635       * @access private
11636       * @var string
11637       */
11638      var $scheme;
11639  
11640      /**
11641       * User Information
11642       *
11643       * @access private
11644       * @var string
11645       */
11646      var $userinfo;
11647  
11648      /**
11649       * Host
11650       *
11651       * @access private
11652       * @var string
11653       */
11654      var $host;
11655  
11656      /**
11657       * Port
11658       *
11659       * @access private
11660       * @var string
11661       */
11662      var $port;
11663  
11664      /**
11665       * Path
11666       *
11667       * @access private
11668       * @var string
11669       */
11670      var $path;
11671  
11672      /**
11673       * Query
11674       *
11675       * @access private
11676       * @var string
11677       */
11678      var $query;
11679  
11680      /**
11681       * Fragment
11682       *
11683       * @access private
11684       * @var string
11685       */
11686      var $fragment;
11687  
11688      /**
11689       * Whether the object represents a valid IRI
11690       *
11691       * @access private
11692       * @var array
11693       */
11694      var $valid = array();
11695  
11696      /**
11697       * Return the entire IRI when you try and read the object as a string
11698       *
11699       * @access public
11700       * @return string
11701       */
11702  	function __toString()
11703      {
11704          return $this->get_iri();
11705      }
11706  
11707      /**
11708       * Create a new IRI object, from a specified string
11709       *
11710       * @access public
11711       * @param string $iri
11712       * @return SimplePie_IRI
11713       */
11714  	function SimplePie_IRI($iri)
11715      {
11716          $iri = (string) $iri;
11717          if ($iri !== '')
11718          {
11719              $parsed = $this->parse_iri($iri);
11720              $this->set_scheme($parsed['scheme']);
11721              $this->set_authority($parsed['authority']);
11722              $this->set_path($parsed['path']);
11723              $this->set_query($parsed['query']);
11724              $this->set_fragment($parsed['fragment']);
11725          }
11726      }
11727  
11728      /**
11729       * Create a new IRI object by resolving a relative IRI
11730       *
11731       * @static
11732       * @access public
11733       * @param SimplePie_IRI $base Base IRI
11734       * @param string $relative Relative IRI
11735       * @return SimplePie_IRI
11736       */
11737  	function absolutize($base, $relative)
11738      {
11739          $relative = (string) $relative;
11740          if ($relative !== '')
11741          {
11742              $relative =& new SimplePie_IRI($relative);
11743              if ($relative->get_scheme() !== null)
11744              {
11745                  $target = $relative;
11746              }
11747              elseif ($base->get_iri() !== null)
11748              {
11749                  if ($relative->get_authority() !== null)
11750                  {
11751                      $target = $relative;
11752                      $target->set_scheme($base->get_scheme());
11753                  }
11754                  else
11755                  {
11756                      $target =& new SimplePie_IRI('');
11757                      $target->set_scheme($base->get_scheme());
11758                      $target->set_userinfo($base->get_userinfo());
11759                      $target->set_host($base->get_host());
11760                      $target->set_port($base->get_port());
11761                      if ($relative->get_path() !== null)
11762                      {
11763                          if (strpos($relative->get_path(), '/') === 0)
11764                          {
11765                              $target->set_path($relative->get_path());
11766                          }
11767                          elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null)
11768                          {
11769                              $target->set_path('/' . $relative->get_path());
11770                          }
11771                          elseif (($last_segment = strrpos($base->get_path(), '/')) !== false)
11772                          {
11773                              $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path());
11774                          }
11775                          else
11776                          {
11777                              $target->set_path($relative->get_path());
11778                          }
11779                          $target->set_query($relative->get_query());
11780                      }
11781                      else
11782                      {
11783                          $target->set_path($base->get_path());
11784                          if ($relative->get_query() !== null)
11785                          {
11786                              $target->set_query($relative->get_query());
11787                          }
11788                          elseif ($base->get_query() !== null)
11789                          {
11790                              $target->set_query($base->get_query());
11791                          }
11792                      }
11793                  }
11794                  $target->set_fragment($relative->get_fragment());
11795              }
11796              else
11797              {
11798                  // No base URL, just return the relative URL
11799                  $target = $relative;
11800              }
11801          }
11802          else
11803          {
11804              $target = $base;
11805          }
11806          return $target;
11807      }
11808  
11809      /**
11810       * Parse an IRI into scheme/authority/path/query/fragment segments
11811       *
11812       * @access private
11813       * @param string $iri
11814       * @return array
11815       */
11816  	function parse_iri($iri)
11817      {
11818          preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match);
11819          for ($i = count($match); $i <= 9; $i++)
11820          {
11821              $match[$i] = '';
11822          }
11823          return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]);
11824      }
11825  
11826      /**
11827       * Remove dot segments from a path
11828       *
11829       * @access private
11830       * @param string $input
11831       * @return string
11832       */
11833  	function remove_dot_segments($input)
11834      {
11835          $output = '';
11836          while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
11837          {
11838              // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
11839              if (strpos($input, '../') === 0)
11840              {
11841                  $input = substr($input, 3);
11842              }
11843              elseif (strpos($input, './') === 0)
11844              {
11845                  $input = substr($input, 2);
11846              }
11847              // 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,
11848              elseif (strpos($input, '/./') === 0)
11849              {
11850                  $input = substr_replace($input, '/', 0, 3);
11851              }
11852              elseif ($input === '/.')
11853              {
11854                  $input = '/';
11855              }
11856              // 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,
11857              elseif (strpos($input, '/../') === 0)
11858              {
11859                  $input = substr_replace($input, '/', 0, 4);
11860                  $output = substr_replace($output, '', strrpos($output, '/'));
11861              }
11862              elseif ($input === '/..')
11863              {
11864                  $input = '/';
11865                  $output = substr_replace($output, '', strrpos($output, '/'));
11866              }
11867              // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
11868              elseif ($input === '.' || $input === '..')
11869              {
11870                  $input = '';
11871              }
11872              // 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
11873              elseif (($pos = strpos($input, '/', 1)) !== false)
11874              {
11875                  $output .= substr($input, 0, $pos);
11876                  $input = substr_replace($input, '', 0, $pos);
11877              }
11878              else
11879              {
11880                  $output .= $input;
11881                  $input = '';
11882              }
11883          }
11884          return $output . $input;
11885      }
11886  
11887      /**
11888       * Replace invalid character with percent encoding
11889       *
11890       * @access private
11891       * @param string $string Input string
11892       * @param string $valid_chars Valid characters
11893       * @param int $case Normalise case
11894       * @return string
11895       */
11896  	function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE)
11897      {
11898          // Normalise case
11899          if ($case & SIMPLEPIE_LOWERCASE)
11900          {
11901              $string = strtolower($string);
11902          }
11903          elseif ($case & SIMPLEPIE_UPPERCASE)
11904          {
11905              $string = strtoupper($string);
11906          }
11907  
11908          // Store position and string length (to avoid constantly recalculating this)
11909          $position = 0;
11910          $strlen = strlen($string);
11911  
11912          // Loop as long as we have invalid characters, advancing the position to the next invalid character
11913          while (($position += strspn($string, $valid_chars, $position)) < $strlen)
11914          {
11915              // If we have a % character
11916              if ($string[$position] === '%')
11917              {
11918                  // If we have a pct-encoded section
11919                  if ($position + 2 < $strlen && strspn($string, '0123456789ABCDEFabcdef', $position + 1, 2) === 2)
11920                  {
11921                      // Get the the represented character
11922                      $chr = chr(hexdec(substr($string, $position + 1, 2)));
11923  
11924                      // If the character is valid, replace the pct-encoded with the actual character while normalising case
11925                      if (strpos($valid_chars, $chr) !== false)
11926                      {
11927                          if ($case & SIMPLEPIE_LOWERCASE)
11928                          {
11929                              $chr = strtolower($chr);
11930                          }
11931                          elseif ($case & SIMPLEPIE_UPPERCASE)
11932                          {
11933                              $chr = strtoupper($chr);
11934                          }
11935                          $string = substr_replace($string, $chr, $position, 3);
11936                          $strlen -= 2;
11937                          $position++;
11938                      }
11939  
11940                      // Otherwise just normalise the pct-encoded to uppercase
11941                      else
11942                      {
11943                          $string = substr_replace($string, strtoupper(substr($string, $position + 1, 2)), $position + 1, 2);
11944                          $position += 3;
11945                      }
11946                  }
11947                  // If we don't have a pct-encoded section, just replace the % with its own esccaped form
11948                  else
11949                  {
11950                      $string = substr_replace($string, '%25', $position, 1);
11951                      $strlen += 2;
11952                      $position += 3;
11953                  }
11954              }
11955              // If we have an invalid character, change into its pct-encoded form
11956              else
11957              {
11958                  $replacement = sprintf("%%%02X", ord($string[$position]));
11959                  $string = str_replace($string[$position], $replacement, $string);
11960                  $strlen = strlen($string);
11961              }
11962          }
11963          return $string;
11964      }
11965  
11966      /**
11967       * Check if the object represents a valid IRI
11968       *
11969       * @access public
11970       * @return bool
11971       */
11972  	function is_valid()
11973      {
11974          return array_sum($this->valid) === count($this->valid);
11975      }
11976  
11977      /**
11978       * Set the scheme. Returns true on success, false on failure (if there are
11979       * any invalid characters).
11980       *
11981       * @access public
11982       * @param string $scheme
11983       * @return bool
11984       */
11985  	function set_scheme($scheme)
11986      {
11987          if ($scheme === null || $scheme === '')
11988          {
11989              $this->scheme = null;
11990          }
11991          else
11992          {
11993              $len = strlen($scheme);
11994              switch (true)
11995              {
11996                  case $len > 1:
11997                      if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1))
11998                      {
11999                          $this->scheme = null;
12000                          $this->valid[__FUNCTION__] = false;
12001                          return false;
12002                      }
12003  
12004                  case $len > 0:
12005                      if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1))
12006                      {
12007                          $this->scheme = null;
12008                          $this->valid[__FUNCTION__] = false;
12009                          return false;
12010                      }
12011              }
12012              $this->scheme = strtolower($scheme);
12013          }
12014          $this->valid[__FUNCTION__] = true;
12015          return true;
12016      }
12017  
12018      /**
12019       * Set the authority. Returns true on success, false on failure (if there are
12020       * any invalid characters).
12021       *
12022       * @access public
12023       * @param string $authority
12024       * @return bool
12025       */
12026  	function set_authority($authority)
12027      {
12028          if (($userinfo_end = strrpos($authority, '@')) !== false)
12029          {
12030              $userinfo = substr($authority, 0, $userinfo_end);
12031              $authority = substr($authority, $userinfo_end + 1);
12032          }
12033          else
12034          {
12035              $userinfo = null;
12036          }
12037  
12038          if (($port_start = strpos($authority, ':')) !== false)
12039          {
12040              $port = substr($authority, $port_start + 1);
12041              $authority = substr($authority, 0, $port_start);
12042          }
12043          else
12044          {
12045              $port = null;
12046          }
12047  
12048          return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port);
12049      }
12050  
12051      /**
12052       * Set the userinfo.
12053       *
12054       * @access public
12055       * @param string $userinfo
12056       * @return bool
12057       */
12058  	function set_userinfo($userinfo)
12059      {
12060          if ($userinfo === null || $userinfo === '')
12061          {
12062              $this->userinfo = null;
12063          }
12064          else
12065          {
12066              $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:');
12067          }
12068          $this->valid[__FUNCTION__] = true;
12069          return true;
12070      }
12071  
12072      /**
12073       * Set the host. Returns true on success, false on failure (if there are
12074       * any invalid characters).
12075       *
12076       * @access public
12077       * @param string $host
12078       * @return bool
12079       */
12080  	function set_host($host)
12081      {
12082          if ($host === null || $host === '')
12083          {
12084              $this->host = null;
12085              $this->valid[__FUNCTION__] = true;
12086              return true;
12087          }
12088          elseif ($host[0] === '[' && substr($host, -1) === ']')
12089          {
12090              if (Net_IPv6::checkIPv6(substr($host, 1, -1)))
12091              {
12092                  $this->host = $host;
12093                  $this->valid[__FUNCTION__] = true;
12094                  return true;
12095              }
12096              else
12097              {
12098                  $this->host = null;
12099                  $this->valid[__FUNCTION__] = false;
12100                  return false;
12101              }
12102          }
12103          else
12104          {
12105              $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE);
12106              $this->valid[__FUNCTION__] = true;
12107              return true;
12108          }
12109      }
12110  
12111      /**
12112       * Set the port. Returns true on success, false on failure (if there are
12113       * any invalid characters).
12114       *
12115       * @access public
12116       * @param string $port
12117       * @return bool
12118       */
12119  	function set_port($port)
12120      {
12121          if ($port === null || $port === '')
12122          {
12123              $this->port = null;
12124              $this->valid[__FUNCTION__] = true;
12125              return true;
12126          }
12127          elseif (strspn($port, '0123456789') === strlen($port))
12128          {
12129              $this->port = (int) $port;
12130              $this->valid[__FUNCTION__] = true;
12131              return true;
12132          }
12133          else
12134          {
12135              $this->port = null;
12136              $this->valid[__FUNCTION__] = false;
12137              return false;
12138          }
12139      }
12140  
12141      /**
12142       * Set the path.
12143       *
12144       * @access public
12145       * @param string $path
12146       * @return bool
12147       */
12148  	function set_path($path)
12149      {
12150          if ($path === null || $path === '')
12151          {
12152              $this->path = null;
12153              $this->valid[__FUNCTION__] = true;
12154              return true;
12155          }
12156          elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null)
12157          {
12158              $this->path = null;
12159              $this->valid[__FUNCTION__] = false;
12160              return false;
12161          }
12162          else
12163          {
12164              $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/');
12165              if ($this->scheme !== null)
12166              {
12167                  $this->path = $this->remove_dot_segments($this->path);
12168              }
12169              $this->valid[__FUNCTION__] = true;
12170              return true;
12171          }
12172      }
12173  
12174      /**
12175       * Set the query.
12176       *
12177       * @access public
12178       * @param string $query
12179       * @return bool
12180       */
12181  	function set_query($query)
12182      {
12183          if ($query === null || $query === '')
12184          {
12185              $this->query = null;
12186          }
12187          else
12188          {
12189              $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?');
12190          }
12191          $this->valid[__FUNCTION__] = true;
12192          return true;
12193      }
12194  
12195      /**
12196       * Set the fragment.
12197       *
12198       * @access public
12199       * @param string $fragment
12200       * @return bool
12201       */
12202  	function set_fragment($fragment)
12203      {
12204          if ($fragment === null || $fragment === '')
12205          {
12206              $this->fragment = null;
12207          }
12208          else
12209          {
12210              $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?');
12211          }
12212          $this->valid[__FUNCTION__] = true;
12213          return true;
12214      }
12215  
12216      /**
12217       * Get the complete IRI
12218       *
12219       * @access public
12220       * @return string
12221       */
12222  	function get_iri()
12223      {
12224          $iri = '';
12225          if ($this->scheme !== null)
12226          {
12227              $iri .= $this->scheme . ':';
12228          }
12229          if (($authority = $this->get_authority()) !== null)
12230          {
12231              $iri .= '//' . $authority;
12232          }
12233          if ($this->path !== null)
12234          {
12235              $iri .= $this->path;
12236          }
12237          if ($this->query !== null)
12238          {
12239              $iri .= '?' . $this->query;
12240          }
12241          if ($this->fragment !== null)
12242          {
12243              $iri .= '#' . $this->fragment;
12244          }
12245  
12246          if ($iri !== '')
12247          {
12248              return $iri;
12249          }
12250          else
12251          {
12252              return null;
12253          }
12254      }
12255  
12256      /**
12257       * Get the scheme
12258       *
12259       * @access public
12260       * @return string
12261       */
12262  	function get_scheme()
12263      {
12264          return $this->scheme;
12265      }
12266  
12267      /**
12268       * Get the complete authority
12269       *
12270       * @access public
12271       * @return string
12272       */
12273  	function get_authority()
12274      {
12275          $authority = '';
12276          if ($this->userinfo !== null)
12277          {
12278              $authority .= $this->userinfo . '@';
12279          }
12280          if ($this->host !== null)
12281          {
12282              $authority .= $this->host;
12283          }
12284          if ($this->port !== null)
12285          {
12286              $authority .= ':' . $this->port;
12287          }
12288  
12289          if ($authority !== '')
12290          {
12291              return $authority;
12292          }
12293          else
12294          {
12295              return null;
12296          }
12297      }
12298  
12299      /**
12300       * Get the user information
12301       *
12302       * @access public
12303       * @return string
12304       */
12305  	function get_userinfo()
12306      {
12307          return $this->userinfo;
12308      }
12309  
12310      /**
12311       * Get the host
12312       *
12313       * @access public
12314       * @return string
12315       */
12316  	function get_host()
12317      {
12318          return $this->host;
12319      }
12320  
12321      /**
12322       * Get the port
12323       *
12324       * @access public
12325       * @return string
12326       */
12327  	function get_port()
12328      {
12329          return $this->port;
12330      }
12331  
12332      /**
12333       * Get the path
12334       *
12335       * @access public
12336       * @return string
12337       */
12338  	function get_path()
12339      {
12340          return $this->path;
12341      }
12342  
12343      /**
12344       * Get the query
12345       *
12346       * @access public
12347       * @return string
12348       */
12349  	function get_query()
12350      {
12351          return $this->query;
12352      }
12353  
12354      /**
12355       * Get the fragment
12356       *
12357       * @access public
12358       * @return string
12359       */
12360  	function get_fragment()
12361      {
12362          return $this->fragment;
12363      }
12364  }
12365  
12366  /**
12367   * Class to validate and to work with IPv6 addresses.
12368   *
12369   * @package SimplePie
12370   * @copyright 2003-2005 The PHP Group
12371   * @license http://www.opensource.org/licenses/bsd-license.php
12372   * @link http://pear.php.net/package/Net_IPv6
12373   * @author Alexander Merz <alexander.merz@web.de>
12374   * @author elfrink at introweb dot nl
12375   * @author Josh Peck <jmp at joshpeck dot org>
12376   * @author Geoffrey Sneddon <geoffers@gmail.com>
12377   */
12378  class SimplePie_Net_IPv6
12379  {
12380      /**
12381       * Removes a possible existing netmask specification of an IP address.
12382       *
12383       * @param string $ip the (compressed) IP as Hex representation
12384       * @return string the IP the without netmask
12385       * @since 1.1.0
12386       * @access public
12387       * @static
12388       */
12389  	function removeNetmaskSpec($ip)
12390      {
12391          if (strpos($ip, '/') !== false)
12392          {
12393              list($addr, $nm) = explode('/', $ip);
12394          }
12395          else
12396          {
12397              $addr = $ip;
12398          }
12399          return $addr;
12400      }
12401  
12402      /**
12403       * Uncompresses an IPv6 address
12404       *
12405       * RFC 2373 allows you to compress zeros in an address to '::'. This
12406       * function expects an valid IPv6 address and expands the '::' to
12407       * the required zeros.
12408       *
12409       * Example:     FF01::101    ->    FF01:0:0:0:0:0:0:101
12410       *             ::1        ->    0:0:0:0:0:0:0:1
12411       *
12412       * @access public
12413       * @static
12414       * @param string $ip a valid IPv6-address (hex format)
12415       * @return string the uncompressed IPv6-address (hex format)
12416       */
12417  	function Uncompress($ip)
12418      {
12419          $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip);
12420          $c1 = -1;
12421          $c2 = -1;
12422          if (strpos($ip, '::') !== false)
12423          {
12424              list($ip1, $ip2) = explode('::', $ip);
12425              if ($ip1 === '')
12426              {
12427                  $c1 = -1;
12428              }
12429              else
12430              {
12431                  $pos = 0;
12432                  if (($pos = substr_count($ip1, ':')) > 0)
12433                  {
12434                      $c1 = $pos;
12435                  }
12436                  else
12437                  {
12438                      $c1 = 0;
12439                  }
12440              }
12441              if ($ip2 === '')
12442              {
12443                  $c2 = -1;
12444              }
12445              else
12446              {
12447                  $pos = 0;
12448                  if (($pos = substr_count($ip2, ':')) > 0)
12449                  {
12450                      $c2 = $pos;
12451                  }
12452                  else
12453                  {
12454                      $c2 = 0;
12455                  }
12456              }
12457              if (strstr($ip2, '.'))
12458              {
12459                  $c2++;
12460              }
12461              // ::
12462              if ($c1 === -1 && $c2 === -1)
12463              {
12464                  $uip = '0:0:0:0:0:0:0:0';
12465              }
12466              // ::xxx
12467              else if ($c1 === -1)
12468              {
12469                  $fill = str_repeat('0:', 7 - $c2);
12470                  $uip =    str_replace('::', $fill, $uip);
12471              }
12472              // xxx::
12473              else if ($c2 === -1)
12474              {
12475                  $fill = str_repeat(':0', 7 - $c1);
12476                  $uip =    str_replace('::', $fill, $uip);
12477              }
12478              // xxx::xxx
12479              else
12480              {
12481                  $fill = str_repeat(':0:', 6 - $c2 - $c1);
12482                  $uip =    str_replace('::', $fill, $uip);
12483                  $uip =    str_replace('::', ':', $uip);
12484              }
12485          }
12486          return $uip;
12487      }
12488  
12489      /**
12490       * Splits an IPv6 address into the IPv6 and a possible IPv4 part
12491       *
12492       * RFC 2373 allows you to note the last two parts of an IPv6 address as
12493       * an IPv4 compatible address
12494       *
12495       * Example:     0:0:0:0:0:0:13.1.68.3
12496       *             0:0:0:0:0:FFFF:129.144.52.38
12497       *
12498       * @access public
12499       * @static
12500       * @param string $ip a valid IPv6-address (hex format)
12501       * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format)
12502       */
12503  	function SplitV64($ip)
12504      {
12505          $ip = SimplePie_Net_IPv6::Uncompress($ip);
12506          if (strstr($ip, '.'))
12507          {
12508              $pos = strrpos($ip, ':');
12509              $ip[$pos] = '_';
12510              $ipPart = explode('_', $ip);
12511              return $ipPart;
12512          }
12513          else
12514          {
12515              return array($ip, '');
12516          }
12517      }
12518  
12519      /**
12520       * Checks an IPv6 address
12521       *
12522       * Checks if the given IP is IPv6-compatible
12523       *
12524       * @access public
12525       * @static
12526       * @param string $ip a valid IPv6-address
12527       * @return bool true if $ip is an IPv6 address
12528       */
12529  	function checkIPv6($ip)
12530      {
12531          $ipPart = SimplePie_Net_IPv6::SplitV64($ip);
12532          $count = 0;
12533          if (!empty($ipPart[0]))
12534          {
12535              $ipv6 = explode(':', $ipPart[0]);
12536              for ($i = 0; $i < count($ipv6); $i++)
12537              {
12538                  $dec = hexdec($ipv6[$i]);
12539                  $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i]));
12540                  if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec)))
12541                  {
12542                      $count++;
12543                  }
12544              }
12545              if ($count === 8)
12546              {
12547                  return true;
12548              }
12549              elseif ($count === 6 && !empty($ipPart[1]))
12550              {
12551                  $ipv4 = explode('.', $ipPart[1]);
12552                  $count = 0;
12553                  foreach ($ipv4 as $ipv4_part)
12554                  {
12555                      if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part))
12556                      {
12557                          $count++;
12558                      }
12559                  }
12560                  if ($count === 4)
12561                  {
12562                      return true;
12563                  }
12564              }
12565              else
12566              {
12567                  return false;
12568              }
12569  
12570          }
12571          else
12572          {
12573              return false;
12574          }
12575      }
12576  }
12577  
12578  /**
12579   * Date Parser
12580   *
12581   * @package SimplePie
12582   */
12583  class SimplePie_Parse_Date
12584  {
12585      /**
12586       * Input data
12587       *
12588       * @access protected
12589       * @var string
12590       */
12591      var $date;
12592  
12593      /**
12594       * List of days, calendar day name => ordinal day number in the week
12595       *
12596       * @access protected
12597       * @var array
12598       */
12599      var $day = array(
12600          // English
12601          'mon' => 1,
12602          'monday' => 1,
12603          'tue' => 2,
12604          'tuesday' => 2,
12605          'wed' => 3,
12606          'wednesday' => 3,
12607          'thu' => 4,
12608          'thursday' => 4,
12609          'fri' => 5,
12610          'friday' => 5,
12611          'sat' => 6,
12612          'saturday' => 6,
12613          'sun' => 7,
12614          'sunday' => 7,
12615          // Dutch
12616          'maandag' => 1,
12617          'dinsdag' => 2,
12618          'woensdag' => 3,
12619          'donderdag' => 4,
12620          'vrijdag' => 5,
12621          'zaterdag' => 6,
12622          'zondag' => 7,
12623          // French
12624          'lundi' => 1,
12625          'mardi' => 2,
12626          'mercredi' => 3,
12627          'jeudi' => 4,
12628          'vendredi' => 5,
12629          'samedi' => 6,
12630          'dimanche' => 7,
12631          // German
12632          'montag' => 1,
12633          'dienstag' => 2,
12634          'mittwoch' => 3,
12635          'donnerstag' => 4,
12636          'freitag' => 5,
12637          'samstag' => 6,
12638          'sonnabend' => 6,
12639          'sonntag' => 7,
12640          // Italian
12641          'lunedì' => 1,
12642          'martedì' => 2,
12643          'mercoledì' => 3,
12644          'giovedì' => 4,
12645          'venerdì' => 5,
12646          'sabato' => 6,
12647          'domenica' => 7,
12648          // Spanish
12649          'lunes' => 1,
12650          'martes' => 2,
12651          'miércoles' => 3,
12652          'jueves' => 4,
12653          'viernes' => 5,
12654          'sábado' => 6,
12655          'domingo' => 7,
12656          // Finnish
12657          'maanantai' => 1,
12658          'tiistai' => 2,
12659          'keskiviikko' => 3,
12660          'torstai' => 4,
12661          'perjantai' => 5,
12662          'lauantai' => 6,
12663          'sunnuntai' => 7,
12664          // Hungarian
12665          'hétfő' => 1,
12666          'kedd' => 2,
12667          'szerda' => 3,
12668          'csütörtok' => 4,
12669          'péntek' => 5,
12670          'szombat' => 6,
12671          'vasárnap' => 7,
12672          // Greek
12673          'Δευ' => 1,
12674          'Τρι' => 2,
12675          'Τετ' => 3,
12676          'Πεμ' => 4,
12677          'Παρ' => 5,
12678          'Σαβ' => 6,
12679          'Κυρ' => 7,
12680      );
12681  
12682      /**
12683       * List of months, calendar month name => calendar month number
12684       *
12685       * @access protected
12686       * @var array
12687       */
12688      var $month = array(
12689          // English
12690          'jan' => 1,
12691          'january' => 1,
12692          'feb' => 2,
12693          'february' => 2,
12694          'mar' => 3,
12695          'march' => 3,
12696          'apr' => 4,
12697          'april' => 4,
12698          'may' => 5,
12699          // No long form of May
12700          'jun' => 6,
12701          'june' => 6,
12702          'jul' => 7,
12703          'july' => 7,
12704          'aug' => 8,
12705          'august' => 8,
12706          'sep' => 9,
12707          'september' => 8,
12708          'oct' => 10,
12709          'october' => 10,
12710          'nov' => 11,
12711          'november' => 11,
12712          'dec' => 12,
12713          'december' => 12,
12714          // Dutch
12715          'januari' => 1,
12716          'februari' => 2,
12717          'maart' => 3,
12718          'april' => 4,
12719          'mei' => 5,
12720          'juni' => 6,
12721          'juli' => 7,
12722          'augustus' => 8,
12723          'september' => 9,
12724          'oktober' => 10,
12725          'november' => 11,
12726          'december' => 12,
12727          // French
12728          'janvier' => 1,
12729          'février' => 2,
12730          'mars' => 3,
12731          'avril' => 4,
12732          'mai' => 5,
12733          'juin' => 6,
12734          'juillet' => 7,
12735          'août' => 8,
12736          'septembre' => 9,
12737          'octobre' => 10,
12738          'novembre' => 11,
12739          'décembre' => 12,
12740          // German
12741          'januar' => 1,
12742          'februar' => 2,
12743          'märz' => 3,
12744          'april' => 4,
12745          'mai' => 5,
12746          'juni' => 6,
12747          'juli' => 7,
12748          'august' => 8,
12749          'september' => 9,
12750          'oktober' => 10,
12751          'november' => 11,
12752          'dezember' => 12,
12753          // Italian
12754          'gennaio' => 1,
12755          'febbraio' => 2,
12756          'marzo' => 3,
12757          'aprile' => 4,
12758          'maggio' => 5,
12759          'giugno' => 6,
12760          'luglio' => 7,
12761          'agosto' => 8,
12762          'settembre' => 9,
12763          'ottobre' => 10,
12764          'novembre' => 11,
12765          'dicembre' => 12,
12766          // Spanish
12767          'enero' => 1,
12768          'febrero' => 2,
12769          'marzo' => 3,
12770          'abril' => 4,
12771          'mayo' => 5,
12772          'junio' => 6,
12773          'julio' => 7,
12774          'agosto' => 8,
12775          'septiembre' => 9,
12776          'setiembre' => 9,
12777          'octubre' => 10,
12778          'noviembre' => 11,
12779          'diciembre' => 12,
12780          // Finnish
12781          'tammikuu' => 1,
12782          'helmikuu' => 2,
12783          'maaliskuu' => 3,
12784          'huhtikuu' => 4,
12785          'toukokuu' => 5,
12786          'kesäkuu' => 6,
12787          'heinäkuu' => 7,
12788          'elokuu' => 8,
12789          'suuskuu' => 9,
12790          'lokakuu' => 10,
12791          'marras' => 11,
12792          'joulukuu' => 12,
12793          // Hungarian
12794          'január' => 1,
12795          'február' => 2,
12796          'március' => 3,
12797          'április' => 4,
12798          'május' => 5,
12799          'június' => 6,
12800          'július' => 7,
12801          'augusztus' => 8,
12802          'szeptember' => 9,
12803          'október' => 10,
12804          'november' => 11,
12805          'december' => 12,
12806          // Greek
12807          'Ιαν' => 1,
12808          'Φεβ' => 2,
12809          'Μάώ' => 3,
12810          'Μαώ' => 3,
12811          'Απρ' => 4,
12812          'Μάι' => 5,
12813          'Μαϊ' => 5,
12814          'Μαι' => 5,
12815          'Ιούν' => 6,
12816          'Ιον' => 6,
12817          'Ιούλ' => 7,
12818          'Ιολ' => 7,
12819          'Αύγ' => 8,
12820          'Αυγ' => 8,
12821          'Σεπ' => 9,
12822          'Οκτ' => 10,
12823          'Νοέ' => 11,
12824          'Δεκ' => 12,
12825      );
12826  
12827      /**
12828       * List of timezones, abbreviation => offset from UTC
12829       *
12830       * @access protected
12831       * @var array
12832       */
12833      var $timezone = array(
12834          'ACDT' => 37800,
12835          'ACIT' => 28800,
12836          'ACST' => 34200,
12837          'ACT' => -18000,
12838          'ACWDT' => 35100,
12839          'ACWST' => 31500,
12840          'AEDT' => 39600,
12841          'AEST' => 36000,
12842          'AFT' => 16200,
12843          'AKDT' => -28800,
12844          'AKST' => -32400,
12845          'AMDT' => 18000,
12846          'AMT' => -14400,
12847          'ANAST' => 46800,
12848          'ANAT' => 43200,
12849          'ART' => -10800,
12850          'AZOST' => -3600,
12851          'AZST' => 18000,
12852          'AZT' => 14400,
12853          'BIOT' => 21600,
12854          'BIT' => -43200,
12855          'BOT' => -14400,
12856          'BRST' => -7200,
12857          'BRT' => -10800,
12858          'BST' => 3600,
12859          'BTT' => 21600,
12860          'CAST' => 18000,
12861          'CAT' => 7200,
12862          'CCT' => 23400,
12863          'CDT' => -18000,
12864          'CEDT' => 7200,
12865          'CET' => 3600,
12866          'CGST' => -7200,
12867          'CGT' => -10800,
12868          'CHADT' => 49500,
12869          'CHAST' => 45900,
12870          'CIST' => -28800,
12871          'CKT' => -36000,
12872          'CLDT' => -10800,
12873          'CLST' => -14400,
12874          'COT' => -18000,
12875          'CST' => -21600,
12876          'CVT' => -3600,
12877          'CXT' => 25200,
12878          'DAVT' => 25200,
12879          'DTAT' => 36000,
12880          'EADT' => -18000,
12881          'EAST' => -21600,
12882          'EAT' => 10800,
12883          'ECT' => -18000,
12884          'EDT' => -14400,
12885          'EEST' => 10800,
12886          'EET' => 7200,
12887          'EGT' => -3600,
12888          'EKST' => 21600,
12889          'EST' => -18000,
12890          'FJT' => 43200,
12891          'FKDT' => -10800,
12892          'FKST' => -14400,
12893          'FNT' => -7200,
12894          'GALT' => -21600,
12895          'GEDT' => 14400,
12896          'GEST' => 10800,
12897          'GFT' => -10800,
12898          'GILT' => 43200,
12899          'GIT' => -32400,
12900          'GST' => 14400,
12901          'GST' => -7200,
12902          'GYT' => -14400,
12903          'HAA' => -10800,
12904          'HAC' => -18000,
12905          'HADT' => -32400,
12906          'HAE' => -14400,
12907          'HAP' => -25200,
12908          'HAR' => -21600,
12909          'HAST' => -36000,
12910          'HAT' => -9000,
12911          'HAY' => -28800,
12912          'HKST' => 28800,
12913          'HMT' => 18000,
12914          'HNA' => -14400,
12915          'HNC' => -21600,
12916          'HNE' => -18000,
12917          'HNP' => -28800,
12918          'HNR' => -25200,
12919          'HNT' => -12600,
12920          'HNY' => -32400,
12921          'IRDT' => 16200,
12922          'IRKST' => 32400,
12923          'IRKT' => 28800,
12924          'IRST' => 12600,
12925          'JFDT' => -10800,
12926          'JFST' => -14400,
12927          'JST' => 32400,
12928          'KGST' => 21600,
12929          'KGT' => 18000,
12930          'KOST' => 39600,
12931          'KOVST' => 28800,
12932          'KOVT' => 25200,
12933          'KRAST' => 28800,
12934          'KRAT' => 25200,
12935          'KST' => 32400,
12936          'LHDT' => 39600,
12937          'LHST' => 37800,
12938          'LINT' => 50400,
12939          'LKT' => 21600,
12940          'MAGST' => 43200,
12941          'MAGT' => 39600,
12942          'MAWT' => 21600,
12943          'MDT' => -21600,
12944          'MESZ' => 7200,
12945          'MEZ' => 3600,
12946          'MHT' => 43200,
12947          'MIT' => -34200,
12948          'MNST' => 32400,
12949          'MSDT' => 14400,
12950          'MSST' => 10800,
12951          'MST' => -25200,
12952          'MUT' => 14400,
12953          'MVT' => 18000,
12954          'MYT' => 28800,
12955          'NCT' => 39600,
12956          'NDT' => -9000,
12957          'NFT' => 41400,
12958          'NMIT' => 36000,
12959          'NOVST' => 25200,
12960          'NOVT' => 21600,
12961          'NPT' => 20700,
12962          'NRT' => 43200,
12963          'NST' => -12600,
12964          'NUT' => -39600,
12965          'NZDT' => 46800,
12966          'NZST' => 43200,
12967          'OMSST' => 25200,
12968          'OMST' => 21600,
12969          'PDT' => -25200,
12970          'PET' => -18000,
12971          'PETST' => 46800,
12972          'PETT' => 43200,
12973          'PGT' => 36000,
12974          'PHOT' => 46800,
12975          'PHT' => 28800,
12976          'PKT' => 18000,
12977          'PMDT' => -7200,
12978          'PMST' => -10800,
12979          'PONT' => 39600,
12980          'PST' => -28800,
12981          'PWT' => 32400,
12982          'PYST' => -10800,
12983          'PYT' => -14400,
12984          'RET' => 14400,
12985          'ROTT' => -10800,
12986          'SAMST' => 18000,
12987          'SAMT' => 14400,
12988          'SAST' => 7200,
12989          'SBT' => 39600,
12990          'SCDT' => 46800,
12991          'SCST' => 43200,
12992          'SCT' => 14400,
12993          'SEST' => 3600,
12994          'SGT' => 28800,
12995          'SIT' => 28800,
12996          'SRT' => -10800,
12997          'SST' => -39600,
12998          'SYST' => 10800,
12999          'SYT' => 7200,
13000          'TFT' => 18000,
13001          'THAT' => -36000,
13002          'TJT' => 18000,
13003          'TKT' => -36000,
13004          'TMT' => 18000,
13005          'TOT' => 46800,
13006          'TPT' => 32400,
13007          'TRUT' => 36000,
13008          'TVT' => 43200,
13009          'TWT' => 28800,
13010          'UYST' => -7200,
13011          'UYT' => -10800,
13012          'UZT' => 18000,
13013          'VET' => -14400,
13014          'VLAST' => 39600,
13015          'VLAT' => 36000,
13016          'VOST' => 21600,
13017          'VUT' => 39600,
13018          'WAST' => 7200,
13019          'WAT' => 3600,
13020          'WDT' => 32400,
13021          'WEST' => 3600,
13022          'WFT' => 43200,
13023          'WIB' => 25200,
13024          'WIT' => 32400,
13025          'WITA' => 28800,
13026          'WKST' => 18000,
13027          'WST' => 28800,
13028          'YAKST' => 36000,
13029          'YAKT' => 32400,
13030          'YAPT' => 36000,
13031          'YEKST' => 21600,
13032          'YEKT' => 18000,
13033      );
13034  
13035      /**
13036       * Cached PCRE for SimplePie_Parse_Date::$day
13037       *
13038       * @access protected
13039       * @var string
13040       */
13041      var $day_pcre;
13042  
13043      /**
13044       * Cached PCRE for SimplePie_Parse_Date::$month
13045       *
13046       * @access protected
13047       * @var string
13048       */
13049      var $month_pcre;
13050  
13051      /**
13052       * Array of user-added callback methods
13053       *
13054       * @access private
13055       * @var array
13056       */
13057      var $built_in = array();
13058  
13059      /**
13060       * Array of user-added callback methods
13061       *
13062       * @access private
13063       * @var array
13064       */
13065      var $user = array();
13066  
13067      /**
13068       * Create new SimplePie_Parse_Date object, and set self::day_pcre,
13069       * self::month_pcre, and self::built_in
13070       *
13071       * @access private
13072       */
13073  	function SimplePie_Parse_Date()
13074      {
13075          $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')';
13076          $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')';
13077  
13078          static $cache;
13079          if (!isset($cache[get_class($this)]))
13080          {
13081              $all_methods = get_class_methods($this);
13082  
13083              foreach ($all_methods as $method)
13084              {
13085                  if (strtolower(substr($method, 0, 5)) === 'date_')
13086                  {
13087                      $cache[get_class($this)][] = $method;
13088                  }
13089              }
13090          }
13091  
13092          foreach ($cache[get_class($this)] as $method)
13093          {
13094              $this->built_in[] = $method;
13095          }
13096      }
13097  
13098      /**
13099       * Get the object
13100       *
13101       * @access public
13102       */
13103  	function get()
13104      {
13105          static $object;
13106          if (!$object)
13107          {
13108              $object =& new SimplePie_Parse_Date;
13109          }
13110          return $object;
13111      }
13112  
13113      /**
13114       * Parse a date
13115       *
13116       * @final
13117       * @access public
13118       * @param string $date Date to parse
13119       * @return int Timestamp corresponding to date string, or false on failure
13120       */
13121  	function parse($date)
13122      {
13123          foreach ($this->user as $method)
13124          {
13125              if (($returned = call_user_func($method, $date)) !== false)
13126              {
13127                  return $returned;
13128              }
13129          }
13130  
13131          foreach ($this->built_in as $method)
13132          {
13133              if (($returned = call_user_func(array(&$this, $method), $date)) !== false)
13134              {
13135                  return $returned;
13136              }
13137          }
13138  
13139          return false;
13140      }
13141  
13142      /**
13143       * Add a callback method to parse a date
13144       *
13145       * @final
13146       * @access public
13147       * @param callback $callback
13148       */
13149  	function add_callback($callback)
13150      {
13151          if (is_callable($callback))
13152          {
13153              $this->user[] = $callback;
13154          }
13155          else
13156          {
13157              trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
13158          }
13159      }
13160  
13161      /**
13162       * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
13163       * well as allowing any of upper or lower case "T", horizontal tabs, or
13164       * spaces to be used as the time seperator (including more than one))
13165       *
13166       * @access protected
13167       * @return int Timestamp
13168       */
13169  	function date_w3cdtf($date)
13170      {
13171          static $pcre;
13172          if (!$pcre)
13173          {
13174              $year = '([0-9]{4})';
13175              $month = $day = $hour = $minute = $second = '([0-9]{2})';
13176              $decimal = '([0-9]*)';
13177              $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
13178              $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
13179          }
13180          if (preg_match($pcre, $date, $match))
13181          {
13182              /*
13183              Capturing subpatterns:
13184              1: Year
13185              2: Month
13186              3: Day
13187              4: Hour
13188              5: Minute
13189              6: Second
13190              7: Decimal fraction of a second
13191              8: Zulu
13192              9: Timezone ±
13193              10: Timezone hours
13194              11: Timezone minutes
13195              */
13196  
13197              // Fill in empty matches
13198              for ($i = count($match); $i <= 3; $i++)
13199              {
13200                  $match[$i] = '1';
13201              }
13202  
13203              for ($i = count($match); $i <= 7; $i++)
13204              {
13205                  $match[$i] = '0';
13206              }
13207  
13208              // Numeric timezone
13209              if (isset($match[9]) && $match[9] !== '')
13210              {
13211                  $timezone = $match[10] * 3600;
13212                  $timezone += $match[11] * 60;
13213                  if ($match[9] === '-')
13214                  {
13215                      $timezone = 0 - $timezone;
13216                  }
13217              }
13218              else
13219              {
13220                  $timezone = 0;
13221              }
13222  
13223              // Convert the number of seconds to an integer, taking decimals into account
13224              $second = round($match[6] + $match[7] / pow(10, strlen($match[7])));
13225  
13226              return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
13227          }
13228          else
13229          {
13230              return false;
13231          }
13232      }
13233  
13234      /**
13235       * Remove RFC822 comments
13236       *
13237       * @access protected
13238       * @param string $data Data to strip comments from
13239       * @return string Comment stripped string
13240       */
13241  	function remove_rfc2822_comments($string)
13242      {
13243          $string = (string) $string;
13244          $position = 0;
13245          $length = strlen($string);
13246          $depth = 0;
13247  
13248          $output = '';
13249  
13250          while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
13251          {
13252              $output .= substr($string, $position, $pos - $position);
13253              $position = $pos + 1;
13254              if ($string[$pos - 1] !== '\\')
13255              {
13256                  $depth++;
13257                  while ($depth && $position < $length)
13258                  {
13259                      $position += strcspn($string, '()', $position);
13260                      if ($string[$position - 1] === '\\')
13261                      {
13262                          $position++;
13263                          continue;
13264                      }
13265                      elseif (isset($string[$position]))
13266                      {
13267                          switch ($string[$position])
13268                          {
13269                              case '(':
13270                                  $depth++;
13271                                  break;
13272  
13273                              case ')':
13274                                  $depth--;
13275                                  break;
13276                          }
13277                          $position++;
13278                      }
13279                      else
13280                      {
13281                          break;
13282                      }
13283                  }
13284              }
13285              else
13286              {
13287                  $output .= '(';
13288              }
13289          }
13290          $output .= substr($string, $position);
13291  
13292          return $output;
13293      }
13294  
13295      /**
13296       * Parse RFC2822's date format
13297       *
13298       * @access protected
13299       * @return int Timestamp
13300       */
13301  	function date_rfc2822($date)
13302      {
13303          static $pcre;
13304          if (!$pcre)
13305          {
13306              $wsp = '[\x09\x20]';
13307              $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
13308              $optional_fws = $fws . '?';
13309              $day_name = $this->day_pcre;
13310              $month = $this->month_pcre;
13311              $day = '([0-9]{1,2})';
13312              $hour = $minute = $second = '([0-9]{2})';
13313              $year = '([0-9]{2,4})';
13314              $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
13315              $character_zone = '([A-Z]{1,5})';
13316              $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
13317              $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';
13318          }
13319          if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
13320          {
13321              /*
13322              Capturing subpatterns:
13323              1: Day name
13324              2: Day
13325              3: Month
13326              4: Year
13327              5: Hour
13328              6: Minute
13329              7: Second
13330              8: Timezone ±
13331              9: Timezone hours
13332              10: Timezone minutes
13333              11: Alphabetic timezone
13334              */
13335  
13336              // Find the month number
13337              $month = $this->month[strtolower($match[3])];
13338  
13339              // Numeric timezone
13340              if ($match[8] !== '')
13341              {
13342                  $timezone = $match[9] * 3600;
13343                  $timezone += $match[10] * 60;
13344                  if ($match[8] === '-')
13345                  {
13346                      $timezone = 0 - $timezone;
13347                  }
13348              }
13349              // Character timezone
13350              elseif (isset($this->timezone[strtoupper($match[11])]))
13351              {
13352                  $timezone = $this->timezone[strtoupper($match[11])];
13353              }
13354              // Assume everything else to be -0000
13355              else
13356              {
13357                  $timezone = 0;
13358              }
13359  
13360              // Deal with 2/3 digit years
13361              if ($match[4] < 50)
13362              {
13363                  $match[4] += 2000;
13364              }
13365              elseif ($match[4] < 1000)
13366              {
13367                  $match[4] += 1900;
13368              }
13369  
13370              // Second is optional, if it is empty set it to zero
13371              if ($match[7] !== '')
13372              {
13373                  $second = $match[7];
13374              }
13375              else
13376              {
13377                  $second = 0;
13378              }
13379  
13380              return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
13381          }
13382          else
13383          {
13384              return false;
13385          }
13386      }
13387  
13388      /**
13389       * Parse RFC850's date format
13390       *
13391       * @access protected
13392       * @return int Timestamp
13393       */
13394  	function date_rfc850($date)
13395      {
13396          static $pcre;
13397          if (!$pcre)
13398          {
13399              $space = '[\x09\x20]+';
13400              $day_name = $this->day_pcre;
13401              $month = $this->month_pcre;
13402              $day = '([0-9]{1,2})';
13403              $year = $hour = $minute = $second = '([0-9]{2})';
13404              $zone = '([A-Z]{1,5})';
13405              $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
13406          }
13407          if (preg_match($pcre, $date, $match))
13408          {
13409              /*
13410              Capturing subpatterns:
13411              1: Day name
13412              2: Day
13413              3: Month
13414              4: Year
13415              5: Hour
13416              6: Minute
13417              7: Second
13418              8: Timezone
13419              */
13420  
13421              // Month
13422              $month = $this->month[strtolower($match[3])];
13423  
13424              // Character timezone
13425              if (isset($this->timezone[strtoupper($match[8])]))
13426              {
13427                  $timezone = $this->timezone[strtoupper($match[8])];
13428              }
13429              // Assume everything else to be -0000
13430              else
13431              {
13432                  $timezone = 0;
13433              }
13434  
13435              // Deal with 2 digit year
13436              if ($match[4] < 50)
13437              {
13438                  $match[4] += 2000;
13439              }
13440              else
13441              {
13442                  $match[4] += 1900;
13443              }
13444  
13445              return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
13446          }
13447          else
13448          {
13449              return false;
13450          }
13451      }
13452  
13453      /**
13454       * Parse C99's asctime()'s date format
13455       *
13456       * @access protected
13457       * @return int Timestamp
13458       */
13459  	function date_asctime($date)
13460      {
13461          static $pcre;
13462          if (!$pcre)
13463          {
13464              $space = '[\x09\x20]+';
13465              $wday_name = $this->day_pcre;
13466              $mon_name = $this->month_pcre;
13467              $day = '([0-9]{1,2})';
13468              $hour = $sec = $min = '([0-9]{2})';
13469              $year = '([0-9]{4})';
13470              $terminator = '\x0A?\x00?';
13471              $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
13472          }
13473          if (preg_match($pcre, $date, $match))
13474          {
13475              /*
13476              Capturing subpatterns:
13477              1: Day name
13478              2: Month
13479              3: Day
13480              4: Hour
13481              5: Minute
13482              6: Second
13483              7: Year
13484              */
13485  
13486              $month = $this->month[strtolower($match[2])];
13487              return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
13488          }
13489          else
13490          {
13491              return false;
13492          }
13493      }
13494  
13495      /**
13496       * Parse dates using strtotime()
13497       *
13498       * @access protected
13499       * @return int Timestamp
13500       */
13501  	function date_strtotime($date)
13502      {
13503          $strtotime = strtotime($date);
13504          if ($strtotime === -1 || $strtotime === false)
13505          {
13506              return false;
13507          }
13508          else
13509          {
13510              return $strtotime;
13511          }
13512      }
13513  }
13514  
13515  /**
13516   * Content-type sniffing
13517   *
13518   * @package SimplePie
13519   */
13520  class SimplePie_Content_Type_Sniffer
13521  {
13522      /**
13523       * File object
13524       *
13525       * @var SimplePie_File
13526       * @access private
13527       */
13528      var $file;
13529  
13530      /**
13531       * Create an instance of the class with the input file
13532       *
13533       * @access public
13534       * @param SimplePie_Content_Type_Sniffer $file Input file
13535       */
13536  	function SimplePie_Content_Type_Sniffer($file)
13537      {
13538          $this->file = $file;
13539      }
13540  
13541      /**
13542       * Get the Content-Type of the specified file
13543       *
13544       * @access public
13545       * @return string Actual Content-Type
13546       */
13547  	function get_type()
13548      {
13549          if (isset($this->file->headers['content-type']))
13550          {
13551              if (!isset($this->file->headers['content-encoding'])
13552                  && ($this->file->headers['content-type'] === 'text/plain'
13553                      || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
13554                      || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'))
13555              {
13556                  return $this->text_or_binary();
13557              }
13558  
13559              if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
13560              {
13561                  $official = substr($this->file->headers['content-type'], 0, $pos);
13562              }
13563              else
13564              {
13565                  $official = $this->file->headers['content-type'];
13566              }
13567              $official = strtolower($official);
13568  
13569              if ($official === 'unknown/unknown'
13570                  || $official === 'application/unknown')
13571              {
13572                  return $this->unknown();
13573              }
13574              elseif (substr($official, -4) === '+xml'
13575                  || $official === 'text/xml'
13576                  || $official === 'application/xml')
13577              {
13578                  return $official;
13579              }
13580              elseif (substr($official, 0, 6) === 'image/')
13581              {
13582                  if ($return = $this->image())
13583                  {
13584                      return $return;
13585                  }
13586                  else
13587                  {
13588                      return $official;
13589                  }
13590              }
13591              elseif ($official === 'text/html')
13592              {
13593                  return $this->feed_or_html();
13594              }
13595              else
13596              {
13597                  return $official;
13598              }
13599          }
13600          else
13601          {
13602              return $this->unknown();
13603          }
13604      }
13605  
13606      /**
13607       * Sniff text or binary
13608       *
13609       * @access private
13610       * @return string Actual Content-Type
13611       */
13612  	function text_or_binary()
13613      {
13614          if (substr($this->file->body, 0, 2) === "\xFE\xFF"
13615              || substr($this->file->body, 0, 2) === "\xFF\xFE"
13616              || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
13617              || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
13618          {
13619              return 'text/plain';
13620          }
13621          elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
13622          {
13623              return 'application/octect-stream';
13624          }
13625          else
13626          {
13627              return 'text/plain';
13628          }
13629      }
13630  
13631      /**
13632       * Sniff unknown
13633       *
13634       * @access private
13635       * @return string Actual Content-Type
13636       */
13637  	function unknown()
13638      {
13639          $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
13640          if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
13641              || strtolower(substr($this->file->body, $ws, 5)) === '<html'
13642              || strtolower(substr($this->file->body, $ws, 7)) === '<script')
13643          {
13644              return 'text/html';
13645          }
13646          elseif (substr($this->file->body, 0, 5) === '%PDF-')
13647          {
13648              return 'application/pdf';
13649          }
13650          elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
13651          {
13652              return 'application/postscript';
13653          }
13654          elseif (substr($this->file->body, 0, 6) === 'GIF87a'
13655              || substr($this->file->body, 0, 6) === 'GIF89a')
13656          {
13657              return 'image/gif';
13658          }
13659          elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13660          {
13661              return 'image/png';
13662          }
13663          elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13664          {
13665              return 'image/jpeg';
13666          }
13667          elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13668          {
13669              return 'image/bmp';
13670          }
13671          else
13672          {
13673              return $this->text_or_binary();
13674          }
13675      }
13676  
13677      /**
13678       * Sniff images
13679       *
13680       * @access private
13681       * @return string Actual Content-Type
13682       */
13683  	function image()
13684      {
13685          if (substr($this->file->body, 0, 6) === 'GIF87a'
13686              || substr($this->file->body, 0, 6) === 'GIF89a')
13687          {
13688              return 'image/gif';
13689          }
13690          elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
13691          {
13692              return 'image/png';
13693          }
13694          elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
13695          {
13696              return 'image/jpeg';
13697          }
13698          elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
13699          {
13700              return 'image/bmp';
13701          }
13702          else
13703          {
13704              return false;
13705          }
13706      }
13707  
13708      /**
13709       * Sniff HTML
13710       *
13711       * @access private
13712       * @return string Actual Content-Type
13713       */
13714  	function feed_or_html()
13715      {
13716          $len = strlen($this->file->body);
13717          $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
13718  
13719          while ($pos < $len)
13720          {
13721              switch ($this->file->body[$pos])
13722              {
13723                  case "\x09":
13724                  case "\x0A":
13725                  case "\x0D":
13726                  case "\x20":
13727                      $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
13728                      continue 2;
13729  
13730                  case '<':
13731                      $pos++;
13732                      break;
13733  
13734                  default:
13735                      return 'text/html';
13736              }
13737  
13738              if (substr($this->file->body, $pos, 3) === '!--')
13739              {
13740                  $pos += 3;
13741                  if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
13742                  {
13743                      $pos += 3;
13744                  }
13745                  else
13746                  {
13747                      return 'text/html';
13748                  }
13749              }
13750              elseif (substr($this->file->body, $pos, 1) === '!')
13751              {
13752                  if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
13753                  {
13754                      $pos++;
13755                  }
13756                  else
13757                  {
13758                      return 'text/html';
13759                  }
13760              }
13761              elseif (substr($this->file->body, $pos, 1) === '?')
13762              {
13763                  if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
13764                  {
13765                      $pos += 2;
13766                  }
13767                  else
13768                  {
13769                      return 'text/html';
13770                  }
13771              }
13772              elseif (substr($this->file->body, $pos, 3) === 'rss'
13773                  || substr($this->file->body, $pos, 7) === 'rdf:RDF')
13774              {
13775                  return 'application/rss+xml';
13776              }
13777              elseif (substr($this->file->body, $pos, 4) === 'feed')
13778              {
13779                  return 'application/atom+xml';
13780              }
13781              else
13782              {
13783                  return 'text/html';
13784              }
13785          }
13786  
13787          return 'text/html';
13788      }
13789  }
13790  
13791  /**
13792   * Parses the XML Declaration
13793   *
13794   * @package SimplePie
13795   */
13796  class SimplePie_XML_Declaration_Parser
13797  {
13798      /**
13799       * XML Version
13800       *
13801       * @access public
13802       * @var string
13803       */
13804      var $version = '1.0';
13805  
13806      /**
13807       * Encoding
13808       *
13809       * @access public
13810       * @var string
13811       */
13812      var $encoding = 'UTF-8';
13813  
13814      /**
13815       * Standalone
13816       *
13817       * @access public
13818       * @var bool
13819       */
13820      var $standalone = false;
13821  
13822      /**
13823       * Current state of the state machine
13824       *
13825       * @access private
13826       * @var string
13827       */
13828      var $state = 'before_version_name';
13829  
13830      /**
13831       * Input data
13832       *
13833       * @access private
13834       * @var string
13835       */
13836      var $data = '';
13837  
13838      /**
13839       * Input data length (to avoid calling strlen() everytime this is needed)
13840       *
13841       * @access private
13842       * @var int
13843       */
13844      var $data_length = 0;
13845  
13846      /**
13847       * Current position of the pointer
13848       *
13849       * @var int
13850       * @access private
13851       */
13852      var $position = 0;
13853  
13854      /**
13855       * Create an instance of the class with the input data
13856       *
13857       * @access public
13858       * @param string $data Input data
13859       */
13860  	function SimplePie_XML_Declaration_Parser($data)
13861      {
13862          $this->data = $data;
13863          $this->data_length = strlen($this->data);
13864      }
13865  
13866      /**
13867       * Parse the input data
13868       *
13869       * @access public
13870       * @return bool true on success, false on failure
13871       */
13872  	function parse()
13873      {
13874          while ($this->state && $this->state !== 'emit' && $this->has_data())
13875          {
13876              $state = $this->state;
13877              $this->$state();
13878          }
13879          $this->data = '';
13880          if ($this->state === 'emit')
13881          {
13882              return true;
13883          }
13884          else
13885          {
13886              $this->version = '';
13887              $this->encoding = '';
13888              $this->standalone = '';
13889              return false;
13890          }
13891      }
13892  
13893      /**
13894       * Check whether there is data beyond the pointer
13895       *
13896       * @access private
13897       * @return bool true if there is further data, false if not
13898       */
13899  	function has_data()
13900      {
13901          return (bool) ($this->position < $this->data_length);
13902      }
13903  
13904      /**
13905       * Advance past any whitespace
13906       *
13907       * @return int Number of whitespace characters passed
13908       */
13909  	function skip_whitespace()
13910      {
13911          $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
13912          $this->position += $whitespace;
13913          return $whitespace;
13914      }
13915  
13916      /**
13917       * Read value
13918       */
13919  	function get_value()
13920      {
13921          $quote = substr($this->data, $this->position, 1);
13922          if ($quote === '"' || $quote === "'")
13923          {
13924              $this->position++;
13925              $len = strcspn($this->data, $quote, $this->position);
13926              if ($this->has_data())
13927              {
13928                  $value = substr($this->data, $this->position, $len);
13929                  $this->position += $len + 1;
13930                  return $value;
13931              }
13932          }
13933          return false;
13934      }
13935  
13936  	function before_version_name()
13937      {
13938          if ($this->skip_whitespace())
13939          {
13940              $this->state = 'version_name';
13941          }
13942          else
13943          {
13944              $this->state = false;
13945          }
13946      }
13947  
13948  	function version_name()
13949      {
13950          if (substr($this->data, $this->position, 7) === 'version')
13951          {
13952              $this->position += 7;
13953              $this->skip_whitespace();
13954              $this->state = 'version_equals';
13955          }
13956          else
13957          {
13958              $this->state = false;
13959          }
13960      }
13961  
13962  	function version_equals()
13963      {
13964          if (substr($this->data, $this->position, 1) === '=')
13965          {
13966              $this->position++;
13967              $this->skip_whitespace();
13968              $this->state = 'version_value';
13969          }
13970          else
13971          {
13972              $this->state = false;
13973          }
13974      }
13975  
13976  	function version_value()
13977      {
13978          if ($this->version = $this->get_value())
13979          {
13980              $this->skip_whitespace();
13981              if ($this->has_data())
13982              {
13983                  $this->state = 'encoding_name';
13984              }
13985              else
13986              {
13987                  $this->state = 'emit';
13988              }
13989          }
13990          else
13991          {
13992              $this->state = false;
13993          }
13994      }
13995  
13996  	function encoding_name()
13997      {
13998          if (substr($this->data, $this->position, 8) === 'encoding')
13999          {
14000              $this->position += 8;
14001              $this->skip_whitespace();
14002              $this->state = 'encoding_equals';
14003          }
14004          else
14005          {
14006              $this->state = 'standalone_name';
14007          }
14008      }
14009  
14010  	function encoding_equals()
14011      {
14012          if (substr($this->data, $this->position, 1) === '=')
14013          {
14014              $this->position++;
14015              $this->skip_whitespace();
14016              $this->state = 'encoding_value';
14017          }
14018          else
14019          {
14020              $this->state = false;
14021          }
14022      }
14023  
14024  	function encoding_value()
14025      {
14026          if ($this->encoding = $this->get_value())
14027          {
14028              $this->skip_whitespace();
14029              if ($this->has_data())
14030              {
14031                  $this->state = 'standalone_name';
14032              }
14033              else
14034              {
14035                  $this->state = 'emit';
14036              }
14037          }
14038          else
14039          {
14040              $this->state = false;
14041          }
14042      }
14043  
14044  	function standalone_name()
14045      {
14046          if (substr($this->data, $this->position, 10) === 'standalone')
14047          {
14048              $this->position += 10;
14049              $this->skip_whitespace();
14050              $this->state = 'standalone_equals';
14051          }
14052          else
14053          {
14054              $this->state = false;
14055          }
14056      }
14057  
14058  	function standalone_equals()
14059      {
14060          if (substr($this->data, $this->position, 1) === '=')
14061          {
14062              $this->position++;
14063              $this->skip_whitespace();
14064              $this->state = 'standalone_value';
14065          }
14066          else
14067          {
14068              $this->state = false;
14069          }
14070      }
14071  
14072  	function standalone_value()
14073      {
14074          if ($standalone = $this->get_value())
14075          {
14076              switch ($standalone)
14077              {
14078                  case 'yes':
14079                      $this->standalone = true;
14080                      break;
14081  
14082                  case 'no':
14083                      $this->standalone = false;
14084                      break;
14085  
14086                  default:
14087                      $this->state = false;
14088                      return;
14089              }
14090  
14091              $this->skip_whitespace();
14092              if ($this->has_data())
14093              {
14094                  $this->state = false;
14095              }
14096              else
14097              {
14098                  $this->state = 'emit';
14099              }
14100          }
14101          else
14102          {
14103              $this->state = false;
14104          }
14105      }
14106  }
14107  
14108  class SimplePie_Locator
14109  {
14110      var $useragent;
14111      var $timeout;
14112      var $file;
14113      var $local = array();
14114      var $elsewhere = array();
14115      var $file_class = 'SimplePie_File';
14116      var $cached_entities = array();
14117      var $http_base;
14118      var $base;
14119      var $base_location = 0;
14120      var $checked_feeds = 0;
14121      var $max_checked_feeds = 10;
14122      var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer';
14123  
14124  	function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer')
14125      {
14126          $this->file =& $file;
14127          $this->file_class = $file_class;
14128          $this->useragent = $useragent;
14129          $this->timeout = $timeout;
14130          $this->max_checked_feeds = $max_checked_feeds;
14131          $this->content_type_sniffer_class = $content_type_sniffer_class;
14132      }
14133  
14134  	function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
14135      {
14136          if ($this->is_feed($this->file))
14137          {
14138              return $this->file;
14139          }
14140  
14141          if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14142          {
14143              $sniffer =& new $this->content_type_sniffer_class($this->file);
14144              if ($sniffer->get_type() !== 'text/html')
14145              {
14146                  return null;
14147              }
14148          }
14149  
14150          if ($type & ~SIMPLEPIE_LOCATOR_NONE)
14151          {
14152              $this->get_base();
14153          }
14154  
14155          if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
14156          {
14157              return $working[0];
14158          }
14159  
14160          if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
14161          {
14162              if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
14163              {
14164                  return $working;
14165              }
14166  
14167              if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
14168              {
14169                  return $working;
14170              }
14171  
14172              if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
14173              {
14174                  return $working;
14175              }
14176  
14177              if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
14178              {
14179                  return $working;
14180              }
14181          }
14182          return null;
14183      }
14184  
14185  	function is_feed(&$file)
14186      {
14187          if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
14188          {
14189              $sniffer =& new $this->content_type_sniffer_class($file);
14190              $sniffed = $sniffer->get_type();
14191              if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml')))
14192              {
14193                  return true;
14194              }
14195              else
14196              {
14197                  return false;
14198              }
14199          }
14200          elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
14201          {
14202              return true;
14203          }
14204          else
14205          {
14206              return false;
14207          }
14208      }
14209  
14210  	function get_base()
14211      {
14212          $this->http_base = $this->file->url;
14213          $this->base = $this->http_base;
14214          $elements = SimplePie_Misc::get_element('base', $this->file->body);
14215          foreach ($elements as $element)
14216          {
14217              if ($element['attribs']['href']['data'] !== '')
14218              {
14219                  $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base);
14220                  $this->base_location = $element['offset'];
14221                  break;
14222              }
14223          }
14224      }
14225  
14226  	function autodiscovery()
14227      {
14228          $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));
14229          $done = array();
14230          $feeds = array();
14231          foreach ($links as $link)
14232          {
14233              if ($this->checked_feeds === $this->max_checked_feeds)
14234              {
14235                  break;
14236              }
14237              if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data']))
14238              {
14239                  $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data'])));
14240  
14241                  if ($this->base_location < $link['offset'])
14242                  {
14243                      $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14244                  }
14245                  else
14246                  {
14247                      $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14248                  }
14249  
14250                  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]))
14251                  {
14252                      $this->checked_feeds++;
14253                      $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent);
14254                      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))
14255                      {
14256                          $feeds[$href] = $feed;
14257                      }
14258                  }
14259                  $done[] = $href;
14260              }
14261          }
14262  
14263          if (!empty($feeds))
14264          {
14265              return array_values($feeds);
14266          }
14267          else {
14268              return null;
14269          }
14270      }
14271  
14272  	function get_links()
14273      {
14274          $links = SimplePie_Misc::get_element('a', $this->file->body);
14275          foreach ($links as $link)
14276          {
14277              if (isset($link['attribs']['href']['data']))
14278              {
14279                  $href = trim($link['attribs']['href']['data']);
14280                  $parsed = SimplePie_Misc::parse_url($href);
14281                  if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme']))
14282                  {
14283                      if ($this->base_location < $link['offset'])
14284                      {
14285                          $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base);
14286                      }
14287                      else
14288                      {
14289                          $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base);
14290                      }
14291  
14292                      $current = SimplePie_Misc::parse_url($this->file->url);
14293  
14294                      if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
14295                      {
14296                          $this->local[] = $href;
14297                      }
14298                      else
14299                      {
14300                          $this->elsewhere[] = $href;
14301                      }
14302                  }
14303              }
14304          }
14305          $this->local = array_unique($this->local);
14306          $this->elsewhere = array_unique($this->elsewhere);
14307          if (!empty($this->local) || !empty($this->elsewhere))
14308          {
14309              return true;
14310          }
14311          return null;
14312      }
14313  
14314  	function extension(&$array)
14315      {
14316          foreach ($array as $key => $value)
14317          {
14318              if ($this->checked_feeds === $this->max_checked_feeds)
14319              {
14320                  break;
14321              }
14322              if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
14323              {
14324                  $this->checked_feeds++;
14325                  $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14326                  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))
14327                  {
14328                      return $feed;
14329                  }
14330                  else
14331                  {
14332                      unset($array[$key]);
14333                  }
14334              }
14335          }
14336          return null;
14337      }
14338  
14339  	function body(&$array)
14340      {
14341          foreach ($array as $key => $value)
14342          {
14343              if ($this->checked_feeds === $this->max_checked_feeds)
14344              {
14345                  break;
14346              }
14347              if (preg_match('/(rss|rdf|atom|xml)/i', $value))
14348              {
14349                  $this->checked_feeds++;
14350                  $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent);
14351                  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))
14352                  {
14353                      return $feed;
14354                  }
14355                  else
14356                  {
14357                      unset($array[$key]);
14358                  }
14359              }
14360          }
14361          return null;
14362      }
14363  }
14364  
14365  class SimplePie_Parser
14366  {
14367      var $error_code;
14368      var $error_string;
14369      var $current_line;
14370      var $current_column;
14371      var $current_byte;
14372      var $separator = ' ';
14373      var $namespace = array('');
14374      var $element = array('');
14375      var $xml_base = array('');
14376      var $xml_base_explicit = array(false);
14377      var $xml_lang = array('');
14378      var $data = array();
14379      var $datas = array(array());
14380      var $current_xhtml_construct = -1;
14381      var $encoding;
14382  
14383  	function parse(&$data, $encoding)
14384      {
14385          // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
14386          if (strtoupper($encoding) === 'US-ASCII')
14387          {
14388              $this->encoding = 'UTF-8';
14389          }
14390          else
14391          {
14392              $this->encoding = $encoding;
14393          }
14394  
14395          // Strip BOM:
14396          // UTF-32 Big Endian BOM
14397          if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
14398          {
14399              $data = substr($data, 4);
14400          }
14401          // UTF-32 Little Endian BOM
14402          elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
14403          {
14404              $data = substr($data, 4);
14405          }
14406          // UTF-16 Big Endian BOM
14407          elseif (substr($data, 0, 2) === "\xFE\xFF")
14408          {
14409              $data = substr($data, 2);
14410          }
14411          // UTF-16 Little Endian BOM
14412          elseif (substr($data, 0, 2) === "\xFF\xFE")
14413          {
14414              $data = substr($data, 2);
14415          }
14416          // UTF-8 BOM
14417          elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
14418          {
14419              $data = substr($data, 3);
14420          }
14421  
14422          if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
14423          {
14424              $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5));
14425              if ($declaration->parse())
14426              {
14427                  $data = substr($data, $pos + 2);
14428                  $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data;
14429              }
14430              else
14431              {
14432                  $this->error_string = 'SimplePie bug! Please report this!';
14433                  return false;
14434              }
14435          }
14436  
14437          $return = true;
14438  
14439          static $xml_is_sane = null;
14440          if ($xml_is_sane === null)
14441          {
14442              $parser_check = xml_parser_create();
14443              xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
14444              xml_parser_free($parser_check);
14445              $xml_is_sane = isset($values[0]['value']);
14446          }
14447  
14448          // Create the parser
14449          if ($xml_is_sane)
14450          {
14451              $xml = xml_parser_create_ns($this->encoding, $this->separator);
14452              xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
14453              xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
14454              xml_set_object($xml, $this);
14455              xml_set_character_data_handler($xml, 'cdata');
14456              xml_set_element_handler($xml, 'tag_open', 'tag_close');
14457  
14458              // Parse!
14459              if (!xml_parse($xml, $data, true))
14460              {
14461                  $this->error_code = xml_get_error_code($xml);
14462                  $this->error_string = xml_error_string($this->error_code);
14463                  $return = false;
14464              }
14465              $this->current_line = xml_get_current_line_number($xml);
14466              $this->current_column = xml_get_current_column_number($xml);
14467              $this->current_byte = xml_get_current_byte_index($xml);
14468              xml_parser_free($xml);
14469              return $return;
14470          }
14471          else
14472          {
14473              libxml_clear_errors();
14474              $xml =& new XMLReader();
14475              $xml->xml($data);
14476              while (@$xml->read())
14477              {
14478                  switch ($xml->nodeType)
14479                  {
14480  
14481                      case constant('XMLReader::END_ELEMENT'):
14482                          if ($xml->namespaceURI !== '')
14483                          {
14484                              $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14485                          }
14486                          else
14487                          {
14488                              $tagName = $xml->localName;
14489                          }
14490                          $this->tag_close(null, $tagName);
14491                          break;
14492                      case constant('XMLReader::ELEMENT'):
14493                          $empty = $xml->isEmptyElement;
14494                          if ($xml->namespaceURI !== '')
14495                          {
14496                              $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14497                          }
14498                          else
14499                          {
14500                              $tagName = $xml->localName;
14501                          }
14502                          $attributes = array();
14503                          while ($xml->moveToNextAttribute())
14504                          {
14505                              if ($xml->namespaceURI !== '')
14506                              {
14507                                  $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}";
14508                              }
14509                              else
14510                              {
14511                                  $attrName = $xml->localName;
14512                              }
14513                              $attributes[$attrName] = $xml->value;
14514                          }
14515                          $this->tag_open(null, $tagName, $attributes);
14516                          if ($empty)
14517                          {
14518                              $this->tag_close(null, $tagName);
14519                          }
14520                          break;
14521                      case constant('XMLReader::TEXT'):
14522  
14523                      case constant('XMLReader::CDATA'):
14524                          $this->cdata(null, $xml->value);
14525                          break;
14526                  }
14527              }
14528              if ($error = libxml_get_last_error())
14529              {
14530                  $this->error_code = $error->code;
14531                  $this->error_string = $error->message;
14532                  $this->current_line = $error->line;
14533                  $this->current_column = $error->column;
14534                  return false;
14535              }
14536              else
14537              {
14538                  return true;
14539              }
14540          }
14541      }
14542  
14543  	function get_error_code()
14544      {
14545          return $this->error_code;
14546      }
14547  
14548  	function get_error_string()
14549      {
14550          return $this->error_string;
14551      }
14552  
14553  	function get_current_line()
14554      {
14555          return $this->current_line;
14556      }
14557  
14558  	function get_current_column()
14559      {
14560          return $this->current_column;
14561      }
14562  
14563  	function get_current_byte()
14564      {
14565          return $this->current_byte;
14566      }
14567  
14568  	function get_data()
14569      {
14570          return $this->data;
14571      }
14572  
14573  	function tag_open($parser, $tag, $attributes)
14574      {
14575          list($this->namespace[], $this->element[]) = $this->split_ns($tag);
14576  
14577          $attribs = array();
14578          foreach ($attributes as $name => $value)
14579          {
14580              list($attrib_namespace, $attribute) = $this->split_ns($name);
14581              $attribs[$attrib_namespace][$attribute] = $value;
14582          }
14583  
14584          if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
14585          {
14586              $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base));
14587              $this->xml_base_explicit[] = true;
14588          }
14589          else
14590          {
14591              $this->xml_base[] = end($this->xml_base);
14592              $this->xml_base_explicit[] = end($this->xml_base_explicit);
14593          }
14594  
14595          if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
14596          {
14597              $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
14598          }
14599          else
14600          {
14601              $this->xml_lang[] = end($this->xml_lang);
14602          }
14603  
14604          if ($this->current_xhtml_construct >= 0)
14605          {
14606              $this->current_xhtml_construct++;
14607              if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
14608              {
14609                  $this->data['data'] .= '<' . end($this->element);
14610                  if (isset($attribs['']))
14611                  {
14612                      foreach ($attribs[''] as $name => $value)
14613                      {
14614                          $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
14615                      }
14616                  }
14617                  $this->data['data'] .= '>';
14618              }
14619          }
14620          else
14621          {
14622              $this->datas[] =& $this->data;
14623              $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
14624              $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));
14625              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')
14626              || (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'))
14627              {
14628                  $this->current_xhtml_construct = 0;
14629              }
14630          }
14631      }
14632  
14633  	function cdata($parser, $cdata)
14634      {
14635          if ($this->current_xhtml_construct >= 0)
14636          {
14637              $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
14638          }
14639          else
14640          {
14641              $this->data['data'] .= $cdata;
14642          }
14643      }
14644  
14645  	function tag_close($parser, $tag)
14646      {
14647          if ($this->current_xhtml_construct >= 0)
14648          {
14649              $this->current_xhtml_construct--;
14650              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')))
14651              {
14652                  $this->data['data'] .= '</' . end($this->element) . '>';
14653              }
14654          }
14655          if ($this->current_xhtml_construct === -1)
14656          {
14657              $this->data =& $this->datas[count($this->datas) - 1];
14658              array_pop($this->datas);
14659          }
14660  
14661          array_pop($this->element);
14662          array_pop($this->namespace);
14663          array_pop($this->xml_base);
14664          array_pop($this->xml_base_explicit);
14665          array_pop($this->xml_lang);
14666      }
14667  
14668  	function split_ns($string)
14669      {
14670          static $cache = array();
14671          if (!isset($cache[$string]))
14672          {
14673              if ($pos = strpos($string, $this->separator))
14674              {
14675                  static $separator_length;
14676                  if (!$separator_length)
14677                  {
14678                      $separator_length = strlen($this->separator);
14679                  }
14680                  $namespace = substr($string, 0, $pos);
14681                  $local_name = substr($string, $pos + $separator_length);
14682                  if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
14683                  {
14684                      $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
14685                  }
14686  
14687                  // Normalize the Media RSS namespaces
14688                  if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG ||
14689                      $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2 ||
14690                      $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3 ||
14691                      $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4 ||
14692                      $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5 )
14693                  {
14694                      $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
14695                  }
14696                  $cache[$string] = array($namespace, $local_name);
14697              }
14698              else
14699              {
14700                  $cache[$string] = array('', $string);
14701              }
14702          }
14703          return $cache[$string];
14704      }
14705  }
14706  
14707  /**
14708   * @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
14709   */
14710  class SimplePie_Sanitize
14711  {
14712      // Private vars
14713      var $base;
14714  
14715      // Options
14716      var $remove_div = true;
14717      var $image_handler = '';
14718      var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
14719      var $encode_instead_of_strip = false;
14720      var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
14721      var $strip_comments = false;
14722      var $output_encoding = 'UTF-8';
14723      var $enable_cache = true;
14724      var $cache_location = './cache';
14725      var $cache_name_function = 'md5';
14726      var $cache_class = 'SimplePie_Cache';
14727      var $file_class = 'SimplePie_File';
14728      var $timeout = 10;
14729      var $useragent = '';
14730      var $force_fsockopen = false;
14731  
14732      var $replace_url_attributes = array(
14733          'a' => 'href',
14734          'area' => 'href',
14735          'blockquote' => 'cite',
14736          'del' => 'cite',
14737          'form' => 'action',
14738          'img' => array('longdesc', 'src'),
14739          'input' => 'src',
14740          'ins' => 'cite',
14741          'q' => 'cite'
14742      );
14743  
14744  	function remove_div($enable = true)
14745      {
14746          $this->remove_div = (bool) $enable;
14747      }
14748  
14749  	function set_image_handler($page = false)
14750      {
14751          if ($page)
14752          {
14753              $this->image_handler = (string) $page;
14754          }
14755          else
14756          {
14757              $this->image_handler = false;
14758          }
14759      }
14760  
14761  	function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
14762      {
14763          if (isset($enable_cache))
14764          {
14765              $this->enable_cache = (bool) $enable_cache;
14766          }
14767  
14768          if ($cache_location)
14769          {
14770              $this->cache_location = (string) $cache_location;
14771          }
14772  
14773          if ($cache_name_function)
14774          {
14775              $this->cache_name_function = (string) $cache_name_function;
14776          }
14777  
14778          if ($cache_class)
14779          {
14780              $this->cache_class = (string) $cache_class;
14781          }
14782      }
14783  
14784  	function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
14785      {
14786          if ($file_class)
14787          {
14788              $this->file_class = (string) $file_class;
14789          }
14790  
14791          if ($timeout)
14792          {
14793              $this->timeout = (string) $timeout;
14794          }
14795  
14796          if ($useragent)
14797          {
14798              $this->useragent = (string) $useragent;
14799          }
14800  
14801          if ($force_fsockopen)
14802          {
14803              $this->force_fsockopen = (string) $force_fsockopen;
14804          }
14805      }
14806  
14807  	function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
14808      {
14809          if ($tags)
14810          {
14811              if (is_array($tags))
14812              {
14813                  $this->strip_htmltags = $tags;
14814              }
14815              else
14816              {
14817                  $this->strip_htmltags = explode(',', $tags);
14818              }
14819          }
14820          else
14821          {
14822              $this->strip_htmltags = false;
14823          }
14824      }
14825  
14826  	function encode_instead_of_strip($encode = false)
14827      {
14828          $this->encode_instead_of_strip = (bool) $encode;
14829      }
14830  
14831  	function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
14832      {
14833          if ($attribs)
14834          {
14835              if (is_array($attribs))
14836              {
14837                  $this->strip_attributes = $attribs;
14838              }
14839              else
14840              {
14841                  $this->strip_attributes = explode(',', $attribs);
14842              }
14843          }
14844          else
14845          {
14846              $this->strip_attributes = false;
14847          }
14848      }
14849  
14850  	function strip_comments($strip = false)
14851      {
14852          $this->strip_comments = (bool) $strip;
14853      }
14854  
14855  	function set_output_encoding($encoding = 'UTF-8')
14856      {
14857          $this->output_encoding = (string) $encoding;
14858      }
14859  
14860      /**
14861       * Set element/attribute key/value pairs of HTML attributes
14862       * containing URLs that need to be resolved relative to the feed
14863       *
14864       * @access public
14865       * @since 1.0
14866       * @param array $element_attribute Element/attribute key/value pairs
14867       */
14868  	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'))
14869      {
14870          $this->replace_url_attributes = (array) $element_attribute;
14871      }
14872  
14873  	function sanitize($data, $type, $base = '')
14874      {
14875          $data = trim($data);
14876          if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
14877          {
14878              if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
14879              {
14880                  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))
14881                  {
14882                      $type |= SIMPLEPIE_CONSTRUCT_HTML;
14883                  }
14884                  else
14885                  {
14886                      $type |= SIMPLEPIE_CONSTRUCT_TEXT;
14887                  }
14888              }
14889  
14890              if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
14891              {
14892                  $data = base64_decode($data);
14893              }
14894  
14895              if ($type & SIMPLEPIE_CONSTRUCT_XHTML)
14896              {
14897                  if ($this->remove_div)
14898                  {
14899                      $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
14900                      $data = preg_replace('/<\/div>$/', '', $data);
14901                  }
14902                  else
14903                  {
14904                      $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
14905                  }
14906              }
14907  
14908              if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
14909              {
14910                  // Strip comments
14911                  if ($this->strip_comments)
14912                  {
14913                      $data = SimplePie_Misc::strip_comments($data);
14914                  }
14915  
14916                  // Strip out HTML tags and attributes that might cause various security problems.
14917                  // Based on recommendations by Mark Pilgrim at:
14918                  // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
14919                  if ($this->strip_htmltags)
14920                  {
14921                      foreach ($this->strip_htmltags as $tag)
14922                      {
14923                          $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU';
14924                          while (preg_match($pcre, $data))
14925                          {
14926                              $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data);
14927                          }
14928                      }
14929                  }
14930  
14931                  if ($this->strip_attributes)
14932                  {
14933                      foreach ($this->strip_attributes as $attrib)
14934                      {
14935                          $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);
14936                      }
14937                  }
14938  
14939                  // Replace relative URLs
14940                  $this->base = $base;
14941                  foreach ($this->replace_url_attributes as $element => $attributes)
14942                  {
14943                      $data = $this->replace_urls($data, $element, $attributes);
14944                  }
14945  
14946                  // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
14947                  if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
14948                  {
14949                      $images = SimplePie_Misc::get_element('img', $data);
14950                      foreach ($images as $img)
14951                      {
14952                          if (isset($img['attribs']['src']['data']))
14953                          {
14954                              $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']);
14955                              $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi');
14956  
14957                              if ($cache->load())
14958                              {
14959                                  $img['attribs']['src']['data'] = $this->image_handler . $image_url;
14960                                  $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
14961                              }
14962                              else
14963                              {
14964                                  $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen);
14965                                  $headers = $file->headers;
14966  
14967                                  if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
14968                                  {
14969                                      if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
14970                                      {
14971                                          $img['attribs']['src']['data'] = $this->image_handler . $image_url;
14972                                          $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data);
14973                                      }
14974                                      else
14975                                      {
14976                                          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);
14977                                      }
14978                                  }
14979                              }
14980                          }
14981                      }
14982                  }
14983  
14984                  // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data
14985                  $data = trim($data);
14986              }
14987  
14988              if ($type & SIMPLEPIE_CONSTRUCT_IRI)
14989              {
14990                  $data = SimplePie_Misc::absolutize_url($data, $base);
14991              }
14992  
14993              if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
14994              {
14995                  $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
14996              }
14997  
14998              if ($this->output_encoding !== 'UTF-8')
14999              {
15000                  $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding);
15001              }
15002          }
15003          return $data;
15004      }
15005  
15006  	function replace_urls($data, $tag, $attributes)
15007      {
15008          if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
15009          {
15010              $elements = SimplePie_Misc::get_element($tag, $data);
15011              foreach ($elements as $element)
15012              {
15013                  if (is_array($attributes))
15014                  {
15015                      foreach ($attributes as $attribute)
15016                      {
15017                          if (isset($element['attribs'][$attribute]['data']))
15018                          {
15019                              $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base);
15020                              $new_element = SimplePie_Misc::element_implode($element);
15021                              $data = str_replace($element['full'], $new_element, $data);
15022                              $element['full'] = $new_element;
15023                          }
15024                      }
15025                  }
15026                  elseif (isset($element['attribs'][$attributes]['data']))
15027                  {
15028                      $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base);
15029                      $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data);
15030                  }
15031              }
15032          }
15033          return $data;
15034      }
15035  
15036  	function do_strip_htmltags($match)
15037      {
15038          if ($this->encode_instead_of_strip)
15039          {
15040              if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
15041              {
15042                  $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
15043                  $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
15044                  return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
15045              }
15046              else
15047              {
15048                  return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
15049              }
15050          }
15051          elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
15052          {
15053              return $match[4];
15054          }
15055          else
15056          {
15057              return '';
15058          }
15059      }
15060  }
15061  
15062  ?>


Generated: Tue Nov 16 22:51:00 2010 Cross-referenced by PHPXref 0.7