1<?php 2if ( !class_exists( 'SimplePie' ) ) : 3/** 4 * SimplePie 5 * 6 * A PHP-Based RSS and Atom Feed Framework. 7 * Takes the hard work out of managing a complete RSS/Atom solution. 8 * 9 * Copyright (c) 2004-2009, Ryan Parman and Geoffrey Sneddon 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without modification, are 13 * permitted provided that the following conditions are met: 14 * 15 * * Redistributions of source code must retain the above copyright notice, this list of 16 * conditions and the following disclaimer. 17 * 18 * * Redistributions in binary form must reproduce the above copyright notice, this list 19 * of conditions and the following disclaimer in the documentation and/or other materials 20 * provided with the distribution. 21 * 22 * * Neither the name of the SimplePie Team nor the names of its contributors may be used 23 * to endorse or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 27 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 28 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 29 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 33 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 * 36 * @package SimplePie 37 * @version 1.2 38 * @copyright 2004-2009 Ryan Parman, Geoffrey Sneddon 39 * @author Ryan Parman 40 * @author Geoffrey Sneddon 41 * @link http://simplepie.org/ SimplePie 42 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums 43 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 44 * @todo phpDoc comments 45 */ 46 47/** 48 * SimplePie Name 49 */ 50define('SIMPLEPIE_NAME', 'SimplePie'); 51 52/** 53 * SimplePie Version 54 */ 55define('SIMPLEPIE_VERSION', '1.2'); 56 57/** 58 * SimplePie Build 59 */ 60define('SIMPLEPIE_BUILD', '20090627192103'); 61 62/** 63 * SimplePie Website URL 64 */ 65define('SIMPLEPIE_URL', 'http://simplepie.org'); 66 67/** 68 * SimplePie Useragent 69 * @see SimplePie::set_useragent() 70 */ 71define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD); 72 73/** 74 * SimplePie Linkback 75 */ 76define('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 */ 82define('SIMPLEPIE_LOCATOR_NONE', 0); 83 84/** 85 * Feed Link Element Autodiscovery 86 * @see SimplePie::set_autodiscovery_level() 87 */ 88define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1); 89 90/** 91 * Local Feed Extension Autodiscovery 92 * @see SimplePie::set_autodiscovery_level() 93 */ 94define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2); 95 96/** 97 * Local Feed Body Autodiscovery 98 * @see SimplePie::set_autodiscovery_level() 99 */ 100define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4); 101 102/** 103 * Remote Feed Extension Autodiscovery 104 * @see SimplePie::set_autodiscovery_level() 105 */ 106define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8); 107 108/** 109 * Remote Feed Body Autodiscovery 110 * @see SimplePie::set_autodiscovery_level() 111 */ 112define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16); 113 114/** 115 * All Feed Autodiscovery 116 * @see SimplePie::set_autodiscovery_level() 117 */ 118define('SIMPLEPIE_LOCATOR_ALL', 31); 119 120/** 121 * No known feed type 122 */ 123define('SIMPLEPIE_TYPE_NONE', 0); 124 125/** 126 * RSS 0.90 127 */ 128define('SIMPLEPIE_TYPE_RSS_090', 1); 129 130/** 131 * RSS 0.91 (Netscape) 132 */ 133define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2); 134 135/** 136 * RSS 0.91 (Userland) 137 */ 138define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4); 139 140/** 141 * RSS 0.91 (both Netscape and Userland) 142 */ 143define('SIMPLEPIE_TYPE_RSS_091', 6); 144 145/** 146 * RSS 0.92 147 */ 148define('SIMPLEPIE_TYPE_RSS_092', 8); 149 150/** 151 * RSS 0.93 152 */ 153define('SIMPLEPIE_TYPE_RSS_093', 16); 154 155/** 156 * RSS 0.94 157 */ 158define('SIMPLEPIE_TYPE_RSS_094', 32); 159 160/** 161 * RSS 1.0 162 */ 163define('SIMPLEPIE_TYPE_RSS_10', 64); 164 165/** 166 * RSS 2.0 167 */ 168define('SIMPLEPIE_TYPE_RSS_20', 128); 169 170/** 171 * RDF-based RSS 172 */ 173define('SIMPLEPIE_TYPE_RSS_RDF', 65); 174 175/** 176 * Non-RDF-based RSS (truly intended as syndication format) 177 */ 178define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190); 179 180/** 181 * All RSS 182 */ 183define('SIMPLEPIE_TYPE_RSS_ALL', 255); 184 185/** 186 * Atom 0.3 187 */ 188define('SIMPLEPIE_TYPE_ATOM_03', 256); 189 190/** 191 * Atom 1.0 192 */ 193define('SIMPLEPIE_TYPE_ATOM_10', 512); 194 195/** 196 * All Atom 197 */ 198define('SIMPLEPIE_TYPE_ATOM_ALL', 768); 199 200/** 201 * All feed types 202 */ 203define('SIMPLEPIE_TYPE_ALL', 1023); 204 205/** 206 * No construct 207 */ 208define('SIMPLEPIE_CONSTRUCT_NONE', 0); 209 210/** 211 * Text construct 212 */ 213define('SIMPLEPIE_CONSTRUCT_TEXT', 1); 214 215/** 216 * HTML construct 217 */ 218define('SIMPLEPIE_CONSTRUCT_HTML', 2); 219 220/** 221 * XHTML construct 222 */ 223define('SIMPLEPIE_CONSTRUCT_XHTML', 4); 224 225/** 226 * base64-encoded construct 227 */ 228define('SIMPLEPIE_CONSTRUCT_BASE64', 8); 229 230/** 231 * IRI construct 232 */ 233define('SIMPLEPIE_CONSTRUCT_IRI', 16); 234 235/** 236 * A construct that might be HTML 237 */ 238define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32); 239 240/** 241 * All constructs 242 */ 243define('SIMPLEPIE_CONSTRUCT_ALL', 63); 244 245/** 246 * Don't change case 247 */ 248define('SIMPLEPIE_SAME_CASE', 1); 249 250/** 251 * Change to lowercase 252 */ 253define('SIMPLEPIE_LOWERCASE', 2); 254 255/** 256 * Change to uppercase 257 */ 258define('SIMPLEPIE_UPPERCASE', 4); 259 260/** 261 * PCRE for HTML attributes 262 */ 263define('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 */ 268define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*'); 269 270/** 271 * XML Namespace 272 */ 273define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace'); 274 275/** 276 * Atom 1.0 Namespace 277 */ 278define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom'); 279 280/** 281 * Atom 0.3 Namespace 282 */ 283define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#'); 284 285/** 286 * RDF Namespace 287 */ 288define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); 289 290/** 291 * RSS 0.90 Namespace 292 */ 293define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/'); 294 295/** 296 * RSS 1.0 Namespace 297 */ 298define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/'); 299 300/** 301 * RSS 1.0 Content Module Namespace 302 */ 303define('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 */ 309define('SIMPLEPIE_NAMESPACE_RSS_20', ''); 310 311/** 312 * DC 1.0 Namespace 313 */ 314define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/'); 315 316/** 317 * DC 1.1 Namespace 318 */ 319define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/'); 320 321/** 322 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace 323 */ 324define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#'); 325 326/** 327 * GeoRSS Namespace 328 */ 329define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss'); 330 331/** 332 * Media RSS Namespace 333 */ 334define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/'); 335 336/** 337 * Wrong Media RSS Namespace 338 */ 339define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss'); 340 341/** 342 * iTunes RSS Namespace 343 */ 344define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd'); 345 346/** 347 * XHTML Namespace 348 */ 349define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml'); 350 351/** 352 * IANA Link Relations Registry 353 */ 354define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/'); 355 356/** 357 * Whether we're running on PHP5 358 */ 359define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>=')); 360 361/** 362 * No file source 363 */ 364define('SIMPLEPIE_FILE_SOURCE_NONE', 0); 365 366/** 367 * Remote file source 368 */ 369define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1); 370 371/** 372 * Local file source 373 */ 374define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2); 375 376/** 377 * fsockopen() file source 378 */ 379define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4); 380 381/** 382 * cURL file source 383 */ 384define('SIMPLEPIE_FILE_SOURCE_CURL', 8); 385 386/** 387 * file_get_contents() file source 388 */ 389define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16); 390 391/** 392 * SimplePie 393 * 394 * @package SimplePie 395 */ 396class SimplePie 397{ 398 /** 399 * @var array Raw data 400 * @access private 401 */ 402 var $data = array(); 403 404 /** 405 * @var mixed Error string 406 * @access private 407 */ 408 var $error; 409 410 /** 411 * @var object Instance of SimplePie_Sanitize (or other class) 412 * @see SimplePie::set_sanitize_class() 413 * @access private 414 */ 415 var $sanitize; 416 417 /** 418 * @var string SimplePie Useragent 419 * @see SimplePie::set_useragent() 420 * @access private 421 */ 422 var $useragent = SIMPLEPIE_USERAGENT; 423 424 /** 425 * @var string Feed URL 426 * @see SimplePie::set_feed_url() 427 * @access private 428 */ 429 var $feed_url; 430 431 /** 432 * @var object Instance of SimplePie_File to use as a feed 433 * @see SimplePie::set_file() 434 * @access private 435 */ 436 var $file; 437 438 /** 439 * @var string Raw feed data 440 * @see SimplePie::set_raw_data() 441 * @access private 442 */ 443 var $raw_data; 444 445 /** 446 * @var int Timeout for fetching remote files 447 * @see SimplePie::set_timeout() 448 * @access private 449 */ 450 var $timeout = 10; 451 452 /** 453 * @var bool Forces fsockopen() to be used for remote files instead 454 * of cURL, even if a new enough version is installed 455 * @see SimplePie::force_fsockopen() 456 * @access private 457 */ 458 var $force_fsockopen = false; 459 460 /** 461 * @var bool Force the given data/URL to be treated as a feed no matter what 462 * it appears like 463 * @see SimplePie::force_feed() 464 * @access private 465 */ 466 var $force_feed = false; 467 468 /** 469 * @var bool Enable/Disable XML dump 470 * @see SimplePie::enable_xml_dump() 471 * @access private 472 */ 473 var $xml_dump = false; 474 475 /** 476 * @var bool Enable/Disable Caching 477 * @see SimplePie::enable_cache() 478 * @access private 479 */ 480 var $cache = true; 481 482 /** 483 * @var int Cache duration (in seconds) 484 * @see SimplePie::set_cache_duration() 485 * @access private 486 */ 487 var $cache_duration = 3600; 488 489 /** 490 * @var int Auto-discovery cache duration (in seconds) 491 * @see SimplePie::set_autodiscovery_cache_duration() 492 * @access private 493 */ 494 var $autodiscovery_cache_duration = 604800; // 7 Days. 495 496 /** 497 * @var string Cache location (relative to executing script) 498 * @see SimplePie::set_cache_location() 499 * @access private 500 */ 501 var $cache_location = './cache'; 502 503 /** 504 * @var string Function that creates the cache filename 505 * @see SimplePie::set_cache_name_function() 506 * @access private 507 */ 508 var $cache_name_function = 'md5'; 509 510 /** 511 * @var bool Reorder feed by date descending 512 * @see SimplePie::enable_order_by_date() 513 * @access private 514 */ 515 var $order_by_date = true; 516 517 /** 518 * @var mixed Force input encoding to be set to the follow value 519 * (false, or anything type-cast to false, disables this feature) 520 * @see SimplePie::set_input_encoding() 521 * @access private 522 */ 523 var $input_encoding = false; 524 525 /** 526 * @var int Feed Autodiscovery Level 527 * @see SimplePie::set_autodiscovery_level() 528 * @access private 529 */ 530 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL; 531 532 /** 533 * @var string Class used for caching feeds 534 * @see SimplePie::set_cache_class() 535 * @access private 536 */ 537 var $cache_class = 'SimplePie_Cache'; 538 539 /** 540 * @var string Class used for locating feeds 541 * @see SimplePie::set_locator_class() 542 * @access private 543 */ 544 var $locator_class = 'SimplePie_Locator'; 545 546 /** 547 * @var string Class used for parsing feeds 548 * @see SimplePie::set_parser_class() 549 * @access private 550 */ 551 var $parser_class = 'SimplePie_Parser'; 552 553 /** 554 * @var string Class used for fetching feeds 555 * @see SimplePie::set_file_class() 556 * @access private 557 */ 558 var $file_class = 'SimplePie_File'; 559 560 /** 561 * @var string Class used for items 562 * @see SimplePie::set_item_class() 563 * @access private 564 */ 565 var $item_class = 'SimplePie_Item'; 566 567 /** 568 * @var string Class used for authors 569 * @see SimplePie::set_author_class() 570 * @access private 571 */ 572 var $author_class = 'SimplePie_Author'; 573 574 /** 575 * @var string Class used for categories 576 * @see SimplePie::set_category_class() 577 * @access private 578 */ 579 var $category_class = 'SimplePie_Category'; 580 581 /** 582 * @var string Class used for enclosures 583 * @see SimplePie::set_enclosures_class() 584 * @access private 585 */ 586 var $enclosure_class = 'SimplePie_Enclosure'; 587 588 /** 589 * @var string Class used for Media RSS <media:text> captions 590 * @see SimplePie::set_caption_class() 591 * @access private 592 */ 593 var $caption_class = 'SimplePie_Caption'; 594 595 /** 596 * @var string Class used for Media RSS <media:copyright> 597 * @see SimplePie::set_copyright_class() 598 * @access private 599 */ 600 var $copyright_class = 'SimplePie_Copyright'; 601 602 /** 603 * @var string Class used for Media RSS <media:credit> 604 * @see SimplePie::set_credit_class() 605 * @access private 606 */ 607 var $credit_class = 'SimplePie_Credit'; 608 609 /** 610 * @var string Class used for Media RSS <media:rating> 611 * @see SimplePie::set_rating_class() 612 * @access private 613 */ 614 var $rating_class = 'SimplePie_Rating'; 615 616 /** 617 * @var string Class used for Media RSS <media:restriction> 618 * @see SimplePie::set_restriction_class() 619 * @access private 620 */ 621 var $restriction_class = 'SimplePie_Restriction'; 622 623 /** 624 * @var string Class used for content-type sniffing 625 * @see SimplePie::set_content_type_sniffer_class() 626 * @access private 627 */ 628 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; 629 630 /** 631 * @var string Class used for item sources. 632 * @see SimplePie::set_source_class() 633 * @access private 634 */ 635 var $source_class = 'SimplePie_Source'; 636 637 /** 638 * @var mixed Set javascript query string parameter (false, or 639 * anything type-cast to false, disables this feature) 640 * @see SimplePie::set_javascript() 641 * @access private 642 */ 643 var $javascript = 'js'; 644 645 /** 646 * @var int Maximum number of feeds to check with autodiscovery 647 * @see SimplePie::set_max_checked_feeds() 648 * @access private 649 */ 650 var $max_checked_feeds = 10; 651 652 /** 653 * @var array All the feeds found during the autodiscovery process 654 * @see SimplePie::get_all_discovered_feeds() 655 * @access private 656 */ 657 var $all_discovered_feeds = array(); 658 659 /** 660 * @var string Web-accessible path to the handler_favicon.php file. 661 * @see SimplePie::set_favicon_handler() 662 * @access private 663 */ 664 var $favicon_handler = ''; 665 666 /** 667 * @var string Web-accessible path to the handler_image.php file. 668 * @see SimplePie::set_image_handler() 669 * @access private 670 */ 671 var $image_handler = ''; 672 673 /** 674 * @var array Stores the URLs when multiple feeds are being initialized. 675 * @see SimplePie::set_feed_url() 676 * @access private 677 */ 678 var $multifeed_url = array(); 679 680 /** 681 * @var array Stores SimplePie objects when multiple feeds initialized. 682 * @access private 683 */ 684 var $multifeed_objects = array(); 685 686 /** 687 * @var array Stores the get_object_vars() array for use with multifeeds. 688 * @see SimplePie::set_feed_url() 689 * @access private 690 */ 691 var $config_settings = null; 692 693 /** 694 * @var integer Stores the number of items to return per-feed with multifeeds. 695 * @see SimplePie::set_item_limit() 696 * @access private 697 */ 698 var $item_limit = 0; 699 700 /** 701 * @var array Stores the default attributes to be stripped by strip_attributes(). 702 * @see SimplePie::strip_attributes() 703 * @access private 704 */ 705 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); 706 707 /** 708 * @var array Stores the default tags to be stripped by strip_htmltags(). 709 * @see SimplePie::strip_htmltags() 710 * @access private 711 */ 712 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); 713 714 /** 715 * The SimplePie class contains feed level data and options 716 * 717 * There are two ways that you can create a new SimplePie object. The first 718 * is by passing a feed URL as a parameter to the SimplePie constructor 719 * (as well as optionally setting the cache location and cache expiry). This 720 * will initialise the whole feed with all of the default settings, and you 721 * can begin accessing methods and properties immediately. 722 * 723 * The second way is to create the SimplePie object with no parameters 724 * at all. This will enable you to set configuration options. After setting 725 * them, you must initialise the feed using $feed->init(). At that point the 726 * object's methods and properties will be available to you. This format is 727 * what is used throughout this documentation. 728 * 729 * @access public 730 * @since 1.0 Preview Release 731 * @param string $feed_url This is the URL you want to parse. 732 * @param string $cache_location This is where you want the cache to be stored. 733 * @param int $cache_duration This is the number of seconds that you want to store the cache file for. 734 */ 735 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null) 736 { 737 // Other objects, instances created here so we can set options on them 738 $this->sanitize =& new SimplePie_Sanitize; 739 740 // Set options if they're passed to the constructor 741 if ($cache_location !== null) 742 { 743 $this->set_cache_location($cache_location); 744 } 745 746 if ($cache_duration !== null) 747 { 748 $this->set_cache_duration($cache_duration); 749 } 750 751 // Only init the script if we're passed a feed URL 752 if ($feed_url !== null) 753 { 754 $this->set_feed_url($feed_url); 755 $this->init(); 756 } 757 } 758 759 /** 760 * Used for converting object to a string 761 */ 762 function __toString() 763 { 764 return md5(serialize($this->data)); 765 } 766 767 /** 768 * Remove items that link back to this before destroying this object 769 */ 770 function __destruct() 771 { 772 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode')) 773 { 774 if (!empty($this->data['items'])) 775 { 776 foreach ($this->data['items'] as $item) 777 { 778 $item->__destruct(); 779 } 780 unset($item, $this->data['items']); 781 } 782 if (!empty($this->data['ordered_items'])) 783 { 784 foreach ($this->data['ordered_items'] as $item) 785 { 786 $item->__destruct(); 787 } 788 unset($item, $this->data['ordered_items']); 789 } 790 } 791 } 792 793 /** 794 * Force the given data/URL to be treated as a feed no matter what it 795 * appears like 796 * 797 * @access public 798 * @since 1.1 799 * @param bool $enable Force the given data/URL to be treated as a feed 800 */ 801 function force_feed($enable = false) 802 { 803 $this->force_feed = (bool) $enable; 804 } 805 806 /** 807 * This is the URL of the feed you want to parse. 808 * 809 * This allows you to enter the URL of the feed you want to parse, or the 810 * website you want to try to use auto-discovery on. This takes priority 811 * over any set raw data. 812 * 813 * You can set multiple feeds to mash together by passing an array instead 814 * of a string for the $url. Remember that with each additional feed comes 815 * additional processing and resources. 816 * 817 * @access public 818 * @since 1.0 Preview Release 819 * @param mixed $url This is the URL (or array of URLs) that you want to parse. 820 * @see SimplePie::set_raw_data() 821 */ 822 function set_feed_url($url) 823 { 824 if (is_array($url)) 825 { 826 $this->multifeed_url = array(); 827 foreach ($url as $value) 828 { 829 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1); 830 } 831 } 832 else 833 { 834 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1); 835 } 836 } 837 838 /** 839 * Provides an instance of SimplePie_File to use as a feed 840 * 841 * @access public 842 * @param object &$file Instance of SimplePie_File (or subclass) 843 * @return bool True on success, false on failure 844 */ 845 function set_file(&$file) 846 { 847 if (is_a($file, 'SimplePie_File')) 848 { 849 $this->feed_url = $file->url; 850 $this->file =& $file; 851 return true; 852 } 853 return false; 854 } 855 856 /** 857 * Allows you to use a string of RSS/Atom data instead of a remote feed. 858 * 859 * If you have a feed available as a string in PHP, you can tell SimplePie 860 * to parse that data string instead of a remote feed. Any set feed URL 861 * takes precedence. 862 * 863 * @access public 864 * @since 1.0 Beta 3 865 * @param string $data RSS or Atom data as a string. 866 * @see SimplePie::set_feed_url() 867 */ 868 function set_raw_data($data) 869 { 870 $this->raw_data = $data; 871 } 872 873 /** 874 * Allows you to override the default timeout for fetching remote feeds. 875 * 876 * This allows you to change the maximum time the feed's server to respond 877 * and send the feed back. 878 * 879 * @access public 880 * @since 1.0 Beta 3 881 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed. 882 */ 883 function set_timeout($timeout = 10) 884 { 885 $this->timeout = (int) $timeout; 886 } 887 888 /** 889 * Forces SimplePie to use fsockopen() instead of the preferred cURL 890 * functions. 891 * 892 * @access public 893 * @since 1.0 Beta 3 894 * @param bool $enable Force fsockopen() to be used 895 */ 896 function force_fsockopen($enable = false) 897 { 898 $this->force_fsockopen = (bool) $enable; 899 } 900 901 /** 902 * Outputs the raw XML content of the feed, after it has gone through 903 * SimplePie's filters. 904 * 905 * Used only for debugging, this function will output the XML content as 906 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up 907 * before trying to parse it. Many parts of the feed are re-written in 908 * memory, and in the end, you have a parsable feed. XML dump shows you the 909 * actual XML that SimplePie tries to parse, which may or may not be very 910 * different from the original feed. 911 * 912 * @access public 913 * @since 1.0 Preview Release 914 * @param bool $enable Enable XML dump 915 */ 916 function enable_xml_dump($enable = false) 917 { 918 $this->xml_dump = (bool) $enable; 919 } 920 921 /** 922 * Enables/disables caching in SimplePie. 923 * 924 * This option allows you to disable caching all-together in SimplePie. 925 * However, disabling the cache can lead to longer load times. 926 * 927 * @access public 928 * @since 1.0 Preview Release 929 * @param bool $enable Enable caching 930 */ 931 function enable_cache($enable = true) 932 { 933 $this->cache = (bool) $enable; 934 } 935 936 /** 937 * Set the length of time (in seconds) that the contents of a feed 938 * will be cached. 939 * 940 * @access public 941 * @param int $seconds The feed content cache duration. 942 */ 943 function set_cache_duration($seconds = 3600) 944 { 945 $this->cache_duration = (int) $seconds; 946 } 947 948 /** 949 * Set the length of time (in seconds) that the autodiscovered feed 950 * URL will be cached. 951 * 952 * @access public 953 * @param int $seconds The autodiscovered feed URL cache duration. 954 */ 955 function set_autodiscovery_cache_duration($seconds = 604800) 956 { 957 $this->autodiscovery_cache_duration = (int) $seconds; 958 } 959 960 /** 961 * Set the file system location where the cached files should be stored. 962 * 963 * @access public 964 * @param string $location The file system location. 965 */ 966 function set_cache_location($location = './cache') 967 { 968 $this->cache_location = (string) $location; 969 } 970 971 /** 972 * Determines whether feed items should be sorted into reverse chronological order. 973 * 974 * @access public 975 * @param bool $enable Sort as reverse chronological order. 976 */ 977 function enable_order_by_date($enable = true) 978 { 979 $this->order_by_date = (bool) $enable; 980 } 981 982 /** 983 * Allows you to override the character encoding reported by the feed. 984 * 985 * @access public 986 * @param string $encoding Character encoding. 987 */ 988 function set_input_encoding($encoding = false) 989 { 990 if ($encoding) 991 { 992 $this->input_encoding = (string) $encoding; 993 } 994 else 995 { 996 $this->input_encoding = false; 997 } 998 } 999 1000 /** 1001 * Set how much feed autodiscovery to do 1002 * 1003 * @access public 1004 * @see SIMPLEPIE_LOCATOR_NONE 1005 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY 1006 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION 1007 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY 1008 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION 1009 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY 1010 * @see SIMPLEPIE_LOCATOR_ALL 1011 * @param int $level Feed Autodiscovery Level (level can be a 1012 * combination of the above constants, see bitwise OR operator) 1013 */ 1014 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL) 1015 { 1016 $this->autodiscovery = (int) $level; 1017 } 1018 1019 /** 1020 * Allows you to change which class SimplePie uses for caching. 1021 * Useful when you are overloading or extending SimplePie's default classes. 1022 * 1023 * @access public 1024 * @param string $class Name of custom class. 1025 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1026 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1027 */ 1028 function set_cache_class($class = 'SimplePie_Cache') 1029 { 1030 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache')) 1031 { 1032 $this->cache_class = $class; 1033 return true; 1034 } 1035 return false; 1036 } 1037 1038 /** 1039 * Allows you to change which class SimplePie uses for auto-discovery. 1040 * Useful when you are overloading or extending SimplePie's default classes. 1041 * 1042 * @access public 1043 * @param string $class Name of custom class. 1044 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1045 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1046 */ 1047 function set_locator_class($class = 'SimplePie_Locator') 1048 { 1049 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator')) 1050 { 1051 $this->locator_class = $class; 1052 return true; 1053 } 1054 return false; 1055 } 1056 1057 /** 1058 * Allows you to change which class SimplePie uses for XML parsing. 1059 * Useful when you are overloading or extending SimplePie's default classes. 1060 * 1061 * @access public 1062 * @param string $class Name of custom class. 1063 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1064 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1065 */ 1066 function set_parser_class($class = 'SimplePie_Parser') 1067 { 1068 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser')) 1069 { 1070 $this->parser_class = $class; 1071 return true; 1072 } 1073 return false; 1074 } 1075 1076 /** 1077 * Allows you to change which class SimplePie uses for remote file fetching. 1078 * Useful when you are overloading or extending SimplePie's default classes. 1079 * 1080 * @access public 1081 * @param string $class Name of custom class. 1082 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1083 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1084 */ 1085 function set_file_class($class = 'SimplePie_File') 1086 { 1087 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File')) 1088 { 1089 $this->file_class = $class; 1090 return true; 1091 } 1092 return false; 1093 } 1094 1095 /** 1096 * Allows you to change which class SimplePie uses for data sanitization. 1097 * Useful when you are overloading or extending SimplePie's default classes. 1098 * 1099 * @access public 1100 * @param string $class Name of custom class. 1101 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1102 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1103 */ 1104 function set_sanitize_class($class = 'SimplePie_Sanitize') 1105 { 1106 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize')) 1107 { 1108 $this->sanitize =& new $class; 1109 return true; 1110 } 1111 return false; 1112 } 1113 1114 /** 1115 * Allows you to change which class SimplePie uses for handling feed items. 1116 * Useful when you are overloading or extending SimplePie's default classes. 1117 * 1118 * @access public 1119 * @param string $class Name of custom class. 1120 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1121 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1122 */ 1123 function set_item_class($class = 'SimplePie_Item') 1124 { 1125 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item')) 1126 { 1127 $this->item_class = $class; 1128 return true; 1129 } 1130 return false; 1131 } 1132 1133 /** 1134 * Allows you to change which class SimplePie uses for handling author data. 1135 * Useful when you are overloading or extending SimplePie's default classes. 1136 * 1137 * @access public 1138 * @param string $class Name of custom class. 1139 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1140 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1141 */ 1142 function set_author_class($class = 'SimplePie_Author') 1143 { 1144 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author')) 1145 { 1146 $this->author_class = $class; 1147 return true; 1148 } 1149 return false; 1150 } 1151 1152 /** 1153 * Allows you to change which class SimplePie uses for handling category data. 1154 * Useful when you are overloading or extending SimplePie's default classes. 1155 * 1156 * @access public 1157 * @param string $class Name of custom class. 1158 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1159 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1160 */ 1161 function set_category_class($class = 'SimplePie_Category') 1162 { 1163 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category')) 1164 { 1165 $this->category_class = $class; 1166 return true; 1167 } 1168 return false; 1169 } 1170 1171 /** 1172 * Allows you to change which class SimplePie uses for feed enclosures. 1173 * Useful when you are overloading or extending SimplePie's default classes. 1174 * 1175 * @access public 1176 * @param string $class Name of custom class. 1177 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1178 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1179 */ 1180 function set_enclosure_class($class = 'SimplePie_Enclosure') 1181 { 1182 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure')) 1183 { 1184 $this->enclosure_class = $class; 1185 return true; 1186 } 1187 return false; 1188 } 1189 1190 /** 1191 * Allows you to change which class SimplePie uses for <media:text> captions 1192 * Useful when you are overloading or extending SimplePie's default classes. 1193 * 1194 * @access public 1195 * @param string $class Name of custom class. 1196 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1197 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1198 */ 1199 function set_caption_class($class = 'SimplePie_Caption') 1200 { 1201 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption')) 1202 { 1203 $this->caption_class = $class; 1204 return true; 1205 } 1206 return false; 1207 } 1208 1209 /** 1210 * Allows you to change which class SimplePie uses for <media:copyright> 1211 * Useful when you are overloading or extending SimplePie's default classes. 1212 * 1213 * @access public 1214 * @param string $class Name of custom class. 1215 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1216 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1217 */ 1218 function set_copyright_class($class = 'SimplePie_Copyright') 1219 { 1220 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright')) 1221 { 1222 $this->copyright_class = $class; 1223 return true; 1224 } 1225 return false; 1226 } 1227 1228 /** 1229 * Allows you to change which class SimplePie uses for <media:credit> 1230 * Useful when you are overloading or extending SimplePie's default classes. 1231 * 1232 * @access public 1233 * @param string $class Name of custom class. 1234 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1235 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1236 */ 1237 function set_credit_class($class = 'SimplePie_Credit') 1238 { 1239 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit')) 1240 { 1241 $this->credit_class = $class; 1242 return true; 1243 } 1244 return false; 1245 } 1246 1247 /** 1248 * Allows you to change which class SimplePie uses for <media:rating> 1249 * Useful when you are overloading or extending SimplePie's default classes. 1250 * 1251 * @access public 1252 * @param string $class Name of custom class. 1253 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1254 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1255 */ 1256 function set_rating_class($class = 'SimplePie_Rating') 1257 { 1258 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating')) 1259 { 1260 $this->rating_class = $class; 1261 return true; 1262 } 1263 return false; 1264 } 1265 1266 /** 1267 * Allows you to change which class SimplePie uses for <media:restriction> 1268 * Useful when you are overloading or extending SimplePie's default classes. 1269 * 1270 * @access public 1271 * @param string $class Name of custom class. 1272 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1273 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1274 */ 1275 function set_restriction_class($class = 'SimplePie_Restriction') 1276 { 1277 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction')) 1278 { 1279 $this->restriction_class = $class; 1280 return true; 1281 } 1282 return false; 1283 } 1284 1285 /** 1286 * Allows you to change which class SimplePie uses for content-type sniffing. 1287 * Useful when you are overloading or extending SimplePie's default classes. 1288 * 1289 * @access public 1290 * @param string $class Name of custom class. 1291 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1292 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1293 */ 1294 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer') 1295 { 1296 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer')) 1297 { 1298 $this->content_type_sniffer_class = $class; 1299 return true; 1300 } 1301 return false; 1302 } 1303 1304 /** 1305 * Allows you to change which class SimplePie uses item sources. 1306 * Useful when you are overloading or extending SimplePie's default classes. 1307 * 1308 * @access public 1309 * @param string $class Name of custom class. 1310 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1311 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1312 */ 1313 function set_source_class($class = 'SimplePie_Source') 1314 { 1315 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source')) 1316 { 1317 $this->source_class = $class; 1318 return true; 1319 } 1320 return false; 1321 } 1322 1323 /** 1324 * Allows you to override the default user agent string. 1325 * 1326 * @access public 1327 * @param string $ua New user agent string. 1328 */ 1329 function set_useragent($ua = SIMPLEPIE_USERAGENT) 1330 { 1331 $this->useragent = (string) $ua; 1332 } 1333 1334 /** 1335 * Set callback function to create cache filename with 1336 * 1337 * @access public 1338 * @param mixed $function Callback function 1339 */ 1340 function set_cache_name_function($function = 'md5') 1341 { 1342 if (is_callable($function)) 1343 { 1344 $this->cache_name_function = $function; 1345 } 1346 } 1347 1348 /** 1349 * Set javascript query string parameter 1350 * 1351 * @access public 1352 * @param mixed $get Javascript query string parameter 1353 */ 1354 function set_javascript($get = 'js') 1355 { 1356 if ($get) 1357 { 1358 $this->javascript = (string) $get; 1359 } 1360 else 1361 { 1362 $this->javascript = false; 1363 } 1364 } 1365 1366 /** 1367 * Set options to make SP as fast as possible. Forgoes a 1368 * substantial amount of data sanitization in favor of speed. 1369 * 1370 * @access public 1371 * @param bool $set Whether to set them or not 1372 */ 1373 function set_stupidly_fast($set = false) 1374 { 1375 if ($set) 1376 { 1377 $this->enable_order_by_date(false); 1378 $this->remove_div(false); 1379 $this->strip_comments(false); 1380 $this->strip_htmltags(false); 1381 $this->strip_attributes(false); 1382 $this->set_image_handler(false); 1383 } 1384 } 1385 1386 /** 1387 * Set maximum number of feeds to check with autodiscovery 1388 * 1389 * @access public 1390 * @param int $max Maximum number of feeds to check 1391 */ 1392 function set_max_checked_feeds($max = 10) 1393 { 1394 $this->max_checked_feeds = (int) $max; 1395 } 1396 1397 function remove_div($enable = true) 1398 { 1399 $this->sanitize->remove_div($enable); 1400 } 1401 1402 function strip_htmltags($tags = '', $encode = null) 1403 { 1404 if ($tags === '') 1405 { 1406 $tags = $this->strip_htmltags; 1407 } 1408 $this->sanitize->strip_htmltags($tags); 1409 if ($encode !== null) 1410 { 1411 $this->sanitize->encode_instead_of_strip($tags); 1412 } 1413 } 1414 1415 function encode_instead_of_strip($enable = true) 1416 { 1417 $this->sanitize->encode_instead_of_strip($enable); 1418 } 1419 1420 function strip_attributes($attribs = '') 1421 { 1422 if ($attribs === '') 1423 { 1424 $attribs = $this->strip_attributes; 1425 } 1426 $this->sanitize->strip_attributes($attribs); 1427 } 1428 1429 function set_output_encoding($encoding = 'UTF-8') 1430 { 1431 $this->sanitize->set_output_encoding($encoding); 1432 } 1433 1434 function strip_comments($strip = false) 1435 { 1436 $this->sanitize->strip_comments($strip); 1437 } 1438 1439 /** 1440 * Set element/attribute key/value pairs of HTML attributes 1441 * containing URLs that need to be resolved relative to the feed 1442 * 1443 * @access public 1444 * @since 1.0 1445 * @param array $element_attribute Element/attribute key/value pairs 1446 */ 1447 function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite')) 1448 { 1449 $this->sanitize->set_url_replacements($element_attribute); 1450 } 1451 1452 /** 1453 * Set the handler to enable the display of cached favicons. 1454 * 1455 * @access public 1456 * @param str $page Web-accessible path to the handler_favicon.php file. 1457 * @param str $qs The query string that the value should be passed to. 1458 */ 1459 function set_favicon_handler($page = false, $qs = 'i') 1460 { 1461 if ($page !== false) 1462 { 1463 $this->favicon_handler = $page . '?' . $qs . '='; 1464 } 1465 else 1466 { 1467 $this->favicon_handler = ''; 1468 } 1469 } 1470 1471 /** 1472 * Set the handler to enable the display of cached images. 1473 * 1474 * @access public 1475 * @param str $page Web-accessible path to the handler_image.php file. 1476 * @param str $qs The query string that the value should be passed to. 1477 */ 1478 function set_image_handler($page = false, $qs = 'i') 1479 { 1480 if ($page !== false) 1481 { 1482 $this->sanitize->set_image_handler($page . '?' . $qs . '='); 1483 } 1484 else 1485 { 1486 $this->image_handler = ''; 1487 } 1488 } 1489 1490 /** 1491 * Set the limit for items returned per-feed with multifeeds. 1492 * 1493 * @access public 1494 * @param integer $limit The maximum number of items to return. 1495 */ 1496 function set_item_limit($limit = 0) 1497 { 1498 $this->item_limit = (int) $limit; 1499 } 1500 1501 function init() 1502 { 1503 // Check absolute bare minimum requirements. 1504 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre')) 1505 { 1506 return false; 1507 } 1508 // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader. 1509 elseif (!extension_loaded('xmlreader')) 1510 { 1511 static $xml_is_sane = null; 1512 if ($xml_is_sane === null) 1513 { 1514 $parser_check = xml_parser_create(); 1515 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values); 1516 xml_parser_free($parser_check); 1517 $xml_is_sane = isset($values[0]['value']); 1518 } 1519 if (!$xml_is_sane) 1520 { 1521 return false; 1522 } 1523 } 1524 1525 if (isset($_GET[$this->javascript])) 1526 { 1527 SimplePie_Misc::output_javascript(); 1528 exit; 1529 } 1530 1531 // Pass whatever was set with config options over to the sanitizer. 1532 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class); 1533 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen); 1534 1535 if ($this->feed_url !== null || $this->raw_data !== null) 1536 { 1537 $this->data = array(); 1538 $this->multifeed_objects = array(); 1539 $cache = false; 1540 1541 if ($this->feed_url !== null) 1542 { 1543 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url); 1544 // Decide whether to enable caching 1545 if ($this->cache && $parsed_feed_url['scheme'] !== '') 1546 { 1547 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'); 1548 } 1549 // If it's enabled and we don't want an XML dump, use the cache 1550 if ($cache && !$this->xml_dump) 1551 { 1552 // Load the Cache 1553 $this->data = $cache->load(); 1554 if (!empty($this->data)) 1555 { 1556 // If the cache is for an outdated build of SimplePie 1557 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD) 1558 { 1559 $cache->unlink(); 1560 $this->data = array(); 1561 } 1562 // If we've hit a collision just rerun it with caching disabled 1563 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url) 1564 { 1565 $cache = false; 1566 $this->data = array(); 1567 } 1568 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL. 1569 elseif (isset($this->data['feed_url'])) 1570 { 1571 // If the autodiscovery cache is still valid use it. 1572 if ($cache->mtime() + $this->autodiscovery_cache_duration > time()) 1573 { 1574 // Do not need to do feed autodiscovery yet. 1575 if ($this->data['feed_url'] === $this->data['url']) 1576 { 1577 $cache->unlink(); 1578 $this->data = array(); 1579 } 1580 else 1581 { 1582 $this->set_feed_url($this->data['feed_url']); 1583 return $this->init(); 1584 } 1585 } 1586 } 1587 // Check if the cache has been updated 1588 elseif ($cache->mtime() + $this->cache_duration < time()) 1589 { 1590 // If we have last-modified and/or etag set 1591 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) 1592 { 1593 $headers = array(); 1594 if (isset($this->data['headers']['last-modified'])) 1595 { 1596 $headers['if-modified-since'] = $this->data['headers']['last-modified']; 1597 } 1598 if (isset($this->data['headers']['etag'])) 1599 { 1600 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"'; 1601 } 1602 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen); 1603 if ($file->success) 1604 { 1605 if ($file->status_code === 304) 1606 { 1607 $cache->touch(); 1608 return true; 1609 } 1610 else 1611 { 1612 $headers = $file->headers; 1613 } 1614 } 1615 else 1616 { 1617 unset($file); 1618 } 1619 } 1620 } 1621 // If the cache is still valid, just return true 1622 else 1623 { 1624 return true; 1625 } 1626 } 1627 // If the cache is empty, delete it 1628 else 1629 { 1630 $cache->unlink(); 1631 $this->data = array(); 1632 } 1633 } 1634 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it. 1635 if (!isset($file)) 1636 { 1637 if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url) 1638 { 1639 $file =& $this->file; 1640 } 1641 else 1642 { 1643 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen); 1644 } 1645 } 1646 // If the file connection has an error, set SimplePie::error to that and quit 1647 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) 1648 { 1649 $this->error = $file->error; 1650 if (!empty($this->data)) 1651 { 1652 return true; 1653 } 1654 else 1655 { 1656 return false; 1657 } 1658 } 1659 1660 if (!$this->force_feed) 1661 { 1662 // Check if the supplied URL is a feed, if it isn't, look for it. 1663 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class); 1664 if (!$locate->is_feed($file)) 1665 { 1666 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched 1667 unset($file); 1668 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)) 1669 { 1670 if ($cache) 1671 { 1672 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD); 1673 if (!$cache->save($this)) 1674 { 1675 trigger_error("$this->cache_location is not writeable", E_USER_WARNING); 1676 } 1677 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'); 1678 } 1679 $this->feed_url = $file->url; 1680 } 1681 else 1682 { 1683 $this->error = "A feed could not be found at $this->feed_url"; 1684 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1685 return false; 1686 } 1687 } 1688 $locate = null; 1689 } 1690 1691 $headers = $file->headers; 1692 $data = $file->body; 1693 $sniffer =& new $this->content_type_sniffer_class($file); 1694 $sniffed = $sniffer->get_type(); 1695 } 1696 else 1697 { 1698 $data = $this->raw_data; 1699 } 1700 1701 // Set up array of possible encodings 1702 $encodings = array(); 1703 1704 // First check to see if input has been overridden. 1705 if ($this->input_encoding !== false) 1706 { 1707 $encodings[] = $this->input_encoding; 1708 } 1709 1710 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); 1711 $text_types = array('text/xml', 'text/xml-external-parsed-entity'); 1712 1713 // RFC 3023 (only applies to sniffed content) 1714 if (isset($sniffed)) 1715 { 1716 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml') 1717 { 1718 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1719 { 1720 $encodings[] = strtoupper($charset[1]); 1721 } 1722 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); 1723 $encodings[] = 'UTF-8'; 1724 } 1725 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') 1726 { 1727 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1728 { 1729 $encodings[] = $charset[1]; 1730 } 1731 $encodings[] = 'US-ASCII'; 1732 } 1733 // Text MIME-type default 1734 elseif (substr($sniffed, 0, 5) === 'text/') 1735 { 1736 $encodings[] = 'US-ASCII'; 1737 } 1738 } 1739 1740 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1 1741 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); 1742 $encodings[] = 'UTF-8'; 1743 $encodings[] = 'ISO-8859-1'; 1744 1745 // There's no point in trying an encoding twice 1746 $encodings = array_unique($encodings); 1747 1748 // If we want the XML, just output that with the most likely encoding and quit 1749 if ($this->xml_dump) 1750 { 1751 header('Content-type: text/xml; charset=' . $encodings[0]); 1752 echo $data; 1753 exit; 1754 } 1755 1756 // Loop through each possible encoding, till we return something, or run out of possibilities 1757 foreach ($encodings as $encoding) 1758 { 1759 // Change the encoding to UTF-8 (as we always use UTF-8 internally) 1760 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8')) 1761 { 1762 // Create new parser 1763 $parser =& new $this->parser_class(); 1764 1765 // If it's parsed fine 1766 if ($parser->parse($utf8_data, 'UTF-8')) 1767 { 1768 $this->data = $parser->get_data(); 1769 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE) 1770 { 1771 if (isset($headers)) 1772 { 1773 $this->data['headers'] = $headers; 1774 } 1775 $this->data['build'] = SIMPLEPIE_BUILD; 1776 1777 // Cache the file if caching is enabled 1778 if ($cache && !$cache->save($this)) 1779 { 1780 trigger_error("$cache->name is not writeable", E_USER_WARNING); 1781 } 1782 return true; 1783 } 1784 else 1785 { 1786 $this->error = "A feed could not be found at $this->feed_url"; 1787 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1788 return false; 1789 } 1790 } 1791 } 1792 } 1793 if(isset($parser)) 1794 { 1795 // We have an error, just set SimplePie_Misc::error to it and quit 1796 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column()); 1797 } 1798 else 1799 { 1800 $this->error = 'The data could not be converted to UTF-8'; 1801 } 1802 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1803 return false; 1804 } 1805 elseif (!empty($this->multifeed_url)) 1806 { 1807 $i = 0; 1808 $success = 0; 1809 $this->multifeed_objects = array(); 1810 foreach ($this->multifeed_url as $url) 1811 { 1812 if (SIMPLEPIE_PHP5) 1813 { 1814 // This keyword needs to defy coding standards for PHP4 compatibility 1815 $this->multifeed_objects[$i] = clone($this); 1816 } 1817 else 1818 { 1819 $this->multifeed_objects[$i] = $this; 1820 } 1821 $this->multifeed_objects[$i]->set_feed_url($url); 1822 $success |= $this->multifeed_objects[$i]->init(); 1823 $i++; 1824 } 1825 return (bool) $success; 1826 } 1827 else 1828 { 1829 return false; 1830 } 1831 } 1832 1833 /** 1834 * Return the error message for the occured error 1835 * 1836 * @access public 1837 * @return string Error message 1838 */ 1839 function error() 1840 { 1841 return $this->error; 1842 } 1843 1844 function get_encoding() 1845 { 1846 return $this->sanitize->output_encoding; 1847 } 1848 1849 function handle_content_type($mime = 'text/html') 1850 { 1851 if (!headers_sent()) 1852 { 1853 $header = "Content-type: $mime;"; 1854 if ($this->get_encoding()) 1855 { 1856 $header .= ' charset=' . $this->get_encoding(); 1857 } 1858 else 1859 { 1860 $header .= ' charset=UTF-8'; 1861 } 1862 header($header); 1863 } 1864 } 1865 1866 function get_type() 1867 { 1868 if (!isset($this->data['type'])) 1869 { 1870 $this->data['type'] = SIMPLEPIE_TYPE_ALL; 1871 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'])) 1872 { 1873 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10; 1874 } 1875 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'])) 1876 { 1877 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03; 1878 } 1879 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'])) 1880 { 1881 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel']) 1882 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image']) 1883 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']) 1884 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput'])) 1885 { 1886 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10; 1887 } 1888 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel']) 1889 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image']) 1890 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']) 1891 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput'])) 1892 { 1893 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090; 1894 } 1895 } 1896 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'])) 1897 { 1898 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL; 1899 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) 1900 { 1901 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) 1902 { 1903 case '0.91': 1904 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091; 1905 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) 1906 { 1907 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) 1908 { 1909 case '0': 1910 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE; 1911 break; 1912 1913 case '24': 1914 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND; 1915 break; 1916 } 1917 } 1918 break; 1919 1920 case '0.92': 1921 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092; 1922 break; 1923 1924 case '0.93': 1925 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093; 1926 break; 1927 1928 case '0.94': 1929 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094; 1930 break; 1931 1932 case '2.0': 1933 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20; 1934 break; 1935 } 1936 } 1937 } 1938 else 1939 { 1940 $this->data['type'] = SIMPLEPIE_TYPE_NONE; 1941 } 1942 } 1943 return $this->data['type']; 1944 } 1945 1946 /** 1947 * Returns the URL for the favicon of the feed's website. 1948 * 1949 * @todo Cache atom:icon 1950 * @access public 1951 * @since 1.0 1952 */ 1953 function get_favicon() 1954 { 1955 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) 1956 { 1957 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 1958 } 1959 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url)) 1960 { 1961 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url); 1962 1963 if ($this->cache && $this->favicon_handler) 1964 { 1965 $favicon_filename = call_user_func($this->cache_name_function, $favicon); 1966 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi'); 1967 1968 if ($cache->load()) 1969 { 1970 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); 1971 } 1972 else 1973 { 1974 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); 1975 1976 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0) 1977 { 1978 $sniffer =& new $this->content_type_sniffer_class($file); 1979 if (substr($sniffer->get_type(), 0, 6) === 'image/') 1980 { 1981 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) 1982 { 1983 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); 1984 } 1985 else 1986 { 1987 trigger_error("$cache->name is not writeable", E_USER_WARNING); 1988 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); 1989 } 1990 } 1991 // not an image 1992 else 1993 { 1994 return false; 1995 } 1996 } 1997 } 1998 } 1999 else 2000 { 2001 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); 2002 } 2003 } 2004 return false; 2005 } 2006 2007 /** 2008 * @todo If we have a perm redirect we should return the new URL 2009 * @todo When we make the above change, let's support <itunes:new-feed-url> as well 2010 * @todo Also, |atom:link|@rel=self 2011 */ 2012 function subscribe_url() 2013 { 2014 if ($this->feed_url !== null) 2015 { 2016 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI); 2017 } 2018 else 2019 { 2020 return null; 2021 } 2022 } 2023 2024 function subscribe_feed() 2025 { 2026 if ($this->feed_url !== null) 2027 { 2028 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); 2029 } 2030 else 2031 { 2032 return null; 2033 } 2034 } 2035 2036 function subscribe_outlook() 2037 { 2038 if ($this->feed_url !== null) 2039 { 2040 return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); 2041 } 2042 else 2043 { 2044 return null; 2045 } 2046 } 2047 2048 function subscribe_podcast() 2049 { 2050 if ($this->feed_url !== null) 2051 { 2052 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI); 2053 } 2054 else 2055 { 2056 return null; 2057 } 2058 } 2059 2060 function subscribe_itunes() 2061 { 2062 if ($this->feed_url !== null) 2063 { 2064 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI); 2065 } 2066 else 2067 { 2068 return null; 2069 } 2070 } 2071 2072 /** 2073 * Creates the subscribe_* methods' return data 2074 * 2075 * @access private 2076 * @param string $feed_url String to prefix to the feed URL 2077 * @param string $site_url String to prefix to the site URL (and 2078 * suffix to the feed URL) 2079 * @return mixed URL if feed exists, false otherwise 2080 */ 2081 function subscribe_service($feed_url, $site_url = null) 2082 { 2083 if ($this->subscribe_url()) 2084 { 2085 $return = $feed_url . rawurlencode($this->feed_url); 2086 if ($site_url !== null && $this->get_link() !== null) 2087 { 2088 $return .= $site_url . rawurlencode($this->get_link()); 2089 } 2090 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI); 2091 } 2092 else 2093 { 2094 return null; 2095 } 2096 } 2097 2098 function subscribe_aol() 2099 { 2100 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url='); 2101 } 2102 2103 function subscribe_bloglines() 2104 { 2105 return $this->subscribe_service('http://www.bloglines.com/sub/'); 2106 } 2107 2108 function subscribe_eskobo() 2109 { 2110 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage='); 2111 } 2112 2113 function subscribe_feedfeeds() 2114 { 2115 return $this->subscribe_service('http://www.feedfeeds.com/add?feed='); 2116 } 2117 2118 function subscribe_feedster() 2119 { 2120 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl='); 2121 } 2122 2123 function subscribe_google() 2124 { 2125 return $this->subscribe_service('http://fusion.google.com/add?feedurl='); 2126 } 2127 2128 function subscribe_gritwire() 2129 { 2130 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl='); 2131 } 2132 2133 function subscribe_msn() 2134 { 2135 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru='); 2136 } 2137 2138 function subscribe_netvibes() 2139 { 2140 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url='); 2141 } 2142 2143 function subscribe_newsburst() 2144 { 2145 return $this->subscribe_service('http://www.newsburst.com/Source/?add='); 2146 } 2147 2148 function subscribe_newsgator() 2149 { 2150 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url='); 2151 } 2152 2153 function subscribe_odeo() 2154 { 2155 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed='); 2156 } 2157 2158 function subscribe_podnova() 2159 { 2160 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url='); 2161 } 2162 2163 function subscribe_rojo() 2164 { 2165 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource='); 2166 } 2167 2168 function subscribe_yahoo() 2169 { 2170 return $this->subscribe_service('http://add.my.yahoo.com/rss?url='); 2171 } 2172 2173 function get_feed_tags($namespace, $tag) 2174 { 2175 $type = $this->get_type(); 2176 if ($type & SIMPLEPIE_TYPE_ATOM_10) 2177 { 2178 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag])) 2179 { 2180 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]; 2181 } 2182 } 2183 if ($type & SIMPLEPIE_TYPE_ATOM_03) 2184 { 2185 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag])) 2186 { 2187 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]; 2188 } 2189 } 2190 if ($type & SIMPLEPIE_TYPE_RSS_RDF) 2191 { 2192 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag])) 2193 { 2194 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]; 2195 } 2196 } 2197 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) 2198 { 2199 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag])) 2200 { 2201 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]; 2202 } 2203 } 2204 return null; 2205 } 2206 2207 function get_channel_tags($namespace, $tag) 2208 { 2209 $type = $this->get_type(); 2210 if ($type & SIMPLEPIE_TYPE_ATOM_ALL) 2211 { 2212 if ($return = $this->get_feed_tags($namespace, $tag)) 2213 { 2214 return $return; 2215 } 2216 } 2217 if ($type & SIMPLEPIE_TYPE_RSS_10) 2218 { 2219 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel')) 2220 { 2221 if (isset($channel[0]['child'][$namespace][$tag])) 2222 { 2223 return $channel[0]['child'][$namespace][$tag]; 2224 } 2225 } 2226 } 2227 if ($type & SIMPLEPIE_TYPE_RSS_090) 2228 { 2229 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel')) 2230 { 2231 if (isset($channel[0]['child'][$namespace][$tag])) 2232 { 2233 return $channel[0]['child'][$namespace][$tag]; 2234 } 2235 } 2236 } 2237 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) 2238 { 2239 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel')) 2240 { 2241 if (isset($channel[0]['child'][$namespace][$tag])) 2242 { 2243 return $channel[0]['child'][$namespace][$tag]; 2244 } 2245 } 2246 } 2247 return null; 2248 } 2249 2250 function get_image_tags($namespace, $tag) 2251 { 2252 $type = $this->get_type(); 2253 if ($type & SIMPLEPIE_TYPE_RSS_10) 2254 { 2255 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image')) 2256 { 2257 if (isset($image[0]['child'][$namespace][$tag])) 2258 { 2259 return $image[0]['child'][$namespace][$tag]; 2260 } 2261 } 2262 } 2263 if ($type & SIMPLEPIE_TYPE_RSS_090) 2264 { 2265 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image')) 2266 { 2267 if (isset($image[0]['child'][$namespace][$tag])) 2268 { 2269 return $image[0]['child'][$namespace][$tag]; 2270 } 2271 } 2272 } 2273 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) 2274 { 2275 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image')) 2276 { 2277 if (isset($image[0]['child'][$namespace][$tag])) 2278 { 2279 return $image[0]['child'][$namespace][$tag]; 2280 } 2281 } 2282 } 2283 return null; 2284 } 2285 2286 function get_base($element = array()) 2287 { 2288 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base'])) 2289 { 2290 return $element['xml_base']; 2291 } 2292 elseif ($this->get_link() !== null) 2293 { 2294 return $this->get_link(); 2295 } 2296 else 2297 { 2298 return $this->subscribe_url(); 2299 } 2300 } 2301 2302 function sanitize($data, $type, $base = '') 2303 { 2304 return $this->sanitize->sanitize($data, $type, $base); 2305 } 2306 2307 function get_title() 2308 { 2309 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) 2310 { 2311 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2312 } 2313 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) 2314 { 2315 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2316 } 2317 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 2318 { 2319 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2320 } 2321 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 2322 { 2323 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2324 } 2325 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 2326 { 2327 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2328 } 2329 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 2330 { 2331 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2332 } 2333 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 2334 { 2335 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2336 } 2337 else 2338 { 2339 return null; 2340 } 2341 } 2342 2343 function get_category($key = 0) 2344 { 2345 $categories = $this->get_categories(); 2346 if (isset($categories[$key])) 2347 { 2348 return $categories[$key]; 2349 } 2350 else 2351 { 2352 return null; 2353 } 2354 } 2355 2356 function get_categories() 2357 { 2358 $categories = array(); 2359 2360 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) 2361 { 2362 $term = null; 2363 $scheme = null; 2364 $label = null; 2365 if (isset($category['attribs']['']['term'])) 2366 { 2367 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); 2368 } 2369 if (isset($category['attribs']['']['scheme'])) 2370 { 2371 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 2372 } 2373 if (isset($category['attribs']['']['label'])) 2374 { 2375 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 2376 } 2377 $categories[] =& new $this->category_class($term, $scheme, $label); 2378 } 2379 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) 2380 { 2381 // This is really the label, but keep this as the term also for BC. 2382 // Label will also work on retrieving because that falls back to term. 2383 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2384 if (isset($category['attribs']['']['domain'])) 2385 { 2386 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); 2387 } 2388 else 2389 { 2390 $scheme = null; 2391 } 2392 $categories[] =& new $this->category_class($term, $scheme, null); 2393 } 2394 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) 2395 { 2396 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2397 } 2398 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) 2399 { 2400 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2401 } 2402 2403 if (!empty($categories)) 2404 { 2405 return SimplePie_Misc::array_unique($categories); 2406 } 2407 else 2408 { 2409 return null; 2410 } 2411 } 2412 2413 function get_author($key = 0) 2414 { 2415 $authors = $this->get_authors(); 2416 if (isset($authors[$key])) 2417 { 2418 return $authors[$key]; 2419 } 2420 else 2421 { 2422 return null; 2423 } 2424 } 2425 2426 function get_authors() 2427 { 2428 $authors = array(); 2429 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) 2430 { 2431 $name = null; 2432 $uri = null; 2433 $email = null; 2434 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 2435 { 2436 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2437 } 2438 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 2439 { 2440 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); 2441 } 2442 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 2443 { 2444 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2445 } 2446 if ($name !== null || $email !== null || $uri !== null) 2447 { 2448 $authors[] =& new $this->author_class($name, $uri, $email); 2449 } 2450 } 2451 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) 2452 { 2453 $name = null; 2454 $url = null; 2455 $email = null; 2456 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 2457 { 2458 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2459 } 2460 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 2461 { 2462 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); 2463 } 2464 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 2465 { 2466 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2467 } 2468 if ($name !== null || $email !== null || $url !== null) 2469 { 2470 $authors[] =& new $this->author_class($name, $url, $email); 2471 } 2472 } 2473 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) 2474 { 2475 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2476 } 2477 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) 2478 { 2479 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2480 } 2481 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) 2482 { 2483 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2484 } 2485 2486 if (!empty($authors)) 2487 { 2488 return SimplePie_Misc::array_unique($authors); 2489 } 2490 else 2491 { 2492 return null; 2493 } 2494 } 2495 2496 function get_contributor($key = 0) 2497 { 2498 $contributors = $this->get_contributors(); 2499 if (isset($contributors[$key])) 2500 { 2501 return $contributors[$key]; 2502 } 2503 else 2504 { 2505 return null; 2506 } 2507 } 2508 2509 function get_contributors() 2510 { 2511 $contributors = array(); 2512 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) 2513 { 2514 $name = null; 2515 $uri = null; 2516 $email = null; 2517 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 2518 { 2519 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2520 } 2521 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 2522 { 2523 $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])); 2524 } 2525 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 2526 { 2527 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2528 } 2529 if ($name !== null || $email !== null || $uri !== null) 2530 { 2531 $contributors[] =& new $this->author_class($name, $uri, $email); 2532 } 2533 } 2534 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) 2535 { 2536 $name = null; 2537 $url = null; 2538 $email = null; 2539 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 2540 { 2541 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2542 } 2543 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 2544 { 2545 $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])); 2546 } 2547 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 2548 { 2549 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2550 } 2551 if ($name !== null || $email !== null || $url !== null) 2552 { 2553 $contributors[] =& new $this->author_class($name, $url, $email); 2554 } 2555 } 2556 2557 if (!empty($contributors)) 2558 { 2559 return SimplePie_Misc::array_unique($contributors); 2560 } 2561 else 2562 { 2563 return null; 2564 } 2565 } 2566 2567 function get_link($key = 0, $rel = 'alternate') 2568 { 2569 $links = $this->get_links($rel); 2570 if (isset($links[$key])) 2571 { 2572 return $links[$key]; 2573 } 2574 else 2575 { 2576 return null; 2577 } 2578 } 2579 2580 /** 2581 * Added for parity between the parent-level and the item/entry-level. 2582 */ 2583 function get_permalink() 2584 { 2585 return $this->get_link(0); 2586 } 2587 2588 function get_links($rel = 'alternate') 2589 { 2590 if (!isset($this->data['links'])) 2591 { 2592 $this->data['links'] = array(); 2593 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) 2594 { 2595 foreach ($links as $link) 2596 { 2597 if (isset($link['attribs']['']['href'])) 2598 { 2599 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 2600 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 2601 } 2602 } 2603 } 2604 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) 2605 { 2606 foreach ($links as $link) 2607 { 2608 if (isset($link['attribs']['']['href'])) 2609 { 2610 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 2611 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 2612 2613 } 2614 } 2615 } 2616 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 2617 { 2618 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 2619 } 2620 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 2621 { 2622 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 2623 } 2624 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 2625 { 2626 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 2627 } 2628 2629 $keys = array_keys($this->data['links']); 2630 foreach ($keys as $key) 2631 { 2632 if (SimplePie_Misc::is_isegment_nz_nc($key)) 2633 { 2634 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) 2635 { 2636 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); 2637 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; 2638 } 2639 else 2640 { 2641 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; 2642 } 2643 } 2644 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) 2645 { 2646 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; 2647 } 2648 $this->data['links'][$key] = array_unique($this->data['links'][$key]); 2649 } 2650 } 2651 2652 if (isset($this->data['links'][$rel])) 2653 { 2654 return $this->data['links'][$rel]; 2655 } 2656 else 2657 { 2658 return null; 2659 } 2660 } 2661 2662 function get_all_discovered_feeds() 2663 { 2664 return $this->all_discovered_feeds; 2665 } 2666 2667 function get_description() 2668 { 2669 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) 2670 { 2671 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2672 } 2673 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) 2674 { 2675 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2676 } 2677 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) 2678 { 2679 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2680 } 2681 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) 2682 { 2683 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2684 } 2685 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) 2686 { 2687 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 2688 } 2689 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) 2690 { 2691 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2692 } 2693 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) 2694 { 2695 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2696 } 2697 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) 2698 { 2699 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 2700 } 2701 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) 2702 { 2703 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 2704 } 2705 else 2706 { 2707 return null; 2708 } 2709 } 2710 2711 function get_copyright() 2712 { 2713 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) 2714 { 2715 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2716 } 2717 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) 2718 { 2719 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2720 } 2721 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright')) 2722 { 2723 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2724 } 2725 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) 2726 { 2727 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2728 } 2729 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) 2730 { 2731 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2732 } 2733 else 2734 { 2735 return null; 2736 } 2737 } 2738 2739 function get_language() 2740 { 2741 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language')) 2742 { 2743 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2744 } 2745 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) 2746 { 2747 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2748 } 2749 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) 2750 { 2751 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2752 } 2753 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'])) 2754 { 2755 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 2756 } 2757 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'])) 2758 { 2759 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 2760 } 2761 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'])) 2762 { 2763 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 2764 } 2765 elseif (isset($this->data['headers']['content-language'])) 2766 { 2767 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT); 2768 } 2769 else 2770 { 2771 return null; 2772 } 2773 } 2774 2775 function get_latitude() 2776 { 2777 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) 2778 { 2779 return (float) $return[0]['data']; 2780 } 2781 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) 2782 { 2783 return (float) $match[1]; 2784 } 2785 else 2786 { 2787 return null; 2788 } 2789 } 2790 2791 function get_longitude() 2792 { 2793 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) 2794 { 2795 return (float) $return[0]['data']; 2796 } 2797 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) 2798 { 2799 return (float) $return[0]['data']; 2800 } 2801 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) 2802 { 2803 return (float) $match[2]; 2804 } 2805 else 2806 { 2807 return null; 2808 } 2809 } 2810 2811 function get_image_title() 2812 { 2813 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 2814 { 2815 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2816 } 2817 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 2818 { 2819 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2820 } 2821 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 2822 { 2823 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2824 } 2825 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 2826 { 2827 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2828 } 2829 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 2830 { 2831 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2832 } 2833 else 2834 { 2835 return null; 2836 } 2837 } 2838 2839 function get_image_url() 2840 { 2841 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) 2842 { 2843 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); 2844 } 2845 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) 2846 { 2847 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2848 } 2849 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) 2850 { 2851 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2852 } 2853 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url')) 2854 { 2855 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2856 } 2857 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url')) 2858 { 2859 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2860 } 2861 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) 2862 { 2863 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2864 } 2865 else 2866 { 2867 return null; 2868 } 2869 } 2870 2871 function get_image_link() 2872 { 2873 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 2874 { 2875 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2876 } 2877 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 2878 { 2879 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2880 } 2881 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 2882 { 2883 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2884 } 2885 else 2886 { 2887 return null; 2888 } 2889 } 2890 2891 function get_image_width() 2892 { 2893 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width')) 2894 { 2895 return round($return[0]['data']); 2896 } 2897 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) 2898 { 2899 return 88.0; 2900 } 2901 else 2902 { 2903 return null; 2904 } 2905 } 2906 2907 function get_image_height() 2908 { 2909 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height')) 2910 { 2911 return round($return[0]['data']); 2912 } 2913 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) 2914 { 2915 return 31.0; 2916 } 2917 else 2918 { 2919 return null; 2920 } 2921 } 2922 2923 function get_item_quantity($max = 0) 2924 { 2925 $max = (int) $max; 2926 $qty = count($this->get_items()); 2927 if ($max === 0) 2928 { 2929 return $qty; 2930 } 2931 else 2932 { 2933 return ($qty > $max) ? $max : $qty; 2934 } 2935 } 2936 2937 function get_item($key = 0) 2938 { 2939 $items = $this->get_items(); 2940 if (isset($items[$key])) 2941 { 2942 return $items[$key]; 2943 } 2944 else 2945 { 2946 return null; 2947 } 2948 } 2949 2950 function get_items($start = 0, $end = 0) 2951 { 2952 if (!isset($this->data['items'])) 2953 { 2954 if (!empty($this->multifeed_objects)) 2955 { 2956 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit); 2957 } 2958 else 2959 { 2960 $this->data['items'] = array(); 2961 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry')) 2962 { 2963 $keys = array_keys($items); 2964 foreach ($keys as $key) 2965 { 2966 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 2967 } 2968 } 2969 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry')) 2970 { 2971 $keys = array_keys($items); 2972 foreach ($keys as $key) 2973 { 2974 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 2975 } 2976 } 2977 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item')) 2978 { 2979 $keys = array_keys($items); 2980 foreach ($keys as $key) 2981 { 2982 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 2983 } 2984 } 2985 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item')) 2986 { 2987 $keys = array_keys($items); 2988 foreach ($keys as $key) 2989 { 2990 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 2991 } 2992 } 2993 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item')) 2994 { 2995 $keys = array_keys($items); 2996 foreach ($keys as $key) 2997 { 2998 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 2999 } 3000 } 3001 } 3002 } 3003 3004 if (!empty($this->data['items'])) 3005 { 3006 // If we want to order it by date, check if all items have a date, and then sort it 3007 if ($this->order_by_date && empty($this->multifeed_objects)) 3008 { 3009 if (!isset($this->data['ordered_items'])) 3010 { 3011 $do_sort = true; 3012 foreach ($this->data['items'] as $item) 3013 { 3014 if (!$item->get_date('U')) 3015 { 3016 $do_sort = false; 3017 break; 3018 } 3019 } 3020 $item = null; 3021 $this->data['ordered_items'] = $this->data['items']; 3022 if ($do_sort) 3023 { 3024 usort($this->data['ordered_items'], array(&$this, 'sort_items')); 3025 } 3026 } 3027 $items = $this->data['ordered_items']; 3028 } 3029 else 3030 { 3031 $items = $this->data['items']; 3032 } 3033 3034 // Slice the data as desired 3035 if ($end === 0) 3036 { 3037 return array_slice($items, $start); 3038 } 3039 else 3040 { 3041 return array_slice($items, $start, $end); 3042 } 3043 } 3044 else 3045 { 3046 return array(); 3047 } 3048 } 3049 3050 /** 3051 * @static 3052 */ 3053 function sort_items($a, $b) 3054 { 3055 return $a->get_date('U') <= $b->get_date('U'); 3056 } 3057 3058 /** 3059 * @static 3060 */ 3061 function merge_items($urls, $start = 0, $end = 0, $limit = 0) 3062 { 3063 if (is_array($urls) && sizeof($urls) > 0) 3064 { 3065 $items = array(); 3066 foreach ($urls as $arg) 3067 { 3068 if (is_a($arg, 'SimplePie')) 3069 { 3070 $items = array_merge($items, $arg->get_items(0, $limit)); 3071 } 3072 else 3073 { 3074 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING); 3075 } 3076 } 3077 3078 $do_sort = true; 3079 foreach ($items as $item) 3080 { 3081 if (!$item->get_date('U')) 3082 { 3083 $do_sort = false; 3084 break; 3085 } 3086 } 3087 $item = null; 3088 if ($do_sort) 3089 { 3090 usort($items, array('SimplePie', 'sort_items')); 3091 } 3092 3093 if ($end === 0) 3094 { 3095 return array_slice($items, $start); 3096 } 3097 else 3098 { 3099 return array_slice($items, $start, $end); 3100 } 3101 } 3102 else 3103 { 3104 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING); 3105 return array(); 3106 } 3107 } 3108} 3109 3110class SimplePie_Item 3111{ 3112 var $feed; 3113 var $data = array(); 3114 3115 function SimplePie_Item($feed, $data) 3116 { 3117 $this->feed = $feed; 3118 $this->data = $data; 3119 } 3120 3121 function __toString() 3122 { 3123 return md5(serialize($this->data)); 3124 } 3125 3126 /** 3127 * Remove items that link back to this before destroying this object 3128 */ 3129 function __destruct() 3130 { 3131 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode')) 3132 { 3133 unset($this->feed); 3134 } 3135 } 3136 3137 function get_item_tags($namespace, $tag) 3138 { 3139 if (isset($this->data['child'][$namespace][$tag])) 3140 { 3141 return $this->data['child'][$namespace][$tag]; 3142 } 3143 else 3144 { 3145 return null; 3146 } 3147 } 3148 3149 function get_base($element = array()) 3150 { 3151 return $this->feed->get_base($element); 3152 } 3153 3154 function sanitize($data, $type, $base = '') 3155 { 3156 return $this->feed->sanitize($data, $type, $base); 3157 } 3158 3159 function get_feed() 3160 { 3161 return $this->feed; 3162 } 3163 3164 function get_id($hash = false) 3165 { 3166 if (!$hash) 3167 { 3168 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id')) 3169 { 3170 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3171 } 3172 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id')) 3173 { 3174 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3175 } 3176 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid')) 3177 { 3178 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3179 } 3180 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier')) 3181 { 3182 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3183 } 3184 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier')) 3185 { 3186 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3187 } 3188 elseif (($return = $this->get_permalink()) !== null) 3189 { 3190 return $return; 3191 } 3192 elseif (($return = $this->get_title()) !== null) 3193 { 3194 return $return; 3195 } 3196 } 3197 if ($this->get_permalink() !== null || $this->get_title() !== null) 3198 { 3199 return md5($this->get_permalink() . $this->get_title()); 3200 } 3201 else 3202 { 3203 return md5(serialize($this->data)); 3204 } 3205 } 3206 3207 function get_title() 3208 { 3209 if (!isset($this->data['title'])) 3210 { 3211 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) 3212 { 3213 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3214 } 3215 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) 3216 { 3217 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3218 } 3219 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 3220 { 3221 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3222 } 3223 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 3224 { 3225 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3226 } 3227 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 3228 { 3229 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3230 } 3231 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 3232 { 3233 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3234 } 3235 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 3236 { 3237 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3238 } 3239 else 3240 { 3241 $this->data['title'] = null; 3242 } 3243 } 3244 return $this->data['title']; 3245 } 3246 3247 function get_description($description_only = false) 3248 { 3249 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary')) 3250 { 3251 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3252 } 3253 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary')) 3254 { 3255 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3256 } 3257 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) 3258 { 3259 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3260 } 3261 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) 3262 { 3263 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 3264 } 3265 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) 3266 { 3267 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3268 } 3269 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) 3270 { 3271 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3272 } 3273 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) 3274 { 3275 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 3276 } 3277 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) 3278 { 3279 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3280 } 3281 elseif (!$description_only) 3282 { 3283 return $this->get_content(true); 3284 } 3285 else 3286 { 3287 return null; 3288 } 3289 } 3290 3291 function get_content($content_only = false) 3292 { 3293 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content')) 3294 { 3295 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3296 } 3297 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content')) 3298 { 3299 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3300 } 3301 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded')) 3302 { 3303 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 3304 } 3305 elseif (!$content_only) 3306 { 3307 return $this->get_description(true); 3308 } 3309 else 3310 { 3311 return null; 3312 } 3313 } 3314 3315 function get_category($key = 0) 3316 { 3317 $categories = $this->get_categories(); 3318 if (isset($categories[$key])) 3319 { 3320 return $categories[$key]; 3321 } 3322 else 3323 { 3324 return null; 3325 } 3326 } 3327 3328 function get_categories() 3329 { 3330 $categories = array(); 3331 3332 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) 3333 { 3334 $term = null; 3335 $scheme = null; 3336 $label = null; 3337 if (isset($category['attribs']['']['term'])) 3338 { 3339 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); 3340 } 3341 if (isset($category['attribs']['']['scheme'])) 3342 { 3343 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3344 } 3345 if (isset($category['attribs']['']['label'])) 3346 { 3347 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 3348 } 3349 $categories[] =& new $this->feed->category_class($term, $scheme, $label); 3350 } 3351 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) 3352 { 3353 // This is really the label, but keep this as the term also for BC. 3354 // Label will also work on retrieving because that falls back to term. 3355 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3356 if (isset($category['attribs']['']['domain'])) 3357 { 3358 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); 3359 } 3360 else 3361 { 3362 $scheme = null; 3363 } 3364 $categories[] =& new $this->feed->category_class($term, $scheme, null); 3365 } 3366 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) 3367 { 3368 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3369 } 3370 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) 3371 { 3372 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3373 } 3374 3375 if (!empty($categories)) 3376 { 3377 return SimplePie_Misc::array_unique($categories); 3378 } 3379 else 3380 { 3381 return null; 3382 } 3383 } 3384 3385 function get_author($key = 0) 3386 { 3387 $authors = $this->get_authors(); 3388 if (isset($authors[$key])) 3389 { 3390 return $authors[$key]; 3391 } 3392 else 3393 { 3394 return null; 3395 } 3396 } 3397 3398 function get_contributor($key = 0) 3399 { 3400 $contributors = $this->get_contributors(); 3401 if (isset($contributors[$key])) 3402 { 3403 return $contributors[$key]; 3404 } 3405 else 3406 { 3407 return null; 3408 } 3409 } 3410 3411 function get_contributors() 3412 { 3413 $contributors = array(); 3414 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) 3415 { 3416 $name = null; 3417 $uri = null; 3418 $email = null; 3419 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 3420 { 3421 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3422 } 3423 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 3424 { 3425 $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])); 3426 } 3427 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 3428 { 3429 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3430 } 3431 if ($name !== null || $email !== null || $uri !== null) 3432 { 3433 $contributors[] =& new $this->feed->author_class($name, $uri, $email); 3434 } 3435 } 3436 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) 3437 { 3438 $name = null; 3439 $url = null; 3440 $email = null; 3441 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 3442 { 3443 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3444 } 3445 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 3446 { 3447 $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])); 3448 } 3449 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 3450 { 3451 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3452 } 3453 if ($name !== null || $email !== null || $url !== null) 3454 { 3455 $contributors[] =& new $this->feed->author_class($name, $url, $email); 3456 } 3457 } 3458 3459 if (!empty($contributors)) 3460 { 3461 return SimplePie_Misc::array_unique($contributors); 3462 } 3463 else 3464 { 3465 return null; 3466 } 3467 } 3468 3469 function get_authors() 3470 { 3471 $authors = array(); 3472 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) 3473 { 3474 $name = null; 3475 $uri = null; 3476 $email = null; 3477 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 3478 { 3479 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3480 } 3481 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 3482 { 3483 $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])); 3484 } 3485 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 3486 { 3487 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3488 } 3489 if ($name !== null || $email !== null || $uri !== null) 3490 { 3491 $authors[] =& new $this->feed->author_class($name, $uri, $email); 3492 } 3493 } 3494 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) 3495 { 3496 $name = null; 3497 $url = null; 3498 $email = null; 3499 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 3500 { 3501 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3502 } 3503 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 3504 { 3505 $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])); 3506 } 3507 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 3508 { 3509 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3510 } 3511 if ($name !== null || $email !== null || $url !== null) 3512 { 3513 $authors[] =& new $this->feed->author_class($name, $url, $email); 3514 } 3515 } 3516 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author')) 3517 { 3518 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 3519 } 3520 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) 3521 { 3522 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3523 } 3524 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) 3525 { 3526 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3527 } 3528 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) 3529 { 3530 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3531 } 3532 3533 if (!empty($authors)) 3534 { 3535 return SimplePie_Misc::array_unique($authors); 3536 } 3537 elseif (($source = $this->get_source()) && ($authors = $source->get_authors())) 3538 { 3539 return $authors; 3540 } 3541 elseif ($authors = $this->feed->get_authors()) 3542 { 3543 return $authors; 3544 } 3545 else 3546 { 3547 return null; 3548 } 3549 } 3550 3551 function get_copyright() 3552 { 3553 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) 3554 { 3555 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3556 } 3557 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) 3558 { 3559 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3560 } 3561 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) 3562 { 3563 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3564 } 3565 else 3566 { 3567 return null; 3568 } 3569 } 3570 3571 function get_date($date_format = 'j F Y, g:i a') 3572 { 3573 if (!isset($this->data['date'])) 3574 { 3575 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published')) 3576 { 3577 $this->data['date']['raw'] = $return[0]['data']; 3578 } 3579 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated')) 3580 { 3581 $this->data['date']['raw'] = $return[0]['data']; 3582 } 3583 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued')) 3584 { 3585 $this->data['date']['raw'] = $return[0]['data']; 3586 } 3587 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created')) 3588 { 3589 $this->data['date']['raw'] = $return[0]['data']; 3590 } 3591 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified')) 3592 { 3593 $this->data['date']['raw'] = $return[0]['data']; 3594 } 3595 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate')) 3596 { 3597 $this->data['date']['raw'] = $return[0]['data']; 3598 } 3599 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date')) 3600 { 3601 $this->data['date']['raw'] = $return[0]['data']; 3602 } 3603 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date')) 3604 { 3605 $this->data['date']['raw'] = $return[0]['data']; 3606 } 3607 3608 if (!empty($this->data['date']['raw'])) 3609 { 3610 $parser = SimplePie_Parse_Date::get(); 3611 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']); 3612 } 3613 else 3614 { 3615 $this->data['date'] = null; 3616 } 3617 } 3618 if ($this->data['date']) 3619 { 3620 $date_format = (string) $date_format; 3621 switch ($date_format) 3622 { 3623 case '': 3624 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT); 3625 3626 case 'U': 3627 return $this->data['date']['parsed']; 3628 3629 default: 3630 return date($date_format, $this->data['date']['parsed']); 3631 } 3632 } 3633 else 3634 { 3635 return null; 3636 } 3637 } 3638 3639 function get_local_date($date_format = '%c') 3640 { 3641 if (!$date_format) 3642 { 3643 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT); 3644 } 3645 elseif (($date = $this->get_date('U')) !== null) 3646 { 3647 return strftime($date_format, $date); 3648 } 3649 else 3650 { 3651 return null; 3652 } 3653 } 3654 3655 function get_permalink() 3656 { 3657 $link = $this->get_link(); 3658 $enclosure = $this->get_enclosure(0); 3659 if ($link !== null) 3660 { 3661 return $link; 3662 } 3663 elseif ($enclosure !== null) 3664 { 3665 return $enclosure->get_link(); 3666 } 3667 else 3668 { 3669 return null; 3670 } 3671 } 3672 3673 function get_link($key = 0, $rel = 'alternate') 3674 { 3675 $links = $this->get_links($rel); 3676 if ($links[$key] !== null) 3677 { 3678 return $links[$key]; 3679 } 3680 else 3681 { 3682 return null; 3683 } 3684 } 3685 3686 function get_links($rel = 'alternate') 3687 { 3688 if (!isset($this->data['links'])) 3689 { 3690 $this->data['links'] = array(); 3691 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link) 3692 { 3693 if (isset($link['attribs']['']['href'])) 3694 { 3695 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 3696 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 3697 3698 } 3699 } 3700 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link) 3701 { 3702 if (isset($link['attribs']['']['href'])) 3703 { 3704 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 3705 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 3706 } 3707 } 3708 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 3709 { 3710 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3711 } 3712 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 3713 { 3714 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3715 } 3716 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 3717 { 3718 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3719 } 3720 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid')) 3721 { 3722 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true') 3723 { 3724 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3725 } 3726 } 3727 3728 $keys = array_keys($this->data['links']); 3729 foreach ($keys as $key) 3730 { 3731 if (SimplePie_Misc::is_isegment_nz_nc($key)) 3732 { 3733 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) 3734 { 3735 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); 3736 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; 3737 } 3738 else 3739 { 3740 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; 3741 } 3742 } 3743 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) 3744 { 3745 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; 3746 } 3747 $this->data['links'][$key] = array_unique($this->data['links'][$key]); 3748 } 3749 } 3750 if (isset($this->data['links'][$rel])) 3751 { 3752 return $this->data['links'][$rel]; 3753 } 3754 else 3755 { 3756 return null; 3757 } 3758 } 3759 3760 /** 3761 * @todo Add ability to prefer one type of content over another (in a media group). 3762 */ 3763 function get_enclosure($key = 0, $prefer = null) 3764 { 3765 $enclosures = $this->get_enclosures(); 3766 if (isset($enclosures[$key])) 3767 { 3768 return $enclosures[$key]; 3769 } 3770 else 3771 { 3772 return null; 3773 } 3774 } 3775 3776 /** 3777 * Grabs all available enclosures (podcasts, etc.) 3778 * 3779 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS. 3780 * 3781 * 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. 3782 * 3783 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4). 3784 * @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). 3785 */ 3786 function get_enclosures() 3787 { 3788 if (!isset($this->data['enclosures'])) 3789 { 3790 $this->data['enclosures'] = array(); 3791 3792 // Elements 3793 $captions_parent = null; 3794 $categories_parent = null; 3795 $copyrights_parent = null; 3796 $credits_parent = null; 3797 $description_parent = null; 3798 $duration_parent = null; 3799 $hashes_parent = null; 3800 $keywords_parent = null; 3801 $player_parent = null; 3802 $ratings_parent = null; 3803 $restrictions_parent = null; 3804 $thumbnails_parent = null; 3805 $title_parent = null; 3806 3807 // Let's do the channel and item-level ones first, and just re-use them if we need to. 3808 $parent = $this->get_feed(); 3809 3810 // CAPTIONS 3811 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) 3812 { 3813 foreach ($captions as $caption) 3814 { 3815 $caption_type = null; 3816 $caption_lang = null; 3817 $caption_startTime = null; 3818 $caption_endTime = null; 3819 $caption_text = null; 3820 if (isset($caption['attribs']['']['type'])) 3821 { 3822 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 3823 } 3824 if (isset($caption['attribs']['']['lang'])) 3825 { 3826 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 3827 } 3828 if (isset($caption['attribs']['']['start'])) 3829 { 3830 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 3831 } 3832 if (isset($caption['attribs']['']['end'])) 3833 { 3834 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 3835 } 3836 if (isset($caption['data'])) 3837 { 3838 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3839 } 3840 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 3841 } 3842 } 3843 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) 3844 { 3845 foreach ($captions as $caption) 3846 { 3847 $caption_type = null; 3848 $caption_lang = null; 3849 $caption_startTime = null; 3850 $caption_endTime = null; 3851 $caption_text = null; 3852 if (isset($caption['attribs']['']['type'])) 3853 { 3854 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 3855 } 3856 if (isset($caption['attribs']['']['lang'])) 3857 { 3858 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 3859 } 3860 if (isset($caption['attribs']['']['start'])) 3861 { 3862 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 3863 } 3864 if (isset($caption['attribs']['']['end'])) 3865 { 3866 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 3867 } 3868 if (isset($caption['data'])) 3869 { 3870 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3871 } 3872 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 3873 } 3874 } 3875 if (is_array($captions_parent)) 3876 { 3877 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent)); 3878 } 3879 3880 // CATEGORIES 3881 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) 3882 { 3883 $term = null; 3884 $scheme = null; 3885 $label = null; 3886 if (isset($category['data'])) 3887 { 3888 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3889 } 3890 if (isset($category['attribs']['']['scheme'])) 3891 { 3892 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3893 } 3894 else 3895 { 3896 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 3897 } 3898 if (isset($category['attribs']['']['label'])) 3899 { 3900 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 3901 } 3902 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); 3903 } 3904 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) 3905 { 3906 $term = null; 3907 $scheme = null; 3908 $label = null; 3909 if (isset($category['data'])) 3910 { 3911 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3912 } 3913 if (isset($category['attribs']['']['scheme'])) 3914 { 3915 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3916 } 3917 else 3918 { 3919 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 3920 } 3921 if (isset($category['attribs']['']['label'])) 3922 { 3923 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 3924 } 3925 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); 3926 } 3927 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category) 3928 { 3929 $term = null; 3930 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd'; 3931 $label = null; 3932 if (isset($category['attribs']['']['text'])) 3933 { 3934 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); 3935 } 3936 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); 3937 3938 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'])) 3939 { 3940 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory) 3941 { 3942 if (isset($subcategory['attribs']['']['text'])) 3943 { 3944 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); 3945 } 3946 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); 3947 } 3948 } 3949 } 3950 if (is_array($categories_parent)) 3951 { 3952 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent)); 3953 } 3954 3955 // COPYRIGHT 3956 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) 3957 { 3958 $copyright_url = null; 3959 $copyright_label = null; 3960 if (isset($copyright[0]['attribs']['']['url'])) 3961 { 3962 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 3963 } 3964 if (isset($copyright[0]['data'])) 3965 { 3966 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3967 } 3968 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label); 3969 } 3970 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) 3971 { 3972 $copyright_url = null; 3973 $copyright_label = null; 3974 if (isset($copyright[0]['attribs']['']['url'])) 3975 { 3976 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 3977 } 3978 if (isset($copyright[0]['data'])) 3979 { 3980 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3981 } 3982 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label); 3983 } 3984 3985 // CREDITS 3986 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) 3987 { 3988 foreach ($credits as $credit) 3989 { 3990 $credit_role = null; 3991 $credit_scheme = null; 3992 $credit_name = null; 3993 if (isset($credit['attribs']['']['role'])) 3994 { 3995 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 3996 } 3997 if (isset($credit['attribs']['']['scheme'])) 3998 { 3999 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4000 } 4001 else 4002 { 4003 $credit_scheme = 'urn:ebu'; 4004 } 4005 if (isset($credit['data'])) 4006 { 4007 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4008 } 4009 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4010 } 4011 } 4012 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) 4013 { 4014 foreach ($credits as $credit) 4015 { 4016 $credit_role = null; 4017 $credit_scheme = null; 4018 $credit_name = null; 4019 if (isset($credit['attribs']['']['role'])) 4020 { 4021 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 4022 } 4023 if (isset($credit['attribs']['']['scheme'])) 4024 { 4025 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4026 } 4027 else 4028 { 4029 $credit_scheme = 'urn:ebu'; 4030 } 4031 if (isset($credit['data'])) 4032 { 4033 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4034 } 4035 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4036 } 4037 } 4038 if (is_array($credits_parent)) 4039 { 4040 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent)); 4041 } 4042 4043 // DESCRIPTION 4044 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) 4045 { 4046 if (isset($description_parent[0]['data'])) 4047 { 4048 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4049 } 4050 } 4051 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) 4052 { 4053 if (isset($description_parent[0]['data'])) 4054 { 4055 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4056 } 4057 } 4058 4059 // DURATION 4060 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration')) 4061 { 4062 $seconds = null; 4063 $minutes = null; 4064 $hours = null; 4065 if (isset($duration_parent[0]['data'])) 4066 { 4067 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4068 if (sizeof($temp) > 0) 4069 { 4070 $seconds = (int) array_pop($temp); 4071 } 4072 if (sizeof($temp) > 0) 4073 { 4074 $minutes = (int) array_pop($temp); 4075 $seconds += $minutes * 60; 4076 } 4077 if (sizeof($temp) > 0) 4078 { 4079 $hours = (int) array_pop($temp); 4080 $seconds += $hours * 3600; 4081 } 4082 unset($temp); 4083 $duration_parent = $seconds; 4084 } 4085 } 4086 4087 // HASHES 4088 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) 4089 { 4090 foreach ($hashes_iterator as $hash) 4091 { 4092 $value = null; 4093 $algo = null; 4094 if (isset($hash['data'])) 4095 { 4096 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4097 } 4098 if (isset($hash['attribs']['']['algo'])) 4099 { 4100 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4101 } 4102 else 4103 { 4104 $algo = 'md5'; 4105 } 4106 $hashes_parent[] = $algo.':'.$value; 4107 } 4108 } 4109 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) 4110 { 4111 foreach ($hashes_iterator as $hash) 4112 { 4113 $value = null; 4114 $algo = null; 4115 if (isset($hash['data'])) 4116 { 4117 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4118 } 4119 if (isset($hash['attribs']['']['algo'])) 4120 { 4121 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4122 } 4123 else 4124 { 4125 $algo = 'md5'; 4126 } 4127 $hashes_parent[] = $algo.':'.$value; 4128 } 4129 } 4130 if (is_array($hashes_parent)) 4131 { 4132 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent)); 4133 } 4134 4135 // KEYWORDS 4136 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) 4137 { 4138 if (isset($keywords[0]['data'])) 4139 { 4140 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4141 foreach ($temp as $word) 4142 { 4143 $keywords_parent[] = trim($word); 4144 } 4145 } 4146 unset($temp); 4147 } 4148 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) 4149 { 4150 if (isset($keywords[0]['data'])) 4151 { 4152 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4153 foreach ($temp as $word) 4154 { 4155 $keywords_parent[] = trim($word); 4156 } 4157 } 4158 unset($temp); 4159 } 4160 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) 4161 { 4162 if (isset($keywords[0]['data'])) 4163 { 4164 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4165 foreach ($temp as $word) 4166 { 4167 $keywords_parent[] = trim($word); 4168 } 4169 } 4170 unset($temp); 4171 } 4172 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) 4173 { 4174 if (isset($keywords[0]['data'])) 4175 { 4176 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4177 foreach ($temp as $word) 4178 { 4179 $keywords_parent[] = trim($word); 4180 } 4181 } 4182 unset($temp); 4183 } 4184 if (is_array($keywords_parent)) 4185 { 4186 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent)); 4187 } 4188 4189 // PLAYER 4190 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player')) 4191 { 4192 if (isset($player_parent[0]['attribs']['']['url'])) 4193 { 4194 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4195 } 4196 } 4197 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player')) 4198 { 4199 if (isset($player_parent[0]['attribs']['']['url'])) 4200 { 4201 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4202 } 4203 } 4204 4205 // RATINGS 4206 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating')) 4207 { 4208 foreach ($ratings as $rating) 4209 { 4210 $rating_scheme = null; 4211 $rating_value = null; 4212 if (isset($rating['attribs']['']['scheme'])) 4213 { 4214 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4215 } 4216 else 4217 { 4218 $rating_scheme = 'urn:simple'; 4219 } 4220 if (isset($rating['data'])) 4221 { 4222 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4223 } 4224 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4225 } 4226 } 4227 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit')) 4228 { 4229 foreach ($ratings as $rating) 4230 { 4231 $rating_scheme = 'urn:itunes'; 4232 $rating_value = null; 4233 if (isset($rating['data'])) 4234 { 4235 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4236 } 4237 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4238 } 4239 } 4240 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating')) 4241 { 4242 foreach ($ratings as $rating) 4243 { 4244 $rating_scheme = null; 4245 $rating_value = null; 4246 if (isset($rating['attribs']['']['scheme'])) 4247 { 4248 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4249 } 4250 else 4251 { 4252 $rating_scheme = 'urn:simple'; 4253 } 4254 if (isset($rating['data'])) 4255 { 4256 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4257 } 4258 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4259 } 4260 } 4261 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit')) 4262 { 4263 foreach ($ratings as $rating) 4264 { 4265 $rating_scheme = 'urn:itunes'; 4266 $rating_value = null; 4267 if (isset($rating['data'])) 4268 { 4269 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4270 } 4271 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4272 } 4273 } 4274 if (is_array($ratings_parent)) 4275 { 4276 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent)); 4277 } 4278 4279 // RESTRICTIONS 4280 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction')) 4281 { 4282 foreach ($restrictions as $restriction) 4283 { 4284 $restriction_relationship = null; 4285 $restriction_type = null; 4286 $restriction_value = null; 4287 if (isset($restriction['attribs']['']['relationship'])) 4288 { 4289 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 4290 } 4291 if (isset($restriction['attribs']['']['type'])) 4292 { 4293 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4294 } 4295 if (isset($restriction['data'])) 4296 { 4297 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4298 } 4299 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4300 } 4301 } 4302 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block')) 4303 { 4304 foreach ($restrictions as $restriction) 4305 { 4306 $restriction_relationship = 'allow'; 4307 $restriction_type = null; 4308 $restriction_value = 'itunes'; 4309 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes') 4310 { 4311 $restriction_relationship = 'deny'; 4312 } 4313 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4314 } 4315 } 4316 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction')) 4317 { 4318 foreach ($restrictions as $restriction) 4319 { 4320 $restriction_relationship = null; 4321 $restriction_type = null; 4322 $restriction_value = null; 4323 if (isset($restriction['attribs']['']['relationship'])) 4324 { 4325 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 4326 } 4327 if (isset($restriction['attribs']['']['type'])) 4328 { 4329 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4330 } 4331 if (isset($restriction['data'])) 4332 { 4333 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4334 } 4335 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4336 } 4337 } 4338 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block')) 4339 { 4340 foreach ($restrictions as $restriction) 4341 { 4342 $restriction_relationship = 'allow'; 4343 $restriction_type = null; 4344 $restriction_value = 'itunes'; 4345 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes') 4346 { 4347 $restriction_relationship = 'deny'; 4348 } 4349 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4350 } 4351 } 4352 if (is_array($restrictions_parent)) 4353 { 4354 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent)); 4355 } 4356 4357 // THUMBNAILS 4358 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail')) 4359 { 4360 foreach ($thumbnails as $thumbnail) 4361 { 4362 if (isset($thumbnail['attribs']['']['url'])) 4363 { 4364 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4365 } 4366 } 4367 } 4368 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail')) 4369 { 4370 foreach ($thumbnails as $thumbnail) 4371 { 4372 if (isset($thumbnail['attribs']['']['url'])) 4373 { 4374 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4375 } 4376 } 4377 } 4378 4379 // TITLES 4380 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title')) 4381 { 4382 if (isset($title_parent[0]['data'])) 4383 { 4384 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4385 } 4386 } 4387 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title')) 4388 { 4389 if (isset($title_parent[0]['data'])) 4390 { 4391 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4392 } 4393 } 4394 4395 // Clear the memory 4396 unset($parent); 4397 4398 // Attributes 4399 $bitrate = null; 4400 $channels = null; 4401 $duration = null; 4402 $expression = null; 4403 $framerate = null; 4404 $height = null; 4405 $javascript = null; 4406 $lang = null; 4407 $length = null; 4408 $medium = null; 4409 $samplingrate = null; 4410 $type = null; 4411 $url = null; 4412 $width = null; 4413 4414 // Elements 4415 $captions = null; 4416 $categories = null; 4417 $copyrights = null; 4418 $credits = null; 4419 $description = null; 4420 $hashes = null; 4421 $keywords = null; 4422 $player = null; 4423 $ratings = null; 4424 $restrictions = null; 4425 $thumbnails = null; 4426 $title = null; 4427 4428 // If we have media:group tags, loop through them. 4429 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group) 4430 { 4431 // If we have media:content tags, loop through them. 4432 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content) 4433 { 4434 if (isset($content['attribs']['']['url'])) 4435 { 4436 // Attributes 4437 $bitrate = null; 4438 $channels = null; 4439 $duration = null; 4440 $expression = null; 4441 $framerate = null; 4442 $height = null; 4443 $javascript = null; 4444 $lang = null; 4445 $length = null; 4446 $medium = null; 4447 $samplingrate = null; 4448 $type = null; 4449 $url = null; 4450 $width = null; 4451 4452 // Elements 4453 $captions = null; 4454 $categories = null; 4455 $copyrights = null; 4456 $credits = null; 4457 $description = null; 4458 $hashes = null; 4459 $keywords = null; 4460 $player = null; 4461 $ratings = null; 4462 $restrictions = null; 4463 $thumbnails = null; 4464 $title = null; 4465 4466 // Start checking the attributes of media:content 4467 if (isset($content['attribs']['']['bitrate'])) 4468 { 4469 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT); 4470 } 4471 if (isset($content['attribs']['']['channels'])) 4472 { 4473 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT); 4474 } 4475 if (isset($content['attribs']['']['duration'])) 4476 { 4477 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT); 4478 } 4479 else 4480 { 4481 $duration = $duration_parent; 4482 } 4483 if (isset($content['attribs']['']['expression'])) 4484 { 4485 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT); 4486 } 4487 if (isset($content['attribs']['']['framerate'])) 4488 { 4489 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT); 4490 } 4491 if (isset($content['attribs']['']['height'])) 4492 { 4493 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT); 4494 } 4495 if (isset($content['attribs']['']['lang'])) 4496 { 4497 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 4498 } 4499 if (isset($content['attribs']['']['fileSize'])) 4500 { 4501 $length = ceil($content['attribs']['']['fileSize']); 4502 } 4503 if (isset($content['attribs']['']['medium'])) 4504 { 4505 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT); 4506 } 4507 if (isset($content['attribs']['']['samplingrate'])) 4508 { 4509 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT); 4510 } 4511 if (isset($content['attribs']['']['type'])) 4512 { 4513 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4514 } 4515 if (isset($content['attribs']['']['width'])) 4516 { 4517 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT); 4518 } 4519 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4520 4521 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel 4522 4523 // CAPTIONS 4524 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) 4525 { 4526 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) 4527 { 4528 $caption_type = null; 4529 $caption_lang = null; 4530 $caption_startTime = null; 4531 $caption_endTime = null; 4532 $caption_text = null; 4533 if (isset($caption['attribs']['']['type'])) 4534 { 4535 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4536 } 4537 if (isset($caption['attribs']['']['lang'])) 4538 { 4539 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 4540 } 4541 if (isset($caption['attribs']['']['start'])) 4542 { 4543 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 4544 } 4545 if (isset($caption['attribs']['']['end'])) 4546 { 4547 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 4548 } 4549 if (isset($caption['data'])) 4550 { 4551 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4552 } 4553 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 4554 } 4555 if (is_array($captions)) 4556 { 4557 $captions = array_values(SimplePie_Misc::array_unique($captions)); 4558 } 4559 } 4560 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) 4561 { 4562 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) 4563 { 4564 $caption_type = null; 4565 $caption_lang = null; 4566 $caption_startTime = null; 4567 $caption_endTime = null; 4568 $caption_text = null; 4569 if (isset($caption['attribs']['']['type'])) 4570 { 4571 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4572 } 4573 if (isset($caption['attribs']['']['lang'])) 4574 { 4575 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 4576 } 4577 if (isset($caption['attribs']['']['start'])) 4578 { 4579 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 4580 } 4581 if (isset($caption['attribs']['']['end'])) 4582 { 4583 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 4584 } 4585 if (isset($caption['data'])) 4586 { 4587 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4588 } 4589 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 4590 } 4591 if (is_array($captions)) 4592 { 4593 $captions = array_values(SimplePie_Misc::array_unique($captions)); 4594 } 4595 } 4596 else 4597 { 4598 $captions = $captions_parent; 4599 } 4600 4601 // CATEGORIES 4602 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) 4603 { 4604 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) 4605 { 4606 $term = null; 4607 $scheme = null; 4608 $label = null; 4609 if (isset($category['data'])) 4610 { 4611 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4612 } 4613 if (isset($category['attribs']['']['scheme'])) 4614 { 4615 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4616 } 4617 else 4618 { 4619 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 4620 } 4621 if (isset($category['attribs']['']['label'])) 4622 { 4623 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 4624 } 4625 $categories[] =& new $this->feed->category_class($term, $scheme, $label); 4626 } 4627 } 4628 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) 4629 { 4630 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) 4631 { 4632 $term = null; 4633 $scheme = null; 4634 $label = null; 4635 if (isset($category['data'])) 4636 { 4637 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4638 } 4639 if (isset($category['attribs']['']['scheme'])) 4640 { 4641 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4642 } 4643 else 4644 { 4645 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 4646 } 4647 if (isset($category['attribs']['']['label'])) 4648 { 4649 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 4650 } 4651 $categories[] =& new $this->feed->category_class($term, $scheme, $label); 4652 } 4653 } 4654 if (is_array($categories) && is_array($categories_parent)) 4655 { 4656 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent))); 4657 } 4658 elseif (is_array($categories)) 4659 { 4660 $categories = array_values(SimplePie_Misc::array_unique($categories)); 4661 } 4662 elseif (is_array($categories_parent)) 4663 { 4664 $categories = array_values(SimplePie_Misc::array_unique($categories_parent)); 4665 } 4666 4667 // COPYRIGHTS 4668 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) 4669 { 4670 $copyright_url = null; 4671 $copyright_label = null; 4672 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) 4673 { 4674 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 4675 } 4676 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) 4677 { 4678 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4679 } 4680 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); 4681 } 4682 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) 4683 { 4684 $copyright_url = null; 4685 $copyright_label = null; 4686 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) 4687 { 4688 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 4689 } 4690 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) 4691 { 4692 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4693 } 4694 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); 4695 } 4696 else 4697 { 4698 $copyrights = $copyrights_parent; 4699 } 4700 4701 // CREDITS 4702 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) 4703 { 4704 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) 4705 { 4706 $credit_role = null; 4707 $credit_scheme = null; 4708 $credit_name = null; 4709 if (isset($credit['attribs']['']['role'])) 4710 { 4711 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 4712 } 4713 if (isset($credit['attribs']['']['scheme'])) 4714 { 4715 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4716 } 4717 else 4718 { 4719 $credit_scheme = 'urn:ebu'; 4720 } 4721 if (isset($credit['data'])) 4722 { 4723 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4724 } 4725 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4726 } 4727 if (is_array($credits)) 4728 { 4729 $credits = array_values(SimplePie_Misc::array_unique($credits)); 4730 } 4731 } 4732 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) 4733 { 4734 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) 4735 { 4736 $credit_role = null; 4737 $credit_scheme = null; 4738 $credit_name = null; 4739 if (isset($credit['attribs']['']['role'])) 4740 { 4741 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 4742 } 4743 if (isset($credit['attribs']['']['scheme'])) 4744 { 4745 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4746 } 4747 else 4748 { 4749 $credit_scheme = 'urn:ebu'; 4750 } 4751 if (isset($credit['data'])) 4752 { 4753 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4754 } 4755 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4756 } 4757 if (is_array($credits)) 4758 { 4759 $credits = array_values(SimplePie_Misc::array_unique($credits)); 4760 } 4761 } 4762 else 4763 { 4764 $credits = $credits_parent; 4765 } 4766 4767 // DESCRIPTION 4768 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) 4769 { 4770 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4771 } 4772 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) 4773 { 4774 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4775 } 4776 else 4777 { 4778 $description = $description_parent; 4779 } 4780 4781 // HASHES 4782 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) 4783 { 4784 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) 4785 { 4786 $value = null; 4787 $algo = null; 4788 if (isset($hash['data'])) 4789 { 4790 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4791 } 4792 if (isset($hash['attribs']['']['algo'])) 4793 { 4794 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4795 } 4796 else 4797 { 4798 $algo = 'md5'; 4799 } 4800 $hashes[] = $algo.':'.$value; 4801 } 4802 if (is_array($hashes)) 4803 { 4804 $hashes = array_values(SimplePie_Misc::array_unique($hashes)); 4805 } 4806 } 4807 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) 4808 { 4809 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) 4810 { 4811 $value = null; 4812 $algo = null; 4813 if (isset($hash['data'])) 4814 { 4815 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4816 } 4817 if (isset($hash['attribs']['']['algo'])) 4818 { 4819 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4820 } 4821 else 4822 { 4823 $algo = 'md5'; 4824 } 4825 $hashes[] = $algo.':'.$value; 4826 } 4827 if (is_array($hashes)) 4828 { 4829 $hashes = array_values(SimplePie_Misc::array_unique($hashes)); 4830 } 4831 } 4832 else 4833 { 4834 $hashes = $hashes_parent; 4835 } 4836 4837 // KEYWORDS 4838 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) 4839 { 4840 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) 4841 { 4842 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4843 foreach ($temp as $word) 4844 { 4845 $keywords[] = trim($word); 4846 } 4847 unset($temp); 4848 } 4849 if (is_array($keywords)) 4850 { 4851 $keywords = array_values(SimplePie_Misc::array_unique($keywords)); 4852 } 4853 } 4854 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) 4855 { 4856 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) 4857 { 4858 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4859 foreach ($temp as $word) 4860 { 4861 $keywords[] = trim($word); 4862 } 4863 unset($temp); 4864 } 4865 if (is_array($keywords)) 4866 { 4867 $keywords = array_values(SimplePie_Misc::array_unique($keywords)); 4868 } 4869 } 4870 else 4871 { 4872 $keywords = $keywords_parent; 4873 } 4874 4875 // PLAYER 4876 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) 4877 { 4878 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4879 } 4880 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) 4881 { 4882 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4883 } 4884 else 4885 { 4886 $player = $player_parent; 4887 } 4888 4889 // RATINGS 4890 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) 4891 { 4892 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) 4893 { 4894 $rating_scheme = null; 4895 $rating_value = null; 4896 if (isset($rating['attribs']['']['scheme'])) 4897 { 4898 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4899 } 4900 else 4901 { 4902 $rating_scheme = 'urn:simple'; 4903 } 4904 if (isset($rating['data'])) 4905 { 4906 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4907 } 4908 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4909 } 4910 if (is_array($ratings)) 4911 { 4912 $ratings = array_values(SimplePie_Misc::array_unique($ratings)); 4913 } 4914 } 4915 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) 4916 { 4917 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) 4918 { 4919 $rating_scheme = null; 4920 $rating_value = null; 4921 if (isset($rating['attribs']['']['scheme'])) 4922 { 4923 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4924 } 4925 else 4926 { 4927 $rating_scheme = 'urn:simple'; 4928 } 4929 if (isset($rating['data'])) 4930 { 4931 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4932 } 4933 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4934 } 4935 if (is_array($ratings)) 4936 { 4937 $ratings = array_values(SimplePie_Misc::array_unique($ratings)); 4938 } 4939 } 4940 else 4941 { 4942 $ratings = $ratings_parent; 4943 } 4944 4945 // RESTRICTIONS 4946 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) 4947 { 4948 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) 4949 { 4950 $restriction_relationship = null; 4951 $restriction_type = null; 4952 $restriction_value = null; 4953 if (isset($restriction['attribs']['']['relationship'])) 4954 { 4955 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 4956 } 4957 if (isset($restriction['attribs']['']['type'])) 4958 { 4959 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4960 } 4961 if (isset($restriction['data'])) 4962 { 4963 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4964 } 4965 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4966 } 4967 if (is_array($restrictions)) 4968 { 4969 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); 4970 } 4971 } 4972 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) 4973 { 4974 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) 4975 { 4976 $restriction_relationship = null; 4977 $restriction_type = null; 4978 $restriction_value = null; 4979 if (isset($restriction['attribs']['']['relationship'])) 4980 { 4981 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 4982 } 4983 if (isset($restriction['attribs']['']['type'])) 4984 { 4985 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4986 } 4987 if (isset($restriction['data'])) 4988 { 4989 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4990 } 4991 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4992 } 4993 if (is_array($restrictions)) 4994 { 4995 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); 4996 } 4997 } 4998 else 4999 { 5000 $restrictions = $restrictions_parent; 5001 } 5002 5003 // THUMBNAILS 5004 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) 5005 { 5006 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) 5007 { 5008 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5009 } 5010 if (is_array($thumbnails)) 5011 { 5012 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); 5013 } 5014 } 5015 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) 5016 { 5017 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) 5018 { 5019 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5020 } 5021 if (is_array($thumbnails)) 5022 { 5023 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); 5024 } 5025 } 5026 else 5027 { 5028 $thumbnails = $thumbnails_parent; 5029 } 5030 5031 // TITLES 5032 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) 5033 { 5034 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5035 } 5036 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) 5037 { 5038 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5039 } 5040 else 5041 { 5042 $title = $title_parent; 5043 } 5044 5045 $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); 5046 } 5047 } 5048 } 5049 5050 // If we have standalone media:content tags, loop through them. 5051 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'])) 5052 { 5053 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content) 5054 { 5055 if (isset($content['attribs']['']['url'])) 5056 { 5057 // Attributes 5058 $bitrate = null; 5059 $channels = null; 5060 $duration = null; 5061 $expression = null; 5062 $framerate = null; 5063 $height = null; 5064 $javascript = null; 5065 $lang = null; 5066 $length = null; 5067 $medium = null; 5068 $samplingrate = null; 5069 $type = null; 5070 $url = null; 5071 $width = null; 5072 5073 // Elements 5074 $captions = null; 5075 $categories = null; 5076 $copyrights = null; 5077 $credits = null; 5078 $description = null; 5079 $hashes = null; 5080 $keywords = null; 5081 $player = null; 5082 $ratings = null; 5083 $restrictions = null; 5084 $thumbnails = null; 5085 $title = null; 5086 5087 // Start checking the attributes of media:content 5088 if (isset($content['attribs']['']['bitrate'])) 5089 { 5090 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT); 5091 } 5092 if (isset($content['attribs']['']['channels'])) 5093 { 5094 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT); 5095 } 5096 if (isset($content['attribs']['']['duration'])) 5097 { 5098 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT); 5099 } 5100 else 5101 { 5102 $duration = $duration_parent; 5103 } 5104 if (isset($content['attribs']['']['expression'])) 5105 { 5106 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT); 5107 } 5108 if (isset($content['attribs']['']['framerate'])) 5109 { 5110 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT); 5111 } 5112 if (isset($content['attribs']['']['height'])) 5113 { 5114 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT); 5115 } 5116 if (isset($content['attribs']['']['lang'])) 5117 { 5118 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 5119 } 5120 if (isset($content['attribs']['']['fileSize'])) 5121 { 5122 $length = ceil($content['attribs']['']['fileSize']); 5123 } 5124 if (isset($content['attribs']['']['medium'])) 5125 { 5126 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT); 5127 } 5128 if (isset($content['attribs']['']['samplingrate'])) 5129 { 5130 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT); 5131 } 5132 if (isset($content['attribs']['']['type'])) 5133 { 5134 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5135 } 5136 if (isset($content['attribs']['']['width'])) 5137 { 5138 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT); 5139 } 5140 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5141 5142 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel 5143 5144 // CAPTIONS 5145 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) 5146 { 5147 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) 5148 { 5149 $caption_type = null; 5150 $caption_lang = null; 5151 $caption_startTime = null; 5152 $caption_endTime = null; 5153 $caption_text = null; 5154 if (isset($caption['attribs']['']['type'])) 5155 { 5156 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5157 } 5158 if (isset($caption['attribs']['']['lang'])) 5159 { 5160 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 5161 } 5162 if (isset($caption['attribs']['']['start'])) 5163 { 5164 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 5165 } 5166 if (isset($caption['attribs']['']['end'])) 5167 { 5168 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 5169 } 5170 if (isset($caption['data'])) 5171 { 5172 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5173 } 5174 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 5175 } 5176 if (is_array($captions)) 5177 { 5178 $captions = array_values(SimplePie_Misc::array_unique($captions)); 5179 } 5180 } 5181 else 5182 { 5183 $captions = $captions_parent; 5184 } 5185 5186 // CATEGORIES 5187 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) 5188 { 5189 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) 5190 { 5191 $term = null; 5192 $scheme = null; 5193 $label = null; 5194 if (isset($category['data'])) 5195 { 5196 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5197 } 5198 if (isset($category['attribs']['']['scheme'])) 5199 { 5200 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 5201 } 5202 else 5203 { 5204 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 5205 } 5206 if (isset($category['attribs']['']['label'])) 5207 { 5208 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 5209 } 5210 $categories[] =& new $this->feed->category_class($term, $scheme, $label); 5211 } 5212 } 5213 if (is_array($categories) && is_array($categories_parent)) 5214 { 5215 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent))); 5216 } 5217 elseif (is_array($categories)) 5218 { 5219 $categories = array_values(SimplePie_Misc::array_unique($categories)); 5220 } 5221 elseif (is_array($categories_parent)) 5222 { 5223 $categories = array_values(SimplePie_Misc::array_unique($categories_parent)); 5224 } 5225 else 5226 { 5227 $categories = null; 5228 } 5229 5230 // COPYRIGHTS 5231 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) 5232 { 5233 $copyright_url = null; 5234 $copyright_label = null; 5235 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) 5236 { 5237 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 5238 } 5239 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) 5240 { 5241 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5242 } 5243 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); 5244 } 5245 else 5246 { 5247 $copyrights = $copyrights_parent; 5248 } 5249 5250 // CREDITS 5251 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) 5252 { 5253 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) 5254 { 5255 $credit_role = null; 5256 $credit_scheme = null; 5257 $credit_name = null; 5258 if (isset($credit['attribs']['']['role'])) 5259 { 5260 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 5261 } 5262 if (isset($credit['attribs']['']['scheme'])) 5263 { 5264 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 5265 } 5266 else 5267 { 5268 $credit_scheme = 'urn:ebu'; 5269 } 5270 if (isset($credit['data'])) 5271 { 5272 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5273 } 5274 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 5275 } 5276 if (is_array($credits)) 5277 { 5278 $credits = array_values(SimplePie_Misc::array_unique($credits)); 5279 } 5280 } 5281 else 5282 { 5283 $credits = $credits_parent; 5284 } 5285 5286 // DESCRIPTION 5287 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) 5288 { 5289 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5290 } 5291 else 5292 { 5293 $description = $description_parent; 5294 } 5295 5296 // HASHES 5297 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) 5298 { 5299 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) 5300 { 5301 $value = null; 5302 $algo = null; 5303 if (isset($hash['data'])) 5304 { 5305 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5306 } 5307 if (isset($hash['attribs']['']['algo'])) 5308 { 5309 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 5310 } 5311 else 5312 { 5313 $algo = 'md5'; 5314 } 5315 $hashes[] = $algo.':'.$value; 5316 } 5317 if (is_array($hashes)) 5318 { 5319 $hashes = array_values(SimplePie_Misc::array_unique($hashes)); 5320 } 5321 } 5322 else 5323 { 5324 $hashes = $hashes_parent; 5325 } 5326 5327 // KEYWORDS 5328 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) 5329 { 5330 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) 5331 { 5332 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 5333 foreach ($temp as $word) 5334 { 5335 $keywords[] = trim($word); 5336 } 5337 unset($temp); 5338 } 5339 if (is_array($keywords)) 5340 { 5341 $keywords = array_values(SimplePie_Misc::array_unique($keywords)); 5342 } 5343 } 5344 else 5345 { 5346 $keywords = $keywords_parent; 5347 } 5348 5349 // PLAYER 5350 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) 5351 { 5352 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5353 } 5354 else 5355 { 5356 $player = $player_parent; 5357 } 5358 5359 // RATINGS 5360 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) 5361 { 5362 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) 5363 { 5364 $rating_scheme = null; 5365 $rating_value = null; 5366 if (isset($rating['attribs']['']['scheme'])) 5367 { 5368 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 5369 } 5370 else 5371 { 5372 $rating_scheme = 'urn:simple'; 5373 } 5374 if (isset($rating['data'])) 5375 { 5376 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5377 } 5378 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 5379 } 5380 if (is_array($ratings)) 5381 { 5382 $ratings = array_values(SimplePie_Misc::array_unique($ratings)); 5383 } 5384 } 5385 else 5386 { 5387 $ratings = $ratings_parent; 5388 } 5389 5390 // RESTRICTIONS 5391 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) 5392 { 5393 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) 5394 { 5395 $restriction_relationship = null; 5396 $restriction_type = null; 5397 $restriction_value = null; 5398 if (isset($restriction['attribs']['']['relationship'])) 5399 { 5400 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 5401 } 5402 if (isset($restriction['attribs']['']['type'])) 5403 { 5404 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5405 } 5406 if (isset($restriction['data'])) 5407 { 5408 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5409 } 5410 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 5411 } 5412 if (is_array($restrictions)) 5413 { 5414 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); 5415 } 5416 } 5417 else 5418 { 5419 $restrictions = $restrictions_parent; 5420 } 5421 5422 // THUMBNAILS 5423 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) 5424 { 5425 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) 5426 { 5427 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5428 } 5429 if (is_array($thumbnails)) 5430 { 5431 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); 5432 } 5433 } 5434 else 5435 { 5436 $thumbnails = $thumbnails_parent; 5437 } 5438 5439 // TITLES 5440 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) 5441 { 5442 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5443 } 5444 else 5445 { 5446 $title = $title_parent; 5447 } 5448 5449 $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); 5450 } 5451 } 5452 } 5453 5454 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link) 5455 { 5456 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure') 5457 { 5458 // Attributes 5459 $bitrate = null; 5460 $channels = null; 5461 $duration = null; 5462 $expression = null; 5463 $framerate = null; 5464 $height = null; 5465 $javascript = null; 5466 $lang = null; 5467 $length = null; 5468 $medium = null; 5469 $samplingrate = null; 5470 $type = null; 5471 $url = null; 5472 $width = null; 5473 5474 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 5475 if (isset($link['attribs']['']['type'])) 5476 { 5477 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5478 } 5479 if (isset($link['attribs']['']['length'])) 5480 { 5481 $length = ceil($link['attribs']['']['length']); 5482 } 5483 5484 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor 5485 $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); 5486 } 5487 } 5488 5489 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link) 5490 { 5491 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure') 5492 { 5493 // Attributes 5494 $bitrate = null; 5495 $channels = null; 5496 $duration = null; 5497 $expression = null; 5498 $framerate = null; 5499 $height = null; 5500 $javascript = null; 5501 $lang = null; 5502 $length = null; 5503 $medium = null; 5504 $samplingrate = null; 5505 $type = null; 5506 $url = null; 5507 $width = null; 5508 5509 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 5510 if (isset($link['attribs']['']['type'])) 5511 { 5512 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5513 } 5514 if (isset($link['attribs']['']['length'])) 5515 { 5516 $length = ceil($link['attribs']['']['length']); 5517 } 5518 5519 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor 5520 $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); 5521 } 5522 } 5523 5524 if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure')) 5525 { 5526 if (isset($enclosure[0]['attribs']['']['url'])) 5527 { 5528 // Attributes 5529 $bitrate = null; 5530 $channels = null; 5531 $duration = null; 5532 $expression = null; 5533 $framerate = null; 5534 $height = null; 5535 $javascript = null; 5536 $lang = null; 5537 $length = null; 5538 $medium = null; 5539 $samplingrate = null; 5540 $type = null; 5541 $url = null; 5542 $width = null; 5543 5544 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0])); 5545 if (isset($enclosure[0]['attribs']['']['type'])) 5546 { 5547 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5548 } 5549 if (isset($enclosure[0]['attribs']['']['length'])) 5550 { 5551 $length = ceil($enclosure[0]['attribs']['']['length']); 5552 } 5553 5554 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor 5555 $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); 5556 } 5557 } 5558 5559 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)) 5560 { 5561 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor 5562 $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); 5563 } 5564 5565 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures'])); 5566 } 5567 if (!empty($this->data['enclosures'])) 5568 { 5569 return $this->data['enclosures']; 5570 } 5571 else 5572 { 5573 return null; 5574 } 5575 } 5576 5577 function get_latitude() 5578 { 5579 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) 5580 { 5581 return (float) $return[0]['data']; 5582 } 5583 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) 5584 { 5585 return (float) $match[1]; 5586 } 5587 else 5588 { 5589 return null; 5590 } 5591 } 5592 5593 function get_longitude() 5594 { 5595 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) 5596 { 5597 return (float) $return[0]['data']; 5598 } 5599 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) 5600 { 5601 return (float) $return[0]['data']; 5602 } 5603 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) 5604 { 5605 return (float) $match[2]; 5606 } 5607 else 5608 { 5609 return null; 5610 } 5611 } 5612 5613 function get_source() 5614 { 5615 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source')) 5616 { 5617 return new $this->feed->source_class($this, $return[0]); 5618 } 5619 else 5620 { 5621 return null; 5622 } 5623 } 5624 5625 /** 5626 * Creates the add_to_* methods' return data 5627 * 5628 * @access private 5629 * @param string $item_url String to prefix to the item permalink 5630 * @param string $title_url String to prefix to the item title 5631 * (and suffix to the item permalink) 5632 * @return mixed URL if feed exists, false otherwise 5633 */ 5634 function add_to_service($item_url, $title_url = null, $summary_url = null) 5635 { 5636 if ($this->get_permalink() !== null) 5637 { 5638 $return = $item_url . rawurlencode($this->get_permalink()); 5639 if ($title_url !== null && $this->get_title() !== null) 5640 { 5641 $return .= $title_url . rawurlencode($this->get_title()); 5642 } 5643 if ($summary_url !== null && $this->get_description() !== null) 5644 { 5645 $return .= $summary_url . rawurlencode($this->get_description()); 5646 } 5647 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI); 5648 } 5649 else 5650 { 5651 return null; 5652 } 5653 } 5654 5655 function add_to_blinklist() 5656 { 5657 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title='); 5658 } 5659 5660 function add_to_blogmarks() 5661 { 5662 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title='); 5663 } 5664 5665 function add_to_delicious() 5666 { 5667 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title='); 5668 } 5669 5670 function add_to_digg() 5671 { 5672 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext='); 5673 } 5674 5675 function add_to_furl() 5676 { 5677 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t='); 5678 } 5679 5680 function add_to_magnolia() 5681 { 5682 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title='); 5683 } 5684 5685 function add_to_myweb20() 5686 { 5687 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t='); 5688 } 5689 5690 function add_to_newsvine() 5691 { 5692 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h='); 5693 } 5694 5695 function add_to_reddit() 5696 { 5697 return $this->add_to_service('http://reddit.com/submit?url=', '&title='); 5698 } 5699 5700 function add_to_segnalo() 5701 { 5702 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title='); 5703 } 5704 5705 function add_to_simpy() 5706 { 5707 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title='); 5708 } 5709 5710 function add_to_spurl() 5711 { 5712 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title='); 5713 } 5714 5715 function add_to_wists() 5716 { 5717 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title='); 5718 } 5719 5720 function search_technorati() 5721 { 5722 return $this->add_to_service('http://www.technorati.com/search/'); 5723 } 5724} 5725 5726class SimplePie_Source 5727{ 5728 var $item; 5729 var $data = array(); 5730 5731 function SimplePie_Source($item, $data) 5732 { 5733 $this->item = $item; 5734 $this->data = $data; 5735 } 5736 5737 function __toString() 5738 { 5739 return md5(serialize($this->data)); 5740 } 5741 5742 function get_source_tags($namespace, $tag) 5743 { 5744 if (isset($this->data['child'][$namespace][$tag])) 5745 { 5746 return $this->data['child'][$namespace][$tag]; 5747 } 5748 else 5749 { 5750 return null; 5751 } 5752 } 5753 5754 function get_base($element = array()) 5755 { 5756 return $this->item->get_base($element); 5757 } 5758 5759 function sanitize($data, $type, $base = '') 5760 { 5761 return $this->item->sanitize($data, $type, $base); 5762 } 5763 5764 function get_item() 5765 { 5766 return $this->item; 5767 } 5768 5769 function get_title() 5770 { 5771 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) 5772 { 5773 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 5774 } 5775 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) 5776 { 5777 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 5778 } 5779 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 5780 { 5781 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 5782 } 5783 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 5784 { 5785 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 5786 } 5787 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 5788 { 5789 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 5790 } 5791 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 5792 { 5793 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5794 } 5795 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 5796 { 5797 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5798 } 5799 else 5800 { 5801 return null; 5802 } 5803 } 5804 5805 function get_category($key = 0) 5806 { 5807 $categories = $this->get_categories(); 5808 if (isset($categories[$key])) 5809 { 5810 return $categories[$key]; 5811 } 5812 else 5813 { 5814 return null; 5815 } 5816 } 5817 5818 function get_categories() 5819 { 5820 $categories = array(); 5821 5822 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) 5823 { 5824 $term = null; 5825 $scheme = null; 5826 $label = null; 5827 if (isset($category['attribs']['']['term'])) 5828 { 5829 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); 5830 } 5831 if (isset($category['attribs']['']['scheme'])) 5832 { 5833 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 5834 } 5835 if (isset($category['attribs']['']['label'])) 5836 { 5837 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 5838 } 5839 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label); 5840 } 5841 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) 5842 { 5843 // This is really the label, but keep this as the term also for BC. 5844 // Label will also work on retrieving because that falls back to term. 5845 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5846 if (isset($category['attribs']['']['domain'])) 5847 { 5848 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); 5849 } 5850 else 5851 { 5852 $scheme = null; 5853 } 5854 $categories[] =& new $this->item->feed->category_class($term, $scheme, null); 5855 } 5856 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) 5857 { 5858 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5859 } 5860 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) 5861 { 5862 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5863 } 5864 5865 if (!empty($categories)) 5866 { 5867 return SimplePie_Misc::array_unique($categories); 5868 } 5869 else 5870 { 5871 return null; 5872 } 5873 } 5874 5875 function get_author($key = 0) 5876 { 5877 $authors = $this->get_authors(); 5878 if (isset($authors[$key])) 5879 { 5880 return $authors[$key]; 5881 } 5882 else 5883 { 5884 return null; 5885 } 5886 } 5887 5888 function get_authors() 5889 { 5890 $authors = array(); 5891 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) 5892 { 5893 $name = null; 5894 $uri = null; 5895 $email = null; 5896 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 5897 { 5898 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5899 } 5900 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 5901 { 5902 $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])); 5903 } 5904 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 5905 { 5906 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5907 } 5908 if ($name !== null || $email !== null || $uri !== null) 5909 { 5910 $authors[] =& new $this->item->feed->author_class($name, $uri, $email); 5911 } 5912 } 5913 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) 5914 { 5915 $name = null; 5916 $url = null; 5917 $email = null; 5918 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 5919 { 5920 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5921 } 5922 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 5923 { 5924 $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])); 5925 } 5926 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 5927 { 5928 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5929 } 5930 if ($name !== null || $email !== null || $url !== null) 5931 { 5932 $authors[] =& new $this->item->feed->author_class($name, $url, $email); 5933 } 5934 } 5935 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) 5936 { 5937 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5938 } 5939 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) 5940 { 5941 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5942 } 5943 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) 5944 { 5945 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5946 } 5947 5948 if (!empty($authors)) 5949 { 5950 return SimplePie_Misc::array_unique($authors); 5951 } 5952 else 5953 { 5954 return null; 5955 } 5956 } 5957 5958 function get_contributor($key = 0) 5959 { 5960 $contributors = $this->get_contributors(); 5961 if (isset($contributors[$key])) 5962 { 5963 return $contributors[$key]; 5964 } 5965 else 5966 { 5967 return null; 5968 } 5969 } 5970 5971 function get_contributors() 5972 { 5973 $contributors = array(); 5974 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) 5975 { 5976 $name = null; 5977 $uri = null; 5978 $email = null; 5979 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 5980 { 5981 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5982 } 5983 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 5984 { 5985 $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])); 5986 } 5987 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 5988 { 5989 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5990 } 5991 if ($name !== null || $email !== null || $uri !== null) 5992 { 5993 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email); 5994 } 5995 } 5996 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) 5997 { 5998 $name = null; 5999 $url = null; 6000 $email = null; 6001 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 6002 { 6003 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6004 } 6005 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 6006 { 6007 $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])); 6008 } 6009 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 6010 { 6011 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6012 } 6013 if ($name !== null || $email !== null || $url !== null) 6014 { 6015 $contributors[] =& new $this->item->feed->author_class($name, $url, $email); 6016 } 6017 } 6018 6019 if (!empty($contributors)) 6020 { 6021 return SimplePie_Misc::array_unique($contributors); 6022 } 6023 else 6024 { 6025 return null; 6026 } 6027 } 6028 6029 function get_link($key = 0, $rel = 'alternate') 6030 { 6031 $links = $this->get_links($rel); 6032 if (isset($links[$key])) 6033 { 6034 return $links[$key]; 6035 } 6036 else 6037 { 6038 return null; 6039 } 6040 } 6041 6042 /** 6043 * Added for parity between the parent-level and the item/entry-level. 6044 */ 6045 function get_permalink() 6046 { 6047 return $this->get_link(0); 6048 } 6049 6050 function get_links($rel = 'alternate') 6051 { 6052 if (!isset($this->data['links'])) 6053 { 6054 $this->data['links'] = array(); 6055 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) 6056 { 6057 foreach ($links as $link) 6058 { 6059 if (isset($link['attribs']['']['href'])) 6060 { 6061 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 6062 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 6063 } 6064 } 6065 } 6066 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) 6067 { 6068 foreach ($links as $link) 6069 { 6070 if (isset($link['attribs']['']['href'])) 6071 { 6072 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 6073 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 6074 6075 } 6076 } 6077 } 6078 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 6079 { 6080 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 6081 } 6082 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 6083 { 6084 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 6085 } 6086 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 6087 { 6088 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 6089 } 6090 6091 $keys = array_keys($this->data['links']); 6092 foreach ($keys as $key) 6093 { 6094 if (SimplePie_Misc::is_isegment_nz_nc($key)) 6095 { 6096 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) 6097 { 6098 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); 6099 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; 6100 } 6101 else 6102 { 6103 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; 6104 } 6105 } 6106 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) 6107 { 6108 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; 6109 } 6110 $this->data['links'][$key] = array_unique($this->data['links'][$key]); 6111 } 6112 } 6113 6114 if (isset($this->data['links'][$rel])) 6115 { 6116 return $this->data['links'][$rel]; 6117 } 6118 else 6119 { 6120 return null; 6121 } 6122 } 6123 6124 function get_description() 6125 { 6126 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) 6127 { 6128 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 6129 } 6130 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) 6131 { 6132 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 6133 } 6134 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) 6135 { 6136 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 6137 } 6138 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) 6139 { 6140 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 6141 } 6142 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) 6143 { 6144 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 6145 } 6146 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) 6147 { 6148 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6149 } 6150 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) 6151 { 6152 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6153 } 6154 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) 6155 { 6156 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 6157 } 6158 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) 6159 { 6160 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 6161 } 6162 else 6163 { 6164 return null; 6165 } 6166 } 6167 6168 function get_copyright() 6169 { 6170 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) 6171 { 6172 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 6173 } 6174 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) 6175 { 6176 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 6177 } 6178 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright')) 6179 { 6180 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6181 } 6182 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) 6183 { 6184 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6185 } 6186 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) 6187 { 6188 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6189 } 6190 else 6191 { 6192 return null; 6193 } 6194 } 6195 6196 function get_language() 6197 { 6198 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language')) 6199 { 6200 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6201 } 6202 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) 6203 { 6204 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6205 } 6206 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) 6207 { 6208 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6209 } 6210 elseif (isset($this->data['xml_lang'])) 6211 { 6212 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 6213 } 6214 else 6215 { 6216 return null; 6217 } 6218 } 6219 6220 function get_latitude() 6221 { 6222 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) 6223 { 6224 return (float) $return[0]['data']; 6225 } 6226 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) 6227 { 6228 return (float) $match[1]; 6229 } 6230 else 6231 { 6232 return null; 6233 } 6234 } 6235 6236 function get_longitude() 6237 { 6238 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) 6239 { 6240 return (float) $return[0]['data']; 6241 } 6242 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) 6243 { 6244 return (float) $return[0]['data']; 6245 } 6246 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) 6247 { 6248 return (float) $match[2]; 6249 } 6250 else 6251 { 6252 return null; 6253 } 6254 } 6255 6256 function get_image_url() 6257 { 6258 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) 6259 { 6260 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); 6261 } 6262 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) 6263 { 6264 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 6265 } 6266 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) 6267 { 6268 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 6269 } 6270 else 6271 { 6272 return null; 6273 } 6274 } 6275} 6276 6277class SimplePie_Author 6278{ 6279 var $name; 6280 var $link; 6281 var $email; 6282 6283 // Constructor, used to input the data 6284 function SimplePie_Author($name = null, $link = null, $email = null) 6285 { 6286 $this->name = $name; 6287 $this->link = $link; 6288 $this->email = $email; 6289 } 6290 6291 function __toString() 6292 { 6293 // There is no $this->data here 6294 return md5(serialize($this)); 6295 } 6296 6297 function get_name() 6298 { 6299 if ($this->name !== null) 6300 { 6301 return $this->name; 6302 } 6303 else 6304 { 6305 return null; 6306 } 6307 } 6308 6309 function get_link() 6310 { 6311 if ($this->link !== null) 6312 { 6313 return $this->link; 6314 } 6315 else 6316 { 6317 return null; 6318 } 6319 } 6320 6321 function get_email() 6322 { 6323 if ($this->email !== null) 6324 { 6325 return $this->email; 6326 } 6327 else 6328 { 6329 return null; 6330 } 6331 } 6332} 6333 6334class SimplePie_Category 6335{ 6336 var $term; 6337 var $scheme; 6338 var $label; 6339 6340 // Constructor, used to input the data 6341 function SimplePie_Category($term = null, $scheme = null, $label = null) 6342 { 6343 $this->term = $term; 6344 $this->scheme = $scheme; 6345 $this->label = $label; 6346 } 6347 6348 function __toString() 6349 { 6350 // There is no $this->data here 6351 return md5(serialize($this)); 6352 } 6353 6354 function get_term() 6355 { 6356 if ($this->term !== null) 6357 { 6358 return $this->term; 6359 } 6360 else 6361 { 6362 return null; 6363 } 6364 } 6365 6366 function get_scheme() 6367 { 6368 if ($this->scheme !== null) 6369 { 6370 return $this->scheme; 6371 } 6372 else 6373 { 6374 return null; 6375 } 6376 } 6377 6378 function get_label() 6379 { 6380 if ($this->label !== null) 6381 { 6382 return $this->label; 6383 } 6384 else 6385 { 6386 return $this->get_term(); 6387 } 6388 } 6389} 6390 6391class SimplePie_Enclosure 6392{ 6393 var $bitrate; 6394 var $captions; 6395 var $categories; 6396 var $channels; 6397 var $copyright; 6398 var $credits; 6399 var $description; 6400 var $duration; 6401 var $expression; 6402 var $framerate; 6403 var $handler; 6404 var $hashes; 6405 var $height; 6406 var $javascript; 6407 var $keywords; 6408 var $lang; 6409 var $length; 6410 var $link; 6411 var $medium; 6412 var $player; 6413 var $ratings; 6414 var $restrictions; 6415 var $samplingrate; 6416 var $thumbnails; 6417 var $title; 6418 var $type; 6419 var $width; 6420 6421 // Constructor, used to input the data 6422 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) 6423 { 6424 $this->bitrate = $bitrate; 6425 $this->captions = $captions; 6426 $this->categories = $categories; 6427 $this->channels = $channels; 6428 $this->copyright = $copyright; 6429 $this->credits = $credits; 6430 $this->description = $description; 6431 $this->duration = $duration; 6432 $this->expression = $expression; 6433 $this->framerate = $framerate; 6434 $this->hashes = $hashes; 6435 $this->height = $height; 6436 $this->javascript = $javascript; 6437 $this->keywords = $keywords; 6438 $this->lang = $lang; 6439 $this->length = $length; 6440 $this->link = $link; 6441 $this->medium = $medium; 6442 $this->player = $player; 6443 $this->ratings = $ratings; 6444 $this->restrictions = $restrictions; 6445 $this->samplingrate = $samplingrate; 6446 $this->thumbnails = $thumbnails; 6447 $this->title = $title; 6448 $this->type = $type; 6449 $this->width = $width; 6450 if (class_exists('idna_convert')) 6451 { 6452 $idn =& new idna_convert; 6453 $parsed = SimplePie_Misc::parse_url($link); 6454 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); 6455 } 6456 $this->handler = $this->get_handler(); // Needs to load last 6457 } 6458 6459 function __toString() 6460 { 6461 // There is no $this->data here 6462 return md5(serialize($this)); 6463 } 6464 6465 function get_bitrate() 6466 { 6467 if ($this->bitrate !== null) 6468 { 6469 return $this->bitrate; 6470 } 6471 else 6472 { 6473 return null; 6474 } 6475 } 6476 6477 function get_caption($key = 0) 6478 { 6479 $captions = $this->get_captions(); 6480 if (isset($captions[$key])) 6481 { 6482 return $captions[$key]; 6483 } 6484 else 6485 { 6486 return null; 6487 } 6488 } 6489 6490 function get_captions() 6491 { 6492 if ($this->captions !== null) 6493 { 6494 return $this->captions; 6495 } 6496 else 6497 { 6498 return null; 6499 } 6500 } 6501 6502 function get_category($key = 0) 6503 { 6504 $categories = $this->get_categories(); 6505 if (isset($categories[$key])) 6506 { 6507 return $categories[$key]; 6508 } 6509 else 6510 { 6511 return null; 6512 } 6513 } 6514 6515 function get_categories() 6516 { 6517 if ($this->categories !== null) 6518 { 6519 return $this->categories; 6520 } 6521 else 6522 { 6523 return null; 6524 } 6525 } 6526 6527 function get_channels() 6528 { 6529 if ($this->channels !== null) 6530 { 6531 return $this->channels; 6532 } 6533 else 6534 { 6535 return null; 6536 } 6537 } 6538 6539 function get_copyright() 6540 { 6541 if ($this->copyright !== null) 6542 { 6543 return $this->copyright; 6544 } 6545 else 6546 { 6547 return null; 6548 } 6549 } 6550 6551 function get_credit($key = 0) 6552 { 6553 $credits = $this->get_credits(); 6554 if (isset($credits[$key])) 6555 { 6556 return $credits[$key]; 6557 } 6558 else 6559 { 6560 return null; 6561 } 6562 } 6563 6564 function get_credits() 6565 { 6566 if ($this->credits !== null) 6567 { 6568 return $this->credits; 6569 } 6570 else 6571 { 6572 return null; 6573 } 6574 } 6575 6576 function get_description() 6577 { 6578 if ($this->description !== null) 6579 { 6580 return $this->description; 6581 } 6582 else 6583 { 6584 return null; 6585 } 6586 } 6587 6588 function get_duration($convert = false) 6589 { 6590 if ($this->duration !== null) 6591 { 6592 if ($convert) 6593 { 6594 $time = SimplePie_Misc::time_hms($this->duration); 6595 return $time; 6596 } 6597 else 6598 { 6599 return $this->duration; 6600 } 6601 } 6602 else 6603 { 6604 return null; 6605 } 6606 } 6607 6608 function get_expression() 6609 { 6610 if ($this->expression !== null) 6611 { 6612 return $this->expression; 6613 } 6614 else 6615 { 6616 return 'full'; 6617 } 6618 } 6619 6620 function get_extension() 6621 { 6622 if ($this->link !== null) 6623 { 6624 $url = SimplePie_Misc::parse_url($this->link); 6625 if ($url['path'] !== '') 6626 { 6627 return pathinfo($url['path'], PATHINFO_EXTENSION); 6628 } 6629 } 6630 return null; 6631 } 6632 6633 function get_framerate() 6634 { 6635 if ($this->framerate !== null) 6636 { 6637 return $this->framerate; 6638 } 6639 else 6640 { 6641 return null; 6642 } 6643 } 6644 6645 function get_handler() 6646 { 6647 return $this->get_real_type(true); 6648 } 6649 6650 function get_hash($key = 0) 6651 { 6652 $hashes = $this->get_hashes(); 6653 if (isset($hashes[$key])) 6654 { 6655 return $hashes[$key]; 6656 } 6657 else 6658 { 6659 return null; 6660 } 6661 } 6662 6663 function get_hashes() 6664 { 6665 if ($this->hashes !== null) 6666 { 6667 return $this->hashes; 6668 } 6669 else 6670 { 6671 return null; 6672 } 6673 } 6674 6675 function get_height() 6676 { 6677 if ($this->height !== null) 6678 { 6679 return $this->height; 6680 } 6681 else 6682 { 6683 return null; 6684 } 6685 } 6686 6687 function get_language() 6688 { 6689 if ($this->lang !== null) 6690 { 6691 return $this->lang; 6692 } 6693 else 6694 { 6695 return null; 6696 } 6697 } 6698 6699 function get_keyword($key = 0) 6700 { 6701 $keywords = $this->get_keywords(); 6702 if (isset($keywords[$key])) 6703 { 6704 return $keywords[$key]; 6705 } 6706 else 6707 { 6708 return null; 6709 } 6710 } 6711 6712 function get_keywords() 6713 { 6714 if ($this->keywords !== null) 6715 { 6716 return $this->keywords; 6717 } 6718 else 6719 { 6720 return null; 6721 } 6722 } 6723 6724 function get_length() 6725 { 6726 if ($this->length !== null) 6727 { 6728 return $this->length; 6729 } 6730 else 6731 { 6732 return null; 6733 } 6734 } 6735 6736 function get_link() 6737 { 6738 if ($this->link !== null) 6739 { 6740 return urldecode($this->link); 6741 } 6742 else 6743 { 6744 return null; 6745 } 6746 } 6747 6748 function get_medium() 6749 { 6750 if ($this->medium !== null) 6751 { 6752 return $this->medium; 6753 } 6754 else 6755 { 6756 return null; 6757 } 6758 } 6759 6760 function get_player() 6761 { 6762 if ($this->player !== null) 6763 { 6764 return $this->player; 6765 } 6766 else 6767 { 6768 return null; 6769 } 6770 } 6771 6772 function get_rating($key = 0) 6773 { 6774 $ratings = $this->get_ratings(); 6775 if (isset($ratings[$key])) 6776 { 6777 return $ratings[$key]; 6778 } 6779 else 6780 { 6781 return null; 6782 } 6783 } 6784 6785 function get_ratings() 6786 { 6787 if ($this->ratings !== null) 6788 { 6789 return $this->ratings; 6790 } 6791 else 6792 { 6793 return null; 6794 } 6795 } 6796 6797 function get_restriction($key = 0) 6798 { 6799 $restrictions = $this->get_restrictions(); 6800 if (isset($restrictions[$key])) 6801 { 6802 return $restrictions[$key]; 6803 } 6804 else 6805 { 6806 return null; 6807 } 6808 } 6809 6810 function get_restrictions() 6811 { 6812 if ($this->restrictions !== null) 6813 { 6814 return $this->restrictions; 6815 } 6816 else 6817 { 6818 return null; 6819 } 6820 } 6821 6822 function get_sampling_rate() 6823 { 6824 if ($this->samplingrate !== null) 6825 { 6826 return $this->samplingrate; 6827 } 6828 else 6829 { 6830 return null; 6831 } 6832 } 6833 6834 function get_size() 6835 { 6836 $length = $this->get_length(); 6837 if ($length !== null) 6838 { 6839 return round($length/1048576, 2); 6840 } 6841 else 6842 { 6843 return null; 6844 } 6845 } 6846 6847 function get_thumbnail($key = 0) 6848 { 6849 $thumbnails = $this->get_thumbnails(); 6850 if (isset($thumbnails[$key])) 6851 { 6852 return $thumbnails[$key]; 6853 } 6854 else 6855 { 6856 return null; 6857 } 6858 } 6859 6860 function get_thumbnails() 6861 { 6862 if ($this->thumbnails !== null) 6863 { 6864 return $this->thumbnails; 6865 } 6866 else 6867 { 6868 return null; 6869 } 6870 } 6871 6872 function get_title() 6873 { 6874 if ($this->title !== null) 6875 { 6876 return $this->title; 6877 } 6878 else 6879 { 6880 return null; 6881 } 6882 } 6883 6884 function get_type() 6885 { 6886 if ($this->type !== null) 6887 { 6888 return $this->type; 6889 } 6890 else 6891 { 6892 return null; 6893 } 6894 } 6895 6896 function get_width() 6897 { 6898 if ($this->width !== null) 6899 { 6900 return $this->width; 6901 } 6902 else 6903 { 6904 return null; 6905 } 6906 } 6907 6908 function native_embed($options='') 6909 { 6910 return $this->embed($options, true); 6911 } 6912 6913 /** 6914 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'. 6915 */ 6916 function embed($options = '', $native = false) 6917 { 6918 // Set up defaults 6919 $audio = ''; 6920 $video = ''; 6921 $alt = ''; 6922 $altclass = ''; 6923 $loop = 'false'; 6924 $width = 'auto'; 6925 $height = 'auto'; 6926 $bgcolor = '#ffffff'; 6927 $mediaplayer = ''; 6928 $widescreen = false; 6929 $handler = $this->get_handler(); 6930 $type = $this->get_real_type(); 6931 6932 // Process options and reassign values as necessary 6933 if (is_array($options)) 6934 { 6935 extract($options); 6936 } 6937 else 6938 { 6939 $options = explode(',', $options); 6940 foreach($options as $option) 6941 { 6942 $opt = explode(':', $option, 2); 6943 if (isset($opt[0], $opt[1])) 6944 { 6945 $opt[0] = trim($opt[0]); 6946 $opt[1] = trim($opt[1]); 6947 switch ($opt[0]) 6948 { 6949 case 'audio': 6950 $audio = $opt[1]; 6951 break; 6952 6953 case 'video': 6954 $video = $opt[1]; 6955 break; 6956 6957 case 'alt': 6958 $alt = $opt[1]; 6959 break; 6960 6961 case 'altclass': 6962 $altclass = $opt[1]; 6963 break; 6964 6965 case 'loop': 6966 $loop = $opt[1]; 6967 break; 6968 6969 case 'width': 6970 $width = $opt[1]; 6971 break; 6972 6973 case 'height': 6974 $height = $opt[1]; 6975 break; 6976 6977 case 'bgcolor': 6978 $bgcolor = $opt[1]; 6979 break; 6980 6981 case 'mediaplayer': 6982 $mediaplayer = $opt[1]; 6983 break; 6984 6985 case 'widescreen': 6986 $widescreen = $opt[1]; 6987 break; 6988 } 6989 } 6990 } 6991 } 6992 6993 $mime = explode('/', $type, 2); 6994 $mime = $mime[0]; 6995 6996 // Process values for 'auto' 6997 if ($width === 'auto') 6998 { 6999 if ($mime === 'video') 7000 { 7001 if ($height === 'auto') 7002 { 7003 $width = 480; 7004 } 7005 elseif ($widescreen) 7006 { 7007 $width = round((intval($height)/9)*16); 7008 } 7009 else 7010 { 7011 $width = round((intval($height)/3)*4); 7012 } 7013 } 7014 else 7015 { 7016 $width = '100%'; 7017 } 7018 } 7019 7020 if ($height === 'auto') 7021 { 7022 if ($mime === 'audio') 7023 { 7024 $height = 0; 7025 } 7026 elseif ($mime === 'video') 7027 { 7028 if ($width === 'auto') 7029 { 7030 if ($widescreen) 7031 { 7032 $height = 270; 7033 } 7034 else 7035 { 7036 $height = 360; 7037 } 7038 } 7039 elseif ($widescreen) 7040 { 7041 $height = round((intval($width)/16)*9); 7042 } 7043 else 7044 { 7045 $height = round((intval($width)/4)*3); 7046 } 7047 } 7048 else 7049 { 7050 $height = 376; 7051 } 7052 } 7053 elseif ($mime === 'audio') 7054 { 7055 $height = 0; 7056 } 7057 7058 // Set proper placeholder value 7059 if ($mime === 'audio') 7060 { 7061 $placeholder = $audio; 7062 } 7063 elseif ($mime === 'video') 7064 { 7065 $placeholder = $video; 7066 } 7067 7068 $embed = ''; 7069 7070 // Make sure the JS library is included 7071 if (!$native) 7072 { 7073 static $javascript_outputted = null; 7074 if (!$javascript_outputted && $this->javascript) 7075 { 7076 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>'; 7077 $javascript_outputted = true; 7078 } 7079 } 7080 7081 // Odeo Feed MP3's 7082 if ($handler === 'odeo') 7083 { 7084 if ($native) 7085 { 7086 $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>'; 7087 } 7088 else 7089 { 7090 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>'; 7091 } 7092 } 7093 7094 // Flash 7095 elseif ($handler === 'flash') 7096 { 7097 if ($native) 7098 { 7099 $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>"; 7100 } 7101 else 7102 { 7103 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>"; 7104 } 7105 } 7106 7107 // Flash Media Player file types. 7108 // Preferred handler for MP3 file types. 7109 elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== '')) 7110 { 7111 $height += 20; 7112 if ($native) 7113 { 7114 $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>"; 7115 } 7116 else 7117 { 7118 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>"; 7119 } 7120 } 7121 7122 // QuickTime 7 file types. Need to test with QuickTime 6. 7123 // Only handle MP3's if the Flash Media Player is not present. 7124 elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === '')) 7125 { 7126 $height += 16; 7127 if ($native) 7128 { 7129 if ($placeholder !== '') 7130 { 7131 $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>"; 7132 } 7133 else 7134 { 7135 $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>"; 7136 } 7137 } 7138 else 7139 { 7140 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>"; 7141 } 7142 } 7143 7144 // Windows Media 7145 elseif ($handler === 'wmedia') 7146 { 7147 $height += 45; 7148 if ($native) 7149 { 7150 $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>"; 7151 } 7152 else 7153 { 7154 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>"; 7155 } 7156 } 7157 7158 // Everything else 7159 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>'; 7160 7161 return $embed; 7162 } 7163 7164 function get_real_type($find_handler = false) 7165 { 7166 // If it's Odeo, let's get it out of the way. 7167 if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com') 7168 { 7169 return 'odeo'; 7170 } 7171 7172 // Mime-types by handler. 7173 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash 7174 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player 7175 $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 7176 $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 7177 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3 7178 7179 if ($this->get_type() !== null) 7180 { 7181 $type = strtolower($this->type); 7182 } 7183 else 7184 { 7185 $type = null; 7186 } 7187 7188 // If we encounter an unsupported mime-type, check the file extension and guess intelligently. 7189 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3))) 7190 { 7191 switch (strtolower($this->get_extension())) 7192 { 7193 // Audio mime-types 7194 case 'aac': 7195 case 'adts': 7196 $type = 'audio/acc'; 7197 break; 7198 7199 case 'aif': 7200 case 'aifc': 7201 case 'aiff': 7202 case 'cdda': 7203 $type = 'audio/aiff'; 7204 break; 7205 7206 case 'bwf': 7207 $type = 'audio/wav'; 7208 break; 7209 7210 case 'kar': 7211 case 'mid': 7212 case 'midi': 7213 case 'smf': 7214 $type = 'audio/midi'; 7215 break; 7216 7217 case 'm4a': 7218 $type = 'audio/x-m4a'; 7219 break; 7220 7221 case 'mp3': 7222 case 'swa': 7223 $type = 'audio/mp3'; 7224 break; 7225 7226 case 'wav': 7227 $type = 'audio/wav'; 7228 break; 7229 7230 case 'wax': 7231 $type = 'audio/x-ms-wax'; 7232 break; 7233 7234 case 'wma': 7235 $type = 'audio/x-ms-wma'; 7236 break; 7237 7238 // Video mime-types 7239 case '3gp': 7240 case '3gpp': 7241 $type = 'video/3gpp'; 7242 break; 7243 7244 case '3g2': 7245 case '3gp2': 7246 $type = 'video/3gpp2'; 7247 break; 7248 7249 case 'asf': 7250 $type = 'video/x-ms-asf'; 7251 break; 7252 7253 case 'flv': 7254 $type = 'video/x-flv'; 7255 break; 7256 7257 case 'm1a': 7258 case 'm1s': 7259 case 'm1v': 7260 case 'm15': 7261 case 'm75': 7262 case 'mp2': 7263 case 'mpa': 7264 case 'mpeg': 7265 case 'mpg': 7266 case 'mpm': 7267 case 'mpv': 7268 $type = 'video/mpeg'; 7269 break; 7270 7271 case 'm4v': 7272 $type = 'video/x-m4v'; 7273 break; 7274 7275 case 'mov': 7276 case 'qt': 7277 $type = 'video/quicktime'; 7278 break; 7279 7280 case 'mp4': 7281 case 'mpg4': 7282 $type = 'video/mp4'; 7283 break; 7284 7285 case 'sdv': 7286 $type = 'video/sd-video'; 7287 break; 7288 7289 case 'wm': 7290 $type = 'video/x-ms-wm'; 7291 break; 7292 7293 case 'wmv': 7294 $type = 'video/x-ms-wmv'; 7295 break; 7296 7297 case 'wvx': 7298 $type = 'video/x-ms-wvx'; 7299 break; 7300 7301 // Flash mime-types 7302 case 'spl': 7303 $type = 'application/futuresplash'; 7304 break; 7305 7306 case 'swf': 7307 $type = 'application/x-shockwave-flash'; 7308 break; 7309 } 7310 } 7311 7312 if ($find_handler) 7313 { 7314 if (in_array($type, $types_flash)) 7315 { 7316 return 'flash'; 7317 } 7318 elseif (in_array($type, $types_fmedia)) 7319 { 7320 return 'fmedia'; 7321 } 7322 elseif (in_array($type, $types_quicktime)) 7323 { 7324 return 'quicktime'; 7325 } 7326 elseif (in_array($type, $types_wmedia)) 7327 { 7328 return 'wmedia'; 7329 } 7330 elseif (in_array($type, $types_mp3)) 7331 { 7332 return 'mp3'; 7333 } 7334 else 7335 { 7336 return null; 7337 } 7338 } 7339 else 7340 { 7341 return $type; 7342 } 7343 } 7344} 7345 7346class SimplePie_Caption 7347{ 7348 var $type; 7349 var $lang; 7350 var $startTime; 7351 var $endTime; 7352 var $text; 7353 7354 // Constructor, used to input the data 7355 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null) 7356 { 7357 $this->type = $type; 7358 $this->lang = $lang; 7359 $this->startTime = $startTime; 7360 $this->endTime = $endTime; 7361 $this->text = $text; 7362 } 7363 7364 function __toString() 7365 { 7366 // There is no $this->data here 7367 return md5(serialize($this)); 7368 } 7369 7370 function get_endtime() 7371 { 7372 if ($this->endTime !== null) 7373 { 7374 return $this->endTime; 7375 } 7376 else 7377 { 7378 return null; 7379 } 7380 } 7381 7382 function get_language() 7383 { 7384 if ($this->lang !== null) 7385 { 7386 return $this->lang; 7387 } 7388 else 7389 { 7390 return null; 7391 } 7392 } 7393 7394 function get_starttime() 7395 { 7396 if ($this->startTime !== null) 7397 { 7398 return $this->startTime; 7399 } 7400 else 7401 { 7402 return null; 7403 } 7404 } 7405 7406 function get_text() 7407 { 7408 if ($this->text !== null) 7409 { 7410 return $this->text; 7411 } 7412 else 7413 { 7414 return null; 7415 } 7416 } 7417 7418 function get_type() 7419 { 7420 if ($this->type !== null) 7421 { 7422 return $this->type; 7423 } 7424 else 7425 { 7426 return null; 7427 } 7428 } 7429} 7430 7431class SimplePie_Credit 7432{ 7433 var $role; 7434 var $scheme; 7435 var $name; 7436 7437 // Constructor, used to input the data 7438 function SimplePie_Credit($role = null, $scheme = null, $name = null) 7439 { 7440 $this->role = $role; 7441 $this->scheme = $scheme; 7442 $this->name = $name; 7443 } 7444 7445 function __toString() 7446 { 7447 // There is no $this->data here 7448 return md5(serialize($this)); 7449 } 7450 7451 function get_role() 7452 { 7453 if ($this->role !== null) 7454 { 7455 return $this->role; 7456 } 7457 else 7458 { 7459 return null; 7460 } 7461 } 7462 7463 function get_scheme() 7464 { 7465 if ($this->scheme !== null) 7466 { 7467 return $this->scheme; 7468 } 7469 else 7470 { 7471 return null; 7472 } 7473 } 7474 7475 function get_name() 7476 { 7477 if ($this->name !== null) 7478 { 7479 return $this->name; 7480 } 7481 else 7482 { 7483 return null; 7484 } 7485 } 7486} 7487 7488class SimplePie_Copyright 7489{ 7490 var $url; 7491 var $label; 7492 7493 // Constructor, used to input the data 7494 function SimplePie_Copyright($url = null, $label = null) 7495 { 7496 $this->url = $url; 7497 $this->label = $label; 7498 } 7499 7500 function __toString() 7501 { 7502 // There is no $this->data here 7503 return md5(serialize($this)); 7504 } 7505 7506 function get_url() 7507 { 7508 if ($this->url !== null) 7509 { 7510 return $this->url; 7511 } 7512 else 7513 { 7514 return null; 7515 } 7516 } 7517 7518 function get_attribution() 7519 { 7520 if ($this->label !== null) 7521 { 7522 return $this->label; 7523 } 7524 else 7525 { 7526 return null; 7527 } 7528 } 7529} 7530 7531class SimplePie_Rating 7532{ 7533 var $scheme; 7534 var $value; 7535 7536 // Constructor, used to input the data 7537 function SimplePie_Rating($scheme = null, $value = null) 7538 { 7539 $this->scheme = $scheme; 7540 $this->value = $value; 7541 } 7542 7543 function __toString() 7544 { 7545 // There is no $this->data here 7546 return md5(serialize($this)); 7547 } 7548 7549 function get_scheme() 7550 { 7551 if ($this->scheme !== null) 7552 { 7553 return $this->scheme; 7554 } 7555 else 7556 { 7557 return null; 7558 } 7559 } 7560 7561 function get_value() 7562 { 7563 if ($this->value !== null) 7564 { 7565 return $this->value; 7566 } 7567 else 7568 { 7569 return null; 7570 } 7571 } 7572} 7573 7574class SimplePie_Restriction 7575{ 7576 var $relationship; 7577 var $type; 7578 var $value; 7579 7580 // Constructor, used to input the data 7581 function SimplePie_Restriction($relationship = null, $type = null, $value = null) 7582 { 7583 $this->relationship = $relationship; 7584 $this->type = $type; 7585 $this->value = $value; 7586 } 7587 7588 function __toString() 7589 { 7590 // There is no $this->data here 7591 return md5(serialize($this)); 7592 } 7593 7594 function get_relationship() 7595 { 7596 if ($this->relationship !== null) 7597 { 7598 return $this->relationship; 7599 } 7600 else 7601 { 7602 return null; 7603 } 7604 } 7605 7606 function get_type() 7607 { 7608 if ($this->type !== null) 7609 { 7610 return $this->type; 7611 } 7612 else 7613 { 7614 return null; 7615 } 7616 } 7617 7618 function get_value() 7619 { 7620 if ($this->value !== null) 7621 { 7622 return $this->value; 7623 } 7624 else 7625 { 7626 return null; 7627 } 7628 } 7629} 7630 7631/** 7632 * @todo Move to properly supporting RFC2616 (HTTP/1.1) 7633 */ 7634class SimplePie_File 7635{ 7636 var $url; 7637 var $useragent; 7638 var $success = true; 7639 var $headers = array(); 7640 var $body; 7641 var $status_code; 7642 var $redirects = 0; 7643 var $error; 7644 var $method = SIMPLEPIE_FILE_SOURCE_NONE; 7645 7646 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) 7647 { 7648 if (class_exists('idna_convert')) 7649 { 7650 $idn =& new idna_convert; 7651 $parsed = SimplePie_Misc::parse_url($url); 7652 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); 7653 } 7654 $this->url = $url; 7655 $this->useragent = $useragent; 7656 if (preg_match('/^http(s)?:\/\//i', $url)) 7657 { 7658 if ($useragent === null) 7659 { 7660 $useragent = ini_get('user_agent'); 7661 $this->useragent = $useragent; 7662 } 7663 if (!is_array($headers)) 7664 { 7665 $headers = array(); 7666 } 7667 if (!$force_fsockopen && function_exists('curl_exec')) 7668 { 7669 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL; 7670 $fp = curl_init(); 7671 $headers2 = array(); 7672 foreach ($headers as $key => $value) 7673 { 7674 $headers2[] = "$key: $value"; 7675 } 7676 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>=')) 7677 { 7678 curl_setopt($fp, CURLOPT_ENCODING, ''); 7679 } 7680 curl_setopt($fp, CURLOPT_URL, $url); 7681 curl_setopt($fp, CURLOPT_HEADER, 1); 7682 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1); 7683 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout); 7684 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout); 7685 curl_setopt($fp, CURLOPT_REFERER, $url); 7686 curl_setopt($fp, CURLOPT_USERAGENT, $useragent); 7687 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); 7688 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>=')) 7689 { 7690 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1); 7691 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects); 7692 } 7693 7694 $this->headers = curl_exec($fp); 7695 if (curl_errno($fp) === 23 || curl_errno($fp) === 61) 7696 { 7697 curl_setopt($fp, CURLOPT_ENCODING, 'none'); 7698 $this->headers = curl_exec($fp); 7699 } 7700 if (curl_errno($fp)) 7701 { 7702 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp); 7703 $this->success = false; 7704 } 7705 else 7706 { 7707 $info = curl_getinfo($fp); 7708 curl_close($fp); 7709 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1); 7710 $this->headers = array_pop($this->headers); 7711 $parser =& new SimplePie_HTTP_Parser($this->headers); 7712 if ($parser->parse()) 7713 { 7714 $this->headers = $parser->headers; 7715 $this->body = $parser->body; 7716 $this->status_code = $parser->status_code; 7717 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) 7718 { 7719 $this->redirects++; 7720 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); 7721 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); 7722 } 7723 } 7724 } 7725 } 7726 else 7727 { 7728 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN; 7729 $url_parts = parse_url($url); 7730 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') 7731 { 7732 $url_parts['host'] = "ssl://$url_parts[host]"; 7733 $url_parts['port'] = 443; 7734 } 7735 if (!isset($url_parts['port'])) 7736 { 7737 $url_parts['port'] = 80; 7738 } 7739 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout); 7740 if (!$fp) 7741 { 7742 $this->error = 'fsockopen error: ' . $errstr; 7743 $this->success = false; 7744 } 7745 else 7746 { 7747 stream_set_timeout($fp, $timeout); 7748 if (isset($url_parts['path'])) 7749 { 7750 if (isset($url_parts['query'])) 7751 { 7752 $get = "$url_parts[path]?$url_parts[query]"; 7753 } 7754 else 7755 { 7756 $get = $url_parts['path']; 7757 } 7758 } 7759 else 7760 { 7761 $get = '/'; 7762 } 7763 $out = "GET $get HTTP/1.0\r\n"; 7764 $out .= "Host: $url_parts[host]\r\n"; 7765 $out .= "User-Agent: $useragent\r\n"; 7766 if (extension_loaded('zlib')) 7767 { 7768 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n"; 7769 } 7770 7771 if (isset($url_parts['user']) && isset($url_parts['pass'])) 7772 { 7773 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n"; 7774 } 7775 foreach ($headers as $key => $value) 7776 { 7777 $out .= "$key: $value\r\n"; 7778 } 7779 $out .= "Connection: Close\r\n\r\n"; 7780 fwrite($fp, $out); 7781 7782 $info = stream_get_meta_data($fp); 7783 7784 $this->headers = ''; 7785 while (!$info['eof'] && !$info['timed_out']) 7786 { 7787 $this->headers .= fread($fp, 1160); 7788 $info = stream_get_meta_data($fp); 7789 } 7790 if (!$info['timed_out']) 7791 { 7792 $parser =& new SimplePie_HTTP_Parser($this->headers); 7793 if ($parser->parse()) 7794 { 7795 $this->headers = $parser->headers; 7796 $this->body = $parser->body; 7797 $this->status_code = $parser->status_code; 7798 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) 7799 { 7800 $this->redirects++; 7801 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); 7802 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); 7803 } 7804 if (isset($this->headers['content-encoding'])) 7805 { 7806 // Hey, we act dumb elsewhere, so let's do that here too 7807 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20"))) 7808 { 7809 case 'gzip': 7810 case 'x-gzip': 7811 $decoder =& new SimplePie_gzdecode($this->body); 7812 if (!$decoder->parse()) 7813 { 7814 $this->error = 'Unable to decode HTTP "gzip" stream'; 7815 $this->success = false; 7816 } 7817 else 7818 { 7819 $this->body = $decoder->data; 7820 } 7821 break; 7822 7823 case 'deflate': 7824 if (($body = gzuncompress($this->body)) === false) 7825 { 7826 if (($body = gzinflate($this->body)) === false) 7827 { 7828 $this->error = 'Unable to decode HTTP "deflate" stream'; 7829 $this->success = false; 7830 } 7831 } 7832 $this->body = $body; 7833 break; 7834 7835 default: 7836 $this->error = 'Unknown content coding'; 7837 $this->success = false; 7838 } 7839 } 7840 } 7841 } 7842 else 7843 { 7844 $this->error = 'fsocket timed out'; 7845 $this->success = false; 7846 } 7847 fclose($fp); 7848 } 7849 } 7850 } 7851 else 7852 { 7853 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS; 7854 if (!$this->body = file_get_contents($url)) 7855 { 7856 $this->error = 'file_get_contents could not read the file'; 7857 $this->success = false; 7858 } 7859 } 7860 } 7861} 7862 7863/** 7864 * HTTP Response Parser 7865 * 7866 * @package SimplePie 7867 */ 7868class SimplePie_HTTP_Parser 7869{ 7870 /** 7871 * HTTP Version 7872 * 7873 * @access public 7874 * @var float 7875 */ 7876 var $http_version = 0.0; 7877 7878 /** 7879 * Status code 7880 * 7881 * @access public 7882 * @var int 7883 */ 7884 var $status_code = 0; 7885 7886 /** 7887 * Reason phrase 7888 * 7889 * @access public 7890 * @var string 7891 */ 7892 var $reason = ''; 7893 7894 /** 7895 * Key/value pairs of the headers 7896 * 7897 * @access public 7898 * @var array 7899 */ 7900 var $headers = array(); 7901 7902 /** 7903 * Body of the response 7904 * 7905 * @access public 7906 * @var string 7907 */ 7908 var $body = ''; 7909 7910 /** 7911 * Current state of the state machine 7912 * 7913 * @access private 7914 * @var string 7915 */ 7916 var $state = 'http_version'; 7917 7918 /** 7919 * Input data 7920 * 7921 * @access private 7922 * @var string 7923 */ 7924 var $data = ''; 7925 7926 /** 7927 * Input data length (to avoid calling strlen() everytime this is needed) 7928 * 7929 * @access private 7930 * @var int 7931 */ 7932 var $data_length = 0; 7933 7934 /** 7935 * Current position of the pointer 7936 * 7937 * @var int 7938 * @access private 7939 */ 7940 var $position = 0; 7941 7942 /** 7943 * Name of the hedaer currently being parsed 7944 * 7945 * @access private 7946 * @var string 7947 */ 7948 var $name = ''; 7949 7950 /** 7951 * Value of the hedaer currently being parsed 7952 * 7953 * @access private 7954 * @var string 7955 */ 7956 var $value = ''; 7957 7958 /** 7959 * Create an instance of the class with the input data 7960 * 7961 * @access public 7962 * @param string $data Input data 7963 */ 7964 function SimplePie_HTTP_Parser($data) 7965 { 7966 $this->data = $data; 7967 $this->data_length = strlen($this->data); 7968 } 7969 7970 /** 7971 * Parse the input data 7972 * 7973 * @access public 7974 * @return bool true on success, false on failure 7975 */ 7976 function parse() 7977 { 7978 while ($this->state && $this->state !== 'emit' && $this->has_data()) 7979 { 7980 $state = $this->state; 7981 $this->$state(); 7982 } 7983 $this->data = ''; 7984 if ($this->state === 'emit' || $this->state === 'body') 7985 { 7986 return true; 7987 } 7988 else 7989 { 7990 $this->http_version = ''; 7991 $this->status_code = ''; 7992 $this->reason = ''; 7993 $this->headers = array(); 7994 $this->body = ''; 7995 return false; 7996 } 7997 } 7998 7999 /** 8000 * Check whether there is data beyond the pointer 8001 * 8002 * @access private 8003 * @return bool true if there is further data, false if not 8004 */ 8005 function has_data() 8006 { 8007 return (bool) ($this->position < $this->data_length); 8008 } 8009 8010 /** 8011 * See if the next character is LWS 8012 * 8013 * @access private 8014 * @return bool true if the next character is LWS, false if not 8015 */ 8016 function is_linear_whitespace() 8017 { 8018 return (bool) ($this->data[$this->position] === "\x09" 8019 || $this->data[$this->position] === "\x20" 8020 || ($this->data[$this->position] === "\x0A" 8021 && isset($this->data[$this->position + 1]) 8022 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20"))); 8023 } 8024 8025 /** 8026 * Parse the HTTP version 8027 * 8028 * @access private 8029 */ 8030 function http_version() 8031 { 8032 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/') 8033 { 8034 $len = strspn($this->data, '0123456789.', 5); 8035 $this->http_version = substr($this->data, 5, $len); 8036 $this->position += 5 + $len; 8037 if (substr_count($this->http_version, '.') <= 1) 8038 { 8039 $this->http_version = (float) $this->http_version; 8040 $this->position += strspn($this->data, "\x09\x20", $this->position); 8041 $this->state = 'status'; 8042 } 8043 else 8044 { 8045 $this->state = false; 8046 } 8047 } 8048 else 8049 { 8050 $this->state = false; 8051 } 8052 } 8053 8054 /** 8055 * Parse the status code 8056 * 8057 * @access private 8058 */ 8059 function status() 8060 { 8061 if ($len = strspn($this->data, '0123456789', $this->position)) 8062 { 8063 $this->status_code = (int) substr($this->data, $this->position, $len); 8064 $this->position += $len; 8065 $this->state = 'reason'; 8066 } 8067 else 8068 { 8069 $this->state = false; 8070 } 8071 } 8072 8073 /** 8074 * Parse the reason phrase 8075 * 8076 * @access private 8077 */ 8078 function reason() 8079 { 8080 $len = strcspn($this->data, "\x0A", $this->position); 8081 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20"); 8082 $this->position += $len + 1; 8083 $this->state = 'new_line'; 8084 } 8085 8086 /** 8087 * Deal with a new line, shifting data around as needed 8088 * 8089 * @access private 8090 */ 8091 function new_line() 8092 { 8093 $this->value = trim($this->value, "\x0D\x20"); 8094 if ($this->name !== '' && $this->value !== '') 8095 { 8096 $this->name = strtolower($this->name); 8097 if (isset($this->headers[$this->name])) 8098 { 8099 $this->headers[$this->name] .= ', ' . $this->value; 8100 } 8101 else 8102 { 8103 $this->headers[$this->name] = $this->value; 8104 } 8105 } 8106 $this->name = ''; 8107 $this->value = ''; 8108 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A") 8109 { 8110 $this->position += 2; 8111 $this->state = 'body'; 8112 } 8113 elseif ($this->data[$this->position] === "\x0A") 8114 { 8115 $this->position++; 8116 $this->state = 'body'; 8117 } 8118 else 8119 { 8120 $this->state = 'name'; 8121 } 8122 } 8123 8124 /** 8125 * Parse a header name 8126 * 8127 * @access private 8128 */ 8129 function name() 8130 { 8131 $len = strcspn($this->data, "\x0A:", $this->position); 8132 if (isset($this->data[$this->position + $len])) 8133 { 8134 if ($this->data[$this->position + $len] === "\x0A") 8135 { 8136 $this->position += $len; 8137 $this->state = 'new_line'; 8138 } 8139 else 8140 { 8141 $this->name = substr($this->data, $this->position, $len); 8142 $this->position += $len + 1; 8143 $this->state = 'value'; 8144 } 8145 } 8146 else 8147 { 8148 $this->state = false; 8149 } 8150 } 8151 8152 /** 8153 * Parse LWS, replacing consecutive LWS characters with a single space 8154 * 8155 * @access private 8156 */ 8157 function linear_whitespace() 8158 { 8159 do 8160 { 8161 if (substr($this->data, $this->position, 2) === "\x0D\x0A") 8162 { 8163 $this->position += 2; 8164 } 8165 elseif ($this->data[$this->position] === "\x0A") 8166 { 8167 $this->position++; 8168 } 8169 $this->position += strspn($this->data, "\x09\x20", $this->position); 8170 } while ($this->has_data() && $this->is_linear_whitespace()); 8171 $this->value .= "\x20"; 8172 } 8173 8174 /** 8175 * See what state to move to while within non-quoted header values 8176 * 8177 * @access private 8178 */ 8179 function value() 8180 { 8181 if ($this->is_linear_whitespace()) 8182 { 8183 $this->linear_whitespace(); 8184 } 8185 else 8186 { 8187 switch ($this->data[$this->position]) 8188 { 8189 case '"': 8190 $this->position++; 8191 $this->state = 'quote'; 8192 break; 8193 8194 case "\x0A": 8195 $this->position++; 8196 $this->state = 'new_line'; 8197 break; 8198 8199 default: 8200 $this->state = 'value_char'; 8201 break; 8202 } 8203 } 8204 } 8205 8206 /** 8207 * Parse a header value while outside quotes 8208 * 8209 * @access private 8210 */ 8211 function value_char() 8212 { 8213 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position); 8214 $this->value .= substr($this->data, $this->position, $len); 8215 $this->position += $len; 8216 $this->state = 'value'; 8217 } 8218 8219 /** 8220 * See what state to move to while within quoted header values 8221 * 8222 * @access private 8223 */ 8224 function quote() 8225 { 8226 if ($this->is_linear_whitespace()) 8227 { 8228 $this->linear_whitespace(); 8229 } 8230 else 8231 { 8232 switch ($this->data[$this->position]) 8233 { 8234 case '"': 8235 $this->position++; 8236 $this->state = 'value'; 8237 break; 8238 8239 case "\x0A": 8240 $this->position++; 8241 $this->state = 'new_line'; 8242 break; 8243 8244 case '\\': 8245 $this->position++; 8246 $this->state = 'quote_escaped'; 8247 break; 8248 8249 default: 8250 $this->state = 'quote_char'; 8251 break; 8252 } 8253 } 8254 } 8255 8256 /** 8257 * Parse a header value while within quotes 8258 * 8259 * @access private 8260 */ 8261 function quote_char() 8262 { 8263 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position); 8264 $this->value .= substr($this->data, $this->position, $len); 8265 $this->position += $len; 8266 $this->state = 'value'; 8267 } 8268 8269 /** 8270 * Parse an escaped character within quotes 8271 * 8272 * @access private 8273 */ 8274 function quote_escaped() 8275 { 8276 $this->value .= $this->data[$this->position]; 8277 $this->position++; 8278 $this->state = 'quote'; 8279 } 8280 8281 /** 8282 * Parse the body 8283 * 8284 * @access private 8285 */ 8286 function body() 8287 { 8288 $this->body = substr($this->data, $this->position); 8289 $this->state = 'emit'; 8290 } 8291} 8292 8293/** 8294 * gzdecode 8295 * 8296 * @package SimplePie 8297 */ 8298class SimplePie_gzdecode 8299{ 8300 /** 8301 * Compressed data 8302 * 8303 * @access private 8304 * @see gzdecode::$data 8305 */ 8306 var $compressed_data; 8307 8308 /** 8309 * Size of compressed data 8310 * 8311 * @access private 8312 */ 8313 var $compressed_size; 8314 8315 /** 8316 * Minimum size of a valid gzip string 8317 * 8318 * @access private 8319 */ 8320 var $min_compressed_size = 18; 8321 8322 /** 8323 * Current position of pointer 8324 * 8325 * @access private 8326 */ 8327 var $position = 0; 8328 8329 /** 8330 * Flags (FLG) 8331 * 8332 * @access private 8333 */ 8334 var $flags; 8335 8336 /** 8337 * Uncompressed data 8338 * 8339 * @access public 8340 * @see gzdecode::$compressed_data 8341 */ 8342 var $data; 8343 8344 /** 8345 * Modified time 8346 * 8347 * @access public 8348 */ 8349 var $MTIME; 8350 8351 /** 8352 * Extra Flags 8353 * 8354 * @access public 8355 */ 8356 var $XFL; 8357 8358 /** 8359 * Operating System 8360 * 8361 * @access public 8362 */ 8363 var $OS; 8364 8365 /** 8366 * Subfield ID 1 8367 * 8368 * @access public 8369 * @see gzdecode::$extra_field 8370 * @see gzdecode::$SI2 8371 */ 8372 var $SI1; 8373 8374 /** 8375 * Subfield ID 2 8376 * 8377 * @access public 8378 * @see gzdecode::$extra_field 8379 * @see gzdecode::$SI1 8380 */ 8381 var $SI2; 8382 8383 /** 8384 * Extra field content 8385 * 8386 * @access public 8387 * @see gzdecode::$SI1 8388 * @see gzdecode::$SI2 8389 */ 8390 var $extra_field; 8391 8392 /** 8393 * Original filename 8394 * 8395 * @access public 8396 */ 8397 var $filename; 8398 8399 /** 8400 * Human readable comment 8401 * 8402 * @access public 8403 */ 8404 var $comment; 8405 8406 /** 8407 * Don't allow anything to be set 8408 * 8409 * @access public 8410 */ 8411 function __set($name, $value) 8412 { 8413 trigger_error("Cannot write property $name", E_USER_ERROR); 8414 } 8415 8416 /** 8417 * Set the compressed string and related properties 8418 * 8419 * @access public 8420 */ 8421 function SimplePie_gzdecode($data) 8422 { 8423 $this->compressed_data = $data; 8424 $this->compressed_size = strlen($data); 8425 } 8426 8427 /** 8428 * Decode the GZIP stream 8429 * 8430 * @access public 8431 */ 8432 function parse() 8433 { 8434 if ($this->compressed_size >= $this->min_compressed_size) 8435 { 8436 // Check ID1, ID2, and CM 8437 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08") 8438 { 8439 return false; 8440 } 8441 8442 // Get the FLG (FLaGs) 8443 $this->flags = ord($this->compressed_data[3]); 8444 8445 // FLG bits above (1 << 4) are reserved 8446 if ($this->flags > 0x1F) 8447 { 8448 return false; 8449 } 8450 8451 // Advance the pointer after the above 8452 $this->position += 4; 8453 8454 // MTIME 8455 $mtime = substr($this->compressed_data, $this->position, 4); 8456 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness 8457 if (current(unpack('S', "\x00\x01")) === 1) 8458 { 8459 $mtime = strrev($mtime); 8460 } 8461 $this->MTIME = current(unpack('l', $mtime)); 8462 $this->position += 4; 8463 8464 // Get the XFL (eXtra FLags) 8465 $this->XFL = ord($this->compressed_data[$this->position++]); 8466 8467 // Get the OS (Operating System) 8468 $this->OS = ord($this->compressed_data[$this->position++]); 8469 8470 // Parse the FEXTRA 8471 if ($this->flags & 4) 8472 { 8473 // Read subfield IDs 8474 $this->SI1 = $this->compressed_data[$this->position++]; 8475 $this->SI2 = $this->compressed_data[$this->position++]; 8476 8477 // SI2 set to zero is reserved for future use 8478 if ($this->SI2 === "\x00") 8479 { 8480 return false; 8481 } 8482 8483 // Get the length of the extra field 8484 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2))); 8485 $position += 2; 8486 8487 // Check the length of the string is still valid 8488 $this->min_compressed_size += $len + 4; 8489 if ($this->compressed_size >= $this->min_compressed_size) 8490 { 8491 // Set the extra field to the given data 8492 $this->extra_field = substr($this->compressed_data, $this->position, $len); 8493 $this->position += $len; 8494 } 8495 else 8496 { 8497 return false; 8498 } 8499 } 8500 8501 // Parse the FNAME 8502 if ($this->flags & 8) 8503 { 8504 // Get the length of the filename 8505 $len = strcspn($this->compressed_data, "\x00", $this->position); 8506 8507 // Check the length of the string is still valid 8508 $this->min_compressed_size += $len + 1; 8509 if ($this->compressed_size >= $this->min_compressed_size) 8510 { 8511 // Set the original filename to the given string 8512 $this->filename = substr($this->compressed_data, $this->position, $len); 8513 $this->position += $len + 1; 8514 } 8515 else 8516 { 8517 return false; 8518 } 8519 } 8520 8521 // Parse the FCOMMENT 8522 if ($this->flags & 16) 8523 { 8524 // Get the length of the comment 8525 $len = strcspn($this->compressed_data, "\x00", $this->position); 8526 8527 // Check the length of the string is still valid 8528 $this->min_compressed_size += $len + 1; 8529 if ($this->compressed_size >= $this->min_compressed_size) 8530 { 8531 // Set the original comment to the given string 8532 $this->comment = substr($this->compressed_data, $this->position, $len); 8533 $this->position += $len + 1; 8534 } 8535 else 8536 { 8537 return false; 8538 } 8539 } 8540 8541 // Parse the FHCRC 8542 if ($this->flags & 2) 8543 { 8544 // Check the length of the string is still valid 8545 $this->min_compressed_size += $len + 2; 8546 if ($this->compressed_size >= $this->min_compressed_size) 8547 { 8548 // Read the CRC 8549 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2))); 8550 8551 // Check the CRC matches 8552 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc) 8553 { 8554 $this->position += 2; 8555 } 8556 else 8557 { 8558 return false; 8559 } 8560 } 8561 else 8562 { 8563 return false; 8564 } 8565 } 8566 8567 // Decompress the actual data 8568 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false) 8569 { 8570 return false; 8571 } 8572 else 8573 { 8574 $this->position = $this->compressed_size - 8; 8575 } 8576 8577 // Check CRC of data 8578 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4))); 8579 $this->position += 4; 8580 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc)) 8581 { 8582 return false; 8583 }*/ 8584 8585 // Check ISIZE of data 8586 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4))); 8587 $this->position += 4; 8588 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize)) 8589 { 8590 return false; 8591 } 8592 8593 // Wow, against all odds, we've actually got a valid gzip string 8594 return true; 8595 } 8596 else 8597 { 8598 return false; 8599 } 8600 } 8601} 8602 8603class SimplePie_Cache 8604{ 8605 /** 8606 * Don't call the constructor. Please. 8607 * 8608 * @access private 8609 */ 8610 function SimplePie_Cache() 8611 { 8612 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR); 8613 } 8614 8615 /** 8616 * Create a new SimplePie_Cache object 8617 * 8618 * @static 8619 * @access public 8620 */ 8621 function create($location, $filename, $extension) 8622 { 8623 $location_iri =& new SimplePie_IRI($location); 8624 switch ($location_iri->get_scheme()) 8625 { 8626 case 'mysql': 8627 if (extension_loaded('mysql')) 8628 { 8629 return new SimplePie_Cache_MySQL($location_iri, $filename, $extension); 8630 } 8631 break; 8632 8633 default: 8634 return new SimplePie_Cache_File($location, $filename, $extension); 8635 } 8636 } 8637} 8638 8639class SimplePie_Cache_File 8640{ 8641 var $location; 8642 var $filename; 8643 var $extension; 8644 var $name; 8645 8646 function SimplePie_Cache_File($location, $filename, $extension) 8647 { 8648 $this->location = $location; 8649 $this->filename = $filename; 8650 $this->extension = $extension; 8651 $this->name = "$this->location/$this->filename.$this->extension"; 8652 } 8653 8654 function save($data) 8655 { 8656 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location)) 8657 { 8658 if (is_a($data, 'SimplePie')) 8659 { 8660 $data = $data->data; 8661 } 8662 8663 $data = serialize($data); 8664 8665 if (function_exists('file_put_contents')) 8666 { 8667 return (bool) file_put_contents($this->name, $data); 8668 } 8669 else 8670 { 8671 $fp = fopen($this->name, 'wb'); 8672 if ($fp) 8673 { 8674 fwrite($fp, $data); 8675 fclose($fp); 8676 return true; 8677 } 8678 } 8679 } 8680 return false; 8681 } 8682 8683 function load() 8684 { 8685 if (file_exists($this->name) && is_readable($this->name)) 8686 { 8687 return unserialize(file_get_contents($this->name)); 8688 } 8689 return false; 8690 } 8691 8692 function mtime() 8693 { 8694 if (file_exists($this->name)) 8695 { 8696 return filemtime($this->name); 8697 } 8698 return false; 8699 } 8700 8701 function touch() 8702 { 8703 if (file_exists($this->name)) 8704 { 8705 return touch($this->name); 8706 } 8707 return false; 8708 } 8709 8710 function unlink() 8711 { 8712 if (file_exists($this->name)) 8713 { 8714 return unlink($this->name); 8715 } 8716 return false; 8717 } 8718} 8719 8720class SimplePie_Cache_DB 8721{ 8722 function prepare_simplepie_object_for_cache($data) 8723 { 8724 $items = $data->get_items(); 8725 $items_by_id = array(); 8726 8727 if (!empty($items)) 8728 { 8729 foreach ($items as $item) 8730 { 8731 $items_by_id[$item->get_id()] = $item; 8732 } 8733 8734 if (count($items_by_id) !== count($items)) 8735 { 8736 $items_by_id = array(); 8737 foreach ($items as $item) 8738 { 8739 $items_by_id[$item->get_id(true)] = $item; 8740 } 8741 } 8742 8743 if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0])) 8744 { 8745 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]; 8746 } 8747 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0])) 8748 { 8749 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]; 8750 } 8751 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0])) 8752 { 8753 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]; 8754 } 8755 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0])) 8756 { 8757 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]; 8758 } 8759 else 8760 { 8761 $channel = null; 8762 } 8763 8764 if ($channel !== null) 8765 { 8766 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'])) 8767 { 8768 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']); 8769 } 8770 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry'])) 8771 { 8772 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']); 8773 } 8774 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])) 8775 { 8776 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']); 8777 } 8778 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])) 8779 { 8780 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']); 8781 } 8782 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item'])) 8783 { 8784 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']); 8785 } 8786 } 8787 if (isset($data->data['items'])) 8788 { 8789 unset($data->data['items']); 8790 } 8791 if (isset($data->data['ordered_items'])) 8792 { 8793 unset($data->data['ordered_items']); 8794 } 8795 } 8796 return array(serialize($data->data), $items_by_id); 8797 } 8798} 8799 8800class SimplePie_Cache_MySQL extends SimplePie_Cache_DB 8801{ 8802 var $mysql; 8803 var $options; 8804 var $id; 8805 8806 function SimplePie_Cache_MySQL($mysql_location, $name, $extension) 8807 { 8808 $host = $mysql_location->get_host(); 8809 if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')') 8810 { 8811 $server = ':' . substr($host, 5, -1); 8812 } 8813 else 8814 { 8815 $server = $host; 8816 if ($mysql_location->get_port() !== null) 8817 { 8818 $server .= ':' . $mysql_location->get_port(); 8819 } 8820 } 8821 8822 if (strpos($mysql_location->get_userinfo(), ':') !== false) 8823 { 8824 list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2); 8825 } 8826 else 8827 { 8828 $username = $mysql_location->get_userinfo(); 8829 $password = null; 8830 } 8831 8832 if ($this->mysql = mysql_connect($server, $username, $password)) 8833 { 8834 $this->id = $name . $extension; 8835 $this->options = SimplePie_Misc::parse_str($mysql_location->get_query()); 8836 if (!isset($this->options['prefix'][0])) 8837 { 8838 $this->options['prefix'][0] = ''; 8839 } 8840 8841 if (mysql_select_db(ltrim($mysql_location->get_path(), '/')) 8842 && mysql_query('SET NAMES utf8') 8843 && ($query = mysql_unbuffered_query('SHOW TABLES'))) 8844 { 8845 $db = array(); 8846 while ($row = mysql_fetch_row($query)) 8847 { 8848 $db[] = $row[0]; 8849 } 8850 8851 if (!in_array($this->options['prefix'][0] . 'cache_data', $db)) 8852 { 8853 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)))')) 8854 { 8855 $this->mysql = null; 8856 } 8857 } 8858 8859 if (!in_array($this->options['prefix'][0] . 'items', $db)) 8860 { 8861 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)))')) 8862 { 8863 $this->mysql = null; 8864 } 8865 } 8866 } 8867 else 8868 { 8869 $this->mysql = null; 8870 } 8871 } 8872 } 8873 8874 function save($data) 8875 { 8876 if ($this->mysql) 8877 { 8878 $feed_id = "'" . mysql_real_escape_string($this->id) . "'"; 8879 8880 if (is_a($data, 'SimplePie')) 8881 { 8882 if (SIMPLEPIE_PHP5) 8883 { 8884 // This keyword needs to defy coding standards for PHP4 compatibility 8885 $data = clone($data); 8886 } 8887 8888 $prepared = $this->prepare_simplepie_object_for_cache($data); 8889 8890 if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql)) 8891 { 8892 if (mysql_num_rows($query)) 8893 { 8894 $items = count($prepared[1]); 8895 if ($items) 8896 { 8897 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id; 8898 } 8899 else 8900 { 8901 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id; 8902 } 8903 8904 if (!mysql_query($sql, $this->mysql)) 8905 { 8906 return false; 8907 } 8908 } 8909 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)) 8910 { 8911 return false; 8912 } 8913 8914 $ids = array_keys($prepared[1]); 8915 if (!empty($ids)) 8916 { 8917 foreach ($ids as $id) 8918 { 8919 $database_ids[] = mysql_real_escape_string($id); 8920 } 8921 8922 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)) 8923 { 8924 $existing_ids = array(); 8925 while ($row = mysql_fetch_row($query)) 8926 { 8927 $existing_ids[] = $row[0]; 8928 } 8929 8930 $new_ids = array_diff($ids, $existing_ids); 8931 8932 foreach ($new_ids as $new_id) 8933 { 8934 if (!($date = $prepared[1][$new_id]->get_date('U'))) 8935 { 8936 $date = time(); 8937 } 8938 8939 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)) 8940 { 8941 return false; 8942 } 8943 } 8944 return true; 8945 } 8946 } 8947 else 8948 { 8949 return true; 8950 } 8951 } 8952 } 8953 elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql)) 8954 { 8955 if (mysql_num_rows($query)) 8956 { 8957 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)) 8958 { 8959 return true; 8960 } 8961 } 8962 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)) 8963 { 8964 return true; 8965 } 8966 } 8967 } 8968 return false; 8969 } 8970 8971 function load() 8972 { 8973 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))) 8974 { 8975 $data = unserialize($row[1]); 8976 8977 if (isset($this->options['items'][0])) 8978 { 8979 $items = (int) $this->options['items'][0]; 8980 } 8981 else 8982 { 8983 $items = (int) $row[0]; 8984 } 8985 8986 if ($items !== 0) 8987 { 8988 if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0])) 8989 { 8990 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]; 8991 } 8992 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0])) 8993 { 8994 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]; 8995 } 8996 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0])) 8997 { 8998 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]; 8999 } 9000 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0])) 9001 { 9002 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]; 9003 } 9004 else 9005 { 9006 $feed = null; 9007 } 9008 9009 if ($feed !== null) 9010 { 9011 $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC'; 9012 if ($items > 0) 9013 { 9014 $sql .= ' LIMIT ' . $items; 9015 } 9016 9017 if ($query = mysql_unbuffered_query($sql, $this->mysql)) 9018 { 9019 while ($row = mysql_fetch_row($query)) 9020 { 9021 $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]); 9022 } 9023 } 9024 else 9025 { 9026 return false; 9027 } 9028 } 9029 } 9030 return $data; 9031 } 9032 return false; 9033 } 9034 9035 function mtime() 9036 { 9037 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))) 9038 { 9039 return $row[0]; 9040 } 9041 else 9042 { 9043 return false; 9044 } 9045 } 9046 9047 function touch() 9048 { 9049 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)) 9050 { 9051 return true; 9052 } 9053 else 9054 { 9055 return false; 9056 } 9057 } 9058 9059 function unlink() 9060 { 9061 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))) 9062 { 9063 return true; 9064 } 9065 else 9066 { 9067 return false; 9068 } 9069 } 9070} 9071 9072class SimplePie_Misc 9073{ 9074 function time_hms($seconds) 9075 { 9076 $time = ''; 9077 9078 $hours = floor($seconds / 3600); 9079 $remainder = $seconds % 3600; 9080 if ($hours > 0) 9081 { 9082 $time .= $hours.':'; 9083 } 9084 9085 $minutes = floor($remainder / 60); 9086 $seconds = $remainder % 60; 9087 if ($minutes < 10 && $hours > 0) 9088 { 9089 $minutes = '0' . $minutes; 9090 } 9091 if ($seconds < 10) 9092 { 9093 $seconds = '0' . $seconds; 9094 } 9095 9096 $time .= $minutes.':'; 9097 $time .= $seconds; 9098 9099 return $time; 9100 } 9101 9102 function absolutize_url($relative, $base) 9103 { 9104 $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative); 9105 return $iri->get_iri(); 9106 } 9107 9108 function remove_dot_segments($input) 9109 { 9110 $output = ''; 9111 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..') 9112 { 9113 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise, 9114 if (strpos($input, '../') === 0) 9115 { 9116 $input = substr($input, 3); 9117 } 9118 elseif (strpos($input, './') === 0) 9119 { 9120 $input = substr($input, 2); 9121 } 9122 // 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, 9123 elseif (strpos($input, '/./') === 0) 9124 { 9125 $input = substr_replace($input, '/', 0, 3); 9126 } 9127 elseif ($input === '/.') 9128 { 9129 $input = '/'; 9130 } 9131 // 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, 9132 elseif (strpos($input, '/../') === 0) 9133 { 9134 $input = substr_replace($input, '/', 0, 4); 9135 $output = substr_replace($output, '', strrpos($output, '/')); 9136 } 9137 elseif ($input === '/..') 9138 { 9139 $input = '/'; 9140 $output = substr_replace($output, '', strrpos($output, '/')); 9141 } 9142 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise, 9143 elseif ($input === '.' || $input === '..') 9144 { 9145 $input = ''; 9146 } 9147 // 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 9148 elseif (($pos = strpos($input, '/', 1)) !== false) 9149 { 9150 $output .= substr($input, 0, $pos); 9151 $input = substr_replace($input, '', 0, $pos); 9152 } 9153 else 9154 { 9155 $output .= $input; 9156 $input = ''; 9157 } 9158 } 9159 return $output . $input; 9160 } 9161 9162 function get_element($realname, $string) 9163 { 9164 $return = array(); 9165 $name = preg_quote($realname, '/'); 9166 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) 9167 { 9168 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++) 9169 { 9170 $return[$i]['tag'] = $realname; 9171 $return[$i]['full'] = $matches[$i][0][0]; 9172 $return[$i]['offset'] = $matches[$i][0][1]; 9173 if (strlen($matches[$i][3][0]) <= 2) 9174 { 9175 $return[$i]['self_closing'] = true; 9176 } 9177 else 9178 { 9179 $return[$i]['self_closing'] = false; 9180 $return[$i]['content'] = $matches[$i][4][0]; 9181 } 9182 $return[$i]['attribs'] = array(); 9183 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)) 9184 { 9185 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++) 9186 { 9187 if (count($attribs[$j]) === 2) 9188 { 9189 $attribs[$j][2] = $attribs[$j][1]; 9190 } 9191 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8'); 9192 } 9193 } 9194 } 9195 } 9196 return $return; 9197 } 9198 9199 function element_implode($element) 9200 { 9201 $full = "<$element[tag]"; 9202 foreach ($element['attribs'] as $key => $value) 9203 { 9204 $key = strtolower($key); 9205 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"'; 9206 } 9207 if ($element['self_closing']) 9208 { 9209 $full .= ' />'; 9210 } 9211 else 9212 { 9213 $full .= ">$element[content]</$element[tag]>"; 9214 } 9215 return $full; 9216 } 9217 9218 function error($message, $level, $file, $line) 9219 { 9220 if ((ini_get('error_reporting') & $level) > 0) 9221 { 9222 switch ($level) 9223 { 9224 case E_USER_ERROR: 9225 $note = 'PHP Error'; 9226 break; 9227 case E_USER_WARNING: 9228 $note = 'PHP Warning'; 9229 break; 9230 case E_USER_NOTICE: 9231 $note = 'PHP Notice'; 9232 break; 9233 default: 9234 $note = 'Unknown Error'; 9235 break; 9236 } 9237 error_log("$note: $message in $file on line $line", 0); 9238 } 9239 return $message; 9240 } 9241 9242 /** 9243 * If a file has been cached, retrieve and display it. 9244 * 9245 * This is most useful for caching images (get_favicon(), etc.), 9246 * however it works for all cached files. This WILL NOT display ANY 9247 * file/image/page/whatever, but rather only display what has already 9248 * been cached by SimplePie. 9249 * 9250 * @access public 9251 * @see SimplePie::get_favicon() 9252 * @param str $identifier_url URL that is used to identify the content. 9253 * This may or may not be the actual URL of the live content. 9254 * @param str $cache_location Location of SimplePie's cache. Defaults 9255 * to './cache'. 9256 * @param str $cache_extension The file extension that the file was 9257 * cached with. Defaults to 'spc'. 9258 * @param str $cache_class Name of the cache-handling class being used 9259 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left 9260 * as-is unless you've overloaded the class. 9261 * @param str $cache_name_function Obsolete. Exists for backwards 9262 * compatibility reasons only. 9263 */ 9264 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5') 9265 { 9266 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension); 9267 9268 if ($file = $cache->load()) 9269 { 9270 if (isset($file['headers']['content-type'])) 9271 { 9272 header('Content-type:' . $file['headers']['content-type']); 9273 } 9274 else 9275 { 9276 header('Content-type: application/octet-stream'); 9277 } 9278 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days 9279 echo $file['body']; 9280 exit; 9281 } 9282 9283 die('Cached file for ' . $identifier_url . ' cannot be found.'); 9284 } 9285 9286 function fix_protocol($url, $http = 1) 9287 { 9288 $url = SimplePie_Misc::normalize_url($url); 9289 $parsed = SimplePie_Misc::parse_url($url); 9290 if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https') 9291 { 9292 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http); 9293 } 9294 9295 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url)) 9296 { 9297 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http); 9298 } 9299 9300 if ($http === 2 && $parsed['scheme'] !== '') 9301 { 9302 return "feed:$url"; 9303 } 9304 elseif ($http === 3 && strtolower($parsed['scheme']) === 'http') 9305 { 9306 return substr_replace($url, 'podcast', 0, 4); 9307 } 9308 elseif ($http === 4 && strtolower($parsed['scheme']) === 'http') 9309 { 9310 return substr_replace($url, 'itpc', 0, 4); 9311 } 9312 else 9313 { 9314 return $url; 9315 } 9316 } 9317 9318 function parse_url($url) 9319 { 9320 $iri =& new SimplePie_IRI($url); 9321 return array( 9322 'scheme' => (string) $iri->get_scheme(), 9323 'authority' => (string) $iri->get_authority(), 9324 'path' => (string) $iri->get_path(), 9325 'query' => (string) $iri->get_query(), 9326 'fragment' => (string) $iri->get_fragment() 9327 ); 9328 } 9329 9330 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '') 9331 { 9332 $iri =& new SimplePie_IRI(''); 9333 $iri->set_scheme($scheme); 9334 $iri->set_authority($authority); 9335 $iri->set_path($path); 9336 $iri->set_query($query); 9337 $iri->set_fragment($fragment); 9338 return $iri->get_iri(); 9339 } 9340 9341 function normalize_url($url) 9342 { 9343 $iri =& new SimplePie_IRI($url); 9344 return $iri->get_iri(); 9345 } 9346 9347 function percent_encoding_normalization($match) 9348 { 9349 $integer = hexdec($match[1]); 9350 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E) 9351 { 9352 return chr($integer); 9353 } 9354 else 9355 { 9356 return strtoupper($match[0]); 9357 } 9358 } 9359 9360 /** 9361 * Remove bad UTF-8 bytes 9362 * 9363 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C 9364 * FAQ: Multilingual Forms (modified to include full ASCII range) 9365 * 9366 * @author Geoffrey Sneddon 9367 * @see http://www.w3.org/International/questions/qa-forms-utf-8 9368 * @param string $str String to remove bad UTF-8 bytes from 9369 * @return string UTF-8 string 9370 */ 9371 function utf8_bad_replace($str) 9372 { 9373 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str))) 9374 { 9375 return $return; 9376 } 9377 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8'))) 9378 { 9379 return $return; 9380 } 9381 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)) 9382 { 9383 return implode("\xEF\xBF\xBD", $matches[0]); 9384 } 9385 elseif ($str !== '') 9386 { 9387 return "\xEF\xBF\xBD"; 9388 } 9389 else 9390 { 9391 return ''; 9392 } 9393 } 9394 9395 /** 9396 * Converts a Windows-1252 encoded string to a UTF-8 encoded string 9397 * 9398 * @static 9399 * @access public 9400 * @param string $string Windows-1252 encoded string 9401 * @return string UTF-8 encoded string 9402 */ 9403 function windows_1252_to_utf8($string) 9404 { 9405 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"); 9406 9407 return strtr($string, $convert_table); 9408 } 9409 9410 function change_encoding($data, $input, $output) 9411 { 9412 $input = SimplePie_Misc::encoding($input); 9413 $output = SimplePie_Misc::encoding($output); 9414 9415 // We fail to fail on non US-ASCII bytes 9416 if ($input === 'US-ASCII') 9417 { 9418 static $non_ascii_octects = ''; 9419 if (!$non_ascii_octects) 9420 { 9421 for ($i = 0x80; $i <= 0xFF; $i++) 9422 { 9423 $non_ascii_octects .= chr($i); 9424 } 9425 } 9426 $data = substr($data, 0, strcspn($data, $non_ascii_octects)); 9427 } 9428 9429 // This is first, as behaviour of this is completely predictable 9430 if ($input === 'windows-1252' && $output === 'UTF-8') 9431 { 9432 return SimplePie_Misc::windows_1252_to_utf8($data); 9433 } 9434 // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported). 9435 elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && ($return = @mb_convert_encoding($data, $output, $input))) 9436 { 9437 return $return; 9438 } 9439 // This is last, as behaviour of this varies with OS userland and PHP version 9440 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data))) 9441 { 9442 return $return; 9443 } 9444 // If we can't do anything, just fail 9445 else 9446 { 9447 return false; 9448 } 9449 } 9450 9451 function encoding($charset) 9452 { 9453 // Normalization from UTS #22 9454 switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset))) 9455 { 9456 case 'adobestandardencoding': 9457 case 'csadobestandardencoding': 9458 return 'Adobe-Standard-Encoding'; 9459 9460 case 'adobesymbolencoding': 9461 case 'cshppsmath': 9462 return 'Adobe-Symbol-Encoding'; 9463 9464 case 'ami1251': 9465 case 'amiga1251': 9466 return 'Amiga-1251'; 9467 9468 case 'ansix31101983': 9469 case 'csat5001983': 9470 case 'csiso99naplps': 9471 case 'isoir99': 9472 case 'naplps': 9473 return 'ANSI_X3.110-1983'; 9474 9475 case 'arabic7': 9476 case 'asmo449': 9477 case 'csiso89asmo449': 9478 case 'iso9036': 9479 case 'isoir89': 9480 return 'ASMO_449'; 9481 9482 case 'big5': 9483 case 'csbig5': 9484 case 'xxbig5': 9485 return 'Big5'; 9486 9487 case 'big5hkscs': 9488 return 'Big5-HKSCS'; 9489 9490 case 'bocu1': 9491 case 'csbocu1': 9492 return 'BOCU-1'; 9493 9494 case 'brf': 9495 case 'csbrf': 9496 return 'BRF'; 9497 9498 case 'bs4730': 9499 case 'csiso4unitedkingdom': 9500 case 'gb': 9501 case 'iso646gb': 9502 case 'isoir4': 9503 case 'uk': 9504 return 'BS_4730'; 9505 9506 case 'bsviewdata': 9507 case 'csiso47bsviewdata': 9508 case 'isoir47': 9509 return 'BS_viewdata'; 9510 9511 case 'cesu8': 9512 case 'cscesu8': 9513 return 'CESU-8'; 9514 9515 case 'ca': 9516 case 'csa71': 9517 case 'csaz243419851': 9518 case 'csiso121canadian1': 9519 case 'iso646ca': 9520 case 'isoir121': 9521 return 'CSA_Z243.4-1985-1'; 9522 9523 case 'csa72': 9524 case 'csaz243419852': 9525 case 'csiso122canadian2': 9526 case 'iso646ca2': 9527 case 'isoir122': 9528 return 'CSA_Z243.4-1985-2'; 9529 9530 case 'csaz24341985gr': 9531 case 'csiso123csaz24341985gr': 9532 case 'isoir123': 9533 return 'CSA_Z243.4-1985-gr'; 9534 9535 case 'csiso139csn369103': 9536 case 'csn369103': 9537 case 'isoir139': 9538 return 'CSN_369103'; 9539 9540 case 'csdecmcs': 9541 case 'dec': 9542 case 'decmcs': 9543 return 'DEC-MCS'; 9544 9545 case 'csiso21german': 9546 case 'de': 9547 case 'din66003': 9548 case 'iso646de': 9549 case 'isoir21': 9550 return 'DIN_66003'; 9551 9552 case 'csdkus': 9553 case 'dkus': 9554 return 'dk-us'; 9555 9556 case 'csiso646danish': 9557 case 'dk': 9558 case 'ds2089': 9559 case 'iso646dk': 9560 return 'DS_2089'; 9561 9562 case 'csibmebcdicatde': 9563 case 'ebcdicatde': 9564 return 'EBCDIC-AT-DE'; 9565 9566 case 'csebcdicatdea': 9567 case 'ebcdicatdea': 9568 return 'EBCDIC-AT-DE-A'; 9569 9570 case 'csebcdiccafr': 9571 case 'ebcdiccafr': 9572 return 'EBCDIC-CA-FR'; 9573 9574 case 'csebcdicdkno': 9575 case 'ebcdicdkno': 9576 return 'EBCDIC-DK-NO'; 9577 9578 case 'csebcdicdknoa': 9579 case 'ebcdicdknoa': 9580 return 'EBCDIC-DK-NO-A'; 9581 9582 case 'csebcdices': 9583 case 'ebcdices': 9584 return 'EBCDIC-ES'; 9585 9586 case 'csebcdicesa': 9587 case 'ebcdicesa': 9588 return 'EBCDIC-ES-A'; 9589 9590 case 'csebcdicess': 9591 case 'ebcdicess': 9592 return 'EBCDIC-ES-S'; 9593 9594 case 'csebcdicfise': 9595 case 'ebcdicfise': 9596 return 'EBCDIC-FI-SE'; 9597 9598 case 'csebcdicfisea': 9599 case 'ebcdicfisea': 9600 return 'EBCDIC-FI-SE-A'; 9601 9602 case 'csebcdicfr': 9603 case 'ebcdicfr': 9604 return 'EBCDIC-FR'; 9605 9606 case 'csebcdicit': 9607 case 'ebcdicit': 9608 return 'EBCDIC-IT'; 9609 9610 case 'csebcdicpt': 9611 case 'ebcdicpt': 9612 return 'EBCDIC-PT'; 9613 9614 case 'csebcdicuk': 9615 case 'ebcdicuk': 9616 return 'EBCDIC-UK'; 9617 9618 case 'csebcdicus': 9619 case 'ebcdicus': 9620 return 'EBCDIC-US'; 9621 9622 case 'csiso111ecmacyrillic': 9623 case 'ecmacyrillic': 9624 case 'isoir111': 9625 case 'koi8e': 9626 return 'ECMA-cyrillic'; 9627 9628 case 'csiso17spanish': 9629 case 'es': 9630 case 'iso646es': 9631 case 'isoir17': 9632 return 'ES'; 9633 9634 case 'csiso85spanish2': 9635 case 'es2': 9636 case 'iso646es2': 9637 case 'isoir85': 9638 return 'ES2'; 9639 9640 case 'cseucfixwidjapanese': 9641 case 'extendedunixcodefixedwidthforjapanese': 9642 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese'; 9643 9644 case 'cseucpkdfmtjapanese': 9645 case 'eucjp': 9646 case 'extendedunixcodepackedformatforjapanese': 9647 return 'Extended_UNIX_Code_Packed_Format_for_Japanese'; 9648 9649 case 'gb18030': 9650 return 'GB18030'; 9651 9652 case 'chinese': 9653 case 'cp936': 9654 case 'csgb2312': 9655 case 'csiso58gb231280': 9656 case 'gb2312': 9657 case 'gb231280': 9658 case 'gbk': 9659 case 'isoir58': 9660 case 'ms936': 9661 case 'windows936': 9662 return 'GBK'; 9663 9664 case 'cn': 9665 case 'csiso57gb1988': 9666 case 'gb198880': 9667 case 'iso646cn': 9668 case 'isoir57': 9669 return 'GB_1988-80'; 9670 9671 case 'csiso153gost1976874': 9672 case 'gost1976874': 9673 case 'isoir153': 9674 case 'stsev35888': 9675 return 'GOST_19768-74'; 9676 9677 case 'csiso150': 9678 case 'csiso150greekccitt': 9679 case 'greekccitt': 9680 case 'isoir150': 9681 return 'greek-ccitt'; 9682 9683 case 'csiso88greek7': 9684 case 'greek7': 9685 case 'isoir88': 9686 return 'greek7'; 9687 9688 case 'csiso18greek7old': 9689 case 'greek7old': 9690 case 'isoir18': 9691 return 'greek7-old'; 9692 9693 case 'cshpdesktop': 9694 case 'hpdesktop': 9695 return 'HP-DeskTop'; 9696 9697 case 'cshplegal': 9698 case 'hplegal': 9699 return 'HP-Legal'; 9700 9701 case 'cshpmath8': 9702 case 'hpmath8': 9703 return 'HP-Math8'; 9704 9705 case 'cshppifont': 9706 case 'hppifont': 9707 return 'HP-Pi-font'; 9708 9709 case 'cshproman8': 9710 case 'hproman8': 9711 case 'r8': 9712 case 'roman8': 9713 return 'hp-roman8'; 9714 9715 case 'hzgb2312': 9716 return 'HZ-GB-2312'; 9717 9718 case 'csibmsymbols': 9719 case 'ibmsymbols': 9720 return 'IBM-Symbols'; 9721 9722 case 'csibmthai': 9723 case 'ibmthai': 9724 return 'IBM-Thai'; 9725 9726 case 'ccsid858': 9727 case 'cp858': 9728 case 'ibm858': 9729 case 'pcmultilingual850euro': 9730 return 'IBM00858'; 9731 9732 case 'ccsid924': 9733 case 'cp924': 9734 case 'ebcdiclatin9euro': 9735 case 'ibm924': 9736 return 'IBM00924'; 9737 9738 case 'ccsid1140': 9739 case 'cp1140': 9740 case 'ebcdicus37euro': 9741 case 'ibm1140': 9742 return 'IBM01140'; 9743 9744 case 'ccsid1141': 9745 case 'cp1141': 9746 case 'ebcdicde273euro': 9747 case 'ibm1141': 9748 return 'IBM01141'; 9749 9750 case 'ccsid1142': 9751 case 'cp1142': 9752 case 'ebcdicdk277euro': 9753 case 'ebcdicno277euro': 9754 case 'ibm1142': 9755 return 'IBM01142'; 9756 9757 case 'ccsid1143': 9758 case 'cp1143': 9759 case 'ebcdicfi278euro': 9760 case 'ebcdicse278euro': 9761 case 'ibm1143': 9762 return 'IBM01143'; 9763 9764 case 'ccsid1144': 9765 case 'cp1144': 9766 case 'ebcdicit280euro': 9767 case 'ibm1144': 9768 return 'IBM01144'; 9769 9770 case 'ccsid1145': 9771 case 'cp1145': 9772 case 'ebcdices284euro': 9773 case 'ibm1145': 9774 return 'IBM01145'; 9775 9776 case 'ccsid1146': 9777 case 'cp1146': 9778 case 'ebcdicgb285euro': 9779 case 'ibm1146': 9780 return 'IBM01146'; 9781 9782 case 'ccsid1147': 9783 case 'cp1147': 9784 case 'ebcdicfr297euro': 9785 case 'ibm1147': 9786 return 'IBM01147'; 9787 9788 case 'ccsid1148': 9789 case 'cp1148': 9790 case 'ebcdicinternational500euro': 9791 case 'ibm1148': 9792 return 'IBM01148'; 9793 9794 case 'ccsid1149': 9795 case 'cp1149': 9796 case 'ebcdicis871euro': 9797 case 'ibm1149': 9798 return 'IBM01149'; 9799 9800 case 'cp37': 9801 case 'csibm37': 9802 case 'ebcdiccpca': 9803 case 'ebcdiccpnl': 9804 case 'ebcdiccpus': 9805 case 'ebcdiccpwt': 9806 case 'ibm37': 9807 return 'IBM037'; 9808 9809 case 'cp38': 9810 case 'csibm38': 9811 case 'ebcdicint': 9812 case 'ibm38': 9813 return 'IBM038'; 9814 9815 case 'cp273': 9816 case 'csibm273': 9817 case 'ibm273': 9818 return 'IBM273'; 9819 9820 case 'cp274': 9821 case 'csibm274': 9822 case 'ebcdicbe': 9823 case 'ibm274': 9824 return 'IBM274'; 9825 9826 case 'cp275': 9827 case 'csibm275': 9828 case 'ebcdicbr': 9829 case 'ibm275': 9830 return 'IBM275'; 9831 9832 case 'csibm277': 9833 case 'ebcdiccpdk': 9834 case 'ebcdiccpno': 9835 case 'ibm277': 9836 return 'IBM277'; 9837 9838 case 'cp278': 9839 case 'csibm278': 9840 case 'ebcdiccpfi': 9841 case 'ebcdiccpse': 9842 case 'ibm278': 9843 return 'IBM278'; 9844 9845 case 'cp280': 9846 case 'csibm280': 9847 case 'ebcdiccpit': 9848 case 'ibm280': 9849 return 'IBM280'; 9850 9851 case 'cp281': 9852 case 'csibm281': 9853 case 'ebcdicjpe': 9854 case 'ibm281': 9855 return 'IBM281'; 9856 9857 case 'cp284': 9858 case 'csibm284': 9859 case 'ebcdiccpes': 9860 case 'ibm284': 9861 return 'IBM284'; 9862 9863 case 'cp285': 9864 case 'csibm285': 9865 case 'ebcdiccpgb': 9866 case 'ibm285': 9867 return 'IBM285'; 9868 9869 case 'cp290': 9870 case 'csibm290': 9871 case 'ebcdicjpkana': 9872 case 'ibm290': 9873 return 'IBM290'; 9874 9875 case 'cp297': 9876 case 'csibm297': 9877 case 'ebcdiccpfr': 9878 case 'ibm297': 9879 return 'IBM297'; 9880 9881 case 'cp420': 9882 case 'csibm420': 9883 case 'ebcdiccpar1': 9884 case 'ibm420': 9885 return 'IBM420'; 9886 9887 case 'cp423': 9888 case 'csibm423': 9889 case 'ebcdiccpgr': 9890 case 'ibm423': 9891 return 'IBM423'; 9892 9893 case 'cp424': 9894 case 'csibm424': 9895 case 'ebcdiccphe': 9896 case 'ibm424': 9897 return 'IBM424'; 9898 9899 case '437': 9900 case 'cp437': 9901 case 'cspc8codepage437': 9902 case 'ibm437': 9903 return 'IBM437'; 9904 9905 case 'cp500': 9906 case 'csibm500': 9907 case 'ebcdiccpbe': 9908 case 'ebcdiccpch': 9909 case 'ibm500': 9910 return 'IBM500'; 9911 9912 case 'cp775': 9913 case 'cspc775baltic': 9914 case 'ibm775': 9915 return 'IBM775'; 9916 9917 case '850': 9918 case 'cp850': 9919 case 'cspc850multilingual': 9920 case 'ibm850': 9921 return 'IBM850'; 9922 9923 case '851': 9924 case 'cp851': 9925 case 'csibm851': 9926 case 'ibm851': 9927 return 'IBM851'; 9928 9929 case '852': 9930 case 'cp852': 9931 case 'cspcp852': 9932 case 'ibm852': 9933 return 'IBM852'; 9934 9935 case '855': 9936 case 'cp855': 9937 case 'csibm855': 9938 case 'ibm855': 9939 return 'IBM855'; 9940 9941 case '857': 9942 case 'cp857': 9943 case 'csibm857': 9944 case 'ibm857': 9945 return 'IBM857'; 9946 9947 case '860': 9948 case 'cp860': 9949 case 'csibm860': 9950 case 'ibm860': 9951 return 'IBM860'; 9952 9953 case '861': 9954 case 'cp861': 9955 case 'cpis': 9956 case 'csibm861': 9957 case 'ibm861': 9958 return 'IBM861'; 9959 9960 case '862': 9961 case 'cp862': 9962 case 'cspc862latinhebrew': 9963 case 'ibm862': 9964 return 'IBM862'; 9965 9966 case '863': 9967 case 'cp863': 9968 case 'csibm863': 9969 case 'ibm863': 9970 return 'IBM863'; 9971 9972 case 'cp864': 9973 case 'csibm864': 9974 case 'ibm864': 9975 return 'IBM864'; 9976 9977 case '865': 9978 case 'cp865': 9979 case 'csibm865': 9980 case 'ibm865': 9981 return 'IBM865'; 9982 9983 case '866': 9984 case 'cp866': 9985 case 'csibm866': 9986 case 'ibm866': 9987 return 'IBM866'; 9988 9989 case 'cp868': 9990 case 'cpar': 9991 case 'csibm868': 9992 case 'ibm868': 9993 return 'IBM868'; 9994 9995 case '869': 9996 case 'cp869': 9997 case 'cpgr': 9998 case 'csibm869': 9999 case 'ibm869': 10000 return 'IBM869'; 10001 10002 case 'cp870': 10003 case 'csibm870': 10004 case 'ebcdiccproece': 10005 case 'ebcdiccpyu': 10006 case 'ibm870': 10007 return 'IBM870'; 10008 10009 case 'cp871': 10010 case 'csibm871': 10011 case 'ebcdiccpis': 10012 case 'ibm871': 10013 return 'IBM871'; 10014 10015 case 'cp880': 10016 case 'csibm880': 10017 case 'ebcdiccyrillic': 10018 case 'ibm880': 10019 return 'IBM880'; 10020 10021 case 'cp891': 10022 case 'csibm891': 10023 case 'ibm891': 10024 return 'IBM891'; 10025 10026 case 'cp903': 10027 case 'csibm903': 10028 case 'ibm903': 10029 return 'IBM903'; 10030 10031 case '904': 10032 case 'cp904': 10033 case 'csibbm904': 10034 case 'ibm904': 10035 return 'IBM904'; 10036 10037 case 'cp905': 10038 case 'csibm905': 10039 case 'ebcdiccptr': 10040 case 'ibm905': 10041 return 'IBM905'; 10042 10043 case 'cp918': 10044 case 'csibm918': 10045 case 'ebcdiccpar2': 10046 case 'ibm918': 10047 return 'IBM918'; 10048 10049 case 'cp1026': 10050 case 'csibm1026': 10051 case 'ibm1026': 10052 return 'IBM1026'; 10053 10054 case 'ibm1047': 10055 return 'IBM1047'; 10056 10057 case 'csiso143iecp271': 10058 case 'iecp271': 10059 case 'isoir143': 10060 return 'IEC_P27-1'; 10061 10062 case 'csiso49inis': 10063 case 'inis': 10064 case 'isoir49': 10065 return 'INIS'; 10066 10067 case 'csiso50inis8': 10068 case 'inis8': 10069 case 'isoir50': 10070 return 'INIS-8'; 10071 10072 case 'csiso51iniscyrillic': 10073 case 'iniscyrillic': 10074 case 'isoir51': 10075 return 'INIS-cyrillic'; 10076 10077 case 'csinvariant': 10078 case 'invariant': 10079 return 'INVARIANT'; 10080 10081 case 'iso2022cn': 10082 return 'ISO-2022-CN'; 10083 10084 case 'iso2022cnext': 10085 return 'ISO-2022-CN-EXT'; 10086 10087 case 'csiso2022jp': 10088 case 'iso2022jp': 10089 return 'ISO-2022-JP'; 10090 10091 case 'csiso2022jp2': 10092 case 'iso2022jp2': 10093 return 'ISO-2022-JP-2'; 10094 10095 case 'csiso2022kr': 10096 case 'iso2022kr': 10097 return 'ISO-2022-KR'; 10098 10099 case 'cswindows30latin1': 10100 case 'iso88591windows30latin1': 10101 return 'ISO-8859-1-Windows-3.0-Latin-1'; 10102 10103 case 'cswindows31latin1': 10104 case 'iso88591windows31latin1': 10105 return 'ISO-8859-1-Windows-3.1-Latin-1'; 10106 10107 case 'csisolatin2': 10108 case 'iso88592': 10109 case 'iso885921987': 10110 case 'isoir101': 10111 case 'l2': 10112 case 'latin2': 10113 return 'ISO-8859-2'; 10114 10115 case 'cswindows31latin2': 10116 case 'iso88592windowslatin2': 10117 return 'ISO-8859-2-Windows-Latin-2'; 10118 10119 case 'csisolatin3': 10120 case 'iso88593': 10121 case 'iso885931988': 10122 case 'isoir109': 10123 case 'l3': 10124 case 'latin3': 10125 return 'ISO-8859-3'; 10126 10127 case 'csisolatin4': 10128 case 'iso88594': 10129 case 'iso885941988': 10130 case 'isoir110': 10131 case 'l4': 10132 case 'latin4': 10133 return 'ISO-8859-4'; 10134 10135 case 'csisolatincyrillic': 10136 case 'cyrillic': 10137 case 'iso88595': 10138 case 'iso885951988': 10139 case 'isoir144': 10140 return 'ISO-8859-5'; 10141 10142 case 'arabic': 10143 case 'asmo708': 10144 case 'csisolatinarabic': 10145 case 'ecma114': 10146 case 'iso88596': 10147 case 'iso885961987': 10148 case 'isoir127': 10149 return 'ISO-8859-6'; 10150 10151 case 'csiso88596e': 10152 case 'iso88596e': 10153 return 'ISO-8859-6-E'; 10154 10155 case 'csiso88596i': 10156 case 'iso88596i': 10157 return 'ISO-8859-6-I'; 10158 10159 case 'csisolatingreek': 10160 case 'ecma118': 10161 case 'elot928': 10162 case 'greek': 10163 case 'greek8': 10164 case 'iso88597': 10165 case 'iso885971987': 10166 case 'isoir126': 10167 return 'ISO-8859-7'; 10168 10169 case 'csisolatinhebrew': 10170 case 'hebrew': 10171 case 'iso88598': 10172 case 'iso885981988': 10173 case 'isoir138': 10174 return 'ISO-8859-8'; 10175 10176 case 'csiso88598e': 10177 case 'iso88598e': 10178 return 'ISO-8859-8-E'; 10179 10180 case 'csiso88598i': 10181 case 'iso88598i': 10182 return 'ISO-8859-8-I'; 10183 10184 case 'cswindows31latin5': 10185 case 'iso88599windowslatin5': 10186 return 'ISO-8859-9-Windows-Latin-5'; 10187 10188 case 'csisolatin6': 10189 case 'iso885910': 10190 case 'iso8859101992': 10191 case 'isoir157': 10192 case 'l6': 10193 case 'latin6': 10194 return 'ISO-8859-10'; 10195 10196 case 'iso885913': 10197 return 'ISO-8859-13'; 10198 10199 case 'iso885914': 10200 case 'iso8859141998': 10201 case 'isoceltic': 10202 case 'isoir199': 10203 case 'l8': 10204 case 'latin8': 10205 return 'ISO-8859-14'; 10206 10207 case 'iso885915': 10208 case 'latin9': 10209 return 'ISO-8859-15'; 10210 10211 case 'iso885916': 10212 case 'iso8859162001': 10213 case 'isoir226': 10214 case 'l10': 10215 case 'latin10': 10216 return 'ISO-8859-16'; 10217 10218 case 'iso10646j1': 10219 return 'ISO-10646-J-1'; 10220 10221 case 'csunicode': 10222 case 'iso10646ucs2': 10223 return 'ISO-10646-UCS-2'; 10224 10225 case 'csucs4': 10226 case 'iso10646ucs4': 10227 return 'ISO-10646-UCS-4'; 10228 10229 case 'csunicodeascii': 10230 case 'iso10646ucsbasic': 10231 return 'ISO-10646-UCS-Basic'; 10232 10233 case 'csunicodelatin1': 10234 case 'iso10646': 10235 case 'iso10646unicodelatin1': 10236 return 'ISO-10646-Unicode-Latin1'; 10237 10238 case 'csiso10646utf1': 10239 case 'iso10646utf1': 10240 return 'ISO-10646-UTF-1'; 10241 10242 case 'csiso115481': 10243 case 'iso115481': 10244 case 'isotr115481': 10245 return 'ISO-11548-1'; 10246 10247 case 'csiso90': 10248 case 'isoir90': 10249 return 'iso-ir-90'; 10250 10251 case 'csunicodeibm1261': 10252 case 'isounicodeibm1261': 10253 return 'ISO-Unicode-IBM-1261'; 10254 10255 case 'csunicodeibm1264': 10256 case 'isounicodeibm1264': 10257 return 'ISO-Unicode-IBM-1264'; 10258 10259 case 'csunicodeibm1265': 10260 case 'isounicodeibm1265': 10261 return 'ISO-Unicode-IBM-1265'; 10262 10263 case 'csunicodeibm1268': 10264 case 'isounicodeibm1268': 10265 return 'ISO-Unicode-IBM-1268'; 10266 10267 case 'csunicodeibm1276': 10268 case 'isounicodeibm1276': 10269 return 'ISO-Unicode-IBM-1276'; 10270 10271 case 'csiso646basic1983': 10272 case 'iso646basic1983': 10273 case 'ref': 10274 return 'ISO_646.basic:1983'; 10275 10276 case 'csiso2intlrefversion': 10277 case 'irv': 10278 case 'iso646irv1983': 10279 case 'isoir2': 10280 return 'ISO_646.irv:1983'; 10281 10282 case 'csiso2033': 10283 case 'e13b': 10284 case 'iso20331983': 10285 case 'isoir98': 10286 return 'ISO_2033-1983'; 10287 10288 case 'csiso5427cyrillic': 10289 case 'iso5427': 10290 case 'isoir37': 10291 return 'ISO_5427'; 10292 10293 case 'iso5427cyrillic1981': 10294 case 'iso54271981': 10295 case 'isoir54': 10296 return 'ISO_5427:1981'; 10297 10298 case 'csiso5428greek': 10299 case 'iso54281980': 10300 case 'isoir55': 10301 return 'ISO_5428:1980'; 10302 10303 case 'csiso6937add': 10304 case 'iso6937225': 10305 case 'isoir152': 10306 return 'ISO_6937-2-25'; 10307 10308 case 'csisotextcomm': 10309 case 'iso69372add': 10310 case 'isoir142': 10311 return 'ISO_6937-2-add'; 10312 10313 case 'csiso8859supp': 10314 case 'iso8859supp': 10315 case 'isoir154': 10316 case 'latin125': 10317 return 'ISO_8859-supp'; 10318 10319 case 'csiso10367box': 10320 case 'iso10367box': 10321 case 'isoir155': 10322 return 'ISO_10367-box'; 10323 10324 case 'csiso15italian': 10325 case 'iso646it': 10326 case 'isoir15': 10327 case 'it': 10328 return 'IT'; 10329 10330 case 'csiso13jisc6220jp': 10331 case 'isoir13': 10332 case 'jisc62201969': 10333 case 'jisc62201969jp': 10334 case 'katakana': 10335 case 'x2017': 10336 return 'JIS_C6220-1969-jp'; 10337 10338 case 'csiso14jisc6220ro': 10339 case 'iso646jp': 10340 case 'isoir14': 10341 case 'jisc62201969ro': 10342 case 'jp': 10343 return 'JIS_C6220-1969-ro'; 10344 10345 case 'csiso42jisc62261978': 10346 case 'isoir42': 10347 case 'jisc62261978': 10348 return 'JIS_C6226-1978'; 10349 10350 case 'csiso87jisx208': 10351 case 'isoir87': 10352 case 'jisc62261983': 10353 case 'jisx2081983': 10354 case 'x208': 10355 return 'JIS_C6226-1983'; 10356 10357 case 'csiso91jisc62291984a': 10358 case 'isoir91': 10359 case 'jisc62291984a': 10360 case 'jpocra': 10361 return 'JIS_C6229-1984-a'; 10362 10363 case 'csiso92jisc62991984b': 10364 case 'iso646jpocrb': 10365 case 'isoir92': 10366 case 'jisc62291984b': 10367 case 'jpocrb': 10368 return 'JIS_C6229-1984-b'; 10369 10370 case 'csiso93jis62291984badd': 10371 case 'isoir93': 10372 case 'jisc62291984badd': 10373 case 'jpocrbadd': 10374 return 'JIS_C6229-1984-b-add'; 10375 10376 case 'csiso94jis62291984hand': 10377 case 'isoir94': 10378 case 'jisc62291984hand': 10379 case 'jpocrhand': 10380 return 'JIS_C6229-1984-hand'; 10381 10382 case 'csiso95jis62291984handadd': 10383 case 'isoir95': 10384 case 'jisc62291984handadd': 10385 case 'jpocrhandadd': 10386 return 'JIS_C6229-1984-hand-add'; 10387 10388 case 'csiso96jisc62291984kana': 10389 case 'isoir96': 10390 case 'jisc62291984kana': 10391 return 'JIS_C6229-1984-kana'; 10392 10393 case 'csjisencoding': 10394 case 'jisencoding': 10395 return 'JIS_Encoding'; 10396 10397 case 'cshalfwidthkatakana': 10398 case 'jisx201': 10399 case 'x201': 10400 return 'JIS_X0201'; 10401 10402 case 'csiso159jisx2121990': 10403 case 'isoir159': 10404 case 'jisx2121990': 10405 case 'x212': 10406 return 'JIS_X0212-1990'; 10407 10408 case 'csiso141jusib1002': 10409 case 'iso646yu': 10410 case 'isoir141': 10411 case 'js': 10412 case 'jusib1002': 10413 case 'yu': 10414 return 'JUS_I.B1.002'; 10415 10416 case 'csiso147macedonian': 10417 case 'isoir147': 10418 case 'jusib1003mac': 10419 case 'macedonian': 10420 return 'JUS_I.B1.003-mac'; 10421 10422 case 'csiso146serbian': 10423 case 'isoir146': 10424 case 'jusib1003serb': 10425 case 'serbian': 10426 return 'JUS_I.B1.003-serb'; 10427 10428 case 'koi7switched': 10429 return 'KOI7-switched'; 10430 10431 case 'cskoi8r': 10432 case 'koi8r': 10433 return 'KOI8-R'; 10434 10435 case 'koi8u': 10436 return 'KOI8-U'; 10437 10438 case 'csksc5636': 10439 case 'iso646kr': 10440 case 'ksc5636': 10441 return 'KSC5636'; 10442 10443 case 'cskz1048': 10444 case 'kz1048': 10445 case 'rk1048': 10446 case 'strk10482002': 10447 return 'KZ-1048'; 10448 10449 case 'csiso19latingreek': 10450 case 'isoir19': 10451 case 'latingreek': 10452 return 'latin-greek'; 10453 10454 case 'csiso27latingreek1': 10455 case 'isoir27': 10456 case 'latingreek1': 10457 return 'Latin-greek-1'; 10458 10459 case 'csiso158lap': 10460 case 'isoir158': 10461 case 'lap': 10462 case 'latinlap': 10463 return 'latin-lap'; 10464 10465 case 'csmacintosh': 10466 case 'mac': 10467 case 'macintosh': 10468 return 'macintosh'; 10469 10470 case 'csmicrosoftpublishing': 10471 case 'microsoftpublishing': 10472 return 'Microsoft-Publishing'; 10473 10474 case 'csmnem': 10475 case 'mnem': 10476 return 'MNEM'; 10477 10478 case 'csmnemonic': 10479 case 'mnemonic': 10480 return 'MNEMONIC'; 10481 10482 case 'csiso86hungarian': 10483 case 'hu': 10484 case 'iso646hu': 10485 case 'isoir86': 10486 case 'msz77953': 10487 return 'MSZ_7795.3'; 10488 10489 case 'csnatsdano': 10490 case 'isoir91': 10491 case 'natsdano': 10492 return 'NATS-DANO'; 10493 10494 case 'csnatsdanoadd': 10495 case 'isoir92': 10496 case 'natsdanoadd': 10497 return 'NATS-DANO-ADD'; 10498 10499 case 'csnatssefi': 10500 case 'isoir81': 10501 case 'natssefi': 10502 return 'NATS-SEFI'; 10503 10504 case 'csnatssefiadd': 10505 case 'isoir82': 10506 case 'natssefiadd': 10507 return 'NATS-SEFI-ADD'; 10508 10509 case 'csiso151cuba': 10510 case 'cuba': 10511 case 'iso646cu': 10512 case 'isoir151': 10513 case 'ncnc1081': 10514 return 'NC_NC00-10:81'; 10515 10516 case 'csiso69french': 10517 case 'fr': 10518 case 'iso646fr': 10519 case 'isoir69': 10520 case 'nfz62010': 10521 return 'NF_Z_62-010'; 10522 10523 case 'csiso25french': 10524 case 'iso646fr1': 10525 case 'isoir25': 10526 case 'nfz620101973': 10527 return 'NF_Z_62-010_(1973)'; 10528 10529 case 'csiso60danishnorwegian': 10530 case 'csiso60norwegian1': 10531 case 'iso646no': 10532 case 'isoir60': 10533 case 'no': 10534 case 'ns45511': 10535 return 'NS_4551-1'; 10536 10537 case 'csiso61norwegian2': 10538 case 'iso646no2': 10539 case 'isoir61': 10540 case 'no2': 10541 case 'ns45512': 10542 return 'NS_4551-2'; 10543 10544 case 'osdebcdicdf3irv': 10545 return 'OSD_EBCDIC_DF03_IRV'; 10546 10547 case 'osdebcdicdf41': 10548 return 'OSD_EBCDIC_DF04_1'; 10549 10550 case 'osdebcdicdf415': 10551 return 'OSD_EBCDIC_DF04_15'; 10552 10553 case 'cspc8danishnorwegian': 10554 case 'pc8danishnorwegian': 10555 return 'PC8-Danish-Norwegian'; 10556 10557 case 'cspc8turkish': 10558 case 'pc8turkish': 10559 return 'PC8-Turkish'; 10560 10561 case 'csiso16portuguese': 10562 case 'iso646pt': 10563 case 'isoir16': 10564 case 'pt': 10565 return 'PT'; 10566 10567 case 'csiso84portuguese2': 10568 case 'iso646pt2': 10569 case 'isoir84': 10570 case 'pt2': 10571 return 'PT2'; 10572 10573 case 'cp154': 10574 case 'csptcp154': 10575 case 'cyrillicasian': 10576 case 'pt154': 10577 case 'ptcp154': 10578 return 'PTCP154'; 10579 10580 case 'scsu': 10581 return 'SCSU'; 10582 10583 case 'csiso10swedish': 10584 case 'fi': 10585 case 'iso646fi': 10586 case 'iso646se': 10587 case 'isoir10': 10588 case 'se': 10589 case 'sen850200b': 10590 return 'SEN_850200_B'; 10591 10592 case 'csiso11swedishfornames': 10593 case 'iso646se2': 10594 case 'isoir11': 10595 case 'se2': 10596 case 'sen850200c': 10597 return 'SEN_850200_C'; 10598 10599 case 'csshiftjis': 10600 case 'mskanji': 10601 case 'shiftjis': 10602 return 'Shift_JIS'; 10603 10604 case 'csiso102t617bit': 10605 case 'isoir102': 10606 case 't617bit': 10607 return 'T.61-7bit'; 10608 10609 case 'csiso103t618bit': 10610 case 'isoir103': 10611 case 't61': 10612 case 't618bit': 10613 return 'T.61-8bit'; 10614 10615 case 'csiso128t101g2': 10616 case 'isoir128': 10617 case 't101g2': 10618 return 'T.101-G2'; 10619 10620 case 'cstscii': 10621 case 'tscii': 10622 return 'TSCII'; 10623 10624 case 'csunicode11': 10625 case 'unicode11': 10626 return 'UNICODE-1-1'; 10627 10628 case 'csunicode11utf7': 10629 case 'unicode11utf7': 10630 return 'UNICODE-1-1-UTF-7'; 10631 10632 case 'csunknown8bit': 10633 case 'unknown8bit': 10634 return 'UNKNOWN-8BIT'; 10635 10636 case 'ansix341968': 10637 case 'ansix341986': 10638 case 'ascii': 10639 case 'cp367': 10640 case 'csascii': 10641 case 'ibm367': 10642 case 'iso646irv1991': 10643 case 'iso646us': 10644 case 'isoir6': 10645 case 'us': 10646 case 'usascii': 10647 return 'US-ASCII'; 10648 10649 case 'csusdk': 10650 case 'usdk': 10651 return 'us-dk'; 10652 10653 case 'utf7': 10654 return 'UTF-7'; 10655 10656 case 'utf8': 10657 return 'UTF-8'; 10658 10659 case 'utf16': 10660 return 'UTF-16'; 10661 10662 case 'utf16be': 10663 return 'UTF-16BE'; 10664 10665 case 'utf16le': 10666 return 'UTF-16LE'; 10667 10668 case 'utf32': 10669 return 'UTF-32'; 10670 10671 case 'utf32be': 10672 return 'UTF-32BE'; 10673 10674 case 'utf32le': 10675 return 'UTF-32LE'; 10676 10677 case 'csventurainternational': 10678 case 'venturainternational': 10679 return 'Ventura-International'; 10680 10681 case 'csventuramath': 10682 case 'venturamath': 10683 return 'Ventura-Math'; 10684 10685 case 'csventuraus': 10686 case 'venturaus': 10687 return 'Ventura-US'; 10688 10689 case 'csiso70videotexsupp1': 10690 case 'isoir70': 10691 case 'videotexsuppl': 10692 return 'videotex-suppl'; 10693 10694 case 'csviqr': 10695 case 'viqr': 10696 return 'VIQR'; 10697 10698 case 'csviscii': 10699 case 'viscii': 10700 return 'VISCII'; 10701 10702 case 'cswindows31j': 10703 case 'windows31j': 10704 return 'Windows-31J'; 10705 10706 case 'iso885911': 10707 case 'tis620': 10708 return 'windows-874'; 10709 10710 case 'cseuckr': 10711 case 'csksc56011987': 10712 case 'euckr': 10713 case 'isoir149': 10714 case 'korean': 10715 case 'ksc5601': 10716 case 'ksc56011987': 10717 case 'ksc56011989': 10718 case 'windows949': 10719 return 'windows-949'; 10720 10721 case 'windows1250': 10722 return 'windows-1250'; 10723 10724 case 'windows1251': 10725 return 'windows-1251'; 10726 10727 case 'cp819': 10728 case 'csisolatin1': 10729 case 'ibm819': 10730 case 'iso88591': 10731 case 'iso885911987': 10732 case 'isoir100': 10733 case 'l1': 10734 case 'latin1': 10735 case 'windows1252': 10736 return 'windows-1252'; 10737 10738 case 'windows1253': 10739 return 'windows-1253'; 10740 10741 case 'csisolatin5': 10742 case 'iso88599': 10743 case 'iso885991989': 10744 case 'isoir148': 10745 case 'l5': 10746 case 'latin5': 10747 case 'windows1254': 10748 return 'windows-1254'; 10749 10750 case 'windows1255': 10751 return 'windows-1255'; 10752 10753 case 'windows1256': 10754 return 'windows-1256'; 10755 10756 case 'windows1257': 10757 return 'windows-1257'; 10758 10759 case 'windows1258': 10760 return 'windows-1258'; 10761 10762 default: 10763 return $charset; 10764 } 10765 } 10766 10767 function get_curl_version() 10768 { 10769 if (is_array($curl = curl_version())) 10770 { 10771 $curl = $curl['version']; 10772 } 10773 elseif (substr($curl, 0, 5) === 'curl/') 10774 { 10775 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5)); 10776 } 10777 elseif (substr($curl, 0, 8) === 'libcurl/') 10778 { 10779 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8)); 10780 } 10781 else 10782 { 10783 $curl = 0; 10784 } 10785 return $curl; 10786 } 10787 10788 function is_subclass_of($class1, $class2) 10789 { 10790 if (func_num_args() !== 2) 10791 { 10792 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING); 10793 } 10794 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1)) 10795 { 10796 return is_subclass_of($class1, $class2); 10797 } 10798 elseif (is_string($class1) && is_string($class2)) 10799 { 10800 if (class_exists($class1)) 10801 { 10802 if (class_exists($class2)) 10803 { 10804 $class2 = strtolower($class2); 10805 while ($class1 = strtolower(get_parent_class($class1))) 10806 { 10807 if ($class1 === $class2) 10808 { 10809 return true; 10810 } 10811 } 10812 } 10813 } 10814 else 10815 { 10816 trigger_error('Unknown class passed as parameter', E_USER_WARNNG); 10817 } 10818 } 10819 return false; 10820 } 10821 10822 /** 10823 * Strip HTML comments 10824 * 10825 * @access public 10826 * @param string $data Data to strip comments from 10827 * @return string Comment stripped string 10828 */ 10829 function strip_comments($data) 10830 { 10831 $output = ''; 10832 while (($start = strpos($data, '<!--')) !== false) 10833 { 10834 $output .= substr($data, 0, $start); 10835 if (($end = strpos($data, '-->', $start)) !== false) 10836 { 10837 $data = substr_replace($data, '', 0, $end + 3); 10838 } 10839 else 10840 { 10841 $data = ''; 10842 } 10843 } 10844 return $output . $data; 10845 } 10846 10847 function parse_date($dt) 10848 { 10849 $parser = SimplePie_Parse_Date::get(); 10850 return $parser->parse($dt); 10851 } 10852 10853 /** 10854 * Decode HTML entities 10855 * 10856 * @static 10857 * @access public 10858 * @param string $data Input data 10859 * @return string Output data 10860 */ 10861 function entities_decode($data) 10862 { 10863 $decoder =& new SimplePie_Decode_HTML_Entities($data); 10864 return $decoder->parse(); 10865 } 10866 10867 /** 10868 * Remove RFC822 comments 10869 * 10870 * @access public 10871 * @param string $data Data to strip comments from 10872 * @return string Comment stripped string 10873 */ 10874 function uncomment_rfc822($string) 10875 { 10876 $string = (string) $string; 10877 $position = 0; 10878 $length = strlen($string); 10879 $depth = 0; 10880 10881 $output = ''; 10882 10883 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) 10884 { 10885 $output .= substr($string, $position, $pos - $position); 10886 $position = $pos + 1; 10887 if ($string[$pos - 1] !== '\\') 10888 { 10889 $depth++; 10890 while ($depth && $position < $length) 10891 { 10892 $position += strcspn($string, '()', $position); 10893 if ($string[$position - 1] === '\\') 10894 { 10895 $position++; 10896 continue; 10897 } 10898 elseif (isset($string[$position])) 10899 { 10900 switch ($string[$position]) 10901 { 10902 case '(': 10903 $depth++; 10904 break; 10905 10906 case ')': 10907 $depth--; 10908 break; 10909 } 10910 $position++; 10911 } 10912 else 10913 { 10914 break; 10915 } 10916 } 10917 } 10918 else 10919 { 10920 $output .= '('; 10921 } 10922 } 10923 $output .= substr($string, $position); 10924 10925 return $output; 10926 } 10927 10928 function parse_mime($mime) 10929 { 10930 if (($pos = strpos($mime, ';')) === false) 10931 { 10932 return trim($mime); 10933 } 10934 else 10935 { 10936 return trim(substr($mime, 0, $pos)); 10937 } 10938 } 10939 10940 function htmlspecialchars_decode($string, $quote_style) 10941 { 10942 if (function_exists('htmlspecialchars_decode')) 10943 { 10944 return htmlspecialchars_decode($string, $quote_style); 10945 } 10946 else 10947 { 10948 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style))); 10949 } 10950 } 10951 10952 function atom_03_construct_type($attribs) 10953 { 10954 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64')) 10955 { 10956 $mode = SIMPLEPIE_CONSTRUCT_BASE64; 10957 } 10958 else 10959 { 10960 $mode = SIMPLEPIE_CONSTRUCT_NONE; 10961 } 10962 if (isset($attribs['']['type'])) 10963 { 10964 switch (strtolower(trim($attribs['']['type']))) 10965 { 10966 case 'text': 10967 case 'text/plain': 10968 return SIMPLEPIE_CONSTRUCT_TEXT | $mode; 10969 10970 case 'html': 10971 case 'text/html': 10972 return SIMPLEPIE_CONSTRUCT_HTML | $mode; 10973 10974 case 'xhtml': 10975 case 'application/xhtml+xml': 10976 return SIMPLEPIE_CONSTRUCT_XHTML | $mode; 10977 10978 default: 10979 return SIMPLEPIE_CONSTRUCT_NONE | $mode; 10980 } 10981 } 10982 else 10983 { 10984 return SIMPLEPIE_CONSTRUCT_TEXT | $mode; 10985 } 10986 } 10987 10988 function atom_10_construct_type($attribs) 10989 { 10990 if (isset($attribs['']['type'])) 10991 { 10992 switch (strtolower(trim($attribs['']['type']))) 10993 { 10994 case 'text': 10995 return SIMPLEPIE_CONSTRUCT_TEXT; 10996 10997 case 'html': 10998 return SIMPLEPIE_CONSTRUCT_HTML; 10999 11000 case 'xhtml': 11001 return SIMPLEPIE_CONSTRUCT_XHTML; 11002 11003 default: 11004 return SIMPLEPIE_CONSTRUCT_NONE; 11005 } 11006 } 11007 return SIMPLEPIE_CONSTRUCT_TEXT; 11008 } 11009 11010 function atom_10_content_construct_type($attribs) 11011 { 11012 if (isset($attribs['']['type'])) 11013 { 11014 $type = strtolower(trim($attribs['']['type'])); 11015 switch ($type) 11016 { 11017 case 'text': 11018 return SIMPLEPIE_CONSTRUCT_TEXT; 11019 11020 case 'html': 11021 return SIMPLEPIE_CONSTRUCT_HTML; 11022 11023 case 'xhtml': 11024 return SIMPLEPIE_CONSTRUCT_XHTML; 11025 } 11026 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/') 11027 { 11028 return SIMPLEPIE_CONSTRUCT_NONE; 11029 } 11030 else 11031 { 11032 return SIMPLEPIE_CONSTRUCT_BASE64; 11033 } 11034 } 11035 else 11036 { 11037 return SIMPLEPIE_CONSTRUCT_TEXT; 11038 } 11039 } 11040 11041 function is_isegment_nz_nc($string) 11042 { 11043 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); 11044 } 11045 11046 function space_seperated_tokens($string) 11047 { 11048 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D"; 11049 $string_length = strlen($string); 11050 11051 $position = strspn($string, $space_characters); 11052 $tokens = array(); 11053 11054 while ($position < $string_length) 11055 { 11056 $len = strcspn($string, $space_characters, $position); 11057 $tokens[] = substr($string, $position, $len); 11058 $position += $len; 11059 $position += strspn($string, $space_characters, $position); 11060 } 11061 11062 return $tokens; 11063 } 11064 11065 function array_unique($array) 11066 { 11067 if (version_compare(PHP_VERSION, '5.2', '>=')) 11068 { 11069 return array_unique($array); 11070 } 11071 else 11072 { 11073 $array = (array) $array; 11074 $new_array = array(); 11075 $new_array_strings = array(); 11076 foreach ($array as $key => $value) 11077 { 11078 if (is_object($value)) 11079 { 11080 if (method_exists($value, '__toString')) 11081 { 11082 $cmp = $value->__toString(); 11083 } 11084 else 11085 { 11086 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR); 11087 } 11088 } 11089 elseif (is_array($value)) 11090 { 11091 $cmp = (string) reset($value); 11092 } 11093 else 11094 { 11095 $cmp = (string) $value; 11096 } 11097 if (!in_array($cmp, $new_array_strings)) 11098 { 11099 $new_array[$key] = $value; 11100 $new_array_strings[] = $cmp; 11101 } 11102 } 11103 return $new_array; 11104 } 11105 } 11106 11107 /** 11108 * Converts a unicode codepoint to a UTF-8 character 11109 * 11110 * @static 11111 * @access public 11112 * @param int $codepoint Unicode codepoint 11113 * @return string UTF-8 character 11114 */ 11115 function codepoint_to_utf8($codepoint) 11116 { 11117 $codepoint = (int) $codepoint; 11118 if ($codepoint < 0) 11119 { 11120 return false; 11121 } 11122 else if ($codepoint <= 0x7f) 11123 { 11124 return chr($codepoint); 11125 } 11126 else if ($codepoint <= 0x7ff) 11127 { 11128 return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f)); 11129 } 11130 else if ($codepoint <= 0xffff) 11131 { 11132 return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f)); 11133 } 11134 else if ($codepoint <= 0x10ffff) 11135 { 11136 return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f)); 11137 } 11138 else 11139 { 11140 // U+FFFD REPLACEMENT CHARACTER 11141 return "\xEF\xBF\xBD"; 11142 } 11143 } 11144 11145 /** 11146 * Re-implementation of PHP 5's stripos() 11147 * 11148 * Returns the numeric position of the first occurrence of needle in the 11149 * haystack string. 11150 * 11151 * @static 11152 * @access string 11153 * @param object $haystack 11154 * @param string $needle Note that the needle may be a string of one or more 11155 * characters. If needle is not a string, it is converted to an integer 11156 * and applied as the ordinal value of a character. 11157 * @param int $offset The optional offset parameter allows you to specify which 11158 * character in haystack to start searching. The position returned is still 11159 * relative to the beginning of haystack. 11160 * @return bool If needle is not found, stripos() will return boolean false. 11161 */ 11162 function stripos($haystack, $needle, $offset = 0) 11163 { 11164 if (function_exists('stripos')) 11165 { 11166 return stripos($haystack, $needle, $offset); 11167 } 11168 else 11169 { 11170 if (is_string($needle)) 11171 { 11172 $needle = strtolower($needle); 11173 } 11174 elseif (is_int($needle) || is_bool($needle) || is_double($needle)) 11175 { 11176 $needle = strtolower(chr($needle)); 11177 } 11178 else 11179 { 11180 trigger_error('needle is not a string or an integer', E_USER_WARNING); 11181 return false; 11182 } 11183 11184 return strpos(strtolower($haystack), $needle, $offset); 11185 } 11186 } 11187 11188 /** 11189 * Similar to parse_str() 11190 * 11191 * Returns an associative array of name/value pairs, where the value is an 11192 * array of values that have used the same name 11193 * 11194 * @static 11195 * @access string 11196 * @param string $str The input string. 11197 * @return array 11198 */ 11199 function parse_str($str) 11200 { 11201 $return = array(); 11202 $str = explode('&', $str); 11203 11204 foreach ($str as $section) 11205 { 11206 if (strpos($section, '=') !== false) 11207 { 11208 list($name, $value) = explode('=', $section, 2); 11209 $return[urldecode($name)][] = urldecode($value); 11210 } 11211 else 11212 { 11213 $return[urldecode($section)][] = null; 11214 } 11215 } 11216 11217 return $return; 11218 } 11219 11220 /** 11221 * Detect XML encoding, as per XML 1.0 Appendix F.1 11222 * 11223 * @todo Add support for EBCDIC 11224 * @param string $data XML data 11225 * @return array Possible encodings 11226 */ 11227 function xml_encoding($data) 11228 { 11229 // UTF-32 Big Endian BOM 11230 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") 11231 { 11232 $encoding[] = 'UTF-32BE'; 11233 } 11234 // UTF-32 Little Endian BOM 11235 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") 11236 { 11237 $encoding[] = 'UTF-32LE'; 11238 } 11239 // UTF-16 Big Endian BOM 11240 elseif (substr($data, 0, 2) === "\xFE\xFF") 11241 { 11242 $encoding[] = 'UTF-16BE'; 11243 } 11244 // UTF-16 Little Endian BOM 11245 elseif (substr($data, 0, 2) === "\xFF\xFE") 11246 { 11247 $encoding[] = 'UTF-16LE'; 11248 } 11249 // UTF-8 BOM 11250 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") 11251 { 11252 $encoding[] = 'UTF-8'; 11253 } 11254 // UTF-32 Big Endian Without BOM 11255 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") 11256 { 11257 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E")) 11258 { 11259 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8')); 11260 if ($parser->parse()) 11261 { 11262 $encoding[] = $parser->encoding; 11263 } 11264 } 11265 $encoding[] = 'UTF-32BE'; 11266 } 11267 // UTF-32 Little Endian Without BOM 11268 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") 11269 { 11270 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00")) 11271 { 11272 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8')); 11273 if ($parser->parse()) 11274 { 11275 $encoding[] = $parser->encoding; 11276 } 11277 } 11278 $encoding[] = 'UTF-32LE'; 11279 } 11280 // UTF-16 Big Endian Without BOM 11281 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C") 11282 { 11283 if ($pos = strpos($data, "\x00\x3F\x00\x3E")) 11284 { 11285 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8')); 11286 if ($parser->parse()) 11287 { 11288 $encoding[] = $parser->encoding; 11289 } 11290 } 11291 $encoding[] = 'UTF-16BE'; 11292 } 11293 // UTF-16 Little Endian Without BOM 11294 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00") 11295 { 11296 if ($pos = strpos($data, "\x3F\x00\x3E\x00")) 11297 { 11298 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8')); 11299 if ($parser->parse()) 11300 { 11301 $encoding[] = $parser->encoding; 11302 } 11303 } 11304 $encoding[] = 'UTF-16LE'; 11305 } 11306 // US-ASCII (or superset) 11307 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C") 11308 { 11309 if ($pos = strpos($data, "\x3F\x3E")) 11310 { 11311 $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5)); 11312 if ($parser->parse()) 11313 { 11314 $encoding[] = $parser->encoding; 11315 } 11316 } 11317 $encoding[] = 'UTF-8'; 11318 } 11319 // Fallback to UTF-8 11320 else 11321 { 11322 $encoding[] = 'UTF-8'; 11323 } 11324 return $encoding; 11325 } 11326 11327 function output_javascript() 11328 { 11329 if (function_exists('ob_gzhandler')) 11330 { 11331 ob_start('ob_gzhandler'); 11332 } 11333 header('Content-type: text/javascript; charset: UTF-8'); 11334 header('Cache-Control: must-revalidate'); 11335 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days 11336 ?> 11337function embed_odeo(link) { 11338 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>'); 11339} 11340 11341function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) { 11342 if (placeholder != '') { 11343 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>'); 11344 } 11345 else { 11346 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>'); 11347 } 11348} 11349 11350function embed_flash(bgcolor, width, height, link, loop, type) { 11351 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>'); 11352} 11353 11354function embed_flv(width, height, link, placeholder, loop, player) { 11355 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>'); 11356} 11357 11358function embed_wmedia(width, height, link) { 11359 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>'); 11360} 11361 <?php 11362 } 11363} 11364 11365/** 11366 * Decode HTML Entities 11367 * 11368 * This implements HTML5 as of revision 967 (2007-06-28) 11369 * 11370 * @package SimplePie 11371 */ 11372class SimplePie_Decode_HTML_Entities 11373{ 11374 /** 11375 * Data to be parsed 11376 * 11377 * @access private 11378 * @var string 11379 */ 11380 var $data = ''; 11381 11382 /** 11383 * Currently consumed bytes 11384 * 11385 * @access private 11386 * @var string 11387 */ 11388 var $consumed = ''; 11389 11390 /** 11391 * Position of the current byte being parsed 11392 * 11393 * @access private 11394 * @var int 11395 */ 11396 var $position = 0; 11397 11398 /** 11399 * Create an instance of the class with the input data 11400 * 11401 * @access public 11402 * @param string $data Input data 11403 */ 11404 function SimplePie_Decode_HTML_Entities($data) 11405 { 11406 $this->data = $data; 11407 } 11408 11409 /** 11410 * Parse the input data 11411 * 11412 * @access public 11413 * @return string Output data 11414 */ 11415 function parse() 11416 { 11417 while (($this->position = strpos($this->data, '&', $this->position)) !== false) 11418 { 11419 $this->consume(); 11420 $this->entity(); 11421 $this->consumed = ''; 11422 } 11423 return $this->data; 11424 } 11425 11426 /** 11427 * Consume the next byte 11428 * 11429 * @access private 11430 * @return mixed The next byte, or false, if there is no more data 11431 */ 11432 function consume() 11433 { 11434 if (isset($this->data[$this->position])) 11435 { 11436 $this->consumed .= $this->data[$this->position]; 11437 return $this->data[$this->position++]; 11438 } 11439 else 11440 { 11441 return false; 11442 } 11443 } 11444 11445 /** 11446 * Consume a range of characters 11447 * 11448 * @access private 11449 * @param string $chars Characters to consume 11450 * @return mixed A series of characters that match the range, or false 11451 */ 11452 function consume_range($chars) 11453 { 11454 if ($len = strspn($this->data, $chars, $this->position)) 11455 { 11456 $data = substr($this->data, $this->position, $len); 11457 $this->consumed .= $data; 11458 $this->position += $len; 11459 return $data; 11460 } 11461 else 11462 { 11463 return false; 11464 } 11465 } 11466 11467 /** 11468 * Unconsume one byte 11469 * 11470 * @access private 11471 */ 11472 function unconsume() 11473 { 11474 $this->consumed = substr($this->consumed, 0, -1); 11475 $this->position--; 11476 } 11477 11478 /** 11479 * Decode an entity 11480 * 11481 * @access private 11482 */ 11483 function entity() 11484 { 11485 switch ($this->consume()) 11486 { 11487 case "\x09": 11488 case "\x0A": 11489 case "\x0B": 11490 case "\x0B": 11491 case "\x0C": 11492 case "\x20": 11493 case "\x3C": 11494 case "\x26": 11495 case false: 11496 break; 11497 11498 case "\x23": 11499 switch ($this->consume()) 11500 { 11501 case "\x78": 11502 case "\x58": 11503 $range = '0123456789ABCDEFabcdef'; 11504 $hex = true; 11505 break; 11506 11507 default: 11508 $range = '0123456789'; 11509 $hex = false; 11510 $this->unconsume(); 11511 break; 11512 } 11513 11514 if ($codepoint = $this->consume_range($range)) 11515 { 11516 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"); 11517 11518 if ($hex) 11519 { 11520 $codepoint = hexdec($codepoint); 11521 } 11522 else 11523 { 11524 $codepoint = intval($codepoint); 11525 } 11526 11527 if (isset($windows_1252_specials[$codepoint])) 11528 { 11529 $replacement = $windows_1252_specials[$codepoint]; 11530 } 11531 else 11532 { 11533 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint); 11534 } 11535 11536 if (!in_array($this->consume(), array(';', false), true)) 11537 { 11538 $this->unconsume(); 11539 } 11540 11541 $consumed_length = strlen($this->consumed); 11542 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length); 11543 $this->position += strlen($replacement) - $consumed_length; 11544 } 11545 break; 11546 11547 default: 11548 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"); 11549 11550 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++) 11551 { 11552 $consumed = substr($this->consumed, 1); 11553 if (isset($entities[$consumed])) 11554 { 11555 $match = $consumed; 11556 } 11557 } 11558 11559 if ($match !== null) 11560 { 11561 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1); 11562 $this->position += strlen($entities[$match]) - strlen($consumed) - 1; 11563 } 11564 break; 11565 } 11566 } 11567} 11568 11569/** 11570 * IRI parser/serialiser 11571 * 11572 * @package SimplePie 11573 */ 11574class SimplePie_IRI 11575{ 11576 /** 11577 * Scheme 11578 * 11579 * @access private 11580 * @var string 11581 */ 11582 var $scheme; 11583 11584 /** 11585 * User Information 11586 * 11587 * @access private 11588 * @var string 11589 */ 11590 var $userinfo; 11591 11592 /** 11593 * Host 11594 * 11595 * @access private 11596 * @var string 11597 */ 11598 var $host; 11599 11600 /** 11601 * Port 11602 * 11603 * @access private 11604 * @var string 11605 */ 11606 var $port; 11607 11608 /** 11609 * Path 11610 * 11611 * @access private 11612 * @var string 11613 */ 11614 var $path; 11615 11616 /** 11617 * Query 11618 * 11619 * @access private 11620 * @var string 11621 */ 11622 var $query; 11623 11624 /** 11625 * Fragment 11626 * 11627 * @access private 11628 * @var string 11629 */ 11630 var $fragment; 11631 11632 /** 11633 * Whether the object represents a valid IRI 11634 * 11635 * @access private 11636 * @var array 11637 */ 11638 var $valid = array(); 11639 11640 /** 11641 * Return the entire IRI when you try and read the object as a string 11642 * 11643 * @access public 11644 * @return string 11645 */ 11646 function __toString() 11647 { 11648 return $this->get_iri(); 11649 } 11650 11651 /** 11652 * Create a new IRI object, from a specified string 11653 * 11654 * @access public 11655 * @param string $iri 11656 * @return SimplePie_IRI 11657 */ 11658 function SimplePie_IRI($iri) 11659 { 11660 $iri = (string) $iri; 11661 if ($iri !== '') 11662 { 11663 $parsed = $this->parse_iri($iri); 11664 $this->set_scheme($parsed['scheme']); 11665 $this->set_authority($parsed['authority']); 11666 $this->set_path($parsed['path']); 11667 $this->set_query($parsed['query']); 11668 $this->set_fragment($parsed['fragment']); 11669 } 11670 } 11671 11672 /** 11673 * Create a new IRI object by resolving a relative IRI 11674 * 11675 * @static 11676 * @access public 11677 * @param SimplePie_IRI $base Base IRI 11678 * @param string $relative Relative IRI 11679 * @return SimplePie_IRI 11680 */ 11681 function absolutize($base, $relative) 11682 { 11683 $relative = (string) $relative; 11684 if ($relative !== '') 11685 { 11686 $relative =& new SimplePie_IRI($relative); 11687 if ($relative->get_scheme() !== null) 11688 { 11689 $target = $relative; 11690 } 11691 elseif ($base->get_iri() !== null) 11692 { 11693 if ($relative->get_authority() !== null) 11694 { 11695 $target = $relative; 11696 $target->set_scheme($base->get_scheme()); 11697 } 11698 else 11699 { 11700 $target =& new SimplePie_IRI(''); 11701 $target->set_scheme($base->get_scheme()); 11702 $target->set_userinfo($base->get_userinfo()); 11703 $target->set_host($base->get_host()); 11704 $target->set_port($base->get_port()); 11705 if ($relative->get_path() !== null) 11706 { 11707 if (strpos($relative->get_path(), '/') === 0) 11708 { 11709 $target->set_path($relative->get_path()); 11710 } 11711 elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null) 11712 { 11713 $target->set_path('/' . $relative->get_path()); 11714 } 11715 elseif (($last_segment = strrpos($base->get_path(), '/')) !== false) 11716 { 11717 $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path()); 11718 } 11719 else 11720 { 11721 $target->set_path($relative->get_path()); 11722 } 11723 $target->set_query($relative->get_query()); 11724 } 11725 else 11726 { 11727 $target->set_path($base->get_path()); 11728 if ($relative->get_query() !== null) 11729 { 11730 $target->set_query($relative->get_query()); 11731 } 11732 elseif ($base->get_query() !== null) 11733 { 11734 $target->set_query($base->get_query()); 11735 } 11736 } 11737 } 11738 $target->set_fragment($relative->get_fragment()); 11739 } 11740 else 11741 { 11742 // No base URL, just return the relative URL 11743 $target = $relative; 11744 } 11745 } 11746 else 11747 { 11748 $target = $base; 11749 } 11750 return $target; 11751 } 11752 11753 /** 11754 * Parse an IRI into scheme/authority/path/query/fragment segments 11755 * 11756 * @access private 11757 * @param string $iri 11758 * @return array 11759 */ 11760 function parse_iri($iri) 11761 { 11762 preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match); 11763 for ($i = count($match); $i <= 9; $i++) 11764 { 11765 $match[$i] = ''; 11766 } 11767 return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]); 11768 } 11769 11770 /** 11771 * Remove dot segments from a path 11772 * 11773 * @access private 11774 * @param string $input 11775 * @return string 11776 */ 11777 function remove_dot_segments($input) 11778 { 11779 $output = ''; 11780 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..') 11781 { 11782 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise, 11783 if (strpos($input, '../') === 0) 11784 { 11785 $input = substr($input, 3); 11786 } 11787 elseif (strpos($input, './') === 0) 11788 { 11789 $input = substr($input, 2); 11790 } 11791 // 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, 11792 elseif (strpos($input, '/./') === 0) 11793 { 11794 $input = substr_replace($input, '/', 0, 3); 11795 } 11796 elseif ($input === '/.') 11797 { 11798 $input = '/'; 11799 } 11800 // 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, 11801 elseif (strpos($input, '/../') === 0) 11802 { 11803 $input = substr_replace($input, '/', 0, 4); 11804 $output = substr_replace($output, '', strrpos($output, '/')); 11805 } 11806 elseif ($input === '/..') 11807 { 11808 $input = '/'; 11809 $output = substr_replace($output, '', strrpos($output, '/')); 11810 } 11811 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise, 11812 elseif ($input === '.' || $input === '..') 11813 { 11814 $input = ''; 11815 } 11816 // 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 11817 elseif (($pos = strpos($input, '/', 1)) !== false) 11818 { 11819 $output .= substr($input, 0, $pos); 11820 $input = substr_replace($input, '', 0, $pos); 11821 } 11822 else 11823 { 11824 $output .= $input; 11825 $input = ''; 11826 } 11827 } 11828 return $output . $input; 11829 } 11830 11831 /** 11832 * Replace invalid character with percent encoding 11833 * 11834 * @access private 11835 * @param string $string Input string 11836 * @param string $valid_chars Valid characters 11837 * @param int $case Normalise case 11838 * @return string 11839 */ 11840 function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE) 11841 { 11842 // Normalise case 11843 if ($case & SIMPLEPIE_LOWERCASE) 11844 { 11845 $string = strtolower($string); 11846 } 11847 elseif ($case & SIMPLEPIE_UPPERCASE) 11848 { 11849 $string = strtoupper($string); 11850 } 11851 11852 // Store position and string length (to avoid constantly recalculating this) 11853 $position = 0; 11854 $strlen = strlen($string); 11855 11856 // Loop as long as we have invalid characters, advancing the position to the next invalid character 11857 while (($position += strspn($string, $valid_chars, $position)) < $strlen) 11858 { 11859 // If we have a % character 11860 if ($string[$position] === '%') 11861 { 11862 // If we have a pct-encoded section 11863 if ($position + 2 < $strlen && strspn($string, '0123456789ABCDEFabcdef', $position + 1, 2) === 2) 11864 { 11865 // Get the the represented character 11866 $chr = chr(hexdec(substr($string, $position + 1, 2))); 11867 11868 // If the character is valid, replace the pct-encoded with the actual character while normalising case 11869 if (strpos($valid_chars, $chr) !== false) 11870 { 11871 if ($case & SIMPLEPIE_LOWERCASE) 11872 { 11873 $chr = strtolower($chr); 11874 } 11875 elseif ($case & SIMPLEPIE_UPPERCASE) 11876 { 11877 $chr = strtoupper($chr); 11878 } 11879 $string = substr_replace($string, $chr, $position, 3); 11880 $strlen -= 2; 11881 $position++; 11882 } 11883 11884 // Otherwise just normalise the pct-encoded to uppercase 11885 else 11886 { 11887 $string = substr_replace($string, strtoupper(substr($string, $position + 1, 2)), $position + 1, 2); 11888 $position += 3; 11889 } 11890 } 11891 // If we don't have a pct-encoded section, just replace the % with its own esccaped form 11892 else 11893 { 11894 $string = substr_replace($string, '%25', $position, 1); 11895 $strlen += 2; 11896 $position += 3; 11897 } 11898 } 11899 // If we have an invalid character, change into its pct-encoded form 11900 else 11901 { 11902 $replacement = sprintf("%%%02X", ord($string[$position])); 11903 $string = str_replace($string[$position], $replacement, $string); 11904 $strlen = strlen($string); 11905 } 11906 } 11907 return $string; 11908 } 11909 11910 /** 11911 * Check if the object represents a valid IRI 11912 * 11913 * @access public 11914 * @return bool 11915 */ 11916 function is_valid() 11917 { 11918 return array_sum($this->valid) === count($this->valid); 11919 } 11920 11921 /** 11922 * Set the scheme. Returns true on success, false on failure (if there are 11923 * any invalid characters). 11924 * 11925 * @access public 11926 * @param string $scheme 11927 * @return bool 11928 */ 11929 function set_scheme($scheme) 11930 { 11931 if ($scheme === null || $scheme === '') 11932 { 11933 $this->scheme = null; 11934 } 11935 else 11936 { 11937 $len = strlen($scheme); 11938 switch (true) 11939 { 11940 case $len > 1: 11941 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1)) 11942 { 11943 $this->scheme = null; 11944 $this->valid[__FUNCTION__] = false; 11945 return false; 11946 } 11947 11948 case $len > 0: 11949 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1)) 11950 { 11951 $this->scheme = null; 11952 $this->valid[__FUNCTION__] = false; 11953 return false; 11954 } 11955 } 11956 $this->scheme = strtolower($scheme); 11957 } 11958 $this->valid[__FUNCTION__] = true; 11959 return true; 11960 } 11961 11962 /** 11963 * Set the authority. Returns true on success, false on failure (if there are 11964 * any invalid characters). 11965 * 11966 * @access public 11967 * @param string $authority 11968 * @return bool 11969 */ 11970 function set_authority($authority) 11971 { 11972 if (($userinfo_end = strrpos($authority, '@')) !== false) 11973 { 11974 $userinfo = substr($authority, 0, $userinfo_end); 11975 $authority = substr($authority, $userinfo_end + 1); 11976 } 11977 else 11978 { 11979 $userinfo = null; 11980 } 11981 11982 if (($port_start = strpos($authority, ':')) !== false) 11983 { 11984 $port = substr($authority, $port_start + 1); 11985 $authority = substr($authority, 0, $port_start); 11986 } 11987 else 11988 { 11989 $port = null; 11990 } 11991 11992 return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port); 11993 } 11994 11995 /** 11996 * Set the userinfo. 11997 * 11998 * @access public 11999 * @param string $userinfo 12000 * @return bool 12001 */ 12002 function set_userinfo($userinfo) 12003 { 12004 if ($userinfo === null || $userinfo === '') 12005 { 12006 $this->userinfo = null; 12007 } 12008 else 12009 { 12010 $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:'); 12011 } 12012 $this->valid[__FUNCTION__] = true; 12013 return true; 12014 } 12015 12016 /** 12017 * Set the host. Returns true on success, false on failure (if there are 12018 * any invalid characters). 12019 * 12020 * @access public 12021 * @param string $host 12022 * @return bool 12023 */ 12024 function set_host($host) 12025 { 12026 if ($host === null || $host === '') 12027 { 12028 $this->host = null; 12029 $this->valid[__FUNCTION__] = true; 12030 return true; 12031 } 12032 elseif ($host[0] === '[' && substr($host, -1) === ']') 12033 { 12034 if (Net_IPv6::checkIPv6(substr($host, 1, -1))) 12035 { 12036 $this->host = $host; 12037 $this->valid[__FUNCTION__] = true; 12038 return true; 12039 } 12040 else 12041 { 12042 $this->host = null; 12043 $this->valid[__FUNCTION__] = false; 12044 return false; 12045 } 12046 } 12047 else 12048 { 12049 $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE); 12050 $this->valid[__FUNCTION__] = true; 12051 return true; 12052 } 12053 } 12054 12055 /** 12056 * Set the port. Returns true on success, false on failure (if there are 12057 * any invalid characters). 12058 * 12059 * @access public 12060 * @param string $port 12061 * @return bool 12062 */ 12063 function set_port($port) 12064 { 12065 if ($port === null || $port === '') 12066 { 12067 $this->port = null; 12068 $this->valid[__FUNCTION__] = true; 12069 return true; 12070 } 12071 elseif (strspn($port, '0123456789') === strlen($port)) 12072 { 12073 $this->port = (int) $port; 12074 $this->valid[__FUNCTION__] = true; 12075 return true; 12076 } 12077 else 12078 { 12079 $this->port = null; 12080 $this->valid[__FUNCTION__] = false; 12081 return false; 12082 } 12083 } 12084 12085 /** 12086 * Set the path. 12087 * 12088 * @access public 12089 * @param string $path 12090 * @return bool 12091 */ 12092 function set_path($path) 12093 { 12094 if ($path === null || $path === '') 12095 { 12096 $this->path = null; 12097 $this->valid[__FUNCTION__] = true; 12098 return true; 12099 } 12100 elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null) 12101 { 12102 $this->path = null; 12103 $this->valid[__FUNCTION__] = false; 12104 return false; 12105 } 12106 else 12107 { 12108 $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/'); 12109 if ($this->scheme !== null) 12110 { 12111 $this->path = $this->remove_dot_segments($this->path); 12112 } 12113 $this->valid[__FUNCTION__] = true; 12114 return true; 12115 } 12116 } 12117 12118 /** 12119 * Set the query. 12120 * 12121 * @access public 12122 * @param string $query 12123 * @return bool 12124 */ 12125 function set_query($query) 12126 { 12127 if ($query === null || $query === '') 12128 { 12129 $this->query = null; 12130 } 12131 else 12132 { 12133 $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?'); 12134 } 12135 $this->valid[__FUNCTION__] = true; 12136 return true; 12137 } 12138 12139 /** 12140 * Set the fragment. 12141 * 12142 * @access public 12143 * @param string $fragment 12144 * @return bool 12145 */ 12146 function set_fragment($fragment) 12147 { 12148 if ($fragment === null || $fragment === '') 12149 { 12150 $this->fragment = null; 12151 } 12152 else 12153 { 12154 $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?'); 12155 } 12156 $this->valid[__FUNCTION__] = true; 12157 return true; 12158 } 12159 12160 /** 12161 * Get the complete IRI 12162 * 12163 * @access public 12164 * @return string 12165 */ 12166 function get_iri() 12167 { 12168 $iri = ''; 12169 if ($this->scheme !== null) 12170 { 12171 $iri .= $this->scheme . ':'; 12172 } 12173 if (($authority = $this->get_authority()) !== null) 12174 { 12175 $iri .= '//' . $authority; 12176 } 12177 if ($this->path !== null) 12178 { 12179 $iri .= $this->path; 12180 } 12181 if ($this->query !== null) 12182 { 12183 $iri .= '?' . $this->query; 12184 } 12185 if ($this->fragment !== null) 12186 { 12187 $iri .= '#' . $this->fragment; 12188 } 12189 12190 if ($iri !== '') 12191 { 12192 return $iri; 12193 } 12194 else 12195 { 12196 return null; 12197 } 12198 } 12199 12200 /** 12201 * Get the scheme 12202 * 12203 * @access public 12204 * @return string 12205 */ 12206 function get_scheme() 12207 { 12208 return $this->scheme; 12209 } 12210 12211 /** 12212 * Get the complete authority 12213 * 12214 * @access public 12215 * @return string 12216 */ 12217 function get_authority() 12218 { 12219 $authority = ''; 12220 if ($this->userinfo !== null) 12221 { 12222 $authority .= $this->userinfo . '@'; 12223 } 12224 if ($this->host !== null) 12225 { 12226 $authority .= $this->host; 12227 } 12228 if ($this->port !== null) 12229 { 12230 $authority .= ':' . $this->port; 12231 } 12232 12233 if ($authority !== '') 12234 { 12235 return $authority; 12236 } 12237 else 12238 { 12239 return null; 12240 } 12241 } 12242 12243 /** 12244 * Get the user information 12245 * 12246 * @access public 12247 * @return string 12248 */ 12249 function get_userinfo() 12250 { 12251 return $this->userinfo; 12252 } 12253 12254 /** 12255 * Get the host 12256 * 12257 * @access public 12258 * @return string 12259 */ 12260 function get_host() 12261 { 12262 return $this->host; 12263 } 12264 12265 /** 12266 * Get the port 12267 * 12268 * @access public 12269 * @return string 12270 */ 12271 function get_port() 12272 { 12273 return $this->port; 12274 } 12275 12276 /** 12277 * Get the path 12278 * 12279 * @access public 12280 * @return string 12281 */ 12282 function get_path() 12283 { 12284 return $this->path; 12285 } 12286 12287 /** 12288 * Get the query 12289 * 12290 * @access public 12291 * @return string 12292 */ 12293 function get_query() 12294 { 12295 return $this->query; 12296 } 12297 12298 /** 12299 * Get the fragment 12300 * 12301 * @access public 12302 * @return string 12303 */ 12304 function get_fragment() 12305 { 12306 return $this->fragment; 12307 } 12308} 12309 12310/** 12311 * Class to validate and to work with IPv6 addresses. 12312 * 12313 * @package SimplePie 12314 * @copyright 2003-2005 The PHP Group 12315 * @license http://www.opensource.org/licenses/bsd-license.php 12316 * @link http://pear.php.net/package/Net_IPv6 12317 * @author Alexander Merz <alexander.merz@web.de> 12318 * @author elfrink at introweb dot nl 12319 * @author Josh Peck <jmp at joshpeck dot org> 12320 * @author Geoffrey Sneddon <geoffers@gmail.com> 12321 */ 12322class SimplePie_Net_IPv6 12323{ 12324 /** 12325 * Removes a possible existing netmask specification of an IP address. 12326 * 12327 * @param string $ip the (compressed) IP as Hex representation 12328 * @return string the IP the without netmask 12329 * @since 1.1.0 12330 * @access public 12331 * @static 12332 */ 12333 function removeNetmaskSpec($ip) 12334 { 12335 if (strpos($ip, '/') !== false) 12336 { 12337 list($addr, $nm) = explode('/', $ip); 12338 } 12339 else 12340 { 12341 $addr = $ip; 12342 } 12343 return $addr; 12344 } 12345 12346 /** 12347 * Uncompresses an IPv6 address 12348 * 12349 * RFC 2373 allows you to compress zeros in an address to '::'. This 12350 * function expects an valid IPv6 address and expands the '::' to 12351 * the required zeros. 12352 * 12353 * Example: FF01::101 -> FF01:0:0:0:0:0:0:101 12354 * ::1 -> 0:0:0:0:0:0:0:1 12355 * 12356 * @access public 12357 * @static 12358 * @param string $ip a valid IPv6-address (hex format) 12359 * @return string the uncompressed IPv6-address (hex format) 12360 */ 12361 function Uncompress($ip) 12362 { 12363 $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip); 12364 $c1 = -1; 12365 $c2 = -1; 12366 if (strpos($ip, '::') !== false) 12367 { 12368 list($ip1, $ip2) = explode('::', $ip); 12369 if ($ip1 === '') 12370 { 12371 $c1 = -1; 12372 } 12373 else 12374 { 12375 $pos = 0; 12376 if (($pos = substr_count($ip1, ':')) > 0) 12377 { 12378 $c1 = $pos; 12379 } 12380 else 12381 { 12382 $c1 = 0; 12383 } 12384 } 12385 if ($ip2 === '') 12386 { 12387 $c2 = -1; 12388 } 12389 else 12390 { 12391 $pos = 0; 12392 if (($pos = substr_count($ip2, ':')) > 0) 12393 { 12394 $c2 = $pos; 12395 } 12396 else 12397 { 12398 $c2 = 0; 12399 } 12400 } 12401 if (strstr($ip2, '.')) 12402 { 12403 $c2++; 12404 } 12405 // :: 12406 if ($c1 === -1 && $c2 === -1) 12407 { 12408 $uip = '0:0:0:0:0:0:0:0'; 12409 } 12410 // ::xxx 12411 else if ($c1 === -1) 12412 { 12413 $fill = str_repeat('0:', 7 - $c2); 12414 $uip = str_replace('::', $fill, $uip); 12415 } 12416 // xxx:: 12417 else if ($c2 === -1) 12418 { 12419 $fill = str_repeat(':0', 7 - $c1); 12420 $uip = str_replace('::', $fill, $uip); 12421 } 12422 // xxx::xxx 12423 else 12424 { 12425 $fill = str_repeat(':0:', 6 - $c2 - $c1); 12426 $uip = str_replace('::', $fill, $uip); 12427 $uip = str_replace('::', ':', $uip); 12428 } 12429 } 12430 return $uip; 12431 } 12432 12433 /** 12434 * Splits an IPv6 address into the IPv6 and a possible IPv4 part 12435 * 12436 * RFC 2373 allows you to note the last two parts of an IPv6 address as 12437 * an IPv4 compatible address 12438 * 12439 * Example: 0:0:0:0:0:0:13.1.68.3 12440 * 0:0:0:0:0:FFFF:129.144.52.38 12441 * 12442 * @access public 12443 * @static 12444 * @param string $ip a valid IPv6-address (hex format) 12445 * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format) 12446 */ 12447 function SplitV64($ip) 12448 { 12449 $ip = SimplePie_Net_IPv6::Uncompress($ip); 12450 if (strstr($ip, '.')) 12451 { 12452 $pos = strrpos($ip, ':'); 12453 $ip[$pos] = '_'; 12454 $ipPart = explode('_', $ip); 12455 return $ipPart; 12456 } 12457 else 12458 { 12459 return array($ip, ''); 12460 } 12461 } 12462 12463 /** 12464 * Checks an IPv6 address 12465 * 12466 * Checks if the given IP is IPv6-compatible 12467 * 12468 * @access public 12469 * @static 12470 * @param string $ip a valid IPv6-address 12471 * @return bool true if $ip is an IPv6 address 12472 */ 12473 function checkIPv6($ip) 12474 { 12475 $ipPart = SimplePie_Net_IPv6::SplitV64($ip); 12476 $count = 0; 12477 if (!empty($ipPart[0])) 12478 { 12479 $ipv6 = explode(':', $ipPart[0]); 12480 for ($i = 0; $i < count($ipv6); $i++) 12481 { 12482 $dec = hexdec($ipv6[$i]); 12483 $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i])); 12484 if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec))) 12485 { 12486 $count++; 12487 } 12488 } 12489 if ($count === 8) 12490 { 12491 return true; 12492 } 12493 elseif ($count === 6 && !empty($ipPart[1])) 12494 { 12495 $ipv4 = explode('.', $ipPart[1]); 12496 $count = 0; 12497 foreach ($ipv4 as $ipv4_part) 12498 { 12499 if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part)) 12500 { 12501 $count++; 12502 } 12503 } 12504 if ($count === 4) 12505 { 12506 return true; 12507 } 12508 } 12509 else 12510 { 12511 return false; 12512 } 12513 12514 } 12515 else 12516 { 12517 return false; 12518 } 12519 } 12520} 12521 12522/** 12523 * Date Parser 12524 * 12525 * @package SimplePie 12526 */ 12527class SimplePie_Parse_Date 12528{ 12529 /** 12530 * Input data 12531 * 12532 * @access protected 12533 * @var string 12534 */ 12535 var $date; 12536 12537 /** 12538 * List of days, calendar day name => ordinal day number in the week 12539 * 12540 * @access protected 12541 * @var array 12542 */ 12543 var $day = array( 12544 // English 12545 'mon' => 1, 12546 'monday' => 1, 12547 'tue' => 2, 12548 'tuesday' => 2, 12549 'wed' => 3, 12550 'wednesday' => 3, 12551 'thu' => 4, 12552 'thursday' => 4, 12553 'fri' => 5, 12554 'friday' => 5, 12555 'sat' => 6, 12556 'saturday' => 6, 12557 'sun' => 7, 12558 'sunday' => 7, 12559 // Dutch 12560 'maandag' => 1, 12561 'dinsdag' => 2, 12562 'woensdag' => 3, 12563 'donderdag' => 4, 12564 'vrijdag' => 5, 12565 'zaterdag' => 6, 12566 'zondag' => 7, 12567 // French 12568 'lundi' => 1, 12569 'mardi' => 2, 12570 'mercredi' => 3, 12571 'jeudi' => 4, 12572 'vendredi' => 5, 12573 'samedi' => 6, 12574 'dimanche' => 7, 12575 // German 12576 'montag' => 1, 12577 'dienstag' => 2, 12578 'mittwoch' => 3, 12579 'donnerstag' => 4, 12580 'freitag' => 5, 12581 'samstag' => 6, 12582 'sonnabend' => 6, 12583 'sonntag' => 7, 12584 // Italian 12585 'lunedì' => 1, 12586 'martedì' => 2, 12587 'mercoledì' => 3, 12588 'giovedì' => 4, 12589 'venerdì' => 5, 12590 'sabato' => 6, 12591 'domenica' => 7, 12592 // Spanish 12593 'lunes' => 1, 12594 'martes' => 2, 12595 'miércoles' => 3, 12596 'jueves' => 4, 12597 'viernes' => 5, 12598 'sábado' => 6, 12599 'domingo' => 7, 12600 // Finnish 12601 'maanantai' => 1, 12602 'tiistai' => 2, 12603 'keskiviikko' => 3, 12604 'torstai' => 4, 12605 'perjantai' => 5, 12606 'lauantai' => 6, 12607 'sunnuntai' => 7, 12608 // Hungarian 12609 'hétfő' => 1, 12610 'kedd' => 2, 12611 'szerda' => 3, 12612 'csütörtok' => 4, 12613 'péntek' => 5, 12614 'szombat' => 6, 12615 'vasárnap' => 7, 12616 // Greek 12617 'Δευ' => 1, 12618 'Τρι' => 2, 12619 'Τετ' => 3, 12620 'Πεμ' => 4, 12621 'Παρ' => 5, 12622 'Σαβ' => 6, 12623 'Κυρ' => 7, 12624 ); 12625 12626 /** 12627 * List of months, calendar month name => calendar month number 12628 * 12629 * @access protected 12630 * @var array 12631 */ 12632 var $month = array( 12633 // English 12634 'jan' => 1, 12635 'january' => 1, 12636 'feb' => 2, 12637 'february' => 2, 12638 'mar' => 3, 12639 'march' => 3, 12640 'apr' => 4, 12641 'april' => 4, 12642 'may' => 5, 12643 // No long form of May 12644 'jun' => 6, 12645 'june' => 6, 12646 'jul' => 7, 12647 'july' => 7, 12648 'aug' => 8, 12649 'august' => 8, 12650 'sep' => 9, 12651 'september' => 8, 12652 'oct' => 10, 12653 'october' => 10, 12654 'nov' => 11, 12655 'november' => 11, 12656 'dec' => 12, 12657 'december' => 12, 12658 // Dutch 12659 'januari' => 1, 12660 'februari' => 2, 12661 'maart' => 3, 12662 'april' => 4, 12663 'mei' => 5, 12664 'juni' => 6, 12665 'juli' => 7, 12666 'augustus' => 8, 12667 'september' => 9, 12668 'oktober' => 10, 12669 'november' => 11, 12670 'december' => 12, 12671 // French 12672 'janvier' => 1, 12673 'février' => 2, 12674 'mars' => 3, 12675 'avril' => 4, 12676 'mai' => 5, 12677 'juin' => 6, 12678 'juillet' => 7, 12679 'août' => 8, 12680 'septembre' => 9, 12681 'octobre' => 10, 12682 'novembre' => 11, 12683 'décembre' => 12, 12684 // German 12685 'januar' => 1, 12686 'februar' => 2, 12687 'märz' => 3, 12688 'april' => 4, 12689 'mai' => 5, 12690 'juni' => 6, 12691 'juli' => 7, 12692 'august' => 8, 12693 'september' => 9, 12694 'oktober' => 10, 12695 'november' => 11, 12696 'dezember' => 12, 12697 // Italian 12698 'gennaio' => 1, 12699 'febbraio' => 2, 12700 'marzo' => 3, 12701 'aprile' => 4, 12702 'maggio' => 5, 12703 'giugno' => 6, 12704 'luglio' => 7, 12705 'agosto' => 8, 12706 'settembre' => 9, 12707 'ottobre' => 10, 12708 'novembre' => 11, 12709 'dicembre' => 12, 12710 // Spanish 12711 'enero' => 1, 12712 'febrero' => 2, 12713 'marzo' => 3, 12714 'abril' => 4, 12715 'mayo' => 5, 12716 'junio' => 6, 12717 'julio' => 7, 12718 'agosto' => 8, 12719 'septiembre' => 9, 12720 'setiembre' => 9, 12721 'octubre' => 10, 12722 'noviembre' => 11, 12723 'diciembre' => 12, 12724 // Finnish 12725 'tammikuu' => 1, 12726 'helmikuu' => 2, 12727 'maaliskuu' => 3, 12728 'huhtikuu' => 4, 12729 'toukokuu' => 5, 12730 'kesäkuu' => 6, 12731 'heinäkuu' => 7, 12732 'elokuu' => 8, 12733 'suuskuu' => 9, 12734 'lokakuu' => 10, 12735 'marras' => 11, 12736 'joulukuu' => 12, 12737 // Hungarian 12738 'január' => 1, 12739 'február' => 2, 12740 'március' => 3, 12741 'április' => 4, 12742 'május' => 5, 12743 'június' => 6, 12744 'július' => 7, 12745 'augusztus' => 8, 12746 'szeptember' => 9, 12747 'október' => 10, 12748 'november' => 11, 12749 'december' => 12, 12750 // Greek 12751 'Ιαν' => 1, 12752 'Φεβ' => 2, 12753 'Μάώ' => 3, 12754 'Μαώ' => 3, 12755 'Απρ' => 4, 12756 'Μάι' => 5, 12757 'Μαϊ' => 5, 12758 'Μαι' => 5, 12759 'Ιούν' => 6, 12760 'Ιον' => 6, 12761 'Ιούλ' => 7, 12762 'Ιολ' => 7, 12763 'Αύγ' => 8, 12764 'Αυγ' => 8, 12765 'Σεπ' => 9, 12766 'Οκτ' => 10, 12767 'Νοέ' => 11, 12768 'Δεκ' => 12, 12769 ); 12770 12771 /** 12772 * List of timezones, abbreviation => offset from UTC 12773 * 12774 * @access protected 12775 * @var array 12776 */ 12777 var $timezone = array( 12778 'ACDT' => 37800, 12779 'ACIT' => 28800, 12780 'ACST' => 34200, 12781 'ACT' => -18000, 12782 'ACWDT' => 35100, 12783 'ACWST' => 31500, 12784 'AEDT' => 39600, 12785 'AEST' => 36000, 12786 'AFT' => 16200, 12787 'AKDT' => -28800, 12788 'AKST' => -32400, 12789 'AMDT' => 18000, 12790 'AMT' => -14400, 12791 'ANAST' => 46800, 12792 'ANAT' => 43200, 12793 'ART' => -10800, 12794 'AZOST' => -3600, 12795 'AZST' => 18000, 12796 'AZT' => 14400, 12797 'BIOT' => 21600, 12798 'BIT' => -43200, 12799 'BOT' => -14400, 12800 'BRST' => -7200, 12801 'BRT' => -10800, 12802 'BST' => 3600, 12803 'BTT' => 21600, 12804 'CAST' => 18000, 12805 'CAT' => 7200, 12806 'CCT' => 23400, 12807 'CDT' => -18000, 12808 'CEDT' => 7200, 12809 'CET' => 3600, 12810 'CGST' => -7200, 12811 'CGT' => -10800, 12812 'CHADT' => 49500, 12813 'CHAST' => 45900, 12814 'CIST' => -28800, 12815 'CKT' => -36000, 12816 'CLDT' => -10800, 12817 'CLST' => -14400, 12818 'COT' => -18000, 12819 'CST' => -21600, 12820 'CVT' => -3600, 12821 'CXT' => 25200, 12822 'DAVT' => 25200, 12823 'DTAT' => 36000, 12824 'EADT' => -18000, 12825 'EAST' => -21600, 12826 'EAT' => 10800, 12827 'ECT' => -18000, 12828 'EDT' => -14400, 12829 'EEST' => 10800, 12830 'EET' => 7200, 12831 'EGT' => -3600, 12832 'EKST' => 21600, 12833 'EST' => -18000, 12834 'FJT' => 43200, 12835 'FKDT' => -10800, 12836 'FKST' => -14400, 12837 'FNT' => -7200, 12838 'GALT' => -21600, 12839 'GEDT' => 14400, 12840 'GEST' => 10800, 12841 'GFT' => -10800, 12842 'GILT' => 43200, 12843 'GIT' => -32400, 12844 'GST' => 14400, 12845 'GST' => -7200, 12846 'GYT' => -14400, 12847 'HAA' => -10800, 12848 'HAC' => -18000, 12849 'HADT' => -32400, 12850 'HAE' => -14400, 12851 'HAP' => -25200, 12852 'HAR' => -21600, 12853 'HAST' => -36000, 12854 'HAT' => -9000, 12855 'HAY' => -28800, 12856 'HKST' => 28800, 12857 'HMT' => 18000, 12858 'HNA' => -14400, 12859 'HNC' => -21600, 12860 'HNE' => -18000, 12861 'HNP' => -28800, 12862 'HNR' => -25200, 12863 'HNT' => -12600, 12864 'HNY' => -32400, 12865 'IRDT' => 16200, 12866 'IRKST' => 32400, 12867 'IRKT' => 28800, 12868 'IRST' => 12600, 12869 'JFDT' => -10800, 12870 'JFST' => -14400, 12871 'JST' => 32400, 12872 'KGST' => 21600, 12873 'KGT' => 18000, 12874 'KOST' => 39600, 12875 'KOVST' => 28800, 12876 'KOVT' => 25200, 12877 'KRAST' => 28800, 12878 'KRAT' => 25200, 12879 'KST' => 32400, 12880 'LHDT' => 39600, 12881 'LHST' => 37800, 12882 'LINT' => 50400, 12883 'LKT' => 21600, 12884 'MAGST' => 43200, 12885 'MAGT' => 39600, 12886 'MAWT' => 21600, 12887 'MDT' => -21600, 12888 'MESZ' => 7200, 12889 'MEZ' => 3600, 12890 'MHT' => 43200, 12891 'MIT' => -34200, 12892 'MNST' => 32400, 12893 'MSDT' => 14400, 12894 'MSST' => 10800, 12895 'MST' => -25200, 12896 'MUT' => 14400, 12897 'MVT' => 18000, 12898 'MYT' => 28800, 12899 'NCT' => 39600, 12900 'NDT' => -9000, 12901 'NFT' => 41400, 12902 'NMIT' => 36000, 12903 'NOVST' => 25200, 12904 'NOVT' => 21600, 12905 'NPT' => 20700, 12906 'NRT' => 43200, 12907 'NST' => -12600, 12908 'NUT' => -39600, 12909 'NZDT' => 46800, 12910 'NZST' => 43200, 12911 'OMSST' => 25200, 12912 'OMST' => 21600, 12913 'PDT' => -25200, 12914 'PET' => -18000, 12915 'PETST' => 46800, 12916 'PETT' => 43200, 12917 'PGT' => 36000, 12918 'PHOT' => 46800, 12919 'PHT' => 28800, 12920 'PKT' => 18000, 12921 'PMDT' => -7200, 12922 'PMST' => -10800, 12923 'PONT' => 39600, 12924 'PST' => -28800, 12925 'PWT' => 32400, 12926 'PYST' => -10800, 12927 'PYT' => -14400, 12928 'RET' => 14400, 12929 'ROTT' => -10800, 12930 'SAMST' => 18000, 12931 'SAMT' => 14400, 12932 'SAST' => 7200, 12933 'SBT' => 39600, 12934 'SCDT' => 46800, 12935 'SCST' => 43200, 12936 'SCT' => 14400, 12937 'SEST' => 3600, 12938 'SGT' => 28800, 12939 'SIT' => 28800, 12940 'SRT' => -10800, 12941 'SST' => -39600, 12942 'SYST' => 10800, 12943 'SYT' => 7200, 12944 'TFT' => 18000, 12945 'THAT' => -36000, 12946 'TJT' => 18000, 12947 'TKT' => -36000, 12948 'TMT' => 18000, 12949 'TOT' => 46800, 12950 'TPT' => 32400, 12951 'TRUT' => 36000, 12952 'TVT' => 43200, 12953 'TWT' => 28800, 12954 'UYST' => -7200, 12955 'UYT' => -10800, 12956 'UZT' => 18000, 12957 'VET' => -14400, 12958 'VLAST' => 39600, 12959 'VLAT' => 36000, 12960 'VOST' => 21600, 12961 'VUT' => 39600, 12962 'WAST' => 7200, 12963 'WAT' => 3600, 12964 'WDT' => 32400, 12965 'WEST' => 3600, 12966 'WFT' => 43200, 12967 'WIB' => 25200, 12968 'WIT' => 32400, 12969 'WITA' => 28800, 12970 'WKST' => 18000, 12971 'WST' => 28800, 12972 'YAKST' => 36000, 12973 'YAKT' => 32400, 12974 'YAPT' => 36000, 12975 'YEKST' => 21600, 12976 'YEKT' => 18000, 12977 ); 12978 12979 /** 12980 * Cached PCRE for SimplePie_Parse_Date::$day 12981 * 12982 * @access protected 12983 * @var string 12984 */ 12985 var $day_pcre; 12986 12987 /** 12988 * Cached PCRE for SimplePie_Parse_Date::$month 12989 * 12990 * @access protected 12991 * @var string 12992 */ 12993 var $month_pcre; 12994 12995 /** 12996 * Array of user-added callback methods 12997 * 12998 * @access private 12999 * @var array 13000 */ 13001 var $built_in = array(); 13002 13003 /** 13004 * Array of user-added callback methods 13005 * 13006 * @access private 13007 * @var array 13008 */ 13009 var $user = array(); 13010 13011 /** 13012 * Create new SimplePie_Parse_Date object, and set self::day_pcre, 13013 * self::month_pcre, and self::built_in 13014 * 13015 * @access private 13016 */ 13017 function SimplePie_Parse_Date() 13018 { 13019 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')'; 13020 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')'; 13021 13022 static $cache; 13023 if (!isset($cache[get_class($this)])) 13024 { 13025 $all_methods = get_class_methods($this); 13026 13027 foreach ($all_methods as $method) 13028 { 13029 if (strtolower(substr($method, 0, 5)) === 'date_') 13030 { 13031 $cache[get_class($this)][] = $method; 13032 } 13033 } 13034 } 13035 13036 foreach ($cache[get_class($this)] as $method) 13037 { 13038 $this->built_in[] = $method; 13039 } 13040 } 13041 13042 /** 13043 * Get the object 13044 * 13045 * @access public 13046 */ 13047 function get() 13048 { 13049 static $object; 13050 if (!$object) 13051 { 13052 $object =& new SimplePie_Parse_Date; 13053 } 13054 return $object; 13055 } 13056 13057 /** 13058 * Parse a date 13059 * 13060 * @final 13061 * @access public 13062 * @param string $date Date to parse 13063 * @return int Timestamp corresponding to date string, or false on failure 13064 */ 13065 function parse($date) 13066 { 13067 foreach ($this->user as $method) 13068 { 13069 if (($returned = call_user_func($method, $date)) !== false) 13070 { 13071 return $returned; 13072 } 13073 } 13074 13075 foreach ($this->built_in as $method) 13076 { 13077 if (($returned = call_user_func(array(&$this, $method), $date)) !== false) 13078 { 13079 return $returned; 13080 } 13081 } 13082 13083 return false; 13084 } 13085 13086 /** 13087 * Add a callback method to parse a date 13088 * 13089 * @final 13090 * @access public 13091 * @param callback $callback 13092 */ 13093 function add_callback($callback) 13094 { 13095 if (is_callable($callback)) 13096 { 13097 $this->user[] = $callback; 13098 } 13099 else 13100 { 13101 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING); 13102 } 13103 } 13104 13105 /** 13106 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as 13107 * well as allowing any of upper or lower case "T", horizontal tabs, or 13108 * spaces to be used as the time seperator (including more than one)) 13109 * 13110 * @access protected 13111 * @return int Timestamp 13112 */ 13113 function date_w3cdtf($date) 13114 { 13115 static $pcre; 13116 if (!$pcre) 13117 { 13118 $year = '([0-9]{4})'; 13119 $month = $day = $hour = $minute = $second = '([0-9]{2})'; 13120 $decimal = '([0-9]*)'; 13121 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))'; 13122 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/'; 13123 } 13124 if (preg_match($pcre, $date, $match)) 13125 { 13126 /* 13127 Capturing subpatterns: 13128 1: Year 13129 2: Month 13130 3: Day 13131 4: Hour 13132 5: Minute 13133 6: Second 13134 7: Decimal fraction of a second 13135 8: Zulu 13136 9: Timezone ± 13137 10: Timezone hours 13138 11: Timezone minutes 13139 */ 13140 13141 // Fill in empty matches 13142 for ($i = count($match); $i <= 3; $i++) 13143 { 13144 $match[$i] = '1'; 13145 } 13146 13147 for ($i = count($match); $i <= 7; $i++) 13148 { 13149 $match[$i] = '0'; 13150 } 13151 13152 // Numeric timezone 13153 if (isset($match[9]) && $match[9] !== '') 13154 { 13155 $timezone = $match[10] * 3600; 13156 $timezone += $match[11] * 60; 13157 if ($match[9] === '-') 13158 { 13159 $timezone = 0 - $timezone; 13160 } 13161 } 13162 else 13163 { 13164 $timezone = 0; 13165 } 13166 13167 // Convert the number of seconds to an integer, taking decimals into account 13168 $second = round($match[6] + $match[7] / pow(10, strlen($match[7]))); 13169 13170 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone; 13171 } 13172 else 13173 { 13174 return false; 13175 } 13176 } 13177 13178 /** 13179 * Remove RFC822 comments 13180 * 13181 * @access protected 13182 * @param string $data Data to strip comments from 13183 * @return string Comment stripped string 13184 */ 13185 function remove_rfc2822_comments($string) 13186 { 13187 $string = (string) $string; 13188 $position = 0; 13189 $length = strlen($string); 13190 $depth = 0; 13191 13192 $output = ''; 13193 13194 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) 13195 { 13196 $output .= substr($string, $position, $pos - $position); 13197 $position = $pos + 1; 13198 if ($string[$pos - 1] !== '\\') 13199 { 13200 $depth++; 13201 while ($depth && $position < $length) 13202 { 13203 $position += strcspn($string, '()', $position); 13204 if ($string[$position - 1] === '\\') 13205 { 13206 $position++; 13207 continue; 13208 } 13209 elseif (isset($string[$position])) 13210 { 13211 switch ($string[$position]) 13212 { 13213 case '(': 13214 $depth++; 13215 break; 13216 13217 case ')': 13218 $depth--; 13219 break; 13220 } 13221 $position++; 13222 } 13223 else 13224 { 13225 break; 13226 } 13227 } 13228 } 13229 else 13230 { 13231 $output .= '('; 13232 } 13233 } 13234 $output .= substr($string, $position); 13235 13236 return $output; 13237 } 13238 13239 /** 13240 * Parse RFC2822's date format 13241 * 13242 * @access protected 13243 * @return int Timestamp 13244 */ 13245 function date_rfc2822($date) 13246 { 13247 static $pcre; 13248 if (!$pcre) 13249 { 13250 $wsp = '[\x09\x20]'; 13251 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)'; 13252 $optional_fws = $fws . '?'; 13253 $day_name = $this->day_pcre; 13254 $month = $this->month_pcre; 13255 $day = '([0-9]{1,2})'; 13256 $hour = $minute = $second = '([0-9]{2})'; 13257 $year = '([0-9]{2,4})'; 13258 $num_zone = '([+\-])([0-9]{2})([0-9]{2})'; 13259 $character_zone = '([A-Z]{1,5})'; 13260 $zone = '(?:' . $num_zone . '|' . $character_zone . ')'; 13261 $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'; 13262 } 13263 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match)) 13264 { 13265 /* 13266 Capturing subpatterns: 13267 1: Day name 13268 2: Day 13269 3: Month 13270 4: Year 13271 5: Hour 13272 6: Minute 13273 7: Second 13274 8: Timezone ± 13275 9: Timezone hours 13276 10: Timezone minutes 13277 11: Alphabetic timezone 13278 */ 13279 13280 // Find the month number 13281 $month = $this->month[strtolower($match[3])]; 13282 13283 // Numeric timezone 13284 if ($match[8] !== '') 13285 { 13286 $timezone = $match[9] * 3600; 13287 $timezone += $match[10] * 60; 13288 if ($match[8] === '-') 13289 { 13290 $timezone = 0 - $timezone; 13291 } 13292 } 13293 // Character timezone 13294 elseif (isset($this->timezone[strtoupper($match[11])])) 13295 { 13296 $timezone = $this->timezone[strtoupper($match[11])]; 13297 } 13298 // Assume everything else to be -0000 13299 else 13300 { 13301 $timezone = 0; 13302 } 13303 13304 // Deal with 2/3 digit years 13305 if ($match[4] < 50) 13306 { 13307 $match[4] += 2000; 13308 } 13309 elseif ($match[4] < 1000) 13310 { 13311 $match[4] += 1900; 13312 } 13313 13314 // Second is optional, if it is empty set it to zero 13315 if ($match[7] !== '') 13316 { 13317 $second = $match[7]; 13318 } 13319 else 13320 { 13321 $second = 0; 13322 } 13323 13324 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone; 13325 } 13326 else 13327 { 13328 return false; 13329 } 13330 } 13331 13332 /** 13333 * Parse RFC850's date format 13334 * 13335 * @access protected 13336 * @return int Timestamp 13337 */ 13338 function date_rfc850($date) 13339 { 13340 static $pcre; 13341 if (!$pcre) 13342 { 13343 $space = '[\x09\x20]+'; 13344 $day_name = $this->day_pcre; 13345 $month = $this->month_pcre; 13346 $day = '([0-9]{1,2})'; 13347 $year = $hour = $minute = $second = '([0-9]{2})'; 13348 $zone = '([A-Z]{1,5})'; 13349 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i'; 13350 } 13351 if (preg_match($pcre, $date, $match)) 13352 { 13353 /* 13354 Capturing subpatterns: 13355 1: Day name 13356 2: Day 13357 3: Month 13358 4: Year 13359 5: Hour 13360 6: Minute 13361 7: Second 13362 8: Timezone 13363 */ 13364 13365 // Month 13366 $month = $this->month[strtolower($match[3])]; 13367 13368 // Character timezone 13369 if (isset($this->timezone[strtoupper($match[8])])) 13370 { 13371 $timezone = $this->timezone[strtoupper($match[8])]; 13372 } 13373 // Assume everything else to be -0000 13374 else 13375 { 13376 $timezone = 0; 13377 } 13378 13379 // Deal with 2 digit year 13380 if ($match[4] < 50) 13381 { 13382 $match[4] += 2000; 13383 } 13384 else 13385 { 13386 $match[4] += 1900; 13387 } 13388 13389 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone; 13390 } 13391 else 13392 { 13393 return false; 13394 } 13395 } 13396 13397 /** 13398 * Parse C99's asctime()'s date format 13399 * 13400 * @access protected 13401 * @return int Timestamp 13402 */ 13403 function date_asctime($date) 13404 { 13405 static $pcre; 13406 if (!$pcre) 13407 { 13408 $space = '[\x09\x20]+'; 13409 $wday_name = $this->day_pcre; 13410 $mon_name = $this->month_pcre; 13411 $day = '([0-9]{1,2})'; 13412 $hour = $sec = $min = '([0-9]{2})'; 13413 $year = '([0-9]{4})'; 13414 $terminator = '\x0A?\x00?'; 13415 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i'; 13416 } 13417 if (preg_match($pcre, $date, $match)) 13418 { 13419 /* 13420 Capturing subpatterns: 13421 1: Day name 13422 2: Month 13423 3: Day 13424 4: Hour 13425 5: Minute 13426 6: Second 13427 7: Year 13428 */ 13429 13430 $month = $this->month[strtolower($match[2])]; 13431 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]); 13432 } 13433 else 13434 { 13435 return false; 13436 } 13437 } 13438 13439 /** 13440 * Parse dates using strtotime() 13441 * 13442 * @access protected 13443 * @return int Timestamp 13444 */ 13445 function date_strtotime($date) 13446 { 13447 $strtotime = strtotime($date); 13448 if ($strtotime === -1 || $strtotime === false) 13449 { 13450 return false; 13451 } 13452 else 13453 { 13454 return $strtotime; 13455 } 13456 } 13457} 13458 13459/** 13460 * Content-type sniffing 13461 * 13462 * @package SimplePie 13463 */ 13464class SimplePie_Content_Type_Sniffer 13465{ 13466 /** 13467 * File object 13468 * 13469 * @var SimplePie_File 13470 * @access private 13471 */ 13472 var $file; 13473 13474 /** 13475 * Create an instance of the class with the input file 13476 * 13477 * @access public 13478 * @param SimplePie_Content_Type_Sniffer $file Input file 13479 */ 13480 function SimplePie_Content_Type_Sniffer($file) 13481 { 13482 $this->file = $file; 13483 } 13484 13485 /** 13486 * Get the Content-Type of the specified file 13487 * 13488 * @access public 13489 * @return string Actual Content-Type 13490 */ 13491 function get_type() 13492 { 13493 if (isset($this->file->headers['content-type'])) 13494 { 13495 if (!isset($this->file->headers['content-encoding']) 13496 && ($this->file->headers['content-type'] === 'text/plain' 13497 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1' 13498 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1')) 13499 { 13500 return $this->text_or_binary(); 13501 } 13502 13503 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false) 13504 { 13505 $official = substr($this->file->headers['content-type'], 0, $pos); 13506 } 13507 else 13508 { 13509 $official = $this->file->headers['content-type']; 13510 } 13511 $official = strtolower($official); 13512 13513 if ($official === 'unknown/unknown' 13514 || $official === 'application/unknown') 13515 { 13516 return $this->unknown(); 13517 } 13518 elseif (substr($official, -4) === '+xml' 13519 || $official === 'text/xml' 13520 || $official === 'application/xml') 13521 { 13522 return $official; 13523 } 13524 elseif (substr($official, 0, 6) === 'image/') 13525 { 13526 if ($return = $this->image()) 13527 { 13528 return $return; 13529 } 13530 else 13531 { 13532 return $official; 13533 } 13534 } 13535 elseif ($official === 'text/html') 13536 { 13537 return $this->feed_or_html(); 13538 } 13539 else 13540 { 13541 return $official; 13542 } 13543 } 13544 else 13545 { 13546 return $this->unknown(); 13547 } 13548 } 13549 13550 /** 13551 * Sniff text or binary 13552 * 13553 * @access private 13554 * @return string Actual Content-Type 13555 */ 13556 function text_or_binary() 13557 { 13558 if (substr($this->file->body, 0, 2) === "\xFE\xFF" 13559 || substr($this->file->body, 0, 2) === "\xFF\xFE" 13560 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF" 13561 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF") 13562 { 13563 return 'text/plain'; 13564 } 13565 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body)) 13566 { 13567 return 'application/octect-stream'; 13568 } 13569 else 13570 { 13571 return 'text/plain'; 13572 } 13573 } 13574 13575 /** 13576 * Sniff unknown 13577 * 13578 * @access private 13579 * @return string Actual Content-Type 13580 */ 13581 function unknown() 13582 { 13583 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20"); 13584 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html' 13585 || strtolower(substr($this->file->body, $ws, 5)) === '<html' 13586 || strtolower(substr($this->file->body, $ws, 7)) === '<script') 13587 { 13588 return 'text/html'; 13589 } 13590 elseif (substr($this->file->body, 0, 5) === '%PDF-') 13591 { 13592 return 'application/pdf'; 13593 } 13594 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-') 13595 { 13596 return 'application/postscript'; 13597 } 13598 elseif (substr($this->file->body, 0, 6) === 'GIF87a' 13599 || substr($this->file->body, 0, 6) === 'GIF89a') 13600 { 13601 return 'image/gif'; 13602 } 13603 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") 13604 { 13605 return 'image/png'; 13606 } 13607 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") 13608 { 13609 return 'image/jpeg'; 13610 } 13611 elseif (substr($this->file->body, 0, 2) === "\x42\x4D") 13612 { 13613 return 'image/bmp'; 13614 } 13615 else 13616 { 13617 return $this->text_or_binary(); 13618 } 13619 } 13620 13621 /** 13622 * Sniff images 13623 * 13624 * @access private 13625 * @return string Actual Content-Type 13626 */ 13627 function image() 13628 { 13629 if (substr($this->file->body, 0, 6) === 'GIF87a' 13630 || substr($this->file->body, 0, 6) === 'GIF89a') 13631 { 13632 return 'image/gif'; 13633 } 13634 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") 13635 { 13636 return 'image/png'; 13637 } 13638 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") 13639 { 13640 return 'image/jpeg'; 13641 } 13642 elseif (substr($this->file->body, 0, 2) === "\x42\x4D") 13643 { 13644 return 'image/bmp'; 13645 } 13646 else 13647 { 13648 return false; 13649 } 13650 } 13651 13652 /** 13653 * Sniff HTML 13654 * 13655 * @access private 13656 * @return string Actual Content-Type 13657 */ 13658 function feed_or_html() 13659 { 13660 $len = strlen($this->file->body); 13661 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20"); 13662 13663 while ($pos < $len) 13664 { 13665 switch ($this->file->body[$pos]) 13666 { 13667 case "\x09": 13668 case "\x0A": 13669 case "\x0D": 13670 case "\x20": 13671 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos); 13672 continue 2; 13673 13674 case '<': 13675 $pos++; 13676 break; 13677 13678 default: 13679 return 'text/html'; 13680 } 13681 13682 if (substr($this->file->body, $pos, 3) === '!--') 13683 { 13684 $pos += 3; 13685 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false) 13686 { 13687 $pos += 3; 13688 } 13689 else 13690 { 13691 return 'text/html'; 13692 } 13693 } 13694 elseif (substr($this->file->body, $pos, 1) === '!') 13695 { 13696 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false) 13697 { 13698 $pos++; 13699 } 13700 else 13701 { 13702 return 'text/html'; 13703 } 13704 } 13705 elseif (substr($this->file->body, $pos, 1) === '?') 13706 { 13707 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false) 13708 { 13709 $pos += 2; 13710 } 13711 else 13712 { 13713 return 'text/html'; 13714 } 13715 } 13716 elseif (substr($this->file->body, $pos, 3) === 'rss' 13717 || substr($this->file->body, $pos, 7) === 'rdf:RDF') 13718 { 13719 return 'application/rss+xml'; 13720 } 13721 elseif (substr($this->file->body, $pos, 4) === 'feed') 13722 { 13723 return 'application/atom+xml'; 13724 } 13725 else 13726 { 13727 return 'text/html'; 13728 } 13729 } 13730 13731 return 'text/html'; 13732 } 13733} 13734 13735/** 13736 * Parses the XML Declaration 13737 * 13738 * @package SimplePie 13739 */ 13740class SimplePie_XML_Declaration_Parser 13741{ 13742 /** 13743 * XML Version 13744 * 13745 * @access public 13746 * @var string 13747 */ 13748 var $version = '1.0'; 13749 13750 /** 13751 * Encoding 13752 * 13753 * @access public 13754 * @var string 13755 */ 13756 var $encoding = 'UTF-8'; 13757 13758 /** 13759 * Standalone 13760 * 13761 * @access public 13762 * @var bool 13763 */ 13764 var $standalone = false; 13765 13766 /** 13767 * Current state of the state machine 13768 * 13769 * @access private 13770 * @var string 13771 */ 13772 var $state = 'before_version_name'; 13773 13774 /** 13775 * Input data 13776 * 13777 * @access private 13778 * @var string 13779 */ 13780 var $data = ''; 13781 13782 /** 13783 * Input data length (to avoid calling strlen() everytime this is needed) 13784 * 13785 * @access private 13786 * @var int 13787 */ 13788 var $data_length = 0; 13789 13790 /** 13791 * Current position of the pointer 13792 * 13793 * @var int 13794 * @access private 13795 */ 13796 var $position = 0; 13797 13798 /** 13799 * Create an instance of the class with the input data 13800 * 13801 * @access public 13802 * @param string $data Input data 13803 */ 13804 function SimplePie_XML_Declaration_Parser($data) 13805 { 13806 $this->data = $data; 13807 $this->data_length = strlen($this->data); 13808 } 13809 13810 /** 13811 * Parse the input data 13812 * 13813 * @access public 13814 * @return bool true on success, false on failure 13815 */ 13816 function parse() 13817 { 13818 while ($this->state && $this->state !== 'emit' && $this->has_data()) 13819 { 13820 $state = $this->state; 13821 $this->$state(); 13822 } 13823 $this->data = ''; 13824 if ($this->state === 'emit') 13825 { 13826 return true; 13827 } 13828 else 13829 { 13830 $this->version = ''; 13831 $this->encoding = ''; 13832 $this->standalone = ''; 13833 return false; 13834 } 13835 } 13836 13837 /** 13838 * Check whether there is data beyond the pointer 13839 * 13840 * @access private 13841 * @return bool true if there is further data, false if not 13842 */ 13843 function has_data() 13844 { 13845 return (bool) ($this->position < $this->data_length); 13846 } 13847 13848 /** 13849 * Advance past any whitespace 13850 * 13851 * @return int Number of whitespace characters passed 13852 */ 13853 function skip_whitespace() 13854 { 13855 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position); 13856 $this->position += $whitespace; 13857 return $whitespace; 13858 } 13859 13860 /** 13861 * Read value 13862 */ 13863 function get_value() 13864 { 13865 $quote = substr($this->data, $this->position, 1); 13866 if ($quote === '"' || $quote === "'") 13867 { 13868 $this->position++; 13869 $len = strcspn($this->data, $quote, $this->position); 13870 if ($this->has_data()) 13871 { 13872 $value = substr($this->data, $this->position, $len); 13873 $this->position += $len + 1; 13874 return $value; 13875 } 13876 } 13877 return false; 13878 } 13879 13880 function before_version_name() 13881 { 13882 if ($this->skip_whitespace()) 13883 { 13884 $this->state = 'version_name'; 13885 } 13886 else 13887 { 13888 $this->state = false; 13889 } 13890 } 13891 13892 function version_name() 13893 { 13894 if (substr($this->data, $this->position, 7) === 'version') 13895 { 13896 $this->position += 7; 13897 $this->skip_whitespace(); 13898 $this->state = 'version_equals'; 13899 } 13900 else 13901 { 13902 $this->state = false; 13903 } 13904 } 13905 13906 function version_equals() 13907 { 13908 if (substr($this->data, $this->position, 1) === '=') 13909 { 13910 $this->position++; 13911 $this->skip_whitespace(); 13912 $this->state = 'version_value'; 13913 } 13914 else 13915 { 13916 $this->state = false; 13917 } 13918 } 13919 13920 function version_value() 13921 { 13922 if ($this->version = $this->get_value()) 13923 { 13924 $this->skip_whitespace(); 13925 if ($this->has_data()) 13926 { 13927 $this->state = 'encoding_name'; 13928 } 13929 else 13930 { 13931 $this->state = 'emit'; 13932 } 13933 } 13934 else 13935 { 13936 $this->state = 'standalone_name'; 13937 } 13938 } 13939 13940 function encoding_name() 13941 { 13942 if (substr($this->data, $this->position, 8) === 'encoding') 13943 { 13944 $this->position += 8; 13945 $this->skip_whitespace(); 13946 $this->state = 'encoding_equals'; 13947 } 13948 else 13949 { 13950 $this->state = false; 13951 } 13952 } 13953 13954 function encoding_equals() 13955 { 13956 if (substr($this->data, $this->position, 1) === '=') 13957 { 13958 $this->position++; 13959 $this->skip_whitespace(); 13960 $this->state = 'encoding_value'; 13961 } 13962 else 13963 { 13964 $this->state = false; 13965 } 13966 } 13967 13968 function encoding_value() 13969 { 13970 if ($this->encoding = $this->get_value()) 13971 { 13972 $this->skip_whitespace(); 13973 if ($this->has_data()) 13974 { 13975 $this->state = 'standalone_name'; 13976 } 13977 else 13978 { 13979 $this->state = 'emit'; 13980 } 13981 } 13982 else 13983 { 13984 $this->state = false; 13985 } 13986 } 13987 13988 function standalone_name() 13989 { 13990 if (substr($this->data, $this->position, 10) === 'standalone') 13991 { 13992 $this->position += 10; 13993 $this->skip_whitespace(); 13994 $this->state = 'standalone_equals'; 13995 } 13996 else 13997 { 13998 $this->state = false; 13999 } 14000 } 14001 14002 function standalone_equals() 14003 { 14004 if (substr($this->data, $this->position, 1) === '=') 14005 { 14006 $this->position++; 14007 $this->skip_whitespace(); 14008 $this->state = 'standalone_value'; 14009 } 14010 else 14011 { 14012 $this->state = false; 14013 } 14014 } 14015 14016 function standalone_value() 14017 { 14018 if ($standalone = $this->get_value()) 14019 { 14020 switch ($standalone) 14021 { 14022 case 'yes': 14023 $this->standalone = true; 14024 break; 14025 14026 case 'no': 14027 $this->standalone = false; 14028 break; 14029 14030 default: 14031 $this->state = false; 14032 return; 14033 } 14034 14035 $this->skip_whitespace(); 14036 if ($this->has_data()) 14037 { 14038 $this->state = false; 14039 } 14040 else 14041 { 14042 $this->state = 'emit'; 14043 } 14044 } 14045 else 14046 { 14047 $this->state = false; 14048 } 14049 } 14050} 14051 14052class SimplePie_Locator 14053{ 14054 var $useragent; 14055 var $timeout; 14056 var $file; 14057 var $local = array(); 14058 var $elsewhere = array(); 14059 var $file_class = 'SimplePie_File'; 14060 var $cached_entities = array(); 14061 var $http_base; 14062 var $base; 14063 var $base_location = 0; 14064 var $checked_feeds = 0; 14065 var $max_checked_feeds = 10; 14066 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; 14067 14068 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer') 14069 { 14070 $this->file =& $file; 14071 $this->file_class = $file_class; 14072 $this->useragent = $useragent; 14073 $this->timeout = $timeout; 14074 $this->max_checked_feeds = $max_checked_feeds; 14075 $this->content_type_sniffer_class = $content_type_sniffer_class; 14076 } 14077 14078 function find($type = SIMPLEPIE_LOCATOR_ALL, &$working) 14079 { 14080 if ($this->is_feed($this->file)) 14081 { 14082 return $this->file; 14083 } 14084 14085 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) 14086 { 14087 $sniffer =& new $this->content_type_sniffer_class($this->file); 14088 if ($sniffer->get_type() !== 'text/html') 14089 { 14090 return null; 14091 } 14092 } 14093 14094 if ($type & ~SIMPLEPIE_LOCATOR_NONE) 14095 { 14096 $this->get_base(); 14097 } 14098 14099 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery()) 14100 { 14101 return $working[0]; 14102 } 14103 14104 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links()) 14105 { 14106 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) 14107 { 14108 return $working; 14109 } 14110 14111 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) 14112 { 14113 return $working; 14114 } 14115 14116 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) 14117 { 14118 return $working; 14119 } 14120 14121 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) 14122 { 14123 return $working; 14124 } 14125 } 14126 return null; 14127 } 14128 14129 function is_feed(&$file) 14130 { 14131 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) 14132 { 14133 $sniffer =& new $this->content_type_sniffer_class($file); 14134 $sniffed = $sniffer->get_type(); 14135 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml'))) 14136 { 14137 return true; 14138 } 14139 else 14140 { 14141 return false; 14142 } 14143 } 14144 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL) 14145 { 14146 return true; 14147 } 14148 else 14149 { 14150 return false; 14151 } 14152 } 14153 14154 function get_base() 14155 { 14156 $this->http_base = $this->file->url; 14157 $this->base = $this->http_base; 14158 $elements = SimplePie_Misc::get_element('base', $this->file->body); 14159 foreach ($elements as $element) 14160 { 14161 if ($element['attribs']['href']['data'] !== '') 14162 { 14163 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base); 14164 $this->base_location = $element['offset']; 14165 break; 14166 } 14167 } 14168 } 14169 14170 function autodiscovery() 14171 { 14172 $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)); 14173 $done = array(); 14174 $feeds = array(); 14175 foreach ($links as $link) 14176 { 14177 if ($this->checked_feeds === $this->max_checked_feeds) 14178 { 14179 break; 14180 } 14181 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data'])) 14182 { 14183 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data']))); 14184 14185 if ($this->base_location < $link['offset']) 14186 { 14187 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base); 14188 } 14189 else 14190 { 14191 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base); 14192 } 14193 14194 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])) 14195 { 14196 $this->checked_feeds++; 14197 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent); 14198 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)) 14199 { 14200 $feeds[$href] = $feed; 14201 } 14202 } 14203 $done[] = $href; 14204 } 14205 } 14206 14207 if (!empty($feeds)) 14208 { 14209 return array_values($feeds); 14210 } 14211 else { 14212 return null; 14213 } 14214 } 14215 14216 function get_links() 14217 { 14218 $links = SimplePie_Misc::get_element('a', $this->file->body); 14219 foreach ($links as $link) 14220 { 14221 if (isset($link['attribs']['href']['data'])) 14222 { 14223 $href = trim($link['attribs']['href']['data']); 14224 $parsed = SimplePie_Misc::parse_url($href); 14225 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme'])) 14226 { 14227 if ($this->base_location < $link['offset']) 14228 { 14229 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base); 14230 } 14231 else 14232 { 14233 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base); 14234 } 14235 14236 $current = SimplePie_Misc::parse_url($this->file->url); 14237 14238 if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority']) 14239 { 14240 $this->local[] = $href; 14241 } 14242 else 14243 { 14244 $this->elsewhere[] = $href; 14245 } 14246 } 14247 } 14248 } 14249 $this->local = array_unique($this->local); 14250 $this->elsewhere = array_unique($this->elsewhere); 14251 if (!empty($this->local) || !empty($this->elsewhere)) 14252 { 14253 return true; 14254 } 14255 return null; 14256 } 14257 14258 function extension(&$array) 14259 { 14260 foreach ($array as $key => $value) 14261 { 14262 if ($this->checked_feeds === $this->max_checked_feeds) 14263 { 14264 break; 14265 } 14266 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml'))) 14267 { 14268 $this->checked_feeds++; 14269 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent); 14270 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)) 14271 { 14272 return $feed; 14273 } 14274 else 14275 { 14276 unset($array[$key]); 14277 } 14278 } 14279 } 14280 return null; 14281 } 14282 14283 function body(&$array) 14284 { 14285 foreach ($array as $key => $value) 14286 { 14287 if ($this->checked_feeds === $this->max_checked_feeds) 14288 { 14289 break; 14290 } 14291 if (preg_match('/(rss|rdf|atom|xml)/i', $value)) 14292 { 14293 $this->checked_feeds++; 14294 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent); 14295 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)) 14296 { 14297 return $feed; 14298 } 14299 else 14300 { 14301 unset($array[$key]); 14302 } 14303 } 14304 } 14305 return null; 14306 } 14307} 14308 14309class SimplePie_Parser 14310{ 14311 var $error_code; 14312 var $error_string; 14313 var $current_line; 14314 var $current_column; 14315 var $current_byte; 14316 var $separator = ' '; 14317 var $namespace = array(''); 14318 var $element = array(''); 14319 var $xml_base = array(''); 14320 var $xml_base_explicit = array(false); 14321 var $xml_lang = array(''); 14322 var $data = array(); 14323 var $datas = array(array()); 14324 var $current_xhtml_construct = -1; 14325 var $encoding; 14326 14327 function parse(&$data, $encoding) 14328 { 14329 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character 14330 if (strtoupper($encoding) === 'US-ASCII') 14331 { 14332 $this->encoding = 'UTF-8'; 14333 } 14334 else 14335 { 14336 $this->encoding = $encoding; 14337 } 14338 14339 // Strip BOM: 14340 // UTF-32 Big Endian BOM 14341 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") 14342 { 14343 $data = substr($data, 4); 14344 } 14345 // UTF-32 Little Endian BOM 14346 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") 14347 { 14348 $data = substr($data, 4); 14349 } 14350 // UTF-16 Big Endian BOM 14351 elseif (substr($data, 0, 2) === "\xFE\xFF") 14352 { 14353 $data = substr($data, 2); 14354 } 14355 // UTF-16 Little Endian BOM 14356 elseif (substr($data, 0, 2) === "\xFF\xFE") 14357 { 14358 $data = substr($data, 2); 14359 } 14360 // UTF-8 BOM 14361 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") 14362 { 14363 $data = substr($data, 3); 14364 } 14365 14366 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false) 14367 { 14368 $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5)); 14369 if ($declaration->parse()) 14370 { 14371 $data = substr($data, $pos + 2); 14372 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data; 14373 } 14374 else 14375 { 14376 $this->error_string = 'SimplePie bug! Please report this!'; 14377 return false; 14378 } 14379 } 14380 14381 $return = true; 14382 14383 static $xml_is_sane = null; 14384 if ($xml_is_sane === null) 14385 { 14386 $parser_check = xml_parser_create(); 14387 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values); 14388 xml_parser_free($parser_check); 14389 $xml_is_sane = isset($values[0]['value']); 14390 } 14391 14392 // Create the parser 14393 if ($xml_is_sane) 14394 { 14395 $xml = xml_parser_create_ns($this->encoding, $this->separator); 14396 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1); 14397 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0); 14398 xml_set_object($xml, $this); 14399 xml_set_character_data_handler($xml, 'cdata'); 14400 xml_set_element_handler($xml, 'tag_open', 'tag_close'); 14401 14402 // Parse! 14403 if (!xml_parse($xml, $data, true)) 14404 { 14405 $this->error_code = xml_get_error_code($xml); 14406 $this->error_string = xml_error_string($this->error_code); 14407 $return = false; 14408 } 14409 $this->current_line = xml_get_current_line_number($xml); 14410 $this->current_column = xml_get_current_column_number($xml); 14411 $this->current_byte = xml_get_current_byte_index($xml); 14412 xml_parser_free($xml); 14413 return $return; 14414 } 14415 else 14416 { 14417 libxml_clear_errors(); 14418 $xml =& new XMLReader(); 14419 $xml->xml($data); 14420 while (@$xml->read()) 14421 { 14422 switch ($xml->nodeType) 14423 { 14424 14425 case constant('XMLReader::END_ELEMENT'): 14426 if ($xml->namespaceURI !== '') 14427 { 14428 $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}"; 14429 } 14430 else 14431 { 14432 $tagName = $xml->localName; 14433 } 14434 $this->tag_close(null, $tagName); 14435 break; 14436 case constant('XMLReader::ELEMENT'): 14437 $empty = $xml->isEmptyElement; 14438 if ($xml->namespaceURI !== '') 14439 { 14440 $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}"; 14441 } 14442 else 14443 { 14444 $tagName = $xml->localName; 14445 } 14446 $attributes = array(); 14447 while ($xml->moveToNextAttribute()) 14448 { 14449 if ($xml->namespaceURI !== '') 14450 { 14451 $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}"; 14452 } 14453 else 14454 { 14455 $attrName = $xml->localName; 14456 } 14457 $attributes[$attrName] = $xml->value; 14458 } 14459 $this->tag_open(null, $tagName, $attributes); 14460 if ($empty) 14461 { 14462 $this->tag_close(null, $tagName); 14463 } 14464 break; 14465 case constant('XMLReader::TEXT'): 14466 14467 case constant('XMLReader::CDATA'): 14468 $this->cdata(null, $xml->value); 14469 break; 14470 } 14471 } 14472 if ($error = libxml_get_last_error()) 14473 { 14474 $this->error_code = $error->code; 14475 $this->error_string = $error->message; 14476 $this->current_line = $error->line; 14477 $this->current_column = $error->column; 14478 return false; 14479 } 14480 else 14481 { 14482 return true; 14483 } 14484 } 14485 } 14486 14487 function get_error_code() 14488 { 14489 return $this->error_code; 14490 } 14491 14492 function get_error_string() 14493 { 14494 return $this->error_string; 14495 } 14496 14497 function get_current_line() 14498 { 14499 return $this->current_line; 14500 } 14501 14502 function get_current_column() 14503 { 14504 return $this->current_column; 14505 } 14506 14507 function get_current_byte() 14508 { 14509 return $this->current_byte; 14510 } 14511 14512 function get_data() 14513 { 14514 return $this->data; 14515 } 14516 14517 function tag_open($parser, $tag, $attributes) 14518 { 14519 list($this->namespace[], $this->element[]) = $this->split_ns($tag); 14520 14521 $attribs = array(); 14522 foreach ($attributes as $name => $value) 14523 { 14524 list($attrib_namespace, $attribute) = $this->split_ns($name); 14525 $attribs[$attrib_namespace][$attribute] = $value; 14526 } 14527 14528 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base'])) 14529 { 14530 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base)); 14531 $this->xml_base_explicit[] = true; 14532 } 14533 else 14534 { 14535 $this->xml_base[] = end($this->xml_base); 14536 $this->xml_base_explicit[] = end($this->xml_base_explicit); 14537 } 14538 14539 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang'])) 14540 { 14541 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang']; 14542 } 14543 else 14544 { 14545 $this->xml_lang[] = end($this->xml_lang); 14546 } 14547 14548 if ($this->current_xhtml_construct >= 0) 14549 { 14550 $this->current_xhtml_construct++; 14551 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML) 14552 { 14553 $this->data['data'] .= '<' . end($this->element); 14554 if (isset($attribs[''])) 14555 { 14556 foreach ($attribs[''] as $name => $value) 14557 { 14558 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"'; 14559 } 14560 } 14561 $this->data['data'] .= '>'; 14562 } 14563 } 14564 else 14565 { 14566 $this->datas[] =& $this->data; 14567 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][]; 14568 $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)); 14569 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') 14570 || (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')) 14571 { 14572 $this->current_xhtml_construct = 0; 14573 } 14574 } 14575 } 14576 14577 function cdata($parser, $cdata) 14578 { 14579 if ($this->current_xhtml_construct >= 0) 14580 { 14581 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding); 14582 } 14583 else 14584 { 14585 $this->data['data'] .= $cdata; 14586 } 14587 } 14588 14589 function tag_close($parser, $tag) 14590 { 14591 if ($this->current_xhtml_construct >= 0) 14592 { 14593 $this->current_xhtml_construct--; 14594 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'))) 14595 { 14596 $this->data['data'] .= '</' . end($this->element) . '>'; 14597 } 14598 } 14599 if ($this->current_xhtml_construct === -1) 14600 { 14601 $this->data =& $this->datas[count($this->datas) - 1]; 14602 array_pop($this->datas); 14603 } 14604 14605 array_pop($this->element); 14606 array_pop($this->namespace); 14607 array_pop($this->xml_base); 14608 array_pop($this->xml_base_explicit); 14609 array_pop($this->xml_lang); 14610 } 14611 14612 function split_ns($string) 14613 { 14614 static $cache = array(); 14615 if (!isset($cache[$string])) 14616 { 14617 if ($pos = strpos($string, $this->separator)) 14618 { 14619 static $separator_length; 14620 if (!$separator_length) 14621 { 14622 $separator_length = strlen($this->separator); 14623 } 14624 $namespace = substr($string, 0, $pos); 14625 $local_name = substr($string, $pos + $separator_length); 14626 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES) 14627 { 14628 $namespace = SIMPLEPIE_NAMESPACE_ITUNES; 14629 } 14630 14631 // Normalize the Media RSS namespaces 14632 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG) 14633 { 14634 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS; 14635 } 14636 $cache[$string] = array($namespace, $local_name); 14637 } 14638 else 14639 { 14640 $cache[$string] = array('', $string); 14641 } 14642 } 14643 return $cache[$string]; 14644 } 14645} 14646 14647/** 14648 * @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 14649 */ 14650class SimplePie_Sanitize 14651{ 14652 // Private vars 14653 var $base; 14654 14655 // Options 14656 var $remove_div = true; 14657 var $image_handler = ''; 14658 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); 14659 var $encode_instead_of_strip = false; 14660 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); 14661 var $strip_comments = false; 14662 var $output_encoding = 'UTF-8'; 14663 var $enable_cache = true; 14664 var $cache_location = './cache'; 14665 var $cache_name_function = 'md5'; 14666 var $cache_class = 'SimplePie_Cache'; 14667 var $file_class = 'SimplePie_File'; 14668 var $timeout = 10; 14669 var $useragent = ''; 14670 var $force_fsockopen = false; 14671 14672 var $replace_url_attributes = array( 14673 'a' => 'href', 14674 'area' => 'href', 14675 'blockquote' => 'cite', 14676 'del' => 'cite', 14677 'form' => 'action', 14678 'img' => array('longdesc', 'src'), 14679 'input' => 'src', 14680 'ins' => 'cite', 14681 'q' => 'cite' 14682 ); 14683 14684 function remove_div($enable = true) 14685 { 14686 $this->remove_div = (bool) $enable; 14687 } 14688 14689 function set_image_handler($page = false) 14690 { 14691 if ($page) 14692 { 14693 $this->image_handler = (string) $page; 14694 } 14695 else 14696 { 14697 $this->image_handler = false; 14698 } 14699 } 14700 14701 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache') 14702 { 14703 if (isset($enable_cache)) 14704 { 14705 $this->enable_cache = (bool) $enable_cache; 14706 } 14707 14708 if ($cache_location) 14709 { 14710 $this->cache_location = (string) $cache_location; 14711 } 14712 14713 if ($cache_name_function) 14714 { 14715 $this->cache_name_function = (string) $cache_name_function; 14716 } 14717 14718 if ($cache_class) 14719 { 14720 $this->cache_class = (string) $cache_class; 14721 } 14722 } 14723 14724 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false) 14725 { 14726 if ($file_class) 14727 { 14728 $this->file_class = (string) $file_class; 14729 } 14730 14731 if ($timeout) 14732 { 14733 $this->timeout = (string) $timeout; 14734 } 14735 14736 if ($useragent) 14737 { 14738 $this->useragent = (string) $useragent; 14739 } 14740 14741 if ($force_fsockopen) 14742 { 14743 $this->force_fsockopen = (string) $force_fsockopen; 14744 } 14745 } 14746 14747 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style')) 14748 { 14749 if ($tags) 14750 { 14751 if (is_array($tags)) 14752 { 14753 $this->strip_htmltags = $tags; 14754 } 14755 else 14756 { 14757 $this->strip_htmltags = explode(',', $tags); 14758 } 14759 } 14760 else 14761 { 14762 $this->strip_htmltags = false; 14763 } 14764 } 14765 14766 function encode_instead_of_strip($encode = false) 14767 { 14768 $this->encode_instead_of_strip = (bool) $encode; 14769 } 14770 14771 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc')) 14772 { 14773 if ($attribs) 14774 { 14775 if (is_array($attribs)) 14776 { 14777 $this->strip_attributes = $attribs; 14778 } 14779 else 14780 { 14781 $this->strip_attributes = explode(',', $attribs); 14782 } 14783 } 14784 else 14785 { 14786 $this->strip_attributes = false; 14787 } 14788 } 14789 14790 function strip_comments($strip = false) 14791 { 14792 $this->strip_comments = (bool) $strip; 14793 } 14794 14795 function set_output_encoding($encoding = 'UTF-8') 14796 { 14797 $this->output_encoding = (string) $encoding; 14798 } 14799 14800 /** 14801 * Set element/attribute key/value pairs of HTML attributes 14802 * containing URLs that need to be resolved relative to the feed 14803 * 14804 * @access public 14805 * @since 1.0 14806 * @param array $element_attribute Element/attribute key/value pairs 14807 */ 14808 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')) 14809 { 14810 $this->replace_url_attributes = (array) $element_attribute; 14811 } 14812 14813 function sanitize($data, $type, $base = '') 14814 { 14815 $data = trim($data); 14816 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI) 14817 { 14818 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML) 14819 { 14820 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)) 14821 { 14822 $type |= SIMPLEPIE_CONSTRUCT_HTML; 14823 } 14824 else 14825 { 14826 $type |= SIMPLEPIE_CONSTRUCT_TEXT; 14827 } 14828 } 14829 14830 if ($type & SIMPLEPIE_CONSTRUCT_BASE64) 14831 { 14832 $data = base64_decode($data); 14833 } 14834 14835 if ($type & SIMPLEPIE_CONSTRUCT_XHTML) 14836 { 14837 if ($this->remove_div) 14838 { 14839 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data); 14840 $data = preg_replace('/<\/div>$/', '', $data); 14841 } 14842 else 14843 { 14844 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data); 14845 } 14846 } 14847 14848 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML)) 14849 { 14850 // Strip comments 14851 if ($this->strip_comments) 14852 { 14853 $data = SimplePie_Misc::strip_comments($data); 14854 } 14855 14856 // Strip out HTML tags and attributes that might cause various security problems. 14857 // Based on recommendations by Mark Pilgrim at: 14858 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely 14859 if ($this->strip_htmltags) 14860 { 14861 foreach ($this->strip_htmltags as $tag) 14862 { 14863 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU'; 14864 while (preg_match($pcre, $data)) 14865 { 14866 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data); 14867 } 14868 } 14869 } 14870 14871 if ($this->strip_attributes) 14872 { 14873 foreach ($this->strip_attributes as $attrib) 14874 { 14875 $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); 14876 } 14877 } 14878 14879 // Replace relative URLs 14880 $this->base = $base; 14881 foreach ($this->replace_url_attributes as $element => $attributes) 14882 { 14883 $data = $this->replace_urls($data, $element, $attributes); 14884 } 14885 14886 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags. 14887 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache) 14888 { 14889 $images = SimplePie_Misc::get_element('img', $data); 14890 foreach ($images as $img) 14891 { 14892 if (isset($img['attribs']['src']['data'])) 14893 { 14894 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']); 14895 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi'); 14896 14897 if ($cache->load()) 14898 { 14899 $img['attribs']['src']['data'] = $this->image_handler . $image_url; 14900 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data); 14901 } 14902 else 14903 { 14904 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); 14905 $headers = $file->headers; 14906 14907 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) 14908 { 14909 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) 14910 { 14911 $img['attribs']['src']['data'] = $this->image_handler . $image_url; 14912 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data); 14913 } 14914 else 14915 { 14916 trigger_error("$this->cache_location is not writeable", E_USER_WARNING); 14917 } 14918 } 14919 } 14920 } 14921 } 14922 } 14923 14924 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data 14925 $data = trim($data); 14926 } 14927 14928 if ($type & SIMPLEPIE_CONSTRUCT_IRI) 14929 { 14930 $data = SimplePie_Misc::absolutize_url($data, $base); 14931 } 14932 14933 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI)) 14934 { 14935 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8'); 14936 } 14937 14938 if ($this->output_encoding !== 'UTF-8') 14939 { 14940 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding); 14941 } 14942 } 14943 return $data; 14944 } 14945 14946 function replace_urls($data, $tag, $attributes) 14947 { 14948 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags)) 14949 { 14950 $elements = SimplePie_Misc::get_element($tag, $data); 14951 foreach ($elements as $element) 14952 { 14953 if (is_array($attributes)) 14954 { 14955 foreach ($attributes as $attribute) 14956 { 14957 if (isset($element['attribs'][$attribute]['data'])) 14958 { 14959 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base); 14960 $new_element = SimplePie_Misc::element_implode($element); 14961 $data = str_replace($element['full'], $new_element, $data); 14962 $element['full'] = $new_element; 14963 } 14964 } 14965 } 14966 elseif (isset($element['attribs'][$attributes]['data'])) 14967 { 14968 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base); 14969 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data); 14970 } 14971 } 14972 } 14973 return $data; 14974 } 14975 14976 function do_strip_htmltags($match) 14977 { 14978 if ($this->encode_instead_of_strip) 14979 { 14980 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style'))) 14981 { 14982 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8'); 14983 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8'); 14984 return "<$match[1]$match[2]>$match[3]</$match[1]>"; 14985 } 14986 else 14987 { 14988 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8'); 14989 } 14990 } 14991 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style'))) 14992 { 14993 return $match[4]; 14994 } 14995 else 14996 { 14997 return ''; 14998 } 14999 } 15000} 15001endif; 15002?> 15003