| [ Index ] |
PHP Cross Reference of Wordpress 2.9.1 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MagpieRSS: a simple RSS integration tool 4 * 5 * A compiled file for RSS syndication 6 * 7 * @author Kellan Elliott-McCrea <kellan@protest.net> 8 * @version 0.51 9 * @license GPL 10 * 11 * @package External 12 * @subpackage MagpieRSS 13 */ 14 15 /* 16 * Hook to use another RSS object instead of MagpieRSS 17 */ 18 do_action('load_feed_engine'); 19 20 /** RSS feed constant. */ 21 define('RSS', 'RSS'); 22 define('ATOM', 'Atom'); 23 define('MAGPIE_USER_AGENT', 'WordPress/' . $GLOBALS['wp_version']); 24 25 class MagpieRSS { 26 var $parser; 27 var $current_item = array(); // item currently being parsed 28 var $items = array(); // collection of parsed items 29 var $channel = array(); // hash of channel fields 30 var $textinput = array(); 31 var $image = array(); 32 var $feed_type; 33 var $feed_version; 34 35 // parser variables 36 var $stack = array(); // parser stack 37 var $inchannel = false; 38 var $initem = false; 39 var $incontent = false; // if in Atom <content mode="xml"> field 40 var $intextinput = false; 41 var $inimage = false; 42 var $current_field = ''; 43 var $current_namespace = false; 44 45 //var $ERROR = ""; 46 47 var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright'); 48 49 function MagpieRSS ($source) { 50 51 # if PHP xml isn't compiled in, die 52 # 53 if ( !function_exists('xml_parser_create') ) 54 trigger_error( "Failed to load PHP's XML Extension. http://www.php.net/manual/en/ref.xml.php" ); 55 56 $parser = @xml_parser_create(); 57 58 if ( !is_resource($parser) ) 59 trigger_error( "Failed to create an instance of PHP's XML parser. http://www.php.net/manual/en/ref.xml.php"); 60 61 62 $this->parser = $parser; 63 64 # pass in parser, and a reference to this object 65 # setup handlers 66 # 67 xml_set_object( $this->parser, $this ); 68 xml_set_element_handler($this->parser, 69 'feed_start_element', 'feed_end_element' ); 70 71 xml_set_character_data_handler( $this->parser, 'feed_cdata' ); 72 73 $status = xml_parse( $this->parser, $source ); 74 75 if (! $status ) { 76 $errorcode = xml_get_error_code( $this->parser ); 77 if ( $errorcode != XML_ERROR_NONE ) { 78 $xml_error = xml_error_string( $errorcode ); 79 $error_line = xml_get_current_line_number($this->parser); 80 $error_col = xml_get_current_column_number($this->parser); 81 $errormsg = "$xml_error at line $error_line, column $error_col"; 82 83 $this->error( $errormsg ); 84 } 85 } 86 87 xml_parser_free( $this->parser ); 88 89 $this->normalize(); 90 } 91 92 function feed_start_element($p, $element, &$attrs) { 93 $el = $element = strtolower($element); 94 $attrs = array_change_key_case($attrs, CASE_LOWER); 95 96 // check for a namespace, and split if found 97 $ns = false; 98 if ( strpos( $element, ':' ) ) { 99 list($ns, $el) = split( ':', $element, 2); 100 } 101 if ( $ns and $ns != 'rdf' ) { 102 $this->current_namespace = $ns; 103 } 104 105 # if feed type isn't set, then this is first element of feed 106 # identify feed from root element 107 # 108 if (!isset($this->feed_type) ) { 109 if ( $el == 'rdf' ) { 110 $this->feed_type = RSS; 111 $this->feed_version = '1.0'; 112 } 113 elseif ( $el == 'rss' ) { 114 $this->feed_type = RSS; 115 $this->feed_version = $attrs['version']; 116 } 117 elseif ( $el == 'feed' ) { 118 $this->feed_type = ATOM; 119 $this->feed_version = $attrs['version']; 120 $this->inchannel = true; 121 } 122 return; 123 } 124 125 if ( $el == 'channel' ) 126 { 127 $this->inchannel = true; 128 } 129 elseif ($el == 'item' or $el == 'entry' ) 130 { 131 $this->initem = true; 132 if ( isset($attrs['rdf:about']) ) { 133 $this->current_item['about'] = $attrs['rdf:about']; 134 } 135 } 136 137 // if we're in the default namespace of an RSS feed, 138 // record textinput or image fields 139 elseif ( 140 $this->feed_type == RSS and 141 $this->current_namespace == '' and 142 $el == 'textinput' ) 143 { 144 $this->intextinput = true; 145 } 146 147 elseif ( 148 $this->feed_type == RSS and 149 $this->current_namespace == '' and 150 $el == 'image' ) 151 { 152 $this->inimage = true; 153 } 154 155 # handle atom content constructs 156 elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) ) 157 { 158 // avoid clashing w/ RSS mod_content 159 if ($el == 'content' ) { 160 $el = 'atom_content'; 161 } 162 163 $this->incontent = $el; 164 165 166 } 167 168 // if inside an Atom content construct (e.g. content or summary) field treat tags as text 169 elseif ($this->feed_type == ATOM and $this->incontent ) 170 { 171 // if tags are inlined, then flatten 172 $attrs_str = join(' ', 173 array_map(array('MagpieRSS', 'map_attrs'), 174 array_keys($attrs), 175 array_values($attrs) ) ); 176 177 $this->append_content( "<$element $attrs_str>" ); 178 179 array_unshift( $this->stack, $el ); 180 } 181 182 // Atom support many links per containging element. 183 // Magpie treats link elements of type rel='alternate' 184 // as being equivalent to RSS's simple link element. 185 // 186 elseif ($this->feed_type == ATOM and $el == 'link' ) 187 { 188 if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' ) 189 { 190 $link_el = 'link'; 191 } 192 else { 193 $link_el = 'link_' . $attrs['rel']; 194 } 195 196 $this->append($link_el, $attrs['href']); 197 } 198 // set stack[0] to current element 199 else { 200 array_unshift($this->stack, $el); 201 } 202 } 203 204 205 206 function feed_cdata ($p, $text) { 207 208 if ($this->feed_type == ATOM and $this->incontent) 209 { 210 $this->append_content( $text ); 211 } 212 else { 213 $current_el = join('_', array_reverse($this->stack)); 214 $this->append($current_el, $text); 215 } 216 } 217 218 function feed_end_element ($p, $el) { 219 $el = strtolower($el); 220 221 if ( $el == 'item' or $el == 'entry' ) 222 { 223 $this->items[] = $this->current_item; 224 $this->current_item = array(); 225 $this->initem = false; 226 } 227 elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' ) 228 { 229 $this->intextinput = false; 230 } 231 elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' ) 232 { 233 $this->inimage = false; 234 } 235 elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) ) 236 { 237 $this->incontent = false; 238 } 239 elseif ($el == 'channel' or $el == 'feed' ) 240 { 241 $this->inchannel = false; 242 } 243 elseif ($this->feed_type == ATOM and $this->incontent ) { 244 // balance tags properly 245 // note: i don't think this is actually neccessary 246 if ( $this->stack[0] == $el ) 247 { 248 $this->append_content("</$el>"); 249 } 250 else { 251 $this->append_content("<$el />"); 252 } 253 254 array_shift( $this->stack ); 255 } 256 else { 257 array_shift( $this->stack ); 258 } 259 260 $this->current_namespace = false; 261 } 262 263 function concat (&$str1, $str2="") { 264 if (!isset($str1) ) { 265 $str1=""; 266 } 267 $str1 .= $str2; 268 } 269 270 function append_content($text) { 271 if ( $this->initem ) { 272 $this->concat( $this->current_item[ $this->incontent ], $text ); 273 } 274 elseif ( $this->inchannel ) { 275 $this->concat( $this->channel[ $this->incontent ], $text ); 276 } 277 } 278 279 // smart append - field and namespace aware 280 function append($el, $text) { 281 if (!$el) { 282 return; 283 } 284 if ( $this->current_namespace ) 285 { 286 if ( $this->initem ) { 287 $this->concat( 288 $this->current_item[ $this->current_namespace ][ $el ], $text); 289 } 290 elseif ($this->inchannel) { 291 $this->concat( 292 $this->channel[ $this->current_namespace][ $el ], $text ); 293 } 294 elseif ($this->intextinput) { 295 $this->concat( 296 $this->textinput[ $this->current_namespace][ $el ], $text ); 297 } 298 elseif ($this->inimage) { 299 $this->concat( 300 $this->image[ $this->current_namespace ][ $el ], $text ); 301 } 302 } 303 else { 304 if ( $this->initem ) { 305 $this->concat( 306 $this->current_item[ $el ], $text); 307 } 308 elseif ($this->intextinput) { 309 $this->concat( 310 $this->textinput[ $el ], $text ); 311 } 312 elseif ($this->inimage) { 313 $this->concat( 314 $this->image[ $el ], $text ); 315 } 316 elseif ($this->inchannel) { 317 $this->concat( 318 $this->channel[ $el ], $text ); 319 } 320 321 } 322 } 323 324 function normalize () { 325 // if atom populate rss fields 326 if ( $this->is_atom() ) { 327 $this->channel['descripton'] = $this->channel['tagline']; 328 for ( $i = 0; $i < count($this->items); $i++) { 329 $item = $this->items[$i]; 330 if ( isset($item['summary']) ) 331 $item['description'] = $item['summary']; 332 if ( isset($item['atom_content'])) 333 $item['content']['encoded'] = $item['atom_content']; 334 335 $this->items[$i] = $item; 336 } 337 } 338 elseif ( $this->is_rss() ) { 339 $this->channel['tagline'] = $this->channel['description']; 340 for ( $i = 0; $i < count($this->items); $i++) { 341 $item = $this->items[$i]; 342 if ( isset($item['description'])) 343 $item['summary'] = $item['description']; 344 if ( isset($item['content']['encoded'] ) ) 345 $item['atom_content'] = $item['content']['encoded']; 346 347 $this->items[$i] = $item; 348 } 349 } 350 } 351 352 function is_rss () { 353 if ( $this->feed_type == RSS ) { 354 return $this->feed_version; 355 } 356 else { 357 return false; 358 } 359 } 360 361 function is_atom() { 362 if ( $this->feed_type == ATOM ) { 363 return $this->feed_version; 364 } 365 else { 366 return false; 367 } 368 } 369 370 function map_attrs($k, $v) { 371 return "$k=\"$v\""; 372 } 373 374 function error( $errormsg, $lvl = E_USER_WARNING ) { 375 // append PHP's error message if track_errors enabled 376 if ( isset($php_errormsg) ) { 377 $errormsg .= " ($php_errormsg)"; 378 } 379 if ( MAGPIE_DEBUG ) { 380 trigger_error( $errormsg, $lvl); 381 } else { 382 error_log( $errormsg, 0); 383 } 384 } 385 386 } 387 388 if ( !function_exists('fetch_rss') ) : 389 /** 390 * Build Magpie object based on RSS from URL. 391 * 392 * @since unknown 393 * @package External 394 * @subpackage MagpieRSS 395 * 396 * @param string $url URL to retrieve feed 397 * @return bool|MagpieRSS false on failure or MagpieRSS object on success. 398 */ 399 function fetch_rss ($url) { 400 // initialize constants 401 init(); 402 403 if ( !isset($url) ) { 404 // error("fetch_rss called without a url"); 405 return false; 406 } 407 408 // if cache is disabled 409 if ( !MAGPIE_CACHE_ON ) { 410 // fetch file, and parse it 411 $resp = _fetch_remote_file( $url ); 412 if ( is_success( $resp->status ) ) { 413 return _response_to_rss( $resp ); 414 } 415 else { 416 // error("Failed to fetch $url and cache is off"); 417 return false; 418 } 419 } 420 // else cache is ON 421 else { 422 // Flow 423 // 1. check cache 424 // 2. if there is a hit, make sure its fresh 425 // 3. if cached obj fails freshness check, fetch remote 426 // 4. if remote fails, return stale object, or error 427 428 $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE ); 429 430 if (MAGPIE_DEBUG and $cache->ERROR) { 431 debug($cache->ERROR, E_USER_WARNING); 432 } 433 434 435 $cache_status = 0; // response of check_cache 436 $request_headers = array(); // HTTP headers to send with fetch 437 $rss = 0; // parsed RSS object 438 $errormsg = 0; // errors, if any 439 440 if (!$cache->ERROR) { 441 // return cache HIT, MISS, or STALE 442 $cache_status = $cache->check_cache( $url ); 443 } 444 445 // if object cached, and cache is fresh, return cached obj 446 if ( $cache_status == 'HIT' ) { 447 $rss = $cache->get( $url ); 448 if ( isset($rss) and $rss ) { 449 $rss->from_cache = 1; 450 if ( MAGPIE_DEBUG > 1) { 451 debug("MagpieRSS: Cache HIT", E_USER_NOTICE); 452 } 453 return $rss; 454 } 455 } 456 457 // else attempt a conditional get 458 459 // setup headers 460 if ( $cache_status == 'STALE' ) { 461 $rss = $cache->get( $url ); 462 if ( isset($rss->etag) and $rss->last_modified ) { 463 $request_headers['If-None-Match'] = $rss->etag; 464 $request_headers['If-Last-Modified'] = $rss->last_modified; 465 } 466 } 467 468 $resp = _fetch_remote_file( $url, $request_headers ); 469 470 if (isset($resp) and $resp) { 471 if ($resp->status == '304' ) { 472 // we have the most current copy 473 if ( MAGPIE_DEBUG > 1) { 474 debug("Got 304 for $url"); 475 } 476 // reset cache on 304 (at minutillo insistent prodding) 477 $cache->set($url, $rss); 478 return $rss; 479 } 480 elseif ( is_success( $resp->status ) ) { 481 $rss = _response_to_rss( $resp ); 482 if ( $rss ) { 483 if (MAGPIE_DEBUG > 1) { 484 debug("Fetch successful"); 485 } 486 // add object to cache 487 $cache->set( $url, $rss ); 488 return $rss; 489 } 490 } 491 else { 492 $errormsg = "Failed to fetch $url. "; 493 if ( $resp->error ) { 494 # compensate for Snoopy's annoying habbit to tacking 495 # on '\n' 496 $http_error = substr($resp->error, 0, -2); 497 $errormsg .= "(HTTP Error: $http_error)"; 498 } 499 else { 500 $errormsg .= "(HTTP Response: " . $resp->response_code .')'; 501 } 502 } 503 } 504 else { 505 $errormsg = "Unable to retrieve RSS file for unknown reasons."; 506 } 507 508 // else fetch failed 509 510 // attempt to return cached object 511 if ($rss) { 512 if ( MAGPIE_DEBUG ) { 513 debug("Returning STALE object for $url"); 514 } 515 return $rss; 516 } 517 518 // else we totally failed 519 // error( $errormsg ); 520 521 return false; 522 523 } // end if ( !MAGPIE_CACHE_ON ) { 524 } // end fetch_rss() 525 endif; 526 527 /** 528 * Retrieve URL headers and content using WP HTTP Request API. 529 * 530 * @since unknown 531 * @package External 532 * @subpackage MagpieRSS 533 * 534 * @param string $url URL to retrieve 535 * @param array $headers Optional. Headers to send to the URL. 536 * @return Snoopy style response 537 */ 538 function _fetch_remote_file ($url, $headers = "" ) { 539 $resp = wp_remote_request($url, array('headers' => $headers, 'timeout' => MAGPIE_FETCH_TIME_OUT)); 540 if ( is_wp_error($resp) ) { 541 $error = array_shift($resp->errors); 542 543 $resp = new stdClass; 544 $resp->status = 500; 545 $resp->response_code = 500; 546 $resp->error = $error[0] . "\n"; //\n = Snoopy compatibility 547 return $resp; 548 } 549 $response = new stdClass; 550 $response->status = $resp['response']['code']; 551 $response->response_code = $resp['response']['code']; 552 $response->headers = $resp['headers']; 553 $response->results = $resp['body']; 554 555 return $response; 556 } 557 558 /** 559 * Retrieve 560 * 561 * @since unknown 562 * @package External 563 * @subpackage MagpieRSS 564 * 565 * @param unknown_type $resp 566 * @return unknown 567 */ 568 function _response_to_rss ($resp) { 569 $rss = new MagpieRSS( $resp->results ); 570 571 // if RSS parsed successfully 572 if ( $rss && (!isset($rss->ERROR) || !$rss->ERROR) ) { 573 574 // find Etag, and Last-Modified 575 foreach( (array) $resp->headers as $h) { 576 // 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1" 577 if (strpos($h, ": ")) { 578 list($field, $val) = explode(": ", $h, 2); 579 } 580 else { 581 $field = $h; 582 $val = ""; 583 } 584 585 if ( $field == 'ETag' ) { 586 $rss->etag = $val; 587 } 588 589 if ( $field == 'Last-Modified' ) { 590 $rss->last_modified = $val; 591 } 592 } 593 594 return $rss; 595 } // else construct error message 596 else { 597 $errormsg = "Failed to parse RSS file."; 598 599 if ($rss) { 600 $errormsg .= " (" . $rss->ERROR . ")"; 601 } 602 // error($errormsg); 603 604 return false; 605 } // end if ($rss and !$rss->error) 606 } 607 608 /** 609 * Setup constants with default values, unless user overrides. 610 * 611 * @since unknown 612 * @package External 613 * @subpackage MagpieRSS 614 */ 615 function init () { 616 if ( defined('MAGPIE_INITALIZED') ) { 617 return; 618 } 619 else { 620 define('MAGPIE_INITALIZED', 1); 621 } 622 623 if ( !defined('MAGPIE_CACHE_ON') ) { 624 define('MAGPIE_CACHE_ON', 1); 625 } 626 627 if ( !defined('MAGPIE_CACHE_DIR') ) { 628 define('MAGPIE_CACHE_DIR', './cache'); 629 } 630 631 if ( !defined('MAGPIE_CACHE_AGE') ) { 632 define('MAGPIE_CACHE_AGE', 60*60); // one hour 633 } 634 635 if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) { 636 define('MAGPIE_CACHE_FRESH_ONLY', 0); 637 } 638 639 if ( !defined('MAGPIE_DEBUG') ) { 640 define('MAGPIE_DEBUG', 0); 641 } 642 643 if ( !defined('MAGPIE_USER_AGENT') ) { 644 $ua = 'WordPress/' . $GLOBALS['wp_version']; 645 646 if ( MAGPIE_CACHE_ON ) { 647 $ua = $ua . ')'; 648 } 649 else { 650 $ua = $ua . '; No cache)'; 651 } 652 653 define('MAGPIE_USER_AGENT', $ua); 654 } 655 656 if ( !defined('MAGPIE_FETCH_TIME_OUT') ) { 657 define('MAGPIE_FETCH_TIME_OUT', 2); // 2 second timeout 658 } 659 660 // use gzip encoding to fetch rss files if supported? 661 if ( !defined('MAGPIE_USE_GZIP') ) { 662 define('MAGPIE_USE_GZIP', true); 663 } 664 } 665 666 function is_info ($sc) { 667 return $sc >= 100 && $sc < 200; 668 } 669 670 function is_success ($sc) { 671 return $sc >= 200 && $sc < 300; 672 } 673 674 function is_redirect ($sc) { 675 return $sc >= 300 && $sc < 400; 676 } 677 678 function is_error ($sc) { 679 return $sc >= 400 && $sc < 600; 680 } 681 682 function is_client_error ($sc) { 683 return $sc >= 400 && $sc < 500; 684 } 685 686 function is_server_error ($sc) { 687 return $sc >= 500 && $sc < 600; 688 } 689 690 class RSSCache { 691 var $BASE_CACHE; // where the cache files are stored 692 var $MAX_AGE = 43200; // when are files stale, default twelve hours 693 var $ERROR = ''; // accumulate error messages 694 695 function RSSCache ($base='', $age='') { 696 $this->BASE_CACHE = WP_CONTENT_DIR . '/cache'; 697 if ( $base ) { 698 $this->BASE_CACHE = $base; 699 } 700 if ( $age ) { 701 $this->MAX_AGE = $age; 702 } 703 704 } 705 706 /*=======================================================================*\ 707 Function: set 708 Purpose: add an item to the cache, keyed on url 709 Input: url from wich the rss file was fetched 710 Output: true on sucess 711 \*=======================================================================*/ 712 function set ($url, $rss) { 713 global $wpdb; 714 $cache_option = 'rss_' . $this->file_name( $url ); 715 716 set_transient($cache_option, $rss, $this->MAX_AGE); 717 718 return $cache_option; 719 } 720 721 /*=======================================================================*\ 722 Function: get 723 Purpose: fetch an item from the cache 724 Input: url from wich the rss file was fetched 725 Output: cached object on HIT, false on MISS 726 \*=======================================================================*/ 727 function get ($url) { 728 $this->ERROR = ""; 729 $cache_option = 'rss_' . $this->file_name( $url ); 730 731 if ( ! $rss = get_transient( $cache_option ) ) { 732 $this->debug( 733 "Cache doesn't contain: $url (cache option: $cache_option)" 734 ); 735 return 0; 736 } 737 738 return $rss; 739 } 740 741 /*=======================================================================*\ 742 Function: check_cache 743 Purpose: check a url for membership in the cache 744 and whether the object is older then MAX_AGE (ie. STALE) 745 Input: url from wich the rss file was fetched 746 Output: cached object on HIT, false on MISS 747 \*=======================================================================*/ 748 function check_cache ( $url ) { 749 $this->ERROR = ""; 750 $cache_option = 'rss_' . $this->file_name( $url ); 751 752 if ( get_transient($cache_option) ) { 753 // object exists and is current 754 return 'HIT'; 755 } else { 756 // object does not exist 757 return 'MISS'; 758 } 759 } 760 761 /*=======================================================================*\ 762 Function: serialize 763 \*=======================================================================*/ 764 function serialize ( $rss ) { 765 return serialize( $rss ); 766 } 767 768 /*=======================================================================*\ 769 Function: unserialize 770 \*=======================================================================*/ 771 function unserialize ( $data ) { 772 return unserialize( $data ); 773 } 774 775 /*=======================================================================*\ 776 Function: file_name 777 Purpose: map url to location in cache 778 Input: url from wich the rss file was fetched 779 Output: a file name 780 \*=======================================================================*/ 781 function file_name ($url) { 782 return md5( $url ); 783 } 784 785 /*=======================================================================*\ 786 Function: error 787 Purpose: register error 788 \*=======================================================================*/ 789 function error ($errormsg, $lvl=E_USER_WARNING) { 790 // append PHP's error message if track_errors enabled 791 if ( isset($php_errormsg) ) { 792 $errormsg .= " ($php_errormsg)"; 793 } 794 $this->ERROR = $errormsg; 795 if ( MAGPIE_DEBUG ) { 796 trigger_error( $errormsg, $lvl); 797 } 798 else { 799 error_log( $errormsg, 0); 800 } 801 } 802 function debug ($debugmsg, $lvl=E_USER_NOTICE) { 803 if ( MAGPIE_DEBUG ) { 804 $this->error("MagpieRSS [debug] $debugmsg", $lvl); 805 } 806 } 807 } 808 809 if ( !function_exists('parse_w3cdtf') ) : 810 function parse_w3cdtf ( $date_str ) { 811 812 # regex to match wc3dtf 813 $pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/"; 814 815 if ( preg_match( $pat, $date_str, $match ) ) { 816 list( $year, $month, $day, $hours, $minutes, $seconds) = 817 array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[7]); 818 819 # calc epoch for current date assuming GMT 820 $epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year); 821 822 $offset = 0; 823 if ( $match[11] == 'Z' ) { 824 # zulu time, aka GMT 825 } 826 else { 827 list( $tz_mod, $tz_hour, $tz_min ) = 828 array( $match[8], $match[9], $match[10]); 829 830 # zero out the variables 831 if ( ! $tz_hour ) { $tz_hour = 0; } 832 if ( ! $tz_min ) { $tz_min = 0; } 833 834 $offset_secs = (($tz_hour*60)+$tz_min)*60; 835 836 # is timezone ahead of GMT? then subtract offset 837 # 838 if ( $tz_mod == '+' ) { 839 $offset_secs = $offset_secs * -1; 840 } 841 842 $offset = $offset_secs; 843 } 844 $epoch = $epoch + $offset; 845 return $epoch; 846 } 847 else { 848 return -1; 849 } 850 } 851 endif; 852 853 if ( !function_exists('wp_rss') ) : 854 /** 855 * Display all RSS items in a HTML ordered list. 856 * 857 * @since unknown 858 * @package External 859 * @subpackage MagpieRSS 860 * 861 * @param string $url URL of feed to display. Will not auto sense feed URL. 862 * @param int $num_items Optional. Number of items to display, default is all. 863 */ 864 function wp_rss( $url, $num_items = -1 ) { 865 if ( $rss = fetch_rss( $url ) ) { 866 echo '<ul>'; 867 868 if ( $num_items !== -1 ) { 869 $rss->items = array_slice( $rss->items, 0, $num_items ); 870 } 871 872 foreach ( (array) $rss->items as $item ) { 873 printf( 874 '<li><a href="%1$s" title="%2$s">%3$s</a></li>', 875 esc_url( $item['link'] ), 876 esc_attr( strip_tags( $item['description'] ) ), 877 htmlentities( $item['title'] ) 878 ); 879 } 880 881 echo '</ul>'; 882 } else { 883 _e( 'An error has occurred, which probably means the feed is down. Try again later.' ); 884 } 885 } 886 endif; 887 888 if ( !function_exists('get_rss') ) : 889 /** 890 * Display RSS items in HTML list items. 891 * 892 * You have to specify which HTML list you want, either ordered or unordered 893 * before using the function. You also have to specify how many items you wish 894 * to display. You can't display all of them like you can with wp_rss() 895 * function. 896 * 897 * @since unknown 898 * @package External 899 * @subpackage MagpieRSS 900 * 901 * @param string $url URL of feed to display. Will not auto sense feed URL. 902 * @param int $num_items Optional. Number of items to display, default is all. 903 * @return bool False on failure. 904 */ 905 function get_rss ($url, $num_items = 5) { // Like get posts, but for RSS 906 $rss = fetch_rss($url); 907 if ( $rss ) { 908 $rss->items = array_slice($rss->items, 0, $num_items); 909 foreach ( (array) $rss->items as $item ) { 910 echo "<li>\n"; 911 echo "<a href='$item[link]' title='$item[description]'>"; 912 echo htmlentities($item['title']); 913 echo "</a><br />\n"; 914 echo "</li>\n"; 915 } 916 } else { 917 return false; 918 } 919 } 920 endif; 921 922 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Fri Jan 8 00:19:48 2010 | Cross-referenced by PHPXref 0.7 |