Make WordPress Core

Changeset 4399


Ignore:
Timestamp:
10/16/2006 04:16:06 AM (19 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.