| Joomla! | PHP Cross Reference | Web Portals |
Description: SimplePie A PHP-Based RSS and Atom Feed Framework. Takes the hard work out of managing a complete RSS/Atom solution.
1 <?php 2 /** 3 * SimplePie 4 * 5 * A PHP-Based RSS and Atom Feed Framework. 6 * Takes the hard work out of managing a complete RSS/Atom solution. 7 * 8 * Copyright (c) 2004-2009, Ryan Parman and Geoffrey Sneddon 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without modification, are 12 * permitted provided that the following conditions are met: 13 * 14 * * Redistributions of source code must retain the above copyright notice, this list of 15 * conditions and the following disclaimer. 16 * 17 * * Redistributions in binary form must reproduce the above copyright notice, this list 18 * of conditions and the following disclaimer in the documentation and/or other materials 19 * provided with the distribution. 20 * 21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used 22 * to endorse or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * @package SimplePie 36 * @version 1.2 37 * @copyright 2004-2009 Ryan Parman, Geoffrey Sneddon 38 * @author Ryan Parman 39 * @author Geoffrey Sneddon 40 * @link http://simplepie.org/ SimplePie 41 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums 42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 43 * @todo phpDoc comments 44 */ 45 46 /** 47 * SimplePie Name 48 */ 49 define('SIMPLEPIE_NAME', 'SimplePie'); 50 51 /** 52 * SimplePie Version 53 */ 54 define('SIMPLEPIE_VERSION', '1.2'); 55 56 /** 57 * SimplePie Build 58 */ 59 define('SIMPLEPIE_BUILD', '20090627192103'); 60 61 /** 62 * SimplePie Website URL 63 */ 64 define('SIMPLEPIE_URL', 'http://simplepie.org'); 65 66 /** 67 * SimplePie Useragent 68 * @see SimplePie::set_useragent() 69 */ 70 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD); 71 72 /** 73 * SimplePie Linkback 74 */ 75 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>'); 76 77 /** 78 * No Autodiscovery 79 * @see SimplePie::set_autodiscovery_level() 80 */ 81 define('SIMPLEPIE_LOCATOR_NONE', 0); 82 83 /** 84 * Feed Link Element Autodiscovery 85 * @see SimplePie::set_autodiscovery_level() 86 */ 87 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1); 88 89 /** 90 * Local Feed Extension Autodiscovery 91 * @see SimplePie::set_autodiscovery_level() 92 */ 93 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2); 94 95 /** 96 * Local Feed Body Autodiscovery 97 * @see SimplePie::set_autodiscovery_level() 98 */ 99 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4); 100 101 /** 102 * Remote Feed Extension Autodiscovery 103 * @see SimplePie::set_autodiscovery_level() 104 */ 105 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8); 106 107 /** 108 * Remote Feed Body Autodiscovery 109 * @see SimplePie::set_autodiscovery_level() 110 */ 111 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16); 112 113 /** 114 * All Feed Autodiscovery 115 * @see SimplePie::set_autodiscovery_level() 116 */ 117 define('SIMPLEPIE_LOCATOR_ALL', 31); 118 119 /** 120 * No known feed type 121 */ 122 define('SIMPLEPIE_TYPE_NONE', 0); 123 124 /** 125 * RSS 0.90 126 */ 127 define('SIMPLEPIE_TYPE_RSS_090', 1); 128 129 /** 130 * RSS 0.91 (Netscape) 131 */ 132 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2); 133 134 /** 135 * RSS 0.91 (Userland) 136 */ 137 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4); 138 139 /** 140 * RSS 0.91 (both Netscape and Userland) 141 */ 142 define('SIMPLEPIE_TYPE_RSS_091', 6); 143 144 /** 145 * RSS 0.92 146 */ 147 define('SIMPLEPIE_TYPE_RSS_092', 8); 148 149 /** 150 * RSS 0.93 151 */ 152 define('SIMPLEPIE_TYPE_RSS_093', 16); 153 154 /** 155 * RSS 0.94 156 */ 157 define('SIMPLEPIE_TYPE_RSS_094', 32); 158 159 /** 160 * RSS 1.0 161 */ 162 define('SIMPLEPIE_TYPE_RSS_10', 64); 163 164 /** 165 * RSS 2.0 166 */ 167 define('SIMPLEPIE_TYPE_RSS_20', 128); 168 169 /** 170 * RDF-based RSS 171 */ 172 define('SIMPLEPIE_TYPE_RSS_RDF', 65); 173 174 /** 175 * Non-RDF-based RSS (truly intended as syndication format) 176 */ 177 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190); 178 179 /** 180 * All RSS 181 */ 182 define('SIMPLEPIE_TYPE_RSS_ALL', 255); 183 184 /** 185 * Atom 0.3 186 */ 187 define('SIMPLEPIE_TYPE_ATOM_03', 256); 188 189 /** 190 * Atom 1.0 191 */ 192 define('SIMPLEPIE_TYPE_ATOM_10', 512); 193 194 /** 195 * All Atom 196 */ 197 define('SIMPLEPIE_TYPE_ATOM_ALL', 768); 198 199 /** 200 * All feed types 201 */ 202 define('SIMPLEPIE_TYPE_ALL', 1023); 203 204 /** 205 * No construct 206 */ 207 define('SIMPLEPIE_CONSTRUCT_NONE', 0); 208 209 /** 210 * Text construct 211 */ 212 define('SIMPLEPIE_CONSTRUCT_TEXT', 1); 213 214 /** 215 * HTML construct 216 */ 217 define('SIMPLEPIE_CONSTRUCT_HTML', 2); 218 219 /** 220 * XHTML construct 221 */ 222 define('SIMPLEPIE_CONSTRUCT_XHTML', 4); 223 224 /** 225 * base64-encoded construct 226 */ 227 define('SIMPLEPIE_CONSTRUCT_BASE64', 8); 228 229 /** 230 * IRI construct 231 */ 232 define('SIMPLEPIE_CONSTRUCT_IRI', 16); 233 234 /** 235 * A construct that might be HTML 236 */ 237 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32); 238 239 /** 240 * All constructs 241 */ 242 define('SIMPLEPIE_CONSTRUCT_ALL', 63); 243 244 /** 245 * Don't change case 246 */ 247 define('SIMPLEPIE_SAME_CASE', 1); 248 249 /** 250 * Change to lowercase 251 */ 252 define('SIMPLEPIE_LOWERCASE', 2); 253 254 /** 255 * Change to uppercase 256 */ 257 define('SIMPLEPIE_UPPERCASE', 4); 258 259 /** 260 * PCRE for HTML attributes 261 */ 262 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*'); 263 264 /** 265 * PCRE for XML attributes 266 */ 267 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*'); 268 269 /** 270 * XML Namespace 271 */ 272 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace'); 273 274 /** 275 * Atom 1.0 Namespace 276 */ 277 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom'); 278 279 /** 280 * Atom 0.3 Namespace 281 */ 282 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#'); 283 284 /** 285 * RDF Namespace 286 */ 287 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); 288 289 /** 290 * RSS 0.90 Namespace 291 */ 292 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/'); 293 294 /** 295 * RSS 1.0 Namespace 296 */ 297 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/'); 298 299 /** 300 * RSS 1.0 Content Module Namespace 301 */ 302 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/'); 303 304 /** 305 * RSS 2.0 Namespace 306 * (Stupid, I know, but I'm certain it will confuse people less with support.) 307 */ 308 define('SIMPLEPIE_NAMESPACE_RSS_20', ''); 309 310 /** 311 * DC 1.0 Namespace 312 */ 313 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/'); 314 315 /** 316 * DC 1.1 Namespace 317 */ 318 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/'); 319 320 /** 321 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace 322 */ 323 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#'); 324 325 /** 326 * GeoRSS Namespace 327 */ 328 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss'); 329 330 /** 331 * Media RSS Namespace 332 */ 333 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/'); 334 335 /** 336 * Wrong Media RSS Namespace 337 */ 338 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss'); 339 340 /** 341 * iTunes RSS Namespace 342 */ 343 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd'); 344 345 /** 346 * XHTML Namespace 347 */ 348 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml'); 349 350 /** 351 * IANA Link Relations Registry 352 */ 353 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/'); 354 355 /** 356 * Whether we're running on PHP5 357 */ 358 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>=')); 359 360 /** 361 * No file source 362 */ 363 define('SIMPLEPIE_FILE_SOURCE_NONE', 0); 364 365 /** 366 * Remote file source 367 */ 368 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1); 369 370 /** 371 * Local file source 372 */ 373 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2); 374 375 /** 376 * fsockopen() file source 377 */ 378 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4); 379 380 /** 381 * cURL file source 382 */ 383 define('SIMPLEPIE_FILE_SOURCE_CURL', 8); 384 385 /** 386 * file_get_contents() file source 387 */ 388 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16); 389 390 /** 391 * SimplePie 392 * 393 * @package SimplePie 394 */ 395 class SimplePie 396 { 397 /** 398 * @var array Raw data 399 * @access private 400 */ 401 var $data = array(); 402 403 /** 404 * @var mixed Error string 405 * @access private 406 */ 407 var $error; 408 409 /** 410 * @var object Instance of SimplePie_Sanitize (or other class) 411 * @see SimplePie::set_sanitize_class() 412 * @access private 413 */ 414 var $sanitize; 415 416 /** 417 * @var string SimplePie Useragent 418 * @see SimplePie::set_useragent() 419 * @access private 420 */ 421 var $useragent = SIMPLEPIE_USERAGENT; 422 423 /** 424 * @var string Feed URL 425 * @see SimplePie::set_feed_url() 426 * @access private 427 */ 428 var $feed_url; 429 430 /** 431 * @var object Instance of SimplePie_File to use as a feed 432 * @see SimplePie::set_file() 433 * @access private 434 */ 435 var $file; 436 437 /** 438 * @var string Raw feed data 439 * @see SimplePie::set_raw_data() 440 * @access private 441 */ 442 var $raw_data; 443 444 /** 445 * @var int Timeout for fetching remote files 446 * @see SimplePie::set_timeout() 447 * @access private 448 */ 449 var $timeout = 10; 450 451 /** 452 * @var bool Forces fsockopen() to be used for remote files instead 453 * of cURL, even if a new enough version is installed 454 * @see SimplePie::force_fsockopen() 455 * @access private 456 */ 457 var $force_fsockopen = false; 458 459 /** 460 * @var bool Force the given data/URL to be treated as a feed no matter what 461 * it appears like 462 * @see SimplePie::force_feed() 463 * @access private 464 */ 465 var $force_feed = false; 466 467 /** 468 * @var bool Enable/Disable XML dump 469 * @see SimplePie::enable_xml_dump() 470 * @access private 471 */ 472 var $xml_dump = false; 473 474 /** 475 * @var bool Enable/Disable Caching 476 * @see SimplePie::enable_cache() 477 * @access private 478 */ 479 var $cache = true; 480 481 /** 482 * @var int Cache duration (in seconds) 483 * @see SimplePie::set_cache_duration() 484 * @access private 485 */ 486 var $cache_duration = 3600; 487 488 /** 489 * @var int Auto-discovery cache duration (in seconds) 490 * @see SimplePie::set_autodiscovery_cache_duration() 491 * @access private 492 */ 493 var $autodiscovery_cache_duration = 604800; // 7 Days. 494 495 /** 496 * @var string Cache location (relative to executing script) 497 * @see SimplePie::set_cache_location() 498 * @access private 499 */ 500 var $cache_location = './cache'; 501 502 /** 503 * @var string Function that creates the cache filename 504 * @see SimplePie::set_cache_name_function() 505 * @access private 506 */ 507 var $cache_name_function = 'md5'; 508 509 /** 510 * @var bool Reorder feed by date descending 511 * @see SimplePie::enable_order_by_date() 512 * @access private 513 */ 514 var $order_by_date = true; 515 516 /** 517 * @var mixed Force input encoding to be set to the follow value 518 * (false, or anything type-cast to false, disables this feature) 519 * @see SimplePie::set_input_encoding() 520 * @access private 521 */ 522 var $input_encoding = false; 523 524 /** 525 * @var int Feed Autodiscovery Level 526 * @see SimplePie::set_autodiscovery_level() 527 * @access private 528 */ 529 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL; 530 531 /** 532 * @var string Class used for caching feeds 533 * @see SimplePie::set_cache_class() 534 * @access private 535 */ 536 var $cache_class = 'SimplePie_Cache'; 537 538 /** 539 * @var string Class used for locating feeds 540 * @see SimplePie::set_locator_class() 541 * @access private 542 */ 543 var $locator_class = 'SimplePie_Locator'; 544 545 /** 546 * @var string Class used for parsing feeds 547 * @see SimplePie::set_parser_class() 548 * @access private 549 */ 550 var $parser_class = 'SimplePie_Parser'; 551 552 /** 553 * @var string Class used for fetching feeds 554 * @see SimplePie::set_file_class() 555 * @access private 556 */ 557 var $file_class = 'SimplePie_File'; 558 559 /** 560 * @var string Class used for items 561 * @see SimplePie::set_item_class() 562 * @access private 563 */ 564 var $item_class = 'SimplePie_Item'; 565 566 /** 567 * @var string Class used for authors 568 * @see SimplePie::set_author_class() 569 * @access private 570 */ 571 var $author_class = 'SimplePie_Author'; 572 573 /** 574 * @var string Class used for categories 575 * @see SimplePie::set_category_class() 576 * @access private 577 */ 578 var $category_class = 'SimplePie_Category'; 579 580 /** 581 * @var string Class used for enclosures 582 * @see SimplePie::set_enclosures_class() 583 * @access private 584 */ 585 var $enclosure_class = 'SimplePie_Enclosure'; 586 587 /** 588 * @var string Class used for Media RSS <media:text> captions 589 * @see SimplePie::set_caption_class() 590 * @access private 591 */ 592 var $caption_class = 'SimplePie_Caption'; 593 594 /** 595 * @var string Class used for Media RSS <media:copyright> 596 * @see SimplePie::set_copyright_class() 597 * @access private 598 */ 599 var $copyright_class = 'SimplePie_Copyright'; 600 601 /** 602 * @var string Class used for Media RSS <media:credit> 603 * @see SimplePie::set_credit_class() 604 * @access private 605 */ 606 var $credit_class = 'SimplePie_Credit'; 607 608 /** 609 * @var string Class used for Media RSS <media:rating> 610 * @see SimplePie::set_rating_class() 611 * @access private 612 */ 613 var $rating_class = 'SimplePie_Rating'; 614 615 /** 616 * @var string Class used for Media RSS <media:restriction> 617 * @see SimplePie::set_restriction_class() 618 * @access private 619 */ 620 var $restriction_class = 'SimplePie_Restriction'; 621 622 /** 623 * @var string Class used for content-type sniffing 624 * @see SimplePie::set_content_type_sniffer_class() 625 * @access private 626 */ 627 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; 628 629 /** 630 * @var string Class used for item sources. 631 * @see SimplePie::set_source_class() 632 * @access private 633 */ 634 var $source_class = 'SimplePie_Source'; 635 636 /** 637 * @var mixed Set javascript query string parameter (false, or 638 * anything type-cast to false, disables this feature) 639 * @see SimplePie::set_javascript() 640 * @access private 641 */ 642 var $javascript = 'js'; 643 644 /** 645 * @var int Maximum number of feeds to check with autodiscovery 646 * @see SimplePie::set_max_checked_feeds() 647 * @access private 648 */ 649 var $max_checked_feeds = 10; 650 651 /** 652 * @var array All the feeds found during the autodiscovery process 653 * @see SimplePie::get_all_discovered_feeds() 654 * @access private 655 */ 656 var $all_discovered_feeds = array(); 657 658 /** 659 * @var string Web-accessible path to the handler_favicon.php file. 660 * @see SimplePie::set_favicon_handler() 661 * @access private 662 */ 663 var $favicon_handler = ''; 664 665 /** 666 * @var string Web-accessible path to the handler_image.php file. 667 * @see SimplePie::set_image_handler() 668 * @access private 669 */ 670 var $image_handler = ''; 671 672 /** 673 * @var array Stores the URLs when multiple feeds are being initialized. 674 * @see SimplePie::set_feed_url() 675 * @access private 676 */ 677 var $multifeed_url = array(); 678 679 /** 680 * @var array Stores SimplePie objects when multiple feeds initialized. 681 * @access private 682 */ 683 var $multifeed_objects = array(); 684 685 /** 686 * @var array Stores the get_object_vars() array for use with multifeeds. 687 * @see SimplePie::set_feed_url() 688 * @access private 689 */ 690 var $config_settings = null; 691 692 /** 693 * @var integer Stores the number of items to return per-feed with multifeeds. 694 * @see SimplePie::set_item_limit() 695 * @access private 696 */ 697 var $item_limit = 0; 698 699 /** 700 * @var array Stores the default attributes to be stripped by strip_attributes(). 701 * @see SimplePie::strip_attributes() 702 * @access private 703 */ 704 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); 705 706 /** 707 * @var array Stores the default tags to be stripped by strip_htmltags(). 708 * @see SimplePie::strip_htmltags() 709 * @access private 710 */ 711 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); 712 713 /** 714 * The SimplePie class contains feed level data and options 715 * 716 * There are two ways that you can create a new SimplePie object. The first 717 * is by passing a feed URL as a parameter to the SimplePie constructor 718 * (as well as optionally setting the cache location and cache expiry). This 719 * will initialise the whole feed with all of the default settings, and you 720 * can begin accessing methods and properties immediately. 721 * 722 * The second way is to create the SimplePie object with no parameters 723 * at all. This will enable you to set configuration options. After setting 724 * them, you must initialise the feed using $feed->init(). At that point the 725 * object's methods and properties will be available to you. This format is 726 * what is used throughout this documentation. 727 * 728 * @access public 729 * @since 1.0 Preview Release 730 * @param string $feed_url This is the URL you want to parse. 731 * @param string $cache_location This is where you want the cache to be stored. 732 * @param int $cache_duration This is the number of seconds that you want to store the cache file for. 733 */ 734 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null) 735 { 736 // Other objects, instances created here so we can set options on them 737 $this->sanitize = new SimplePie_Sanitize; 738 739 // Set options if they're passed to the constructor 740 if ($cache_location !== null) 741 { 742 $this->set_cache_location($cache_location); 743 } 744 745 if ($cache_duration !== null) 746 { 747 $this->set_cache_duration($cache_duration); 748 } 749 750 // Only init the script if we're passed a feed URL 751 if ($feed_url !== null) 752 { 753 $this->set_feed_url($feed_url); 754 $this->init(); 755 } 756 } 757 758 /** 759 * Used for converting object to a string 760 */ 761 function __toString() 762 { 763 return md5(serialize($this->data)); 764 } 765 766 /** 767 * Remove items that link back to this before destroying this object 768 */ 769 function __destruct() 770 { 771 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode')) 772 { 773 if (!empty($this->data['items'])) 774 { 775 foreach ($this->data['items'] as $item) 776 { 777 $item->__destruct(); 778 } 779 unset($item, $this->data['items']); 780 } 781 if (!empty($this->data['ordered_items'])) 782 { 783 foreach ($this->data['ordered_items'] as $item) 784 { 785 $item->__destruct(); 786 } 787 unset($item, $this->data['ordered_items']); 788 } 789 } 790 } 791 792 /** 793 * Force the given data/URL to be treated as a feed no matter what it 794 * appears like 795 * 796 * @access public 797 * @since 1.1 798 * @param bool $enable Force the given data/URL to be treated as a feed 799 */ 800 function force_feed($enable = false) 801 { 802 $this->force_feed = (bool) $enable; 803 } 804 805 /** 806 * This is the URL of the feed you want to parse. 807 * 808 * This allows you to enter the URL of the feed you want to parse, or the 809 * website you want to try to use auto-discovery on. This takes priority 810 * over any set raw data. 811 * 812 * You can set multiple feeds to mash together by passing an array instead 813 * of a string for the $url. Remember that with each additional feed comes 814 * additional processing and resources. 815 * 816 * @access public 817 * @since 1.0 Preview Release 818 * @param mixed $url This is the URL (or array of URLs) that you want to parse. 819 * @see SimplePie::set_raw_data() 820 */ 821 function set_feed_url($url) 822 { 823 if (is_array($url)) 824 { 825 $this->multifeed_url = array(); 826 foreach ($url as $value) 827 { 828 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1); 829 } 830 } 831 else 832 { 833 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1); 834 } 835 } 836 837 /** 838 * Provides an instance of SimplePie_File to use as a feed 839 * 840 * @access public 841 * @param object &$file Instance of SimplePie_File (or subclass) 842 * @return bool True on success, false on failure 843 */ 844 function set_file(&$file) 845 { 846 if (is_a($file, 'SimplePie_File')) 847 { 848 $this->feed_url = $file->url; 849 $this->file =& $file; 850 return true; 851 } 852 return false; 853 } 854 855 /** 856 * Allows you to use a string of RSS/Atom data instead of a remote feed. 857 * 858 * If you have a feed available as a string in PHP, you can tell SimplePie 859 * to parse that data string instead of a remote feed. Any set feed URL 860 * takes precedence. 861 * 862 * @access public 863 * @since 1.0 Beta 3 864 * @param string $data RSS or Atom data as a string. 865 * @see SimplePie::set_feed_url() 866 */ 867 function set_raw_data($data) 868 { 869 $this->raw_data = $data; 870 } 871 872 /** 873 * Allows you to override the default timeout for fetching remote feeds. 874 * 875 * This allows you to change the maximum time the feed's server to respond 876 * and send the feed back. 877 * 878 * @access public 879 * @since 1.0 Beta 3 880 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed. 881 */ 882 function set_timeout($timeout = 10) 883 { 884 $this->timeout = (int) $timeout; 885 } 886 887 /** 888 * Forces SimplePie to use fsockopen() instead of the preferred cURL 889 * functions. 890 * 891 * @access public 892 * @since 1.0 Beta 3 893 * @param bool $enable Force fsockopen() to be used 894 */ 895 function force_fsockopen($enable = false) 896 { 897 $this->force_fsockopen = (bool) $enable; 898 } 899 900 /** 901 * Outputs the raw XML content of the feed, after it has gone through 902 * SimplePie's filters. 903 * 904 * Used only for debugging, this function will output the XML content as 905 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up 906 * before trying to parse it. Many parts of the feed are re-written in 907 * memory, and in the end, you have a parsable feed. XML dump shows you the 908 * actual XML that SimplePie tries to parse, which may or may not be very 909 * different from the original feed. 910 * 911 * @access public 912 * @since 1.0 Preview Release 913 * @param bool $enable Enable XML dump 914 */ 915 function enable_xml_dump($enable = false) 916 { 917 $this->xml_dump = (bool) $enable; 918 } 919 920 /** 921 * Enables/disables caching in SimplePie. 922 * 923 * This option allows you to disable caching all-together in SimplePie. 924 * However, disabling the cache can lead to longer load times. 925 * 926 * @access public 927 * @since 1.0 Preview Release 928 * @param bool $enable Enable caching 929 */ 930 function enable_cache($enable = true) 931 { 932 $this->cache = (bool) $enable; 933 } 934 935 /** 936 * Set the length of time (in seconds) that the contents of a feed 937 * will be cached. 938 * 939 * @access public 940 * @param int $seconds The feed content cache duration. 941 */ 942 function set_cache_duration($seconds = 3600) 943 { 944 $this->cache_duration = (int) $seconds; 945 } 946 947 /** 948 * Set the length of time (in seconds) that the autodiscovered feed 949 * URL will be cached. 950 * 951 * @access public 952 * @param int $seconds The autodiscovered feed URL cache duration. 953 */ 954 function set_autodiscovery_cache_duration($seconds = 604800) 955 { 956 $this->autodiscovery_cache_duration = (int) $seconds; 957 } 958 959 /** 960 * Set the file system location where the cached files should be stored. 961 * 962 * @access public 963 * @param string $location The file system location. 964 */ 965 function set_cache_location($location = './cache') 966 { 967 $this->cache_location = (string) $location; 968 } 969 970 /** 971 * Determines whether feed items should be sorted into reverse chronological order. 972 * 973 * @access public 974 * @param bool $enable Sort as reverse chronological order. 975 */ 976 function enable_order_by_date($enable = true) 977 { 978 $this->order_by_date = (bool) $enable; 979 } 980 981 /** 982 * Allows you to override the character encoding reported by the feed. 983 * 984 * @access public 985 * @param string $encoding Character encoding. 986 */ 987 function set_input_encoding($encoding = false) 988 { 989 if ($encoding) 990 { 991 $this->input_encoding = (string) $encoding; 992 } 993 else 994 { 995 $this->input_encoding = false; 996 } 997 } 998 999 /** 1000 * Set how much feed autodiscovery to do 1001 * 1002 * @access public 1003 * @see SIMPLEPIE_LOCATOR_NONE 1004 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY 1005 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION 1006 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY 1007 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION 1008 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY 1009 * @see SIMPLEPIE_LOCATOR_ALL 1010 * @param int $level Feed Autodiscovery Level (level can be a 1011 * combination of the above constants, see bitwise OR operator) 1012 */ 1013 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL) 1014 { 1015 $this->autodiscovery = (int) $level; 1016 } 1017 1018 /** 1019 * Allows you to change which class SimplePie uses for caching. 1020 * Useful when you are overloading or extending SimplePie's default classes. 1021 * 1022 * @access public 1023 * @param string $class Name of custom class. 1024 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1025 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1026 */ 1027 function set_cache_class($class = 'SimplePie_Cache') 1028 { 1029 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache')) 1030 { 1031 $this->cache_class = $class; 1032 return true; 1033 } 1034 return false; 1035 } 1036 1037 /** 1038 * Allows you to change which class SimplePie uses for auto-discovery. 1039 * Useful when you are overloading or extending SimplePie's default classes. 1040 * 1041 * @access public 1042 * @param string $class Name of custom class. 1043 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1044 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1045 */ 1046 function set_locator_class($class = 'SimplePie_Locator') 1047 { 1048 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator')) 1049 { 1050 $this->locator_class = $class; 1051 return true; 1052 } 1053 return false; 1054 } 1055 1056 /** 1057 * Allows you to change which class SimplePie uses for XML parsing. 1058 * Useful when you are overloading or extending SimplePie's default classes. 1059 * 1060 * @access public 1061 * @param string $class Name of custom class. 1062 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1063 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1064 */ 1065 function set_parser_class($class = 'SimplePie_Parser') 1066 { 1067 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser')) 1068 { 1069 $this->parser_class = $class; 1070 return true; 1071 } 1072 return false; 1073 } 1074 1075 /** 1076 * Allows you to change which class SimplePie uses for remote file fetching. 1077 * Useful when you are overloading or extending SimplePie's default classes. 1078 * 1079 * @access public 1080 * @param string $class Name of custom class. 1081 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1082 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1083 */ 1084 function set_file_class($class = 'SimplePie_File') 1085 { 1086 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File')) 1087 { 1088 $this->file_class = $class; 1089 return true; 1090 } 1091 return false; 1092 } 1093 1094 /** 1095 * Allows you to change which class SimplePie uses for data sanitization. 1096 * Useful when you are overloading or extending SimplePie's default classes. 1097 * 1098 * @access public 1099 * @param string $class Name of custom class. 1100 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1101 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1102 */ 1103 function set_sanitize_class($class = 'SimplePie_Sanitize') 1104 { 1105 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize')) 1106 { 1107 $this->sanitize = new $class; 1108 return true; 1109 } 1110 return false; 1111 } 1112 1113 /** 1114 * Allows you to change which class SimplePie uses for handling feed items. 1115 * Useful when you are overloading or extending SimplePie's default classes. 1116 * 1117 * @access public 1118 * @param string $class Name of custom class. 1119 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1120 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1121 */ 1122 function set_item_class($class = 'SimplePie_Item') 1123 { 1124 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item')) 1125 { 1126 $this->item_class = $class; 1127 return true; 1128 } 1129 return false; 1130 } 1131 1132 /** 1133 * Allows you to change which class SimplePie uses for handling author data. 1134 * Useful when you are overloading or extending SimplePie's default classes. 1135 * 1136 * @access public 1137 * @param string $class Name of custom class. 1138 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1139 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1140 */ 1141 function set_author_class($class = 'SimplePie_Author') 1142 { 1143 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author')) 1144 { 1145 $this->author_class = $class; 1146 return true; 1147 } 1148 return false; 1149 } 1150 1151 /** 1152 * Allows you to change which class SimplePie uses for handling category data. 1153 * Useful when you are overloading or extending SimplePie's default classes. 1154 * 1155 * @access public 1156 * @param string $class Name of custom class. 1157 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1158 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1159 */ 1160 function set_category_class($class = 'SimplePie_Category') 1161 { 1162 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category')) 1163 { 1164 $this->category_class = $class; 1165 return true; 1166 } 1167 return false; 1168 } 1169 1170 /** 1171 * Allows you to change which class SimplePie uses for feed enclosures. 1172 * Useful when you are overloading or extending SimplePie's default classes. 1173 * 1174 * @access public 1175 * @param string $class Name of custom class. 1176 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1177 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1178 */ 1179 function set_enclosure_class($class = 'SimplePie_Enclosure') 1180 { 1181 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure')) 1182 { 1183 $this->enclosure_class = $class; 1184 return true; 1185 } 1186 return false; 1187 } 1188 1189 /** 1190 * Allows you to change which class SimplePie uses for <media:text> captions 1191 * Useful when you are overloading or extending SimplePie's default classes. 1192 * 1193 * @access public 1194 * @param string $class Name of custom class. 1195 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1196 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1197 */ 1198 function set_caption_class($class = 'SimplePie_Caption') 1199 { 1200 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption')) 1201 { 1202 $this->caption_class = $class; 1203 return true; 1204 } 1205 return false; 1206 } 1207 1208 /** 1209 * Allows you to change which class SimplePie uses for <media:copyright> 1210 * Useful when you are overloading or extending SimplePie's default classes. 1211 * 1212 * @access public 1213 * @param string $class Name of custom class. 1214 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1215 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1216 */ 1217 function set_copyright_class($class = 'SimplePie_Copyright') 1218 { 1219 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright')) 1220 { 1221 $this->copyright_class = $class; 1222 return true; 1223 } 1224 return false; 1225 } 1226 1227 /** 1228 * Allows you to change which class SimplePie uses for <media:credit> 1229 * Useful when you are overloading or extending SimplePie's default classes. 1230 * 1231 * @access public 1232 * @param string $class Name of custom class. 1233 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1234 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1235 */ 1236 function set_credit_class($class = 'SimplePie_Credit') 1237 { 1238 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit')) 1239 { 1240 $this->credit_class = $class; 1241 return true; 1242 } 1243 return false; 1244 } 1245 1246 /** 1247 * Allows you to change which class SimplePie uses for <media:rating> 1248 * Useful when you are overloading or extending SimplePie's default classes. 1249 * 1250 * @access public 1251 * @param string $class Name of custom class. 1252 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1253 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1254 */ 1255 function set_rating_class($class = 'SimplePie_Rating') 1256 { 1257 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating')) 1258 { 1259 $this->rating_class = $class; 1260 return true; 1261 } 1262 return false; 1263 } 1264 1265 /** 1266 * Allows you to change which class SimplePie uses for <media:restriction> 1267 * Useful when you are overloading or extending SimplePie's default classes. 1268 * 1269 * @access public 1270 * @param string $class Name of custom class. 1271 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1272 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1273 */ 1274 function set_restriction_class($class = 'SimplePie_Restriction') 1275 { 1276 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction')) 1277 { 1278 $this->restriction_class = $class; 1279 return true; 1280 } 1281 return false; 1282 } 1283 1284 /** 1285 * Allows you to change which class SimplePie uses for content-type sniffing. 1286 * Useful when you are overloading or extending SimplePie's default classes. 1287 * 1288 * @access public 1289 * @param string $class Name of custom class. 1290 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1291 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1292 */ 1293 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer') 1294 { 1295 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer')) 1296 { 1297 $this->content_type_sniffer_class = $class; 1298 return true; 1299 } 1300 return false; 1301 } 1302 1303 /** 1304 * Allows you to change which class SimplePie uses item sources. 1305 * Useful when you are overloading or extending SimplePie's default classes. 1306 * 1307 * @access public 1308 * @param string $class Name of custom class. 1309 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1310 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1311 */ 1312 function set_source_class($class = 'SimplePie_Source') 1313 { 1314 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source')) 1315 { 1316 $this->source_class = $class; 1317 return true; 1318 } 1319 return false; 1320 } 1321 1322 /** 1323 * Allows you to override the default user agent string. 1324 * 1325 * @access public 1326 * @param string $ua New user agent string. 1327 */ 1328 function set_useragent($ua = SIMPLEPIE_USERAGENT) 1329 { 1330 $this->useragent = (string) $ua; 1331 } 1332 1333 /** 1334 * Set callback function to create cache filename with 1335 * 1336 * @access public 1337 * @param mixed $function Callback function 1338 */ 1339 function set_cache_name_function($function = 'md5') 1340 { 1341 if (is_callable($function)) 1342 { 1343 $this->cache_name_function = $function; 1344 } 1345 } 1346 1347 /** 1348 * Set javascript query string parameter 1349 * 1350 * @access public 1351 * @param mixed $get Javascript query string parameter 1352 */ 1353 function set_javascript($get = 'js') 1354 { 1355 if ($get) 1356 { 1357 $this->javascript = (string) $get; 1358 } 1359 else 1360 { 1361 $this->javascript = false; 1362 } 1363 } 1364 1365 /** 1366 * Set options to make SP as fast as possible. Forgoes a 1367 * substantial amount of data sanitization in favor of speed. 1368 * 1369 * @access public 1370 * @param bool $set Whether to set them or not 1371 */ 1372 function set_stupidly_fast($set = false) 1373 { 1374 if ($set) 1375 { 1376 $this->enable_order_by_date(false); 1377 $this->remove_div(false); 1378 $this->strip_comments(false); 1379 $this->strip_htmltags(false); 1380 $this->strip_attributes(false); 1381 $this->set_image_handler(false); 1382 } 1383 } 1384 1385 /** 1386 * Set maximum number of feeds to check with autodiscovery 1387 * 1388 * @access public 1389 * @param int $max Maximum number of feeds to check 1390 */ 1391 function set_max_checked_feeds($max = 10) 1392 { 1393 $this->max_checked_feeds = (int) $max; 1394 } 1395 1396 function remove_div($enable = true) 1397 { 1398 $this->sanitize->remove_div($enable); 1399 } 1400 1401 function strip_htmltags($tags = '', $encode = null) 1402 { 1403 if ($tags === '') 1404 { 1405 $tags = $this->strip_htmltags; 1406 } 1407 $this->sanitize->strip_htmltags($tags); 1408 if ($encode !== null) 1409 { 1410 $this->sanitize->encode_instead_of_strip($tags); 1411 } 1412 } 1413 1414 function encode_instead_of_strip($enable = true) 1415 { 1416 $this->sanitize->encode_instead_of_strip($enable); 1417 } 1418 1419 function strip_attributes($attribs = '') 1420 { 1421 if ($attribs === '') 1422 { 1423 $attribs = $this->strip_attributes; 1424 } 1425 $this->sanitize->strip_attributes($attribs); 1426 } 1427 1428 function set_output_encoding($encoding = 'UTF-8') 1429 { 1430 $this->sanitize->set_output_encoding($encoding); 1431 } 1432 1433 function strip_comments($strip = false) 1434 { 1435 $this->sanitize->strip_comments($strip); 1436 } 1437 1438 /** 1439 * Set element/attribute key/value pairs of HTML attributes 1440 * containing URLs that need to be resolved relative to the feed 1441 * 1442 * @access public 1443 * @since 1.0 1444 * @param array $element_attribute Element/attribute key/value pairs 1445 */ 1446 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')) 1447 { 1448 $this->sanitize->set_url_replacements($element_attribute); 1449 } 1450 1451 /** 1452 * Set the handler to enable the display of cached favicons. 1453 * 1454 * @access public 1455 * @param str $page Web-accessible path to the handler_favicon.php file. 1456 * @param str $qs The query string that the value should be passed to. 1457 */ 1458 function set_favicon_handler($page = false, $qs = 'i') 1459 { 1460 if ($page !== false) 1461 { 1462 $this->favicon_handler = $page . '?' . $qs . '='; 1463 } 1464 else 1465 { 1466 $this->favicon_handler = ''; 1467 } 1468 } 1469 1470 /** 1471 * Set the handler to enable the display of cached images. 1472 * 1473 * @access public 1474 * @param str $page Web-accessible path to the handler_image.php file. 1475 * @param str $qs The query string that the value should be passed to. 1476 */ 1477 function set_image_handler($page = false, $qs = 'i') 1478 { 1479 if ($page !== false) 1480 { 1481 $this->sanitize->set_image_handler($page . '?' . $qs . '='); 1482 } 1483 else 1484 { 1485 $this->image_handler = ''; 1486 } 1487 } 1488 1489 /** 1490 * Set the limit for items returned per-feed with multifeeds. 1491 * 1492 * @access public 1493 * @param integer $limit The maximum number of items to return. 1494 */ 1495 function set_item_limit($limit = 0) 1496 { 1497 $this->item_limit = (int) $limit; 1498 } 1499 1500 function init() 1501 { 1502 // Check absolute bare minimum requirements. 1503 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre')) 1504 { 1505 return false; 1506 } 1507 // 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. 1508 elseif (!extension_loaded('xmlreader')) 1509 { 1510 static $xml_is_sane = null; 1511 if ($xml_is_sane === null) 1512 { 1513 $parser_check = xml_parser_create(); 1514 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values); 1515 xml_parser_free($parser_check); 1516 $xml_is_sane = isset($values[0]['value']); 1517 } 1518 if (!$xml_is_sane) 1519 { 1520 return false; 1521 } 1522 } 1523 1524 if (isset($_GET[$this->javascript])) 1525 { 1526 SimplePie_Misc::output_javascript(); 1527 exit; 1528 } 1529 1530 // Pass whatever was set with config options over to the sanitizer. 1531 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class); 1532 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen); 1533 1534 if ($this->feed_url !== null || $this->raw_data !== null) 1535 { 1536 $this->data = array(); 1537 $this->multifeed_objects = array(); 1538 $cache = false; 1539 1540 if ($this->feed_url !== null) 1541 { 1542 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url); 1543 // Decide whether to enable caching 1544 if ($this->cache && $parsed_feed_url['scheme'] !== '') 1545 { 1546 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'); 1547 } 1548 // If it's enabled and we don't want an XML dump, use the cache 1549 if ($cache && !$this->xml_dump) 1550 { 1551 // Load the Cache 1552 $this->data = $cache->load(); 1553 if (!empty($this->data)) 1554 { 1555 // If the cache is for an outdated build of SimplePie 1556 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD) 1557 { 1558 $cache->unlink(); 1559 $this->data = array(); 1560 } 1561 // If we've hit a collision just rerun it with caching disabled 1562 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url) 1563 { 1564 $cache = false; 1565 $this->data = array(); 1566 } 1567 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL. 1568 elseif (isset($this->data['feed_url'])) 1569 { 1570 // If the autodiscovery cache is still valid use it. 1571 if ($cache->mtime() + $this->autodiscovery_cache_duration > time()) 1572 { 1573 // Do not need to do feed autodiscovery yet. 1574 if ($this->data['feed_url'] === $this->data['url']) 1575 { 1576 $cache->unlink(); 1577 $this->data = array(); 1578 } 1579 else 1580 { 1581 $this->set_feed_url($this->data['feed_url']); 1582 return $this->init(); 1583 } 1584 } 1585 } 1586 // Check if the cache has been updated 1587 elseif ($cache->mtime() + $this->cache_duration < time()) 1588 { 1589 // If we have last-modified and/or etag set 1590 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) 1591 { 1592 $headers = array(); 1593 if (isset($this->data['headers']['last-modified'])) 1594 { 1595 $headers['if-modified-since'] = $this->data['headers']['last-modified']; 1596 } 1597 if (isset($this->data['headers']['etag'])) 1598 { 1599 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"'; 1600 } 1601 $file = new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen); 1602 if ($file->success) 1603 { 1604 if ($file->status_code === 304) 1605 { 1606 $cache->touch(); 1607 return true; 1608 } 1609 else 1610 { 1611 $headers = $file->headers; 1612 } 1613 } 1614 else 1615 { 1616 unset($file); 1617 } 1618 } 1619 } 1620 // If the cache is still valid, just return true 1621 else 1622 { 1623 return true; 1624 } 1625 } 1626 // If the cache is empty, delete it 1627 else 1628 { 1629 $cache->unlink(); 1630 $this->data = array(); 1631 } 1632 } 1633 // 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. 1634 if (!isset($file)) 1635 { 1636 if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url) 1637 { 1638 $file =& $this->file; 1639 } 1640 else 1641 { 1642 $file = new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen); 1643 } 1644 } 1645 // If the file connection has an error, set SimplePie::error to that and quit 1646 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) 1647 { 1648 $this->error = $file->error; 1649 if (!empty($this->data)) 1650 { 1651 return true; 1652 } 1653 else 1654 { 1655 return false; 1656 } 1657 } 1658 1659 if (!$this->force_feed) 1660 { 1661 // Check if the supplied URL is a feed, if it isn't, look for it. 1662 $locate = new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class); 1663 if (!$locate->is_feed($file)) 1664 { 1665 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched 1666 unset($file); 1667 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)) 1668 { 1669 if ($cache) 1670 { 1671 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD); 1672 if (!$cache->save($this)) 1673 { 1674 trigger_error("$this->cache_location is not writeable", E_USER_WARNING); 1675 } 1676 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'); 1677 } 1678 $this->feed_url = $file->url; 1679 } 1680 else 1681 { 1682 $this->error = "A feed could not be found at $this->feed_url"; 1683 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1684 return false; 1685 } 1686 } 1687 $locate = null; 1688 } 1689 1690 $headers = $file->headers; 1691 $data = $file->body; 1692 $sniffer = new $this->content_type_sniffer_class($file); 1693 $sniffed = $sniffer->get_type(); 1694 } 1695 else 1696 { 1697 $data = $this->raw_data; 1698 } 1699 1700 // Set up array of possible encodings 1701 $encodings = array(); 1702 1703 // First check to see if input has been overridden. 1704 if ($this->input_encoding !== false) 1705 { 1706 $encodings[] = $this->input_encoding; 1707 } 1708 1709 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); 1710 $text_types = array('text/xml', 'text/xml-external-parsed-entity'); 1711 1712 // RFC 3023 (only applies to sniffed content) 1713 if (isset($sniffed)) 1714 { 1715 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml') 1716 { 1717 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1718 { 1719 $encodings[] = strtoupper($charset[1]); 1720 } 1721 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); 1722 $encodings[] = 'UTF-8'; 1723 } 1724 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') 1725 { 1726 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1727 { 1728 $encodings[] = $charset[1]; 1729 } 1730 $encodings[] = 'US-ASCII'; 1731 } 1732 // Text MIME-type default 1733 elseif (substr($sniffed, 0, 5) === 'text/') 1734 { 1735 $encodings[] = 'US-ASCII'; 1736 } 1737 } 1738 1739 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1 1740 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); 1741 $encodings[] = 'UTF-8'; 1742 $encodings[] = 'ISO-8859-1'; 1743 1744 // There's no point in trying an encoding twice 1745 $encodings = array_unique($encodings); 1746 1747 // If we want the XML, just output that with the most likely encoding and quit 1748 if ($this->xml_dump) 1749 { 1750 header('Content-type: text/xml; charset=' . $encodings[0]); 1751 echo $data; 1752 exit; 1753 } 1754 1755 // Loop through each possible encoding, till we return something, or run out of possibilities 1756 foreach ($encodings as $encoding) 1757 { 1758 // Change the encoding to UTF-8 (as we always use UTF-8 internally) 1759 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8')) 1760 { 1761 // Create new parser 1762 $parser = new $this->parser_class(); 1763 1764 // If it's parsed fine 1765 if ($parser->parse($utf8_data, 'UTF-8')) 1766 { 1767 $this->data = $parser->get_data(); 1768 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE) 1769 { 1770 if (isset($headers)) 1771 { 1772 $this->data['headers'] = $headers; 1773 } 1774 $this->data['build'] = SIMPLEPIE_BUILD; 1775 1776 // Cache the file if caching is enabled 1777 if ($cache && !$cache->save($this)) 1778 { 1779 trigger_error("$cache->name is not writeable", E_USER_WARNING); 1780 } 1781 return true; 1782 } 1783 else 1784 { 1785 $this->error = "A feed could not be found at $this->feed_url"; 1786 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1787 return false; 1788 } 1789 } 1790 } 1791 } 1792 if(isset($parser)) 1793 { 1794 // We have an error, just set SimplePie_Misc::error to it and quit 1795 $this->error = sprintf('XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column()); 1796 } 1797 else 1798 { 1799 $this->error = 'The data could not be converted to UTF-8'; 1800 } 1801 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1802 return false; 1803 } 1804 elseif (!empty($this->multifeed_url)) 1805 { 1806 $i = 0; 1807 $success = 0; 1808 $this->multifeed_objects = array(); 1809 foreach ($this->multifeed_url as $url) 1810 { 1811 if (SIMPLEPIE_PHP5) 1812 { 1813 // This keyword needs to defy coding standards for PHP4 compatibility 1814 $this->multifeed_objects[$i] = clone($this); 1815 } 1816 else 1817 { 1818 $this->multifeed_objects[$i] = $this; 1819 } 1820 $this->multifeed_objects[$i]->set_feed_url($url); 1821 $success |= $this->multifeed_objects[$i]->init(); 1822 $i++; 1823 } 1824 return (bool) $success; 1825 } 1826 else 1827 { 1828 return false; 1829 } 1830 } 1831 1832 /** 1833 * Return the error message for the occured error 1834 * 1835 * @access public 1836 * @return string Error message 1837 */ 1838 function error() 1839 { 1840 return $this->error; 1841 } 1842 1843 function get_encoding() 1844 { 1845 return $this->sanitize->output_encoding; 1846 } 1847 1848 function handle_content_type($mime = 'text/html') 1849 { 1850 if (!headers_sent()) 1851 { 1852 $header = "Content-type: $mime;"; 1853 if ($this->get_encoding()) 1854 { 1855 $header .= ' charset=' . $this->get_encoding(); 1856 } 1857 else 1858 { 1859 $header .= ' charset=UTF-8'; 1860 } 1861 header($header); 1862 } 1863 } 1864 1865 function get_type() 1866 { 1867 if (!isset($this->data['type'])) 1868 { 1869 $this->data['type'] = SIMPLEPIE_TYPE_ALL; 1870 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'])) 1871 { 1872 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10; 1873 } 1874 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'])) 1875 { 1876 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03; 1877 } 1878 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'])) 1879 { 1880 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel']) 1881 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image']) 1882 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']) 1883 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput'])) 1884 { 1885 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10; 1886 } 1887 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel']) 1888 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image']) 1889 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']) 1890 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput'])) 1891 { 1892 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090; 1893 } 1894 } 1895 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'])) 1896 { 1897 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL; 1898 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) 1899 { 1900 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) 1901 { 1902 case '0.91': 1903 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091; 1904 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) 1905 { 1906 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) 1907 { 1908 case '0': 1909 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE; 1910 break; 1911 1912 case '24': 1913 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND; 1914 break; 1915 } 1916 } 1917 break; 1918 1919 case '0.92': 1920 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092; 1921 break; 1922 1923 case '0.93': 1924 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093; 1925 break; 1926 1927 case '0.94': 1928 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094; 1929 break; 1930 1931 case '2.0': 1932 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20; 1933 break; 1934 } 1935 } 1936 } 1937 else 1938 { 1939 $this->data['type'] = SIMPLEPIE_TYPE_NONE; 1940 } 1941 } 1942 return $this->data['type']; 1943 } 1944 1945 /** 1946 * Returns the URL for the favicon of the feed's website. 1947 * 1948 * @todo Cache atom:icon 1949 * @access public 1950 * @since 1.0 1951 */ 1952 function get_favicon() 1953 { 1954 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) 1955 { 1956 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 1957 } 1958 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url)) 1959 { 1960 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url); 1961 1962 if ($this->cache && $this->favicon_handler) 1963 { 1964 $favicon_filename = call_user_func($this->cache_name_function, $favicon); 1965 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi'); 1966 1967 if ($cache->load()) 1968 { 1969 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); 1970 } 1971 else 1972 { 1973 $file = new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); 1974 1975 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) 1976 { 1977 $sniffer = new $this->content_type_sniffer_class($file); 1978 if (substr($sniffer->get_type(), 0, 6) === 'image/') 1979 { 1980 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) 1981 { 1982 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); 1983 } 1984 else 1985 { 1986 trigger_error("$cache->name is not writeable", E_USER_WARNING); 1987 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); 1988 } 1989 } 1990 // not an image 1991 else 1992 { 1993 return false; 1994 } 1995 } 1996 } 1997 } 1998 else 1999 { 2000 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); 2001 } 2002 } 2003 return false; 2004 } 2005 2006 /** 2007 * @todo If we have a perm redirect we should return the new URL 2008 * @todo When we make the above change, let's support <itunes:new-feed-url> as well 2009 * @todo Also, |atom:link|@rel=self 2010 */ 2011 function subscribe_url() 2012 { 2013 if ($this->feed_url !== null) 2014 { 2015 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI); 2016 } 2017 else 2018 { 2019 return null; 2020 } 2021 } 2022 2023 function subscribe_feed() 2024 { 2025 if ($this->feed_url !== null) 2026 { 2027 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); 2028 } 2029 else 2030 { 2031 return null; 2032 } 2033 } 2034 2035 function subscribe_outlook() 2036 { 2037 if ($this->feed_url !== null) 2038 { 2039 return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); 2040 } 2041 else 2042 { 2043 return null; 2044 } 2045 } 2046 2047 function subscribe_podcast() 2048 { 2049 if ($this->feed_url !== null) 2050 { 2051 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI); 2052 } 2053 else 2054 { 2055 return null; 2056 } 2057 } 2058 2059 function subscribe_itunes() 2060 { 2061 if ($this->feed_url !== null) 2062 { 2063 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI); 2064 } 2065 else 2066 { 2067 return null; 2068 } 2069 } 2070 2071 /** 2072 * Creates the subscribe_* methods' return data 2073 * 2074 * @access private 2075 * @param string $feed_url String to prefix to the feed URL 2076 * @param string $site_url String to prefix to the site URL (and 2077 * suffix to the feed URL) 2078 * @return mixed URL if feed exists, false otherwise 2079 */ 2080 function subscribe_service($feed_url, $site_url = null) 2081 { 2082 if ($this->subscribe_url()) 2083 { 2084 $return = $feed_url . rawurlencode($this->feed_url); 2085 if ($site_url !== null && $this->get_link() !== null) 2086 { 2087 $return .= $site_url . rawurlencode($this->get_link()); 2088 } 2089 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI); 2090 } 2091 else 2092 { 2093 return null; 2094 } 2095 } 2096 2097 function subscribe_aol() 2098 { 2099 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url='); 2100 } 2101 2102 function subscribe_bloglines() 2103 { 2104 return $this->subscribe_service('http://www.bloglines.com/sub/'); 2105 } 2106 2107 function subscribe_eskobo() 2108 { 2109 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage='); 2110 } 2111 2112 function subscribe_feedfeeds() 2113 { 2114 return $this->subscribe_service('http://www.feedfeeds.com/add?feed='); 2115 } 2116 2117 function subscribe_feedster() 2118 { 2119 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl='); 2120 } 2121 2122 function subscribe_google() 2123 { 2124 return $this->subscribe_service('http://fusion.google.com/add?feedurl='); 2125 } 2126 2127 function subscribe_gritwire() 2128 { 2129 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl='); 2130 } 2131 2132 function subscribe_msn() 2133 { 2134 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru='); 2135 } 2136 2137 function subscribe_netvibes() 2138 { 2139 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url='); 2140 } 2141 2142 function subscribe_newsburst() 2143 { 2144 return $this->subscribe_service('http://www.newsburst.com/Source/?add='); 2145 } 2146 2147 function subscribe_newsgator() 2148 { 2149 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url='); 2150 } 2151 2152 function subscribe_odeo() 2153 { 2154 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed='); 2155 } 2156 2157 function subscribe_podnova() 2158 { 2159 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url='); 2160 } 2161 2162 function subscribe_rojo() 2163 { 2164 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource='); 2165 } 2166 2167 function subscribe_yahoo() 2168 { 2169 return $this->subscribe_service('http://add.my.yahoo.com/rss?url='); 2170 } 2171 2172 function get_feed_tags($namespace, $tag) 2173 { 2174 $type = $this->get_type(); 2175 if ($type & SIMPLEPIE_TYPE_ATOM_10) 2176 { 2177 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag])) 2178 { 2179 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]; 2180 } 2181 } 2182 if ($type & SIMPLEPIE_TYPE_ATOM_03) 2183 { 2184 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag])) 2185 { 2186 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]; 2187 } 2188 } 2189 if ($type & SIMPLEPIE_TYPE_RSS_RDF) 2190 { 2191 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag])) 2192 { 2193 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]; 2194 } 2195 } 2196 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) 2197 { 2198 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag])) 2199 { 2200 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]; 2201 } 2202 } 2203 return null; 2204 } 2205 2206 function get_channel_tags($namespace, $tag) 2207 { 2208 $type = $this->get_type(); 2209 if ($type & SIMPLEPIE_TYPE_ATOM_ALL) 2210 { 2211 if ($return = $this->get_feed_tags($namespace, $tag)) 2212 { 2213 return $return; 2214 } 2215 } 2216 if ($type & SIMPLEPIE_TYPE_RSS_10) 2217 { 2218 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel')) 2219 { 2220 if (isset($channel[0]['child'][$namespace][$tag])) 2221 { 2222 return $channel[0]['child'][$namespace][$tag]; 2223 } 2224 } 2225 } 2226 if ($type & SIMPLEPIE_TYPE_RSS_090) 2227 { 2228 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel')) 2229 { 2230 if (isset($channel[0]['child'][$namespace][$tag])) 2231 { 2232 return $channel[0]['child'][$namespace][$tag]; 2233 } 2234 } 2235 } 2236 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) 2237 { 2238 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel')) 2239 { 2240 if (isset($channel[0]['child'][$namespace][$tag])) 2241 { 2242 return $channel[0]['child'][$namespace][$tag]; 2243 } 2244 } 2245 } 2246 return null; 2247 } 2248 2249 function get_image_tags($namespace, $tag) 2250 { 2251 $type = $this->get_type(); 2252 if ($type & SIMPLEPIE_TYPE_RSS_10) 2253 { 2254 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image')) 2255 { 2256 if (isset($image[0]['child'][$namespace][$tag])) 2257 { 2258 return $image[0]['child'][$namespace][$tag]; 2259 } 2260 } 2261 } 2262 if ($type & SIMPLEPIE_TYPE_RSS_090) 2263 { 2264 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image')) 2265 { 2266 if (isset($image[0]['child'][$namespace][$tag])) 2267 { 2268 return $image[0]['child'][$namespace][$tag]; 2269 } 2270 } 2271 } 2272 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) 2273 { 2274 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image')) 2275 { 2276 if (isset($image[0]['child'][$namespace][$tag])) 2277 { 2278 return $image[0]['child'][$namespace][$tag]; 2279 } 2280 } 2281 } 2282 return null; 2283 } 2284 2285 function get_base($element = array()) 2286 { 2287 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base'])) 2288 { 2289 return $element['xml_base']; 2290 } 2291 elseif ($this->get_link() !== null) 2292 { 2293 return $this->get_link(); 2294 } 2295 else 2296 { 2297 return $this->subscribe_url(); 2298 } 2299 } 2300 2301 function sanitize($data, $type, $base = '') 2302 { 2303 return $this->sanitize->sanitize($data, $type, $base); 2304 } 2305 2306 function get_title() 2307 { 2308 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) 2309 { 2310 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2311 } 2312 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) 2313 { 2314 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2315 } 2316 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 2317 { 2318 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2319 } 2320 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 2321 { 2322 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2323 } 2324 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 2325 { 2326 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2327 } 2328 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 2329 { 2330 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2331 } 2332 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 2333 { 2334 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2335 } 2336 else 2337 { 2338 return null; 2339 } 2340 } 2341 2342 function get_category($key = 0) 2343 { 2344 $categories = $this->get_categories(); 2345 if (isset($categories[$key])) 2346 { 2347 return $categories[$key]; 2348 } 2349 else 2350 { 2351 return null; 2352 } 2353 } 2354 2355 function get_categories() 2356 { 2357 $categories = array(); 2358 2359 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) 2360 { 2361 $term = null; 2362 $scheme = null; 2363 $label = null; 2364 if (isset($category['attribs']['']['term'])) 2365 { 2366 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); 2367 } 2368 if (isset($category['attribs']['']['scheme'])) 2369 { 2370 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 2371 } 2372 if (isset($category['attribs']['']['label'])) 2373 { 2374 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 2375 } 2376 $categories[] = new $this->category_class($term, $scheme, $label); 2377 } 2378 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) 2379 { 2380 // This is really the label, but keep this as the term also for BC. 2381 // Label will also work on retrieving because that falls back to term. 2382 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2383 if (isset($category['attribs']['']['domain'])) 2384 { 2385 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); 2386 } 2387 else 2388 { 2389 $scheme = null; 2390 } 2391 $categories[] = new $this->category_class($term, $scheme, null); 2392 } 2393 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) 2394 { 2395 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2396 } 2397 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) 2398 { 2399 $categories[] = new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2400 } 2401 2402 if (!empty($categories)) 2403 { 2404 return SimplePie_Misc::array_unique($categories); 2405 } 2406 else 2407 { 2408 return null; 2409 } 2410 } 2411 2412 function get_author($key = 0) 2413 { 2414 $authors = $this->get_authors(); 2415 if (isset($authors[$key])) 2416 { 2417 return $authors[$key]; 2418 } 2419 else 2420 { 2421 return null; 2422 } 2423 } 2424 2425 function get_authors() 2426 { 2427 $authors = array(); 2428 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) 2429 { 2430 $name = null; 2431 $uri = null; 2432 $email = null; 2433 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 2434 { 2435 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2436 } 2437 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 2438 { 2439 $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])); 2440 } 2441 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 2442 { 2443 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2444 } 2445 if ($name !== null || $email !== null || $uri !== null) 2446 { 2447 $authors[] = new $this->author_class($name, $uri, $email); 2448 } 2449 } 2450 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) 2451 { 2452 $name = null; 2453 $url = null; 2454 $email = null; 2455 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 2456 { 2457 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2458 } 2459 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 2460 { 2461 $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])); 2462 } 2463 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 2464 { 2465 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2466 } 2467 if ($name !== null || $email !== null || $url !== null) 2468 { 2469 $authors[] = new $this->author_class($name, $url, $email); 2470 } 2471 } 2472 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) 2473 { 2474 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2475 } 2476 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) 2477 { 2478 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2479 } 2480 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) 2481 { 2482 $authors[] = new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2483 } 2484 2485 if (!empty($authors)) 2486 { 2487 return SimplePie_Misc::array_unique($authors); 2488 } 2489 else 2490 { 2491 return null; 2492 } 2493 } 2494 2495 function get_contributor($key = 0) 2496 { 2497 $contributors = $this->get_contributors(); 2498 if (isset($contributors[$key])) 2499 { 2500 return $contributors[$key]; 2501 } 2502 else 2503 { 2504 return null; 2505 } 2506 } 2507 2508 function get_contributors() 2509 { 2510 $contributors = array(); 2511 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) 2512 { 2513 $name = null; 2514 $uri = null; 2515 $email = null; 2516 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 2517 { 2518 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2519 } 2520 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 2521 { 2522 $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])); 2523 } 2524 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 2525 { 2526 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2527 } 2528 if ($name !== null || $email !== null || $uri !== null) 2529 { 2530 $contributors[] = new $this->author_class($name, $uri, $email); 2531 } 2532 } 2533 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) 2534 { 2535 $name = null; 2536 $url = null; 2537 $email = null; 2538 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 2539 { 2540 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2541 } 2542 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 2543 { 2544 $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])); 2545 } 2546 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 2547 { 2548 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2549 } 2550 if ($name !== null || $email !== null || $url !== null) 2551 { 2552 $contributors[] = new $this->author_class($name, $url, $email); 2553 } 2554 } 2555 2556 if (!empty($contributors)) 2557 { 2558 return SimplePie_Misc::array_unique($contributors); 2559 } 2560 else 2561 { 2562 return null; 2563 } 2564 } 2565 2566 function get_link($key = 0, $rel = 'alternate') 2567 { 2568 $links = $this->get_links($rel); 2569 if (isset($links[$key])) 2570 { 2571 return $links[$key]; 2572 } 2573 else 2574 { 2575 return null; 2576 } 2577 } 2578 2579 /** 2580 * Added for parity between the parent-level and the item/entry-level. 2581 */ 2582 function get_permalink() 2583 { 2584 return $this->get_link(0); 2585 } 2586 2587 function get_links($rel = 'alternate') 2588 { 2589 if (!isset($this->data['links'])) 2590 { 2591 $this->data['links'] = array(); 2592 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) 2593 { 2594 foreach ($links as $link) 2595 { 2596 if (isset($link['attribs']['']['href'])) 2597 { 2598 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 2599 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 2600 } 2601 } 2602 } 2603 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) 2604 { 2605 foreach ($links as $link) 2606 { 2607 if (isset($link['attribs']['']['href'])) 2608 { 2609 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 2610 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 2611 2612 } 2613 } 2614 } 2615 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 2616 { 2617 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 2618 } 2619 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 2620 { 2621 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 2622 } 2623 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 2624 { 2625 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 2626 } 2627 2628 $keys = array_keys($this->data['links']); 2629 foreach ($keys as $key) 2630 { 2631 if (SimplePie_Misc::is_isegment_nz_nc($key)) 2632 { 2633 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) 2634 { 2635 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); 2636 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; 2637 } 2638 else 2639 { 2640 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; 2641 } 2642 } 2643 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) 2644 { 2645 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; 2646 } 2647 $this->data['links'][$key] = array_unique($this->data['links'][$key]); 2648 } 2649 } 2650 2651 if (isset($this->data['links'][$rel])) 2652 { 2653 return $this->data['links'][$rel]; 2654 } 2655 else 2656 { 2657 return null; 2658 } 2659 } 2660 2661 function get_all_discovered_feeds() 2662 { 2663 return $this->all_discovered_feeds; 2664 } 2665 2666 function get_description() 2667 { 2668 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) 2669 { 2670 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2671 } 2672 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) 2673 { 2674 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2675 } 2676 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) 2677 { 2678 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2679 } 2680 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) 2681 { 2682 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2683 } 2684 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) 2685 { 2686 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 2687 } 2688 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) 2689 { 2690 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2691 } 2692 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) 2693 { 2694 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2695 } 2696 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) 2697 { 2698 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 2699 } 2700 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) 2701 { 2702 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 2703 } 2704 else 2705 { 2706 return null; 2707 } 2708 } 2709 2710 function get_copyright() 2711 { 2712 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) 2713 { 2714 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2715 } 2716 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) 2717 { 2718 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2719 } 2720 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright')) 2721 { 2722 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2723 } 2724 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) 2725 { 2726 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2727 } 2728 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) 2729 { 2730 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2731 } 2732 else 2733 { 2734 return null; 2735 } 2736 } 2737 2738 function get_language() 2739 { 2740 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language')) 2741 { 2742 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2743 } 2744 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) 2745 { 2746 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2747 } 2748 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) 2749 { 2750 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2751 } 2752 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'])) 2753 { 2754 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 2755 } 2756 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'])) 2757 { 2758 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 2759 } 2760 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'])) 2761 { 2762 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 2763 } 2764 elseif (isset($this->data['headers']['content-language'])) 2765 { 2766 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT); 2767 } 2768 else 2769 { 2770 return null; 2771 } 2772 } 2773 2774 function get_latitude() 2775 { 2776 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) 2777 { 2778 return (float) $return[0]['data']; 2779 } 2780 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) 2781 { 2782 return (float) $match[1]; 2783 } 2784 else 2785 { 2786 return null; 2787 } 2788 } 2789 2790 function get_longitude() 2791 { 2792 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) 2793 { 2794 return (float) $return[0]['data']; 2795 } 2796 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) 2797 { 2798 return (float) $return[0]['data']; 2799 } 2800 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', $return[0]['data'], $match)) 2801 { 2802 return (float) $match[2]; 2803 } 2804 else 2805 { 2806 return null; 2807 } 2808 } 2809 2810 function get_image_title() 2811 { 2812 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 2813 { 2814 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2815 } 2816 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 2817 { 2818 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2819 } 2820 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 2821 { 2822 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2823 } 2824 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 2825 { 2826 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2827 } 2828 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 2829 { 2830 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2831 } 2832 else 2833 { 2834 return null; 2835 } 2836 } 2837 2838 function get_image_url() 2839 { 2840 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) 2841 { 2842 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); 2843 } 2844 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) 2845 { 2846 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2847 } 2848 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) 2849 { 2850 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2851 } 2852 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url')) 2853 { 2854 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2855 } 2856 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url')) 2857 { 2858 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2859 } 2860 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) 2861 { 2862 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2863 } 2864 else 2865 { 2866 return null; 2867 } 2868 } 2869 2870 function get_image_link() 2871 { 2872 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 2873 { 2874 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2875 } 2876 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 2877 { 2878 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2879 } 2880 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 2881 { 2882 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2883 } 2884 else 2885 { 2886 return null; 2887 } 2888 } 2889 2890 function get_image_width() 2891 { 2892 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width')) 2893 { 2894 return round($return[0]['data']); 2895 } 2896 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) 2897 { 2898 return 88.0; 2899 } 2900 else 2901 { 2902 return null; 2903 } 2904 } 2905 2906 function get_image_height() 2907 { 2908 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height')) 2909 { 2910 return round($return[0]['data']); 2911 } 2912 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) 2913 { 2914 return 31.0; 2915 } 2916 else 2917 { 2918 return null; 2919 } 2920 } 2921 2922 function get_item_quantity($max = 0) 2923 { 2924 $max = (int) $max; 2925 $qty = count($this->get_items()); 2926 if ($max === 0) 2927 { 2928 return $qty; 2929 } 2930 else 2931 { 2932 return ($qty > $max) ? $max : $qty; 2933 } 2934 } 2935 2936 function get_item($key = 0) 2937 { 2938 $items = $this->get_items(); 2939 if (isset($items[$key])) 2940 { 2941 return $items[$key]; 2942 } 2943 else 2944 { 2945 return null; 2946 } 2947 } 2948 2949 function get_items($start = 0, $end = 0) 2950 { 2951 if (!isset($this->data['items'])) 2952 { 2953 if (!empty($this->multifeed_objects)) 2954 { 2955 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit); 2956 } 2957 else 2958 { 2959 $this->data['items'] = array(); 2960 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry')) 2961 { 2962 $keys = array_keys($items); 2963 foreach ($keys as $key) 2964 { 2965 $this->data['items'][] = new $this->item_class($this, $items[$key]); 2966 } 2967 } 2968 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry')) 2969 { 2970 $keys = array_keys($items); 2971 foreach ($keys as $key) 2972 { 2973 $this->data['items'][] = new $this->item_class($this, $items[$key]); 2974 } 2975 } 2976 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item')) 2977 { 2978 $keys = array_keys($items); 2979 foreach ($keys as $key) 2980 { 2981 $this->data['items'][] = new $this->item_class($this, $items[$key]); 2982 } 2983 } 2984 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item')) 2985 { 2986 $keys = array_keys($items); 2987 foreach ($keys as $key) 2988 { 2989 $this->data['items'][] = new $this->item_class($this, $items[$key]); 2990 } 2991 } 2992 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item')) 2993 { 2994 $keys = array_keys($items); 2995 foreach ($keys as $key) 2996 { 2997 $this->data['items'][] = new $this->item_class($this, $items[$key]); 2998 } 2999 } 3000 } 3001 } 3002 3003 if (!empty($this->data['items'])) 3004 { 3005 // If we want to order it by date, check if all items have a date, and then sort it 3006 if ($this->order_by_date && empty($this->multifeed_objects)) 3007 { 3008 if (!isset($this->data['ordered_items'])) 3009 { 3010 $do_sort = true; 3011 foreach ($this->data['items'] as $item) 3012 { 3013 if (!$item->get_date('U')) 3014 { 3015 $do_sort = false; 3016 break; 3017 } 3018 } 3019 $item = null; 3020 $this->data['ordered_items'] = $this->data['items']; 3021 if ($do_sort) 3022 { 3023 usort($this->data['ordered_items'], array(&$this, 'sort_items')); 3024 } 3025 } 3026 $items = $this->data['ordered_items']; 3027 } 3028 else 3029 { 3030 $items = $this->data['items']; 3031 } 3032 3033 // Slice the data as desired 3034 if ($end === 0) 3035 { 3036 return array_slice($items, $start); 3037 } 3038 else 3039 { 3040 return array_slice($items, $start, $end); 3041 } 3042 } 3043 else 3044 { 3045 return array(); 3046 } 3047 } 3048 3049 /** 3050 * @static 3051 */ 3052 function sort_items($a, $b) 3053 { 3054 return $a->get_date('U') <= $b->get_date('U'); 3055 } 3056 3057 /** 3058 * @static 3059 */ 3060 function merge_items($urls, $start = 0, $end = 0, $limit = 0) 3061 { 3062 if (is_array($urls) && sizeof($urls) > 0) 3063 { 3064 $items = array(); 3065 foreach ($urls as $arg) 3066 { 3067 if (is_a($arg, 'SimplePie')) 3068 { 3069 $items = array_merge($items, $arg->get_items(0, $limit)); 3070 } 3071 else 3072 { 3073 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING); 3074 } 3075 } 3076 3077 $do_sort = true; 3078 foreach ($items as $item) 3079 { 3080 if (!$item->get_date('U')) 3081 { 3082 $do_sort = false; 3083 break; 3084 } 3085 } 3086 $item = null; 3087 if ($do_sort) 3088 { 3089 usort($items, array('SimplePie', 'sort_items')); 3090 } 3091 3092 if ($end === 0) 3093 { 3094 return array_slice($items, $start); 3095 } 3096 else 3097 { 3098 return array_slice($items, $start, $end); 3099 } 3100 } 3101 else 3102 { 3103 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING); 3104 return array(); 3105 } 3106 } 3107 } 3108 3109 class SimplePie_Item 3110 { 3111 var $feed; 3112 var $data = array(); 3113 3114 function SimplePie_Item($feed, $data) 3115 { 3116 $this->feed = $feed; 3117 $this->data = $data; 3118 } 3119 3120 function __toString() 3121 { 3122 return md5(serialize($this->data)); 3123 } 3124 3125 /** 3126 * Remove items that link back to this before destroying this object 3127 */ 3128 function __destruct() 3129 { 3130 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode')) 3131 { 3132 unset($this->feed); 3133 } 3134 } 3135 3136 function get_item_tags($namespace, $tag) 3137 { 3138 if (isset($this->data['child'][$namespace][$tag])) 3139 { 3140 return $this->data['child'][$namespace][$tag]; 3141 } 3142 else 3143 { 3144 return null; 3145 } 3146 } 3147 3148 function get_base($element = array()) 3149 { 3150 return $this->feed->get_base($element); 3151 } 3152 3153 function sanitize($data, $type, $base = '') 3154 { 3155 return $this->feed->sanitize($data, $type, $base); 3156 } 3157 3158 function get_feed() 3159 { 3160 return $this->feed; 3161 } 3162 3163 function get_id($hash = false) 3164 { 3165 if (!$hash) 3166 { 3167 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id')) 3168 { 3169 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3170 } 3171 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id')) 3172 { 3173 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3174 } 3175 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid')) 3176 { 3177 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3178 } 3179 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier')) 3180 { 3181 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3182 } 3183 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier')) 3184 { 3185 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3186 } 3187 elseif (($return = $this->get_permalink()) !== null) 3188 { 3189 return $return; 3190 } 3191 elseif (($return = $this->get_title()) !== null) 3192 { 3193 return $return; 3194 } 3195 } 3196 if ($this->get_permalink() !== null || $this->get_title() !== null) 3197 { 3198 return md5($this->get_permalink() . $this->get_title()); 3199 } 3200 else 3201 { 3202 return md5(serialize($this->data)); 3203 } 3204 } 3205 3206 function get_title() 3207 { 3208 if (!isset($this->data['title'])) 3209 { 3210 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) 3211 { 3212 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3213 } 3214 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) 3215 { 3216 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3217 } 3218 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 3219 { 3220 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3221 } 3222 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 3223 { 3224 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3225 } 3226 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 3227 { 3228 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3229 } 3230 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 3231 { 3232 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3233 } 3234 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 3235 { 3236 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3237 } 3238 else 3239 { 3240 $this->data['title'] = null; 3241 } 3242 } 3243 return $this->data['title']; 3244 } 3245 3246 function get_description($description_only = false) 3247 { 3248 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary')) 3249 { 3250 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3251 } 3252 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary')) 3253 { 3254 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3255 } 3256 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) 3257 { 3258 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3259 } 3260 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) 3261 { 3262 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 3263 } 3264 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) 3265 { 3266 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3267 } 3268 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) 3269 { 3270 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3271 } 3272 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) 3273 { 3274 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 3275 } 3276 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) 3277 { 3278 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3279 } 3280 elseif (!$description_only) 3281 { 3282 return $this->get_content(true); 3283 } 3284 else 3285 { 3286 return null; 3287 } 3288 } 3289 3290 function get_content($content_only = false) 3291 { 3292 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content')) 3293 { 3294 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3295 } 3296 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content')) 3297 { 3298 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3299 } 3300 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded')) 3301 { 3302 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 3303 } 3304 elseif (!$content_only) 3305 { 3306 return $this->get_description(true); 3307 } 3308 else 3309 { 3310 return null; 3311 } 3312 } 3313 3314 function get_category($key = 0) 3315 { 3316 $categories = $this->get_categories(); 3317 if (isset($categories[$key])) 3318 { 3319 return $categories[$key]; 3320 } 3321 else 3322 { 3323 return null; 3324 } 3325 } 3326 3327 function get_categories() 3328 { 3329 $categories = array(); 3330 3331 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) 3332 { 3333 $term = null; 3334 $scheme = null; 3335 $label = null; 3336 if (isset($category['attribs']['']['term'])) 3337 { 3338 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); 3339 } 3340 if (isset($category['attribs']['']['scheme'])) 3341 { 3342 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3343 } 3344 if (isset($category['attribs']['']['label'])) 3345 { 3346 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 3347 } 3348 $categories[] = new $this->feed->category_class($term, $scheme, $label); 3349 } 3350 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) 3351 { 3352 // This is really the label, but keep this as the term also for BC. 3353 // Label will also work on retrieving because that falls back to term. 3354 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3355 if (isset($category['attribs']['']['domain'])) 3356 { 3357 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); 3358 } 3359 else 3360 { 3361 $scheme = null; 3362 } 3363 $categories[] = new $this->feed->category_class($term, $scheme, null); 3364 } 3365 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) 3366 { 3367 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3368 } 3369 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) 3370 { 3371 $categories[] = new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3372 } 3373 3374 if (!empty($categories)) 3375 { 3376 return SimplePie_Misc::array_unique($categories); 3377 } 3378 else 3379 { 3380 return null; 3381 } 3382 } 3383 3384 function get_author($key = 0) 3385 { 3386 $authors = $this->get_authors(); 3387 if (isset($authors[$key])) 3388 { 3389 return $authors[$key]; 3390 } 3391 else 3392 { 3393 return null; 3394 } 3395 } 3396 3397 function get_contributor($key = 0) 3398 { 3399 $contributors = $this->get_contributors(); 3400 if (isset($contributors[$key])) 3401 { 3402 return $contributors[$key]; 3403 } 3404 else 3405 { 3406 return null; 3407 } 3408 } 3409 3410 function get_contributors() 3411 { 3412 $contributors = array(); 3413 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) 3414 { 3415 $name = null; 3416 $uri = null; 3417 $email = null; 3418 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 3419 { 3420 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3421 } 3422 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 3423 { 3424 $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])); 3425 } 3426 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 3427 { 3428 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3429 } 3430 if ($name !== null || $email !== null || $uri !== null) 3431 { 3432 $contributors[] = new $this->feed->author_class($name, $uri, $email); 3433 } 3434 } 3435 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) 3436 { 3437 $name = null; 3438 $url = null; 3439 $email = null; 3440 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 3441 { 3442 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3443 } 3444 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 3445 { 3446 $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])); 3447 } 3448 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 3449 { 3450 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3451 } 3452 if ($name !== null || $email !== null || $url !== null) 3453 { 3454 $contributors[] = new $this->feed->author_class($name, $url, $email); 3455 } 3456 } 3457 3458 if (!empty($contributors)) 3459 { 3460 return SimplePie_Misc::array_unique($contributors); 3461 } 3462 else 3463 { 3464 return null; 3465 } 3466 } 3467 3468 function get_authors() 3469 { 3470 $authors = array(); 3471 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) 3472 { 3473 $name = null; 3474 $uri = null; 3475 $email = null; 3476 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 3477 { 3478 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3479 } 3480 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 3481 { 3482 $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])); 3483 } 3484 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 3485 { 3486 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3487 } 3488 if ($name !== null || $email !== null || $uri !== null) 3489 { 3490 $authors[] = new $this->feed->author_class($name, $uri, $email); 3491 } 3492 } 3493 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) 3494 { 3495 $name = null; 3496 $url = null; 3497 $email = null; 3498 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 3499 { 3500 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3501 } 3502 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 3503 { 3504 $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])); 3505 } 3506 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 3507 { 3508 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3509 } 3510 if ($name !== null || $email !== null || $url !== null) 3511 { 3512 $authors[] = new $this->feed->author_class($name, $url, $email); 3513 } 3514 } 3515 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author')) 3516 { 3517 $authors[] = new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 3518 } 3519 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) 3520 { 3521 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3522 } 3523 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) 3524 { 3525 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3526 } 3527 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) 3528 { 3529 $authors[] = new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3530 } 3531 3532 if (!empty($authors)) 3533 { 3534 return SimplePie_Misc::array_unique($authors); 3535 } 3536 elseif (($source = $this->get_source()) && ($authors = $source->get_authors())) 3537 { 3538 return $authors; 3539 } 3540 elseif ($authors = $this->feed->get_authors()) 3541 { 3542 return $authors; 3543 } 3544 else 3545 { 3546 return null; 3547 } 3548 } 3549 3550 function get_copyright() 3551 { 3552 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) 3553 { 3554 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3555 } 3556 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) 3557 { 3558 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3559 } 3560 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) 3561 { 3562 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3563 } 3564 else 3565 { 3566 return null; 3567 } 3568 } 3569 3570 function get_date($date_format = 'j F Y, g:i a') 3571 { 3572 if (!isset($this->data['date'])) 3573 { 3574 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published')) 3575 { 3576 $this->data['date']['raw'] = $return[0]['data']; 3577 } 3578 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated')) 3579 { 3580 $this->data['date']['raw'] = $return[0]['data']; 3581 } 3582 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued')) 3583 { 3584 $this->data['date']['raw'] = $return[0]['data']; 3585 } 3586 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created')) 3587 { 3588 $this->data['date']['raw'] = $return[0]['data']; 3589 } 3590 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified')) 3591 { 3592 $this->data['date']['raw'] = $return[0]['data']; 3593 } 3594 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate')) 3595 { 3596 $this->data['date']['raw'] = $return[0]['data']; 3597 } 3598 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date')) 3599 { 3600 $this->data['date']['raw'] = $return[0]['data']; 3601 } 3602 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date')) 3603 { 3604 $this->data['date']['raw'] = $return[0]['data']; 3605 } 3606 3607 if (!empty($this->data['date']['raw'])) 3608 { 3609 $parser = SimplePie_Parse_Date::get(); 3610 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']); 3611 } 3612 else 3613 { 3614 $this->data['date'] = null; 3615 } 3616 } 3617 if ($this->data['date']) 3618 { 3619 $date_format = (string) $date_format; 3620 switch ($date_format) 3621 { 3622 case '': 3623 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT); 3624 3625 case 'U': 3626 return $this->data['date']['parsed']; 3627 3628 default: 3629 return date($date_format, $this->data['date']['parsed']); 3630 } 3631 } 3632 else 3633 { 3634 return null; 3635 } 3636 } 3637 3638 function get_local_date($date_format = '%c') 3639 { 3640 if (!$date_format) 3641 { 3642 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT); 3643 } 3644 elseif (($date = $this->get_date('U')) !== null) 3645 { 3646 return strftime($date_format, $date); 3647 } 3648 else 3649 { 3650 return null; 3651 } 3652 } 3653 3654 function get_permalink() 3655 { 3656 $link = $this->get_link(); 3657 $enclosure = $this->get_enclosure(0); 3658 if ($link !== null) 3659 { 3660 return $link; 3661 } 3662 elseif ($enclosure !== null) 3663 { 3664 return $enclosure->get_link(); 3665 } 3666 else 3667 { 3668 return null; 3669 } 3670 } 3671 3672 function get_link($key = 0, $rel = 'alternate') 3673 { 3674 $links = $this->get_links($rel); 3675 if ($links[$key] !== null) 3676 { 3677 return $links[$key]; 3678 } 3679 else 3680 { 3681 return null; 3682 } 3683 } 3684 3685 function get_links($rel = 'alternate') 3686 { 3687 if (!isset($this->data['links'])) 3688 { 3689 $this->data['links'] = array(); 3690 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link) 3691 { 3692 if (isset($link['attribs']['']['href'])) 3693 { 3694 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 3695 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 3696 3697 } 3698 } 3699 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link) 3700 { 3701 if (isset($link['attribs']['']['href'])) 3702 { 3703 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 3704 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 3705 } 3706 } 3707 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 3708 { 3709 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3710 } 3711 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 3712 { 3713 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3714 } 3715 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 3716 { 3717 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3718 } 3719 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid')) 3720 { 3721 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true') 3722 { 3723 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3724 } 3725 } 3726 3727 $keys = array_keys($this->data['links']); 3728 foreach ($keys as $key) 3729 { 3730 if (SimplePie_Misc::is_isegment_nz_nc($key)) 3731 { 3732 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) 3733 { 3734 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); 3735 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; 3736 } 3737 else 3738 { 3739 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; 3740 } 3741 } 3742 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) 3743 { 3744 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; 3745 } 3746 $this->data['links'][$key] = array_unique($this->data['links'][$key]); 3747 } 3748 } 3749 if (isset($this->data['links'][$rel])) 3750 { 3751 return $this->data['links'][$rel]; 3752 } 3753 else 3754 { 3755 return null; 3756 } 3757 } 3758 3759 /** 3760 * @todo Add ability to prefer one type of content over another (in a media group). 3761 */ 3762 function get_enclosure($key = 0, $prefer = null) 3763 { 3764 $enclosures = $this->get_enclosures(); 3765 if (isset($enclosures[$key])) 3766 { 3767 return $enclosures[$key]; 3768 } 3769 else 3770 { 3771 return null; 3772 } 3773 } 3774 3775 /** 3776 * Grabs all available enclosures (podcasts, etc.) 3777 * 3778 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS. 3779 * 3780 * 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. 3781 * 3782 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4). 3783 * @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). 3784 */ 3785 function get_enclosures() 3786 { 3787 if (!isset($this->data['enclosures'])) 3788 { 3789 $this->data['enclosures'] = array(); 3790 3791 // Elements 3792 $captions_parent = null; 3793 $categories_parent = null; 3794 $copyrights_parent = null; 3795 $credits_parent = null; 3796 $description_parent = null; 3797 $duration_parent = null; 3798 $hashes_parent = null; 3799 $keywords_parent = null; 3800 $player_parent = null; 3801 $ratings_parent = null; 3802 $restrictions_parent = null; 3803 $thumbnails_parent = null; 3804 $title_parent = null; 3805 3806 // Let's do the channel and item-level ones first, and just re-use them if we need to. 3807 $parent = $this->get_feed(); 3808 3809 // CAPTIONS 3810 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) 3811 { 3812 foreach ($captions as $caption) 3813 { 3814 $caption_type = null; 3815 $caption_lang = null; 3816 $caption_startTime = null; 3817 $caption_endTime = null; 3818 $caption_text = null; 3819 if (isset($caption['attribs']['']['type'])) 3820 { 3821 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 3822 } 3823 if (isset($caption['attribs']['']['lang'])) 3824 { 3825 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 3826 } 3827 if (isset($caption['attribs']['']['start'])) 3828 { 3829 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 3830 } 3831 if (isset($caption['attribs']['']['end'])) 3832 { 3833 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 3834 } 3835 if (isset($caption['data'])) 3836 { 3837 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3838 } 3839 $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 3840 } 3841 } 3842 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) 3843 { 3844 foreach ($captions as $caption) 3845 { 3846 $caption_type = null; 3847 $caption_lang = null; 3848 $caption_startTime = null; 3849 $caption_endTime = null; 3850 $caption_text = null; 3851 if (isset($caption['attribs']['']['type'])) 3852 { 3853 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 3854 } 3855 if (isset($caption['attribs']['']['lang'])) 3856 { 3857 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 3858 } 3859 if (isset($caption['attribs']['']['start'])) 3860 { 3861 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 3862 } 3863 if (isset($caption['attribs']['']['end'])) 3864 { 3865 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 3866 } 3867 if (isset($caption['data'])) 3868 { 3869 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3870 } 3871 $captions_parent[] = new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 3872 } 3873 } 3874 if (is_array($captions_parent)) 3875 { 3876 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent)); 3877 } 3878 3879 // CATEGORIES 3880 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) 3881 { 3882 $term = null; 3883 $scheme = null; 3884 $label = null; 3885 if (isset($category['data'])) 3886 { 3887 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3888 } 3889 if (isset($category['attribs']['']['scheme'])) 3890 { 3891 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3892 } 3893 else 3894 { 3895 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 3896 } 3897 if (isset($category['attribs']['']['label'])) 3898 { 3899 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 3900 } 3901 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label); 3902 } 3903 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) 3904 { 3905 $term = null; 3906 $scheme = null; 3907 $label = null; 3908 if (isset($category['data'])) 3909 { 3910 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3911 } 3912 if (isset($category['attribs']['']['scheme'])) 3913 { 3914 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3915 } 3916 else 3917 { 3918 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 3919 } 3920 if (isset($category['attribs']['']['label'])) 3921 { 3922 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 3923 } 3924 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label); 3925 } 3926 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category) 3927 { 3928 $term = null; 3929 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd'; 3930 $label = null; 3931 if (isset($category['attribs']['']['text'])) 3932 { 3933 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); 3934 } 3935 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label); 3936 3937 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'])) 3938 { 3939 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory) 3940 { 3941 if (isset($subcategory['attribs']['']['text'])) 3942 { 3943 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); 3944 } 3945 $categories_parent[] = new $this->feed->category_class($term, $scheme, $label); 3946 } 3947 } 3948 } 3949 if (is_array($categories_parent)) 3950 { 3951 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent)); 3952 } 3953 3954 // COPYRIGHT 3955 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) 3956 { 3957 $copyright_url = null; 3958 $copyright_label = null; 3959 if (isset($copyright[0]['attribs']['']['url'])) 3960 { 3961 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 3962 } 3963 if (isset($copyright[0]['data'])) 3964 { 3965 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3966 } 3967 $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label); 3968 } 3969 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) 3970 { 3971 $copyright_url = null; 3972 $copyright_label = null; 3973 if (isset($copyright[0]['attribs']['']['url'])) 3974 { 3975 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 3976 } 3977 if (isset($copyright[0]['data'])) 3978 { 3979 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3980 } 3981 $copyrights_parent = new $this->feed->copyright_class($copyright_url, $copyright_label); 3982 } 3983 3984 // CREDITS 3985 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) 3986 { 3987 foreach ($credits as $credit) 3988 { 3989 $credit_role = null; 3990 $credit_scheme = null; 3991 $credit_name = null; 3992 if (isset($credit['attribs']['']['role'])) 3993 { 3994 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 3995 } 3996 if (isset($credit['attribs']['']['scheme'])) 3997 { 3998 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3999 } 4000 else 4001 { 4002 $credit_scheme = 'urn:ebu'; 4003 } 4004 if (isset($credit['data'])) 4005 { 4006 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4007 } 4008 $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4009 } 4010 } 4011 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) 4012 { 4013 foreach ($credits as $credit) 4014 { 4015 $credit_role = null; 4016 $credit_scheme = null; 4017 $credit_name = null; 4018 if (isset($credit['attribs']['']['role'])) 4019 { 4020 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 4021 } 4022 if (isset($credit['attribs']['']['scheme'])) 4023 { 4024 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4025 } 4026 else 4027 { 4028 $credit_scheme = 'urn:ebu'; 4029 } 4030 if (isset($credit['data'])) 4031 { 4032 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4033 } 4034 $credits_parent[] = new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4035 } 4036 } 4037 if (is_array($credits_parent)) 4038 { 4039 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent)); 4040 } 4041 4042 // DESCRIPTION 4043 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) 4044 { 4045 if (isset($description_parent[0]['data'])) 4046 { 4047 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4048 } 4049 } 4050 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) 4051 { 4052 if (isset($description_parent[0]['data'])) 4053 { 4054 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4055 } 4056 } 4057 4058 // DURATION 4059 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration')) 4060 { 4061 $seconds = null; 4062 $minutes = null; 4063 $hours = null; 4064 if (isset($duration_parent[0]['data'])) 4065 { 4066 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4067 if (sizeof($temp) > 0) 4068 { 4069 (int) $seconds = array_pop($temp); 4070 } 4071 if (sizeof($temp) > 0) 4072 { 4073 (int) $minutes = array_pop($temp); 4074 $seconds += $minutes * 60; 4075 } 4076 if (sizeof($temp) > 0) 4077 { 4078 (int) $hours = array_pop($temp); 4079 $seconds += $hours * 3600; 4080 } 4081 unset($temp); 4082 $duration_parent = $seconds; 4083 } 4084 } 4085 4086 // HASHES 4087 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) 4088 { 4089 foreach ($hashes_iterator as $hash) 4090 { 4091 $value = null; 4092 $algo = null; 4093 if (isset($hash['data'])) 4094 { 4095 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4096 } 4097 if (isset($hash['attribs']['']['algo'])) 4098 { 4099 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4100 } 4101 else 4102 { 4103 $algo = 'md5'; 4104 } 4105 $hashes_parent[] = $algo.':'.$value; 4106 } 4107 } 4108 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) 4109 { 4110 foreach ($hashes_iterator as $hash) 4111 { 4112 $value = null; 4113 $algo = null; 4114 if (isset($hash['data'])) 4115 { 4116 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4117 } 4118 if (isset($hash['attribs']['']['algo'])) 4119 { 4120 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4121 } 4122 else 4123 { 4124 $algo = 'md5'; 4125 } 4126 $hashes_parent[] = $algo.':'.$value; 4127 } 4128 } 4129 if (is_array($hashes_parent)) 4130 { 4131 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent)); 4132 } 4133 4134 // KEYWORDS 4135 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) 4136 { 4137 if (isset($keywords[0]['data'])) 4138 { 4139 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4140 foreach ($temp as $word) 4141 { 4142 $keywords_parent[] = trim($word); 4143 } 4144 } 4145 unset($temp); 4146 } 4147 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) 4148 { 4149 if (isset($keywords[0]['data'])) 4150 { 4151 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4152 foreach ($temp as $word) 4153 { 4154 $keywords_parent[] = trim($word); 4155 } 4156 } 4157 unset($temp); 4158 } 4159 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) 4160 { 4161 if (isset($keywords[0]['data'])) 4162 { 4163 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4164 foreach ($temp as $word) 4165 { 4166 $keywords_parent[] = trim($word); 4167 } 4168 } 4169 unset($temp); 4170 } 4171 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) 4172 { 4173 if (isset($keywords[0]['data'])) 4174 { 4175 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4176 foreach ($temp as $word) 4177 { 4178 $keywords_parent[] = trim($word); 4179 } 4180 } 4181 unset($temp); 4182 } 4183 if (is_array($keywords_parent)) 4184 { 4185 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent)); 4186 } 4187 4188 // PLAYER 4189 if ($player_parent = $th