[ Index ] |
PHP Cross Reference of phpwcms V1.4.7 _r403 (01.11.10) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * SimplePie 4 * 5 * A PHP-Based RSS and Atom Feed Framework. 6 * Takes the hard work out of managing a complete RSS/Atom solution. 7 * 8 * Copyright (c) 2004-2010, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without modification, are 12 * permitted provided that the following conditions are met: 13 * 14 * * Redistributions of source code must retain the above copyright notice, this list of 15 * conditions and the following disclaimer. 16 * 17 * * Redistributions in binary form must reproduce the above copyright notice, this list 18 * of conditions and the following disclaimer in the documentation and/or other materials 19 * provided with the distribution. 20 * 21 * * Neither the name of the SimplePie Team nor the names of its contributors may be used 22 * to endorse or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 28 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 32 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * @package SimplePie 36 * @version 1.3-dev 37 * @copyright 2004-2010 Ryan Parman, Geoffrey Sneddon, Ryan McCue 38 * @author Ryan Parman 39 * @author Geoffrey Sneddon 40 * @author Ryan McCue 41 * @link http://simplepie.org/ SimplePie 42 * @link http://simplepie.org/support/ Please submit all bug reports and feature requests to the SimplePie forums 43 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 44 * @todo phpDoc comments 45 */ 46 47 /** 48 * SimplePie Name 49 */ 50 define('SIMPLEPIE_NAME', 'SimplePie'); 51 52 /** 53 * SimplePie Version 54 */ 55 define('SIMPLEPIE_VERSION', '1.3-dev'); 56 57 /** 58 * SimplePie Build 59 */ 60 define('SIMPLEPIE_BUILD', '20101003193300'); 61 62 /** 63 * SimplePie Website URL 64 */ 65 define('SIMPLEPIE_URL', 'http://simplepie.org'); 66 67 /** 68 * SimplePie Useragent 69 * @see SimplePie::set_useragent() 70 */ 71 define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD); 72 73 /** 74 * SimplePie Linkback 75 */ 76 define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>'); 77 78 /** 79 * No Autodiscovery 80 * @see SimplePie::set_autodiscovery_level() 81 */ 82 define('SIMPLEPIE_LOCATOR_NONE', 0); 83 84 /** 85 * Feed Link Element Autodiscovery 86 * @see SimplePie::set_autodiscovery_level() 87 */ 88 define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1); 89 90 /** 91 * Local Feed Extension Autodiscovery 92 * @see SimplePie::set_autodiscovery_level() 93 */ 94 define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2); 95 96 /** 97 * Local Feed Body Autodiscovery 98 * @see SimplePie::set_autodiscovery_level() 99 */ 100 define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4); 101 102 /** 103 * Remote Feed Extension Autodiscovery 104 * @see SimplePie::set_autodiscovery_level() 105 */ 106 define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8); 107 108 /** 109 * Remote Feed Body Autodiscovery 110 * @see SimplePie::set_autodiscovery_level() 111 */ 112 define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16); 113 114 /** 115 * All Feed Autodiscovery 116 * @see SimplePie::set_autodiscovery_level() 117 */ 118 define('SIMPLEPIE_LOCATOR_ALL', 31); 119 120 /** 121 * No known feed type 122 */ 123 define('SIMPLEPIE_TYPE_NONE', 0); 124 125 /** 126 * RSS 0.90 127 */ 128 define('SIMPLEPIE_TYPE_RSS_090', 1); 129 130 /** 131 * RSS 0.91 (Netscape) 132 */ 133 define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2); 134 135 /** 136 * RSS 0.91 (Userland) 137 */ 138 define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4); 139 140 /** 141 * RSS 0.91 (both Netscape and Userland) 142 */ 143 define('SIMPLEPIE_TYPE_RSS_091', 6); 144 145 /** 146 * RSS 0.92 147 */ 148 define('SIMPLEPIE_TYPE_RSS_092', 8); 149 150 /** 151 * RSS 0.93 152 */ 153 define('SIMPLEPIE_TYPE_RSS_093', 16); 154 155 /** 156 * RSS 0.94 157 */ 158 define('SIMPLEPIE_TYPE_RSS_094', 32); 159 160 /** 161 * RSS 1.0 162 */ 163 define('SIMPLEPIE_TYPE_RSS_10', 64); 164 165 /** 166 * RSS 2.0 167 */ 168 define('SIMPLEPIE_TYPE_RSS_20', 128); 169 170 /** 171 * RDF-based RSS 172 */ 173 define('SIMPLEPIE_TYPE_RSS_RDF', 65); 174 175 /** 176 * Non-RDF-based RSS (truly intended as syndication format) 177 */ 178 define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190); 179 180 /** 181 * All RSS 182 */ 183 define('SIMPLEPIE_TYPE_RSS_ALL', 255); 184 185 /** 186 * Atom 0.3 187 */ 188 define('SIMPLEPIE_TYPE_ATOM_03', 256); 189 190 /** 191 * Atom 1.0 192 */ 193 define('SIMPLEPIE_TYPE_ATOM_10', 512); 194 195 /** 196 * All Atom 197 */ 198 define('SIMPLEPIE_TYPE_ATOM_ALL', 768); 199 200 /** 201 * All feed types 202 */ 203 define('SIMPLEPIE_TYPE_ALL', 1023); 204 205 /** 206 * No construct 207 */ 208 define('SIMPLEPIE_CONSTRUCT_NONE', 0); 209 210 /** 211 * Text construct 212 */ 213 define('SIMPLEPIE_CONSTRUCT_TEXT', 1); 214 215 /** 216 * HTML construct 217 */ 218 define('SIMPLEPIE_CONSTRUCT_HTML', 2); 219 220 /** 221 * XHTML construct 222 */ 223 define('SIMPLEPIE_CONSTRUCT_XHTML', 4); 224 225 /** 226 * base64-encoded construct 227 */ 228 define('SIMPLEPIE_CONSTRUCT_BASE64', 8); 229 230 /** 231 * IRI construct 232 */ 233 define('SIMPLEPIE_CONSTRUCT_IRI', 16); 234 235 /** 236 * A construct that might be HTML 237 */ 238 define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32); 239 240 /** 241 * All constructs 242 */ 243 define('SIMPLEPIE_CONSTRUCT_ALL', 63); 244 245 /** 246 * Don't change case 247 */ 248 define('SIMPLEPIE_SAME_CASE', 1); 249 250 /** 251 * Change to lowercase 252 */ 253 define('SIMPLEPIE_LOWERCASE', 2); 254 255 /** 256 * Change to uppercase 257 */ 258 define('SIMPLEPIE_UPPERCASE', 4); 259 260 /** 261 * PCRE for HTML attributes 262 */ 263 define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*'); 264 265 /** 266 * PCRE for XML attributes 267 */ 268 define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*'); 269 270 /** 271 * XML Namespace 272 */ 273 define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace'); 274 275 /** 276 * Atom 1.0 Namespace 277 */ 278 define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom'); 279 280 /** 281 * Atom 0.3 Namespace 282 */ 283 define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#'); 284 285 /** 286 * RDF Namespace 287 */ 288 define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'); 289 290 /** 291 * RSS 0.90 Namespace 292 */ 293 define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/'); 294 295 /** 296 * RSS 1.0 Namespace 297 */ 298 define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/'); 299 300 /** 301 * RSS 1.0 Content Module Namespace 302 */ 303 define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/'); 304 305 /** 306 * RSS 2.0 Namespace 307 * (Stupid, I know, but I'm certain it will confuse people less with support.) 308 */ 309 define('SIMPLEPIE_NAMESPACE_RSS_20', ''); 310 311 /** 312 * DC 1.0 Namespace 313 */ 314 define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/'); 315 316 /** 317 * DC 1.1 Namespace 318 */ 319 define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/'); 320 321 /** 322 * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace 323 */ 324 define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#'); 325 326 /** 327 * GeoRSS Namespace 328 */ 329 define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss'); 330 331 /** 332 * Media RSS Namespace 333 */ 334 define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/'); 335 336 /** 337 * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec. 338 */ 339 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss'); 340 341 /** 342 * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5. 343 */ 344 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss'); 345 346 /** 347 * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace. 348 */ 349 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/'); 350 351 /** 352 * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace. 353 */ 354 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss'); 355 356 /** 357 * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL. 358 */ 359 define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/'); 360 361 /** 362 * iTunes RSS Namespace 363 */ 364 define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd'); 365 366 /** 367 * XHTML Namespace 368 */ 369 define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml'); 370 371 /** 372 * IANA Link Relations Registry 373 */ 374 define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/'); 375 376 /** 377 * Whether we're running on PHP5 378 */ 379 define('SIMPLEPIE_PHP5', version_compare(PHP_VERSION, '5.0.0', '>=')); 380 381 /** 382 * No file source 383 */ 384 define('SIMPLEPIE_FILE_SOURCE_NONE', 0); 385 386 /** 387 * Remote file source 388 */ 389 define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1); 390 391 /** 392 * Local file source 393 */ 394 define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2); 395 396 /** 397 * fsockopen() file source 398 */ 399 define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4); 400 401 /** 402 * cURL file source 403 */ 404 define('SIMPLEPIE_FILE_SOURCE_CURL', 8); 405 406 /** 407 * file_get_contents() file source 408 */ 409 define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16); 410 411 /** 412 * SimplePie 413 * 414 * @package SimplePie 415 */ 416 class SimplePie 417 { 418 /** 419 * @var array Raw data 420 * @access private 421 */ 422 var $data = array(); 423 424 /** 425 * @var mixed Error string 426 * @access private 427 */ 428 var $error; 429 430 /** 431 * @var object Instance of SimplePie_Sanitize (or other class) 432 * @see SimplePie::set_sanitize_class() 433 * @access private 434 */ 435 var $sanitize; 436 437 /** 438 * @var string SimplePie Useragent 439 * @see SimplePie::set_useragent() 440 * @access private 441 */ 442 var $useragent = SIMPLEPIE_USERAGENT; 443 444 /** 445 * @var string Feed URL 446 * @see SimplePie::set_feed_url() 447 * @access private 448 */ 449 var $feed_url; 450 451 /** 452 * @var object Instance of SimplePie_File to use as a feed 453 * @see SimplePie::set_file() 454 * @access private 455 */ 456 var $file; 457 458 /** 459 * @var string Raw feed data 460 * @see SimplePie::set_raw_data() 461 * @access private 462 */ 463 var $raw_data; 464 465 /** 466 * @var int Timeout for fetching remote files 467 * @see SimplePie::set_timeout() 468 * @access private 469 */ 470 var $timeout = 10; 471 472 /** 473 * @var bool Forces fsockopen() to be used for remote files instead 474 * of cURL, even if a new enough version is installed 475 * @see SimplePie::force_fsockopen() 476 * @access private 477 */ 478 var $force_fsockopen = false; 479 480 /** 481 * @var bool Force the given data/URL to be treated as a feed no matter what 482 * it appears like 483 * @see SimplePie::force_feed() 484 * @access private 485 */ 486 var $force_feed = false; 487 488 /** 489 * @var bool Enable/Disable XML dump 490 * @see SimplePie::enable_xml_dump() 491 * @access private 492 */ 493 var $xml_dump = false; 494 495 /** 496 * @var bool Enable/Disable Caching 497 * @see SimplePie::enable_cache() 498 * @access private 499 */ 500 var $cache = true; 501 502 /** 503 * @var int Cache duration (in seconds) 504 * @see SimplePie::set_cache_duration() 505 * @access private 506 */ 507 var $cache_duration = 3600; 508 509 /** 510 * @var int Auto-discovery cache duration (in seconds) 511 * @see SimplePie::set_autodiscovery_cache_duration() 512 * @access private 513 */ 514 var $autodiscovery_cache_duration = 604800; // 7 Days. 515 516 /** 517 * @var string Cache location (relative to executing script) 518 * @see SimplePie::set_cache_location() 519 * @access private 520 */ 521 var $cache_location = './cache'; 522 523 /** 524 * @var string Function that creates the cache filename 525 * @see SimplePie::set_cache_name_function() 526 * @access private 527 */ 528 var $cache_name_function = 'md5'; 529 530 /** 531 * @var bool Reorder feed by date descending 532 * @see SimplePie::enable_order_by_date() 533 * @access private 534 */ 535 var $order_by_date = true; 536 537 /** 538 * @var mixed Force input encoding to be set to the follow value 539 * (false, or anything type-cast to false, disables this feature) 540 * @see SimplePie::set_input_encoding() 541 * @access private 542 */ 543 var $input_encoding = false; 544 545 /** 546 * @var int Feed Autodiscovery Level 547 * @see SimplePie::set_autodiscovery_level() 548 * @access private 549 */ 550 var $autodiscovery = SIMPLEPIE_LOCATOR_ALL; 551 552 /** 553 * @var string Class used for caching feeds 554 * @see SimplePie::set_cache_class() 555 * @access private 556 */ 557 var $cache_class = 'SimplePie_Cache'; 558 559 /** 560 * @var string Class used for locating feeds 561 * @see SimplePie::set_locator_class() 562 * @access private 563 */ 564 var $locator_class = 'SimplePie_Locator'; 565 566 /** 567 * @var string Class used for parsing feeds 568 * @see SimplePie::set_parser_class() 569 * @access private 570 */ 571 var $parser_class = 'SimplePie_Parser'; 572 573 /** 574 * @var string Class used for fetching feeds 575 * @see SimplePie::set_file_class() 576 * @access private 577 */ 578 var $file_class = 'SimplePie_File'; 579 580 /** 581 * @var string Class used for items 582 * @see SimplePie::set_item_class() 583 * @access private 584 */ 585 var $item_class = 'SimplePie_Item'; 586 587 /** 588 * @var string Class used for authors 589 * @see SimplePie::set_author_class() 590 * @access private 591 */ 592 var $author_class = 'SimplePie_Author'; 593 594 /** 595 * @var string Class used for categories 596 * @see SimplePie::set_category_class() 597 * @access private 598 */ 599 var $category_class = 'SimplePie_Category'; 600 601 /** 602 * @var string Class used for enclosures 603 * @see SimplePie::set_enclosures_class() 604 * @access private 605 */ 606 var $enclosure_class = 'SimplePie_Enclosure'; 607 608 /** 609 * @var string Class used for Media RSS <media:text> captions 610 * @see SimplePie::set_caption_class() 611 * @access private 612 */ 613 var $caption_class = 'SimplePie_Caption'; 614 615 /** 616 * @var string Class used for Media RSS <media:copyright> 617 * @see SimplePie::set_copyright_class() 618 * @access private 619 */ 620 var $copyright_class = 'SimplePie_Copyright'; 621 622 /** 623 * @var string Class used for Media RSS <media:credit> 624 * @see SimplePie::set_credit_class() 625 * @access private 626 */ 627 var $credit_class = 'SimplePie_Credit'; 628 629 /** 630 * @var string Class used for Media RSS <media:rating> 631 * @see SimplePie::set_rating_class() 632 * @access private 633 */ 634 var $rating_class = 'SimplePie_Rating'; 635 636 /** 637 * @var string Class used for Media RSS <media:restriction> 638 * @see SimplePie::set_restriction_class() 639 * @access private 640 */ 641 var $restriction_class = 'SimplePie_Restriction'; 642 643 /** 644 * @var string Class used for content-type sniffing 645 * @see SimplePie::set_content_type_sniffer_class() 646 * @access private 647 */ 648 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; 649 650 /** 651 * @var string Class used for item sources. 652 * @see SimplePie::set_source_class() 653 * @access private 654 */ 655 var $source_class = 'SimplePie_Source'; 656 657 /** 658 * @var mixed Set javascript query string parameter (false, or 659 * anything type-cast to false, disables this feature) 660 * @see SimplePie::set_javascript() 661 * @access private 662 */ 663 var $javascript = 'js'; 664 665 /** 666 * @var int Maximum number of feeds to check with autodiscovery 667 * @see SimplePie::set_max_checked_feeds() 668 * @access private 669 */ 670 var $max_checked_feeds = 10; 671 672 /** 673 * @var array All the feeds found during the autodiscovery process 674 * @see SimplePie::get_all_discovered_feeds() 675 * @access private 676 */ 677 var $all_discovered_feeds = array(); 678 679 /** 680 * @var string Web-accessible path to the handler_favicon.php file. 681 * @see SimplePie::set_favicon_handler() 682 * @access private 683 */ 684 var $favicon_handler = ''; 685 686 /** 687 * @var string Web-accessible path to the handler_image.php file. 688 * @see SimplePie::set_image_handler() 689 * @access private 690 */ 691 var $image_handler = ''; 692 693 /** 694 * @var array Stores the URLs when multiple feeds are being initialized. 695 * @see SimplePie::set_feed_url() 696 * @access private 697 */ 698 var $multifeed_url = array(); 699 700 /** 701 * @var array Stores SimplePie objects when multiple feeds initialized. 702 * @access private 703 */ 704 var $multifeed_objects = array(); 705 706 /** 707 * @var array Stores the get_object_vars() array for use with multifeeds. 708 * @see SimplePie::set_feed_url() 709 * @access private 710 */ 711 var $config_settings = null; 712 713 /** 714 * @var integer Stores the number of items to return per-feed with multifeeds. 715 * @see SimplePie::set_item_limit() 716 * @access private 717 */ 718 var $item_limit = 0; 719 720 /** 721 * @var array Stores the default attributes to be stripped by strip_attributes(). 722 * @see SimplePie::strip_attributes() 723 * @access private 724 */ 725 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); 726 727 /** 728 * @var array Stores the default tags to be stripped by strip_htmltags(). 729 * @see SimplePie::strip_htmltags() 730 * @access private 731 */ 732 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); 733 734 /** 735 * The SimplePie class contains feed level data and options 736 * 737 * There are two ways that you can create a new SimplePie object. The first 738 * is by passing a feed URL as a parameter to the SimplePie constructor 739 * (as well as optionally setting the cache location and cache expiry). This 740 * will initialise the whole feed with all of the default settings, and you 741 * can begin accessing methods and properties immediately. 742 * 743 * The second way is to create the SimplePie object with no parameters 744 * at all. This will enable you to set configuration options. After setting 745 * them, you must initialise the feed using $feed->init(). At that point the 746 * object's methods and properties will be available to you. This format is 747 * what is used throughout this documentation. 748 * 749 * @access public 750 * @since 1.0 Preview Release 751 * @param string $feed_url This is the URL you want to parse. 752 * @param string $cache_location This is where you want the cache to be stored. 753 * @param int $cache_duration This is the number of seconds that you want to store the cache file for. 754 */ 755 function SimplePie($feed_url = null, $cache_location = null, $cache_duration = null) 756 { 757 // Other objects, instances created here so we can set options on them 758 $this->sanitize =& new SimplePie_Sanitize; 759 760 // Set options if they're passed to the constructor 761 if ($cache_location !== null) 762 { 763 $this->set_cache_location($cache_location); 764 } 765 766 if ($cache_duration !== null) 767 { 768 $this->set_cache_duration($cache_duration); 769 } 770 771 // Only init the script if we're passed a feed URL 772 if ($feed_url !== null) 773 { 774 $this->set_feed_url($feed_url); 775 $this->init(); 776 } 777 } 778 779 /** 780 * Used for converting object to a string 781 */ 782 function __toString() 783 { 784 return md5(serialize($this->data)); 785 } 786 787 /** 788 * Remove items that link back to this before destroying this object 789 */ 790 function __destruct() 791 { 792 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode')) 793 { 794 if (!empty($this->data['items'])) 795 { 796 foreach ($this->data['items'] as $item) 797 { 798 $item->__destruct(); 799 } 800 unset($item, $this->data['items']); 801 } 802 if (!empty($this->data['ordered_items'])) 803 { 804 foreach ($this->data['ordered_items'] as $item) 805 { 806 $item->__destruct(); 807 } 808 unset($item, $this->data['ordered_items']); 809 } 810 } 811 } 812 813 /** 814 * Force the given data/URL to be treated as a feed no matter what it 815 * appears like 816 * 817 * @access public 818 * @since 1.1 819 * @param bool $enable Force the given data/URL to be treated as a feed 820 */ 821 function force_feed($enable = false) 822 { 823 $this->force_feed = (bool) $enable; 824 } 825 826 /** 827 * This is the URL of the feed you want to parse. 828 * 829 * This allows you to enter the URL of the feed you want to parse, or the 830 * website you want to try to use auto-discovery on. This takes priority 831 * over any set raw data. 832 * 833 * You can set multiple feeds to mash together by passing an array instead 834 * of a string for the $url. Remember that with each additional feed comes 835 * additional processing and resources. 836 * 837 * @access public 838 * @since 1.0 Preview Release 839 * @param mixed $url This is the URL (or array of URLs) that you want to parse. 840 * @see SimplePie::set_raw_data() 841 */ 842 function set_feed_url($url) 843 { 844 if (is_array($url)) 845 { 846 $this->multifeed_url = array(); 847 foreach ($url as $value) 848 { 849 $this->multifeed_url[] = SimplePie_Misc::fix_protocol($value, 1); 850 } 851 } 852 else 853 { 854 $this->feed_url = SimplePie_Misc::fix_protocol($url, 1); 855 } 856 } 857 858 /** 859 * Provides an instance of SimplePie_File to use as a feed 860 * 861 * @access public 862 * @param object &$file Instance of SimplePie_File (or subclass) 863 * @return bool True on success, false on failure 864 */ 865 function set_file(&$file) 866 { 867 if (is_a($file, 'SimplePie_File')) 868 { 869 $this->feed_url = $file->url; 870 $this->file =& $file; 871 return true; 872 } 873 return false; 874 } 875 876 /** 877 * Allows you to use a string of RSS/Atom data instead of a remote feed. 878 * 879 * If you have a feed available as a string in PHP, you can tell SimplePie 880 * to parse that data string instead of a remote feed. Any set feed URL 881 * takes precedence. 882 * 883 * @access public 884 * @since 1.0 Beta 3 885 * @param string $data RSS or Atom data as a string. 886 * @see SimplePie::set_feed_url() 887 */ 888 function set_raw_data($data) 889 { 890 $this->raw_data = $data; 891 } 892 893 /** 894 * Allows you to override the default timeout for fetching remote feeds. 895 * 896 * This allows you to change the maximum time the feed's server to respond 897 * and send the feed back. 898 * 899 * @access public 900 * @since 1.0 Beta 3 901 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed. 902 */ 903 function set_timeout($timeout = 10) 904 { 905 $this->timeout = (int) $timeout; 906 } 907 908 /** 909 * Forces SimplePie to use fsockopen() instead of the preferred cURL 910 * functions. 911 * 912 * @access public 913 * @since 1.0 Beta 3 914 * @param bool $enable Force fsockopen() to be used 915 */ 916 function force_fsockopen($enable = false) 917 { 918 $this->force_fsockopen = (bool) $enable; 919 } 920 921 /** 922 * Outputs the raw XML content of the feed, after it has gone through 923 * SimplePie's filters. 924 * 925 * Used only for debugging, this function will output the XML content as 926 * text/xml. When SimplePie reads in a feed, it does a bit of cleaning up 927 * before trying to parse it. Many parts of the feed are re-written in 928 * memory, and in the end, you have a parsable feed. XML dump shows you the 929 * actual XML that SimplePie tries to parse, which may or may not be very 930 * different from the original feed. 931 * 932 * @access public 933 * @since 1.0 Preview Release 934 * @param bool $enable Enable XML dump 935 */ 936 function enable_xml_dump($enable = false) 937 { 938 $this->xml_dump = (bool) $enable; 939 } 940 941 /** 942 * Enables/disables caching in SimplePie. 943 * 944 * This option allows you to disable caching all-together in SimplePie. 945 * However, disabling the cache can lead to longer load times. 946 * 947 * @access public 948 * @since 1.0 Preview Release 949 * @param bool $enable Enable caching 950 */ 951 function enable_cache($enable = true) 952 { 953 $this->cache = (bool) $enable; 954 } 955 956 /** 957 * Set the length of time (in seconds) that the contents of a feed 958 * will be cached. 959 * 960 * @access public 961 * @param int $seconds The feed content cache duration. 962 */ 963 function set_cache_duration($seconds = 3600) 964 { 965 $this->cache_duration = (int) $seconds; 966 } 967 968 /** 969 * Set the length of time (in seconds) that the autodiscovered feed 970 * URL will be cached. 971 * 972 * @access public 973 * @param int $seconds The autodiscovered feed URL cache duration. 974 */ 975 function set_autodiscovery_cache_duration($seconds = 604800) 976 { 977 $this->autodiscovery_cache_duration = (int) $seconds; 978 } 979 980 /** 981 * Set the file system location where the cached files should be stored. 982 * 983 * @access public 984 * @param string $location The file system location. 985 */ 986 function set_cache_location($location = './cache') 987 { 988 $this->cache_location = (string) $location; 989 } 990 991 /** 992 * Determines whether feed items should be sorted into reverse chronological order. 993 * 994 * @access public 995 * @param bool $enable Sort as reverse chronological order. 996 */ 997 function enable_order_by_date($enable = true) 998 { 999 $this->order_by_date = (bool) $enable; 1000 } 1001 1002 /** 1003 * Allows you to override the character encoding reported by the feed. 1004 * 1005 * @access public 1006 * @param string $encoding Character encoding. 1007 */ 1008 function set_input_encoding($encoding = false) 1009 { 1010 if ($encoding) 1011 { 1012 $this->input_encoding = (string) $encoding; 1013 } 1014 else 1015 { 1016 $this->input_encoding = false; 1017 } 1018 } 1019 1020 /** 1021 * Set how much feed autodiscovery to do 1022 * 1023 * @access public 1024 * @see SIMPLEPIE_LOCATOR_NONE 1025 * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY 1026 * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION 1027 * @see SIMPLEPIE_LOCATOR_LOCAL_BODY 1028 * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION 1029 * @see SIMPLEPIE_LOCATOR_REMOTE_BODY 1030 * @see SIMPLEPIE_LOCATOR_ALL 1031 * @param int $level Feed Autodiscovery Level (level can be a 1032 * combination of the above constants, see bitwise OR operator) 1033 */ 1034 function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL) 1035 { 1036 $this->autodiscovery = (int) $level; 1037 } 1038 1039 /** 1040 * Allows you to change which class SimplePie uses for caching. 1041 * Useful when you are overloading or extending SimplePie's default classes. 1042 * 1043 * @access public 1044 * @param string $class Name of custom class. 1045 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1046 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1047 */ 1048 function set_cache_class($class = 'SimplePie_Cache') 1049 { 1050 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Cache')) 1051 { 1052 $this->cache_class = $class; 1053 return true; 1054 } 1055 return false; 1056 } 1057 1058 /** 1059 * Allows you to change which class SimplePie uses for auto-discovery. 1060 * Useful when you are overloading or extending SimplePie's default classes. 1061 * 1062 * @access public 1063 * @param string $class Name of custom class. 1064 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1065 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1066 */ 1067 function set_locator_class($class = 'SimplePie_Locator') 1068 { 1069 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Locator')) 1070 { 1071 $this->locator_class = $class; 1072 return true; 1073 } 1074 return false; 1075 } 1076 1077 /** 1078 * Allows you to change which class SimplePie uses for XML parsing. 1079 * Useful when you are overloading or extending SimplePie's default classes. 1080 * 1081 * @access public 1082 * @param string $class Name of custom class. 1083 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1084 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1085 */ 1086 function set_parser_class($class = 'SimplePie_Parser') 1087 { 1088 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Parser')) 1089 { 1090 $this->parser_class = $class; 1091 return true; 1092 } 1093 return false; 1094 } 1095 1096 /** 1097 * Allows you to change which class SimplePie uses for remote file fetching. 1098 * Useful when you are overloading or extending SimplePie's default classes. 1099 * 1100 * @access public 1101 * @param string $class Name of custom class. 1102 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1103 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1104 */ 1105 function set_file_class($class = 'SimplePie_File') 1106 { 1107 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_File')) 1108 { 1109 $this->file_class = $class; 1110 return true; 1111 } 1112 return false; 1113 } 1114 1115 /** 1116 * Allows you to change which class SimplePie uses for data sanitization. 1117 * Useful when you are overloading or extending SimplePie's default classes. 1118 * 1119 * @access public 1120 * @param string $class Name of custom class. 1121 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1122 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1123 */ 1124 function set_sanitize_class($class = 'SimplePie_Sanitize') 1125 { 1126 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Sanitize')) 1127 { 1128 $this->sanitize = new $class(); 1129 return true; 1130 } 1131 return false; 1132 } 1133 1134 /** 1135 * Allows you to change which class SimplePie uses for handling feed items. 1136 * Useful when you are overloading or extending SimplePie's default classes. 1137 * 1138 * @access public 1139 * @param string $class Name of custom class. 1140 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1141 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1142 */ 1143 function set_item_class($class = 'SimplePie_Item') 1144 { 1145 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Item')) 1146 { 1147 $this->item_class = $class; 1148 return true; 1149 } 1150 return false; 1151 } 1152 1153 /** 1154 * Allows you to change which class SimplePie uses for handling author data. 1155 * Useful when you are overloading or extending SimplePie's default classes. 1156 * 1157 * @access public 1158 * @param string $class Name of custom class. 1159 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1160 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1161 */ 1162 function set_author_class($class = 'SimplePie_Author') 1163 { 1164 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Author')) 1165 { 1166 $this->author_class = $class; 1167 return true; 1168 } 1169 return false; 1170 } 1171 1172 /** 1173 * Allows you to change which class SimplePie uses for handling category data. 1174 * Useful when you are overloading or extending SimplePie's default classes. 1175 * 1176 * @access public 1177 * @param string $class Name of custom class. 1178 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1179 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1180 */ 1181 function set_category_class($class = 'SimplePie_Category') 1182 { 1183 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Category')) 1184 { 1185 $this->category_class = $class; 1186 return true; 1187 } 1188 return false; 1189 } 1190 1191 /** 1192 * Allows you to change which class SimplePie uses for feed enclosures. 1193 * Useful when you are overloading or extending SimplePie's default classes. 1194 * 1195 * @access public 1196 * @param string $class Name of custom class. 1197 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1198 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1199 */ 1200 function set_enclosure_class($class = 'SimplePie_Enclosure') 1201 { 1202 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Enclosure')) 1203 { 1204 $this->enclosure_class = $class; 1205 return true; 1206 } 1207 return false; 1208 } 1209 1210 /** 1211 * Allows you to change which class SimplePie uses for <media:text> captions 1212 * Useful when you are overloading or extending SimplePie's default classes. 1213 * 1214 * @access public 1215 * @param string $class Name of custom class. 1216 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1217 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1218 */ 1219 function set_caption_class($class = 'SimplePie_Caption') 1220 { 1221 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Caption')) 1222 { 1223 $this->caption_class = $class; 1224 return true; 1225 } 1226 return false; 1227 } 1228 1229 /** 1230 * Allows you to change which class SimplePie uses for <media:copyright> 1231 * Useful when you are overloading or extending SimplePie's default classes. 1232 * 1233 * @access public 1234 * @param string $class Name of custom class. 1235 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1236 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1237 */ 1238 function set_copyright_class($class = 'SimplePie_Copyright') 1239 { 1240 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Copyright')) 1241 { 1242 $this->copyright_class = $class; 1243 return true; 1244 } 1245 return false; 1246 } 1247 1248 /** 1249 * Allows you to change which class SimplePie uses for <media:credit> 1250 * Useful when you are overloading or extending SimplePie's default classes. 1251 * 1252 * @access public 1253 * @param string $class Name of custom class. 1254 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1255 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1256 */ 1257 function set_credit_class($class = 'SimplePie_Credit') 1258 { 1259 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Credit')) 1260 { 1261 $this->credit_class = $class; 1262 return true; 1263 } 1264 return false; 1265 } 1266 1267 /** 1268 * Allows you to change which class SimplePie uses for <media:rating> 1269 * Useful when you are overloading or extending SimplePie's default classes. 1270 * 1271 * @access public 1272 * @param string $class Name of custom class. 1273 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1274 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1275 */ 1276 function set_rating_class($class = 'SimplePie_Rating') 1277 { 1278 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Rating')) 1279 { 1280 $this->rating_class = $class; 1281 return true; 1282 } 1283 return false; 1284 } 1285 1286 /** 1287 * Allows you to change which class SimplePie uses for <media:restriction> 1288 * Useful when you are overloading or extending SimplePie's default classes. 1289 * 1290 * @access public 1291 * @param string $class Name of custom class. 1292 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1293 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1294 */ 1295 function set_restriction_class($class = 'SimplePie_Restriction') 1296 { 1297 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Restriction')) 1298 { 1299 $this->restriction_class = $class; 1300 return true; 1301 } 1302 return false; 1303 } 1304 1305 /** 1306 * Allows you to change which class SimplePie uses for content-type sniffing. 1307 * Useful when you are overloading or extending SimplePie's default classes. 1308 * 1309 * @access public 1310 * @param string $class Name of custom class. 1311 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1312 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1313 */ 1314 function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer') 1315 { 1316 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Content_Type_Sniffer')) 1317 { 1318 $this->content_type_sniffer_class = $class; 1319 return true; 1320 } 1321 return false; 1322 } 1323 1324 /** 1325 * Allows you to change which class SimplePie uses item sources. 1326 * Useful when you are overloading or extending SimplePie's default classes. 1327 * 1328 * @access public 1329 * @param string $class Name of custom class. 1330 * @link http://php.net/manual/en/keyword.extends.php PHP4 extends documentation 1331 * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation 1332 */ 1333 function set_source_class($class = 'SimplePie_Source') 1334 { 1335 if (SimplePie_Misc::is_subclass_of($class, 'SimplePie_Source')) 1336 { 1337 $this->source_class = $class; 1338 return true; 1339 } 1340 return false; 1341 } 1342 1343 /** 1344 * Allows you to override the default user agent string. 1345 * 1346 * @access public 1347 * @param string $ua New user agent string. 1348 */ 1349 function set_useragent($ua = SIMPLEPIE_USERAGENT) 1350 { 1351 $this->useragent = (string) $ua; 1352 } 1353 1354 /** 1355 * Set callback function to create cache filename with 1356 * 1357 * @access public 1358 * @param mixed $function Callback function 1359 */ 1360 function set_cache_name_function($function = 'md5') 1361 { 1362 if (is_callable($function)) 1363 { 1364 $this->cache_name_function = $function; 1365 } 1366 } 1367 1368 /** 1369 * Set javascript query string parameter 1370 * 1371 * @access public 1372 * @param mixed $get Javascript query string parameter 1373 */ 1374 function set_javascript($get = 'js') 1375 { 1376 if ($get) 1377 { 1378 $this->javascript = (string) $get; 1379 } 1380 else 1381 { 1382 $this->javascript = false; 1383 } 1384 } 1385 1386 /** 1387 * Set options to make SP as fast as possible. Forgoes a 1388 * substantial amount of data sanitization in favor of speed. 1389 * 1390 * @access public 1391 * @param bool $set Whether to set them or not 1392 */ 1393 function set_stupidly_fast($set = false) 1394 { 1395 if ($set) 1396 { 1397 $this->enable_order_by_date(false); 1398 $this->remove_div(false); 1399 $this->strip_comments(false); 1400 $this->strip_htmltags(false); 1401 $this->strip_attributes(false); 1402 $this->set_image_handler(false); 1403 } 1404 } 1405 1406 /** 1407 * Set maximum number of feeds to check with autodiscovery 1408 * 1409 * @access public 1410 * @param int $max Maximum number of feeds to check 1411 */ 1412 function set_max_checked_feeds($max = 10) 1413 { 1414 $this->max_checked_feeds = (int) $max; 1415 } 1416 1417 function remove_div($enable = true) 1418 { 1419 $this->sanitize->remove_div($enable); 1420 } 1421 1422 function strip_htmltags($tags = '', $encode = null) 1423 { 1424 if ($tags === '') 1425 { 1426 $tags = $this->strip_htmltags; 1427 } 1428 $this->sanitize->strip_htmltags($tags); 1429 if ($encode !== null) 1430 { 1431 $this->sanitize->encode_instead_of_strip($tags); 1432 } 1433 } 1434 1435 function encode_instead_of_strip($enable = true) 1436 { 1437 $this->sanitize->encode_instead_of_strip($enable); 1438 } 1439 1440 function strip_attributes($attribs = '') 1441 { 1442 if ($attribs === '') 1443 { 1444 $attribs = $this->strip_attributes; 1445 } 1446 $this->sanitize->strip_attributes($attribs); 1447 } 1448 1449 function set_output_encoding($encoding = 'UTF-8') 1450 { 1451 $this->sanitize->set_output_encoding($encoding); 1452 } 1453 1454 function strip_comments($strip = false) 1455 { 1456 $this->sanitize->strip_comments($strip); 1457 } 1458 1459 /** 1460 * Set element/attribute key/value pairs of HTML attributes 1461 * containing URLs that need to be resolved relative to the feed 1462 * 1463 * @access public 1464 * @since 1.0 1465 * @param array $element_attribute Element/attribute key/value pairs 1466 */ 1467 function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite')) 1468 { 1469 $this->sanitize->set_url_replacements($element_attribute); 1470 } 1471 1472 /** 1473 * Set the handler to enable the display of cached favicons. 1474 * 1475 * @access public 1476 * @param str $page Web-accessible path to the handler_favicon.php file. 1477 * @param str $qs The query string that the value should be passed to. 1478 */ 1479 function set_favicon_handler($page = false, $qs = 'i') 1480 { 1481 if ($page !== false) 1482 { 1483 $this->favicon_handler = $page . '?' . $qs . '='; 1484 } 1485 else 1486 { 1487 $this->favicon_handler = ''; 1488 } 1489 } 1490 1491 /** 1492 * Set the handler to enable the display of cached images. 1493 * 1494 * @access public 1495 * @param str $page Web-accessible path to the handler_image.php file. 1496 * @param str $qs The query string that the value should be passed to. 1497 */ 1498 function set_image_handler($page = false, $qs = 'i') 1499 { 1500 if ($page !== false) 1501 { 1502 $this->sanitize->set_image_handler($page . '?' . $qs . '='); 1503 } 1504 else 1505 { 1506 $this->image_handler = ''; 1507 } 1508 } 1509 1510 /** 1511 * Set the limit for items returned per-feed with multifeeds. 1512 * 1513 * @access public 1514 * @param integer $limit The maximum number of items to return. 1515 */ 1516 function set_item_limit($limit = 0) 1517 { 1518 $this->item_limit = (int) $limit; 1519 } 1520 1521 function init() 1522 { 1523 // Check absolute bare minimum requirements. 1524 if ((function_exists('version_compare') && version_compare(PHP_VERSION, '4.3.0', '<')) || !extension_loaded('xml') || !extension_loaded('pcre')) 1525 { 1526 return false; 1527 } 1528 // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader. 1529 elseif (!extension_loaded('xmlreader')) 1530 { 1531 static $xml_is_sane = null; 1532 if ($xml_is_sane === null) 1533 { 1534 $parser_check = xml_parser_create(); 1535 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values); 1536 xml_parser_free($parser_check); 1537 $xml_is_sane = isset($values[0]['value']); 1538 } 1539 if (!$xml_is_sane) 1540 { 1541 return false; 1542 } 1543 } 1544 1545 if (isset($_GET[$this->javascript])) 1546 { 1547 SimplePie_Misc::output_javascript(); 1548 exit; 1549 } 1550 1551 // Pass whatever was set with config options over to the sanitizer. 1552 $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->cache_class); 1553 $this->sanitize->pass_file_data($this->file_class, $this->timeout, $this->useragent, $this->force_fsockopen); 1554 1555 if ($this->feed_url !== null || $this->raw_data !== null) 1556 { 1557 $this->error = null; 1558 $this->data = array(); 1559 $this->multifeed_objects = array(); 1560 $cache = false; 1561 1562 if ($this->feed_url !== null) 1563 { 1564 $parsed_feed_url = SimplePie_Misc::parse_url($this->feed_url); 1565 // Decide whether to enable caching 1566 if ($this->cache && $parsed_feed_url['scheme'] !== '') 1567 { 1568 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $this->feed_url), 'spc'); 1569 } 1570 // If it's enabled and we don't want an XML dump, use the cache 1571 if ($cache && !$this->xml_dump) 1572 { 1573 // Load the Cache 1574 $this->data = $cache->load(); 1575 if (!empty($this->data)) 1576 { 1577 // If the cache is for an outdated build of SimplePie 1578 if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD) 1579 { 1580 $cache->unlink(); 1581 $this->data = array(); 1582 } 1583 // If we've hit a collision just rerun it with caching disabled 1584 elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url) 1585 { 1586 $cache = false; 1587 $this->data = array(); 1588 } 1589 // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL. 1590 elseif (isset($this->data['feed_url'])) 1591 { 1592 // If the autodiscovery cache is still valid use it. 1593 if ($cache->mtime() + $this->autodiscovery_cache_duration > time()) 1594 { 1595 // Do not need to do feed autodiscovery yet. 1596 if ($this->data['feed_url'] === $this->data['url']) 1597 { 1598 $cache->unlink(); 1599 $this->data = array(); 1600 } 1601 else 1602 { 1603 $this->set_feed_url($this->data['feed_url']); 1604 return $this->init(); 1605 } 1606 } 1607 } 1608 // Check if the cache has been updated 1609 elseif ($cache->mtime() + $this->cache_duration < time()) 1610 { 1611 // If we have last-modified and/or etag set 1612 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) 1613 { 1614 $headers = array(); 1615 if (isset($this->data['headers']['last-modified'])) 1616 { 1617 $headers['if-modified-since'] = $this->data['headers']['last-modified']; 1618 } 1619 if (isset($this->data['headers']['etag'])) 1620 { 1621 $headers['if-none-match'] = '"' . $this->data['headers']['etag'] . '"'; 1622 } 1623 $file =& new $this->file_class($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen); 1624 if ($file->success) 1625 { 1626 if ($file->status_code === 304) 1627 { 1628 $cache->touch(); 1629 return true; 1630 } 1631 else 1632 { 1633 $headers = $file->headers; 1634 } 1635 } 1636 else 1637 { 1638 unset($file); 1639 } 1640 } 1641 } 1642 // If the cache is still valid, just return true 1643 else 1644 { 1645 return true; 1646 } 1647 } 1648 // If the cache is empty, delete it 1649 else 1650 { 1651 $cache->unlink(); 1652 $this->data = array(); 1653 } 1654 } 1655 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it. 1656 if (!isset($file)) 1657 { 1658 if (is_a($this->file, 'SimplePie_File') && $this->file->url === $this->feed_url) 1659 { 1660 $file =& $this->file; 1661 } 1662 else 1663 { 1664 $file =& new $this->file_class($this->feed_url, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen); 1665 } 1666 } 1667 // If the file connection has an error, set SimplePie::error to that and quit 1668 if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) 1669 { 1670 $this->error = $file->error; 1671 if (!empty($this->data)) 1672 { 1673 return true; 1674 } 1675 else 1676 { 1677 return false; 1678 } 1679 } 1680 1681 if (!$this->force_feed) 1682 { 1683 // Check if the supplied URL is a feed, if it isn't, look for it. 1684 $locate =& new $this->locator_class($file, $this->timeout, $this->useragent, $this->file_class, $this->max_checked_feeds, $this->content_type_sniffer_class); 1685 if (!$locate->is_feed($file)) 1686 { 1687 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched 1688 unset($file); 1689 if ($file = $locate->find($this->autodiscovery, $this->all_discovered_feeds)) 1690 { 1691 if ($cache) 1692 { 1693 $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD); 1694 if (!$cache->save($this)) 1695 { 1696 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); 1697 } 1698 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'); 1699 } 1700 $this->feed_url = $file->url; 1701 } 1702 else 1703 { 1704 $this->error = "A feed could not be found at $this->feed_url. A feed with an invalid mime type may fall victim to this error, or " . SIMPLEPIE_NAME . " was unable to auto-discover it.. Use force_feed() if you are certain this URL is a real feed."; 1705 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1706 return false; 1707 } 1708 } 1709 $locate = null; 1710 } 1711 1712 $headers = $file->headers; 1713 $data = $file->body; 1714 $sniffer =& new $this->content_type_sniffer_class($file); 1715 $sniffed = $sniffer->get_type(); 1716 } 1717 else 1718 { 1719 $data = $this->raw_data; 1720 } 1721 1722 // Set up array of possible encodings 1723 $encodings = array(); 1724 1725 // First check to see if input has been overridden. 1726 if ($this->input_encoding !== false) 1727 { 1728 $encodings[] = $this->input_encoding; 1729 } 1730 1731 $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); 1732 $text_types = array('text/xml', 'text/xml-external-parsed-entity'); 1733 1734 // RFC 3023 (only applies to sniffed content) 1735 if (isset($sniffed)) 1736 { 1737 if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml') 1738 { 1739 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1740 { 1741 $encodings[] = strtoupper($charset[1]); 1742 } 1743 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); 1744 $encodings[] = 'UTF-8'; 1745 } 1746 elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml') 1747 { 1748 if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) 1749 { 1750 $encodings[] = $charset[1]; 1751 } 1752 $encodings[] = 'US-ASCII'; 1753 } 1754 // Text MIME-type default 1755 elseif (substr($sniffed, 0, 5) === 'text/') 1756 { 1757 $encodings[] = 'US-ASCII'; 1758 } 1759 } 1760 1761 // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1 1762 $encodings = array_merge($encodings, SimplePie_Misc::xml_encoding($data)); 1763 $encodings[] = 'UTF-8'; 1764 $encodings[] = 'ISO-8859-1'; 1765 1766 // There's no point in trying an encoding twice 1767 $encodings = array_unique($encodings); 1768 1769 // If we want the XML, just output that with the most likely encoding and quit 1770 if ($this->xml_dump) 1771 { 1772 header('Content-type: text/xml; charset=' . $encodings[0]); 1773 echo $data; 1774 exit; 1775 } 1776 1777 // Loop through each possible encoding, till we return something, or run out of possibilities 1778 foreach ($encodings as $encoding) 1779 { 1780 // Change the encoding to UTF-8 (as we always use UTF-8 internally) 1781 if ($utf8_data = SimplePie_Misc::change_encoding($data, $encoding, 'UTF-8')) 1782 { 1783 // Create new parser 1784 $parser =& new $this->parser_class(); 1785 1786 // If it's parsed fine 1787 if ($parser->parse($utf8_data, 'UTF-8')) 1788 { 1789 $this->data = $parser->get_data(); 1790 if ($this->get_type() & ~SIMPLEPIE_TYPE_NONE) 1791 { 1792 if (isset($headers)) 1793 { 1794 $this->data['headers'] = $headers; 1795 } 1796 $this->data['build'] = SIMPLEPIE_BUILD; 1797 1798 // Cache the file if caching is enabled 1799 if ($cache && !$cache->save($this)) 1800 { 1801 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); 1802 } 1803 return true; 1804 } 1805 else 1806 { 1807 $this->error = "A feed could not be found at $this->feed_url. This does not appear to be a valid RSS or Atom feed."; 1808 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1809 return false; 1810 } 1811 } 1812 } 1813 } 1814 if (isset($parser)) 1815 { 1816 // We have an error, just set SimplePie_Misc::error to it and quit 1817 $this->error = sprintf('This XML document is invalid, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column()); 1818 } 1819 else 1820 { 1821 $this->error = 'The data could not be converted to UTF-8. You MUST have either the iconv or mbstring extension installed. Upgrading to PHP 5.x (which includes iconv) is highly recommended.'; 1822 } 1823 SimplePie_Misc::error($this->error, E_USER_NOTICE, __FILE__, __LINE__); 1824 return false; 1825 } 1826 elseif (!empty($this->multifeed_url)) 1827 { 1828 $i = 0; 1829 $success = 0; 1830 $this->multifeed_objects = array(); 1831 foreach ($this->multifeed_url as $url) 1832 { 1833 if (SIMPLEPIE_PHP5) 1834 { 1835 // This keyword needs to defy coding standards for PHP4 compatibility 1836 $this->multifeed_objects[$i] = clone($this); 1837 } 1838 else 1839 { 1840 $this->multifeed_objects[$i] = $this; 1841 } 1842 $this->multifeed_objects[$i]->set_feed_url($url); 1843 $success |= $this->multifeed_objects[$i]->init(); 1844 $i++; 1845 } 1846 return (bool) $success; 1847 } 1848 else 1849 { 1850 return false; 1851 } 1852 } 1853 1854 /** 1855 * Return the error message for the occured error 1856 * 1857 * @access public 1858 * @return string Error message 1859 */ 1860 function error() 1861 { 1862 return $this->error; 1863 } 1864 1865 function get_encoding() 1866 { 1867 return $this->sanitize->output_encoding; 1868 } 1869 1870 function handle_content_type($mime = 'text/html') 1871 { 1872 if (!headers_sent()) 1873 { 1874 $header = "Content-type: $mime;"; 1875 if ($this->get_encoding()) 1876 { 1877 $header .= ' charset=' . $this->get_encoding(); 1878 } 1879 else 1880 { 1881 $header .= ' charset=UTF-8'; 1882 } 1883 header($header); 1884 } 1885 } 1886 1887 function get_type() 1888 { 1889 if (!isset($this->data['type'])) 1890 { 1891 $this->data['type'] = SIMPLEPIE_TYPE_ALL; 1892 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'])) 1893 { 1894 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10; 1895 } 1896 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'])) 1897 { 1898 $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03; 1899 } 1900 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'])) 1901 { 1902 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel']) 1903 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image']) 1904 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']) 1905 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput'])) 1906 { 1907 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10; 1908 } 1909 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel']) 1910 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image']) 1911 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']) 1912 || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput'])) 1913 { 1914 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090; 1915 } 1916 } 1917 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'])) 1918 { 1919 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL; 1920 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) 1921 { 1922 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version'])) 1923 { 1924 case '0.91': 1925 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091; 1926 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) 1927 { 1928 switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data'])) 1929 { 1930 case '0': 1931 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE; 1932 break; 1933 1934 case '24': 1935 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND; 1936 break; 1937 } 1938 } 1939 break; 1940 1941 case '0.92': 1942 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092; 1943 break; 1944 1945 case '0.93': 1946 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093; 1947 break; 1948 1949 case '0.94': 1950 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094; 1951 break; 1952 1953 case '2.0': 1954 $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20; 1955 break; 1956 } 1957 } 1958 } 1959 else 1960 { 1961 $this->data['type'] = SIMPLEPIE_TYPE_NONE; 1962 } 1963 } 1964 return $this->data['type']; 1965 } 1966 1967 /** 1968 * Returns the URL for the favicon of the feed's website. 1969 * 1970 * @todo Cache atom:icon 1971 * @access public 1972 * @since 1.0 1973 */ 1974 function get_favicon() 1975 { 1976 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) 1977 { 1978 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 1979 } 1980 elseif (($url = $this->get_link()) !== null && preg_match('/^http(s)?:\/\//i', $url)) 1981 { 1982 $favicon = SimplePie_Misc::absolutize_url('/favicon.ico', $url); 1983 1984 if ($this->cache && $this->favicon_handler) 1985 { 1986 $favicon_filename = call_user_func($this->cache_name_function, $favicon); 1987 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $favicon_filename, 'spi'); 1988 1989 if ($cache->load()) 1990 { 1991 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); 1992 } 1993 else 1994 { 1995 $file =& new $this->file_class($favicon, $this->timeout / 10, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); 1996 1997 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)) && strlen($file->body) > 0) 1998 { 1999 $sniffer =& new $this->content_type_sniffer_class($file); 2000 if (substr($sniffer->get_type(), 0, 6) === 'image/') 2001 { 2002 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) 2003 { 2004 return $this->sanitize($this->favicon_handler . $favicon_filename, SIMPLEPIE_CONSTRUCT_IRI); 2005 } 2006 else 2007 { 2008 trigger_error("$cache->name is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); 2009 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); 2010 } 2011 } 2012 // not an image 2013 else 2014 { 2015 return false; 2016 } 2017 } 2018 } 2019 } 2020 else 2021 { 2022 return $this->sanitize($favicon, SIMPLEPIE_CONSTRUCT_IRI); 2023 } 2024 } 2025 return false; 2026 } 2027 2028 /** 2029 * @todo If we have a perm redirect we should return the new URL 2030 * @todo When we make the above change, let's support <itunes:new-feed-url> as well 2031 * @todo Also, |atom:link|@rel=self 2032 */ 2033 function subscribe_url() 2034 { 2035 if ($this->feed_url !== null) 2036 { 2037 return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI); 2038 } 2039 else 2040 { 2041 return null; 2042 } 2043 } 2044 2045 function subscribe_feed() 2046 { 2047 if ($this->feed_url !== null) 2048 { 2049 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); 2050 } 2051 else 2052 { 2053 return null; 2054 } 2055 } 2056 2057 function subscribe_outlook() 2058 { 2059 if ($this->feed_url !== null) 2060 { 2061 return $this->sanitize('outlook' . SimplePie_Misc::fix_protocol($this->feed_url, 2), SIMPLEPIE_CONSTRUCT_IRI); 2062 } 2063 else 2064 { 2065 return null; 2066 } 2067 } 2068 2069 function subscribe_podcast() 2070 { 2071 if ($this->feed_url !== null) 2072 { 2073 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 3), SIMPLEPIE_CONSTRUCT_IRI); 2074 } 2075 else 2076 { 2077 return null; 2078 } 2079 } 2080 2081 function subscribe_itunes() 2082 { 2083 if ($this->feed_url !== null) 2084 { 2085 return $this->sanitize(SimplePie_Misc::fix_protocol($this->feed_url, 4), SIMPLEPIE_CONSTRUCT_IRI); 2086 } 2087 else 2088 { 2089 return null; 2090 } 2091 } 2092 2093 /** 2094 * Creates the subscribe_* methods' return data 2095 * 2096 * @access private 2097 * @param string $feed_url String to prefix to the feed URL 2098 * @param string $site_url String to prefix to the site URL (and 2099 * suffix to the feed URL) 2100 * @return mixed URL if feed exists, false otherwise 2101 */ 2102 function subscribe_service($feed_url, $site_url = null) 2103 { 2104 if ($this->subscribe_url()) 2105 { 2106 $return = $feed_url . rawurlencode($this->feed_url); 2107 if ($site_url !== null && $this->get_link() !== null) 2108 { 2109 $return .= $site_url . rawurlencode($this->get_link()); 2110 } 2111 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI); 2112 } 2113 else 2114 { 2115 return null; 2116 } 2117 } 2118 2119 function subscribe_aol() 2120 { 2121 return $this->subscribe_service('http://feeds.my.aol.com/add.jsp?url='); 2122 } 2123 2124 function subscribe_bloglines() 2125 { 2126 return $this->subscribe_service('http://www.bloglines.com/sub/'); 2127 } 2128 2129 function subscribe_eskobo() 2130 { 2131 return $this->subscribe_service('http://www.eskobo.com/?AddToMyPage='); 2132 } 2133 2134 function subscribe_feedfeeds() 2135 { 2136 return $this->subscribe_service('http://www.feedfeeds.com/add?feed='); 2137 } 2138 2139 function subscribe_feedster() 2140 { 2141 return $this->subscribe_service('http://www.feedster.com/myfeedster.php?action=addrss&confirm=no&rssurl='); 2142 } 2143 2144 function subscribe_google() 2145 { 2146 return $this->subscribe_service('http://fusion.google.com/add?feedurl='); 2147 } 2148 2149 function subscribe_gritwire() 2150 { 2151 return $this->subscribe_service('http://my.gritwire.com/feeds/addExternalFeed.aspx?FeedUrl='); 2152 } 2153 2154 function subscribe_msn() 2155 { 2156 return $this->subscribe_service('http://my.msn.com/addtomymsn.armx?id=rss&ut=', '&ru='); 2157 } 2158 2159 function subscribe_netvibes() 2160 { 2161 return $this->subscribe_service('http://www.netvibes.com/subscribe.php?url='); 2162 } 2163 2164 function subscribe_newsburst() 2165 { 2166 return $this->subscribe_service('http://www.newsburst.com/Source/?add='); 2167 } 2168 2169 function subscribe_newsgator() 2170 { 2171 return $this->subscribe_service('http://www.newsgator.com/ngs/subscriber/subext.aspx?url='); 2172 } 2173 2174 function subscribe_odeo() 2175 { 2176 return $this->subscribe_service('http://www.odeo.com/listen/subscribe?feed='); 2177 } 2178 2179 function subscribe_podnova() 2180 { 2181 return $this->subscribe_service('http://www.podnova.com/index_your_podcasts.srf?action=add&url='); 2182 } 2183 2184 function subscribe_rojo() 2185 { 2186 return $this->subscribe_service('http://www.rojo.com/add-subscription?resource='); 2187 } 2188 2189 function subscribe_yahoo() 2190 { 2191 return $this->subscribe_service('http://add.my.yahoo.com/rss?url='); 2192 } 2193 2194 function get_feed_tags($namespace, $tag) 2195 { 2196 $type = $this->get_type(); 2197 if ($type & SIMPLEPIE_TYPE_ATOM_10) 2198 { 2199 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag])) 2200 { 2201 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]; 2202 } 2203 } 2204 if ($type & SIMPLEPIE_TYPE_ATOM_03) 2205 { 2206 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag])) 2207 { 2208 return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]; 2209 } 2210 } 2211 if ($type & SIMPLEPIE_TYPE_RSS_RDF) 2212 { 2213 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag])) 2214 { 2215 return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]; 2216 } 2217 } 2218 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) 2219 { 2220 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag])) 2221 { 2222 return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]; 2223 } 2224 } 2225 return null; 2226 } 2227 2228 function get_channel_tags($namespace, $tag) 2229 { 2230 $type = $this->get_type(); 2231 if ($type & SIMPLEPIE_TYPE_ATOM_ALL) 2232 { 2233 if ($return = $this->get_feed_tags($namespace, $tag)) 2234 { 2235 return $return; 2236 } 2237 } 2238 if ($type & SIMPLEPIE_TYPE_RSS_10) 2239 { 2240 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel')) 2241 { 2242 if (isset($channel[0]['child'][$namespace][$tag])) 2243 { 2244 return $channel[0]['child'][$namespace][$tag]; 2245 } 2246 } 2247 } 2248 if ($type & SIMPLEPIE_TYPE_RSS_090) 2249 { 2250 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel')) 2251 { 2252 if (isset($channel[0]['child'][$namespace][$tag])) 2253 { 2254 return $channel[0]['child'][$namespace][$tag]; 2255 } 2256 } 2257 } 2258 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) 2259 { 2260 if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel')) 2261 { 2262 if (isset($channel[0]['child'][$namespace][$tag])) 2263 { 2264 return $channel[0]['child'][$namespace][$tag]; 2265 } 2266 } 2267 } 2268 return null; 2269 } 2270 2271 function get_image_tags($namespace, $tag) 2272 { 2273 $type = $this->get_type(); 2274 if ($type & SIMPLEPIE_TYPE_RSS_10) 2275 { 2276 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image')) 2277 { 2278 if (isset($image[0]['child'][$namespace][$tag])) 2279 { 2280 return $image[0]['child'][$namespace][$tag]; 2281 } 2282 } 2283 } 2284 if ($type & SIMPLEPIE_TYPE_RSS_090) 2285 { 2286 if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image')) 2287 { 2288 if (isset($image[0]['child'][$namespace][$tag])) 2289 { 2290 return $image[0]['child'][$namespace][$tag]; 2291 } 2292 } 2293 } 2294 if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION) 2295 { 2296 if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image')) 2297 { 2298 if (isset($image[0]['child'][$namespace][$tag])) 2299 { 2300 return $image[0]['child'][$namespace][$tag]; 2301 } 2302 } 2303 } 2304 return null; 2305 } 2306 2307 function get_base($element = array()) 2308 { 2309 if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base'])) 2310 { 2311 return $element['xml_base']; 2312 } 2313 elseif ($this->get_link() !== null) 2314 { 2315 return $this->get_link(); 2316 } 2317 else 2318 { 2319 return $this->subscribe_url(); 2320 } 2321 } 2322 2323 function sanitize($data, $type, $base = '') 2324 { 2325 return $this->sanitize->sanitize($data, $type, $base); 2326 } 2327 2328 function get_title() 2329 { 2330 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) 2331 { 2332 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2333 } 2334 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) 2335 { 2336 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2337 } 2338 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 2339 { 2340 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2341 } 2342 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 2343 { 2344 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2345 } 2346 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 2347 { 2348 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2349 } 2350 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 2351 { 2352 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2353 } 2354 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 2355 { 2356 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2357 } 2358 else 2359 { 2360 return null; 2361 } 2362 } 2363 2364 function get_category($key = 0) 2365 { 2366 $categories = $this->get_categories(); 2367 if (isset($categories[$key])) 2368 { 2369 return $categories[$key]; 2370 } 2371 else 2372 { 2373 return null; 2374 } 2375 } 2376 2377 function get_categories() 2378 { 2379 $categories = array(); 2380 2381 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) 2382 { 2383 $term = null; 2384 $scheme = null; 2385 $label = null; 2386 if (isset($category['attribs']['']['term'])) 2387 { 2388 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); 2389 } 2390 if (isset($category['attribs']['']['scheme'])) 2391 { 2392 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 2393 } 2394 if (isset($category['attribs']['']['label'])) 2395 { 2396 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 2397 } 2398 $categories[] =& new $this->category_class($term, $scheme, $label); 2399 } 2400 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) 2401 { 2402 // This is really the label, but keep this as the term also for BC. 2403 // Label will also work on retrieving because that falls back to term. 2404 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2405 if (isset($category['attribs']['']['domain'])) 2406 { 2407 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); 2408 } 2409 else 2410 { 2411 $scheme = null; 2412 } 2413 $categories[] =& new $this->category_class($term, $scheme, null); 2414 } 2415 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) 2416 { 2417 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2418 } 2419 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) 2420 { 2421 $categories[] =& new $this->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2422 } 2423 2424 if (!empty($categories)) 2425 { 2426 return SimplePie_Misc::array_unique($categories); 2427 } 2428 else 2429 { 2430 return null; 2431 } 2432 } 2433 2434 function get_author($key = 0) 2435 { 2436 $authors = $this->get_authors(); 2437 if (isset($authors[$key])) 2438 { 2439 return $authors[$key]; 2440 } 2441 else 2442 { 2443 return null; 2444 } 2445 } 2446 2447 function get_authors() 2448 { 2449 $authors = array(); 2450 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) 2451 { 2452 $name = null; 2453 $uri = null; 2454 $email = null; 2455 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 2456 { 2457 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2458 } 2459 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 2460 { 2461 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); 2462 } 2463 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 2464 { 2465 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2466 } 2467 if ($name !== null || $email !== null || $uri !== null) 2468 { 2469 $authors[] =& new $this->author_class($name, $uri, $email); 2470 } 2471 } 2472 if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) 2473 { 2474 $name = null; 2475 $url = null; 2476 $email = null; 2477 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 2478 { 2479 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2480 } 2481 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 2482 { 2483 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); 2484 } 2485 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 2486 { 2487 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2488 } 2489 if ($name !== null || $email !== null || $url !== null) 2490 { 2491 $authors[] =& new $this->author_class($name, $url, $email); 2492 } 2493 } 2494 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) 2495 { 2496 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2497 } 2498 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) 2499 { 2500 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2501 } 2502 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) 2503 { 2504 $authors[] =& new $this->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 2505 } 2506 2507 if (!empty($authors)) 2508 { 2509 return SimplePie_Misc::array_unique($authors); 2510 } 2511 else 2512 { 2513 return null; 2514 } 2515 } 2516 2517 function get_contributor($key = 0) 2518 { 2519 $contributors = $this->get_contributors(); 2520 if (isset($contributors[$key])) 2521 { 2522 return $contributors[$key]; 2523 } 2524 else 2525 { 2526 return null; 2527 } 2528 } 2529 2530 function get_contributors() 2531 { 2532 $contributors = array(); 2533 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) 2534 { 2535 $name = null; 2536 $uri = null; 2537 $email = null; 2538 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 2539 { 2540 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2541 } 2542 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 2543 { 2544 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); 2545 } 2546 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 2547 { 2548 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2549 } 2550 if ($name !== null || $email !== null || $uri !== null) 2551 { 2552 $contributors[] =& new $this->author_class($name, $uri, $email); 2553 } 2554 } 2555 foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) 2556 { 2557 $name = null; 2558 $url = null; 2559 $email = null; 2560 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 2561 { 2562 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2563 } 2564 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 2565 { 2566 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); 2567 } 2568 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 2569 { 2570 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2571 } 2572 if ($name !== null || $email !== null || $url !== null) 2573 { 2574 $contributors[] =& new $this->author_class($name, $url, $email); 2575 } 2576 } 2577 2578 if (!empty($contributors)) 2579 { 2580 return SimplePie_Misc::array_unique($contributors); 2581 } 2582 else 2583 { 2584 return null; 2585 } 2586 } 2587 2588 function get_link($key = 0, $rel = 'alternate') 2589 { 2590 $links = $this->get_links($rel); 2591 if (isset($links[$key])) 2592 { 2593 return $links[$key]; 2594 } 2595 else 2596 { 2597 return null; 2598 } 2599 } 2600 2601 /** 2602 * Added for parity between the parent-level and the item/entry-level. 2603 */ 2604 function get_permalink() 2605 { 2606 return $this->get_link(0); 2607 } 2608 2609 function get_links($rel = 'alternate') 2610 { 2611 if (!isset($this->data['links'])) 2612 { 2613 $this->data['links'] = array(); 2614 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) 2615 { 2616 foreach ($links as $link) 2617 { 2618 if (isset($link['attribs']['']['href'])) 2619 { 2620 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 2621 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 2622 } 2623 } 2624 } 2625 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) 2626 { 2627 foreach ($links as $link) 2628 { 2629 if (isset($link['attribs']['']['href'])) 2630 { 2631 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 2632 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 2633 2634 } 2635 } 2636 } 2637 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 2638 { 2639 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 2640 } 2641 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 2642 { 2643 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 2644 } 2645 if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 2646 { 2647 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 2648 } 2649 2650 $keys = array_keys($this->data['links']); 2651 foreach ($keys as $key) 2652 { 2653 if (SimplePie_Misc::is_isegment_nz_nc($key)) 2654 { 2655 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) 2656 { 2657 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); 2658 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; 2659 } 2660 else 2661 { 2662 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; 2663 } 2664 } 2665 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) 2666 { 2667 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; 2668 } 2669 $this->data['links'][$key] = array_unique($this->data['links'][$key]); 2670 } 2671 } 2672 2673 if (isset($this->data['links'][$rel])) 2674 { 2675 return $this->data['links'][$rel]; 2676 } 2677 else 2678 { 2679 return null; 2680 } 2681 } 2682 2683 function get_all_discovered_feeds() 2684 { 2685 return $this->all_discovered_feeds; 2686 } 2687 2688 function get_description() 2689 { 2690 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) 2691 { 2692 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2693 } 2694 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) 2695 { 2696 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2697 } 2698 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) 2699 { 2700 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2701 } 2702 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) 2703 { 2704 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 2705 } 2706 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) 2707 { 2708 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 2709 } 2710 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) 2711 { 2712 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2713 } 2714 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) 2715 { 2716 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2717 } 2718 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) 2719 { 2720 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 2721 } 2722 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) 2723 { 2724 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 2725 } 2726 else 2727 { 2728 return null; 2729 } 2730 } 2731 2732 function get_copyright() 2733 { 2734 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) 2735 { 2736 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2737 } 2738 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) 2739 { 2740 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 2741 } 2742 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright')) 2743 { 2744 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2745 } 2746 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) 2747 { 2748 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2749 } 2750 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) 2751 { 2752 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2753 } 2754 else 2755 { 2756 return null; 2757 } 2758 } 2759 2760 function get_language() 2761 { 2762 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language')) 2763 { 2764 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2765 } 2766 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) 2767 { 2768 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2769 } 2770 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) 2771 { 2772 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2773 } 2774 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'])) 2775 { 2776 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 2777 } 2778 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'])) 2779 { 2780 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 2781 } 2782 elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'])) 2783 { 2784 return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 2785 } 2786 elseif (isset($this->data['headers']['content-language'])) 2787 { 2788 return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT); 2789 } 2790 else 2791 { 2792 return null; 2793 } 2794 } 2795 2796 function get_latitude() 2797 { 2798 2799 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) 2800 { 2801 return (float) $return[0]['data']; 2802 } 2803 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) 2804 { 2805 return (float) $match[1]; 2806 } 2807 else 2808 { 2809 return null; 2810 } 2811 } 2812 2813 function get_longitude() 2814 { 2815 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) 2816 { 2817 return (float) $return[0]['data']; 2818 } 2819 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) 2820 { 2821 return (float) $return[0]['data']; 2822 } 2823 elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) 2824 { 2825 return (float) $match[2]; 2826 } 2827 else 2828 { 2829 return null; 2830 } 2831 } 2832 2833 function get_image_title() 2834 { 2835 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 2836 { 2837 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2838 } 2839 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 2840 { 2841 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2842 } 2843 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 2844 { 2845 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2846 } 2847 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 2848 { 2849 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2850 } 2851 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 2852 { 2853 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 2854 } 2855 else 2856 { 2857 return null; 2858 } 2859 } 2860 2861 function get_image_url() 2862 { 2863 if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) 2864 { 2865 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); 2866 } 2867 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) 2868 { 2869 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2870 } 2871 elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) 2872 { 2873 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2874 } 2875 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url')) 2876 { 2877 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2878 } 2879 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url')) 2880 { 2881 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2882 } 2883 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) 2884 { 2885 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2886 } 2887 else 2888 { 2889 return null; 2890 } 2891 } 2892 2893 function get_image_link() 2894 { 2895 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 2896 { 2897 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2898 } 2899 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 2900 { 2901 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2902 } 2903 elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 2904 { 2905 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 2906 } 2907 else 2908 { 2909 return null; 2910 } 2911 } 2912 2913 function get_image_width() 2914 { 2915 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width')) 2916 { 2917 return round($return[0]['data']); 2918 } 2919 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) 2920 { 2921 return 88.0; 2922 } 2923 else 2924 { 2925 return null; 2926 } 2927 } 2928 2929 function get_image_height() 2930 { 2931 if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height')) 2932 { 2933 return round($return[0]['data']); 2934 } 2935 elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url')) 2936 { 2937 return 31.0; 2938 } 2939 else 2940 { 2941 return null; 2942 } 2943 } 2944 2945 function get_item_quantity($max = 0) 2946 { 2947 $max = (int) $max; 2948 $qty = count($this->get_items()); 2949 if ($max === 0) 2950 { 2951 return $qty; 2952 } 2953 else 2954 { 2955 return ($qty > $max) ? $max : $qty; 2956 } 2957 } 2958 2959 function get_item($key = 0) 2960 { 2961 $items = $this->get_items(); 2962 if (isset($items[$key])) 2963 { 2964 return $items[$key]; 2965 } 2966 else 2967 { 2968 return null; 2969 } 2970 } 2971 2972 function get_items($start = 0, $end = 0) 2973 { 2974 if (!isset($this->data['items'])) 2975 { 2976 if (!empty($this->multifeed_objects)) 2977 { 2978 $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit); 2979 } 2980 else 2981 { 2982 $this->data['items'] = array(); 2983 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry')) 2984 { 2985 $keys = array_keys($items); 2986 foreach ($keys as $key) 2987 { 2988 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 2989 } 2990 } 2991 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry')) 2992 { 2993 $keys = array_keys($items); 2994 foreach ($keys as $key) 2995 { 2996 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 2997 } 2998 } 2999 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item')) 3000 { 3001 $keys = array_keys($items); 3002 foreach ($keys as $key) 3003 { 3004 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 3005 } 3006 } 3007 if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item')) 3008 { 3009 $keys = array_keys($items); 3010 foreach ($keys as $key) 3011 { 3012 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 3013 } 3014 } 3015 if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item')) 3016 { 3017 $keys = array_keys($items); 3018 foreach ($keys as $key) 3019 { 3020 $this->data['items'][] =& new $this->item_class($this, $items[$key]); 3021 } 3022 } 3023 } 3024 } 3025 3026 if (!empty($this->data['items'])) 3027 { 3028 // If we want to order it by date, check if all items have a date, and then sort it 3029 if ($this->order_by_date && empty($this->multifeed_objects)) 3030 { 3031 if (!isset($this->data['ordered_items'])) 3032 { 3033 $do_sort = true; 3034 foreach ($this->data['items'] as $item) 3035 { 3036 if (!$item->get_date('U')) 3037 { 3038 $do_sort = false; 3039 break; 3040 } 3041 } 3042 $item = null; 3043 $this->data['ordered_items'] = $this->data['items']; 3044 if ($do_sort) 3045 { 3046 usort($this->data['ordered_items'], array(&$this, 'sort_items')); 3047 } 3048 } 3049 $items = $this->data['ordered_items']; 3050 } 3051 else 3052 { 3053 $items = $this->data['items']; 3054 } 3055 3056 // Slice the data as desired 3057 if ($end === 0) 3058 { 3059 return array_slice($items, $start); 3060 } 3061 else 3062 { 3063 return array_slice($items, $start, $end); 3064 } 3065 } 3066 else 3067 { 3068 return array(); 3069 } 3070 } 3071 3072 /** 3073 * @static 3074 */ 3075 function sort_items($a, $b) 3076 { 3077 return $a->get_date('U') <= $b->get_date('U'); 3078 } 3079 3080 /** 3081 * @static 3082 */ 3083 function merge_items($urls, $start = 0, $end = 0, $limit = 0) 3084 { 3085 if (is_array($urls) && sizeof($urls) > 0) 3086 { 3087 $items = array(); 3088 foreach ($urls as $arg) 3089 { 3090 if (is_a($arg, 'SimplePie')) 3091 { 3092 $items = array_merge($items, $arg->get_items(0, $limit)); 3093 } 3094 else 3095 { 3096 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING); 3097 } 3098 } 3099 3100 $do_sort = true; 3101 foreach ($items as $item) 3102 { 3103 if (!$item->get_date('U')) 3104 { 3105 $do_sort = false; 3106 break; 3107 } 3108 } 3109 $item = null; 3110 if ($do_sort) 3111 { 3112 usort($items, array('SimplePie', 'sort_items')); 3113 } 3114 3115 if ($end === 0) 3116 { 3117 return array_slice($items, $start); 3118 } 3119 else 3120 { 3121 return array_slice($items, $start, $end); 3122 } 3123 } 3124 else 3125 { 3126 trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING); 3127 return array(); 3128 } 3129 } 3130 } 3131 3132 class SimplePie_Item 3133 { 3134 var $feed; 3135 var $data = array(); 3136 3137 function SimplePie_Item($feed, $data) 3138 { 3139 $this->feed = $feed; 3140 $this->data = $data; 3141 } 3142 3143 function __toString() 3144 { 3145 return md5(serialize($this->data)); 3146 } 3147 3148 /** 3149 * Remove items that link back to this before destroying this object 3150 */ 3151 function __destruct() 3152 { 3153 if ((version_compare(PHP_VERSION, '5.3', '<') || !gc_enabled()) && !ini_get('zend.ze1_compatibility_mode')) 3154 { 3155 unset($this->feed); 3156 } 3157 } 3158 3159 function get_item_tags($namespace, $tag) 3160 { 3161 if (isset($this->data['child'][$namespace][$tag])) 3162 { 3163 return $this->data['child'][$namespace][$tag]; 3164 } 3165 else 3166 { 3167 return null; 3168 } 3169 } 3170 3171 function get_base($element = array()) 3172 { 3173 return $this->feed->get_base($element); 3174 } 3175 3176 function sanitize($data, $type, $base = '') 3177 { 3178 return $this->feed->sanitize($data, $type, $base); 3179 } 3180 3181 function get_feed() 3182 { 3183 return $this->feed; 3184 } 3185 3186 function get_id($hash = false) 3187 { 3188 if (!$hash) 3189 { 3190 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id')) 3191 { 3192 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3193 } 3194 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id')) 3195 { 3196 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3197 } 3198 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid')) 3199 { 3200 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3201 } 3202 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier')) 3203 { 3204 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3205 } 3206 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier')) 3207 { 3208 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3209 } 3210 elseif (($return = $this->get_permalink()) !== null) 3211 { 3212 return $return; 3213 } 3214 elseif (($return = $this->get_title()) !== null) 3215 { 3216 return $return; 3217 } 3218 } 3219 if ($this->get_permalink() !== null || $this->get_title() !== null) 3220 { 3221 return md5($this->get_permalink() . $this->get_title()); 3222 } 3223 else 3224 { 3225 return md5(serialize($this->data)); 3226 } 3227 } 3228 3229 function get_title() 3230 { 3231 if (!isset($this->data['title'])) 3232 { 3233 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) 3234 { 3235 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3236 } 3237 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) 3238 { 3239 $this->data['title'] = $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3240 } 3241 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 3242 { 3243 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3244 } 3245 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 3246 { 3247 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3248 } 3249 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 3250 { 3251 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3252 } 3253 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 3254 { 3255 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3256 } 3257 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 3258 { 3259 $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3260 } 3261 else 3262 { 3263 $this->data['title'] = null; 3264 } 3265 } 3266 return $this->data['title']; 3267 } 3268 3269 function get_description($description_only = false) 3270 { 3271 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary')) 3272 { 3273 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3274 } 3275 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary')) 3276 { 3277 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3278 } 3279 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) 3280 { 3281 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 3282 } 3283 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) 3284 { 3285 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 3286 } 3287 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) 3288 { 3289 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3290 } 3291 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) 3292 { 3293 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3294 } 3295 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) 3296 { 3297 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 3298 } 3299 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) 3300 { 3301 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3302 } 3303 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) 3304 { 3305 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML); 3306 } 3307 3308 elseif (!$description_only) 3309 { 3310 return $this->get_content(true); 3311 } 3312 else 3313 { 3314 return null; 3315 } 3316 } 3317 3318 function get_content($content_only = false) 3319 { 3320 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content')) 3321 { 3322 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_content_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3323 } 3324 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content')) 3325 { 3326 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3327 } 3328 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded')) 3329 { 3330 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 3331 } 3332 elseif (!$content_only) 3333 { 3334 return $this->get_description(true); 3335 } 3336 else 3337 { 3338 return null; 3339 } 3340 } 3341 3342 function get_category($key = 0) 3343 { 3344 $categories = $this->get_categories(); 3345 if (isset($categories[$key])) 3346 { 3347 return $categories[$key]; 3348 } 3349 else 3350 { 3351 return null; 3352 } 3353 } 3354 3355 function get_categories() 3356 { 3357 $categories = array(); 3358 3359 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) 3360 { 3361 $term = null; 3362 $scheme = null; 3363 $label = null; 3364 if (isset($category['attribs']['']['term'])) 3365 { 3366 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); 3367 } 3368 if (isset($category['attribs']['']['scheme'])) 3369 { 3370 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3371 } 3372 if (isset($category['attribs']['']['label'])) 3373 { 3374 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 3375 } 3376 $categories[] =& new $this->feed->category_class($term, $scheme, $label); 3377 } 3378 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) 3379 { 3380 // This is really the label, but keep this as the term also for BC. 3381 // Label will also work on retrieving because that falls back to term. 3382 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3383 if (isset($category['attribs']['']['domain'])) 3384 { 3385 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); 3386 } 3387 else 3388 { 3389 $scheme = null; 3390 } 3391 $categories[] =& new $this->feed->category_class($term, $scheme, null); 3392 } 3393 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) 3394 { 3395 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3396 } 3397 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) 3398 { 3399 $categories[] =& new $this->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3400 } 3401 3402 if (!empty($categories)) 3403 { 3404 return SimplePie_Misc::array_unique($categories); 3405 } 3406 else 3407 { 3408 return null; 3409 } 3410 } 3411 3412 function get_author($key = 0) 3413 { 3414 $authors = $this->get_authors(); 3415 if (isset($authors[$key])) 3416 { 3417 return $authors[$key]; 3418 } 3419 else 3420 { 3421 return null; 3422 } 3423 } 3424 3425 function get_contributor($key = 0) 3426 { 3427 $contributors = $this->get_contributors(); 3428 if (isset($contributors[$key])) 3429 { 3430 return $contributors[$key]; 3431 } 3432 else 3433 { 3434 return null; 3435 } 3436 } 3437 3438 function get_contributors() 3439 { 3440 $contributors = array(); 3441 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) 3442 { 3443 $name = null; 3444 $uri = null; 3445 $email = null; 3446 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 3447 { 3448 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3449 } 3450 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 3451 { 3452 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); 3453 } 3454 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 3455 { 3456 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3457 } 3458 if ($name !== null || $email !== null || $uri !== null) 3459 { 3460 $contributors[] =& new $this->feed->author_class($name, $uri, $email); 3461 } 3462 } 3463 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) 3464 { 3465 $name = null; 3466 $url = null; 3467 $email = null; 3468 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 3469 { 3470 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3471 } 3472 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 3473 { 3474 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); 3475 } 3476 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 3477 { 3478 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3479 } 3480 if ($name !== null || $email !== null || $url !== null) 3481 { 3482 $contributors[] =& new $this->feed->author_class($name, $url, $email); 3483 } 3484 } 3485 3486 if (!empty($contributors)) 3487 { 3488 return SimplePie_Misc::array_unique($contributors); 3489 } 3490 else 3491 { 3492 return null; 3493 } 3494 } 3495 3496 function get_authors() 3497 { 3498 $authors = array(); 3499 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) 3500 { 3501 $name = null; 3502 $uri = null; 3503 $email = null; 3504 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 3505 { 3506 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3507 } 3508 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 3509 { 3510 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); 3511 } 3512 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 3513 { 3514 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3515 } 3516 if ($name !== null || $email !== null || $uri !== null) 3517 { 3518 $authors[] =& new $this->feed->author_class($name, $uri, $email); 3519 } 3520 } 3521 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) 3522 { 3523 $name = null; 3524 $url = null; 3525 $email = null; 3526 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 3527 { 3528 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3529 } 3530 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 3531 { 3532 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); 3533 } 3534 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 3535 { 3536 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3537 } 3538 if ($name !== null || $email !== null || $url !== null) 3539 { 3540 $authors[] =& new $this->feed->author_class($name, $url, $email); 3541 } 3542 } 3543 if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author')) 3544 { 3545 $authors[] =& new $this->feed->author_class(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 3546 } 3547 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) 3548 { 3549 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3550 } 3551 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) 3552 { 3553 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3554 } 3555 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) 3556 { 3557 $authors[] =& new $this->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 3558 } 3559 3560 if (!empty($authors)) 3561 { 3562 return SimplePie_Misc::array_unique($authors); 3563 } 3564 elseif (($source = $this->get_source()) && ($authors = $source->get_authors())) 3565 { 3566 return $authors; 3567 } 3568 elseif ($authors = $this->feed->get_authors()) 3569 { 3570 return $authors; 3571 } 3572 else 3573 { 3574 return null; 3575 } 3576 } 3577 3578 function get_copyright() 3579 { 3580 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) 3581 { 3582 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 3583 } 3584 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) 3585 { 3586 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3587 } 3588 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) 3589 { 3590 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3591 } 3592 else 3593 { 3594 return null; 3595 } 3596 } 3597 3598 function get_date($date_format = 'j F Y, g:i a') 3599 { 3600 if (!isset($this->data['date'])) 3601 { 3602 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published')) 3603 { 3604 $this->data['date']['raw'] = $return[0]['data']; 3605 } 3606 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated')) 3607 { 3608 $this->data['date']['raw'] = $return[0]['data']; 3609 } 3610 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued')) 3611 { 3612 $this->data['date']['raw'] = $return[0]['data']; 3613 } 3614 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created')) 3615 { 3616 $this->data['date']['raw'] = $return[0]['data']; 3617 } 3618 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified')) 3619 { 3620 $this->data['date']['raw'] = $return[0]['data']; 3621 } 3622 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate')) 3623 { 3624 $this->data['date']['raw'] = $return[0]['data']; 3625 } 3626 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date')) 3627 { 3628 $this->data['date']['raw'] = $return[0]['data']; 3629 } 3630 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date')) 3631 { 3632 $this->data['date']['raw'] = $return[0]['data']; 3633 } 3634 3635 if (!empty($this->data['date']['raw'])) 3636 { 3637 $parser = SimplePie_Parse_Date::get(); 3638 $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']); 3639 } 3640 else 3641 { 3642 $this->data['date'] = null; 3643 } 3644 } 3645 if ($this->data['date']) 3646 { 3647 $date_format = (string) $date_format; 3648 switch ($date_format) 3649 { 3650 case '': 3651 return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT); 3652 3653 case 'U': 3654 return $this->data['date']['parsed']; 3655 3656 default: 3657 return date($date_format, $this->data['date']['parsed']); 3658 } 3659 } 3660 else 3661 { 3662 return null; 3663 } 3664 } 3665 3666 function get_local_date($date_format = '%c') 3667 { 3668 if (!$date_format) 3669 { 3670 return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT); 3671 } 3672 elseif (($date = $this->get_date('U')) !== null && $date !== false) 3673 { 3674 return strftime($date_format, $date); 3675 } 3676 else 3677 { 3678 return null; 3679 } 3680 } 3681 3682 function get_permalink() 3683 { 3684 $link = $this->get_link(); 3685 $enclosure = $this->get_enclosure(0); 3686 if ($link !== null) 3687 { 3688 return $link; 3689 } 3690 elseif ($enclosure !== null) 3691 { 3692 return $enclosure->get_link(); 3693 } 3694 else 3695 { 3696 return null; 3697 } 3698 } 3699 3700 function get_link($key = 0, $rel = 'alternate') 3701 { 3702 $links = $this->get_links($rel); 3703 if ($links[$key] !== null) 3704 { 3705 return $links[$key]; 3706 } 3707 else 3708 { 3709 return null; 3710 } 3711 } 3712 3713 function get_links($rel = 'alternate') 3714 { 3715 if (!isset($this->data['links'])) 3716 { 3717 $this->data['links'] = array(); 3718 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link) 3719 { 3720 if (isset($link['attribs']['']['href'])) 3721 { 3722 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 3723 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 3724 3725 } 3726 } 3727 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link) 3728 { 3729 if (isset($link['attribs']['']['href'])) 3730 { 3731 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 3732 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 3733 } 3734 } 3735 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 3736 { 3737 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3738 } 3739 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 3740 { 3741 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3742 } 3743 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 3744 { 3745 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3746 } 3747 if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid')) 3748 { 3749 if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true') 3750 { 3751 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 3752 } 3753 } 3754 3755 $keys = array_keys($this->data['links']); 3756 foreach ($keys as $key) 3757 { 3758 if (SimplePie_Misc::is_isegment_nz_nc($key)) 3759 { 3760 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) 3761 { 3762 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); 3763 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; 3764 } 3765 else 3766 { 3767 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; 3768 } 3769 } 3770 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) 3771 { 3772 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; 3773 } 3774 $this->data['links'][$key] = array_unique($this->data['links'][$key]); 3775 } 3776 } 3777 if (isset($this->data['links'][$rel])) 3778 { 3779 return $this->data['links'][$rel]; 3780 } 3781 else 3782 { 3783 return null; 3784 } 3785 } 3786 3787 /** 3788 * @todo Add ability to prefer one type of content over another (in a media group). 3789 */ 3790 function get_enclosure($key = 0, $prefer = null) 3791 { 3792 $enclosures = $this->get_enclosures(); 3793 if (isset($enclosures[$key])) 3794 { 3795 return $enclosures[$key]; 3796 } 3797 else 3798 { 3799 return null; 3800 } 3801 } 3802 3803 /** 3804 * Grabs all available enclosures (podcasts, etc.) 3805 * 3806 * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS. 3807 * 3808 * At this point, we're pretty much assuming that all enclosures for an item are the same content. Anything else is too complicated to properly support. 3809 * 3810 * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4). 3811 * @todo If an element exists at a level, but it's value is empty, we should fall back to the value from the parent (if it exists). 3812 */ 3813 function get_enclosures() 3814 { 3815 if (!isset($this->data['enclosures'])) 3816 { 3817 $this->data['enclosures'] = array(); 3818 3819 // Elements 3820 $captions_parent = null; 3821 $categories_parent = null; 3822 $copyrights_parent = null; 3823 $credits_parent = null; 3824 $description_parent = null; 3825 $duration_parent = null; 3826 $hashes_parent = null; 3827 $keywords_parent = null; 3828 $player_parent = null; 3829 $ratings_parent = null; 3830 $restrictions_parent = null; 3831 $thumbnails_parent = null; 3832 $title_parent = null; 3833 3834 // Let's do the channel and item-level ones first, and just re-use them if we need to. 3835 $parent = $this->get_feed(); 3836 3837 // CAPTIONS 3838 if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) 3839 { 3840 foreach ($captions as $caption) 3841 { 3842 $caption_type = null; 3843 $caption_lang = null; 3844 $caption_startTime = null; 3845 $caption_endTime = null; 3846 $caption_text = null; 3847 if (isset($caption['attribs']['']['type'])) 3848 { 3849 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 3850 } 3851 if (isset($caption['attribs']['']['lang'])) 3852 { 3853 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 3854 } 3855 if (isset($caption['attribs']['']['start'])) 3856 { 3857 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 3858 } 3859 if (isset($caption['attribs']['']['end'])) 3860 { 3861 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 3862 } 3863 if (isset($caption['data'])) 3864 { 3865 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3866 } 3867 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 3868 } 3869 } 3870 elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text')) 3871 { 3872 foreach ($captions as $caption) 3873 { 3874 $caption_type = null; 3875 $caption_lang = null; 3876 $caption_startTime = null; 3877 $caption_endTime = null; 3878 $caption_text = null; 3879 if (isset($caption['attribs']['']['type'])) 3880 { 3881 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 3882 } 3883 if (isset($caption['attribs']['']['lang'])) 3884 { 3885 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 3886 } 3887 if (isset($caption['attribs']['']['start'])) 3888 { 3889 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 3890 } 3891 if (isset($caption['attribs']['']['end'])) 3892 { 3893 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 3894 } 3895 if (isset($caption['data'])) 3896 { 3897 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3898 } 3899 $captions_parent[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 3900 } 3901 } 3902 if (is_array($captions_parent)) 3903 { 3904 $captions_parent = array_values(SimplePie_Misc::array_unique($captions_parent)); 3905 } 3906 3907 // CATEGORIES 3908 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) 3909 { 3910 $term = null; 3911 $scheme = null; 3912 $label = null; 3913 if (isset($category['data'])) 3914 { 3915 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3916 } 3917 if (isset($category['attribs']['']['scheme'])) 3918 { 3919 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3920 } 3921 else 3922 { 3923 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 3924 } 3925 if (isset($category['attribs']['']['label'])) 3926 { 3927 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 3928 } 3929 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); 3930 } 3931 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category) 3932 { 3933 $term = null; 3934 $scheme = null; 3935 $label = null; 3936 if (isset($category['data'])) 3937 { 3938 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3939 } 3940 if (isset($category['attribs']['']['scheme'])) 3941 { 3942 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 3943 } 3944 else 3945 { 3946 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 3947 } 3948 if (isset($category['attribs']['']['label'])) 3949 { 3950 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 3951 } 3952 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); 3953 } 3954 foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category) 3955 { 3956 $term = null; 3957 $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd'; 3958 $label = null; 3959 if (isset($category['attribs']['']['text'])) 3960 { 3961 $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); 3962 } 3963 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); 3964 3965 if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'])) 3966 { 3967 foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory) 3968 { 3969 if (isset($subcategory['attribs']['']['text'])) 3970 { 3971 $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT); 3972 } 3973 $categories_parent[] =& new $this->feed->category_class($term, $scheme, $label); 3974 } 3975 } 3976 } 3977 if (is_array($categories_parent)) 3978 { 3979 $categories_parent = array_values(SimplePie_Misc::array_unique($categories_parent)); 3980 } 3981 3982 // COPYRIGHT 3983 if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) 3984 { 3985 $copyright_url = null; 3986 $copyright_label = null; 3987 if (isset($copyright[0]['attribs']['']['url'])) 3988 { 3989 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 3990 } 3991 if (isset($copyright[0]['data'])) 3992 { 3993 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 3994 } 3995 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label); 3996 } 3997 elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright')) 3998 { 3999 $copyright_url = null; 4000 $copyright_label = null; 4001 if (isset($copyright[0]['attribs']['']['url'])) 4002 { 4003 $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 4004 } 4005 if (isset($copyright[0]['data'])) 4006 { 4007 $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4008 } 4009 $copyrights_parent =& new $this->feed->copyright_class($copyright_url, $copyright_label); 4010 } 4011 4012 // CREDITS 4013 if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) 4014 { 4015 foreach ($credits as $credit) 4016 { 4017 $credit_role = null; 4018 $credit_scheme = null; 4019 $credit_name = null; 4020 if (isset($credit['attribs']['']['role'])) 4021 { 4022 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 4023 } 4024 if (isset($credit['attribs']['']['scheme'])) 4025 { 4026 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4027 } 4028 else 4029 { 4030 $credit_scheme = 'urn:ebu'; 4031 } 4032 if (isset($credit['data'])) 4033 { 4034 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4035 } 4036 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4037 } 4038 } 4039 elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit')) 4040 { 4041 foreach ($credits as $credit) 4042 { 4043 $credit_role = null; 4044 $credit_scheme = null; 4045 $credit_name = null; 4046 if (isset($credit['attribs']['']['role'])) 4047 { 4048 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 4049 } 4050 if (isset($credit['attribs']['']['scheme'])) 4051 { 4052 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4053 } 4054 else 4055 { 4056 $credit_scheme = 'urn:ebu'; 4057 } 4058 if (isset($credit['data'])) 4059 { 4060 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4061 } 4062 $credits_parent[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4063 } 4064 } 4065 if (is_array($credits_parent)) 4066 { 4067 $credits_parent = array_values(SimplePie_Misc::array_unique($credits_parent)); 4068 } 4069 4070 // DESCRIPTION 4071 if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) 4072 { 4073 if (isset($description_parent[0]['data'])) 4074 { 4075 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4076 } 4077 } 4078 elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description')) 4079 { 4080 if (isset($description_parent[0]['data'])) 4081 { 4082 $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4083 } 4084 } 4085 4086 // DURATION 4087 if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration')) 4088 { 4089 $seconds = null; 4090 $minutes = null; 4091 $hours = null; 4092 if (isset($duration_parent[0]['data'])) 4093 { 4094 $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4095 if (sizeof($temp) > 0) 4096 { 4097 $seconds = (int) array_pop($temp); 4098 } 4099 if (sizeof($temp) > 0) 4100 { 4101 $minutes = (int) array_pop($temp); 4102 $seconds += $minutes * 60; 4103 } 4104 if (sizeof($temp) > 0) 4105 { 4106 $hours = (int) array_pop($temp); 4107 $seconds += $hours * 3600; 4108 } 4109 unset($temp); 4110 $duration_parent = $seconds; 4111 } 4112 } 4113 4114 // HASHES 4115 if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) 4116 { 4117 foreach ($hashes_iterator as $hash) 4118 { 4119 $value = null; 4120 $algo = null; 4121 if (isset($hash['data'])) 4122 { 4123 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4124 } 4125 if (isset($hash['attribs']['']['algo'])) 4126 { 4127 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4128 } 4129 else 4130 { 4131 $algo = 'md5'; 4132 } 4133 $hashes_parent[] = $algo.':'.$value; 4134 } 4135 } 4136 elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash')) 4137 { 4138 foreach ($hashes_iterator as $hash) 4139 { 4140 $value = null; 4141 $algo = null; 4142 if (isset($hash['data'])) 4143 { 4144 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4145 } 4146 if (isset($hash['attribs']['']['algo'])) 4147 { 4148 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4149 } 4150 else 4151 { 4152 $algo = 'md5'; 4153 } 4154 $hashes_parent[] = $algo.':'.$value; 4155 } 4156 } 4157 if (is_array($hashes_parent)) 4158 { 4159 $hashes_parent = array_values(SimplePie_Misc::array_unique($hashes_parent)); 4160 } 4161 4162 // KEYWORDS 4163 if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) 4164 { 4165 if (isset($keywords[0]['data'])) 4166 { 4167 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4168 foreach ($temp as $word) 4169 { 4170 $keywords_parent[] = trim($word); 4171 } 4172 } 4173 unset($temp); 4174 } 4175 elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) 4176 { 4177 if (isset($keywords[0]['data'])) 4178 { 4179 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4180 foreach ($temp as $word) 4181 { 4182 $keywords_parent[] = trim($word); 4183 } 4184 } 4185 unset($temp); 4186 } 4187 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords')) 4188 { 4189 if (isset($keywords[0]['data'])) 4190 { 4191 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4192 foreach ($temp as $word) 4193 { 4194 $keywords_parent[] = trim($word); 4195 } 4196 } 4197 unset($temp); 4198 } 4199 elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords')) 4200 { 4201 if (isset($keywords[0]['data'])) 4202 { 4203 $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4204 foreach ($temp as $word) 4205 { 4206 $keywords_parent[] = trim($word); 4207 } 4208 } 4209 unset($temp); 4210 } 4211 if (is_array($keywords_parent)) 4212 { 4213 $keywords_parent = array_values(SimplePie_Misc::array_unique($keywords_parent)); 4214 } 4215 4216 // PLAYER 4217 if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player')) 4218 { 4219 if (isset($player_parent[0]['attribs']['']['url'])) 4220 { 4221 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4222 } 4223 } 4224 elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player')) 4225 { 4226 if (isset($player_parent[0]['attribs']['']['url'])) 4227 { 4228 $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4229 } 4230 } 4231 4232 // RATINGS 4233 if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating')) 4234 { 4235 foreach ($ratings as $rating) 4236 { 4237 $rating_scheme = null; 4238 $rating_value = null; 4239 if (isset($rating['attribs']['']['scheme'])) 4240 { 4241 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4242 } 4243 else 4244 { 4245 $rating_scheme = 'urn:simple'; 4246 } 4247 if (isset($rating['data'])) 4248 { 4249 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4250 } 4251 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4252 } 4253 } 4254 elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit')) 4255 { 4256 foreach ($ratings as $rating) 4257 { 4258 $rating_scheme = 'urn:itunes'; 4259 $rating_value = null; 4260 if (isset($rating['data'])) 4261 { 4262 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4263 } 4264 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4265 } 4266 } 4267 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating')) 4268 { 4269 foreach ($ratings as $rating) 4270 { 4271 $rating_scheme = null; 4272 $rating_value = null; 4273 if (isset($rating['attribs']['']['scheme'])) 4274 { 4275 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4276 } 4277 else 4278 { 4279 $rating_scheme = 'urn:simple'; 4280 } 4281 if (isset($rating['data'])) 4282 { 4283 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4284 } 4285 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4286 } 4287 } 4288 elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit')) 4289 { 4290 foreach ($ratings as $rating) 4291 { 4292 $rating_scheme = 'urn:itunes'; 4293 $rating_value = null; 4294 if (isset($rating['data'])) 4295 { 4296 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4297 } 4298 $ratings_parent[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4299 } 4300 } 4301 if (is_array($ratings_parent)) 4302 { 4303 $ratings_parent = array_values(SimplePie_Misc::array_unique($ratings_parent)); 4304 } 4305 4306 // RESTRICTIONS 4307 if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction')) 4308 { 4309 foreach ($restrictions as $restriction) 4310 { 4311 $restriction_relationship = null; 4312 $restriction_type = null; 4313 $restriction_value = null; 4314 if (isset($restriction['attribs']['']['relationship'])) 4315 { 4316 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 4317 } 4318 if (isset($restriction['attribs']['']['type'])) 4319 { 4320 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4321 } 4322 if (isset($restriction['data'])) 4323 { 4324 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4325 } 4326 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4327 } 4328 } 4329 elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block')) 4330 { 4331 foreach ($restrictions as $restriction) 4332 { 4333 $restriction_relationship = 'allow'; 4334 $restriction_type = null; 4335 $restriction_value = 'itunes'; 4336 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes') 4337 { 4338 $restriction_relationship = 'deny'; 4339 } 4340 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4341 } 4342 } 4343 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction')) 4344 { 4345 foreach ($restrictions as $restriction) 4346 { 4347 $restriction_relationship = null; 4348 $restriction_type = null; 4349 $restriction_value = null; 4350 if (isset($restriction['attribs']['']['relationship'])) 4351 { 4352 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 4353 } 4354 if (isset($restriction['attribs']['']['type'])) 4355 { 4356 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4357 } 4358 if (isset($restriction['data'])) 4359 { 4360 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4361 } 4362 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4363 } 4364 } 4365 elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block')) 4366 { 4367 foreach ($restrictions as $restriction) 4368 { 4369 $restriction_relationship = 'allow'; 4370 $restriction_type = null; 4371 $restriction_value = 'itunes'; 4372 if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes') 4373 { 4374 $restriction_relationship = 'deny'; 4375 } 4376 $restrictions_parent[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4377 } 4378 } 4379 if (is_array($restrictions_parent)) 4380 { 4381 $restrictions_parent = array_values(SimplePie_Misc::array_unique($restrictions_parent)); 4382 } 4383 4384 // THUMBNAILS 4385 if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail')) 4386 { 4387 foreach ($thumbnails as $thumbnail) 4388 { 4389 if (isset($thumbnail['attribs']['']['url'])) 4390 { 4391 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4392 } 4393 } 4394 } 4395 elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail')) 4396 { 4397 foreach ($thumbnails as $thumbnail) 4398 { 4399 if (isset($thumbnail['attribs']['']['url'])) 4400 { 4401 $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4402 } 4403 } 4404 } 4405 4406 // TITLES 4407 if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title')) 4408 { 4409 if (isset($title_parent[0]['data'])) 4410 { 4411 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4412 } 4413 } 4414 elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title')) 4415 { 4416 if (isset($title_parent[0]['data'])) 4417 { 4418 $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4419 } 4420 } 4421 4422 // Clear the memory 4423 unset($parent); 4424 4425 // Attributes 4426 $bitrate = null; 4427 $channels = null; 4428 $duration = null; 4429 $expression = null; 4430 $framerate = null; 4431 $height = null; 4432 $javascript = null; 4433 $lang = null; 4434 $length = null; 4435 $medium = null; 4436 $samplingrate = null; 4437 $type = null; 4438 $url = null; 4439 $width = null; 4440 4441 // Elements 4442 $captions = null; 4443 $categories = null; 4444 $copyrights = null; 4445 $credits = null; 4446 $description = null; 4447 $hashes = null; 4448 $keywords = null; 4449 $player = null; 4450 $ratings = null; 4451 $restrictions = null; 4452 $thumbnails = null; 4453 $title = null; 4454 4455 // If we have media:group tags, loop through them. 4456 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group) 4457 { 4458 if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'])) 4459 { 4460 // If we have media:content tags, loop through them. 4461 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content) 4462 { 4463 if (isset($content['attribs']['']['url'])) 4464 { 4465 // Attributes 4466 $bitrate = null; 4467 $channels = null; 4468 $duration = null; 4469 $expression = null; 4470 $framerate = null; 4471 $height = null; 4472 $javascript = null; 4473 $lang = null; 4474 $length = null; 4475 $medium = null; 4476 $samplingrate = null; 4477 $type = null; 4478 $url = null; 4479 $width = null; 4480 4481 // Elements 4482 $captions = null; 4483 $categories = null; 4484 $copyrights = null; 4485 $credits = null; 4486 $description = null; 4487 $hashes = null; 4488 $keywords = null; 4489 $player = null; 4490 $ratings = null; 4491 $restrictions = null; 4492 $thumbnails = null; 4493 $title = null; 4494 4495 // Start checking the attributes of media:content 4496 if (isset($content['attribs']['']['bitrate'])) 4497 { 4498 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT); 4499 } 4500 if (isset($content['attribs']['']['channels'])) 4501 { 4502 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT); 4503 } 4504 if (isset($content['attribs']['']['duration'])) 4505 { 4506 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT); 4507 } 4508 else 4509 { 4510 $duration = $duration_parent; 4511 } 4512 if (isset($content['attribs']['']['expression'])) 4513 { 4514 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT); 4515 } 4516 if (isset($content['attribs']['']['framerate'])) 4517 { 4518 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT); 4519 } 4520 if (isset($content['attribs']['']['height'])) 4521 { 4522 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT); 4523 } 4524 if (isset($content['attribs']['']['lang'])) 4525 { 4526 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 4527 } 4528 if (isset($content['attribs']['']['fileSize'])) 4529 { 4530 $length = ceil($content['attribs']['']['fileSize']); 4531 } 4532 if (isset($content['attribs']['']['medium'])) 4533 { 4534 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT); 4535 } 4536 if (isset($content['attribs']['']['samplingrate'])) 4537 { 4538 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT); 4539 } 4540 if (isset($content['attribs']['']['type'])) 4541 { 4542 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4543 } 4544 if (isset($content['attribs']['']['width'])) 4545 { 4546 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT); 4547 } 4548 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4549 4550 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel 4551 4552 // CAPTIONS 4553 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) 4554 { 4555 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) 4556 { 4557 $caption_type = null; 4558 $caption_lang = null; 4559 $caption_startTime = null; 4560 $caption_endTime = null; 4561 $caption_text = null; 4562 if (isset($caption['attribs']['']['type'])) 4563 { 4564 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4565 } 4566 if (isset($caption['attribs']['']['lang'])) 4567 { 4568 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 4569 } 4570 if (isset($caption['attribs']['']['start'])) 4571 { 4572 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 4573 } 4574 if (isset($caption['attribs']['']['end'])) 4575 { 4576 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 4577 } 4578 if (isset($caption['data'])) 4579 { 4580 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4581 } 4582 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 4583 } 4584 if (is_array($captions)) 4585 { 4586 $captions = array_values(SimplePie_Misc::array_unique($captions)); 4587 } 4588 } 4589 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) 4590 { 4591 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) 4592 { 4593 $caption_type = null; 4594 $caption_lang = null; 4595 $caption_startTime = null; 4596 $caption_endTime = null; 4597 $caption_text = null; 4598 if (isset($caption['attribs']['']['type'])) 4599 { 4600 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4601 } 4602 if (isset($caption['attribs']['']['lang'])) 4603 { 4604 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 4605 } 4606 if (isset($caption['attribs']['']['start'])) 4607 { 4608 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 4609 } 4610 if (isset($caption['attribs']['']['end'])) 4611 { 4612 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 4613 } 4614 if (isset($caption['data'])) 4615 { 4616 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4617 } 4618 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 4619 } 4620 if (is_array($captions)) 4621 { 4622 $captions = array_values(SimplePie_Misc::array_unique($captions)); 4623 } 4624 } 4625 else 4626 { 4627 $captions = $captions_parent; 4628 } 4629 4630 // CATEGORIES 4631 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) 4632 { 4633 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) 4634 { 4635 $term = null; 4636 $scheme = null; 4637 $label = null; 4638 if (isset($category['data'])) 4639 { 4640 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4641 } 4642 if (isset($category['attribs']['']['scheme'])) 4643 { 4644 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4645 } 4646 else 4647 { 4648 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 4649 } 4650 if (isset($category['attribs']['']['label'])) 4651 { 4652 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 4653 } 4654 $categories[] =& new $this->feed->category_class($term, $scheme, $label); 4655 } 4656 } 4657 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) 4658 { 4659 foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) 4660 { 4661 $term = null; 4662 $scheme = null; 4663 $label = null; 4664 if (isset($category['data'])) 4665 { 4666 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4667 } 4668 if (isset($category['attribs']['']['scheme'])) 4669 { 4670 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4671 } 4672 else 4673 { 4674 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 4675 } 4676 if (isset($category['attribs']['']['label'])) 4677 { 4678 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 4679 } 4680 $categories[] =& new $this->feed->category_class($term, $scheme, $label); 4681 } 4682 } 4683 if (is_array($categories) && is_array($categories_parent)) 4684 { 4685 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent))); 4686 } 4687 elseif (is_array($categories)) 4688 { 4689 $categories = array_values(SimplePie_Misc::array_unique($categories)); 4690 } 4691 elseif (is_array($categories_parent)) 4692 { 4693 $categories = array_values(SimplePie_Misc::array_unique($categories_parent)); 4694 } 4695 4696 // COPYRIGHTS 4697 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) 4698 { 4699 $copyright_url = null; 4700 $copyright_label = null; 4701 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) 4702 { 4703 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 4704 } 4705 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) 4706 { 4707 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4708 } 4709 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); 4710 } 4711 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) 4712 { 4713 $copyright_url = null; 4714 $copyright_label = null; 4715 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) 4716 { 4717 $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 4718 } 4719 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) 4720 { 4721 $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4722 } 4723 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); 4724 } 4725 else 4726 { 4727 $copyrights = $copyrights_parent; 4728 } 4729 4730 // CREDITS 4731 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) 4732 { 4733 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) 4734 { 4735 $credit_role = null; 4736 $credit_scheme = null; 4737 $credit_name = null; 4738 if (isset($credit['attribs']['']['role'])) 4739 { 4740 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 4741 } 4742 if (isset($credit['attribs']['']['scheme'])) 4743 { 4744 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4745 } 4746 else 4747 { 4748 $credit_scheme = 'urn:ebu'; 4749 } 4750 if (isset($credit['data'])) 4751 { 4752 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4753 } 4754 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4755 } 4756 if (is_array($credits)) 4757 { 4758 $credits = array_values(SimplePie_Misc::array_unique($credits)); 4759 } 4760 } 4761 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) 4762 { 4763 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) 4764 { 4765 $credit_role = null; 4766 $credit_scheme = null; 4767 $credit_name = null; 4768 if (isset($credit['attribs']['']['role'])) 4769 { 4770 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 4771 } 4772 if (isset($credit['attribs']['']['scheme'])) 4773 { 4774 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4775 } 4776 else 4777 { 4778 $credit_scheme = 'urn:ebu'; 4779 } 4780 if (isset($credit['data'])) 4781 { 4782 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4783 } 4784 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 4785 } 4786 if (is_array($credits)) 4787 { 4788 $credits = array_values(SimplePie_Misc::array_unique($credits)); 4789 } 4790 } 4791 else 4792 { 4793 $credits = $credits_parent; 4794 } 4795 4796 // DESCRIPTION 4797 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) 4798 { 4799 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4800 } 4801 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) 4802 { 4803 $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4804 } 4805 else 4806 { 4807 $description = $description_parent; 4808 } 4809 4810 // HASHES 4811 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) 4812 { 4813 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) 4814 { 4815 $value = null; 4816 $algo = null; 4817 if (isset($hash['data'])) 4818 { 4819 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4820 } 4821 if (isset($hash['attribs']['']['algo'])) 4822 { 4823 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4824 } 4825 else 4826 { 4827 $algo = 'md5'; 4828 } 4829 $hashes[] = $algo.':'.$value; 4830 } 4831 if (is_array($hashes)) 4832 { 4833 $hashes = array_values(SimplePie_Misc::array_unique($hashes)); 4834 } 4835 } 4836 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) 4837 { 4838 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) 4839 { 4840 $value = null; 4841 $algo = null; 4842 if (isset($hash['data'])) 4843 { 4844 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4845 } 4846 if (isset($hash['attribs']['']['algo'])) 4847 { 4848 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 4849 } 4850 else 4851 { 4852 $algo = 'md5'; 4853 } 4854 $hashes[] = $algo.':'.$value; 4855 } 4856 if (is_array($hashes)) 4857 { 4858 $hashes = array_values(SimplePie_Misc::array_unique($hashes)); 4859 } 4860 } 4861 else 4862 { 4863 $hashes = $hashes_parent; 4864 } 4865 4866 // KEYWORDS 4867 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) 4868 { 4869 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) 4870 { 4871 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4872 foreach ($temp as $word) 4873 { 4874 $keywords[] = trim($word); 4875 } 4876 unset($temp); 4877 } 4878 if (is_array($keywords)) 4879 { 4880 $keywords = array_values(SimplePie_Misc::array_unique($keywords)); 4881 } 4882 } 4883 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) 4884 { 4885 if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) 4886 { 4887 $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 4888 foreach ($temp as $word) 4889 { 4890 $keywords[] = trim($word); 4891 } 4892 unset($temp); 4893 } 4894 if (is_array($keywords)) 4895 { 4896 $keywords = array_values(SimplePie_Misc::array_unique($keywords)); 4897 } 4898 } 4899 else 4900 { 4901 $keywords = $keywords_parent; 4902 } 4903 4904 // PLAYER 4905 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) 4906 { 4907 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4908 } 4909 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) 4910 { 4911 $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 4912 } 4913 else 4914 { 4915 $player = $player_parent; 4916 } 4917 4918 // RATINGS 4919 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) 4920 { 4921 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) 4922 { 4923 $rating_scheme = null; 4924 $rating_value = null; 4925 if (isset($rating['attribs']['']['scheme'])) 4926 { 4927 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4928 } 4929 else 4930 { 4931 $rating_scheme = 'urn:simple'; 4932 } 4933 if (isset($rating['data'])) 4934 { 4935 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4936 } 4937 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4938 } 4939 if (is_array($ratings)) 4940 { 4941 $ratings = array_values(SimplePie_Misc::array_unique($ratings)); 4942 } 4943 } 4944 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) 4945 { 4946 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) 4947 { 4948 $rating_scheme = null; 4949 $rating_value = null; 4950 if (isset($rating['attribs']['']['scheme'])) 4951 { 4952 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 4953 } 4954 else 4955 { 4956 $rating_scheme = 'urn:simple'; 4957 } 4958 if (isset($rating['data'])) 4959 { 4960 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4961 } 4962 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 4963 } 4964 if (is_array($ratings)) 4965 { 4966 $ratings = array_values(SimplePie_Misc::array_unique($ratings)); 4967 } 4968 } 4969 else 4970 { 4971 $ratings = $ratings_parent; 4972 } 4973 4974 // RESTRICTIONS 4975 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) 4976 { 4977 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) 4978 { 4979 $restriction_relationship = null; 4980 $restriction_type = null; 4981 $restriction_value = null; 4982 if (isset($restriction['attribs']['']['relationship'])) 4983 { 4984 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 4985 } 4986 if (isset($restriction['attribs']['']['type'])) 4987 { 4988 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 4989 } 4990 if (isset($restriction['data'])) 4991 { 4992 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 4993 } 4994 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 4995 } 4996 if (is_array($restrictions)) 4997 { 4998 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); 4999 } 5000 } 5001 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) 5002 { 5003 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) 5004 { 5005 $restriction_relationship = null; 5006 $restriction_type = null; 5007 $restriction_value = null; 5008 if (isset($restriction['attribs']['']['relationship'])) 5009 { 5010 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 5011 } 5012 if (isset($restriction['attribs']['']['type'])) 5013 { 5014 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5015 } 5016 if (isset($restriction['data'])) 5017 { 5018 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5019 } 5020 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 5021 } 5022 if (is_array($restrictions)) 5023 { 5024 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); 5025 } 5026 } 5027 else 5028 { 5029 $restrictions = $restrictions_parent; 5030 } 5031 5032 // THUMBNAILS 5033 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) 5034 { 5035 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) 5036 { 5037 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5038 } 5039 if (is_array($thumbnails)) 5040 { 5041 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); 5042 } 5043 } 5044 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) 5045 { 5046 foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) 5047 { 5048 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5049 } 5050 if (is_array($thumbnails)) 5051 { 5052 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); 5053 } 5054 } 5055 else 5056 { 5057 $thumbnails = $thumbnails_parent; 5058 } 5059 5060 // TITLES 5061 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) 5062 { 5063 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5064 } 5065 elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) 5066 { 5067 $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5068 } 5069 else 5070 { 5071 $title = $title_parent; 5072 } 5073 5074 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width); 5075 } 5076 } 5077 } 5078 } 5079 5080 // If we have standalone media:content tags, loop through them. 5081 if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'])) 5082 { 5083 foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content) 5084 { 5085 if (isset($content['attribs']['']['url']) || isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) 5086 { 5087 // Attributes 5088 $bitrate = null; 5089 $channels = null; 5090 $duration = null; 5091 $expression = null; 5092 $framerate = null; 5093 $height = null; 5094 $javascript = null; 5095 $lang = null; 5096 $length = null; 5097 $medium = null; 5098 $samplingrate = null; 5099 $type = null; 5100 $url = null; 5101 $width = null; 5102 5103 // Elements 5104 $captions = null; 5105 $categories = null; 5106 $copyrights = null; 5107 $credits = null; 5108 $description = null; 5109 $hashes = null; 5110 $keywords = null; 5111 $player = null; 5112 $ratings = null; 5113 $restrictions = null; 5114 $thumbnails = null; 5115 $title = null; 5116 5117 // Start checking the attributes of media:content 5118 if (isset($content['attribs']['']['bitrate'])) 5119 { 5120 $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT); 5121 } 5122 if (isset($content['attribs']['']['channels'])) 5123 { 5124 $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT); 5125 } 5126 if (isset($content['attribs']['']['duration'])) 5127 { 5128 $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT); 5129 } 5130 else 5131 { 5132 $duration = $duration_parent; 5133 } 5134 if (isset($content['attribs']['']['expression'])) 5135 { 5136 $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT); 5137 } 5138 if (isset($content['attribs']['']['framerate'])) 5139 { 5140 $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT); 5141 } 5142 if (isset($content['attribs']['']['height'])) 5143 { 5144 $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT); 5145 } 5146 if (isset($content['attribs']['']['lang'])) 5147 { 5148 $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 5149 } 5150 if (isset($content['attribs']['']['fileSize'])) 5151 { 5152 $length = ceil($content['attribs']['']['fileSize']); 5153 } 5154 if (isset($content['attribs']['']['medium'])) 5155 { 5156 $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT); 5157 } 5158 if (isset($content['attribs']['']['samplingrate'])) 5159 { 5160 $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT); 5161 } 5162 if (isset($content['attribs']['']['type'])) 5163 { 5164 $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5165 } 5166 if (isset($content['attribs']['']['width'])) 5167 { 5168 $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT); 5169 } 5170 if (isset($content['attribs']['']['url'])) 5171 { 5172 $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5173 } 5174 // Checking the other optional media: elements. Priority: media:content, media:group, item, channel 5175 5176 // CAPTIONS 5177 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'])) 5178 { 5179 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption) 5180 { 5181 $caption_type = null; 5182 $caption_lang = null; 5183 $caption_startTime = null; 5184 $caption_endTime = null; 5185 $caption_text = null; 5186 if (isset($caption['attribs']['']['type'])) 5187 { 5188 $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5189 } 5190 if (isset($caption['attribs']['']['lang'])) 5191 { 5192 $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT); 5193 } 5194 if (isset($caption['attribs']['']['start'])) 5195 { 5196 $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT); 5197 } 5198 if (isset($caption['attribs']['']['end'])) 5199 { 5200 $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT); 5201 } 5202 if (isset($caption['data'])) 5203 { 5204 $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5205 } 5206 $captions[] =& new $this->feed->caption_class($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text); 5207 } 5208 if (is_array($captions)) 5209 { 5210 $captions = array_values(SimplePie_Misc::array_unique($captions)); 5211 } 5212 } 5213 else 5214 { 5215 $captions = $captions_parent; 5216 } 5217 5218 // CATEGORIES 5219 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'])) 5220 { 5221 foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category) 5222 { 5223 $term = null; 5224 $scheme = null; 5225 $label = null; 5226 if (isset($category['data'])) 5227 { 5228 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5229 } 5230 if (isset($category['attribs']['']['scheme'])) 5231 { 5232 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 5233 } 5234 else 5235 { 5236 $scheme = 'http://search.yahoo.com/mrss/category_schema'; 5237 } 5238 if (isset($category['attribs']['']['label'])) 5239 { 5240 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 5241 } 5242 $categories[] =& new $this->feed->category_class($term, $scheme, $label); 5243 } 5244 } 5245 if (is_array($categories) && is_array($categories_parent)) 5246 { 5247 $categories = array_values(SimplePie_Misc::array_unique(array_merge($categories, $categories_parent))); 5248 } 5249 elseif (is_array($categories)) 5250 { 5251 $categories = array_values(SimplePie_Misc::array_unique($categories)); 5252 } 5253 elseif (is_array($categories_parent)) 5254 { 5255 $categories = array_values(SimplePie_Misc::array_unique($categories_parent)); 5256 } 5257 else 5258 { 5259 $categories = null; 5260 } 5261 5262 // COPYRIGHTS 5263 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'])) 5264 { 5265 $copyright_url = null; 5266 $copyright_label = null; 5267 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'])) 5268 { 5269 $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT); 5270 } 5271 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'])) 5272 { 5273 $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5274 } 5275 $copyrights =& new $this->feed->copyright_class($copyright_url, $copyright_label); 5276 } 5277 else 5278 { 5279 $copyrights = $copyrights_parent; 5280 } 5281 5282 // CREDITS 5283 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'])) 5284 { 5285 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit) 5286 { 5287 $credit_role = null; 5288 $credit_scheme = null; 5289 $credit_name = null; 5290 if (isset($credit['attribs']['']['role'])) 5291 { 5292 $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT); 5293 } 5294 if (isset($credit['attribs']['']['scheme'])) 5295 { 5296 $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 5297 } 5298 else 5299 { 5300 $credit_scheme = 'urn:ebu'; 5301 } 5302 if (isset($credit['data'])) 5303 { 5304 $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5305 } 5306 $credits[] =& new $this->feed->credit_class($credit_role, $credit_scheme, $credit_name); 5307 } 5308 if (is_array($credits)) 5309 { 5310 $credits = array_values(SimplePie_Misc::array_unique($credits)); 5311 } 5312 } 5313 else 5314 { 5315 $credits = $credits_parent; 5316 } 5317 5318 // DESCRIPTION 5319 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'])) 5320 { 5321 $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5322 } 5323 else 5324 { 5325 $description = $description_parent; 5326 } 5327 5328 // HASHES 5329 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'])) 5330 { 5331 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash) 5332 { 5333 $value = null; 5334 $algo = null; 5335 if (isset($hash['data'])) 5336 { 5337 $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5338 } 5339 if (isset($hash['attribs']['']['algo'])) 5340 { 5341 $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT); 5342 } 5343 else 5344 { 5345 $algo = 'md5'; 5346 } 5347 $hashes[] = $algo.':'.$value; 5348 } 5349 if (is_array($hashes)) 5350 { 5351 $hashes = array_values(SimplePie_Misc::array_unique($hashes)); 5352 } 5353 } 5354 else 5355 { 5356 $hashes = $hashes_parent; 5357 } 5358 5359 // KEYWORDS 5360 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'])) 5361 { 5362 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'])) 5363 { 5364 $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)); 5365 foreach ($temp as $word) 5366 { 5367 $keywords[] = trim($word); 5368 } 5369 unset($temp); 5370 } 5371 if (is_array($keywords)) 5372 { 5373 $keywords = array_values(SimplePie_Misc::array_unique($keywords)); 5374 } 5375 } 5376 else 5377 { 5378 $keywords = $keywords_parent; 5379 } 5380 5381 // PLAYER 5382 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'])) 5383 { 5384 $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5385 } 5386 else 5387 { 5388 $player = $player_parent; 5389 } 5390 5391 // RATINGS 5392 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'])) 5393 { 5394 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating) 5395 { 5396 $rating_scheme = null; 5397 $rating_value = null; 5398 if (isset($rating['attribs']['']['scheme'])) 5399 { 5400 $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 5401 } 5402 else 5403 { 5404 $rating_scheme = 'urn:simple'; 5405 } 5406 if (isset($rating['data'])) 5407 { 5408 $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5409 } 5410 $ratings[] =& new $this->feed->rating_class($rating_scheme, $rating_value); 5411 } 5412 if (is_array($ratings)) 5413 { 5414 $ratings = array_values(SimplePie_Misc::array_unique($ratings)); 5415 } 5416 } 5417 else 5418 { 5419 $ratings = $ratings_parent; 5420 } 5421 5422 // RESTRICTIONS 5423 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'])) 5424 { 5425 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction) 5426 { 5427 $restriction_relationship = null; 5428 $restriction_type = null; 5429 $restriction_value = null; 5430 if (isset($restriction['attribs']['']['relationship'])) 5431 { 5432 $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT); 5433 } 5434 if (isset($restriction['attribs']['']['type'])) 5435 { 5436 $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5437 } 5438 if (isset($restriction['data'])) 5439 { 5440 $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5441 } 5442 $restrictions[] =& new $this->feed->restriction_class($restriction_relationship, $restriction_type, $restriction_value); 5443 } 5444 if (is_array($restrictions)) 5445 { 5446 $restrictions = array_values(SimplePie_Misc::array_unique($restrictions)); 5447 } 5448 } 5449 else 5450 { 5451 $restrictions = $restrictions_parent; 5452 } 5453 5454 // THUMBNAILS 5455 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'])) 5456 { 5457 foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail) 5458 { 5459 $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI); 5460 } 5461 if (is_array($thumbnails)) 5462 { 5463 $thumbnails = array_values(SimplePie_Misc::array_unique($thumbnails)); 5464 } 5465 } 5466 else 5467 { 5468 $thumbnails = $thumbnails_parent; 5469 } 5470 5471 // TITLES 5472 if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'])) 5473 { 5474 $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5475 } 5476 else 5477 { 5478 $title = $title_parent; 5479 } 5480 5481 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width); 5482 } 5483 } 5484 } 5485 5486 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link) 5487 { 5488 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure') 5489 { 5490 // Attributes 5491 $bitrate = null; 5492 $channels = null; 5493 $duration = null; 5494 $expression = null; 5495 $framerate = null; 5496 $height = null; 5497 $javascript = null; 5498 $lang = null; 5499 $length = null; 5500 $medium = null; 5501 $samplingrate = null; 5502 $type = null; 5503 $url = null; 5504 $width = null; 5505 5506 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 5507 if (isset($link['attribs']['']['type'])) 5508 { 5509 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5510 } 5511 if (isset($link['attribs']['']['length'])) 5512 { 5513 $length = ceil($link['attribs']['']['length']); 5514 } 5515 5516 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor 5517 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); 5518 } 5519 } 5520 5521 foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link) 5522 { 5523 if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure') 5524 { 5525 // Attributes 5526 $bitrate = null; 5527 $channels = null; 5528 $duration = null; 5529 $expression = null; 5530 $framerate = null; 5531 $height = null; 5532 $javascript = null; 5533 $lang = null; 5534 $length = null; 5535 $medium = null; 5536 $samplingrate = null; 5537 $type = null; 5538 $url = null; 5539 $width = null; 5540 5541 $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 5542 if (isset($link['attribs']['']['type'])) 5543 { 5544 $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5545 } 5546 if (isset($link['attribs']['']['length'])) 5547 { 5548 $length = ceil($link['attribs']['']['length']); 5549 } 5550 5551 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor 5552 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); 5553 } 5554 } 5555 5556 if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure')) 5557 { 5558 if (isset($enclosure[0]['attribs']['']['url'])) 5559 { 5560 // Attributes 5561 $bitrate = null; 5562 $channels = null; 5563 $duration = null; 5564 $expression = null; 5565 $framerate = null; 5566 $height = null; 5567 $javascript = null; 5568 $lang = null; 5569 $length = null; 5570 $medium = null; 5571 $samplingrate = null; 5572 $type = null; 5573 $url = null; 5574 $width = null; 5575 5576 $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0])); 5577 if (isset($enclosure[0]['attribs']['']['type'])) 5578 { 5579 $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT); 5580 } 5581 if (isset($enclosure[0]['attribs']['']['length'])) 5582 { 5583 $length = ceil($enclosure[0]['attribs']['']['length']); 5584 } 5585 5586 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor 5587 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); 5588 } 5589 } 5590 5591 if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width)) 5592 { 5593 // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor 5594 $this->data['enclosures'][] =& new $this->feed->enclosure_class($url, $type, $length, $this->feed->javascript, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width); 5595 } 5596 5597 $this->data['enclosures'] = array_values(SimplePie_Misc::array_unique($this->data['enclosures'])); 5598 } 5599 if (!empty($this->data['enclosures'])) 5600 { 5601 return $this->data['enclosures']; 5602 } 5603 else 5604 { 5605 return null; 5606 } 5607 } 5608 5609 function get_latitude() 5610 { 5611 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) 5612 { 5613 return (float) $return[0]['data']; 5614 } 5615 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) 5616 { 5617 return (float) $match[1]; 5618 } 5619 else 5620 { 5621 return null; 5622 } 5623 } 5624 5625 function get_longitude() 5626 { 5627 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) 5628 { 5629 return (float) $return[0]['data']; 5630 } 5631 elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) 5632 { 5633 return (float) $return[0]['data']; 5634 } 5635 elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) 5636 { 5637 return (float) $match[2]; 5638 } 5639 else 5640 { 5641 return null; 5642 } 5643 } 5644 5645 function get_source() 5646 { 5647 if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source')) 5648 { 5649 return new $this->feed->source_class($this, $return[0]); 5650 } 5651 else 5652 { 5653 return null; 5654 } 5655 } 5656 5657 /** 5658 * Creates the add_to_* methods' return data 5659 * 5660 * @access private 5661 * @param string $item_url String to prefix to the item permalink 5662 * @param string $title_url String to prefix to the item title 5663 * (and suffix to the item permalink) 5664 * @return mixed URL if feed exists, false otherwise 5665 */ 5666 function add_to_service($item_url, $title_url = null, $summary_url = null) 5667 { 5668 if ($this->get_permalink() !== null) 5669 { 5670 $return = $item_url . rawurlencode($this->get_permalink()); 5671 if ($title_url !== null && $this->get_title() !== null) 5672 { 5673 $return .= $title_url . rawurlencode($this->get_title()); 5674 } 5675 if ($summary_url !== null && $this->get_description() !== null) 5676 { 5677 $return .= $summary_url . rawurlencode($this->get_description()); 5678 } 5679 return $this->sanitize($return, SIMPLEPIE_CONSTRUCT_IRI); 5680 } 5681 else 5682 { 5683 return null; 5684 } 5685 } 5686 5687 function add_to_blinklist() 5688 { 5689 return $this->add_to_service('http://www.blinklist.com/index.php?Action=Blink/addblink.php&Description=&Url=', '&Title='); 5690 } 5691 5692 function add_to_blogmarks() 5693 { 5694 return $this->add_to_service('http://blogmarks.net/my/new.php?mini=1&simple=1&url=', '&title='); 5695 } 5696 5697 function add_to_delicious() 5698 { 5699 return $this->add_to_service('http://del.icio.us/post/?v=4&url=', '&title='); 5700 } 5701 5702 function add_to_digg() 5703 { 5704 return $this->add_to_service('http://digg.com/submit?url=', '&title=', '&bodytext='); 5705 } 5706 5707 function add_to_furl() 5708 { 5709 return $this->add_to_service('http://www.furl.net/storeIt.jsp?u=', '&t='); 5710 } 5711 5712 function add_to_magnolia() 5713 { 5714 return $this->add_to_service('http://ma.gnolia.com/bookmarklet/add?url=', '&title='); 5715 } 5716 5717 function add_to_myweb20() 5718 { 5719 return $this->add_to_service('http://myweb2.search.yahoo.com/myresults/bookmarklet?u=', '&t='); 5720 } 5721 5722 function add_to_newsvine() 5723 { 5724 return $this->add_to_service('http://www.newsvine.com/_wine/save?u=', '&h='); 5725 } 5726 5727 function add_to_reddit() 5728 { 5729 return $this->add_to_service('http://reddit.com/submit?url=', '&title='); 5730 } 5731 5732 function add_to_segnalo() 5733 { 5734 return $this->add_to_service('http://segnalo.com/post.html.php?url=', '&title='); 5735 } 5736 5737 function add_to_simpy() 5738 { 5739 return $this->add_to_service('http://www.simpy.com/simpy/LinkAdd.do?href=', '&title='); 5740 } 5741 5742 function add_to_spurl() 5743 { 5744 return $this->add_to_service('http://www.spurl.net/spurl.php?v=3&url=', '&title='); 5745 } 5746 5747 function add_to_wists() 5748 { 5749 return $this->add_to_service('http://wists.com/r.php?c=&r=', '&title='); 5750 } 5751 5752 function search_technorati() 5753 { 5754 return $this->add_to_service('http://www.technorati.com/search/'); 5755 } 5756 } 5757 5758 class SimplePie_Source 5759 { 5760 var $item; 5761 var $data = array(); 5762 5763 function SimplePie_Source($item, $data) 5764 { 5765 $this->item = $item; 5766 $this->data = $data; 5767 } 5768 5769 function __toString() 5770 { 5771 return md5(serialize($this->data)); 5772 } 5773 5774 function get_source_tags($namespace, $tag) 5775 { 5776 if (isset($this->data['child'][$namespace][$tag])) 5777 { 5778 return $this->data['child'][$namespace][$tag]; 5779 } 5780 else 5781 { 5782 return null; 5783 } 5784 } 5785 5786 function get_base($element = array()) 5787 { 5788 return $this->item->get_base($element); 5789 } 5790 5791 function sanitize($data, $type, $base = '') 5792 { 5793 return $this->item->sanitize($data, $type, $base); 5794 } 5795 5796 function get_item() 5797 { 5798 return $this->item; 5799 } 5800 5801 function get_title() 5802 { 5803 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title')) 5804 { 5805 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 5806 } 5807 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title')) 5808 { 5809 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 5810 } 5811 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title')) 5812 { 5813 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 5814 } 5815 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title')) 5816 { 5817 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 5818 } 5819 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title')) 5820 { 5821 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 5822 } 5823 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title')) 5824 { 5825 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5826 } 5827 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title')) 5828 { 5829 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5830 } 5831 else 5832 { 5833 return null; 5834 } 5835 } 5836 5837 function get_category($key = 0) 5838 { 5839 $categories = $this->get_categories(); 5840 if (isset($categories[$key])) 5841 { 5842 return $categories[$key]; 5843 } 5844 else 5845 { 5846 return null; 5847 } 5848 } 5849 5850 function get_categories() 5851 { 5852 $categories = array(); 5853 5854 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category) 5855 { 5856 $term = null; 5857 $scheme = null; 5858 $label = null; 5859 if (isset($category['attribs']['']['term'])) 5860 { 5861 $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT); 5862 } 5863 if (isset($category['attribs']['']['scheme'])) 5864 { 5865 $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT); 5866 } 5867 if (isset($category['attribs']['']['label'])) 5868 { 5869 $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT); 5870 } 5871 $categories[] =& new $this->item->feed->category_class($term, $scheme, $label); 5872 } 5873 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category) 5874 { 5875 // This is really the label, but keep this as the term also for BC. 5876 // Label will also work on retrieving because that falls back to term. 5877 $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5878 if (isset($category['attribs']['']['domain'])) 5879 { 5880 $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT); 5881 } 5882 else 5883 { 5884 $scheme = null; 5885 } 5886 $categories[] =& new $this->item->feed->category_class($term, $scheme, null); 5887 } 5888 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category) 5889 { 5890 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5891 } 5892 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category) 5893 { 5894 $categories[] =& new $this->item->feed->category_class($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5895 } 5896 5897 if (!empty($categories)) 5898 { 5899 return SimplePie_Misc::array_unique($categories); 5900 } 5901 else 5902 { 5903 return null; 5904 } 5905 } 5906 5907 function get_author($key = 0) 5908 { 5909 $authors = $this->get_authors(); 5910 if (isset($authors[$key])) 5911 { 5912 return $authors[$key]; 5913 } 5914 else 5915 { 5916 return null; 5917 } 5918 } 5919 5920 function get_authors() 5921 { 5922 $authors = array(); 5923 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author) 5924 { 5925 $name = null; 5926 $uri = null; 5927 $email = null; 5928 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 5929 { 5930 $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5931 } 5932 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 5933 { 5934 $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); 5935 } 5936 if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 5937 { 5938 $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5939 } 5940 if ($name !== null || $email !== null || $uri !== null) 5941 { 5942 $authors[] =& new $this->item->feed->author_class($name, $uri, $email); 5943 } 5944 } 5945 if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author')) 5946 { 5947 $name = null; 5948 $url = null; 5949 $email = null; 5950 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 5951 { 5952 $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5953 } 5954 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 5955 { 5956 $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); 5957 } 5958 if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 5959 { 5960 $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 5961 } 5962 if ($name !== null || $email !== null || $url !== null) 5963 { 5964 $authors[] =& new $this->item->feed->author_class($name, $url, $email); 5965 } 5966 } 5967 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author) 5968 { 5969 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5970 } 5971 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author) 5972 { 5973 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5974 } 5975 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author) 5976 { 5977 $authors[] =& new $this->item->feed->author_class($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null); 5978 } 5979 5980 if (!empty($authors)) 5981 { 5982 return SimplePie_Misc::array_unique($authors); 5983 } 5984 else 5985 { 5986 return null; 5987 } 5988 } 5989 5990 function get_contributor($key = 0) 5991 { 5992 $contributors = $this->get_contributors(); 5993 if (isset($contributors[$key])) 5994 { 5995 return $contributors[$key]; 5996 } 5997 else 5998 { 5999 return null; 6000 } 6001 } 6002 6003 function get_contributors() 6004 { 6005 $contributors = array(); 6006 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor) 6007 { 6008 $name = null; 6009 $uri = null; 6010 $email = null; 6011 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'])) 6012 { 6013 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6014 } 6015 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'])) 6016 { 6017 $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0])); 6018 } 6019 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'])) 6020 { 6021 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6022 } 6023 if ($name !== null || $email !== null || $uri !== null) 6024 { 6025 $contributors[] =& new $this->item->feed->author_class($name, $uri, $email); 6026 } 6027 } 6028 foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor) 6029 { 6030 $name = null; 6031 $url = null; 6032 $email = null; 6033 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'])) 6034 { 6035 $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6036 } 6037 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'])) 6038 { 6039 $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0])); 6040 } 6041 if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'])) 6042 { 6043 $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6044 } 6045 if ($name !== null || $email !== null || $url !== null) 6046 { 6047 $contributors[] =& new $this->item->feed->author_class($name, $url, $email); 6048 } 6049 } 6050 6051 if (!empty($contributors)) 6052 { 6053 return SimplePie_Misc::array_unique($contributors); 6054 } 6055 else 6056 { 6057 return null; 6058 } 6059 } 6060 6061 function get_link($key = 0, $rel = 'alternate') 6062 { 6063 $links = $this->get_links($rel); 6064 if (isset($links[$key])) 6065 { 6066 return $links[$key]; 6067 } 6068 else 6069 { 6070 return null; 6071 } 6072 } 6073 6074 /** 6075 * Added for parity between the parent-level and the item/entry-level. 6076 */ 6077 function get_permalink() 6078 { 6079 return $this->get_link(0); 6080 } 6081 6082 function get_links($rel = 'alternate') 6083 { 6084 if (!isset($this->data['links'])) 6085 { 6086 $this->data['links'] = array(); 6087 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link')) 6088 { 6089 foreach ($links as $link) 6090 { 6091 if (isset($link['attribs']['']['href'])) 6092 { 6093 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 6094 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 6095 } 6096 } 6097 } 6098 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link')) 6099 { 6100 foreach ($links as $link) 6101 { 6102 if (isset($link['attribs']['']['href'])) 6103 { 6104 $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate'; 6105 $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link)); 6106 6107 } 6108 } 6109 } 6110 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link')) 6111 { 6112 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 6113 } 6114 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link')) 6115 { 6116 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 6117 } 6118 if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link')) 6119 { 6120 $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0])); 6121 } 6122 6123 $keys = array_keys($this->data['links']); 6124 foreach ($keys as $key) 6125 { 6126 if (SimplePie_Misc::is_isegment_nz_nc($key)) 6127 { 6128 if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key])) 6129 { 6130 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]); 6131 $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]; 6132 } 6133 else 6134 { 6135 $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key]; 6136 } 6137 } 6138 elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY) 6139 { 6140 $this->data['links'][substr($key, 41)] =& $this->data['links'][$key]; 6141 } 6142 $this->data['links'][$key] = array_unique($this->data['links'][$key]); 6143 } 6144 } 6145 6146 if (isset($this->data['links'][$rel])) 6147 { 6148 return $this->data['links'][$rel]; 6149 } 6150 else 6151 { 6152 return null; 6153 } 6154 } 6155 6156 function get_description() 6157 { 6158 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle')) 6159 { 6160 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 6161 } 6162 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline')) 6163 { 6164 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 6165 } 6166 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) 6167 { 6168 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 6169 } 6170 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) 6171 { 6172 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 6173 } 6174 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) 6175 { 6176 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0])); 6177 } 6178 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) 6179 { 6180 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6181 } 6182 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) 6183 { 6184 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6185 } 6186 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) 6187 { 6188 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 6189 } 6190 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) 6191 { 6192 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0])); 6193 } 6194 else 6195 { 6196 return null; 6197 } 6198 } 6199 6200 function get_copyright() 6201 { 6202 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights')) 6203 { 6204 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_10_construct_type($return[0]['attribs']), $this->get_base($return[0])); 6205 } 6206 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright')) 6207 { 6208 return $this->sanitize($return[0]['data'], SimplePie_Misc::atom_03_construct_type($return[0]['attribs']), $this->get_base($return[0])); 6209 } 6210 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright')) 6211 { 6212 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6213 } 6214 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights')) 6215 { 6216 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6217 } 6218 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights')) 6219 { 6220 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6221 } 6222 else 6223 { 6224 return null; 6225 } 6226 } 6227 6228 function get_language() 6229 { 6230 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language')) 6231 { 6232 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6233 } 6234 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language')) 6235 { 6236 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6237 } 6238 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language')) 6239 { 6240 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT); 6241 } 6242 elseif (isset($this->data['xml_lang'])) 6243 { 6244 return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT); 6245 } 6246 else 6247 { 6248 return null; 6249 } 6250 } 6251 6252 function get_latitude() 6253 { 6254 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat')) 6255 { 6256 return (float) $return[0]['data']; 6257 } 6258 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) 6259 { 6260 return (float) $match[1]; 6261 } 6262 else 6263 { 6264 return null; 6265 } 6266 } 6267 6268 function get_longitude() 6269 { 6270 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long')) 6271 { 6272 return (float) $return[0]['data']; 6273 } 6274 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon')) 6275 { 6276 return (float) $return[0]['data']; 6277 } 6278 elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match)) 6279 { 6280 return (float) $match[2]; 6281 } 6282 else 6283 { 6284 return null; 6285 } 6286 } 6287 6288 function get_image_url() 6289 { 6290 if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image')) 6291 { 6292 return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI); 6293 } 6294 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo')) 6295 { 6296 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 6297 } 6298 elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon')) 6299 { 6300 return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0])); 6301 } 6302 else 6303 { 6304 return null; 6305 } 6306 } 6307 } 6308 6309 class SimplePie_Author 6310 { 6311 var $name; 6312 var $link; 6313 var $email; 6314 6315 // Constructor, used to input the data 6316 function SimplePie_Author($name = null, $link = null, $email = null) 6317 { 6318 $this->name = $name; 6319 $this->link = $link; 6320 $this->email = $email; 6321 } 6322 6323 function __toString() 6324 { 6325 // There is no $this->data here 6326 return md5(serialize($this)); 6327 } 6328 6329 function get_name() 6330 { 6331 if ($this->name !== null) 6332 { 6333 return $this->name; 6334 } 6335 else 6336 { 6337 return null; 6338 } 6339 } 6340 6341 function get_link() 6342 { 6343 if ($this->link !== null) 6344 { 6345 return $this->link; 6346 } 6347 else 6348 { 6349 return null; 6350 } 6351 } 6352 6353 function get_email() 6354 { 6355 if ($this->email !== null) 6356 { 6357 return $this->email; 6358 } 6359 else 6360 { 6361 return null; 6362 } 6363 } 6364 } 6365 6366 class SimplePie_Category 6367 { 6368 var $term; 6369 var $scheme; 6370 var $label; 6371 6372 // Constructor, used to input the data 6373 function SimplePie_Category($term = null, $scheme = null, $label = null) 6374 { 6375 $this->term = $term; 6376 $this->scheme = $scheme; 6377 $this->label = $label; 6378 } 6379 6380 function __toString() 6381 { 6382 // There is no $this->data here 6383 return md5(serialize($this)); 6384 } 6385 6386 function get_term() 6387 { 6388 if ($this->term !== null) 6389 { 6390 return $this->term; 6391 } 6392 else 6393 { 6394 return null; 6395 } 6396 } 6397 6398 function get_scheme() 6399 { 6400 if ($this->scheme !== null) 6401 { 6402 return $this->scheme; 6403 } 6404 else 6405 { 6406 return null; 6407 } 6408 } 6409 6410 function get_label() 6411 { 6412 if ($this->label !== null) 6413 { 6414 return $this->label; 6415 } 6416 else 6417 { 6418 return $this->get_term(); 6419 } 6420 } 6421 } 6422 6423 class SimplePie_Enclosure 6424 { 6425 var $bitrate; 6426 var $captions; 6427 var $categories; 6428 var $channels; 6429 var $copyright; 6430 var $credits; 6431 var $description; 6432 var $duration; 6433 var $expression; 6434 var $framerate; 6435 var $handler; 6436 var $hashes; 6437 var $height; 6438 var $javascript; 6439 var $keywords; 6440 var $lang; 6441 var $length; 6442 var $link; 6443 var $medium; 6444 var $player; 6445 var $ratings; 6446 var $restrictions; 6447 var $samplingrate; 6448 var $thumbnails; 6449 var $title; 6450 var $type; 6451 var $width; 6452 6453 // Constructor, used to input the data 6454 function SimplePie_Enclosure($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null) 6455 { 6456 $this->bitrate = $bitrate; 6457 $this->captions = $captions; 6458 $this->categories = $categories; 6459 $this->channels = $channels; 6460 $this->copyright = $copyright; 6461 $this->credits = $credits; 6462 $this->description = $description; 6463 $this->duration = $duration; 6464 $this->expression = $expression; 6465 $this->framerate = $framerate; 6466 $this->hashes = $hashes; 6467 $this->height = $height; 6468 $this->javascript = $javascript; 6469 $this->keywords = $keywords; 6470 $this->lang = $lang; 6471 $this->length = $length; 6472 $this->link = $link; 6473 $this->medium = $medium; 6474 $this->player = $player; 6475 $this->ratings = $ratings; 6476 $this->restrictions = $restrictions; 6477 $this->samplingrate = $samplingrate; 6478 $this->thumbnails = $thumbnails; 6479 $this->title = $title; 6480 $this->type = $type; 6481 $this->width = $width; 6482 if (class_exists('idna_convert')) 6483 { 6484 $idn =& new idna_convert(); 6485 $parsed = SimplePie_Misc::parse_url($link); 6486 $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); 6487 } 6488 $this->handler = $this->get_handler(); // Needs to load last 6489 } 6490 6491 function __toString() 6492 { 6493 // There is no $this->data here 6494 return md5(serialize($this)); 6495 } 6496 6497 function get_bitrate() 6498 { 6499 if ($this->bitrate !== null) 6500 { 6501 return $this->bitrate; 6502 } 6503 else 6504 { 6505 return null; 6506 } 6507 } 6508 6509 function get_caption($key = 0) 6510 { 6511 $captions = $this->get_captions(); 6512 if (isset($captions[$key])) 6513 { 6514 return $captions[$key]; 6515 } 6516 else 6517 { 6518 return null; 6519 } 6520 } 6521 6522 function get_captions() 6523 { 6524 if ($this->captions !== null) 6525 { 6526 return $this->captions; 6527 } 6528 else 6529 { 6530 return null; 6531 } 6532 } 6533 6534 function get_category($key = 0) 6535 { 6536 $categories = $this->get_categories(); 6537 if (isset($categories[$key])) 6538 { 6539 return $categories[$key]; 6540 } 6541 else 6542 { 6543 return null; 6544 } 6545 } 6546 6547 function get_categories() 6548 { 6549 if ($this->categories !== null) 6550 { 6551 return $this->categories; 6552 } 6553 else 6554 { 6555 return null; 6556 } 6557 } 6558 6559 function get_channels() 6560 { 6561 if ($this->channels !== null) 6562 { 6563 return $this->channels; 6564 } 6565 else 6566 { 6567 return null; 6568 } 6569 } 6570 6571 function get_copyright() 6572 { 6573 if ($this->copyright !== null) 6574 { 6575 return $this->copyright; 6576 } 6577 else 6578 { 6579 return null; 6580 } 6581 } 6582 6583 function get_credit($key = 0) 6584 { 6585 $credits = $this->get_credits(); 6586 if (isset($credits[$key])) 6587 { 6588 return $credits[$key]; 6589 } 6590 else 6591 { 6592 return null; 6593 } 6594 } 6595 6596 function get_credits() 6597 { 6598 if ($this->credits !== null) 6599 { 6600 return $this->credits; 6601 } 6602 else 6603 { 6604 return null; 6605 } 6606 } 6607 6608 function get_description() 6609 { 6610 if ($this->description !== null) 6611 { 6612 return $this->description; 6613 } 6614 else 6615 { 6616 return null; 6617 } 6618 } 6619 6620 function get_duration($convert = false) 6621 { 6622 if ($this->duration !== null) 6623 { 6624 if ($convert) 6625 { 6626 $time = SimplePie_Misc::time_hms($this->duration); 6627 return $time; 6628 } 6629 else 6630 { 6631 return $this->duration; 6632 } 6633 } 6634 else 6635 { 6636 return null; 6637 } 6638 } 6639 6640 function get_expression() 6641 { 6642 if ($this->expression !== null) 6643 { 6644 return $this->expression; 6645 } 6646 else 6647 { 6648 return 'full'; 6649 } 6650 } 6651 6652 function get_extension() 6653 { 6654 if ($this->link !== null) 6655 { 6656 $url = SimplePie_Misc::parse_url($this->link); 6657 if ($url['path'] !== '') 6658 { 6659 return pathinfo($url['path'], PATHINFO_EXTENSION); 6660 } 6661 } 6662 return null; 6663 } 6664 6665 function get_framerate() 6666 { 6667 if ($this->framerate !== null) 6668 { 6669 return $this->framerate; 6670 } 6671 else 6672 { 6673 return null; 6674 } 6675 } 6676 6677 function get_handler() 6678 { 6679 return $this->get_real_type(true); 6680 } 6681 6682 function get_hash($key = 0) 6683 { 6684 $hashes = $this->get_hashes(); 6685 if (isset($hashes[$key])) 6686 { 6687 return $hashes[$key]; 6688 } 6689 else 6690 { 6691 return null; 6692 } 6693 } 6694 6695 function get_hashes() 6696 { 6697 if ($this->hashes !== null) 6698 { 6699 return $this->hashes; 6700 } 6701 else 6702 { 6703 return null; 6704 } 6705 } 6706 6707 function get_height() 6708 { 6709 if ($this->height !== null) 6710 { 6711 return $this->height; 6712 } 6713 else 6714 { 6715 return null; 6716 } 6717 } 6718 6719 function get_language() 6720 { 6721 if ($this->lang !== null) 6722 { 6723 return $this->lang; 6724 } 6725 else 6726 { 6727 return null; 6728 } 6729 } 6730 6731 function get_keyword($key = 0) 6732 { 6733 $keywords = $this->get_keywords(); 6734 if (isset($keywords[$key])) 6735 { 6736 return $keywords[$key]; 6737 } 6738 else 6739 { 6740 return null; 6741 } 6742 } 6743 6744 function get_keywords() 6745 { 6746 if ($this->keywords !== null) 6747 { 6748 return $this->keywords; 6749 } 6750 else 6751 { 6752 return null; 6753 } 6754 } 6755 6756 function get_length() 6757 { 6758 if ($this->length !== null) 6759 { 6760 return $this->length; 6761 } 6762 else 6763 { 6764 return null; 6765 } 6766 } 6767 6768 function get_link() 6769 { 6770 if ($this->link !== null) 6771 { 6772 return urldecode($this->link); 6773 } 6774 else 6775 { 6776 return null; 6777 } 6778 } 6779 6780 function get_medium() 6781 { 6782 if ($this->medium !== null) 6783 { 6784 return $this->medium; 6785 } 6786 else 6787 { 6788 return null; 6789 } 6790 } 6791 6792 function get_player() 6793 { 6794 if ($this->player !== null) 6795 { 6796 return $this->player; 6797 } 6798 else 6799 { 6800 return null; 6801 } 6802 } 6803 6804 function get_rating($key = 0) 6805 { 6806 $ratings = $this->get_ratings(); 6807 if (isset($ratings[$key])) 6808 { 6809 return $ratings[$key]; 6810 } 6811 else 6812 { 6813 return null; 6814 } 6815 } 6816 6817 function get_ratings() 6818 { 6819 if ($this->ratings !== null) 6820 { 6821 return $this->ratings; 6822 } 6823 else 6824 { 6825 return null; 6826 } 6827 } 6828 6829 function get_restriction($key = 0) 6830 { 6831 $restrictions = $this->get_restrictions(); 6832 if (isset($restrictions[$key])) 6833 { 6834 return $restrictions[$key]; 6835 } 6836 else 6837 { 6838 return null; 6839 } 6840 } 6841 6842 function get_restrictions() 6843 { 6844 if ($this->restrictions !== null) 6845 { 6846 return $this->restrictions; 6847 } 6848 else 6849 { 6850 return null; 6851 } 6852 } 6853 6854 function get_sampling_rate() 6855 { 6856 if ($this->samplingrate !== null) 6857 { 6858 return $this->samplingrate; 6859 } 6860 else 6861 { 6862 return null; 6863 } 6864 } 6865 6866 function get_size() 6867 { 6868 $length = $this->get_length(); 6869 if ($length !== null) 6870 { 6871 return round($length/1048576, 2); 6872 } 6873 else 6874 { 6875 return null; 6876 } 6877 } 6878 6879 function get_thumbnail($key = 0) 6880 { 6881 $thumbnails = $this->get_thumbnails(); 6882 if (isset($thumbnails[$key])) 6883 { 6884 return $thumbnails[$key]; 6885 } 6886 else 6887 { 6888 return null; 6889 } 6890 } 6891 6892 function get_thumbnails() 6893 { 6894 if ($this->thumbnails !== null) 6895 { 6896 return $this->thumbnails; 6897 } 6898 else 6899 { 6900 return null; 6901 } 6902 } 6903 6904 function get_title() 6905 { 6906 if ($this->title !== null) 6907 { 6908 return $this->title; 6909 } 6910 else 6911 { 6912 return null; 6913 } 6914 } 6915 6916 function get_type() 6917 { 6918 if ($this->type !== null) 6919 { 6920 return $this->type; 6921 } 6922 else 6923 { 6924 return null; 6925 } 6926 } 6927 6928 function get_width() 6929 { 6930 if ($this->width !== null) 6931 { 6932 return $this->width; 6933 } 6934 else 6935 { 6936 return null; 6937 } 6938 } 6939 6940 function native_embed($options='') 6941 { 6942 return $this->embed($options, true); 6943 } 6944 6945 /** 6946 * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'. 6947 */ 6948 function embed($options = '', $native = false) 6949 { 6950 // Set up defaults 6951 $audio = ''; 6952 $video = ''; 6953 $alt = ''; 6954 $altclass = ''; 6955 $loop = 'false'; 6956 $width = 'auto'; 6957 $height = 'auto'; 6958 $bgcolor = '#ffffff'; 6959 $mediaplayer = ''; 6960 $widescreen = false; 6961 $handler = $this->get_handler(); 6962 $type = $this->get_real_type(); 6963 6964 // Process options and reassign values as necessary 6965 if (is_array($options)) 6966 { 6967 extract($options); 6968 } 6969 else 6970 { 6971 $options = explode(',', $options); 6972 foreach($options as $option) 6973 { 6974 $opt = explode(':', $option, 2); 6975 if (isset($opt[0], $opt[1])) 6976 { 6977 $opt[0] = trim($opt[0]); 6978 $opt[1] = trim($opt[1]); 6979 switch ($opt[0]) 6980 { 6981 case 'audio': 6982 $audio = $opt[1]; 6983 break; 6984 6985 case 'video': 6986 $video = $opt[1]; 6987 break; 6988 6989 case 'alt': 6990 $alt = $opt[1]; 6991 break; 6992 6993 case 'altclass': 6994 $altclass = $opt[1]; 6995 break; 6996 6997 case 'loop': 6998 $loop = $opt[1]; 6999 break; 7000 7001 case 'width': 7002 $width = $opt[1]; 7003 break; 7004 7005 case 'height': 7006 $height = $opt[1]; 7007 break; 7008 7009 case 'bgcolor': 7010 $bgcolor = $opt[1]; 7011 break; 7012 7013 case 'mediaplayer': 7014 $mediaplayer = $opt[1]; 7015 break; 7016 7017 case 'widescreen': 7018 $widescreen = $opt[1]; 7019 break; 7020 } 7021 } 7022 } 7023 } 7024 7025 $mime = explode('/', $type, 2); 7026 $mime = $mime[0]; 7027 7028 // Process values for 'auto' 7029 if ($width === 'auto') 7030 { 7031 if ($mime === 'video') 7032 { 7033 if ($height === 'auto') 7034 { 7035 $width = 480; 7036 } 7037 elseif ($widescreen) 7038 { 7039 $width = round((intval($height)/9)*16); 7040 } 7041 else 7042 { 7043 $width = round((intval($height)/3)*4); 7044 } 7045 } 7046 else 7047 { 7048 $width = '100%'; 7049 } 7050 } 7051 7052 if ($height === 'auto') 7053 { 7054 if ($mime === 'audio') 7055 { 7056 $height = 0; 7057 } 7058 elseif ($mime === 'video') 7059 { 7060 if ($width === 'auto') 7061 { 7062 if ($widescreen) 7063 { 7064 $height = 270; 7065 } 7066 else 7067 { 7068 $height = 360; 7069 } 7070 } 7071 elseif ($widescreen) 7072 { 7073 $height = round((intval($width)/16)*9); 7074 } 7075 else 7076 { 7077 $height = round((intval($width)/4)*3); 7078 } 7079 } 7080 else 7081 { 7082 $height = 376; 7083 } 7084 } 7085 elseif ($mime === 'audio') 7086 { 7087 $height = 0; 7088 } 7089 7090 // Set proper placeholder value 7091 if ($mime === 'audio') 7092 { 7093 $placeholder = $audio; 7094 } 7095 elseif ($mime === 'video') 7096 { 7097 $placeholder = $video; 7098 } 7099 7100 $embed = ''; 7101 7102 // Make sure the JS library is included 7103 if (!$native) 7104 { 7105 static $javascript_outputted = null; 7106 if (!$javascript_outputted && $this->javascript) 7107 { 7108 $embed .= '<script type="text/javascript" src="?' . htmlspecialchars($this->javascript) . '"></script>'; 7109 $javascript_outputted = true; 7110 } 7111 } 7112 7113 // Odeo Feed MP3's 7114 if ($handler === 'odeo') 7115 { 7116 if ($native) 7117 { 7118 $embed .= '<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://adobe.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url=' . $this->get_link() . '"></embed>'; 7119 } 7120 else 7121 { 7122 $embed .= '<script type="text/javascript">embed_odeo("' . $this->get_link() . '");</script>'; 7123 } 7124 } 7125 7126 // Flash 7127 elseif ($handler === 'flash') 7128 { 7129 if ($native) 7130 { 7131 $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>"; 7132 } 7133 else 7134 { 7135 $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>"; 7136 } 7137 } 7138 7139 // Flash Media Player file types. 7140 // Preferred handler for MP3 file types. 7141 elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== '')) 7142 { 7143 $height += 20; 7144 if ($native) 7145 { 7146 $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>"; 7147 } 7148 else 7149 { 7150 $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>"; 7151 } 7152 } 7153 7154 // QuickTime 7 file types. Need to test with QuickTime 6. 7155 // Only handle MP3's if the Flash Media Player is not present. 7156 elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === '')) 7157 { 7158 $height += 16; 7159 if ($native) 7160 { 7161 if ($placeholder !== '') 7162 { 7163 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>"; 7164 } 7165 else 7166 { 7167 $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>"; 7168 } 7169 } 7170 else 7171 { 7172 $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>"; 7173 } 7174 } 7175 7176 // Windows Media 7177 elseif ($handler === 'wmedia') 7178 { 7179 $height += 45; 7180 if ($native) 7181 { 7182 $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>"; 7183 } 7184 else 7185 { 7186 $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>"; 7187 } 7188 } 7189 7190 // Everything else 7191 else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>'; 7192 7193 return $embed; 7194 } 7195 7196 function get_real_type($find_handler = false) 7197 { 7198 // If it's Odeo, let's get it out of the way. 7199 if (substr(strtolower($this->get_link()), 0, 15) === 'http://odeo.com') 7200 { 7201 return 'odeo'; 7202 } 7203 7204 // Mime-types by handler. 7205 $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash 7206 $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player 7207 $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime 7208 $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media 7209 $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3 7210 7211 if ($this->get_type() !== null) 7212 { 7213 $type = strtolower($this->type); 7214 } 7215 else 7216 { 7217 $type = null; 7218 } 7219 7220 // If we encounter an unsupported mime-type, check the file extension and guess intelligently. 7221 if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3))) 7222 { 7223 switch (strtolower($this->get_extension())) 7224 { 7225 // Audio mime-types 7226 case 'aac': 7227 case 'adts': 7228 $type = 'audio/acc'; 7229 break; 7230 7231 case 'aif': 7232 case 'aifc': 7233 case 'aiff': 7234 case 'cdda': 7235 $type = 'audio/aiff'; 7236 break; 7237 7238 case 'bwf': 7239 $type = 'audio/wav'; 7240 break; 7241 7242 case 'kar': 7243 case 'mid': 7244 case 'midi': 7245 case 'smf': 7246 $type = 'audio/midi'; 7247 break; 7248 7249 case 'm4a': 7250 $type = 'audio/x-m4a'; 7251 break; 7252 7253 case 'mp3': 7254 case 'swa': 7255 $type = 'audio/mp3'; 7256 break; 7257 7258 case 'wav': 7259 $type = 'audio/wav'; 7260 break; 7261 7262 case 'wax': 7263 $type = 'audio/x-ms-wax'; 7264 break; 7265 7266 case 'wma': 7267 $type = 'audio/x-ms-wma'; 7268 break; 7269 7270 // Video mime-types 7271 case '3gp': 7272 case '3gpp': 7273 $type = 'video/3gpp'; 7274 break; 7275 7276 case '3g2': 7277 case '3gp2': 7278 $type = 'video/3gpp2'; 7279 break; 7280 7281 case 'asf': 7282 $type = 'video/x-ms-asf'; 7283 break; 7284 7285 case 'flv': 7286 $type = 'video/x-flv'; 7287 break; 7288 7289 case 'm1a': 7290 case 'm1s': 7291 case 'm1v': 7292 case 'm15': 7293 case 'm75': 7294 case 'mp2': 7295 case 'mpa': 7296 case 'mpeg': 7297 case 'mpg': 7298 case 'mpm': 7299 case 'mpv': 7300 $type = 'video/mpeg'; 7301 break; 7302 7303 case 'm4v': 7304 $type = 'video/x-m4v'; 7305 break; 7306 7307 case 'mov': 7308 case 'qt': 7309 $type = 'video/quicktime'; 7310 break; 7311 7312 case 'mp4': 7313 case 'mpg4': 7314 $type = 'video/mp4'; 7315 break; 7316 7317 case 'sdv': 7318 $type = 'video/sd-video'; 7319 break; 7320 7321 case 'wm': 7322 $type = 'video/x-ms-wm'; 7323 break; 7324 7325 case 'wmv': 7326 $type = 'video/x-ms-wmv'; 7327 break; 7328 7329 case 'wvx': 7330 $type = 'video/x-ms-wvx'; 7331 break; 7332 7333 // Flash mime-types 7334 case 'spl': 7335 $type = 'application/futuresplash'; 7336 break; 7337 7338 case 'swf': 7339 $type = 'application/x-shockwave-flash'; 7340 break; 7341 } 7342 } 7343 7344 if ($find_handler) 7345 { 7346 if (in_array($type, $types_flash)) 7347 { 7348 return 'flash'; 7349 } 7350 elseif (in_array($type, $types_fmedia)) 7351 { 7352 return 'fmedia'; 7353 } 7354 elseif (in_array($type, $types_quicktime)) 7355 { 7356 return 'quicktime'; 7357 } 7358 elseif (in_array($type, $types_wmedia)) 7359 { 7360 return 'wmedia'; 7361 } 7362 elseif (in_array($type, $types_mp3)) 7363 { 7364 return 'mp3'; 7365 } 7366 else 7367 { 7368 return null; 7369 } 7370 } 7371 else 7372 { 7373 return $type; 7374 } 7375 } 7376 } 7377 7378 class SimplePie_Caption 7379 { 7380 var $type; 7381 var $lang; 7382 var $startTime; 7383 var $endTime; 7384 var $text; 7385 7386 // Constructor, used to input the data 7387 function SimplePie_Caption($type = null, $lang = null, $startTime = null, $endTime = null, $text = null) 7388 { 7389 $this->type = $type; 7390 $this->lang = $lang; 7391 $this->startTime = $startTime; 7392 $this->endTime = $endTime; 7393 $this->text = $text; 7394 } 7395 7396 function __toString() 7397 { 7398 // There is no $this->data here 7399 return md5(serialize($this)); 7400 } 7401 7402 function get_endtime() 7403 { 7404 if ($this->endTime !== null) 7405 { 7406 return $this->endTime; 7407 } 7408 else 7409 { 7410 return null; 7411 } 7412 } 7413 7414 function get_language() 7415 { 7416 if ($this->lang !== null) 7417 { 7418 return $this->lang; 7419 } 7420 else 7421 { 7422 return null; 7423 } 7424 } 7425 7426 function get_starttime() 7427 { 7428 if ($this->startTime !== null) 7429 { 7430 return $this->startTime; 7431 } 7432 else 7433 { 7434 return null; 7435 } 7436 } 7437 7438 function get_text() 7439 { 7440 if ($this->text !== null) 7441 { 7442 return $this->text; 7443 } 7444 else 7445 { 7446 return null; 7447 } 7448 } 7449 7450 function get_type() 7451 { 7452 if ($this->type !== null) 7453 { 7454 return $this->type; 7455 } 7456 else 7457 { 7458 return null; 7459 } 7460 } 7461 } 7462 7463 class SimplePie_Credit 7464 { 7465 var $role; 7466 var $scheme; 7467 var $name; 7468 7469 // Constructor, used to input the data 7470 function SimplePie_Credit($role = null, $scheme = null, $name = null) 7471 { 7472 $this->role = $role; 7473 $this->scheme = $scheme; 7474 $this->name = $name; 7475 } 7476 7477 function __toString() 7478 { 7479 // There is no $this->data here 7480 return md5(serialize($this)); 7481 } 7482 7483 function get_role() 7484 { 7485 if ($this->role !== null) 7486 { 7487 return $this->role; 7488 } 7489 else 7490 { 7491 return null; 7492 } 7493 } 7494 7495 function get_scheme() 7496 { 7497 if ($this->scheme !== null) 7498 { 7499 return $this->scheme; 7500 } 7501 else 7502 { 7503 return null; 7504 } 7505 } 7506 7507 function get_name() 7508 { 7509 if ($this->name !== null) 7510 { 7511 return $this->name; 7512 } 7513 else 7514 { 7515 return null; 7516 } 7517 } 7518 } 7519 7520 class SimplePie_Copyright 7521 { 7522 var $url; 7523 var $label; 7524 7525 // Constructor, used to input the data 7526 function SimplePie_Copyright($url = null, $label = null) 7527 { 7528 $this->url = $url; 7529 $this->label = $label; 7530 } 7531 7532 function __toString() 7533 { 7534 // There is no $this->data here 7535 return md5(serialize($this)); 7536 } 7537 7538 function get_url() 7539 { 7540 if ($this->url !== null) 7541 { 7542 return $this->url; 7543 } 7544 else 7545 { 7546 return null; 7547 } 7548 } 7549 7550 function get_attribution() 7551 { 7552 if ($this->label !== null) 7553 { 7554 return $this->label; 7555 } 7556 else 7557 { 7558 return null; 7559 } 7560 } 7561 } 7562 7563 class SimplePie_Rating 7564 { 7565 var $scheme; 7566 var $value; 7567 7568 // Constructor, used to input the data 7569 function SimplePie_Rating($scheme = null, $value = null) 7570 { 7571 $this->scheme = $scheme; 7572 $this->value = $value; 7573 } 7574 7575 function __toString() 7576 { 7577 // There is no $this->data here 7578 return md5(serialize($this)); 7579 } 7580 7581 function get_scheme() 7582 { 7583 if ($this->scheme !== null) 7584 { 7585 return $this->scheme; 7586 } 7587 else 7588 { 7589 return null; 7590 } 7591 } 7592 7593 function get_value() 7594 { 7595 if ($this->value !== null) 7596 { 7597 return $this->value; 7598 } 7599 else 7600 { 7601 return null; 7602 } 7603 } 7604 } 7605 7606 class SimplePie_Restriction 7607 { 7608 var $relationship; 7609 var $type; 7610 var $value; 7611 7612 // Constructor, used to input the data 7613 function SimplePie_Restriction($relationship = null, $type = null, $value = null) 7614 { 7615 $this->relationship = $relationship; 7616 $this->type = $type; 7617 $this->value = $value; 7618 } 7619 7620 function __toString() 7621 { 7622 // There is no $this->data here 7623 return md5(serialize($this)); 7624 } 7625 7626 function get_relationship() 7627 { 7628 if ($this->relationship !== null) 7629 { 7630 return $this->relationship; 7631 } 7632 else 7633 { 7634 return null; 7635 } 7636 } 7637 7638 function get_type() 7639 { 7640 if ($this->type !== null) 7641 { 7642 return $this->type; 7643 } 7644 else 7645 { 7646 return null; 7647 } 7648 } 7649 7650 function get_value() 7651 { 7652 if ($this->value !== null) 7653 { 7654 return $this->value; 7655 } 7656 else 7657 { 7658 return null; 7659 } 7660 } 7661 } 7662 7663 /** 7664 * @todo Move to properly supporting RFC2616 (HTTP/1.1) 7665 */ 7666 class SimplePie_File 7667 { 7668 var $url; 7669 var $useragent; 7670 var $success = true; 7671 var $headers = array(); 7672 var $body; 7673 var $status_code; 7674 var $redirects = 0; 7675 var $error; 7676 var $method = SIMPLEPIE_FILE_SOURCE_NONE; 7677 7678 function SimplePie_File($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) 7679 { 7680 if (class_exists('idna_convert')) 7681 { 7682 $idn =& new idna_convert(); 7683 $parsed = SimplePie_Misc::parse_url($url); 7684 $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); 7685 } 7686 $this->url = $url; 7687 $this->useragent = $useragent; 7688 if (preg_match('/^http(s)?:\/\//i', $url)) 7689 { 7690 if ($useragent === null) 7691 { 7692 $useragent = ini_get('user_agent'); 7693 $this->useragent = $useragent; 7694 } 7695 if (!is_array($headers)) 7696 { 7697 $headers = array(); 7698 } 7699 if (!$force_fsockopen && function_exists('curl_exec')) 7700 { 7701 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL; 7702 $fp = curl_init(); 7703 $headers2 = array(); 7704 foreach ($headers as $key => $value) 7705 { 7706 $headers2[] = "$key: $value"; 7707 } 7708 if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>=')) 7709 { 7710 curl_setopt($fp, CURLOPT_ENCODING, ''); 7711 } 7712 curl_setopt($fp, CURLOPT_URL, $url); 7713 curl_setopt($fp, CURLOPT_HEADER, 1); 7714 curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1); 7715 curl_setopt($fp, CURLOPT_TIMEOUT, $timeout); 7716 curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout); 7717 curl_setopt($fp, CURLOPT_REFERER, $url); 7718 curl_setopt($fp, CURLOPT_USERAGENT, $useragent); 7719 curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); 7720 if (!ini_get('open_basedir') && !ini_get('safe_mode') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>=')) 7721 { 7722 curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1); 7723 curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects); 7724 } 7725 7726 $this->headers = curl_exec($fp); 7727 if (curl_errno($fp) === 23 || curl_errno($fp) === 61) 7728 { 7729 curl_setopt($fp, CURLOPT_ENCODING, 'none'); 7730 $this->headers = curl_exec($fp); 7731 } 7732 if (curl_errno($fp)) 7733 { 7734 $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp); 7735 $this->success = false; 7736 } 7737 else 7738 { 7739 $info = curl_getinfo($fp); 7740 curl_close($fp); 7741 $this->headers = explode("\r\n\r\n", $this->headers, $info['redirect_count'] + 1); 7742 $this->headers = array_pop($this->headers); 7743 $parser =& new SimplePie_HTTP_Parser($this->headers); 7744 if ($parser->parse()) 7745 { 7746 $this->headers = $parser->headers; 7747 $this->body = $parser->body; 7748 $this->status_code = $parser->status_code; 7749 if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) 7750 { 7751 $this->redirects++; 7752 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); 7753 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); 7754 } 7755 } 7756 } 7757 } 7758 else 7759 { 7760 $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN; 7761 $url_parts = parse_url($url); 7762 if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') 7763 { 7764 $url_parts['host'] = "ssl://$url_parts[host]"; 7765 $url_parts['port'] = 443; 7766 } 7767 if (!isset($url_parts['port'])) 7768 { 7769 $url_parts['port'] = 80; 7770 } 7771 $fp = @fsockopen($url_parts['host'], $url_parts['port'], $errno, $errstr, $timeout); 7772 if (!$fp) 7773 { 7774 $this->error = 'fsockopen error: ' . $errstr; 7775 $this->success = false; 7776 } 7777 else 7778 { 7779 stream_set_timeout($fp, $timeout); 7780 if (isset($url_parts['path'])) 7781 { 7782 if (isset($url_parts['query'])) 7783 { 7784 $get = "$url_parts[path]?$url_parts[query]"; 7785 } 7786 else 7787 { 7788 $get = $url_parts['path']; 7789 } 7790 } 7791 else 7792 { 7793 $get = '/'; 7794 } 7795 $out = "GET $get HTTP/1.0\r\n"; 7796 $out .= "Host: $url_parts[host]\r\n"; 7797 $out .= "User-Agent: $useragent\r\n"; 7798 if (extension_loaded('zlib')) 7799 { 7800 $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n"; 7801 } 7802 7803 if (isset($url_parts['user']) && isset($url_parts['pass'])) 7804 { 7805 $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n"; 7806 } 7807 foreach ($headers as $key => $value) 7808 { 7809 $out .= "$key: $value\r\n"; 7810 } 7811 $out .= "Connection: Close\r\n\r\n"; 7812 fwrite($fp, $out); 7813 7814 $info = stream_get_meta_data($fp); 7815 7816 $this->headers = ''; 7817 while (!$info['eof'] && !$info['timed_out']) 7818 { 7819 $this->headers .= fread($fp, 1160); 7820 $info = stream_get_meta_data($fp); 7821 } 7822 if (!$info['timed_out']) 7823 { 7824 $parser =& new SimplePie_HTTP_Parser($this->headers); 7825 if ($parser->parse()) 7826 { 7827 $this->headers = $parser->headers; 7828 $this->body = $parser->body; 7829 $this->status_code = $parser->status_code; 7830 if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects) 7831 { 7832 $this->redirects++; 7833 $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); 7834 return $this->SimplePie_File($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); 7835 } 7836 if (isset($this->headers['content-encoding'])) 7837 { 7838 // Hey, we act dumb elsewhere, so let's do that here too 7839 switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20"))) 7840 { 7841 case 'gzip': 7842 case 'x-gzip': 7843 $decoder =& new SimplePie_gzdecode($this->body); 7844 if (!$decoder->parse()) 7845 { 7846 $this->error = 'Unable to decode HTTP "gzip" stream'; 7847 $this->success = false; 7848 } 7849 else 7850 { 7851 $this->body = $decoder->data; 7852 } 7853 break; 7854 7855 case 'deflate': 7856 if (($body = gzuncompress($this->body)) === false) 7857 { 7858 if (($body = gzinflate($this->body)) === false) 7859 { 7860 $this->error = 'Unable to decode HTTP "deflate" stream'; 7861 $this->success = false; 7862 } 7863 } 7864 $this->body = $body; 7865 break; 7866 7867 default: 7868 $this->error = 'Unknown content coding'; 7869 $this->success = false; 7870 } 7871 } 7872 } 7873 } 7874 else 7875 { 7876 $this->error = 'fsocket timed out'; 7877 $this->success = false; 7878 } 7879 fclose($fp); 7880 } 7881 } 7882 } 7883 else 7884 { 7885 $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS; 7886 if (!$this->body = file_get_contents($url)) 7887 { 7888 $this->error = 'file_get_contents could not read the file'; 7889 $this->success = false; 7890 } 7891 } 7892 } 7893 } 7894 7895 /** 7896 * HTTP Response Parser 7897 * 7898 * @package SimplePie 7899 */ 7900 class SimplePie_HTTP_Parser 7901 { 7902 /** 7903 * HTTP Version 7904 * 7905 * @access public 7906 * @var float 7907 */ 7908 var $http_version = 0.0; 7909 7910 /** 7911 * Status code 7912 * 7913 * @access public 7914 * @var int 7915 */ 7916 var $status_code = 0; 7917 7918 /** 7919 * Reason phrase 7920 * 7921 * @access public 7922 * @var string 7923 */ 7924 var $reason = ''; 7925 7926 /** 7927 * Key/value pairs of the headers 7928 * 7929 * @access public 7930 * @var array 7931 */ 7932 var $headers = array(); 7933 7934 /** 7935 * Body of the response 7936 * 7937 * @access public 7938 * @var string 7939 */ 7940 var $body = ''; 7941 7942 /** 7943 * Current state of the state machine 7944 * 7945 * @access private 7946 * @var string 7947 */ 7948 var $state = 'http_version'; 7949 7950 /** 7951 * Input data 7952 * 7953 * @access private 7954 * @var string 7955 */ 7956 var $data = ''; 7957 7958 /** 7959 * Input data length (to avoid calling strlen() everytime this is needed) 7960 * 7961 * @access private 7962 * @var int 7963 */ 7964 var $data_length = 0; 7965 7966 /** 7967 * Current position of the pointer 7968 * 7969 * @var int 7970 * @access private 7971 */ 7972 var $position = 0; 7973 7974 /** 7975 * Name of the hedaer currently being parsed 7976 * 7977 * @access private 7978 * @var string 7979 */ 7980 var $name = ''; 7981 7982 /** 7983 * Value of the hedaer currently being parsed 7984 * 7985 * @access private 7986 * @var string 7987 */ 7988 var $value = ''; 7989 7990 /** 7991 * Create an instance of the class with the input data 7992 * 7993 * @access public 7994 * @param string $data Input data 7995 */ 7996 function SimplePie_HTTP_Parser($data) 7997 { 7998 $this->data = $data; 7999 $this->data_length = strlen($this->data); 8000 } 8001 8002 /** 8003 * Parse the input data 8004 * 8005 * @access public 8006 * @return bool true on success, false on failure 8007 */ 8008 function parse() 8009 { 8010 while ($this->state && $this->state !== 'emit' && $this->has_data()) 8011 { 8012 $state = $this->state; 8013 $this->$state(); 8014 } 8015 $this->data = ''; 8016 if ($this->state === 'emit' || $this->state === 'body') 8017 { 8018 return true; 8019 } 8020 else 8021 { 8022 $this->http_version = ''; 8023 $this->status_code = ''; 8024 $this->reason = ''; 8025 $this->headers = array(); 8026 $this->body = ''; 8027 return false; 8028 } 8029 } 8030 8031 /** 8032 * Check whether there is data beyond the pointer 8033 * 8034 * @access private 8035 * @return bool true if there is further data, false if not 8036 */ 8037 function has_data() 8038 { 8039 return (bool) ($this->position < $this->data_length); 8040 } 8041 8042 /** 8043 * See if the next character is LWS 8044 * 8045 * @access private 8046 * @return bool true if the next character is LWS, false if not 8047 */ 8048 function is_linear_whitespace() 8049 { 8050 return (bool) ($this->data[$this->position] === "\x09" 8051 || $this->data[$this->position] === "\x20" 8052 || ($this->data[$this->position] === "\x0A" 8053 && isset($this->data[$this->position + 1]) 8054 && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20"))); 8055 } 8056 8057 /** 8058 * Parse the HTTP version 8059 * 8060 * @access private 8061 */ 8062 function http_version() 8063 { 8064 if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/') 8065 { 8066 $len = strspn($this->data, '0123456789.', 5); 8067 $this->http_version = substr($this->data, 5, $len); 8068 $this->position += 5 + $len; 8069 if (substr_count($this->http_version, '.') <= 1) 8070 { 8071 $this->http_version = (float) $this->http_version; 8072 $this->position += strspn($this->data, "\x09\x20", $this->position); 8073 $this->state = 'status'; 8074 } 8075 else 8076 { 8077 $this->state = false; 8078 } 8079 } 8080 else 8081 { 8082 $this->state = false; 8083 } 8084 } 8085 8086 /** 8087 * Parse the status code 8088 * 8089 * @access private 8090 */ 8091 function status() 8092 { 8093 if ($len = strspn($this->data, '0123456789', $this->position)) 8094 { 8095 $this->status_code = (int) substr($this->data, $this->position, $len); 8096 $this->position += $len; 8097 $this->state = 'reason'; 8098 } 8099 else 8100 { 8101 $this->state = false; 8102 } 8103 } 8104 8105 /** 8106 * Parse the reason phrase 8107 * 8108 * @access private 8109 */ 8110 function reason() 8111 { 8112 $len = strcspn($this->data, "\x0A", $this->position); 8113 $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20"); 8114 $this->position += $len + 1; 8115 $this->state = 'new_line'; 8116 } 8117 8118 /** 8119 * Deal with a new line, shifting data around as needed 8120 * 8121 * @access private 8122 */ 8123 function new_line() 8124 { 8125 $this->value = trim($this->value, "\x0D\x20"); 8126 if ($this->name !== '' && $this->value !== '') 8127 { 8128 $this->name = strtolower($this->name); 8129 if (isset($this->headers[$this->name])) 8130 { 8131 $this->headers[$this->name] .= ', ' . $this->value; 8132 } 8133 else 8134 { 8135 $this->headers[$this->name] = $this->value; 8136 } 8137 } 8138 $this->name = ''; 8139 $this->value = ''; 8140 if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A") 8141 { 8142 $this->position += 2; 8143 $this->state = 'body'; 8144 } 8145 elseif ($this->data[$this->position] === "\x0A") 8146 { 8147 $this->position++; 8148 $this->state = 'body'; 8149 } 8150 else 8151 { 8152 $this->state = 'name'; 8153 } 8154 } 8155 8156 /** 8157 * Parse a header name 8158 * 8159 * @access private 8160 */ 8161 function name() 8162 { 8163 $len = strcspn($this->data, "\x0A:", $this->position); 8164 if (isset($this->data[$this->position + $len])) 8165 { 8166 if ($this->data[$this->position + $len] === "\x0A") 8167 { 8168 $this->position += $len; 8169 $this->state = 'new_line'; 8170 } 8171 else 8172 { 8173 $this->name = substr($this->data, $this->position, $len); 8174 $this->position += $len + 1; 8175 $this->state = 'value'; 8176 } 8177 } 8178 else 8179 { 8180 $this->state = false; 8181 } 8182 } 8183 8184 /** 8185 * Parse LWS, replacing consecutive LWS characters with a single space 8186 * 8187 * @access private 8188 */ 8189 function linear_whitespace() 8190 { 8191 do 8192 { 8193 if (substr($this->data, $this->position, 2) === "\x0D\x0A") 8194 { 8195 $this->position += 2; 8196 } 8197 elseif ($this->data[$this->position] === "\x0A") 8198 { 8199 $this->position++; 8200 } 8201 $this->position += strspn($this->data, "\x09\x20", $this->position); 8202 } while ($this->has_data() && $this->is_linear_whitespace()); 8203 $this->value .= "\x20"; 8204 } 8205 8206 /** 8207 * See what state to move to while within non-quoted header values 8208 * 8209 * @access private 8210 */ 8211 function value() 8212 { 8213 if ($this->is_linear_whitespace()) 8214 { 8215 $this->linear_whitespace(); 8216 } 8217 else 8218 { 8219 switch ($this->data[$this->position]) 8220 { 8221 case '"': 8222 $this->position++; 8223 $this->state = 'quote'; 8224 break; 8225 8226 case "\x0A": 8227 $this->position++; 8228 $this->state = 'new_line'; 8229 break; 8230 8231 default: 8232 $this->state = 'value_char'; 8233 break; 8234 } 8235 } 8236 } 8237 8238 /** 8239 * Parse a header value while outside quotes 8240 * 8241 * @access private 8242 */ 8243 function value_char() 8244 { 8245 $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position); 8246 $this->value .= substr($this->data, $this->position, $len); 8247 $this->position += $len; 8248 $this->state = 'value'; 8249 } 8250 8251 /** 8252 * See what state to move to while within quoted header values 8253 * 8254 * @access private 8255 */ 8256 function quote() 8257 { 8258 if ($this->is_linear_whitespace()) 8259 { 8260 $this->linear_whitespace(); 8261 } 8262 else 8263 { 8264 switch ($this->data[$this->position]) 8265 { 8266 case '"': 8267 $this->position++; 8268 $this->state = 'value'; 8269 break; 8270 8271 case "\x0A": 8272 $this->position++; 8273 $this->state = 'new_line'; 8274 break; 8275 8276 case '\\': 8277 $this->position++; 8278 $this->state = 'quote_escaped'; 8279 break; 8280 8281 default: 8282 $this->state = 'quote_char'; 8283 break; 8284 } 8285 } 8286 } 8287 8288 /** 8289 * Parse a header value while within quotes 8290 * 8291 * @access private 8292 */ 8293 function quote_char() 8294 { 8295 $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position); 8296 $this->value .= substr($this->data, $this->position, $len); 8297 $this->position += $len; 8298 $this->state = 'value'; 8299 } 8300 8301 /** 8302 * Parse an escaped character within quotes 8303 * 8304 * @access private 8305 */ 8306 function quote_escaped() 8307 { 8308 $this->value .= $this->data[$this->position]; 8309 $this->position++; 8310 $this->state = 'quote'; 8311 } 8312 8313 /** 8314 * Parse the body 8315 * 8316 * @access private 8317 */ 8318 function body() 8319 { 8320 $this->body = substr($this->data, $this->position); 8321 $this->state = 'emit'; 8322 } 8323 } 8324 8325 /** 8326 * gzdecode 8327 * 8328 * @package SimplePie 8329 */ 8330 class SimplePie_gzdecode 8331 { 8332 /** 8333 * Compressed data 8334 * 8335 * @access private 8336 * @see gzdecode::$data 8337 */ 8338 var $compressed_data; 8339 8340 /** 8341 * Size of compressed data 8342 * 8343 * @access private 8344 */ 8345 var $compressed_size; 8346 8347 /** 8348 * Minimum size of a valid gzip string 8349 * 8350 * @access private 8351 */ 8352 var $min_compressed_size = 18; 8353 8354 /** 8355 * Current position of pointer 8356 * 8357 * @access private 8358 */ 8359 var $position = 0; 8360 8361 /** 8362 * Flags (FLG) 8363 * 8364 * @access private 8365 */ 8366 var $flags; 8367 8368 /** 8369 * Uncompressed data 8370 * 8371 * @access public 8372 * @see gzdecode::$compressed_data 8373 */ 8374 var $data; 8375 8376 /** 8377 * Modified time 8378 * 8379 * @access public 8380 */ 8381 var $MTIME; 8382 8383 /** 8384 * Extra Flags 8385 * 8386 * @access public 8387 */ 8388 var $XFL; 8389 8390 /** 8391 * Operating System 8392 * 8393 * @access public 8394 */ 8395 var $OS; 8396 8397 /** 8398 * Subfield ID 1 8399 * 8400 * @access public 8401 * @see gzdecode::$extra_field 8402 * @see gzdecode::$SI2 8403 */ 8404 var $SI1; 8405 8406 /** 8407 * Subfield ID 2 8408 * 8409 * @access public 8410 * @see gzdecode::$extra_field 8411 * @see gzdecode::$SI1 8412 */ 8413 var $SI2; 8414 8415 /** 8416 * Extra field content 8417 * 8418 * @access public 8419 * @see gzdecode::$SI1 8420 * @see gzdecode::$SI2 8421 */ 8422 var $extra_field; 8423 8424 /** 8425 * Original filename 8426 * 8427 * @access public 8428 */ 8429 var $filename; 8430 8431 /** 8432 * Human readable comment 8433 * 8434 * @access public 8435 */ 8436 var $comment; 8437 8438 /** 8439 * Don't allow anything to be set 8440 * 8441 * @access public 8442 */ 8443 function __set($name, $value) 8444 { 8445 trigger_error("Cannot write property $name", E_USER_ERROR); 8446 } 8447 8448 /** 8449 * Set the compressed string and related properties 8450 * 8451 * @access public 8452 */ 8453 function SimplePie_gzdecode($data) 8454 { 8455 $this->compressed_data = $data; 8456 $this->compressed_size = strlen($data); 8457 } 8458 8459 /** 8460 * Decode the GZIP stream 8461 * 8462 * @access public 8463 */ 8464 function parse() 8465 { 8466 if ($this->compressed_size >= $this->min_compressed_size) 8467 { 8468 // Check ID1, ID2, and CM 8469 if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08") 8470 { 8471 return false; 8472 } 8473 8474 // Get the FLG (FLaGs) 8475 $this->flags = ord($this->compressed_data[3]); 8476 8477 // FLG bits above (1 << 4) are reserved 8478 if ($this->flags > 0x1F) 8479 { 8480 return false; 8481 } 8482 8483 // Advance the pointer after the above 8484 $this->position += 4; 8485 8486 // MTIME 8487 $mtime = substr($this->compressed_data, $this->position, 4); 8488 // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness 8489 if (current(unpack('S', "\x00\x01")) === 1) 8490 { 8491 $mtime = strrev($mtime); 8492 } 8493 $this->MTIME = current(unpack('l', $mtime)); 8494 $this->position += 4; 8495 8496 // Get the XFL (eXtra FLags) 8497 $this->XFL = ord($this->compressed_data[$this->position++]); 8498 8499 // Get the OS (Operating System) 8500 $this->OS = ord($this->compressed_data[$this->position++]); 8501 8502 // Parse the FEXTRA 8503 if ($this->flags & 4) 8504 { 8505 // Read subfield IDs 8506 $this->SI1 = $this->compressed_data[$this->position++]; 8507 $this->SI2 = $this->compressed_data[$this->position++]; 8508 8509 // SI2 set to zero is reserved for future use 8510 if ($this->SI2 === "\x00") 8511 { 8512 return false; 8513 } 8514 8515 // Get the length of the extra field 8516 $len = current(unpack('v', substr($this->compressed_data, $this->position, 2))); 8517 $position += 2; 8518 8519 // Check the length of the string is still valid 8520 $this->min_compressed_size += $len + 4; 8521 if ($this->compressed_size >= $this->min_compressed_size) 8522 { 8523 // Set the extra field to the given data 8524 $this->extra_field = substr($this->compressed_data, $this->position, $len); 8525 $this->position += $len; 8526 } 8527 else 8528 { 8529 return false; 8530 } 8531 } 8532 8533 // Parse the FNAME 8534 if ($this->flags & 8) 8535 { 8536 // Get the length of the filename 8537 $len = strcspn($this->compressed_data, "\x00", $this->position); 8538 8539 // Check the length of the string is still valid 8540 $this->min_compressed_size += $len + 1; 8541 if ($this->compressed_size >= $this->min_compressed_size) 8542 { 8543 // Set the original filename to the given string 8544 $this->filename = substr($this->compressed_data, $this->position, $len); 8545 $this->position += $len + 1; 8546 } 8547 else 8548 { 8549 return false; 8550 } 8551 } 8552 8553 // Parse the FCOMMENT 8554 if ($this->flags & 16) 8555 { 8556 // Get the length of the comment 8557 $len = strcspn($this->compressed_data, "\x00", $this->position); 8558 8559 // Check the length of the string is still valid 8560 $this->min_compressed_size += $len + 1; 8561 if ($this->compressed_size >= $this->min_compressed_size) 8562 { 8563 // Set the original comment to the given string 8564 $this->comment = substr($this->compressed_data, $this->position, $len); 8565 $this->position += $len + 1; 8566 } 8567 else 8568 { 8569 return false; 8570 } 8571 } 8572 8573 // Parse the FHCRC 8574 if ($this->flags & 2) 8575 { 8576 // Check the length of the string is still valid 8577 $this->min_compressed_size += $len + 2; 8578 if ($this->compressed_size >= $this->min_compressed_size) 8579 { 8580 // Read the CRC 8581 $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2))); 8582 8583 // Check the CRC matches 8584 if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc) 8585 { 8586 $this->position += 2; 8587 } 8588 else 8589 { 8590 return false; 8591 } 8592 } 8593 else 8594 { 8595 return false; 8596 } 8597 } 8598 8599 // Decompress the actual data 8600 if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false) 8601 { 8602 return false; 8603 } 8604 else 8605 { 8606 $this->position = $this->compressed_size - 8; 8607 } 8608 8609 // Check CRC of data 8610 $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4))); 8611 $this->position += 4; 8612 /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc)) 8613 { 8614 return false; 8615 }*/ 8616 8617 // Check ISIZE of data 8618 $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4))); 8619 $this->position += 4; 8620 if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize)) 8621 { 8622 return false; 8623 } 8624 8625 // Wow, against all odds, we've actually got a valid gzip string 8626 return true; 8627 } 8628 else 8629 { 8630 return false; 8631 } 8632 } 8633 } 8634 8635 class SimplePie_Cache 8636 { 8637 /** 8638 * Don't call the constructor. Please. 8639 * 8640 * @access private 8641 */ 8642 function SimplePie_Cache() 8643 { 8644 trigger_error('Please call SimplePie_Cache::create() instead of the constructor', E_USER_ERROR); 8645 } 8646 8647 /** 8648 * Create a new SimplePie_Cache object 8649 * 8650 * @static 8651 * @access public 8652 */ 8653 function create($location, $filename, $extension) 8654 { 8655 $location_iri =& new SimplePie_IRI($location); 8656 switch ($location_iri->get_scheme()) 8657 { 8658 case 'mysql': 8659 if (extension_loaded('mysql')) 8660 { 8661 return new SimplePie_Cache_MySQL($location_iri, $filename, $extension); 8662 } 8663 break; 8664 8665 default: 8666 return new SimplePie_Cache_File($location, $filename, $extension); 8667 } 8668 } 8669 } 8670 8671 class SimplePie_Cache_File 8672 { 8673 var $location; 8674 var $filename; 8675 var $extension; 8676 var $name; 8677 8678 function SimplePie_Cache_File($location, $filename, $extension) 8679 { 8680 $this->location = $location; 8681 $this->filename = $filename; 8682 $this->extension = $extension; 8683 $this->name = "$this->location/$this->filename.$this->extension"; 8684 } 8685 8686 function save($data) 8687 { 8688 if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location)) 8689 { 8690 if (is_a($data, 'SimplePie')) 8691 { 8692 $data = $data->data; 8693 } 8694 8695 $data = serialize($data); 8696 8697 if (function_exists('file_put_contents')) 8698 { 8699 return (bool) file_put_contents($this->name, $data); 8700 } 8701 else 8702 { 8703 $fp = fopen($this->name, 'wb'); 8704 if ($fp) 8705 { 8706 fwrite($fp, $data); 8707 fclose($fp); 8708 return true; 8709 } 8710 } 8711 } 8712 return false; 8713 } 8714 8715 function load() 8716 { 8717 if (file_exists($this->name) && is_readable($this->name)) 8718 { 8719 return unserialize(file_get_contents($this->name)); 8720 } 8721 return false; 8722 } 8723 8724 function mtime() 8725 { 8726 if (file_exists($this->name)) 8727 { 8728 return filemtime($this->name); 8729 } 8730 return false; 8731 } 8732 8733 function touch() 8734 { 8735 if (file_exists($this->name)) 8736 { 8737 return touch($this->name); 8738 } 8739 return false; 8740 } 8741 8742 function unlink() 8743 { 8744 if (file_exists($this->name)) 8745 { 8746 return unlink($this->name); 8747 } 8748 return false; 8749 } 8750 } 8751 8752 class SimplePie_Cache_DB 8753 { 8754 function prepare_simplepie_object_for_cache($data) 8755 { 8756 $items = $data->get_items(); 8757 $items_by_id = array(); 8758 8759 if (!empty($items)) 8760 { 8761 foreach ($items as $item) 8762 { 8763 $items_by_id[$item->get_id()] = $item; 8764 } 8765 8766 if (count($items_by_id) !== count($items)) 8767 { 8768 $items_by_id = array(); 8769 foreach ($items as $item) 8770 { 8771 $items_by_id[$item->get_id(true)] = $item; 8772 } 8773 } 8774 8775 if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0])) 8776 { 8777 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]; 8778 } 8779 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0])) 8780 { 8781 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]; 8782 } 8783 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0])) 8784 { 8785 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]; 8786 } 8787 elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0])) 8788 { 8789 $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]; 8790 } 8791 else 8792 { 8793 $channel = null; 8794 } 8795 8796 if ($channel !== null) 8797 { 8798 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'])) 8799 { 8800 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']); 8801 } 8802 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry'])) 8803 { 8804 unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']); 8805 } 8806 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])) 8807 { 8808 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']); 8809 } 8810 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])) 8811 { 8812 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']); 8813 } 8814 if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item'])) 8815 { 8816 unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']); 8817 } 8818 } 8819 if (isset($data->data['items'])) 8820 { 8821 unset($data->data['items']); 8822 } 8823 if (isset($data->data['ordered_items'])) 8824 { 8825 unset($data->data['ordered_items']); 8826 } 8827 } 8828 return array(serialize($data->data), $items_by_id); 8829 } 8830 } 8831 8832 class SimplePie_Cache_MySQL extends SimplePie_Cache_DB 8833 { 8834 var $mysql; 8835 var $options; 8836 var $id; 8837 8838 function SimplePie_Cache_MySQL($mysql_location, $name, $extension) 8839 { 8840 $host = $mysql_location->get_host(); 8841 if (SimplePie_Misc::stripos($host, 'unix(') === 0 && substr($host, -1) === ')') 8842 { 8843 $server = ':' . substr($host, 5, -1); 8844 } 8845 else 8846 { 8847 $server = $host; 8848 if ($mysql_location->get_port() !== null) 8849 { 8850 $server .= ':' . $mysql_location->get_port(); 8851 } 8852 } 8853 8854 if (strpos($mysql_location->get_userinfo(), ':') !== false) 8855 { 8856 list($username, $password) = explode(':', $mysql_location->get_userinfo(), 2); 8857 } 8858 else 8859 { 8860 $username = $mysql_location->get_userinfo(); 8861 $password = null; 8862 } 8863 8864 if ($this->mysql = mysql_connect($server, $username, $password)) 8865 { 8866 $this->id = $name . $extension; 8867 $this->options = SimplePie_Misc::parse_str($mysql_location->get_query()); 8868 if (!isset($this->options['prefix'][0])) 8869 { 8870 $this->options['prefix'][0] = ''; 8871 } 8872 8873 if (mysql_select_db(ltrim($mysql_location->get_path(), '/')) 8874 && mysql_query('SET NAMES utf8') 8875 && ($query = mysql_unbuffered_query('SHOW TABLES'))) 8876 { 8877 $db = array(); 8878 while ($row = mysql_fetch_row($query)) 8879 { 8880 $db[] = $row[0]; 8881 } 8882 8883 if (!in_array($this->options['prefix'][0] . 'cache_data', $db)) 8884 { 8885 if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))')) 8886 { 8887 $this->mysql = null; 8888 } 8889 } 8890 8891 if (!in_array($this->options['prefix'][0] . 'items', $db)) 8892 { 8893 if (!mysql_query('CREATE TABLE `' . $this->options['prefix'][0] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` TEXT CHARACTER SET utf8 NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))')) 8894 { 8895 $this->mysql = null; 8896 } 8897 } 8898 } 8899 else 8900 { 8901 $this->mysql = null; 8902 } 8903 } 8904 } 8905 8906 function save($data) 8907 { 8908 if ($this->mysql) 8909 { 8910 $feed_id = "'" . mysql_real_escape_string($this->id) . "'"; 8911 8912 if (is_a($data, 'SimplePie')) 8913 { 8914 if (SIMPLEPIE_PHP5) 8915 { 8916 // This keyword needs to defy coding standards for PHP4 compatibility 8917 $data = clone($data); 8918 } 8919 8920 $prepared = $this->prepare_simplepie_object_for_cache($data); 8921 8922 if ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql)) 8923 { 8924 if (mysql_num_rows($query)) 8925 { 8926 $items = count($prepared[1]); 8927 if ($items) 8928 { 8929 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = ' . $items . ', `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id; 8930 } 8931 else 8932 { 8933 $sql = 'UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `data` = \'' . mysql_real_escape_string($prepared[0]) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id; 8934 } 8935 8936 if (!mysql_query($sql, $this->mysql)) 8937 { 8938 return false; 8939 } 8940 } 8941 elseif (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(' . $feed_id . ', ' . count($prepared[1]) . ', \'' . mysql_real_escape_string($prepared[0]) . '\', ' . time() . ')', $this->mysql)) 8942 { 8943 return false; 8944 } 8945 8946 $ids = array_keys($prepared[1]); 8947 if (!empty($ids)) 8948 { 8949 foreach ($ids as $id) 8950 { 8951 $database_ids[] = mysql_real_escape_string($id); 8952 } 8953 8954 if ($query = mysql_unbuffered_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'items` WHERE `id` = \'' . implode('\' OR `id` = \'', $database_ids) . '\' AND `feed_id` = ' . $feed_id, $this->mysql)) 8955 { 8956 $existing_ids = array(); 8957 while ($row = mysql_fetch_row($query)) 8958 { 8959 $existing_ids[] = $row[0]; 8960 } 8961 8962 $new_ids = array_diff($ids, $existing_ids); 8963 8964 foreach ($new_ids as $new_id) 8965 { 8966 if (!($date = $prepared[1][$new_id]->get_date('U'))) 8967 { 8968 $date = time(); 8969 } 8970 8971 if (!mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(' . $feed_id . ', \'' . mysql_real_escape_string($new_id) . '\', \'' . mysql_real_escape_string(serialize($prepared[1][$new_id]->data)) . '\', ' . $date . ')', $this->mysql)) 8972 { 8973 return false; 8974 } 8975 } 8976 return true; 8977 } 8978 } 8979 else 8980 { 8981 return true; 8982 } 8983 } 8984 } 8985 elseif ($query = mysql_query('SELECT `id` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = ' . $feed_id, $this->mysql)) 8986 { 8987 if (mysql_num_rows($query)) 8988 { 8989 if (mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `items` = 0, `data` = \'' . mysql_real_escape_string(serialize($data)) . '\', `mtime` = ' . time() . ' WHERE `id` = ' . $feed_id, $this->mysql)) 8990 { 8991 return true; 8992 } 8993 } 8994 elseif (mysql_query('INSERT INTO `' . $this->options['prefix'][0] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(\'' . mysql_real_escape_string($this->id) . '\', 0, \'' . mysql_real_escape_string(serialize($data)) . '\', ' . time() . ')', $this->mysql)) 8995 { 8996 return true; 8997 } 8998 } 8999 } 9000 return false; 9001 } 9002 9003 function load() 9004 { 9005 if ($this->mysql && ($query = mysql_query('SELECT `items`, `data` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query))) 9006 { 9007 $data = unserialize($row[1]); 9008 9009 if (isset($this->options['items'][0])) 9010 { 9011 $items = (int) $this->options['items'][0]; 9012 } 9013 else 9014 { 9015 $items = (int) $row[0]; 9016 } 9017 9018 if ($items !== 0) 9019 { 9020 if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0])) 9021 { 9022 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]; 9023 } 9024 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0])) 9025 { 9026 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]; 9027 } 9028 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0])) 9029 { 9030 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]; 9031 } 9032 elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0])) 9033 { 9034 $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]; 9035 } 9036 else 9037 { 9038 $feed = null; 9039 } 9040 9041 if ($feed !== null) 9042 { 9043 $sql = 'SELECT `data` FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . '\' ORDER BY `posted` DESC'; 9044 if ($items > 0) 9045 { 9046 $sql .= ' LIMIT ' . $items; 9047 } 9048 9049 if ($query = mysql_unbuffered_query($sql, $this->mysql)) 9050 { 9051 while ($row = mysql_fetch_row($query)) 9052 { 9053 $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row[0]); 9054 } 9055 } 9056 else 9057 { 9058 return false; 9059 } 9060 } 9061 } 9062 return $data; 9063 } 9064 return false; 9065 } 9066 9067 function mtime() 9068 { 9069 if ($this->mysql && ($query = mysql_query('SELECT `mtime` FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($row = mysql_fetch_row($query))) 9070 { 9071 return $row[0]; 9072 } 9073 else 9074 { 9075 return false; 9076 } 9077 } 9078 9079 function touch() 9080 { 9081 if ($this->mysql && ($query = mysql_query('UPDATE `' . $this->options['prefix'][0] . 'cache_data` SET `mtime` = ' . time() . ' WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && mysql_affected_rows($this->mysql)) 9082 { 9083 return true; 9084 } 9085 else 9086 { 9087 return false; 9088 } 9089 } 9090 9091 function unlink() 9092 { 9093 if ($this->mysql && ($query = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'cache_data` WHERE `id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql)) && ($query2 = mysql_query('DELETE FROM `' . $this->options['prefix'][0] . 'items` WHERE `feed_id` = \'' . mysql_real_escape_string($this->id) . "'", $this->mysql))) 9094 { 9095 return true; 9096 } 9097 else 9098 { 9099 return false; 9100 } 9101 } 9102 } 9103 9104 class SimplePie_Misc 9105 { 9106 function time_hms($seconds) 9107 { 9108 $time = ''; 9109 9110 $hours = floor($seconds / 3600); 9111 $remainder = $seconds % 3600; 9112 if ($hours > 0) 9113 { 9114 $time .= $hours.':'; 9115 } 9116 9117 $minutes = floor($remainder / 60); 9118 $seconds = $remainder % 60; 9119 if ($minutes < 10 && $hours > 0) 9120 { 9121 $minutes = '0' . $minutes; 9122 } 9123 if ($seconds < 10) 9124 { 9125 $seconds = '0' . $seconds; 9126 } 9127 9128 $time .= $minutes.':'; 9129 $time .= $seconds; 9130 9131 return $time; 9132 } 9133 9134 function absolutize_url($relative, $base) 9135 { 9136 $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative); 9137 return $iri->get_iri(); 9138 } 9139 9140 function remove_dot_segments($input) 9141 { 9142 $output = ''; 9143 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..') 9144 { 9145 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise, 9146 if (strpos($input, '../') === 0) 9147 { 9148 $input = substr($input, 3); 9149 } 9150 elseif (strpos($input, './') === 0) 9151 { 9152 $input = substr($input, 2); 9153 } 9154 // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise, 9155 elseif (strpos($input, '/./') === 0) 9156 { 9157 $input = substr_replace($input, '/', 0, 3); 9158 } 9159 elseif ($input === '/.') 9160 { 9161 $input = '/'; 9162 } 9163 // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise, 9164 elseif (strpos($input, '/../') === 0) 9165 { 9166 $input = substr_replace($input, '/', 0, 4); 9167 $output = substr_replace($output, '', strrpos($output, '/')); 9168 } 9169 elseif ($input === '/..') 9170 { 9171 $input = '/'; 9172 $output = substr_replace($output, '', strrpos($output, '/')); 9173 } 9174 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise, 9175 elseif ($input === '.' || $input === '..') 9176 { 9177 $input = ''; 9178 } 9179 // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer 9180 elseif (($pos = strpos($input, '/', 1)) !== false) 9181 { 9182 $output .= substr($input, 0, $pos); 9183 $input = substr_replace($input, '', 0, $pos); 9184 } 9185 else 9186 { 9187 $output .= $input; 9188 $input = ''; 9189 } 9190 } 9191 return $output . $input; 9192 } 9193 9194 function get_element($realname, $string) 9195 { 9196 $return = array(); 9197 $name = preg_quote($realname, '/'); 9198 if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) 9199 { 9200 for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++) 9201 { 9202 $return[$i]['tag'] = $realname; 9203 $return[$i]['full'] = $matches[$i][0][0]; 9204 $return[$i]['offset'] = $matches[$i][0][1]; 9205 if (strlen($matches[$i][3][0]) <= 2) 9206 { 9207 $return[$i]['self_closing'] = true; 9208 } 9209 else 9210 { 9211 $return[$i]['self_closing'] = false; 9212 $return[$i]['content'] = $matches[$i][4][0]; 9213 } 9214 $return[$i]['attribs'] = array(); 9215 if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER)) 9216 { 9217 for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++) 9218 { 9219 if (count($attribs[$j]) === 2) 9220 { 9221 $attribs[$j][2] = $attribs[$j][1]; 9222 } 9223 $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]), 'UTF-8'); 9224 } 9225 } 9226 } 9227 } 9228 return $return; 9229 } 9230 9231 function element_implode($element) 9232 { 9233 $full = "<$element[tag]"; 9234 foreach ($element['attribs'] as $key => $value) 9235 { 9236 $key = strtolower($key); 9237 $full .= " $key=\"" . htmlspecialchars($value['data']) . '"'; 9238 } 9239 if ($element['self_closing']) 9240 { 9241 $full .= ' />'; 9242 } 9243 else 9244 { 9245 $full .= ">$element[content]</$element[tag]>"; 9246 } 9247 return $full; 9248 } 9249 9250 function error($message, $level, $file, $line) 9251 { 9252 if ((ini_get('error_reporting') & $level) > 0) 9253 { 9254 switch ($level) 9255 { 9256 case E_USER_ERROR: 9257 $note = 'PHP Error'; 9258 break; 9259 case E_USER_WARNING: 9260 $note = 'PHP Warning'; 9261 break; 9262 case E_USER_NOTICE: 9263 $note = 'PHP Notice'; 9264 break; 9265 default: 9266 $note = 'Unknown Error'; 9267 break; 9268 } 9269 9270 $log_error = true; 9271 if (!function_exists('error_log')) 9272 { 9273 $log_error = false; 9274 } 9275 9276 $log_file = @ini_get('error_log'); 9277 if (!empty($log_file) && ('syslog' != $log_file) && !@is_writable($log_file)) 9278 { 9279 $log_error = false; 9280 } 9281 9282 if ($log_error) 9283 { 9284 @error_log("$note: $message in $file on line $line", 0); 9285 } 9286 } 9287 return $message; 9288 } 9289 9290 /** 9291 * If a file has been cached, retrieve and display it. 9292 * 9293 * This is most useful for caching images (get_favicon(), etc.), 9294 * however it works for all cached files. This WILL NOT display ANY 9295 * file/image/page/whatever, but rather only display what has already 9296 * been cached by SimplePie. 9297 * 9298 * @access public 9299 * @see SimplePie::get_favicon() 9300 * @param str $identifier_url URL that is used to identify the content. 9301 * This may or may not be the actual URL of the live content. 9302 * @param str $cache_location Location of SimplePie's cache. Defaults 9303 * to './cache'. 9304 * @param str $cache_extension The file extension that the file was 9305 * cached with. Defaults to 'spc'. 9306 * @param str $cache_class Name of the cache-handling class being used 9307 * in SimplePie. Defaults to 'SimplePie_Cache', and should be left 9308 * as-is unless you've overloaded the class. 9309 * @param str $cache_name_function Obsolete. Exists for backwards 9310 * compatibility reasons only. 9311 */ 9312 function display_cached_file($identifier_url, $cache_location = './cache', $cache_extension = 'spc', $cache_class = 'SimplePie_Cache', $cache_name_function = 'md5') 9313 { 9314 $cache = call_user_func(array($cache_class, 'create'), $cache_location, $identifier_url, $cache_extension); 9315 9316 if ($file = $cache->load()) 9317 { 9318 if (isset($file['headers']['content-type'])) 9319 { 9320 header('Content-type:' . $file['headers']['content-type']); 9321 } 9322 else 9323 { 9324 header('Content-type: application/octet-stream'); 9325 } 9326 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days 9327 echo $file['body']; 9328 exit; 9329 } 9330 9331 die('Cached file for ' . $identifier_url . ' cannot be found.'); 9332 } 9333 9334 function fix_protocol($url, $http = 1) 9335 { 9336 $url = SimplePie_Misc::normalize_url($url); 9337 $parsed = SimplePie_Misc::parse_url($url); 9338 if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https') 9339 { 9340 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http); 9341 } 9342 9343 if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url)) 9344 { 9345 return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http); 9346 } 9347 9348 if ($http === 2 && $parsed['scheme'] !== '') 9349 { 9350 return "feed:$url"; 9351 } 9352 elseif ($http === 3 && strtolower($parsed['scheme']) === 'http') 9353 { 9354 return substr_replace($url, 'podcast', 0, 4); 9355 } 9356 elseif ($http === 4 && strtolower($parsed['scheme']) === 'http') 9357 { 9358 return substr_replace($url, 'itpc', 0, 4); 9359 } 9360 else 9361 { 9362 return $url; 9363 } 9364 } 9365 9366 function parse_url($url) 9367 { 9368 $iri =& new SimplePie_IRI($url); 9369 return array( 9370 'scheme' => (string) $iri->get_scheme(), 9371 'authority' => (string) $iri->get_authority(), 9372 'path' => (string) $iri->get_path(), 9373 'query' => (string) $iri->get_query(), 9374 'fragment' => (string) $iri->get_fragment() 9375 ); 9376 } 9377 9378 function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '') 9379 { 9380 $iri =& new SimplePie_IRI(''); 9381 $iri->set_scheme($scheme); 9382 $iri->set_authority($authority); 9383 $iri->set_path($path); 9384 $iri->set_query($query); 9385 $iri->set_fragment($fragment); 9386 return $iri->get_iri(); 9387 } 9388 9389 function normalize_url($url) 9390 { 9391 $iri =& new SimplePie_IRI($url); 9392 return $iri->get_iri(); 9393 } 9394 9395 function percent_encoding_normalization($match) 9396 { 9397 $integer = hexdec($match[1]); 9398 if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E) 9399 { 9400 return chr($integer); 9401 } 9402 else 9403 { 9404 return strtoupper($match[0]); 9405 } 9406 } 9407 9408 /** 9409 * Remove bad UTF-8 bytes 9410 * 9411 * PCRE Pattern to locate bad bytes in a UTF-8 string comes from W3C 9412 * FAQ: Multilingual Forms (modified to include full ASCII range) 9413 * 9414 * @author Geoffrey Sneddon 9415 * @see http://www.w3.org/International/questions/qa-forms-utf-8 9416 * @param string $str String to remove bad UTF-8 bytes from 9417 * @return string UTF-8 string 9418 */ 9419 function utf8_bad_replace($str) 9420 { 9421 if (function_exists('iconv') && ($return = @iconv('UTF-8', 'UTF-8//IGNORE', $str))) 9422 { 9423 return $return; 9424 } 9425 elseif (function_exists('mb_convert_encoding') && ($return = @mb_convert_encoding($str, 'UTF-8', 'UTF-8'))) 9426 { 9427 return $return; 9428 } 9429 elseif (preg_match_all('/(?:[\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})+/', $str, $matches)) 9430 { 9431 return implode("\xEF\xBF\xBD", $matches[0]); 9432 } 9433 elseif ($str !== '') 9434 { 9435 return "\xEF\xBF\xBD"; 9436 } 9437 else 9438 { 9439 return ''; 9440 } 9441 } 9442 9443 /** 9444 * Converts a Windows-1252 encoded string to a UTF-8 encoded string 9445 * 9446 * @static 9447 * @access public 9448 * @param string $string Windows-1252 encoded string 9449 * @return string UTF-8 encoded string 9450 */ 9451 function windows_1252_to_utf8($string) 9452 { 9453 static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF"); 9454 9455 return strtr($string, $convert_table); 9456 } 9457 9458 function change_encoding($data, $input, $output) 9459 { 9460 $input = SimplePie_Misc::encoding($input); 9461 $output = SimplePie_Misc::encoding($output); 9462 9463 // We fail to fail on non US-ASCII bytes 9464 if ($input === 'US-ASCII') 9465 { 9466 static $non_ascii_octects = ''; 9467 if (!$non_ascii_octects) 9468 { 9469 for ($i = 0x80; $i <= 0xFF; $i++) 9470 { 9471 $non_ascii_octects .= chr($i); 9472 } 9473 } 9474 $data = substr($data, 0, strcspn($data, $non_ascii_octects)); 9475 } 9476 9477 // This is first, as behaviour of this is completely predictable 9478 if ($input === 'windows-1252' && $output === 'UTF-8') 9479 { 9480 return SimplePie_Misc::windows_1252_to_utf8($data); 9481 } 9482 // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported). 9483 elseif (function_exists('mb_convert_encoding') && @mb_convert_encoding("\x80", 'UTF-16BE', $input) !== "\x00\x80" && ($return = @mb_convert_encoding($data, $output, $input))) 9484 { 9485 return $return; 9486 } 9487 // This is last, as behaviour of this varies with OS userland and PHP version 9488 elseif (function_exists('iconv') && ($return = @iconv($input, $output, $data))) 9489 { 9490 return $return; 9491 } 9492 // If we can't do anything, just fail 9493 else 9494 { 9495 return false; 9496 } 9497 } 9498 9499 /** 9500 * Normalize an encoding name 9501 * 9502 * This is automatically generated by create.php 9503 * 9504 * To generate it, run `php create.php` on the command line, and copy the 9505 * output to replace this function. 9506 * 9507 * @param string $charset Character set to standardise 9508 * @return string Standardised name 9509 */ 9510 function encoding($charset) 9511 { 9512 // Normalization from UTS #22 9513 switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset))) 9514 { 9515 case 'adobestandardencoding': 9516 case 'csadobestandardencoding': 9517 return 'Adobe-Standard-Encoding'; 9518 9519 case 'adobesymbolencoding': 9520 case 'cshppsmath': 9521 return 'Adobe-Symbol-Encoding'; 9522 9523 case 'ami1251': 9524 case 'amiga1251': 9525 return 'Amiga-1251'; 9526 9527 case 'ansix31101983': 9528 case 'csat5001983': 9529 case 'csiso99naplps': 9530 case 'isoir99': 9531 case 'naplps': 9532 return 'ANSI_X3.110-1983'; 9533 9534 case 'arabic7': 9535 case 'asmo449': 9536 case 'csiso89asmo449': 9537 case 'iso9036': 9538 case 'isoir89': 9539 return 'ASMO_449'; 9540 9541 case 'big5': 9542 case 'csbig5': 9543 return 'Big5'; 9544 9545 case 'big5hkscs': 9546 return 'Big5-HKSCS'; 9547 9548 case 'bocu1': 9549 case 'csbocu1': 9550 return 'BOCU-1'; 9551 9552 case 'brf': 9553 case 'csbrf': 9554 return 'BRF'; 9555 9556 case 'bs4730': 9557 case 'csiso4unitedkingdom': 9558 case 'gb': 9559 case 'iso646gb': 9560 case 'isoir4': 9561 case 'uk': 9562 return 'BS_4730'; 9563 9564 case 'bsviewdata': 9565 case 'csiso47bsviewdata': 9566 case 'isoir47': 9567 return 'BS_viewdata'; 9568 9569 case 'cesu8': 9570 case 'cscesu8': 9571 return 'CESU-8'; 9572 9573 case 'ca': 9574 case 'csa71': 9575 case 'csaz243419851': 9576 case 'csiso121canadian1': 9577 case 'iso646ca': 9578 case 'isoir121': 9579 return 'CSA_Z243.4-1985-1'; 9580 9581 case 'csa72': 9582 case 'csaz243419852': 9583 case 'csiso122canadian2': 9584 case 'iso646ca2': 9585 case 'isoir122': 9586 return 'CSA_Z243.4-1985-2'; 9587 9588 case 'csaz24341985gr': 9589 case 'csiso123csaz24341985gr': 9590 case 'isoir123': 9591 return 'CSA_Z243.4-1985-gr'; 9592 9593 case 'csiso139csn369103': 9594 case 'csn369103': 9595 case 'isoir139': 9596 return 'CSN_369103'; 9597 9598 case 'csdecmcs': 9599 case 'dec': 9600 case 'decmcs': 9601 return 'DEC-MCS'; 9602 9603 case 'csiso21german': 9604 case 'de': 9605 case 'din66003': 9606 case 'iso646de': 9607 case 'isoir21': 9608 return 'DIN_66003'; 9609 9610 case 'csdkus': 9611 case 'dkus': 9612 return 'dk-us'; 9613 9614 case 'csiso646danish': 9615 case 'dk': 9616 case 'ds2089': 9617 case 'iso646dk': 9618 return 'DS_2089'; 9619 9620 case 'csibmebcdicatde': 9621 case 'ebcdicatde': 9622 return 'EBCDIC-AT-DE'; 9623 9624 case 'csebcdicatdea': 9625 case 'ebcdicatdea': 9626 return 'EBCDIC-AT-DE-A'; 9627 9628 case 'csebcdiccafr': 9629 case 'ebcdiccafr': 9630 return 'EBCDIC-CA-FR'; 9631 9632 case 'csebcdicdkno': 9633 case 'ebcdicdkno': 9634 return 'EBCDIC-DK-NO'; 9635 9636 case 'csebcdicdknoa': 9637 case 'ebcdicdknoa': 9638 return 'EBCDIC-DK-NO-A'; 9639 9640 case 'csebcdices': 9641 case 'ebcdices': 9642 return 'EBCDIC-ES'; 9643 9644 case 'csebcdicesa': 9645 case 'ebcdicesa': 9646 return 'EBCDIC-ES-A'; 9647 9648 case 'csebcdicess': 9649 case 'ebcdicess': 9650 return 'EBCDIC-ES-S'; 9651 9652 case 'csebcdicfise': 9653 case 'ebcdicfise': 9654 return 'EBCDIC-FI-SE'; 9655 9656 case 'csebcdicfisea': 9657 case 'ebcdicfisea': 9658 return 'EBCDIC-FI-SE-A'; 9659 9660 case 'csebcdicfr': 9661 case 'ebcdicfr': 9662 return 'EBCDIC-FR'; 9663 9664 case 'csebcdicit': 9665 case 'ebcdicit': 9666 return 'EBCDIC-IT'; 9667 9668 case 'csebcdicpt': 9669 case 'ebcdicpt': 9670 return 'EBCDIC-PT'; 9671 9672 case 'csebcdicuk': 9673 case 'ebcdicuk': 9674 return 'EBCDIC-UK'; 9675 9676 case 'csebcdicus': 9677 case 'ebcdicus': 9678 return 'EBCDIC-US'; 9679 9680 case 'csiso111ecmacyrillic': 9681 case 'ecmacyrillic': 9682 case 'isoir111': 9683 case 'koi8e': 9684 return 'ECMA-cyrillic'; 9685 9686 case 'csiso17spanish': 9687 case 'es': 9688 case 'iso646es': 9689 case 'isoir17': 9690 return 'ES'; 9691 9692 case 'csiso85spanish2': 9693 case 'es2': 9694 case 'iso646es2': 9695 case 'isoir85': 9696 return 'ES2'; 9697 9698 case 'cseucpkdfmtjapanese': 9699 case 'eucjp': 9700 case 'extendedunixcodepackedformatforjapanese': 9701 return 'EUC-JP'; 9702 9703 case 'cseucfixwidjapanese': 9704 case 'extendedunixcodefixedwidthforjapanese': 9705 return 'Extended_UNIX_Code_Fixed_Width_for_Japanese'; 9706 9707 case 'gb18030': 9708 return 'GB18030'; 9709 9710 case 'chinese': 9711 case 'cp936': 9712 case 'csgb2312': 9713 case 'csiso58gb231280': 9714 case 'gb2312': 9715 case 'gb231280': 9716 case 'gbk': 9717 case 'isoir58': 9718 case 'ms936': 9719 case 'windows936': 9720 return 'GBK'; 9721 9722 case 'cn': 9723 case 'csiso57gb1988': 9724 case 'gb198880': 9725 case 'iso646cn': 9726 case 'isoir57': 9727 return 'GB_1988-80'; 9728 9729 case 'csiso153gost1976874': 9730 case 'gost1976874': 9731 case 'isoir153': 9732 case 'stsev35888': 9733 return 'GOST_19768-74'; 9734 9735 case 'csiso150': 9736 case 'csiso150greekccitt': 9737 case 'greekccitt': 9738 case 'isoir150': 9739 return 'greek-ccitt'; 9740 9741 case 'csiso88greek7': 9742 case 'greek7': 9743 case 'isoir88': 9744 return 'greek7'; 9745 9746 case 'csiso18greek7old': 9747 case 'greek7old': 9748 case 'isoir18': 9749 return 'greek7-old'; 9750 9751 case 'cshpdesktop': 9752 case 'hpdesktop': 9753 return 'HP-DeskTop'; 9754 9755 case 'cshplegal': 9756 case 'hplegal': 9757 return 'HP-Legal'; 9758 9759 case 'cshpmath8': 9760 case 'hpmath8': 9761 return 'HP-Math8'; 9762 9763 case 'cshppifont': 9764 case 'hppifont': 9765 return 'HP-Pi-font'; 9766 9767 case 'cshproman8': 9768 case 'hproman8': 9769 case 'r8': 9770 case 'roman8': 9771 return 'hp-roman8'; 9772 9773 case 'hzgb2312': 9774 return 'HZ-GB-2312'; 9775 9776 case 'csibmsymbols': 9777 case 'ibmsymbols': 9778 return 'IBM-Symbols'; 9779 9780 case 'csibmthai': 9781 case 'ibmthai': 9782 return 'IBM-Thai'; 9783 9784 case 'cp37': 9785 case 'csibm37': 9786 case 'ebcdiccpca': 9787 case 'ebcdiccpnl': 9788 case 'ebcdiccpus': 9789 case 'ebcdiccpwt': 9790 case 'ibm37': 9791 return 'IBM037'; 9792 9793 case 'cp38': 9794 case 'csibm38': 9795 case 'ebcdicint': 9796 case 'ibm38': 9797 return 'IBM038'; 9798 9799 case 'cp273': 9800 case 'csibm273': 9801 case 'ibm273': 9802 return 'IBM273'; 9803 9804 case 'cp274': 9805 case 'csibm274': 9806 case 'ebcdicbe': 9807 case 'ibm274': 9808 return 'IBM274'; 9809 9810 case 'cp275': 9811 case 'csibm275': 9812 case 'ebcdicbr': 9813 case 'ibm275': 9814 return 'IBM275'; 9815 9816 case 'csibm277': 9817 case 'ebcdiccpdk': 9818 case 'ebcdiccpno': 9819 case 'ibm277': 9820 return 'IBM277'; 9821 9822 case 'cp278': 9823 case 'csibm278': 9824 case 'ebcdiccpfi': 9825 case 'ebcdiccpse': 9826 case 'ibm278': 9827 return 'IBM278'; 9828 9829 case 'cp280': 9830 case 'csibm280': 9831 case 'ebcdiccpit': 9832 case 'ibm280': 9833 return 'IBM280'; 9834 9835 case 'cp281': 9836 case 'csibm281': 9837 case 'ebcdicjpe': 9838 case 'ibm281': 9839 return 'IBM281'; 9840 9841 case 'cp284': 9842 case 'csibm284': 9843 case 'ebcdiccpes': 9844 case 'ibm284': 9845 return 'IBM284'; 9846 9847 case 'cp285': 9848 case 'csibm285': 9849 case 'ebcdiccpgb': 9850 case 'ibm285': 9851 return 'IBM285'; 9852 9853 case 'cp290': 9854 case 'csibm290': 9855 case 'ebcdicjpkana': 9856 case 'ibm290': 9857 return 'IBM290'; 9858 9859 case 'cp297': 9860 case 'csibm297': 9861 case 'ebcdiccpfr': 9862 case 'ibm297': 9863 return 'IBM297'; 9864 9865 case 'cp420': 9866 case 'csibm420': 9867 case 'ebcdiccpar1': 9868 case 'ibm420': 9869 return 'IBM420'; 9870 9871 case 'cp423': 9872 case 'csibm423': 9873 case 'ebcdiccpgr': 9874 case 'ibm423': 9875 return 'IBM423'; 9876 9877 case 'cp424': 9878 case 'csibm424': 9879 case 'ebcdiccphe': 9880 case 'ibm424': 9881 return 'IBM424'; 9882 9883 case '437': 9884 case 'cp437': 9885 case 'cspc8codepage437': 9886 case 'ibm437': 9887 return 'IBM437'; 9888 9889 case 'cp500': 9890 case 'csibm500': 9891 case 'ebcdiccpbe': 9892 case 'ebcdiccpch': 9893 case 'ibm500': 9894 return 'IBM500'; 9895 9896 case 'cp775': 9897 case 'cspc775baltic': 9898 case 'ibm775': 9899 return 'IBM775'; 9900 9901 case '850': 9902 case 'cp850': 9903 case 'cspc850multilingual': 9904 case 'ibm850': 9905 return 'IBM850'; 9906 9907 case '851': 9908 case 'cp851': 9909 case 'csibm851': 9910 case 'ibm851': 9911 return 'IBM851'; 9912 9913 case '852': 9914 case 'cp852': 9915 case 'cspcp852': 9916 case 'ibm852': 9917 return 'IBM852'; 9918 9919 case '855': 9920 case 'cp855': 9921 case 'csibm855': 9922 case 'ibm855': 9923 return 'IBM855'; 9924 9925 case '857': 9926 case 'cp857': 9927 case 'csibm857': 9928 case 'ibm857': 9929 return 'IBM857'; 9930 9931 case 'ccsid858': 9932 case 'cp858': 9933 case 'ibm858': 9934 case 'pcmultilingual850euro': 9935 return 'IBM00858'; 9936 9937 case '860': 9938 case 'cp860': 9939 case 'csibm860': 9940 case 'ibm860': 9941 return 'IBM860'; 9942 9943 case '861': 9944 case 'cp861': 9945 case 'cpis': 9946 case 'csibm861': 9947 case 'ibm861': 9948 return 'IBM861'; 9949 9950 case '862': 9951 case 'cp862': 9952 case 'cspc862latinhebrew': 9953 case 'ibm862': 9954 return 'IBM862'; 9955 9956 case '863': 9957 case 'cp863': 9958 case 'csibm863': 9959 case 'ibm863': 9960 return 'IBM863'; 9961 9962 case 'cp864': 9963 case 'csibm864': 9964 case 'ibm864': 9965 return 'IBM864'; 9966 9967 case '865': 9968 case 'cp865': 9969 case 'csibm865': 9970 case 'ibm865': 9971 return 'IBM865'; 9972 9973 case '866': 9974 case 'cp866': 9975 case 'csibm866': 9976 case 'ibm866': 9977 return 'IBM866'; 9978 9979 case 'cp868': 9980 case 'cpar': 9981 case 'csibm868': 9982 case 'ibm868': 9983 return 'IBM868'; 9984 9985 case '869': 9986 case 'cp869': 9987 case 'cpgr': 9988 case 'csibm869': 9989 case 'ibm869': 9990 return 'IBM869'; 9991 9992 case 'cp870': 9993 case 'csibm870': 9994 case 'ebcdiccproece': 9995 case 'ebcdiccpyu': 9996 case 'ibm870': 9997 return 'IBM870'; 9998 9999 case 'cp871': 10000 case 'csibm871': 10001 case 'ebcdiccpis': 10002 case 'ibm871': 10003 return 'IBM871'; 10004 10005 case 'cp880': 10006 case 'csibm880': 10007 case 'ebcdiccyrillic': 10008 case 'ibm880': 10009 return 'IBM880'; 10010 10011 case 'cp891': 10012 case 'csibm891': 10013 case 'ibm891': 10014 return 'IBM891'; 10015 10016 case 'cp903': 10017 case 'csibm903': 10018 case 'ibm903': 10019 return 'IBM903'; 10020 10021 case '904': 10022 case 'cp904': 10023 case 'csibbm904': 10024 case 'ibm904': 10025 return 'IBM904'; 10026 10027 case 'cp905': 10028 case 'csibm905': 10029 case 'ebcdiccptr': 10030 case 'ibm905': 10031 return 'IBM905'; 10032 10033 case 'cp918': 10034 case 'csibm918': 10035 case 'ebcdiccpar2': 10036 case 'ibm918': 10037 return 'IBM918'; 10038 10039 case 'ccsid924': 10040 case 'cp924': 10041 case 'ebcdiclatin9euro': 10042 case 'ibm924': 10043 return 'IBM00924'; 10044 10045 case 'cp1026': 10046 case 'csibm1026': 10047 case 'ibm1026': 10048 return 'IBM1026'; 10049 10050 case 'ibm1047': 10051 return 'IBM1047'; 10052 10053 case 'ccsid1140': 10054 case 'cp1140': 10055 case 'ebcdicus37euro': 10056 case 'ibm1140': 10057 return 'IBM01140'; 10058 10059 case 'ccsid1141': 10060 case 'cp1141': 10061 case 'ebcdicde273euro': 10062 case 'ibm1141': 10063 return 'IBM01141'; 10064 10065 case 'ccsid1142': 10066 case 'cp1142': 10067 case 'ebcdicdk277euro': 10068 case 'ebcdicno277euro': 10069 case 'ibm1142': 10070 return 'IBM01142'; 10071 10072 case 'ccsid1143': 10073 case 'cp1143': 10074 case 'ebcdicfi278euro': 10075 case 'ebcdicse278euro': 10076 case 'ibm1143': 10077 return 'IBM01143'; 10078 10079 case 'ccsid1144': 10080 case 'cp1144': 10081 case 'ebcdicit280euro': 10082 case 'ibm1144': 10083 return 'IBM01144'; 10084 10085 case 'ccsid1145': 10086 case 'cp1145': 10087 case 'ebcdices284euro': 10088 case 'ibm1145': 10089 return 'IBM01145'; 10090 10091 case 'ccsid1146': 10092 case 'cp1146': 10093 case 'ebcdicgb285euro': 10094 case 'ibm1146': 10095 return 'IBM01146'; 10096 10097 case 'ccsid1147': 10098 case 'cp1147': 10099 case 'ebcdicfr297euro': 10100 case 'ibm1147': 10101 return 'IBM01147'; 10102 10103 case 'ccsid1148': 10104 case 'cp1148': 10105 case 'ebcdicinternational500euro': 10106 case 'ibm1148': 10107 return 'IBM01148'; 10108 10109 case 'ccsid1149': 10110 case 'cp1149': 10111 case 'ebcdicis871euro': 10112 case 'ibm1149': 10113 return 'IBM01149'; 10114 10115 case 'csiso143iecp271': 10116 case 'iecp271': 10117 case 'isoir143': 10118 return 'IEC_P27-1'; 10119 10120 case 'csiso49inis': 10121 case 'inis': 10122 case 'isoir49': 10123 return 'INIS'; 10124 10125 case 'csiso50inis8': 10126 case 'inis8': 10127 case 'isoir50': 10128 return 'INIS-8'; 10129 10130 case 'csiso51iniscyrillic': 10131 case 'iniscyrillic': 10132 case 'isoir51': 10133 return 'INIS-cyrillic'; 10134 10135 case 'csinvariant': 10136 case 'invariant': 10137 return 'INVARIANT'; 10138 10139 case 'iso2022cn': 10140 return 'ISO-2022-CN'; 10141 10142 case 'iso2022cnext': 10143 return 'ISO-2022-CN-EXT'; 10144 10145 case 'csiso2022jp': 10146 case 'iso2022jp': 10147 return 'ISO-2022-JP'; 10148 10149 case 'csiso2022jp2': 10150 case 'iso2022jp2': 10151 return 'ISO-2022-JP-2'; 10152 10153 case 'csiso2022kr': 10154 case 'iso2022kr': 10155 return 'ISO-2022-KR'; 10156 10157 case 'cswindows30latin1': 10158 case 'iso88591windows30latin1': 10159 return 'ISO-8859-1-Windows-3.0-Latin-1'; 10160 10161 case 'cswindows31latin1': 10162 case 'iso88591windows31latin1': 10163 return 'ISO-8859-1-Windows-3.1-Latin-1'; 10164 10165 case 'csisolatin2': 10166 case 'iso88592': 10167 case 'iso885921987': 10168 case 'isoir101': 10169 case 'l2': 10170 case 'latin2': 10171 return 'ISO-8859-2'; 10172 10173 case 'cswindows31latin2': 10174 case 'iso88592windowslatin2': 10175 return 'ISO-8859-2-Windows-Latin-2'; 10176 10177 case 'csisolatin3': 10178 case 'iso88593': 10179 case 'iso885931988': 10180 case 'isoir109': 10181 case 'l3': 10182 case 'latin3': 10183 return 'ISO-8859-3'; 10184 10185 case 'csisolatin4': 10186 case 'iso88594': 10187 case 'iso885941988': 10188 case 'isoir110': 10189 case 'l4': 10190 case 'latin4': 10191 return 'ISO-8859-4'; 10192 10193 case 'csisolatincyrillic': 10194 case 'cyrillic': 10195 case 'iso88595': 10196 case 'iso885951988': 10197 case 'isoir144': 10198 return 'ISO-8859-5'; 10199 10200 case 'arabic': 10201 case 'asmo708': 10202 case 'csisolatinarabic': 10203 case 'ecma114': 10204 case 'iso88596': 10205 case 'iso885961987': 10206 case 'isoir127': 10207 return 'ISO-8859-6'; 10208 10209 case 'csiso88596e': 10210 case 'iso88596e': 10211 return 'ISO-8859-6-E'; 10212 10213 case 'csiso88596i': 10214 case 'iso88596i': 10215 return 'ISO-8859-6-I'; 10216 10217 case 'csisolatingreek': 10218 case 'ecma118': 10219 case 'elot928': 10220 case 'greek': 10221 case 'greek8': 10222 case 'iso88597': 10223 case 'iso885971987': 10224 case 'isoir126': 10225 return 'ISO-8859-7'; 10226 10227 case 'csisolatinhebrew': 10228 case 'hebrew': 10229 case 'iso88598': 10230 case 'iso885981988': 10231 case 'isoir138': 10232 return 'ISO-8859-8'; 10233 10234 case 'csiso88598e': 10235 case 'iso88598e': 10236 return 'ISO-8859-8-E'; 10237 10238 case 'csiso88598i': 10239 case 'iso88598i': 10240 return 'ISO-8859-8-I'; 10241 10242 case 'cswindows31latin5': 10243 case 'iso88599windowslatin5': 10244 return 'ISO-8859-9-Windows-Latin-5'; 10245 10246 case 'csisolatin6': 10247 case 'iso885910': 10248 case 'iso8859101992': 10249 case 'isoir157': 10250 case 'l6': 10251 case 'latin6': 10252 return 'ISO-8859-10'; 10253 10254 case 'iso885913': 10255 return 'ISO-8859-13'; 10256 10257 case 'iso885914': 10258 case 'iso8859141998': 10259 case 'isoceltic': 10260 case 'isoir199': 10261 case 'l8': 10262 case 'latin8': 10263 return 'ISO-8859-14'; 10264 10265 case 'iso885915': 10266 case 'latin9': 10267 return 'ISO-8859-15'; 10268 10269 case 'iso885916': 10270 case 'iso8859162001': 10271 case 'isoir226': 10272 case 'l10': 10273 case 'latin10': 10274 return 'ISO-8859-16'; 10275 10276 case 'iso10646j1': 10277 return 'ISO-10646-J-1'; 10278 10279 case 'csunicode': 10280 case 'iso10646ucs2': 10281 return 'ISO-10646-UCS-2'; 10282 10283 case 'csucs4': 10284 case 'iso10646ucs4': 10285 return 'ISO-10646-UCS-4'; 10286 10287 case 'csunicodeascii': 10288 case 'iso10646ucsbasic': 10289 return 'ISO-10646-UCS-Basic'; 10290 10291 case 'csunicodelatin1': 10292 case 'iso10646': 10293 case 'iso10646unicodelatin1': 10294 return 'ISO-10646-Unicode-Latin1'; 10295 10296 case 'csiso10646utf1': 10297 case 'iso10646utf1': 10298 return 'ISO-10646-UTF-1'; 10299 10300 case 'csiso115481': 10301 case 'iso115481': 10302 case 'isotr115481': 10303 return 'ISO-11548-1'; 10304 10305 case 'csiso90': 10306 case 'isoir90': 10307 return 'iso-ir-90'; 10308 10309 case 'csunicodeibm1261': 10310 case 'isounicodeibm1261': 10311 return 'ISO-Unicode-IBM-1261'; 10312 10313 case 'csunicodeibm1264': 10314 case 'isounicodeibm1264': 10315 return 'ISO-Unicode-IBM-1264'; 10316 10317 case 'csunicodeibm1265': 10318 case 'isounicodeibm1265': 10319 return 'ISO-Unicode-IBM-1265'; 10320 10321 case 'csunicodeibm1268': 10322 case 'isounicodeibm1268': 10323 return 'ISO-Unicode-IBM-1268'; 10324 10325 case 'csunicodeibm1276': 10326 case 'isounicodeibm1276': 10327 return 'ISO-Unicode-IBM-1276'; 10328 10329 case 'csiso646basic1983': 10330 case 'iso646basic1983': 10331 case 'ref': 10332 return 'ISO_646.basic:1983'; 10333 10334 case 'csiso2intlrefversion': 10335 case 'irv': 10336 case 'iso646irv1983': 10337 case 'isoir2': 10338 return 'ISO_646.irv:1983'; 10339 10340 case 'csiso2033': 10341 case 'e13b': 10342 case 'iso20331983': 10343 case 'isoir98': 10344 return 'ISO_2033-1983'; 10345 10346 case 'csiso5427cyrillic': 10347 case 'iso5427': 10348 case 'isoir37': 10349 return 'ISO_5427'; 10350 10351 case 'iso5427cyrillic1981': 10352 case 'iso54271981': 10353 case 'isoir54': 10354 return 'ISO_5427:1981'; 10355 10356 case 'csiso5428greek': 10357 case 'iso54281980': 10358 case 'isoir55': 10359 return 'ISO_5428:1980'; 10360 10361 case 'csiso6937add': 10362 case 'iso6937225': 10363 case 'isoir152': 10364 return 'ISO_6937-2-25'; 10365 10366 case 'csisotextcomm': 10367 case 'iso69372add': 10368 case 'isoir142': 10369 return 'ISO_6937-2-add'; 10370 10371 case 'csiso8859supp': 10372 case 'iso8859supp': 10373 case 'isoir154': 10374 case 'latin125': 10375 return 'ISO_8859-supp'; 10376 10377 case 'csiso10367box': 10378 case 'iso10367box': 10379 case 'isoir155': 10380 return 'ISO_10367-box'; 10381 10382 case 'csiso15italian': 10383 case 'iso646it': 10384 case 'isoir15': 10385 case 'it': 10386 return 'IT'; 10387 10388 case 'csiso13jisc6220jp': 10389 case 'isoir13': 10390 case 'jisc62201969': 10391 case 'jisc62201969jp': 10392 case 'katakana': 10393 case 'x2017': 10394 return 'JIS_C6220-1969-jp'; 10395 10396 case 'csiso14jisc6220ro': 10397 case 'iso646jp': 10398 case 'isoir14': 10399 case 'jisc62201969ro': 10400 case 'jp': 10401 return 'JIS_C6220-1969-ro'; 10402 10403 case 'csiso42jisc62261978': 10404 case 'isoir42': 10405 case 'jisc62261978': 10406 return 'JIS_C6226-1978'; 10407 10408 case 'csiso87jisx208': 10409 case 'isoir87': 10410 case 'jisc62261983': 10411 case 'jisx2081983': 10412 case 'x208': 10413 return 'JIS_C6226-1983'; 10414 10415 case 'csiso91jisc62291984a': 10416 case 'isoir91': 10417 case 'jisc62291984a': 10418 case 'jpocra': 10419 return 'JIS_C6229-1984-a'; 10420 10421 case 'csiso92jisc62991984b': 10422 case 'iso646jpocrb': 10423 case 'isoir92': 10424 case 'jisc62291984b': 10425 case 'jpocrb': 10426 return 'JIS_C6229-1984-b'; 10427 10428 case 'csiso93jis62291984badd': 10429 case 'isoir93': 10430 case 'jisc62291984badd': 10431 case 'jpocrbadd': 10432 return 'JIS_C6229-1984-b-add'; 10433 10434 case 'csiso94jis62291984hand': 10435 case 'isoir94': 10436 case 'jisc62291984hand': 10437 case 'jpocrhand': 10438 return 'JIS_C6229-1984-hand'; 10439 10440 case 'csiso95jis62291984handadd': 10441 case 'isoir95': 10442 case 'jisc62291984handadd': 10443 case 'jpocrhandadd': 10444 return 'JIS_C6229-1984-hand-add'; 10445 10446 case 'csiso96jisc62291984kana': 10447 case 'isoir96': 10448 case 'jisc62291984kana': 10449 return 'JIS_C6229-1984-kana'; 10450 10451 case 'csjisencoding': 10452 case 'jisencoding': 10453 return 'JIS_Encoding'; 10454 10455 case 'cshalfwidthkatakana': 10456 case 'jisx201': 10457 case 'x201': 10458 return 'JIS_X0201'; 10459 10460 case 'csiso159jisx2121990': 10461 case 'isoir159': 10462 case 'jisx2121990': 10463 case 'x212': 10464 return 'JIS_X0212-1990'; 10465 10466 case 'csiso141jusib1002': 10467 case 'iso646yu': 10468 case 'isoir141': 10469 case 'js': 10470 case 'jusib1002': 10471 case 'yu': 10472 return 'JUS_I.B1.002'; 10473 10474 case 'csiso147macedonian': 10475 case 'isoir147': 10476 case 'jusib1003mac': 10477 case 'macedonian': 10478 return 'JUS_I.B1.003-mac'; 10479 10480 case 'csiso146serbian': 10481 case 'isoir146': 10482 case 'jusib1003serb': 10483 case 'serbian': 10484 return 'JUS_I.B1.003-serb'; 10485 10486 case 'koi7switched': 10487 return 'KOI7-switched'; 10488 10489 case 'cskoi8r': 10490 case 'koi8r': 10491 return 'KOI8-R'; 10492 10493 case 'koi8u': 10494 return 'KOI8-U'; 10495 10496 case 'csksc5636': 10497 case 'iso646kr': 10498 case 'ksc5636': 10499 return 'KSC5636'; 10500 10501 case 'cskz1048': 10502 case 'kz1048': 10503 case 'rk1048': 10504 case 'strk10482002': 10505 return 'KZ-1048'; 10506 10507 case 'csiso19latingreek': 10508 case 'isoir19': 10509 case 'latingreek': 10510 return 'latin-greek'; 10511 10512 case 'csiso27latingreek1': 10513 case 'isoir27': 10514 case 'latingreek1': 10515 return 'Latin-greek-1'; 10516 10517 case 'csiso158lap': 10518 case 'isoir158': 10519 case 'lap': 10520 case 'latinlap': 10521 return 'latin-lap'; 10522 10523 case 'csmacintosh': 10524 case 'mac': 10525 case 'macintosh': 10526 return 'macintosh'; 10527 10528 case 'csmicrosoftpublishing': 10529 case 'microsoftpublishing': 10530 return 'Microsoft-Publishing'; 10531 10532 case 'csmnem': 10533 case 'mnem': 10534 return 'MNEM'; 10535 10536 case 'csmnemonic': 10537 case 'mnemonic': 10538 return 'MNEMONIC'; 10539 10540 case 'csiso86hungarian': 10541 case 'hu': 10542 case 'iso646hu': 10543 case 'isoir86': 10544 case 'msz77953': 10545 return 'MSZ_7795.3'; 10546 10547 case 'csnatsdano': 10548 case 'isoir91': 10549 case 'natsdano': 10550 return 'NATS-DANO'; 10551 10552 case 'csnatsdanoadd': 10553 case 'isoir92': 10554 case 'natsdanoadd': 10555 return 'NATS-DANO-ADD'; 10556 10557 case 'csnatssefi': 10558 case 'isoir81': 10559 case 'natssefi': 10560 return 'NATS-SEFI'; 10561 10562 case 'csnatssefiadd': 10563 case 'isoir82': 10564 case 'natssefiadd': 10565 return 'NATS-SEFI-ADD'; 10566 10567 case 'csiso151cuba': 10568 case 'cuba': 10569 case 'iso646cu': 10570 case 'isoir151': 10571 case 'ncnc1081': 10572 return 'NC_NC00-10:81'; 10573 10574 case 'csiso69french': 10575 case 'fr': 10576 case 'iso646fr': 10577 case 'isoir69': 10578 case 'nfz62010': 10579 return 'NF_Z_62-010'; 10580 10581 case 'csiso25french': 10582 case 'iso646fr1': 10583 case 'isoir25': 10584 case 'nfz620101973': 10585 return 'NF_Z_62-010_(1973)'; 10586 10587 case 'csiso60danishnorwegian': 10588 case 'csiso60norwegian1': 10589 case 'iso646no': 10590 case 'isoir60': 10591 case 'no': 10592 case 'ns45511': 10593 return 'NS_4551-1'; 10594 10595 case 'csiso61norwegian2': 10596 case 'iso646no2': 10597 case 'isoir61': 10598 case 'no2': 10599 case 'ns45512': 10600 return 'NS_4551-2'; 10601 10602 case 'osdebcdicdf3irv': 10603 return 'OSD_EBCDIC_DF03_IRV'; 10604 10605 case 'osdebcdicdf41': 10606 return 'OSD_EBCDIC_DF04_1'; 10607 10608 case 'osdebcdicdf415': 10609 return 'OSD_EBCDIC_DF04_15'; 10610 10611 case 'cspc8danishnorwegian': 10612 case 'pc8danishnorwegian': 10613 return 'PC8-Danish-Norwegian'; 10614 10615 case 'cspc8turkish': 10616 case 'pc8turkish': 10617 return 'PC8-Turkish'; 10618 10619 case 'csiso16portuguese': 10620 case 'iso646pt': 10621 case 'isoir16': 10622 case 'pt': 10623 return 'PT'; 10624 10625 case 'csiso84portuguese2': 10626 case 'iso646pt2': 10627 case 'isoir84': 10628 case 'pt2': 10629 return 'PT2'; 10630 10631 case 'cp154': 10632 case 'csptcp154': 10633 case 'cyrillicasian': 10634 case 'pt154': 10635 case 'ptcp154': 10636 return 'PTCP154'; 10637 10638 case 'scsu': 10639 return 'SCSU'; 10640 10641 case 'csiso10swedish': 10642 case 'fi': 10643 case 'iso646fi': 10644 case 'iso646se': 10645 case 'isoir10': 10646 case 'se': 10647 case 'sen850200b': 10648 return 'SEN_850200_B'; 10649 10650 case 'csiso11swedishfornames': 10651 case 'iso646se2': 10652 case 'isoir11': 10653 case 'se2': 10654 case 'sen850200c': 10655 return 'SEN_850200_C'; 10656 10657 case 'csiso102t617bit': 10658 case 'isoir102': 10659 case 't617bit': 10660 return 'T.61-7bit'; 10661 10662 case 'csiso103t618bit': 10663 case 'isoir103': 10664 case 't61': 10665 case 't618bit': 10666 return 'T.61-8bit'; 10667 10668 case 'csiso128t101g2': 10669 case 'isoir128': 10670 case 't101g2': 10671 return 'T.101-G2'; 10672 10673 case 'cstscii': 10674 case 'tscii': 10675 return 'TSCII'; 10676 10677 case 'csunicode11': 10678 case 'unicode11': 10679 return 'UNICODE-1-1'; 10680 10681 case 'csunicode11utf7': 10682 case 'unicode11utf7': 10683 return 'UNICODE-1-1-UTF-7'; 10684 10685 case 'csunknown8bit': 10686 case 'unknown8bit': 10687 return 'UNKNOWN-8BIT'; 10688 10689 case 'ansix341968': 10690 case 'ansix341986': 10691 case 'ascii': 10692 case 'cp367': 10693 case 'csascii': 10694 case 'ibm367': 10695 case 'iso646irv1991': 10696 case 'iso646us': 10697 case 'isoir6': 10698 case 'us': 10699 case 'usascii': 10700 return 'US-ASCII'; 10701 10702 case 'csusdk': 10703 case 'usdk': 10704 return 'us-dk'; 10705 10706 case 'utf7': 10707 return 'UTF-7'; 10708 10709 case 'utf8': 10710 return 'UTF-8'; 10711 10712 case 'utf16': 10713 return 'UTF-16'; 10714 10715 case 'utf16be': 10716 return 'UTF-16BE'; 10717 10718 case 'utf16le': 10719 return 'UTF-16LE'; 10720 10721 case 'utf32': 10722 return 'UTF-32'; 10723 10724 case 'utf32be': 10725 return 'UTF-32BE'; 10726 10727 case 'utf32le': 10728 return 'UTF-32LE'; 10729 10730 case 'csventurainternational': 10731 case 'venturainternational': 10732 return 'Ventura-International'; 10733 10734 case 'csventuramath': 10735 case 'venturamath': 10736 return 'Ventura-Math'; 10737 10738 case 'csventuraus': 10739 case 'venturaus': 10740 return 'Ventura-US'; 10741 10742 case 'csiso70videotexsupp1': 10743 case 'isoir70': 10744 case 'videotexsuppl': 10745 return 'videotex-suppl'; 10746 10747 case 'csviqr': 10748 case 'viqr': 10749 return 'VIQR'; 10750 10751 case 'csviscii': 10752 case 'viscii': 10753 return 'VISCII'; 10754 10755 case 'csshiftjis': 10756 case 'cswindows31j': 10757 case 'mskanji': 10758 case 'shiftjis': 10759 case 'windows31j': 10760 return 'Windows-31J'; 10761 10762 case 'iso885911': 10763 case 'tis620': 10764 return 'windows-874'; 10765 10766 case 'cseuckr': 10767 case 'csksc56011987': 10768 case 'euckr': 10769 case 'isoir149': 10770 case 'korean': 10771 case 'ksc5601': 10772 case 'ksc56011987': 10773 case 'ksc56011989': 10774 case 'windows949': 10775 return 'windows-949'; 10776 10777 case 'windows1250': 10778 return 'windows-1250'; 10779 10780 case 'windows1251': 10781 return 'windows-1251'; 10782 10783 case 'cp819': 10784 case 'csisolatin1': 10785 case 'ibm819': 10786 case 'iso88591': 10787 case 'iso885911987': 10788 case 'isoir100': 10789 case 'l1': 10790 case 'latin1': 10791 case 'windows1252': 10792 return 'windows-1252'; 10793 10794 case 'windows1253': 10795 return 'windows-1253'; 10796 10797 case 'csisolatin5': 10798 case 'iso88599': 10799 case 'iso885991989': 10800 case 'isoir148': 10801 case 'l5': 10802 case 'latin5': 10803 case 'windows1254': 10804 return 'windows-1254'; 10805 10806 case 'windows1255': 10807 return 'windows-1255'; 10808 10809 case 'windows1256': 10810 return 'windows-1256'; 10811 10812 case 'windows1257': 10813 return 'windows-1257'; 10814 10815 case 'windows1258': 10816 return 'windows-1258'; 10817 10818 default: 10819 return $charset; 10820 } 10821 } 10822 10823 function get_curl_version() 10824 { 10825 if (is_array($curl = curl_version())) 10826 { 10827 $curl = $curl['version']; 10828 } 10829 elseif (substr($curl, 0, 5) === 'curl/') 10830 { 10831 $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5)); 10832 } 10833 elseif (substr($curl, 0, 8) === 'libcurl/') 10834 { 10835 $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8)); 10836 } 10837 else 10838 { 10839 $curl = 0; 10840 } 10841 return $curl; 10842 } 10843 10844 function is_subclass_of($class1, $class2) 10845 { 10846 if (func_num_args() !== 2) 10847 { 10848 trigger_error('Wrong parameter count for SimplePie_Misc::is_subclass_of()', E_USER_WARNING); 10849 } 10850 elseif (version_compare(PHP_VERSION, '5.0.3', '>=') || is_object($class1)) 10851 { 10852 return is_subclass_of($class1, $class2); 10853 } 10854 elseif (is_string($class1) && is_string($class2)) 10855 { 10856 if (class_exists($class1)) 10857 { 10858 if (class_exists($class2)) 10859 { 10860 $class2 = strtolower($class2); 10861 while ($class1 = strtolower(get_parent_class($class1))) 10862 { 10863 if ($class1 === $class2) 10864 { 10865 return true; 10866 } 10867 } 10868 } 10869 } 10870 else 10871 { 10872 trigger_error('Unknown class passed as parameter', E_USER_WARNNG); 10873 } 10874 } 10875 return false; 10876 } 10877 10878 /** 10879 * Strip HTML comments 10880 * 10881 * @access public 10882 * @param string $data Data to strip comments from 10883 * @return string Comment stripped string 10884 */ 10885 function strip_comments($data) 10886 { 10887 $output = ''; 10888 while (($start = strpos($data, '<!--')) !== false) 10889 { 10890 $output .= substr($data, 0, $start); 10891 if (($end = strpos($data, '-->', $start)) !== false) 10892 { 10893 $data = substr_replace($data, '', 0, $end + 3); 10894 } 10895 else 10896 { 10897 $data = ''; 10898 } 10899 } 10900 return $output . $data; 10901 } 10902 10903 function parse_date($dt) 10904 { 10905 $parser = SimplePie_Parse_Date::get(); 10906 return $parser->parse($dt); 10907 } 10908 10909 /** 10910 * Decode HTML entities 10911 * 10912 * @static 10913 * @access public 10914 * @param string $data Input data 10915 * @return string Output data 10916 */ 10917 function entities_decode($data) 10918 { 10919 $decoder =& new SimplePie_Decode_HTML_Entities($data); 10920 return $decoder->parse(); 10921 } 10922 10923 /** 10924 * Remove RFC822 comments 10925 * 10926 * @access public 10927 * @param string $data Data to strip comments from 10928 * @return string Comment stripped string 10929 */ 10930 function uncomment_rfc822($string) 10931 { 10932 $string = (string) $string; 10933 $position = 0; 10934 $length = strlen($string); 10935 $depth = 0; 10936 10937 $output = ''; 10938 10939 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) 10940 { 10941 $output .= substr($string, $position, $pos - $position); 10942 $position = $pos + 1; 10943 if ($string[$pos - 1] !== '\\') 10944 { 10945 $depth++; 10946 while ($depth && $position < $length) 10947 { 10948 $position += strcspn($string, '()', $position); 10949 if ($string[$position - 1] === '\\') 10950 { 10951 $position++; 10952 continue; 10953 } 10954 elseif (isset($string[$position])) 10955 { 10956 switch ($string[$position]) 10957 { 10958 case '(': 10959 $depth++; 10960 break; 10961 10962 case ')': 10963 $depth--; 10964 break; 10965 } 10966 $position++; 10967 } 10968 else 10969 { 10970 break; 10971 } 10972 } 10973 } 10974 else 10975 { 10976 $output .= '('; 10977 } 10978 } 10979 $output .= substr($string, $position); 10980 10981 return $output; 10982 } 10983 10984 function parse_mime($mime) 10985 { 10986 if (($pos = strpos($mime, ';')) === false) 10987 { 10988 return trim($mime); 10989 } 10990 else 10991 { 10992 return trim(substr($mime, 0, $pos)); 10993 } 10994 } 10995 10996 function htmlspecialchars_decode($string, $quote_style) 10997 { 10998 if (function_exists('htmlspecialchars_decode')) 10999 { 11000 return htmlspecialchars_decode($string, $quote_style); 11001 } 11002 else 11003 { 11004 return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style))); 11005 } 11006 } 11007 11008 function atom_03_construct_type($attribs) 11009 { 11010 if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64')) 11011 { 11012 $mode = SIMPLEPIE_CONSTRUCT_BASE64; 11013 } 11014 else 11015 { 11016 $mode = SIMPLEPIE_CONSTRUCT_NONE; 11017 } 11018 if (isset($attribs['']['type'])) 11019 { 11020 switch (strtolower(trim($attribs['']['type']))) 11021 { 11022 case 'text': 11023 case 'text/plain': 11024 return SIMPLEPIE_CONSTRUCT_TEXT | $mode; 11025 11026 case 'html': 11027 case 'text/html': 11028 return SIMPLEPIE_CONSTRUCT_HTML | $mode; 11029 11030 case 'xhtml': 11031 case 'application/xhtml+xml': 11032 return SIMPLEPIE_CONSTRUCT_XHTML | $mode; 11033 11034 default: 11035 return SIMPLEPIE_CONSTRUCT_NONE | $mode; 11036 } 11037 } 11038 else 11039 { 11040 return SIMPLEPIE_CONSTRUCT_TEXT | $mode; 11041 } 11042 } 11043 11044 function atom_10_construct_type($attribs) 11045 { 11046 if (isset($attribs['']['type'])) 11047 { 11048 switch (strtolower(trim($attribs['']['type']))) 11049 { 11050 case 'text': 11051 return SIMPLEPIE_CONSTRUCT_TEXT; 11052 11053 case 'html': 11054 return SIMPLEPIE_CONSTRUCT_HTML; 11055 11056 case 'xhtml': 11057 return SIMPLEPIE_CONSTRUCT_XHTML; 11058 11059 default: 11060 return SIMPLEPIE_CONSTRUCT_NONE; 11061 } 11062 } 11063 return SIMPLEPIE_CONSTRUCT_TEXT; 11064 } 11065 11066 function atom_10_content_construct_type($attribs) 11067 { 11068 if (isset($attribs['']['type'])) 11069 { 11070 $type = strtolower(trim($attribs['']['type'])); 11071 switch ($type) 11072 { 11073 case 'text': 11074 return SIMPLEPIE_CONSTRUCT_TEXT; 11075 11076 case 'html': 11077 return SIMPLEPIE_CONSTRUCT_HTML; 11078 11079 case 'xhtml': 11080 return SIMPLEPIE_CONSTRUCT_XHTML; 11081 } 11082 if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/') 11083 { 11084 return SIMPLEPIE_CONSTRUCT_NONE; 11085 } 11086 else 11087 { 11088 return SIMPLEPIE_CONSTRUCT_BASE64; 11089 } 11090 } 11091 else 11092 { 11093 return SIMPLEPIE_CONSTRUCT_TEXT; 11094 } 11095 } 11096 11097 function is_isegment_nz_nc($string) 11098 { 11099 return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string); 11100 } 11101 11102 function space_seperated_tokens($string) 11103 { 11104 $space_characters = "\x20\x09\x0A\x0B\x0C\x0D"; 11105 $string_length = strlen($string); 11106 11107 $position = strspn($string, $space_characters); 11108 $tokens = array(); 11109 11110 while ($position < $string_length) 11111 { 11112 $len = strcspn($string, $space_characters, $position); 11113 $tokens[] = substr($string, $position, $len); 11114 $position += $len; 11115 $position += strspn($string, $space_characters, $position); 11116 } 11117 11118 return $tokens; 11119 } 11120 11121 function array_unique($array) 11122 { 11123 if (version_compare(PHP_VERSION, '5.2', '>=')) 11124 { 11125 return array_unique($array); 11126 } 11127 else 11128 { 11129 $array = (array) $array; 11130 $new_array = array(); 11131 $new_array_strings = array(); 11132 foreach ($array as $key => $value) 11133 { 11134 if (is_object($value)) 11135 { 11136 if (method_exists($value, '__toString')) 11137 { 11138 $cmp = $value->__toString(); 11139 } 11140 else 11141 { 11142 trigger_error('Object of class ' . get_class($value) . ' could not be converted to string', E_USER_ERROR); 11143 } 11144 } 11145 elseif (is_array($value)) 11146 { 11147 $cmp = (string) reset($value); 11148 } 11149 else 11150 { 11151 $cmp = (string) $value; 11152 } 11153 if (!in_array($cmp, $new_array_strings)) 11154 { 11155 $new_array[$key] = $value; 11156 $new_array_strings[] = $cmp; 11157 } 11158 } 11159 return $new_array; 11160 } 11161 } 11162 11163 /** 11164 * Converts a unicode codepoint to a UTF-8 character 11165 * 11166 * @static 11167 * @access public 11168 * @param int $codepoint Unicode codepoint 11169 * @return string UTF-8 character 11170 */ 11171 function codepoint_to_utf8($codepoint) 11172 { 11173 $codepoint = (int) $codepoint; 11174 if ($codepoint < 0) 11175 { 11176 return false; 11177 } 11178 else if ($codepoint <= 0x7f) 11179 { 11180 return chr($codepoint); 11181 } 11182 else if ($codepoint <= 0x7ff) 11183 { 11184 return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f)); 11185 } 11186 else if ($codepoint <= 0xffff) 11187 { 11188 return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f)); 11189 } 11190 else if ($codepoint <= 0x10ffff) 11191 { 11192 return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f)); 11193 } 11194 else 11195 { 11196 // U+FFFD REPLACEMENT CHARACTER 11197 return "\xEF\xBF\xBD"; 11198 } 11199 } 11200 11201 /** 11202 * Re-implementation of PHP 5's stripos() 11203 * 11204 * Returns the numeric position of the first occurrence of needle in the 11205 * haystack string. 11206 * 11207 * @static 11208 * @access string 11209 * @param object $haystack 11210 * @param string $needle Note that the needle may be a string of one or more 11211 * characters. If needle is not a string, it is converted to an integer 11212 * and applied as the ordinal value of a character. 11213 * @param int $offset The optional offset parameter allows you to specify which 11214 * character in haystack to start searching. The position returned is still 11215 * relative to the beginning of haystack. 11216 * @return bool If needle is not found, stripos() will return boolean false. 11217 */ 11218 function stripos($haystack, $needle, $offset = 0) 11219 { 11220 if (function_exists('stripos')) 11221 { 11222 return stripos($haystack, $needle, $offset); 11223 } 11224 else 11225 { 11226 if (is_string($needle)) 11227 { 11228 $needle = strtolower($needle); 11229 } 11230 elseif (is_int($needle) || is_bool($needle) || is_double($needle)) 11231 { 11232 $needle = strtolower(chr($needle)); 11233 } 11234 else 11235 { 11236 trigger_error('needle is not a string or an integer', E_USER_WARNING); 11237 return false; 11238 } 11239 11240 return strpos(strtolower($haystack), $needle, $offset); 11241 } 11242 } 11243 11244 /** 11245 * Similar to parse_str() 11246 * 11247 * Returns an associative array of name/value pairs, where the value is an 11248 * array of values that have used the same name 11249 * 11250 * @static 11251 * @access string 11252 * @param string $str The input string. 11253 * @return array 11254 */ 11255 function parse_str($str) 11256 { 11257 $return = array(); 11258 $str = explode('&', $str); 11259 11260 foreach ($str as $section) 11261 { 11262 if (strpos($section, '=') !== false) 11263 { 11264 list($name, $value) = explode('=', $section, 2); 11265 $return[urldecode($name)][] = urldecode($value); 11266 } 11267 else 11268 { 11269 $return[urldecode($section)][] = null; 11270 } 11271 } 11272 11273 return $return; 11274 } 11275 11276 /** 11277 * Detect XML encoding, as per XML 1.0 Appendix F.1 11278 * 11279 * @todo Add support for EBCDIC 11280 * @param string $data XML data 11281 * @return array Possible encodings 11282 */ 11283 function xml_encoding($data) 11284 { 11285 // UTF-32 Big Endian BOM 11286 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") 11287 { 11288 $encoding[] = 'UTF-32BE'; 11289 } 11290 // UTF-32 Little Endian BOM 11291 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") 11292 { 11293 $encoding[] = 'UTF-32LE'; 11294 } 11295 // UTF-16 Big Endian BOM 11296 elseif (substr($data, 0, 2) === "\xFE\xFF") 11297 { 11298 $encoding[] = 'UTF-16BE'; 11299 } 11300 // UTF-16 Little Endian BOM 11301 elseif (substr($data, 0, 2) === "\xFF\xFE") 11302 { 11303 $encoding[] = 'UTF-16LE'; 11304 } 11305 // UTF-8 BOM 11306 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") 11307 { 11308 $encoding[] = 'UTF-8'; 11309 } 11310 // UTF-32 Big Endian Without BOM 11311 elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C") 11312 { 11313 if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E")) 11314 { 11315 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8')); 11316 if ($parser->parse()) 11317 { 11318 $encoding[] = $parser->encoding; 11319 } 11320 } 11321 $encoding[] = 'UTF-32BE'; 11322 } 11323 // UTF-32 Little Endian Without BOM 11324 elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00") 11325 { 11326 if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00")) 11327 { 11328 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8')); 11329 if ($parser->parse()) 11330 { 11331 $encoding[] = $parser->encoding; 11332 } 11333 } 11334 $encoding[] = 'UTF-32LE'; 11335 } 11336 // UTF-16 Big Endian Without BOM 11337 elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C") 11338 { 11339 if ($pos = strpos($data, "\x00\x3F\x00\x3E")) 11340 { 11341 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8')); 11342 if ($parser->parse()) 11343 { 11344 $encoding[] = $parser->encoding; 11345 } 11346 } 11347 $encoding[] = 'UTF-16BE'; 11348 } 11349 // UTF-16 Little Endian Without BOM 11350 elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00") 11351 { 11352 if ($pos = strpos($data, "\x3F\x00\x3E\x00")) 11353 { 11354 $parser =& new SimplePie_XML_Declaration_Parser(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8')); 11355 if ($parser->parse()) 11356 { 11357 $encoding[] = $parser->encoding; 11358 } 11359 } 11360 $encoding[] = 'UTF-16LE'; 11361 } 11362 // US-ASCII (or superset) 11363 elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C") 11364 { 11365 if ($pos = strpos($data, "\x3F\x3E")) 11366 { 11367 $parser =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5)); 11368 if ($parser->parse()) 11369 { 11370 $encoding[] = $parser->encoding; 11371 } 11372 } 11373 $encoding[] = 'UTF-8'; 11374 } 11375 // Fallback to UTF-8 11376 else 11377 { 11378 $encoding[] = 'UTF-8'; 11379 } 11380 return $encoding; 11381 } 11382 11383 function output_javascript() 11384 { 11385 if (function_exists('ob_gzhandler')) 11386 { 11387 ob_start('ob_gzhandler'); 11388 } 11389 header('Content-type: text/javascript; charset: UTF-8'); 11390 header('Cache-Control: must-revalidate'); 11391 header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days 11392 ?> 11393 function embed_odeo(link) { 11394 document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>'); 11395 } 11396 11397 function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) { 11398 if (placeholder != '') { 11399 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>'); 11400 } 11401 else { 11402 document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>'); 11403 } 11404 } 11405 11406 function embed_flash(bgcolor, width, height, link, loop, type) { 11407 document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>'); 11408 } 11409 11410 function embed_flv(width, height, link, placeholder, loop, player) { 11411 document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>'); 11412 } 11413 11414 function embed_wmedia(width, height, link) { 11415 document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>'); 11416 } 11417 <?php 11418 } 11419 } 11420 11421 /** 11422 * Decode HTML Entities 11423 * 11424 * This implements HTML5 as of revision 967 (2007-06-28) 11425 * 11426 * @package SimplePie 11427 */ 11428 class SimplePie_Decode_HTML_Entities 11429 { 11430 /** 11431 * Data to be parsed 11432 * 11433 * @access private 11434 * @var string 11435 */ 11436 var $data = ''; 11437 11438 /** 11439 * Currently consumed bytes 11440 * 11441 * @access private 11442 * @var string 11443 */ 11444 var $consumed = ''; 11445 11446 /** 11447 * Position of the current byte being parsed 11448 * 11449 * @access private 11450 * @var int 11451 */ 11452 var $position = 0; 11453 11454 /** 11455 * Create an instance of the class with the input data 11456 * 11457 * @access public 11458 * @param string $data Input data 11459 */ 11460 function SimplePie_Decode_HTML_Entities($data) 11461 { 11462 $this->data = $data; 11463 } 11464 11465 /** 11466 * Parse the input data 11467 * 11468 * @access public 11469 * @return string Output data 11470 */ 11471 function parse() 11472 { 11473 while (($this->position = strpos($this->data, '&', $this->position)) !== false) 11474 { 11475 $this->consume(); 11476 $this->entity(); 11477 $this->consumed = ''; 11478 } 11479 return $this->data; 11480 } 11481 11482 /** 11483 * Consume the next byte 11484 * 11485 * @access private 11486 * @return mixed The next byte, or false, if there is no more data 11487 */ 11488 function consume() 11489 { 11490 if (isset($this->data[$this->position])) 11491 { 11492 $this->consumed .= $this->data[$this->position]; 11493 return $this->data[$this->position++]; 11494 } 11495 else 11496 { 11497 return false; 11498 } 11499 } 11500 11501 /** 11502 * Consume a range of characters 11503 * 11504 * @access private 11505 * @param string $chars Characters to consume 11506 * @return mixed A series of characters that match the range, or false 11507 */ 11508 function consume_range($chars) 11509 { 11510 if ($len = strspn($this->data, $chars, $this->position)) 11511 { 11512 $data = substr($this->data, $this->position, $len); 11513 $this->consumed .= $data; 11514 $this->position += $len; 11515 return $data; 11516 } 11517 else 11518 { 11519 return false; 11520 } 11521 } 11522 11523 /** 11524 * Unconsume one byte 11525 * 11526 * @access private 11527 */ 11528 function unconsume() 11529 { 11530 $this->consumed = substr($this->consumed, 0, -1); 11531 $this->position--; 11532 } 11533 11534 /** 11535 * Decode an entity 11536 * 11537 * @access private 11538 */ 11539 function entity() 11540 { 11541 switch ($this->consume()) 11542 { 11543 case "\x09": 11544 case "\x0A": 11545 case "\x0B": 11546 case "\x0B": 11547 case "\x0C": 11548 case "\x20": 11549 case "\x3C": 11550 case "\x26": 11551 case false: 11552 break; 11553 11554 case "\x23": 11555 switch ($this->consume()) 11556 { 11557 case "\x78": 11558 case "\x58": 11559 $range = '0123456789ABCDEFabcdef'; 11560 $hex = true; 11561 break; 11562 11563 default: 11564 $range = '0123456789'; 11565 $hex = false; 11566 $this->unconsume(); 11567 break; 11568 } 11569 11570 if ($codepoint = $this->consume_range($range)) 11571 { 11572 static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8"); 11573 11574 if ($hex) 11575 { 11576 $codepoint = hexdec($codepoint); 11577 } 11578 else 11579 { 11580 $codepoint = intval($codepoint); 11581 } 11582 11583 if (isset($windows_1252_specials[$codepoint])) 11584 { 11585 $replacement = $windows_1252_specials[$codepoint]; 11586 } 11587 else 11588 { 11589 $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint); 11590 } 11591 11592 if (!in_array($this->consume(), array(';', false), true)) 11593 { 11594 $this->unconsume(); 11595 } 11596 11597 $consumed_length = strlen($this->consumed); 11598 $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length); 11599 $this->position += strlen($replacement) - $consumed_length; 11600 } 11601 break; 11602 11603 default: 11604 static $entities = array('Aacute' => "\xC3\x81", 'aacute' => "\xC3\xA1", 'Aacute;' => "\xC3\x81", 'aacute;' => "\xC3\xA1", 'Acirc' => "\xC3\x82", 'acirc' => "\xC3\xA2", 'Acirc;' => "\xC3\x82", 'acirc;' => "\xC3\xA2", 'acute' => "\xC2\xB4", 'acute;' => "\xC2\xB4", 'AElig' => "\xC3\x86", 'aelig' => "\xC3\xA6", 'AElig;' => "\xC3\x86", 'aelig;' => "\xC3\xA6", 'Agrave' => "\xC3\x80", 'agrave' => "\xC3\xA0", 'Agrave;' => "\xC3\x80", 'agrave;' => "\xC3\xA0", 'alefsym;' => "\xE2\x84\xB5", 'Alpha;' => "\xCE\x91", 'alpha;' => "\xCE\xB1", 'AMP' => "\x26", 'amp' => "\x26", 'AMP;' => "\x26", 'amp;' => "\x26", 'and;' => "\xE2\x88\xA7", 'ang;' => "\xE2\x88\xA0", 'apos;' => "\x27", 'Aring' => "\xC3\x85", 'aring' => "\xC3\xA5", 'Aring;' => "\xC3\x85", 'aring;' => "\xC3\xA5", 'asymp;' => "\xE2\x89\x88", 'Atilde' => "\xC3\x83", 'atilde' => "\xC3\xA3", 'Atilde;' => "\xC3\x83", 'atilde;' => "\xC3\xA3", 'Auml' => "\xC3\x84", 'auml' => "\xC3\xA4", 'Auml;' => "\xC3\x84", 'auml;' => "\xC3\xA4", 'bdquo;' => "\xE2\x80\x9E", 'Beta;' => "\xCE\x92", 'beta;' => "\xCE\xB2", 'brvbar' => "\xC2\xA6", 'brvbar;' => "\xC2\xA6", 'bull;' => "\xE2\x80\xA2", 'cap;' => "\xE2\x88\xA9", 'Ccedil' => "\xC3\x87", 'ccedil' => "\xC3\xA7", 'Ccedil;' => "\xC3\x87", 'ccedil;' => "\xC3\xA7", 'cedil' => "\xC2\xB8", 'cedil;' => "\xC2\xB8", 'cent' => "\xC2\xA2", 'cent;' => "\xC2\xA2", 'Chi;' => "\xCE\xA7", 'chi;' => "\xCF\x87", 'circ;' => "\xCB\x86", 'clubs;' => "\xE2\x99\xA3", 'cong;' => "\xE2\x89\x85", 'COPY' => "\xC2\xA9", 'copy' => "\xC2\xA9", 'COPY;' => "\xC2\xA9", 'copy;' => "\xC2\xA9", 'crarr;' => "\xE2\x86\xB5", 'cup;' => "\xE2\x88\xAA", 'curren' => "\xC2\xA4", 'curren;' => "\xC2\xA4", 'Dagger;' => "\xE2\x80\xA1", 'dagger;' => "\xE2\x80\xA0", 'dArr;' => "\xE2\x87\x93", 'darr;' => "\xE2\x86\x93", 'deg' => "\xC2\xB0", 'deg;' => "\xC2\xB0", 'Delta;' => "\xCE\x94", 'delta;' => "\xCE\xB4", 'diams;' => "\xE2\x99\xA6", 'divide' => "\xC3\xB7", 'divide;' => "\xC3\xB7", 'Eacute' => "\xC3\x89", 'eacute' => "\xC3\xA9", 'Eacute;' => "\xC3\x89", 'eacute;' => "\xC3\xA9", 'Ecirc' => "\xC3\x8A", 'ecirc' => "\xC3\xAA", 'Ecirc;' => "\xC3\x8A", 'ecirc;' => "\xC3\xAA", 'Egrave' => "\xC3\x88", 'egrave' => "\xC3\xA8", 'Egrave;' => "\xC3\x88", 'egrave;' => "\xC3\xA8", 'empty;' => "\xE2\x88\x85", 'emsp;' => "\xE2\x80\x83", 'ensp;' => "\xE2\x80\x82", 'Epsilon;' => "\xCE\x95", 'epsilon;' => "\xCE\xB5", 'equiv;' => "\xE2\x89\xA1", 'Eta;' => "\xCE\x97", 'eta;' => "\xCE\xB7", 'ETH' => "\xC3\x90", 'eth' => "\xC3\xB0", 'ETH;' => "\xC3\x90", 'eth;' => "\xC3\xB0", 'Euml' => "\xC3\x8B", 'euml' => "\xC3\xAB", 'Euml;' => "\xC3\x8B", 'euml;' => "\xC3\xAB", 'euro;' => "\xE2\x82\xAC", 'exist;' => "\xE2\x88\x83", 'fnof;' => "\xC6\x92", 'forall;' => "\xE2\x88\x80", 'frac12' => "\xC2\xBD", 'frac12;' => "\xC2\xBD", 'frac14' => "\xC2\xBC", 'frac14;' => "\xC2\xBC", 'frac34' => "\xC2\xBE", 'frac34;' => "\xC2\xBE", 'frasl;' => "\xE2\x81\x84", 'Gamma;' => "\xCE\x93", 'gamma;' => "\xCE\xB3", 'ge;' => "\xE2\x89\xA5", 'GT' => "\x3E", 'gt' => "\x3E", 'GT;' => "\x3E", 'gt;' => "\x3E", 'hArr;' => "\xE2\x87\x94", 'harr;' => "\xE2\x86\x94", 'hearts;' => "\xE2\x99\xA5", 'hellip;' => "\xE2\x80\xA6", 'Iacute' => "\xC3\x8D", 'iacute' => "\xC3\xAD", 'Iacute;' => "\xC3\x8D", 'iacute;' => "\xC3\xAD", 'Icirc' => "\xC3\x8E", 'icirc' => "\xC3\xAE", 'Icirc;' => "\xC3\x8E", 'icirc;' => "\xC3\xAE", 'iexcl' => "\xC2\xA1", 'iexcl;' => "\xC2\xA1", 'Igrave' => "\xC3\x8C", 'igrave' => "\xC3\xAC", 'Igrave;' => "\xC3\x8C", 'igrave;' => "\xC3\xAC", 'image;' => "\xE2\x84\x91", 'infin;' => "\xE2\x88\x9E", 'int;' => "\xE2\x88\xAB", 'Iota;' => "\xCE\x99", 'iota;' => "\xCE\xB9", 'iquest' => "\xC2\xBF", 'iquest;' => "\xC2\xBF", 'isin;' => "\xE2\x88\x88", 'Iuml' => "\xC3\x8F", 'iuml' => "\xC3\xAF", 'Iuml;' => "\xC3\x8F", 'iuml;' => "\xC3\xAF", 'Kappa;' => "\xCE\x9A", 'kappa;' => "\xCE\xBA", 'Lambda;' => "\xCE\x9B", 'lambda;' => "\xCE\xBB", 'lang;' => "\xE3\x80\x88", 'laquo' => "\xC2\xAB", 'laquo;' => "\xC2\xAB", 'lArr;' => "\xE2\x87\x90", 'larr;' => "\xE2\x86\x90", 'lceil;' => "\xE2\x8C\x88", 'ldquo;' => "\xE2\x80\x9C", 'le;' => "\xE2\x89\xA4", 'lfloor;' => "\xE2\x8C\x8A", 'lowast;' => "\xE2\x88\x97", 'loz;' => "\xE2\x97\x8A", 'lrm;' => "\xE2\x80\x8E", 'lsaquo;' => "\xE2\x80\xB9", 'lsquo;' => "\xE2\x80\x98", 'LT' => "\x3C", 'lt' => "\x3C", 'LT;' => "\x3C", 'lt;' => "\x3C", 'macr' => "\xC2\xAF", 'macr;' => "\xC2\xAF", 'mdash;' => "\xE2\x80\x94", 'micro' => "\xC2\xB5", 'micro;' => "\xC2\xB5", 'middot' => "\xC2\xB7", 'middot;' => "\xC2\xB7", 'minus;' => "\xE2\x88\x92", 'Mu;' => "\xCE\x9C", 'mu;' => "\xCE\xBC", 'nabla;' => "\xE2\x88\x87", 'nbsp' => "\xC2\xA0", 'nbsp;' => "\xC2\xA0", 'ndash;' => "\xE2\x80\x93", 'ne;' => "\xE2\x89\xA0", 'ni;' => "\xE2\x88\x8B", 'not' => "\xC2\xAC", 'not;' => "\xC2\xAC", 'notin;' => "\xE2\x88\x89", 'nsub;' => "\xE2\x8A\x84", 'Ntilde' => "\xC3\x91", 'ntilde' => "\xC3\xB1", 'Ntilde;' => "\xC3\x91", 'ntilde;' => "\xC3\xB1", 'Nu;' => "\xCE\x9D", 'nu;' => "\xCE\xBD", 'Oacute' => "\xC3\x93", 'oacute' => "\xC3\xB3", 'Oacute;' => "\xC3\x93", 'oacute;' => "\xC3\xB3", 'Ocirc' => "\xC3\x94", 'ocirc' => "\xC3\xB4", 'Ocirc;' => "\xC3\x94", 'ocirc;' => "\xC3\xB4", 'OElig;' => "\xC5\x92", 'oelig;' => "\xC5\x93", 'Ograve' => "\xC3\x92", 'ograve' => "\xC3\xB2", 'Ograve;' => "\xC3\x92", 'ograve;' => "\xC3\xB2", 'oline;' => "\xE2\x80\xBE", 'Omega;' => "\xCE\xA9", 'omega;' => "\xCF\x89", 'Omicron;' => "\xCE\x9F", 'omicron;' => "\xCE\xBF", 'oplus;' => "\xE2\x8A\x95", 'or;' => "\xE2\x88\xA8", 'ordf' => "\xC2\xAA", 'ordf;' => "\xC2\xAA", 'ordm' => "\xC2\xBA", 'ordm;' => "\xC2\xBA", 'Oslash' => "\xC3\x98", 'oslash' => "\xC3\xB8", 'Oslash;' => "\xC3\x98", 'oslash;' => "\xC3\xB8", 'Otilde' => "\xC3\x95", 'otilde' => "\xC3\xB5", 'Otilde;' => "\xC3\x95", 'otilde;' => "\xC3\xB5", 'otimes;' => "\xE2\x8A\x97", 'Ouml' => "\xC3\x96", 'ouml' => "\xC3\xB6", 'Ouml;' => "\xC3\x96", 'ouml;' => "\xC3\xB6", 'para' => "\xC2\xB6", 'para;' => "\xC2\xB6", 'part;' => "\xE2\x88\x82", 'permil;' => "\xE2\x80\xB0", 'perp;' => "\xE2\x8A\xA5", 'Phi;' => "\xCE\xA6", 'phi;' => "\xCF\x86", 'Pi;' => "\xCE\xA0", 'pi;' => "\xCF\x80", 'piv;' => "\xCF\x96", 'plusmn' => "\xC2\xB1", 'plusmn;' => "\xC2\xB1", 'pound' => "\xC2\xA3", 'pound;' => "\xC2\xA3", 'Prime;' => "\xE2\x80\xB3", 'prime;' => "\xE2\x80\xB2", 'prod;' => "\xE2\x88\x8F", 'prop;' => "\xE2\x88\x9D", 'Psi;' => "\xCE\xA8", 'psi;' => "\xCF\x88", 'QUOT' => "\x22", 'quot' => "\x22", 'QUOT;' => "\x22", 'quot;' => "\x22", 'radic;' => "\xE2\x88\x9A", 'rang;' => "\xE3\x80\x89", 'raquo' => "\xC2\xBB", 'raquo;' => "\xC2\xBB", 'rArr;' => "\xE2\x87\x92", 'rarr;' => "\xE2\x86\x92", 'rceil;' => "\xE2\x8C\x89", 'rdquo;' => "\xE2\x80\x9D", 'real;' => "\xE2\x84\x9C", 'REG' => "\xC2\xAE", 'reg' => "\xC2\xAE", 'REG;' => "\xC2\xAE", 'reg;' => "\xC2\xAE", 'rfloor;' => "\xE2\x8C\x8B", 'Rho;' => "\xCE\xA1", 'rho;' => "\xCF\x81", 'rlm;' => "\xE2\x80\x8F", 'rsaquo;' => "\xE2\x80\xBA", 'rsquo;' => "\xE2\x80\x99", 'sbquo;' => "\xE2\x80\x9A", 'Scaron;' => "\xC5\xA0", 'scaron;' => "\xC5\xA1", 'sdot;' => "\xE2\x8B\x85", 'sect' => "\xC2\xA7", 'sect;' => "\xC2\xA7", 'shy' => "\xC2\xAD", 'shy;' => "\xC2\xAD", 'Sigma;' => "\xCE\xA3", 'sigma;' => "\xCF\x83", 'sigmaf;' => "\xCF\x82", 'sim;' => "\xE2\x88\xBC", 'spades;' => "\xE2\x99\xA0", 'sub;' => "\xE2\x8A\x82", 'sube;' => "\xE2\x8A\x86", 'sum;' => "\xE2\x88\x91", 'sup;' => "\xE2\x8A\x83", 'sup1' => "\xC2\xB9", 'sup1;' => "\xC2\xB9", 'sup2' => "\xC2\xB2", 'sup2;' => "\xC2\xB2", 'sup3' => "\xC2\xB3", 'sup3;' => "\xC2\xB3", 'supe;' => "\xE2\x8A\x87", 'szlig' => "\xC3\x9F", 'szlig;' => "\xC3\x9F", 'Tau;' => "\xCE\xA4", 'tau;' => "\xCF\x84", 'there4;' => "\xE2\x88\xB4", 'Theta;' => "\xCE\x98", 'theta;' => "\xCE\xB8", 'thetasym;' => "\xCF\x91", 'thinsp;' => "\xE2\x80\x89", 'THORN' => "\xC3\x9E", 'thorn' => "\xC3\xBE", 'THORN;' => "\xC3\x9E", 'thorn;' => "\xC3\xBE", 'tilde;' => "\xCB\x9C", 'times' => "\xC3\x97", 'times;' => "\xC3\x97", 'TRADE;' => "\xE2\x84\xA2", 'trade;' => "\xE2\x84\xA2", 'Uacute' => "\xC3\x9A", 'uacute' => "\xC3\xBA", 'Uacute;' => "\xC3\x9A", 'uacute;' => "\xC3\xBA", 'uArr;' => "\xE2\x87\x91", 'uarr;' => "\xE2\x86\x91", 'Ucirc' => "\xC3\x9B", 'ucirc' => "\xC3\xBB", 'Ucirc;' => "\xC3\x9B", 'ucirc;' => "\xC3\xBB", 'Ugrave' => "\xC3\x99", 'ugrave' => "\xC3\xB9", 'Ugrave;' => "\xC3\x99", 'ugrave;' => "\xC3\xB9", 'uml' => "\xC2\xA8", 'uml;' => "\xC2\xA8", 'upsih;' => "\xCF\x92", 'Upsilon;' => "\xCE\xA5", 'upsilon;' => "\xCF\x85", 'Uuml' => "\xC3\x9C", 'uuml' => "\xC3\xBC", 'Uuml;' => "\xC3\x9C", 'uuml;' => "\xC3\xBC", 'weierp;' => "\xE2\x84\x98", 'Xi;' => "\xCE\x9E", 'xi;' => "\xCE\xBE", 'Yacute' => "\xC3\x9D", 'yacute' => "\xC3\xBD", 'Yacute;' => "\xC3\x9D", 'yacute;' => "\xC3\xBD", 'yen' => "\xC2\xA5", 'yen;' => "\xC2\xA5", 'yuml' => "\xC3\xBF", 'Yuml;' => "\xC5\xB8", 'yuml;' => "\xC3\xBF", 'Zeta;' => "\xCE\x96", 'zeta;' => "\xCE\xB6", 'zwj;' => "\xE2\x80\x8D", 'zwnj;' => "\xE2\x80\x8C"); 11605 11606 for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++) 11607 { 11608 $consumed = substr($this->consumed, 1); 11609 if (isset($entities[$consumed])) 11610 { 11611 $match = $consumed; 11612 } 11613 } 11614 11615 if ($match !== null) 11616 { 11617 $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1); 11618 $this->position += strlen($entities[$match]) - strlen($consumed) - 1; 11619 } 11620 break; 11621 } 11622 } 11623 } 11624 11625 /** 11626 * IRI parser/serialiser 11627 * 11628 * @package SimplePie 11629 */ 11630 class SimplePie_IRI 11631 { 11632 /** 11633 * Scheme 11634 * 11635 * @access private 11636 * @var string 11637 */ 11638 var $scheme; 11639 11640 /** 11641 * User Information 11642 * 11643 * @access private 11644 * @var string 11645 */ 11646 var $userinfo; 11647 11648 /** 11649 * Host 11650 * 11651 * @access private 11652 * @var string 11653 */ 11654 var $host; 11655 11656 /** 11657 * Port 11658 * 11659 * @access private 11660 * @var string 11661 */ 11662 var $port; 11663 11664 /** 11665 * Path 11666 * 11667 * @access private 11668 * @var string 11669 */ 11670 var $path; 11671 11672 /** 11673 * Query 11674 * 11675 * @access private 11676 * @var string 11677 */ 11678 var $query; 11679 11680 /** 11681 * Fragment 11682 * 11683 * @access private 11684 * @var string 11685 */ 11686 var $fragment; 11687 11688 /** 11689 * Whether the object represents a valid IRI 11690 * 11691 * @access private 11692 * @var array 11693 */ 11694 var $valid = array(); 11695 11696 /** 11697 * Return the entire IRI when you try and read the object as a string 11698 * 11699 * @access public 11700 * @return string 11701 */ 11702 function __toString() 11703 { 11704 return $this->get_iri(); 11705 } 11706 11707 /** 11708 * Create a new IRI object, from a specified string 11709 * 11710 * @access public 11711 * @param string $iri 11712 * @return SimplePie_IRI 11713 */ 11714 function SimplePie_IRI($iri) 11715 { 11716 $iri = (string) $iri; 11717 if ($iri !== '') 11718 { 11719 $parsed = $this->parse_iri($iri); 11720 $this->set_scheme($parsed['scheme']); 11721 $this->set_authority($parsed['authority']); 11722 $this->set_path($parsed['path']); 11723 $this->set_query($parsed['query']); 11724 $this->set_fragment($parsed['fragment']); 11725 } 11726 } 11727 11728 /** 11729 * Create a new IRI object by resolving a relative IRI 11730 * 11731 * @static 11732 * @access public 11733 * @param SimplePie_IRI $base Base IRI 11734 * @param string $relative Relative IRI 11735 * @return SimplePie_IRI 11736 */ 11737 function absolutize($base, $relative) 11738 { 11739 $relative = (string) $relative; 11740 if ($relative !== '') 11741 { 11742 $relative =& new SimplePie_IRI($relative); 11743 if ($relative->get_scheme() !== null) 11744 { 11745 $target = $relative; 11746 } 11747 elseif ($base->get_iri() !== null) 11748 { 11749 if ($relative->get_authority() !== null) 11750 { 11751 $target = $relative; 11752 $target->set_scheme($base->get_scheme()); 11753 } 11754 else 11755 { 11756 $target =& new SimplePie_IRI(''); 11757 $target->set_scheme($base->get_scheme()); 11758 $target->set_userinfo($base->get_userinfo()); 11759 $target->set_host($base->get_host()); 11760 $target->set_port($base->get_port()); 11761 if ($relative->get_path() !== null) 11762 { 11763 if (strpos($relative->get_path(), '/') === 0) 11764 { 11765 $target->set_path($relative->get_path()); 11766 } 11767 elseif (($base->get_userinfo() !== null || $base->get_host() !== null || $base->get_port() !== null) && $base->get_path() === null) 11768 { 11769 $target->set_path('/' . $relative->get_path()); 11770 } 11771 elseif (($last_segment = strrpos($base->get_path(), '/')) !== false) 11772 { 11773 $target->set_path(substr($base->get_path(), 0, $last_segment + 1) . $relative->get_path()); 11774 } 11775 else 11776 { 11777 $target->set_path($relative->get_path()); 11778 } 11779 $target->set_query($relative->get_query()); 11780 } 11781 else 11782 { 11783 $target->set_path($base->get_path()); 11784 if ($relative->get_query() !== null) 11785 { 11786 $target->set_query($relative->get_query()); 11787 } 11788 elseif ($base->get_query() !== null) 11789 { 11790 $target->set_query($base->get_query()); 11791 } 11792 } 11793 } 11794 $target->set_fragment($relative->get_fragment()); 11795 } 11796 else 11797 { 11798 // No base URL, just return the relative URL 11799 $target = $relative; 11800 } 11801 } 11802 else 11803 { 11804 $target = $base; 11805 } 11806 return $target; 11807 } 11808 11809 /** 11810 * Parse an IRI into scheme/authority/path/query/fragment segments 11811 * 11812 * @access private 11813 * @param string $iri 11814 * @return array 11815 */ 11816 function parse_iri($iri) 11817 { 11818 preg_match('/^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/', $iri, $match); 11819 for ($i = count($match); $i <= 9; $i++) 11820 { 11821 $match[$i] = ''; 11822 } 11823 return array('scheme' => $match[2], 'authority' => $match[4], 'path' => $match[5], 'query' => $match[7], 'fragment' => $match[9]); 11824 } 11825 11826 /** 11827 * Remove dot segments from a path 11828 * 11829 * @access private 11830 * @param string $input 11831 * @return string 11832 */ 11833 function remove_dot_segments($input) 11834 { 11835 $output = ''; 11836 while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..') 11837 { 11838 // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise, 11839 if (strpos($input, '../') === 0) 11840 { 11841 $input = substr($input, 3); 11842 } 11843 elseif (strpos($input, './') === 0) 11844 { 11845 $input = substr($input, 2); 11846 } 11847 // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise, 11848 elseif (strpos($input, '/./') === 0) 11849 { 11850 $input = substr_replace($input, '/', 0, 3); 11851 } 11852 elseif ($input === '/.') 11853 { 11854 $input = '/'; 11855 } 11856 // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise, 11857 elseif (strpos($input, '/../') === 0) 11858 { 11859 $input = substr_replace($input, '/', 0, 4); 11860 $output = substr_replace($output, '', strrpos($output, '/')); 11861 } 11862 elseif ($input === '/..') 11863 { 11864 $input = '/'; 11865 $output = substr_replace($output, '', strrpos($output, '/')); 11866 } 11867 // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise, 11868 elseif ($input === '.' || $input === '..') 11869 { 11870 $input = ''; 11871 } 11872 // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer 11873 elseif (($pos = strpos($input, '/', 1)) !== false) 11874 { 11875 $output .= substr($input, 0, $pos); 11876 $input = substr_replace($input, '', 0, $pos); 11877 } 11878 else 11879 { 11880 $output .= $input; 11881 $input = ''; 11882 } 11883 } 11884 return $output . $input; 11885 } 11886 11887 /** 11888 * Replace invalid character with percent encoding 11889 * 11890 * @access private 11891 * @param string $string Input string 11892 * @param string $valid_chars Valid characters 11893 * @param int $case Normalise case 11894 * @return string 11895 */ 11896 function replace_invalid_with_pct_encoding($string, $valid_chars, $case = SIMPLEPIE_SAME_CASE) 11897 { 11898 // Normalise case 11899 if ($case & SIMPLEPIE_LOWERCASE) 11900 { 11901 $string = strtolower($string); 11902 } 11903 elseif ($case & SIMPLEPIE_UPPERCASE) 11904 { 11905 $string = strtoupper($string); 11906 } 11907 11908 // Store position and string length (to avoid constantly recalculating this) 11909 $position = 0; 11910 $strlen = strlen($string); 11911 11912 // Loop as long as we have invalid characters, advancing the position to the next invalid character 11913 while (($position += strspn($string, $valid_chars, $position)) < $strlen) 11914 { 11915 // If we have a % character 11916 if ($string[$position] === '%') 11917 { 11918 // If we have a pct-encoded section 11919 if ($position + 2 < $strlen && strspn($string, '0123456789ABCDEFabcdef', $position + 1, 2) === 2) 11920 { 11921 // Get the the represented character 11922 $chr = chr(hexdec(substr($string, $position + 1, 2))); 11923 11924 // If the character is valid, replace the pct-encoded with the actual character while normalising case 11925 if (strpos($valid_chars, $chr) !== false) 11926 { 11927 if ($case & SIMPLEPIE_LOWERCASE) 11928 { 11929 $chr = strtolower($chr); 11930 } 11931 elseif ($case & SIMPLEPIE_UPPERCASE) 11932 { 11933 $chr = strtoupper($chr); 11934 } 11935 $string = substr_replace($string, $chr, $position, 3); 11936 $strlen -= 2; 11937 $position++; 11938 } 11939 11940 // Otherwise just normalise the pct-encoded to uppercase 11941 else 11942 { 11943 $string = substr_replace($string, strtoupper(substr($string, $position + 1, 2)), $position + 1, 2); 11944 $position += 3; 11945 } 11946 } 11947 // If we don't have a pct-encoded section, just replace the % with its own esccaped form 11948 else 11949 { 11950 $string = substr_replace($string, '%25', $position, 1); 11951 $strlen += 2; 11952 $position += 3; 11953 } 11954 } 11955 // If we have an invalid character, change into its pct-encoded form 11956 else 11957 { 11958 $replacement = sprintf("%%%02X", ord($string[$position])); 11959 $string = str_replace($string[$position], $replacement, $string); 11960 $strlen = strlen($string); 11961 } 11962 } 11963 return $string; 11964 } 11965 11966 /** 11967 * Check if the object represents a valid IRI 11968 * 11969 * @access public 11970 * @return bool 11971 */ 11972 function is_valid() 11973 { 11974 return array_sum($this->valid) === count($this->valid); 11975 } 11976 11977 /** 11978 * Set the scheme. Returns true on success, false on failure (if there are 11979 * any invalid characters). 11980 * 11981 * @access public 11982 * @param string $scheme 11983 * @return bool 11984 */ 11985 function set_scheme($scheme) 11986 { 11987 if ($scheme === null || $scheme === '') 11988 { 11989 $this->scheme = null; 11990 } 11991 else 11992 { 11993 $len = strlen($scheme); 11994 switch (true) 11995 { 11996 case $len > 1: 11997 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-.', 1)) 11998 { 11999 $this->scheme = null; 12000 $this->valid[__FUNCTION__] = false; 12001 return false; 12002 } 12003 12004 case $len > 0: 12005 if (!strspn($scheme, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 0, 1)) 12006 { 12007 $this->scheme = null; 12008 $this->valid[__FUNCTION__] = false; 12009 return false; 12010 } 12011 } 12012 $this->scheme = strtolower($scheme); 12013 } 12014 $this->valid[__FUNCTION__] = true; 12015 return true; 12016 } 12017 12018 /** 12019 * Set the authority. Returns true on success, false on failure (if there are 12020 * any invalid characters). 12021 * 12022 * @access public 12023 * @param string $authority 12024 * @return bool 12025 */ 12026 function set_authority($authority) 12027 { 12028 if (($userinfo_end = strrpos($authority, '@')) !== false) 12029 { 12030 $userinfo = substr($authority, 0, $userinfo_end); 12031 $authority = substr($authority, $userinfo_end + 1); 12032 } 12033 else 12034 { 12035 $userinfo = null; 12036 } 12037 12038 if (($port_start = strpos($authority, ':')) !== false) 12039 { 12040 $port = substr($authority, $port_start + 1); 12041 $authority = substr($authority, 0, $port_start); 12042 } 12043 else 12044 { 12045 $port = null; 12046 } 12047 12048 return $this->set_userinfo($userinfo) && $this->set_host($authority) && $this->set_port($port); 12049 } 12050 12051 /** 12052 * Set the userinfo. 12053 * 12054 * @access public 12055 * @param string $userinfo 12056 * @return bool 12057 */ 12058 function set_userinfo($userinfo) 12059 { 12060 if ($userinfo === null || $userinfo === '') 12061 { 12062 $this->userinfo = null; 12063 } 12064 else 12065 { 12066 $this->userinfo = $this->replace_invalid_with_pct_encoding($userinfo, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:'); 12067 } 12068 $this->valid[__FUNCTION__] = true; 12069 return true; 12070 } 12071 12072 /** 12073 * Set the host. Returns true on success, false on failure (if there are 12074 * any invalid characters). 12075 * 12076 * @access public 12077 * @param string $host 12078 * @return bool 12079 */ 12080 function set_host($host) 12081 { 12082 if ($host === null || $host === '') 12083 { 12084 $this->host = null; 12085 $this->valid[__FUNCTION__] = true; 12086 return true; 12087 } 12088 elseif ($host[0] === '[' && substr($host, -1) === ']') 12089 { 12090 if (Net_IPv6::checkIPv6(substr($host, 1, -1))) 12091 { 12092 $this->host = $host; 12093 $this->valid[__FUNCTION__] = true; 12094 return true; 12095 } 12096 else 12097 { 12098 $this->host = null; 12099 $this->valid[__FUNCTION__] = false; 12100 return false; 12101 } 12102 } 12103 else 12104 { 12105 $this->host = $this->replace_invalid_with_pct_encoding($host, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=', SIMPLEPIE_LOWERCASE); 12106 $this->valid[__FUNCTION__] = true; 12107 return true; 12108 } 12109 } 12110 12111 /** 12112 * Set the port. Returns true on success, false on failure (if there are 12113 * any invalid characters). 12114 * 12115 * @access public 12116 * @param string $port 12117 * @return bool 12118 */ 12119 function set_port($port) 12120 { 12121 if ($port === null || $port === '') 12122 { 12123 $this->port = null; 12124 $this->valid[__FUNCTION__] = true; 12125 return true; 12126 } 12127 elseif (strspn($port, '0123456789') === strlen($port)) 12128 { 12129 $this->port = (int) $port; 12130 $this->valid[__FUNCTION__] = true; 12131 return true; 12132 } 12133 else 12134 { 12135 $this->port = null; 12136 $this->valid[__FUNCTION__] = false; 12137 return false; 12138 } 12139 } 12140 12141 /** 12142 * Set the path. 12143 * 12144 * @access public 12145 * @param string $path 12146 * @return bool 12147 */ 12148 function set_path($path) 12149 { 12150 if ($path === null || $path === '') 12151 { 12152 $this->path = null; 12153 $this->valid[__FUNCTION__] = true; 12154 return true; 12155 } 12156 elseif (substr($path, 0, 2) === '//' && $this->userinfo === null && $this->host === null && $this->port === null) 12157 { 12158 $this->path = null; 12159 $this->valid[__FUNCTION__] = false; 12160 return false; 12161 } 12162 else 12163 { 12164 $this->path = $this->replace_invalid_with_pct_encoding($path, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=@/'); 12165 if ($this->scheme !== null) 12166 { 12167 $this->path = $this->remove_dot_segments($this->path); 12168 } 12169 $this->valid[__FUNCTION__] = true; 12170 return true; 12171 } 12172 } 12173 12174 /** 12175 * Set the query. 12176 * 12177 * @access public 12178 * @param string $query 12179 * @return bool 12180 */ 12181 function set_query($query) 12182 { 12183 if ($query === null || $query === '') 12184 { 12185 $this->query = null; 12186 } 12187 else 12188 { 12189 $this->query = $this->replace_invalid_with_pct_encoding($query, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$\'()*+,;:@/?'); 12190 } 12191 $this->valid[__FUNCTION__] = true; 12192 return true; 12193 } 12194 12195 /** 12196 * Set the fragment. 12197 * 12198 * @access public 12199 * @param string $fragment 12200 * @return bool 12201 */ 12202 function set_fragment($fragment) 12203 { 12204 if ($fragment === null || $fragment === '') 12205 { 12206 $this->fragment = null; 12207 } 12208 else 12209 { 12210 $this->fragment = $this->replace_invalid_with_pct_encoding($fragment, 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~!$&\'()*+,;=:@/?'); 12211 } 12212 $this->valid[__FUNCTION__] = true; 12213 return true; 12214 } 12215 12216 /** 12217 * Get the complete IRI 12218 * 12219 * @access public 12220 * @return string 12221 */ 12222 function get_iri() 12223 { 12224 $iri = ''; 12225 if ($this->scheme !== null) 12226 { 12227 $iri .= $this->scheme . ':'; 12228 } 12229 if (($authority = $this->get_authority()) !== null) 12230 { 12231 $iri .= '//' . $authority; 12232 } 12233 if ($this->path !== null) 12234 { 12235 $iri .= $this->path; 12236 } 12237 if ($this->query !== null) 12238 { 12239 $iri .= '?' . $this->query; 12240 } 12241 if ($this->fragment !== null) 12242 { 12243 $iri .= '#' . $this->fragment; 12244 } 12245 12246 if ($iri !== '') 12247 { 12248 return $iri; 12249 } 12250 else 12251 { 12252 return null; 12253 } 12254 } 12255 12256 /** 12257 * Get the scheme 12258 * 12259 * @access public 12260 * @return string 12261 */ 12262 function get_scheme() 12263 { 12264 return $this->scheme; 12265 } 12266 12267 /** 12268 * Get the complete authority 12269 * 12270 * @access public 12271 * @return string 12272 */ 12273 function get_authority() 12274 { 12275 $authority = ''; 12276 if ($this->userinfo !== null) 12277 { 12278 $authority .= $this->userinfo . '@'; 12279 } 12280 if ($this->host !== null) 12281 { 12282 $authority .= $this->host; 12283 } 12284 if ($this->port !== null) 12285 { 12286 $authority .= ':' . $this->port; 12287 } 12288 12289 if ($authority !== '') 12290 { 12291 return $authority; 12292 } 12293 else 12294 { 12295 return null; 12296 } 12297 } 12298 12299 /** 12300 * Get the user information 12301 * 12302 * @access public 12303 * @return string 12304 */ 12305 function get_userinfo() 12306 { 12307 return $this->userinfo; 12308 } 12309 12310 /** 12311 * Get the host 12312 * 12313 * @access public 12314 * @return string 12315 */ 12316 function get_host() 12317 { 12318 return $this->host; 12319 } 12320 12321 /** 12322 * Get the port 12323 * 12324 * @access public 12325 * @return string 12326 */ 12327 function get_port() 12328 { 12329 return $this->port; 12330 } 12331 12332 /** 12333 * Get the path 12334 * 12335 * @access public 12336 * @return string 12337 */ 12338 function get_path() 12339 { 12340 return $this->path; 12341 } 12342 12343 /** 12344 * Get the query 12345 * 12346 * @access public 12347 * @return string 12348 */ 12349 function get_query() 12350 { 12351 return $this->query; 12352 } 12353 12354 /** 12355 * Get the fragment 12356 * 12357 * @access public 12358 * @return string 12359 */ 12360 function get_fragment() 12361 { 12362 return $this->fragment; 12363 } 12364 } 12365 12366 /** 12367 * Class to validate and to work with IPv6 addresses. 12368 * 12369 * @package SimplePie 12370 * @copyright 2003-2005 The PHP Group 12371 * @license http://www.opensource.org/licenses/bsd-license.php 12372 * @link http://pear.php.net/package/Net_IPv6 12373 * @author Alexander Merz <alexander.merz@web.de> 12374 * @author elfrink at introweb dot nl 12375 * @author Josh Peck <jmp at joshpeck dot org> 12376 * @author Geoffrey Sneddon <geoffers@gmail.com> 12377 */ 12378 class SimplePie_Net_IPv6 12379 { 12380 /** 12381 * Removes a possible existing netmask specification of an IP address. 12382 * 12383 * @param string $ip the (compressed) IP as Hex representation 12384 * @return string the IP the without netmask 12385 * @since 1.1.0 12386 * @access public 12387 * @static 12388 */ 12389 function removeNetmaskSpec($ip) 12390 { 12391 if (strpos($ip, '/') !== false) 12392 { 12393 list($addr, $nm) = explode('/', $ip); 12394 } 12395 else 12396 { 12397 $addr = $ip; 12398 } 12399 return $addr; 12400 } 12401 12402 /** 12403 * Uncompresses an IPv6 address 12404 * 12405 * RFC 2373 allows you to compress zeros in an address to '::'. This 12406 * function expects an valid IPv6 address and expands the '::' to 12407 * the required zeros. 12408 * 12409 * Example: FF01::101 -> FF01:0:0:0:0:0:0:101 12410 * ::1 -> 0:0:0:0:0:0:0:1 12411 * 12412 * @access public 12413 * @static 12414 * @param string $ip a valid IPv6-address (hex format) 12415 * @return string the uncompressed IPv6-address (hex format) 12416 */ 12417 function Uncompress($ip) 12418 { 12419 $uip = SimplePie_Net_IPv6::removeNetmaskSpec($ip); 12420 $c1 = -1; 12421 $c2 = -1; 12422 if (strpos($ip, '::') !== false) 12423 { 12424 list($ip1, $ip2) = explode('::', $ip); 12425 if ($ip1 === '') 12426 { 12427 $c1 = -1; 12428 } 12429 else 12430 { 12431 $pos = 0; 12432 if (($pos = substr_count($ip1, ':')) > 0) 12433 { 12434 $c1 = $pos; 12435 } 12436 else 12437 { 12438 $c1 = 0; 12439 } 12440 } 12441 if ($ip2 === '') 12442 { 12443 $c2 = -1; 12444 } 12445 else 12446 { 12447 $pos = 0; 12448 if (($pos = substr_count($ip2, ':')) > 0) 12449 { 12450 $c2 = $pos; 12451 } 12452 else 12453 { 12454 $c2 = 0; 12455 } 12456 } 12457 if (strstr($ip2, '.')) 12458 { 12459 $c2++; 12460 } 12461 // :: 12462 if ($c1 === -1 && $c2 === -1) 12463 { 12464 $uip = '0:0:0:0:0:0:0:0'; 12465 } 12466 // ::xxx 12467 else if ($c1 === -1) 12468 { 12469 $fill = str_repeat('0:', 7 - $c2); 12470 $uip = str_replace('::', $fill, $uip); 12471 } 12472 // xxx:: 12473 else if ($c2 === -1) 12474 { 12475 $fill = str_repeat(':0', 7 - $c1); 12476 $uip = str_replace('::', $fill, $uip); 12477 } 12478 // xxx::xxx 12479 else 12480 { 12481 $fill = str_repeat(':0:', 6 - $c2 - $c1); 12482 $uip = str_replace('::', $fill, $uip); 12483 $uip = str_replace('::', ':', $uip); 12484 } 12485 } 12486 return $uip; 12487 } 12488 12489 /** 12490 * Splits an IPv6 address into the IPv6 and a possible IPv4 part 12491 * 12492 * RFC 2373 allows you to note the last two parts of an IPv6 address as 12493 * an IPv4 compatible address 12494 * 12495 * Example: 0:0:0:0:0:0:13.1.68.3 12496 * 0:0:0:0:0:FFFF:129.144.52.38 12497 * 12498 * @access public 12499 * @static 12500 * @param string $ip a valid IPv6-address (hex format) 12501 * @return array [0] contains the IPv6 part, [1] the IPv4 part (hex format) 12502 */ 12503 function SplitV64($ip) 12504 { 12505 $ip = SimplePie_Net_IPv6::Uncompress($ip); 12506 if (strstr($ip, '.')) 12507 { 12508 $pos = strrpos($ip, ':'); 12509 $ip[$pos] = '_'; 12510 $ipPart = explode('_', $ip); 12511 return $ipPart; 12512 } 12513 else 12514 { 12515 return array($ip, ''); 12516 } 12517 } 12518 12519 /** 12520 * Checks an IPv6 address 12521 * 12522 * Checks if the given IP is IPv6-compatible 12523 * 12524 * @access public 12525 * @static 12526 * @param string $ip a valid IPv6-address 12527 * @return bool true if $ip is an IPv6 address 12528 */ 12529 function checkIPv6($ip) 12530 { 12531 $ipPart = SimplePie_Net_IPv6::SplitV64($ip); 12532 $count = 0; 12533 if (!empty($ipPart[0])) 12534 { 12535 $ipv6 = explode(':', $ipPart[0]); 12536 for ($i = 0; $i < count($ipv6); $i++) 12537 { 12538 $dec = hexdec($ipv6[$i]); 12539 $hex = strtoupper(preg_replace('/^[0]{1,3}(.*[0-9a-fA-F])$/', '\\1', $ipv6[$i])); 12540 if ($ipv6[$i] >= 0 && $dec <= 65535 && $hex === strtoupper(dechex($dec))) 12541 { 12542 $count++; 12543 } 12544 } 12545 if ($count === 8) 12546 { 12547 return true; 12548 } 12549 elseif ($count === 6 && !empty($ipPart[1])) 12550 { 12551 $ipv4 = explode('.', $ipPart[1]); 12552 $count = 0; 12553 foreach ($ipv4 as $ipv4_part) 12554 { 12555 if ($ipv4_part >= 0 && $ipv4_part <= 255 && preg_match('/^\d{1,3}$/', $ipv4_part)) 12556 { 12557 $count++; 12558 } 12559 } 12560 if ($count === 4) 12561 { 12562 return true; 12563 } 12564 } 12565 else 12566 { 12567 return false; 12568 } 12569 12570 } 12571 else 12572 { 12573 return false; 12574 } 12575 } 12576 } 12577 12578 /** 12579 * Date Parser 12580 * 12581 * @package SimplePie 12582 */ 12583 class SimplePie_Parse_Date 12584 { 12585 /** 12586 * Input data 12587 * 12588 * @access protected 12589 * @var string 12590 */ 12591 var $date; 12592 12593 /** 12594 * List of days, calendar day name => ordinal day number in the week 12595 * 12596 * @access protected 12597 * @var array 12598 */ 12599 var $day = array( 12600 // English 12601 'mon' => 1, 12602 'monday' => 1, 12603 'tue' => 2, 12604 'tuesday' => 2, 12605 'wed' => 3, 12606 'wednesday' => 3, 12607 'thu' => 4, 12608 'thursday' => 4, 12609 'fri' => 5, 12610 'friday' => 5, 12611 'sat' => 6, 12612 'saturday' => 6, 12613 'sun' => 7, 12614 'sunday' => 7, 12615 // Dutch 12616 'maandag' => 1, 12617 'dinsdag' => 2, 12618 'woensdag' => 3, 12619 'donderdag' => 4, 12620 'vrijdag' => 5, 12621 'zaterdag' => 6, 12622 'zondag' => 7, 12623 // French 12624 'lundi' => 1, 12625 'mardi' => 2, 12626 'mercredi' => 3, 12627 'jeudi' => 4, 12628 'vendredi' => 5, 12629 'samedi' => 6, 12630 'dimanche' => 7, 12631 // German 12632 'montag' => 1, 12633 'dienstag' => 2, 12634 'mittwoch' => 3, 12635 'donnerstag' => 4, 12636 'freitag' => 5, 12637 'samstag' => 6, 12638 'sonnabend' => 6, 12639 'sonntag' => 7, 12640 // Italian 12641 'lunedì' => 1, 12642 'martedì' => 2, 12643 'mercoledì' => 3, 12644 'giovedì' => 4, 12645 'venerdì' => 5, 12646 'sabato' => 6, 12647 'domenica' => 7, 12648 // Spanish 12649 'lunes' => 1, 12650 'martes' => 2, 12651 'miércoles' => 3, 12652 'jueves' => 4, 12653 'viernes' => 5, 12654 'sábado' => 6, 12655 'domingo' => 7, 12656 // Finnish 12657 'maanantai' => 1, 12658 'tiistai' => 2, 12659 'keskiviikko' => 3, 12660 'torstai' => 4, 12661 'perjantai' => 5, 12662 'lauantai' => 6, 12663 'sunnuntai' => 7, 12664 // Hungarian 12665 'hétfő' => 1, 12666 'kedd' => 2, 12667 'szerda' => 3, 12668 'csütörtok' => 4, 12669 'péntek' => 5, 12670 'szombat' => 6, 12671 'vasárnap' => 7, 12672 // Greek 12673 'Δευ' => 1, 12674 'Τρι' => 2, 12675 'Τετ' => 3, 12676 'Πεμ' => 4, 12677 'Παρ' => 5, 12678 'Σαβ' => 6, 12679 'Κυρ' => 7, 12680 ); 12681 12682 /** 12683 * List of months, calendar month name => calendar month number 12684 * 12685 * @access protected 12686 * @var array 12687 */ 12688 var $month = array( 12689 // English 12690 'jan' => 1, 12691 'january' => 1, 12692 'feb' => 2, 12693 'february' => 2, 12694 'mar' => 3, 12695 'march' => 3, 12696 'apr' => 4, 12697 'april' => 4, 12698 'may' => 5, 12699 // No long form of May 12700 'jun' => 6, 12701 'june' => 6, 12702 'jul' => 7, 12703 'july' => 7, 12704 'aug' => 8, 12705 'august' => 8, 12706 'sep' => 9, 12707 'september' => 8, 12708 'oct' => 10, 12709 'october' => 10, 12710 'nov' => 11, 12711 'november' => 11, 12712 'dec' => 12, 12713 'december' => 12, 12714 // Dutch 12715 'januari' => 1, 12716 'februari' => 2, 12717 'maart' => 3, 12718 'april' => 4, 12719 'mei' => 5, 12720 'juni' => 6, 12721 'juli' => 7, 12722 'augustus' => 8, 12723 'september' => 9, 12724 'oktober' => 10, 12725 'november' => 11, 12726 'december' => 12, 12727 // French 12728 'janvier' => 1, 12729 'février' => 2, 12730 'mars' => 3, 12731 'avril' => 4, 12732 'mai' => 5, 12733 'juin' => 6, 12734 'juillet' => 7, 12735 'août' => 8, 12736 'septembre' => 9, 12737 'octobre' => 10, 12738 'novembre' => 11, 12739 'décembre' => 12, 12740 // German 12741 'januar' => 1, 12742 'februar' => 2, 12743 'märz' => 3, 12744 'april' => 4, 12745 'mai' => 5, 12746 'juni' => 6, 12747 'juli' => 7, 12748 'august' => 8, 12749 'september' => 9, 12750 'oktober' => 10, 12751 'november' => 11, 12752 'dezember' => 12, 12753 // Italian 12754 'gennaio' => 1, 12755 'febbraio' => 2, 12756 'marzo' => 3, 12757 'aprile' => 4, 12758 'maggio' => 5, 12759 'giugno' => 6, 12760 'luglio' => 7, 12761 'agosto' => 8, 12762 'settembre' => 9, 12763 'ottobre' => 10, 12764 'novembre' => 11, 12765 'dicembre' => 12, 12766 // Spanish 12767 'enero' => 1, 12768 'febrero' => 2, 12769 'marzo' => 3, 12770 'abril' => 4, 12771 'mayo' => 5, 12772 'junio' => 6, 12773 'julio' => 7, 12774 'agosto' => 8, 12775 'septiembre' => 9, 12776 'setiembre' => 9, 12777 'octubre' => 10, 12778 'noviembre' => 11, 12779 'diciembre' => 12, 12780 // Finnish 12781 'tammikuu' => 1, 12782 'helmikuu' => 2, 12783 'maaliskuu' => 3, 12784 'huhtikuu' => 4, 12785 'toukokuu' => 5, 12786 'kesäkuu' => 6, 12787 'heinäkuu' => 7, 12788 'elokuu' => 8, 12789 'suuskuu' => 9, 12790 'lokakuu' => 10, 12791 'marras' => 11, 12792 'joulukuu' => 12, 12793 // Hungarian 12794 'január' => 1, 12795 'február' => 2, 12796 'március' => 3, 12797 'április' => 4, 12798 'május' => 5, 12799 'június' => 6, 12800 'július' => 7, 12801 'augusztus' => 8, 12802 'szeptember' => 9, 12803 'október' => 10, 12804 'november' => 11, 12805 'december' => 12, 12806 // Greek 12807 'Ιαν' => 1, 12808 'Φεβ' => 2, 12809 'Μάώ' => 3, 12810 'Μαώ' => 3, 12811 'Απρ' => 4, 12812 'Μάι' => 5, 12813 'Μαϊ' => 5, 12814 'Μαι' => 5, 12815 'Ιούν' => 6, 12816 'Ιον' => 6, 12817 'Ιούλ' => 7, 12818 'Ιολ' => 7, 12819 'Αύγ' => 8, 12820 'Αυγ' => 8, 12821 'Σεπ' => 9, 12822 'Οκτ' => 10, 12823 'Νοέ' => 11, 12824 'Δεκ' => 12, 12825 ); 12826 12827 /** 12828 * List of timezones, abbreviation => offset from UTC 12829 * 12830 * @access protected 12831 * @var array 12832 */ 12833 var $timezone = array( 12834 'ACDT' => 37800, 12835 'ACIT' => 28800, 12836 'ACST' => 34200, 12837 'ACT' => -18000, 12838 'ACWDT' => 35100, 12839 'ACWST' => 31500, 12840 'AEDT' => 39600, 12841 'AEST' => 36000, 12842 'AFT' => 16200, 12843 'AKDT' => -28800, 12844 'AKST' => -32400, 12845 'AMDT' => 18000, 12846 'AMT' => -14400, 12847 'ANAST' => 46800, 12848 'ANAT' => 43200, 12849 'ART' => -10800, 12850 'AZOST' => -3600, 12851 'AZST' => 18000, 12852 'AZT' => 14400, 12853 'BIOT' => 21600, 12854 'BIT' => -43200, 12855 'BOT' => -14400, 12856 'BRST' => -7200, 12857 'BRT' => -10800, 12858 'BST' => 3600, 12859 'BTT' => 21600, 12860 'CAST' => 18000, 12861 'CAT' => 7200, 12862 'CCT' => 23400, 12863 'CDT' => -18000, 12864 'CEDT' => 7200, 12865 'CET' => 3600, 12866 'CGST' => -7200, 12867 'CGT' => -10800, 12868 'CHADT' => 49500, 12869 'CHAST' => 45900, 12870 'CIST' => -28800, 12871 'CKT' => -36000, 12872 'CLDT' => -10800, 12873 'CLST' => -14400, 12874 'COT' => -18000, 12875 'CST' => -21600, 12876 'CVT' => -3600, 12877 'CXT' => 25200, 12878 'DAVT' => 25200, 12879 'DTAT' => 36000, 12880 'EADT' => -18000, 12881 'EAST' => -21600, 12882 'EAT' => 10800, 12883 'ECT' => -18000, 12884 'EDT' => -14400, 12885 'EEST' => 10800, 12886 'EET' => 7200, 12887 'EGT' => -3600, 12888 'EKST' => 21600, 12889 'EST' => -18000, 12890 'FJT' => 43200, 12891 'FKDT' => -10800, 12892 'FKST' => -14400, 12893 'FNT' => -7200, 12894 'GALT' => -21600, 12895 'GEDT' => 14400, 12896 'GEST' => 10800, 12897 'GFT' => -10800, 12898 'GILT' => 43200, 12899 'GIT' => -32400, 12900 'GST' => 14400, 12901 'GST' => -7200, 12902 'GYT' => -14400, 12903 'HAA' => -10800, 12904 'HAC' => -18000, 12905 'HADT' => -32400, 12906 'HAE' => -14400, 12907 'HAP' => -25200, 12908 'HAR' => -21600, 12909 'HAST' => -36000, 12910 'HAT' => -9000, 12911 'HAY' => -28800, 12912 'HKST' => 28800, 12913 'HMT' => 18000, 12914 'HNA' => -14400, 12915 'HNC' => -21600, 12916 'HNE' => -18000, 12917 'HNP' => -28800, 12918 'HNR' => -25200, 12919 'HNT' => -12600, 12920 'HNY' => -32400, 12921 'IRDT' => 16200, 12922 'IRKST' => 32400, 12923 'IRKT' => 28800, 12924 'IRST' => 12600, 12925 'JFDT' => -10800, 12926 'JFST' => -14400, 12927 'JST' => 32400, 12928 'KGST' => 21600, 12929 'KGT' => 18000, 12930 'KOST' => 39600, 12931 'KOVST' => 28800, 12932 'KOVT' => 25200, 12933 'KRAST' => 28800, 12934 'KRAT' => 25200, 12935 'KST' => 32400, 12936 'LHDT' => 39600, 12937 'LHST' => 37800, 12938 'LINT' => 50400, 12939 'LKT' => 21600, 12940 'MAGST' => 43200, 12941 'MAGT' => 39600, 12942 'MAWT' => 21600, 12943 'MDT' => -21600, 12944 'MESZ' => 7200, 12945 'MEZ' => 3600, 12946 'MHT' => 43200, 12947 'MIT' => -34200, 12948 'MNST' => 32400, 12949 'MSDT' => 14400, 12950 'MSST' => 10800, 12951 'MST' => -25200, 12952 'MUT' => 14400, 12953 'MVT' => 18000, 12954 'MYT' => 28800, 12955 'NCT' => 39600, 12956 'NDT' => -9000, 12957 'NFT' => 41400, 12958 'NMIT' => 36000, 12959 'NOVST' => 25200, 12960 'NOVT' => 21600, 12961 'NPT' => 20700, 12962 'NRT' => 43200, 12963 'NST' => -12600, 12964 'NUT' => -39600, 12965 'NZDT' => 46800, 12966 'NZST' => 43200, 12967 'OMSST' => 25200, 12968 'OMST' => 21600, 12969 'PDT' => -25200, 12970 'PET' => -18000, 12971 'PETST' => 46800, 12972 'PETT' => 43200, 12973 'PGT' => 36000, 12974 'PHOT' => 46800, 12975 'PHT' => 28800, 12976 'PKT' => 18000, 12977 'PMDT' => -7200, 12978 'PMST' => -10800, 12979 'PONT' => 39600, 12980 'PST' => -28800, 12981 'PWT' => 32400, 12982 'PYST' => -10800, 12983 'PYT' => -14400, 12984 'RET' => 14400, 12985 'ROTT' => -10800, 12986 'SAMST' => 18000, 12987 'SAMT' => 14400, 12988 'SAST' => 7200, 12989 'SBT' => 39600, 12990 'SCDT' => 46800, 12991 'SCST' => 43200, 12992 'SCT' => 14400, 12993 'SEST' => 3600, 12994 'SGT' => 28800, 12995 'SIT' => 28800, 12996 'SRT' => -10800, 12997 'SST' => -39600, 12998 'SYST' => 10800, 12999 'SYT' => 7200, 13000 'TFT' => 18000, 13001 'THAT' => -36000, 13002 'TJT' => 18000, 13003 'TKT' => -36000, 13004 'TMT' => 18000, 13005 'TOT' => 46800, 13006 'TPT' => 32400, 13007 'TRUT' => 36000, 13008 'TVT' => 43200, 13009 'TWT' => 28800, 13010 'UYST' => -7200, 13011 'UYT' => -10800, 13012 'UZT' => 18000, 13013 'VET' => -14400, 13014 'VLAST' => 39600, 13015 'VLAT' => 36000, 13016 'VOST' => 21600, 13017 'VUT' => 39600, 13018 'WAST' => 7200, 13019 'WAT' => 3600, 13020 'WDT' => 32400, 13021 'WEST' => 3600, 13022 'WFT' => 43200, 13023 'WIB' => 25200, 13024 'WIT' => 32400, 13025 'WITA' => 28800, 13026 'WKST' => 18000, 13027 'WST' => 28800, 13028 'YAKST' => 36000, 13029 'YAKT' => 32400, 13030 'YAPT' => 36000, 13031 'YEKST' => 21600, 13032 'YEKT' => 18000, 13033 ); 13034 13035 /** 13036 * Cached PCRE for SimplePie_Parse_Date::$day 13037 * 13038 * @access protected 13039 * @var string 13040 */ 13041 var $day_pcre; 13042 13043 /** 13044 * Cached PCRE for SimplePie_Parse_Date::$month 13045 * 13046 * @access protected 13047 * @var string 13048 */ 13049 var $month_pcre; 13050 13051 /** 13052 * Array of user-added callback methods 13053 * 13054 * @access private 13055 * @var array 13056 */ 13057 var $built_in = array(); 13058 13059 /** 13060 * Array of user-added callback methods 13061 * 13062 * @access private 13063 * @var array 13064 */ 13065 var $user = array(); 13066 13067 /** 13068 * Create new SimplePie_Parse_Date object, and set self::day_pcre, 13069 * self::month_pcre, and self::built_in 13070 * 13071 * @access private 13072 */ 13073 function SimplePie_Parse_Date() 13074 { 13075 $this->day_pcre = '(' . implode(array_keys($this->day), '|') . ')'; 13076 $this->month_pcre = '(' . implode(array_keys($this->month), '|') . ')'; 13077 13078 static $cache; 13079 if (!isset($cache[get_class($this)])) 13080 { 13081 $all_methods = get_class_methods($this); 13082 13083 foreach ($all_methods as $method) 13084 { 13085 if (strtolower(substr($method, 0, 5)) === 'date_') 13086 { 13087 $cache[get_class($this)][] = $method; 13088 } 13089 } 13090 } 13091 13092 foreach ($cache[get_class($this)] as $method) 13093 { 13094 $this->built_in[] = $method; 13095 } 13096 } 13097 13098 /** 13099 * Get the object 13100 * 13101 * @access public 13102 */ 13103 function get() 13104 { 13105 static $object; 13106 if (!$object) 13107 { 13108 $object =& new SimplePie_Parse_Date; 13109 } 13110 return $object; 13111 } 13112 13113 /** 13114 * Parse a date 13115 * 13116 * @final 13117 * @access public 13118 * @param string $date Date to parse 13119 * @return int Timestamp corresponding to date string, or false on failure 13120 */ 13121 function parse($date) 13122 { 13123 foreach ($this->user as $method) 13124 { 13125 if (($returned = call_user_func($method, $date)) !== false) 13126 { 13127 return $returned; 13128 } 13129 } 13130 13131 foreach ($this->built_in as $method) 13132 { 13133 if (($returned = call_user_func(array(&$this, $method), $date)) !== false) 13134 { 13135 return $returned; 13136 } 13137 } 13138 13139 return false; 13140 } 13141 13142 /** 13143 * Add a callback method to parse a date 13144 * 13145 * @final 13146 * @access public 13147 * @param callback $callback 13148 */ 13149 function add_callback($callback) 13150 { 13151 if (is_callable($callback)) 13152 { 13153 $this->user[] = $callback; 13154 } 13155 else 13156 { 13157 trigger_error('User-supplied function must be a valid callback', E_USER_WARNING); 13158 } 13159 } 13160 13161 /** 13162 * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as 13163 * well as allowing any of upper or lower case "T", horizontal tabs, or 13164 * spaces to be used as the time seperator (including more than one)) 13165 * 13166 * @access protected 13167 * @return int Timestamp 13168 */ 13169 function date_w3cdtf($date) 13170 { 13171 static $pcre; 13172 if (!$pcre) 13173 { 13174 $year = '([0-9]{4})'; 13175 $month = $day = $hour = $minute = $second = '([0-9]{2})'; 13176 $decimal = '([0-9]*)'; 13177 $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))'; 13178 $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/'; 13179 } 13180 if (preg_match($pcre, $date, $match)) 13181 { 13182 /* 13183 Capturing subpatterns: 13184 1: Year 13185 2: Month 13186 3: Day 13187 4: Hour 13188 5: Minute 13189 6: Second 13190 7: Decimal fraction of a second 13191 8: Zulu 13192 9: Timezone ± 13193 10: Timezone hours 13194 11: Timezone minutes 13195 */ 13196 13197 // Fill in empty matches 13198 for ($i = count($match); $i <= 3; $i++) 13199 { 13200 $match[$i] = '1'; 13201 } 13202 13203 for ($i = count($match); $i <= 7; $i++) 13204 { 13205 $match[$i] = '0'; 13206 } 13207 13208 // Numeric timezone 13209 if (isset($match[9]) && $match[9] !== '') 13210 { 13211 $timezone = $match[10] * 3600; 13212 $timezone += $match[11] * 60; 13213 if ($match[9] === '-') 13214 { 13215 $timezone = 0 - $timezone; 13216 } 13217 } 13218 else 13219 { 13220 $timezone = 0; 13221 } 13222 13223 // Convert the number of seconds to an integer, taking decimals into account 13224 $second = round($match[6] + $match[7] / pow(10, strlen($match[7]))); 13225 13226 return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone; 13227 } 13228 else 13229 { 13230 return false; 13231 } 13232 } 13233 13234 /** 13235 * Remove RFC822 comments 13236 * 13237 * @access protected 13238 * @param string $data Data to strip comments from 13239 * @return string Comment stripped string 13240 */ 13241 function remove_rfc2822_comments($string) 13242 { 13243 $string = (string) $string; 13244 $position = 0; 13245 $length = strlen($string); 13246 $depth = 0; 13247 13248 $output = ''; 13249 13250 while ($position < $length && ($pos = strpos($string, '(', $position)) !== false) 13251 { 13252 $output .= substr($string, $position, $pos - $position); 13253 $position = $pos + 1; 13254 if ($string[$pos - 1] !== '\\') 13255 { 13256 $depth++; 13257 while ($depth && $position < $length) 13258 { 13259 $position += strcspn($string, '()', $position); 13260 if ($string[$position - 1] === '\\') 13261 { 13262 $position++; 13263 continue; 13264 } 13265 elseif (isset($string[$position])) 13266 { 13267 switch ($string[$position]) 13268 { 13269 case '(': 13270 $depth++; 13271 break; 13272 13273 case ')': 13274 $depth--; 13275 break; 13276 } 13277 $position++; 13278 } 13279 else 13280 { 13281 break; 13282 } 13283 } 13284 } 13285 else 13286 { 13287 $output .= '('; 13288 } 13289 } 13290 $output .= substr($string, $position); 13291 13292 return $output; 13293 } 13294 13295 /** 13296 * Parse RFC2822's date format 13297 * 13298 * @access protected 13299 * @return int Timestamp 13300 */ 13301 function date_rfc2822($date) 13302 { 13303 static $pcre; 13304 if (!$pcre) 13305 { 13306 $wsp = '[\x09\x20]'; 13307 $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)'; 13308 $optional_fws = $fws . '?'; 13309 $day_name = $this->day_pcre; 13310 $month = $this->month_pcre; 13311 $day = '([0-9]{1,2})'; 13312 $hour = $minute = $second = '([0-9]{2})'; 13313 $year = '([0-9]{2,4})'; 13314 $num_zone = '([+\-])([0-9]{2})([0-9]{2})'; 13315 $character_zone = '([A-Z]{1,5})'; 13316 $zone = '(?:' . $num_zone . '|' . $character_zone . ')'; 13317 $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i'; 13318 } 13319 if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match)) 13320 { 13321 /* 13322 Capturing subpatterns: 13323 1: Day name 13324 2: Day 13325 3: Month 13326 4: Year 13327 5: Hour 13328 6: Minute 13329 7: Second 13330 8: Timezone ± 13331 9: Timezone hours 13332 10: Timezone minutes 13333 11: Alphabetic timezone 13334 */ 13335 13336 // Find the month number 13337 $month = $this->month[strtolower($match[3])]; 13338 13339 // Numeric timezone 13340 if ($match[8] !== '') 13341 { 13342 $timezone = $match[9] * 3600; 13343 $timezone += $match[10] * 60; 13344 if ($match[8] === '-') 13345 { 13346 $timezone = 0 - $timezone; 13347 } 13348 } 13349 // Character timezone 13350 elseif (isset($this->timezone[strtoupper($match[11])])) 13351 { 13352 $timezone = $this->timezone[strtoupper($match[11])]; 13353 } 13354 // Assume everything else to be -0000 13355 else 13356 { 13357 $timezone = 0; 13358 } 13359 13360 // Deal with 2/3 digit years 13361 if ($match[4] < 50) 13362 { 13363 $match[4] += 2000; 13364 } 13365 elseif ($match[4] < 1000) 13366 { 13367 $match[4] += 1900; 13368 } 13369 13370 // Second is optional, if it is empty set it to zero 13371 if ($match[7] !== '') 13372 { 13373 $second = $match[7]; 13374 } 13375 else 13376 { 13377 $second = 0; 13378 } 13379 13380 return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone; 13381 } 13382 else 13383 { 13384 return false; 13385 } 13386 } 13387 13388 /** 13389 * Parse RFC850's date format 13390 * 13391 * @access protected 13392 * @return int Timestamp 13393 */ 13394 function date_rfc850($date) 13395 { 13396 static $pcre; 13397 if (!$pcre) 13398 { 13399 $space = '[\x09\x20]+'; 13400 $day_name = $this->day_pcre; 13401 $month = $this->month_pcre; 13402 $day = '([0-9]{1,2})'; 13403 $year = $hour = $minute = $second = '([0-9]{2})'; 13404 $zone = '([A-Z]{1,5})'; 13405 $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i'; 13406 } 13407 if (preg_match($pcre, $date, $match)) 13408 { 13409 /* 13410 Capturing subpatterns: 13411 1: Day name 13412 2: Day 13413 3: Month 13414 4: Year 13415 5: Hour 13416 6: Minute 13417 7: Second 13418 8: Timezone 13419 */ 13420 13421 // Month 13422 $month = $this->month[strtolower($match[3])]; 13423 13424 // Character timezone 13425 if (isset($this->timezone[strtoupper($match[8])])) 13426 { 13427 $timezone = $this->timezone[strtoupper($match[8])]; 13428 } 13429 // Assume everything else to be -0000 13430 else 13431 { 13432 $timezone = 0; 13433 } 13434 13435 // Deal with 2 digit year 13436 if ($match[4] < 50) 13437 { 13438 $match[4] += 2000; 13439 } 13440 else 13441 { 13442 $match[4] += 1900; 13443 } 13444 13445 return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone; 13446 } 13447 else 13448 { 13449 return false; 13450 } 13451 } 13452 13453 /** 13454 * Parse C99's asctime()'s date format 13455 * 13456 * @access protected 13457 * @return int Timestamp 13458 */ 13459 function date_asctime($date) 13460 { 13461 static $pcre; 13462 if (!$pcre) 13463 { 13464 $space = '[\x09\x20]+'; 13465 $wday_name = $this->day_pcre; 13466 $mon_name = $this->month_pcre; 13467 $day = '([0-9]{1,2})'; 13468 $hour = $sec = $min = '([0-9]{2})'; 13469 $year = '([0-9]{4})'; 13470 $terminator = '\x0A?\x00?'; 13471 $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i'; 13472 } 13473 if (preg_match($pcre, $date, $match)) 13474 { 13475 /* 13476 Capturing subpatterns: 13477 1: Day name 13478 2: Month 13479 3: Day 13480 4: Hour 13481 5: Minute 13482 6: Second 13483 7: Year 13484 */ 13485 13486 $month = $this->month[strtolower($match[2])]; 13487 return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]); 13488 } 13489 else 13490 { 13491 return false; 13492 } 13493 } 13494 13495 /** 13496 * Parse dates using strtotime() 13497 * 13498 * @access protected 13499 * @return int Timestamp 13500 */ 13501 function date_strtotime($date) 13502 { 13503 $strtotime = strtotime($date); 13504 if ($strtotime === -1 || $strtotime === false) 13505 { 13506 return false; 13507 } 13508 else 13509 { 13510 return $strtotime; 13511 } 13512 } 13513 } 13514 13515 /** 13516 * Content-type sniffing 13517 * 13518 * @package SimplePie 13519 */ 13520 class SimplePie_Content_Type_Sniffer 13521 { 13522 /** 13523 * File object 13524 * 13525 * @var SimplePie_File 13526 * @access private 13527 */ 13528 var $file; 13529 13530 /** 13531 * Create an instance of the class with the input file 13532 * 13533 * @access public 13534 * @param SimplePie_Content_Type_Sniffer $file Input file 13535 */ 13536 function SimplePie_Content_Type_Sniffer($file) 13537 { 13538 $this->file = $file; 13539 } 13540 13541 /** 13542 * Get the Content-Type of the specified file 13543 * 13544 * @access public 13545 * @return string Actual Content-Type 13546 */ 13547 function get_type() 13548 { 13549 if (isset($this->file->headers['content-type'])) 13550 { 13551 if (!isset($this->file->headers['content-encoding']) 13552 && ($this->file->headers['content-type'] === 'text/plain' 13553 || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1' 13554 || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1')) 13555 { 13556 return $this->text_or_binary(); 13557 } 13558 13559 if (($pos = strpos($this->file->headers['content-type'], ';')) !== false) 13560 { 13561 $official = substr($this->file->headers['content-type'], 0, $pos); 13562 } 13563 else 13564 { 13565 $official = $this->file->headers['content-type']; 13566 } 13567 $official = strtolower($official); 13568 13569 if ($official === 'unknown/unknown' 13570 || $official === 'application/unknown') 13571 { 13572 return $this->unknown(); 13573 } 13574 elseif (substr($official, -4) === '+xml' 13575 || $official === 'text/xml' 13576 || $official === 'application/xml') 13577 { 13578 return $official; 13579 } 13580 elseif (substr($official, 0, 6) === 'image/') 13581 { 13582 if ($return = $this->image()) 13583 { 13584 return $return; 13585 } 13586 else 13587 { 13588 return $official; 13589 } 13590 } 13591 elseif ($official === 'text/html') 13592 { 13593 return $this->feed_or_html(); 13594 } 13595 else 13596 { 13597 return $official; 13598 } 13599 } 13600 else 13601 { 13602 return $this->unknown(); 13603 } 13604 } 13605 13606 /** 13607 * Sniff text or binary 13608 * 13609 * @access private 13610 * @return string Actual Content-Type 13611 */ 13612 function text_or_binary() 13613 { 13614 if (substr($this->file->body, 0, 2) === "\xFE\xFF" 13615 || substr($this->file->body, 0, 2) === "\xFF\xFE" 13616 || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF" 13617 || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF") 13618 { 13619 return 'text/plain'; 13620 } 13621 elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body)) 13622 { 13623 return 'application/octect-stream'; 13624 } 13625 else 13626 { 13627 return 'text/plain'; 13628 } 13629 } 13630 13631 /** 13632 * Sniff unknown 13633 * 13634 * @access private 13635 * @return string Actual Content-Type 13636 */ 13637 function unknown() 13638 { 13639 $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20"); 13640 if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html' 13641 || strtolower(substr($this->file->body, $ws, 5)) === '<html' 13642 || strtolower(substr($this->file->body, $ws, 7)) === '<script') 13643 { 13644 return 'text/html'; 13645 } 13646 elseif (substr($this->file->body, 0, 5) === '%PDF-') 13647 { 13648 return 'application/pdf'; 13649 } 13650 elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-') 13651 { 13652 return 'application/postscript'; 13653 } 13654 elseif (substr($this->file->body, 0, 6) === 'GIF87a' 13655 || substr($this->file->body, 0, 6) === 'GIF89a') 13656 { 13657 return 'image/gif'; 13658 } 13659 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") 13660 { 13661 return 'image/png'; 13662 } 13663 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") 13664 { 13665 return 'image/jpeg'; 13666 } 13667 elseif (substr($this->file->body, 0, 2) === "\x42\x4D") 13668 { 13669 return 'image/bmp'; 13670 } 13671 else 13672 { 13673 return $this->text_or_binary(); 13674 } 13675 } 13676 13677 /** 13678 * Sniff images 13679 * 13680 * @access private 13681 * @return string Actual Content-Type 13682 */ 13683 function image() 13684 { 13685 if (substr($this->file->body, 0, 6) === 'GIF87a' 13686 || substr($this->file->body, 0, 6) === 'GIF89a') 13687 { 13688 return 'image/gif'; 13689 } 13690 elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") 13691 { 13692 return 'image/png'; 13693 } 13694 elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") 13695 { 13696 return 'image/jpeg'; 13697 } 13698 elseif (substr($this->file->body, 0, 2) === "\x42\x4D") 13699 { 13700 return 'image/bmp'; 13701 } 13702 else 13703 { 13704 return false; 13705 } 13706 } 13707 13708 /** 13709 * Sniff HTML 13710 * 13711 * @access private 13712 * @return string Actual Content-Type 13713 */ 13714 function feed_or_html() 13715 { 13716 $len = strlen($this->file->body); 13717 $pos = strspn($this->file->body, "\x09\x0A\x0D\x20"); 13718 13719 while ($pos < $len) 13720 { 13721 switch ($this->file->body[$pos]) 13722 { 13723 case "\x09": 13724 case "\x0A": 13725 case "\x0D": 13726 case "\x20": 13727 $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos); 13728 continue 2; 13729 13730 case '<': 13731 $pos++; 13732 break; 13733 13734 default: 13735 return 'text/html'; 13736 } 13737 13738 if (substr($this->file->body, $pos, 3) === '!--') 13739 { 13740 $pos += 3; 13741 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false) 13742 { 13743 $pos += 3; 13744 } 13745 else 13746 { 13747 return 'text/html'; 13748 } 13749 } 13750 elseif (substr($this->file->body, $pos, 1) === '!') 13751 { 13752 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false) 13753 { 13754 $pos++; 13755 } 13756 else 13757 { 13758 return 'text/html'; 13759 } 13760 } 13761 elseif (substr($this->file->body, $pos, 1) === '?') 13762 { 13763 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false) 13764 { 13765 $pos += 2; 13766 } 13767 else 13768 { 13769 return 'text/html'; 13770 } 13771 } 13772 elseif (substr($this->file->body, $pos, 3) === 'rss' 13773 || substr($this->file->body, $pos, 7) === 'rdf:RDF') 13774 { 13775 return 'application/rss+xml'; 13776 } 13777 elseif (substr($this->file->body, $pos, 4) === 'feed') 13778 { 13779 return 'application/atom+xml'; 13780 } 13781 else 13782 { 13783 return 'text/html'; 13784 } 13785 } 13786 13787 return 'text/html'; 13788 } 13789 } 13790 13791 /** 13792 * Parses the XML Declaration 13793 * 13794 * @package SimplePie 13795 */ 13796 class SimplePie_XML_Declaration_Parser 13797 { 13798 /** 13799 * XML Version 13800 * 13801 * @access public 13802 * @var string 13803 */ 13804 var $version = '1.0'; 13805 13806 /** 13807 * Encoding 13808 * 13809 * @access public 13810 * @var string 13811 */ 13812 var $encoding = 'UTF-8'; 13813 13814 /** 13815 * Standalone 13816 * 13817 * @access public 13818 * @var bool 13819 */ 13820 var $standalone = false; 13821 13822 /** 13823 * Current state of the state machine 13824 * 13825 * @access private 13826 * @var string 13827 */ 13828 var $state = 'before_version_name'; 13829 13830 /** 13831 * Input data 13832 * 13833 * @access private 13834 * @var string 13835 */ 13836 var $data = ''; 13837 13838 /** 13839 * Input data length (to avoid calling strlen() everytime this is needed) 13840 * 13841 * @access private 13842 * @var int 13843 */ 13844 var $data_length = 0; 13845 13846 /** 13847 * Current position of the pointer 13848 * 13849 * @var int 13850 * @access private 13851 */ 13852 var $position = 0; 13853 13854 /** 13855 * Create an instance of the class with the input data 13856 * 13857 * @access public 13858 * @param string $data Input data 13859 */ 13860 function SimplePie_XML_Declaration_Parser($data) 13861 { 13862 $this->data = $data; 13863 $this->data_length = strlen($this->data); 13864 } 13865 13866 /** 13867 * Parse the input data 13868 * 13869 * @access public 13870 * @return bool true on success, false on failure 13871 */ 13872 function parse() 13873 { 13874 while ($this->state && $this->state !== 'emit' && $this->has_data()) 13875 { 13876 $state = $this->state; 13877 $this->$state(); 13878 } 13879 $this->data = ''; 13880 if ($this->state === 'emit') 13881 { 13882 return true; 13883 } 13884 else 13885 { 13886 $this->version = ''; 13887 $this->encoding = ''; 13888 $this->standalone = ''; 13889 return false; 13890 } 13891 } 13892 13893 /** 13894 * Check whether there is data beyond the pointer 13895 * 13896 * @access private 13897 * @return bool true if there is further data, false if not 13898 */ 13899 function has_data() 13900 { 13901 return (bool) ($this->position < $this->data_length); 13902 } 13903 13904 /** 13905 * Advance past any whitespace 13906 * 13907 * @return int Number of whitespace characters passed 13908 */ 13909 function skip_whitespace() 13910 { 13911 $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position); 13912 $this->position += $whitespace; 13913 return $whitespace; 13914 } 13915 13916 /** 13917 * Read value 13918 */ 13919 function get_value() 13920 { 13921 $quote = substr($this->data, $this->position, 1); 13922 if ($quote === '"' || $quote === "'") 13923 { 13924 $this->position++; 13925 $len = strcspn($this->data, $quote, $this->position); 13926 if ($this->has_data()) 13927 { 13928 $value = substr($this->data, $this->position, $len); 13929 $this->position += $len + 1; 13930 return $value; 13931 } 13932 } 13933 return false; 13934 } 13935 13936 function before_version_name() 13937 { 13938 if ($this->skip_whitespace()) 13939 { 13940 $this->state = 'version_name'; 13941 } 13942 else 13943 { 13944 $this->state = false; 13945 } 13946 } 13947 13948 function version_name() 13949 { 13950 if (substr($this->data, $this->position, 7) === 'version') 13951 { 13952 $this->position += 7; 13953 $this->skip_whitespace(); 13954 $this->state = 'version_equals'; 13955 } 13956 else 13957 { 13958 $this->state = false; 13959 } 13960 } 13961 13962 function version_equals() 13963 { 13964 if (substr($this->data, $this->position, 1) === '=') 13965 { 13966 $this->position++; 13967 $this->skip_whitespace(); 13968 $this->state = 'version_value'; 13969 } 13970 else 13971 { 13972 $this->state = false; 13973 } 13974 } 13975 13976 function version_value() 13977 { 13978 if ($this->version = $this->get_value()) 13979 { 13980 $this->skip_whitespace(); 13981 if ($this->has_data()) 13982 { 13983 $this->state = 'encoding_name'; 13984 } 13985 else 13986 { 13987 $this->state = 'emit'; 13988 } 13989 } 13990 else 13991 { 13992 $this->state = false; 13993 } 13994 } 13995 13996 function encoding_name() 13997 { 13998 if (substr($this->data, $this->position, 8) === 'encoding') 13999 { 14000 $this->position += 8; 14001 $this->skip_whitespace(); 14002 $this->state = 'encoding_equals'; 14003 } 14004 else 14005 { 14006 $this->state = 'standalone_name'; 14007 } 14008 } 14009 14010 function encoding_equals() 14011 { 14012 if (substr($this->data, $this->position, 1) === '=') 14013 { 14014 $this->position++; 14015 $this->skip_whitespace(); 14016 $this->state = 'encoding_value'; 14017 } 14018 else 14019 { 14020 $this->state = false; 14021 } 14022 } 14023 14024 function encoding_value() 14025 { 14026 if ($this->encoding = $this->get_value()) 14027 { 14028 $this->skip_whitespace(); 14029 if ($this->has_data()) 14030 { 14031 $this->state = 'standalone_name'; 14032 } 14033 else 14034 { 14035 $this->state = 'emit'; 14036 } 14037 } 14038 else 14039 { 14040 $this->state = false; 14041 } 14042 } 14043 14044 function standalone_name() 14045 { 14046 if (substr($this->data, $this->position, 10) === 'standalone') 14047 { 14048 $this->position += 10; 14049 $this->skip_whitespace(); 14050 $this->state = 'standalone_equals'; 14051 } 14052 else 14053 { 14054 $this->state = false; 14055 } 14056 } 14057 14058 function standalone_equals() 14059 { 14060 if (substr($this->data, $this->position, 1) === '=') 14061 { 14062 $this->position++; 14063 $this->skip_whitespace(); 14064 $this->state = 'standalone_value'; 14065 } 14066 else 14067 { 14068 $this->state = false; 14069 } 14070 } 14071 14072 function standalone_value() 14073 { 14074 if ($standalone = $this->get_value()) 14075 { 14076 switch ($standalone) 14077 { 14078 case 'yes': 14079 $this->standalone = true; 14080 break; 14081 14082 case 'no': 14083 $this->standalone = false; 14084 break; 14085 14086 default: 14087 $this->state = false; 14088 return; 14089 } 14090 14091 $this->skip_whitespace(); 14092 if ($this->has_data()) 14093 { 14094 $this->state = false; 14095 } 14096 else 14097 { 14098 $this->state = 'emit'; 14099 } 14100 } 14101 else 14102 { 14103 $this->state = false; 14104 } 14105 } 14106 } 14107 14108 class SimplePie_Locator 14109 { 14110 var $useragent; 14111 var $timeout; 14112 var $file; 14113 var $local = array(); 14114 var $elsewhere = array(); 14115 var $file_class = 'SimplePie_File'; 14116 var $cached_entities = array(); 14117 var $http_base; 14118 var $base; 14119 var $base_location = 0; 14120 var $checked_feeds = 0; 14121 var $max_checked_feeds = 10; 14122 var $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer'; 14123 14124 function SimplePie_Locator(&$file, $timeout = 10, $useragent = null, $file_class = 'SimplePie_File', $max_checked_feeds = 10, $content_type_sniffer_class = 'SimplePie_Content_Type_Sniffer') 14125 { 14126 $this->file =& $file; 14127 $this->file_class = $file_class; 14128 $this->useragent = $useragent; 14129 $this->timeout = $timeout; 14130 $this->max_checked_feeds = $max_checked_feeds; 14131 $this->content_type_sniffer_class = $content_type_sniffer_class; 14132 } 14133 14134 function find($type = SIMPLEPIE_LOCATOR_ALL, &$working) 14135 { 14136 if ($this->is_feed($this->file)) 14137 { 14138 return $this->file; 14139 } 14140 14141 if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) 14142 { 14143 $sniffer =& new $this->content_type_sniffer_class($this->file); 14144 if ($sniffer->get_type() !== 'text/html') 14145 { 14146 return null; 14147 } 14148 } 14149 14150 if ($type & ~SIMPLEPIE_LOCATOR_NONE) 14151 { 14152 $this->get_base(); 14153 } 14154 14155 if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery()) 14156 { 14157 return $working[0]; 14158 } 14159 14160 if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links()) 14161 { 14162 if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) 14163 { 14164 return $working; 14165 } 14166 14167 if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) 14168 { 14169 return $working; 14170 } 14171 14172 if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) 14173 { 14174 return $working; 14175 } 14176 14177 if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) 14178 { 14179 return $working; 14180 } 14181 } 14182 return null; 14183 } 14184 14185 function is_feed(&$file) 14186 { 14187 if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE) 14188 { 14189 $sniffer =& new $this->content_type_sniffer_class($file); 14190 $sniffed = $sniffer->get_type(); 14191 if (in_array($sniffed, array('application/rss+xml', 'application/rdf+xml', 'text/rdf', 'application/atom+xml', 'text/xml', 'application/xml'))) 14192 { 14193 return true; 14194 } 14195 else 14196 { 14197 return false; 14198 } 14199 } 14200 elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL) 14201 { 14202 return true; 14203 } 14204 else 14205 { 14206 return false; 14207 } 14208 } 14209 14210 function get_base() 14211 { 14212 $this->http_base = $this->file->url; 14213 $this->base = $this->http_base; 14214 $elements = SimplePie_Misc::get_element('base', $this->file->body); 14215 foreach ($elements as $element) 14216 { 14217 if ($element['attribs']['href']['data'] !== '') 14218 { 14219 $this->base = SimplePie_Misc::absolutize_url(trim($element['attribs']['href']['data']), $this->http_base); 14220 $this->base_location = $element['offset']; 14221 break; 14222 } 14223 } 14224 } 14225 14226 function autodiscovery() 14227 { 14228 $links = array_merge(SimplePie_Misc::get_element('link', $this->file->body), SimplePie_Misc::get_element('a', $this->file->body), SimplePie_Misc::get_element('area', $this->file->body)); 14229 $done = array(); 14230 $feeds = array(); 14231 foreach ($links as $link) 14232 { 14233 if ($this->checked_feeds === $this->max_checked_feeds) 14234 { 14235 break; 14236 } 14237 if (isset($link['attribs']['href']['data']) && isset($link['attribs']['rel']['data'])) 14238 { 14239 $rel = array_unique(SimplePie_Misc::space_seperated_tokens(strtolower($link['attribs']['rel']['data']))); 14240 14241 if ($this->base_location < $link['offset']) 14242 { 14243 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base); 14244 } 14245 else 14246 { 14247 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base); 14248 } 14249 14250 if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !empty($link['attribs']['type']['data']) && in_array(strtolower(SimplePie_Misc::parse_mime($link['attribs']['type']['data'])), array('application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href])) 14251 { 14252 $this->checked_feeds++; 14253 $feed =& new $this->file_class($href, $this->timeout, 5, null, $this->useragent); 14254 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) 14255 { 14256 $feeds[$href] = $feed; 14257 } 14258 } 14259 $done[] = $href; 14260 } 14261 } 14262 14263 if (!empty($feeds)) 14264 { 14265 return array_values($feeds); 14266 } 14267 else { 14268 return null; 14269 } 14270 } 14271 14272 function get_links() 14273 { 14274 $links = SimplePie_Misc::get_element('a', $this->file->body); 14275 foreach ($links as $link) 14276 { 14277 if (isset($link['attribs']['href']['data'])) 14278 { 14279 $href = trim($link['attribs']['href']['data']); 14280 $parsed = SimplePie_Misc::parse_url($href); 14281 if ($parsed['scheme'] === '' || preg_match('/^(http(s)|feed)?$/i', $parsed['scheme'])) 14282 { 14283 if ($this->base_location < $link['offset']) 14284 { 14285 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->base); 14286 } 14287 else 14288 { 14289 $href = SimplePie_Misc::absolutize_url(trim($link['attribs']['href']['data']), $this->http_base); 14290 } 14291 14292 $current = SimplePie_Misc::parse_url($this->file->url); 14293 14294 if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority']) 14295 { 14296 $this->local[] = $href; 14297 } 14298 else 14299 { 14300 $this->elsewhere[] = $href; 14301 } 14302 } 14303 } 14304 } 14305 $this->local = array_unique($this->local); 14306 $this->elsewhere = array_unique($this->elsewhere); 14307 if (!empty($this->local) || !empty($this->elsewhere)) 14308 { 14309 return true; 14310 } 14311 return null; 14312 } 14313 14314 function extension(&$array) 14315 { 14316 foreach ($array as $key => $value) 14317 { 14318 if ($this->checked_feeds === $this->max_checked_feeds) 14319 { 14320 break; 14321 } 14322 if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml'))) 14323 { 14324 $this->checked_feeds++; 14325 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent); 14326 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) 14327 { 14328 return $feed; 14329 } 14330 else 14331 { 14332 unset($array[$key]); 14333 } 14334 } 14335 } 14336 return null; 14337 } 14338 14339 function body(&$array) 14340 { 14341 foreach ($array as $key => $value) 14342 { 14343 if ($this->checked_feeds === $this->max_checked_feeds) 14344 { 14345 break; 14346 } 14347 if (preg_match('/(rss|rdf|atom|xml)/i', $value)) 14348 { 14349 $this->checked_feeds++; 14350 $feed =& new $this->file_class($value, $this->timeout, 5, null, $this->useragent); 14351 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) 14352 { 14353 return $feed; 14354 } 14355 else 14356 { 14357 unset($array[$key]); 14358 } 14359 } 14360 } 14361 return null; 14362 } 14363 } 14364 14365 class SimplePie_Parser 14366 { 14367 var $error_code; 14368 var $error_string; 14369 var $current_line; 14370 var $current_column; 14371 var $current_byte; 14372 var $separator = ' '; 14373 var $namespace = array(''); 14374 var $element = array(''); 14375 var $xml_base = array(''); 14376 var $xml_base_explicit = array(false); 14377 var $xml_lang = array(''); 14378 var $data = array(); 14379 var $datas = array(array()); 14380 var $current_xhtml_construct = -1; 14381 var $encoding; 14382 14383 function parse(&$data, $encoding) 14384 { 14385 // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character 14386 if (strtoupper($encoding) === 'US-ASCII') 14387 { 14388 $this->encoding = 'UTF-8'; 14389 } 14390 else 14391 { 14392 $this->encoding = $encoding; 14393 } 14394 14395 // Strip BOM: 14396 // UTF-32 Big Endian BOM 14397 if (substr($data, 0, 4) === "\x00\x00\xFE\xFF") 14398 { 14399 $data = substr($data, 4); 14400 } 14401 // UTF-32 Little Endian BOM 14402 elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00") 14403 { 14404 $data = substr($data, 4); 14405 } 14406 // UTF-16 Big Endian BOM 14407 elseif (substr($data, 0, 2) === "\xFE\xFF") 14408 { 14409 $data = substr($data, 2); 14410 } 14411 // UTF-16 Little Endian BOM 14412 elseif (substr($data, 0, 2) === "\xFF\xFE") 14413 { 14414 $data = substr($data, 2); 14415 } 14416 // UTF-8 BOM 14417 elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") 14418 { 14419 $data = substr($data, 3); 14420 } 14421 14422 if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false) 14423 { 14424 $declaration =& new SimplePie_XML_Declaration_Parser(substr($data, 5, $pos - 5)); 14425 if ($declaration->parse()) 14426 { 14427 $data = substr($data, $pos + 2); 14428 $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . $data; 14429 } 14430 else 14431 { 14432 $this->error_string = 'SimplePie bug! Please report this!'; 14433 return false; 14434 } 14435 } 14436 14437 $return = true; 14438 14439 static $xml_is_sane = null; 14440 if ($xml_is_sane === null) 14441 { 14442 $parser_check = xml_parser_create(); 14443 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values); 14444 xml_parser_free($parser_check); 14445 $xml_is_sane = isset($values[0]['value']); 14446 } 14447 14448 // Create the parser 14449 if ($xml_is_sane) 14450 { 14451 $xml = xml_parser_create_ns($this->encoding, $this->separator); 14452 xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1); 14453 xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0); 14454 xml_set_object($xml, $this); 14455 xml_set_character_data_handler($xml, 'cdata'); 14456 xml_set_element_handler($xml, 'tag_open', 'tag_close'); 14457 14458 // Parse! 14459 if (!xml_parse($xml, $data, true)) 14460 { 14461 $this->error_code = xml_get_error_code($xml); 14462 $this->error_string = xml_error_string($this->error_code); 14463 $return = false; 14464 } 14465 $this->current_line = xml_get_current_line_number($xml); 14466 $this->current_column = xml_get_current_column_number($xml); 14467 $this->current_byte = xml_get_current_byte_index($xml); 14468 xml_parser_free($xml); 14469 return $return; 14470 } 14471 else 14472 { 14473 libxml_clear_errors(); 14474 $xml =& new XMLReader(); 14475 $xml->xml($data); 14476 while (@$xml->read()) 14477 { 14478 switch ($xml->nodeType) 14479 { 14480 14481 case constant('XMLReader::END_ELEMENT'): 14482 if ($xml->namespaceURI !== '') 14483 { 14484 $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}"; 14485 } 14486 else 14487 { 14488 $tagName = $xml->localName; 14489 } 14490 $this->tag_close(null, $tagName); 14491 break; 14492 case constant('XMLReader::ELEMENT'): 14493 $empty = $xml->isEmptyElement; 14494 if ($xml->namespaceURI !== '') 14495 { 14496 $tagName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}"; 14497 } 14498 else 14499 { 14500 $tagName = $xml->localName; 14501 } 14502 $attributes = array(); 14503 while ($xml->moveToNextAttribute()) 14504 { 14505 if ($xml->namespaceURI !== '') 14506 { 14507 $attrName = "{$xml->namespaceURI}{$this->separator}{$xml->localName}"; 14508 } 14509 else 14510 { 14511 $attrName = $xml->localName; 14512 } 14513 $attributes[$attrName] = $xml->value; 14514 } 14515 $this->tag_open(null, $tagName, $attributes); 14516 if ($empty) 14517 { 14518 $this->tag_close(null, $tagName); 14519 } 14520 break; 14521 case constant('XMLReader::TEXT'): 14522 14523 case constant('XMLReader::CDATA'): 14524 $this->cdata(null, $xml->value); 14525 break; 14526 } 14527 } 14528 if ($error = libxml_get_last_error()) 14529 { 14530 $this->error_code = $error->code; 14531 $this->error_string = $error->message; 14532 $this->current_line = $error->line; 14533 $this->current_column = $error->column; 14534 return false; 14535 } 14536 else 14537 { 14538 return true; 14539 } 14540 } 14541 } 14542 14543 function get_error_code() 14544 { 14545 return $this->error_code; 14546 } 14547 14548 function get_error_string() 14549 { 14550 return $this->error_string; 14551 } 14552 14553 function get_current_line() 14554 { 14555 return $this->current_line; 14556 } 14557 14558 function get_current_column() 14559 { 14560 return $this->current_column; 14561 } 14562 14563 function get_current_byte() 14564 { 14565 return $this->current_byte; 14566 } 14567 14568 function get_data() 14569 { 14570 return $this->data; 14571 } 14572 14573 function tag_open($parser, $tag, $attributes) 14574 { 14575 list($this->namespace[], $this->element[]) = $this->split_ns($tag); 14576 14577 $attribs = array(); 14578 foreach ($attributes as $name => $value) 14579 { 14580 list($attrib_namespace, $attribute) = $this->split_ns($name); 14581 $attribs[$attrib_namespace][$attribute] = $value; 14582 } 14583 14584 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base'])) 14585 { 14586 $this->xml_base[] = SimplePie_Misc::absolutize_url($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base)); 14587 $this->xml_base_explicit[] = true; 14588 } 14589 else 14590 { 14591 $this->xml_base[] = end($this->xml_base); 14592 $this->xml_base_explicit[] = end($this->xml_base_explicit); 14593 } 14594 14595 if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang'])) 14596 { 14597 $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang']; 14598 } 14599 else 14600 { 14601 $this->xml_lang[] = end($this->xml_lang); 14602 } 14603 14604 if ($this->current_xhtml_construct >= 0) 14605 { 14606 $this->current_xhtml_construct++; 14607 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML) 14608 { 14609 $this->data['data'] .= '<' . end($this->element); 14610 if (isset($attribs[''])) 14611 { 14612 foreach ($attribs[''] as $name => $value) 14613 { 14614 $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"'; 14615 } 14616 } 14617 $this->data['data'] .= '>'; 14618 } 14619 } 14620 else 14621 { 14622 $this->datas[] =& $this->data; 14623 $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][]; 14624 $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang)); 14625 if ((end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml') 14626 || (end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml')) 14627 { 14628 $this->current_xhtml_construct = 0; 14629 } 14630 } 14631 } 14632 14633 function cdata($parser, $cdata) 14634 { 14635 if ($this->current_xhtml_construct >= 0) 14636 { 14637 $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding); 14638 } 14639 else 14640 { 14641 $this->data['data'] .= $cdata; 14642 } 14643 } 14644 14645 function tag_close($parser, $tag) 14646 { 14647 if ($this->current_xhtml_construct >= 0) 14648 { 14649 $this->current_xhtml_construct--; 14650 if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param'))) 14651 { 14652 $this->data['data'] .= '</' . end($this->element) . '>'; 14653 } 14654 } 14655 if ($this->current_xhtml_construct === -1) 14656 { 14657 $this->data =& $this->datas[count($this->datas) - 1]; 14658 array_pop($this->datas); 14659 } 14660 14661 array_pop($this->element); 14662 array_pop($this->namespace); 14663 array_pop($this->xml_base); 14664 array_pop($this->xml_base_explicit); 14665 array_pop($this->xml_lang); 14666 } 14667 14668 function split_ns($string) 14669 { 14670 static $cache = array(); 14671 if (!isset($cache[$string])) 14672 { 14673 if ($pos = strpos($string, $this->separator)) 14674 { 14675 static $separator_length; 14676 if (!$separator_length) 14677 { 14678 $separator_length = strlen($this->separator); 14679 } 14680 $namespace = substr($string, 0, $pos); 14681 $local_name = substr($string, $pos + $separator_length); 14682 if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES) 14683 { 14684 $namespace = SIMPLEPIE_NAMESPACE_ITUNES; 14685 } 14686 14687 // Normalize the Media RSS namespaces 14688 if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG || 14689 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2 || 14690 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3 || 14691 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4 || 14692 $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5 ) 14693 { 14694 $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS; 14695 } 14696 $cache[$string] = array($namespace, $local_name); 14697 } 14698 else 14699 { 14700 $cache[$string] = array('', $string); 14701 } 14702 } 14703 return $cache[$string]; 14704 } 14705 } 14706 14707 /** 14708 * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags 14709 */ 14710 class SimplePie_Sanitize 14711 { 14712 // Private vars 14713 var $base; 14714 14715 // Options 14716 var $remove_div = true; 14717 var $image_handler = ''; 14718 var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'); 14719 var $encode_instead_of_strip = false; 14720 var $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'); 14721 var $strip_comments = false; 14722 var $output_encoding = 'UTF-8'; 14723 var $enable_cache = true; 14724 var $cache_location = './cache'; 14725 var $cache_name_function = 'md5'; 14726 var $cache_class = 'SimplePie_Cache'; 14727 var $file_class = 'SimplePie_File'; 14728 var $timeout = 10; 14729 var $useragent = ''; 14730 var $force_fsockopen = false; 14731 14732 var $replace_url_attributes = array( 14733 'a' => 'href', 14734 'area' => 'href', 14735 'blockquote' => 'cite', 14736 'del' => 'cite', 14737 'form' => 'action', 14738 'img' => array('longdesc', 'src'), 14739 'input' => 'src', 14740 'ins' => 'cite', 14741 'q' => 'cite' 14742 ); 14743 14744 function remove_div($enable = true) 14745 { 14746 $this->remove_div = (bool) $enable; 14747 } 14748 14749 function set_image_handler($page = false) 14750 { 14751 if ($page) 14752 { 14753 $this->image_handler = (string) $page; 14754 } 14755 else 14756 { 14757 $this->image_handler = false; 14758 } 14759 } 14760 14761 function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache') 14762 { 14763 if (isset($enable_cache)) 14764 { 14765 $this->enable_cache = (bool) $enable_cache; 14766 } 14767 14768 if ($cache_location) 14769 { 14770 $this->cache_location = (string) $cache_location; 14771 } 14772 14773 if ($cache_name_function) 14774 { 14775 $this->cache_name_function = (string) $cache_name_function; 14776 } 14777 14778 if ($cache_class) 14779 { 14780 $this->cache_class = (string) $cache_class; 14781 } 14782 } 14783 14784 function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false) 14785 { 14786 if ($file_class) 14787 { 14788 $this->file_class = (string) $file_class; 14789 } 14790 14791 if ($timeout) 14792 { 14793 $this->timeout = (string) $timeout; 14794 } 14795 14796 if ($useragent) 14797 { 14798 $this->useragent = (string) $useragent; 14799 } 14800 14801 if ($force_fsockopen) 14802 { 14803 $this->force_fsockopen = (string) $force_fsockopen; 14804 } 14805 } 14806 14807 function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style')) 14808 { 14809 if ($tags) 14810 { 14811 if (is_array($tags)) 14812 { 14813 $this->strip_htmltags = $tags; 14814 } 14815 else 14816 { 14817 $this->strip_htmltags = explode(',', $tags); 14818 } 14819 } 14820 else 14821 { 14822 $this->strip_htmltags = false; 14823 } 14824 } 14825 14826 function encode_instead_of_strip($encode = false) 14827 { 14828 $this->encode_instead_of_strip = (bool) $encode; 14829 } 14830 14831 function strip_attributes($attribs = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc')) 14832 { 14833 if ($attribs) 14834 { 14835 if (is_array($attribs)) 14836 { 14837 $this->strip_attributes = $attribs; 14838 } 14839 else 14840 { 14841 $this->strip_attributes = explode(',', $attribs); 14842 } 14843 } 14844 else 14845 { 14846 $this->strip_attributes = false; 14847 } 14848 } 14849 14850 function strip_comments($strip = false) 14851 { 14852 $this->strip_comments = (bool) $strip; 14853 } 14854 14855 function set_output_encoding($encoding = 'UTF-8') 14856 { 14857 $this->output_encoding = (string) $encoding; 14858 } 14859 14860 /** 14861 * Set element/attribute key/value pairs of HTML attributes 14862 * containing URLs that need to be resolved relative to the feed 14863 * 14864 * @access public 14865 * @since 1.0 14866 * @param array $element_attribute Element/attribute key/value pairs 14867 */ 14868 function set_url_replacements($element_attribute = array('a' => 'href', 'area' => 'href', 'blockquote' => 'cite', 'del' => 'cite', 'form' => 'action', 'img' => array('longdesc', 'src'), 'input' => 'src', 'ins' => 'cite', 'q' => 'cite')) 14869 { 14870 $this->replace_url_attributes = (array) $element_attribute; 14871 } 14872 14873 function sanitize($data, $type, $base = '') 14874 { 14875 $data = trim($data); 14876 if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI) 14877 { 14878 if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML) 14879 { 14880 if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data)) 14881 { 14882 $type |= SIMPLEPIE_CONSTRUCT_HTML; 14883 } 14884 else 14885 { 14886 $type |= SIMPLEPIE_CONSTRUCT_TEXT; 14887 } 14888 } 14889 14890 if ($type & SIMPLEPIE_CONSTRUCT_BASE64) 14891 { 14892 $data = base64_decode($data); 14893 } 14894 14895 if ($type & SIMPLEPIE_CONSTRUCT_XHTML) 14896 { 14897 if ($this->remove_div) 14898 { 14899 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data); 14900 $data = preg_replace('/<\/div>$/', '', $data); 14901 } 14902 else 14903 { 14904 $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data); 14905 } 14906 } 14907 14908 if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML)) 14909 { 14910 // Strip comments 14911 if ($this->strip_comments) 14912 { 14913 $data = SimplePie_Misc::strip_comments($data); 14914 } 14915 14916 // Strip out HTML tags and attributes that might cause various security problems. 14917 // Based on recommendations by Mark Pilgrim at: 14918 // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely 14919 if ($this->strip_htmltags) 14920 { 14921 foreach ($this->strip_htmltags as $tag) 14922 { 14923 $pcre = "/<($tag)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$tag" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>|(\/)?>)/siU'; 14924 while (preg_match($pcre, $data)) 14925 { 14926 $data = preg_replace_callback($pcre, array(&$this, 'do_strip_htmltags'), $data); 14927 } 14928 } 14929 } 14930 14931 if ($this->strip_attributes) 14932 { 14933 foreach ($this->strip_attributes as $attrib) 14934 { 14935 $data = preg_replace('/(<[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*)' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . trim($attrib) . '(?:\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>/', '\1\2\3>', $data); 14936 } 14937 } 14938 14939 // Replace relative URLs 14940 $this->base = $base; 14941 foreach ($this->replace_url_attributes as $element => $attributes) 14942 { 14943 $data = $this->replace_urls($data, $element, $attributes); 14944 } 14945 14946 // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags. 14947 if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache) 14948 { 14949 $images = SimplePie_Misc::get_element('img', $data); 14950 foreach ($images as $img) 14951 { 14952 if (isset($img['attribs']['src']['data'])) 14953 { 14954 $image_url = call_user_func($this->cache_name_function, $img['attribs']['src']['data']); 14955 $cache = call_user_func(array($this->cache_class, 'create'), $this->cache_location, $image_url, 'spi'); 14956 14957 if ($cache->load()) 14958 { 14959 $img['attribs']['src']['data'] = $this->image_handler . $image_url; 14960 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data); 14961 } 14962 else 14963 { 14964 $file =& new $this->file_class($img['attribs']['src']['data'], $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen); 14965 $headers = $file->headers; 14966 14967 if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300))) 14968 { 14969 if ($cache->save(array('headers' => $file->headers, 'body' => $file->body))) 14970 { 14971 $img['attribs']['src']['data'] = $this->image_handler . $image_url; 14972 $data = str_replace($img['full'], SimplePie_Misc::element_implode($img), $data); 14973 } 14974 else 14975 { 14976 trigger_error("$this->cache_location is not writeable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); 14977 } 14978 } 14979 } 14980 } 14981 } 14982 } 14983 14984 // Having (possibly) taken stuff out, there may now be whitespace at the beginning/end of the data 14985 $data = trim($data); 14986 } 14987 14988 if ($type & SIMPLEPIE_CONSTRUCT_IRI) 14989 { 14990 $data = SimplePie_Misc::absolutize_url($data, $base); 14991 } 14992 14993 if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI)) 14994 { 14995 $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8'); 14996 } 14997 14998 if ($this->output_encoding !== 'UTF-8') 14999 { 15000 $data = SimplePie_Misc::change_encoding($data, 'UTF-8', $this->output_encoding); 15001 } 15002 } 15003 return $data; 15004 } 15005 15006 function replace_urls($data, $tag, $attributes) 15007 { 15008 if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags)) 15009 { 15010 $elements = SimplePie_Misc::get_element($tag, $data); 15011 foreach ($elements as $element) 15012 { 15013 if (is_array($attributes)) 15014 { 15015 foreach ($attributes as $attribute) 15016 { 15017 if (isset($element['attribs'][$attribute]['data'])) 15018 { 15019 $element['attribs'][$attribute]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attribute]['data'], $this->base); 15020 $new_element = SimplePie_Misc::element_implode($element); 15021 $data = str_replace($element['full'], $new_element, $data); 15022 $element['full'] = $new_element; 15023 } 15024 } 15025 } 15026 elseif (isset($element['attribs'][$attributes]['data'])) 15027 { 15028 $element['attribs'][$attributes]['data'] = SimplePie_Misc::absolutize_url($element['attribs'][$attributes]['data'], $this->base); 15029 $data = str_replace($element['full'], SimplePie_Misc::element_implode($element), $data); 15030 } 15031 } 15032 } 15033 return $data; 15034 } 15035 15036 function do_strip_htmltags($match) 15037 { 15038 if ($this->encode_instead_of_strip) 15039 { 15040 if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style'))) 15041 { 15042 $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8'); 15043 $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8'); 15044 return "<$match[1]$match[2]>$match[3]</$match[1]>"; 15045 } 15046 else 15047 { 15048 return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8'); 15049 } 15050 } 15051 elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style'))) 15052 { 15053 return $match[4]; 15054 } 15055 else 15056 { 15057 return ''; 15058 } 15059 } 15060 } 15061 15062 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Nov 16 22:51:00 2010 | Cross-referenced by PHPXref 0.7 |