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