Make WordPress Core

Changeset 4399


Ignore:
Timestamp:
10/16/2006 04:16:06 AM (20 years ago)
Author:
markjaquith
Message:

SimplePie patch not ready for prime time. Need it to be a drop-in solution. Reverting to MagpieRSS for now.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-admin/index.php

    r4378 r4399  
    1717
    1818<?php
    19 $rss = fetch_simplepie('http://feeds.technorati.com/cosmos/rss/?url='. trailingslashit(get_option('home')) .'&partner=wordpress');
    20 if ( $rss && $rss->get_item_quantity() > 0 ) {
     19$rss = @fetch_rss('http://feeds.technorati.com/cosmos/rss/?url='. trailingslashit(get_option('home')) .'&partner=wordpress');
     20if ( isset($rss->items) && 0 != count($rss->items) ) {
    2121?>
    2222<div id="incominglinks">
    … …  
    2424<ul>
    2525<?php
    26 foreach ($rss->get_items(0, 10) as $item ) {
     26$rss->items = array_slice($rss->items, 0, 10);
     27foreach ($rss->items as $item ) {
    2728?>
    28         <li><a href="<?php echo wp_filter_kses($item->get_permalink()); ?>"><?php echo wptexturize(wp_specialchars($item->get_title())); ?></a></li>
     29        <li><a href="<?php echo wp_filter_kses($item['link']); ?>"><?php echo wptexturize(wp_specialchars($item['title'])); ?></a></li>
    2930<?php } ?>
    3031</ul>
    … …  
    129130<p><?php _e("Need help with WordPress? Please see our <a href='http://codex.wordpress.org/'>documentation</a> or visit the <a href='http://wordpress.org/support/'>support forums</a>."); ?></p>
    130131<?php
    131 $rss = fetch_simplepie('http://wordpress.org/development/feed/');
    132 if ( $rss && $rss->get_item_quantity() > 0 ) {
     132$rss = @fetch_rss('http://wordpress.org/development/feed/');
     133if ( isset($rss->items) && 0 != count($rss->items) ) {
    133134?>
    134135<div id="devnews">
    135136<h3><?php _e('WordPress Development Blog'); ?></h3>
    136137<?php
    137 foreach ($rss->get_items(0, 3) as $item ) {
     138$rss->items = array_slice($rss->items, 0, 3);
     139foreach ($rss->items as $item ) {
    138140?>
    139 <h4><a href='<?php echo wp_filter_kses($item->get_permalink()); ?>'><?php echo wp_specialchars($item->get_title()); ?></a> &#8212; <?php printf(__('%s ago'), human_time_diff( $item->get_date('U') ) ); ?></h4>
    140 <p><?php echo $item->get_description(); ?></p>
     141<h4><a href='<?php echo wp_filter_kses($item['link']); ?>'><?php echo wp_specialchars($item['title']); ?></a> &#8212; <?php printf(__('%s ago'), human_time_diff(strtotime($item['pubdate'], time() ) ) ); ?></h4>
     142<p><?php echo $item['description']; ?></p>
    141143<?php
    142144        }
    … …  
    146148
    147149<?php
    148 $rss = fetch_simplepie('http://planet.wordpress.org/feed/');
    149 if ( $rss && $rss->get_item_quantity() > 0 ) {
     150$rss = @fetch_rss('http://planet.wordpress.org/feed/');
     151if ( isset($rss->items) && 0 != count($rss->items) ) {
    150152?>
    151153<div id="planetnews">
    … …  
    153155<ul>
    154156<?php
    155 foreach ($rss->get_items(0, 20) as $item ) {
    156 $title = wp_specialchars($item->get_title());
    157 $author = preg_replace( '|(.+?):.+|s', '$1', $item->get_title() );
    158 $post = preg_replace( '|.+?:(.+)|s', '$1', $item->get_title() );
     157$rss->items = array_slice($rss->items, 0, 20);
     158foreach ($rss->items as $item ) {
     159$title = wp_specialchars($item['title']);
     160$author = preg_replace( '|(.+?):.+|s', '$1', $item['title'] );
     161$post = preg_replace( '|.+?:(.+)|s', '$1', $item['title'] );
    159162?>
    160 <li><a href='<?php echo wp_filter_kses($item->get_permalink()); ?>'><span class="post"><?php echo $post; ?></span><span class="hidden"> - </span><cite><?php echo $author; ?></cite></a></li>
     163<li><a href='<?php echo wp_filter_kses($item['link']); ?>'><span class="post"><?php echo $post; ?></span><span class="hidden"> - </span><cite><?php echo $author; ?></cite></a></li>
    161164<?php
    162165        }
  • trunk/wp-includes/rss.php

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