[ Index ]

PHP Cross Reference of WordPress

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


Generated: Wed Sep 18 01:00:03 2019 Cross-referenced by PHPXref 0.7.1