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