[ Index ]

PHP Cross Reference of Wordpress 2.9.1

title

Body

[close]

/wp-includes/ -> rss.php (source)

   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  ?>


Generated: Fri Jan 8 00:19:48 2010 Cross-referenced by PHPXref 0.7