-
+ 6D33907974C8717162FE675A1AE57FF11A7F3AC2F958FB5B0F785163FCAC35F354F1EB0C3B71AC98FFFFD083367A84B77DF2774F78BBBA9C7722872AC363E376mp-wp/wp-includes/rss.php(0 . 0)(1 . 943)
149690 <?php
149691 /**
149692 * MagpieRSS: a simple RSS integration tool
149693 *
149694 * A compiled file for RSS syndication
149695 *
149696 * @author Kellan Elliott-McCrea <kellan@protest.net>
149697 * @version 0.51
149698 * @license GPL
149699 *
149700 * @package External
149701 * @subpackage MagpieRSS
149702 */
149703
149704 /*
149705 * Hook to use another RSS object instead of MagpieRSS
149706 */
149707 do_action('load_feed_engine');
149708
149709 /** RSS feed constant. */
149710 define('RSS', 'RSS');
149711 define('ATOM', 'Atom');
149712 define('MAGPIE_USER_AGENT', 'WordPress/' . $GLOBALS['wp_version']);
149713
149714 class MagpieRSS {
149715 var $parser;
149716 var $current_item = array(); // item currently being parsed
149717 var $items = array(); // collection of parsed items
149718 var $channel = array(); // hash of channel fields
149719 var $textinput = array();
149720 var $image = array();
149721 var $feed_type;
149722 var $feed_version;
149723
149724 // parser variables
149725 var $stack = array(); // parser stack
149726 var $inchannel = false;
149727 var $initem = false;
149728 var $incontent = false; // if in Atom <content mode="xml"> field
149729 var $intextinput = false;
149730 var $inimage = false;
149731 var $current_field = '';
149732 var $current_namespace = false;
149733
149734 //var $ERROR = "";
149735
149736 var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright');
149737
149738 function MagpieRSS ($source) {
149739
149740 # if PHP xml isn't compiled in, die
149741 #
149742 if ( !function_exists('xml_parser_create') )
149743 trigger_error( "Failed to load PHP's XML Extension. http://www.php.net/manual/en/ref.xml.php" );
149744
149745 $parser = @xml_parser_create();
149746
149747 if ( !is_resource($parser) )
149748 trigger_error( "Failed to create an instance of PHP's XML parser. http://www.php.net/manual/en/ref.xml.php");
149749
149750
149751 $this->parser = $parser;
149752
149753 # pass in parser, and a reference to this object
149754 # setup handlers
149755 #
149756 xml_set_object( $this->parser, $this );
149757 xml_set_element_handler($this->parser,
149758 'feed_start_element', 'feed_end_element' );
149759
149760 xml_set_character_data_handler( $this->parser, 'feed_cdata' );
149761
149762 $status = xml_parse( $this->parser, $source );
149763
149764 if (! $status ) {
149765 $errorcode = xml_get_error_code( $this->parser );
149766 if ( $errorcode != XML_ERROR_NONE ) {
149767 $xml_error = xml_error_string( $errorcode );
149768 $error_line = xml_get_current_line_number($this->parser);
149769 $error_col = xml_get_current_column_number($this->parser);
149770 $errormsg = "$xml_error at line $error_line, column $error_col";
149771
149772 $this->error( $errormsg );
149773 }
149774 }
149775
149776 xml_parser_free( $this->parser );
149777
149778 $this->normalize();
149779 }
149780
149781 function feed_start_element($p, $element, &$attrs) {
149782 $el = $element = strtolower($element);
149783 $attrs = array_change_key_case($attrs, CASE_LOWER);
149784
149785 // check for a namespace, and split if found
149786 $ns = false;
149787 if ( strpos( $element, ':' ) ) {
149788 list($ns, $el) = split( ':', $element, 2);
149789 }
149790 if ( $ns and $ns != 'rdf' ) {
149791 $this->current_namespace = $ns;
149792 }
149793
149794 # if feed type isn't set, then this is first element of feed
149795 # identify feed from root element
149796 #
149797 if (!isset($this->feed_type) ) {
149798 if ( $el == 'rdf' ) {
149799 $this->feed_type = RSS;
149800 $this->feed_version = '1.0';
149801 }
149802 elseif ( $el == 'rss' ) {
149803 $this->feed_type = RSS;
149804 $this->feed_version = $attrs['version'];
149805 }
149806 elseif ( $el == 'feed' ) {
149807 $this->feed_type = ATOM;
149808 $this->feed_version = $attrs['version'];
149809 $this->inchannel = true;
149810 }
149811 return;
149812 }
149813
149814 if ( $el == 'channel' )
149815 {
149816 $this->inchannel = true;
149817 }
149818 elseif ($el == 'item' or $el == 'entry' )
149819 {
149820 $this->initem = true;
149821 if ( isset($attrs['rdf:about']) ) {
149822 $this->current_item['about'] = $attrs['rdf:about'];
149823 }
149824 }
149825
149826 // if we're in the default namespace of an RSS feed,
149827 // record textinput or image fields
149828 elseif (
149829 $this->feed_type == RSS and
149830 $this->current_namespace == '' and
149831 $el == 'textinput' )
149832 {
149833 $this->intextinput = true;
149834 }
149835
149836 elseif (
149837 $this->feed_type == RSS and
149838 $this->current_namespace == '' and
149839 $el == 'image' )
149840 {
149841 $this->inimage = true;
149842 }
149843
149844 # handle atom content constructs
149845 elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
149846 {
149847 // avoid clashing w/ RSS mod_content
149848 if ($el == 'content' ) {
149849 $el = 'atom_content';
149850 }
149851
149852 $this->incontent = $el;
149853
149854
149855 }
149856
149857 // if inside an Atom content construct (e.g. content or summary) field treat tags as text
149858 elseif ($this->feed_type == ATOM and $this->incontent )
149859 {
149860 // if tags are inlined, then flatten
149861 $attrs_str = join(' ',
149862 array_map('map_attrs',
149863 array_keys($attrs),
149864 array_values($attrs) ) );
149865
149866 $this->append_content( "<$element $attrs_str>" );
149867
149868 array_unshift( $this->stack, $el );
149869 }
149870
149871 // Atom support many links per containging element.
149872 // Magpie treats link elements of type rel='alternate'
149873 // as being equivalent to RSS's simple link element.
149874 //
149875 elseif ($this->feed_type == ATOM and $el == 'link' )
149876 {
149877 if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' )
149878 {
149879 $link_el = 'link';
149880 }
149881 else {
149882 $link_el = 'link_' . $attrs['rel'];
149883 }
149884
149885 $this->append($link_el, $attrs['href']);
149886 }
149887 // set stack[0] to current element
149888 else {
149889 array_unshift($this->stack, $el);
149890 }
149891 }
149892
149893
149894
149895 function feed_cdata ($p, $text) {
149896
149897 if ($this->feed_type == ATOM and $this->incontent)
149898 {
149899 $this->append_content( $text );
149900 }
149901 else {
149902 $current_el = join('_', array_reverse($this->stack));
149903 $this->append($current_el, $text);
149904 }
149905 }
149906
149907 function feed_end_element ($p, $el) {
149908 $el = strtolower($el);
149909
149910 if ( $el == 'item' or $el == 'entry' )
149911 {
149912 $this->items[] = $this->current_item;
149913 $this->current_item = array();
149914 $this->initem = false;
149915 }
149916 elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' )
149917 {
149918 $this->intextinput = false;
149919 }
149920 elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' )
149921 {
149922 $this->inimage = false;
149923 }
149924 elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
149925 {
149926 $this->incontent = false;
149927 }
149928 elseif ($el == 'channel' or $el == 'feed' )
149929 {
149930 $this->inchannel = false;
149931 }
149932 elseif ($this->feed_type == ATOM and $this->incontent ) {
149933 // balance tags properly
149934 // note: i don't think this is actually neccessary
149935 if ( $this->stack[0] == $el )
149936 {
149937 $this->append_content("</$el>");
149938 }
149939 else {
149940 $this->append_content("<$el />");
149941 }
149942
149943 array_shift( $this->stack );
149944 }
149945 else {
149946 array_shift( $this->stack );
149947 }
149948
149949 $this->current_namespace = false;
149950 }
149951
149952 function concat (&$str1, $str2="") {
149953 if (!isset($str1) ) {
149954 $str1="";
149955 }
149956 $str1 .= $str2;
149957 }
149958
149959 function append_content($text) {
149960 if ( $this->initem ) {
149961 $this->concat( $this->current_item[ $this->incontent ], $text );
149962 }
149963 elseif ( $this->inchannel ) {
149964 $this->concat( $this->channel[ $this->incontent ], $text );
149965 }
149966 }
149967
149968 // smart append - field and namespace aware
149969 function append($el, $text) {
149970 if (!$el) {
149971 return;
149972 }
149973 if ( $this->current_namespace )
149974 {
149975 if ( $this->initem ) {
149976 $this->concat(
149977 $this->current_item[ $this->current_namespace ][ $el ], $text);
149978 }
149979 elseif ($this->inchannel) {
149980 $this->concat(
149981 $this->channel[ $this->current_namespace][ $el ], $text );
149982 }
149983 elseif ($this->intextinput) {
149984 $this->concat(
149985 $this->textinput[ $this->current_namespace][ $el ], $text );
149986 }
149987 elseif ($this->inimage) {
149988 $this->concat(
149989 $this->image[ $this->current_namespace ][ $el ], $text );
149990 }
149991 }
149992 else {
149993 if ( $this->initem ) {
149994 $this->concat(
149995 $this->current_item[ $el ], $text);
149996 }
149997 elseif ($this->intextinput) {
149998 $this->concat(
149999 $this->textinput[ $el ], $text );
150000 }
150001 elseif ($this->inimage) {
150002 $this->concat(
150003 $this->image[ $el ], $text );
150004 }
150005 elseif ($this->inchannel) {
150006 $this->concat(
150007 $this->channel[ $el ], $text );
150008 }
150009
150010 }
150011 }
150012
150013 function normalize () {
150014 // if atom populate rss fields
150015 if ( $this->is_atom() ) {
150016 $this->channel['descripton'] = $this->channel['tagline'];
150017 for ( $i = 0; $i < count($this->items); $i++) {
150018 $item = $this->items[$i];
150019 if ( isset($item['summary']) )
150020 $item['description'] = $item['summary'];
150021 if ( isset($item['atom_content']))
150022 $item['content']['encoded'] = $item['atom_content'];
150023
150024 $this->items[$i] = $item;
150025 }
150026 }
150027 elseif ( $this->is_rss() ) {
150028 $this->channel['tagline'] = $this->channel['description'];
150029 for ( $i = 0; $i < count($this->items); $i++) {
150030 $item = $this->items[$i];
150031 if ( isset($item['description']))
150032 $item['summary'] = $item['description'];
150033 if ( isset($item['content']['encoded'] ) )
150034 $item['atom_content'] = $item['content']['encoded'];
150035
150036 $this->items[$i] = $item;
150037 }
150038 }
150039 }
150040
150041 function is_rss () {
150042 if ( $this->feed_type == RSS ) {
150043 return $this->feed_version;
150044 }
150045 else {
150046 return false;
150047 }
150048 }
150049
150050 function is_atom() {
150051 if ( $this->feed_type == ATOM ) {
150052 return $this->feed_version;
150053 }
150054 else {
150055 return false;
150056 }
150057 }
150058
150059 function map_attrs($k, $v) {
150060 return "$k=\"$v\"";
150061 }
150062
150063 function error( $errormsg, $lvl = E_USER_WARNING ) {
150064 // append PHP's error message if track_errors enabled
150065 if ( isset($php_errormsg) ) {
150066 $errormsg .= " ($php_errormsg)";
150067 }
150068 if ( MAGPIE_DEBUG ) {
150069 trigger_error( $errormsg, $lvl);
150070 } else {
150071 error_log( $errormsg, 0);
150072 }
150073 }
150074
150075 }
150076
150077 if ( !function_exists('fetch_rss') ) :
150078 /**
150079 * Build Magpie object based on RSS from URL.
150080 *
150081 * @since unknown
150082 * @package External
150083 * @subpackage MagpieRSS
150084 *
150085 * @param string $url URL to retrieve feed
150086 * @return bool|MagpieRSS false on failure or MagpieRSS object on success.
150087 */
150088 function fetch_rss ($url) {
150089 // initialize constants
150090 init();
150091
150092 if ( !isset($url) ) {
150093 // error("fetch_rss called without a url");
150094 return false;
150095 }
150096
150097 // if cache is disabled
150098 if ( !MAGPIE_CACHE_ON ) {
150099 // fetch file, and parse it
150100 $resp = _fetch_remote_file( $url );
150101 if ( is_success( $resp->status ) ) {
150102 return _response_to_rss( $resp );
150103 }
150104 else {
150105 // error("Failed to fetch $url and cache is off");
150106 return false;
150107 }
150108 }
150109 // else cache is ON
150110 else {
150111 // Flow
150112 // 1. check cache
150113 // 2. if there is a hit, make sure its fresh
150114 // 3. if cached obj fails freshness check, fetch remote
150115 // 4. if remote fails, return stale object, or error
150116
150117 $cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
150118
150119 if (MAGPIE_DEBUG and $cache->ERROR) {
150120 debug($cache->ERROR, E_USER_WARNING);
150121 }
150122
150123
150124 $cache_status = 0; // response of check_cache
150125 $request_headers = array(); // HTTP headers to send with fetch
150126 $rss = 0; // parsed RSS object
150127 $errormsg = 0; // errors, if any
150128
150129 if (!$cache->ERROR) {
150130 // return cache HIT, MISS, or STALE
150131 $cache_status = $cache->check_cache( $url );
150132 }
150133
150134 // if object cached, and cache is fresh, return cached obj
150135 if ( $cache_status == 'HIT' ) {
150136 $rss = $cache->get( $url );
150137 if ( isset($rss) and $rss ) {
150138 $rss->from_cache = 1;
150139 if ( MAGPIE_DEBUG > 1) {
150140 debug("MagpieRSS: Cache HIT", E_USER_NOTICE);
150141 }
150142 return $rss;
150143 }
150144 }
150145
150146 // else attempt a conditional get
150147
150148 // setup headers
150149 if ( $cache_status == 'STALE' ) {
150150 $rss = $cache->get( $url );
150151 if ( isset($rss->etag) and $rss->last_modified ) {
150152 $request_headers['If-None-Match'] = $rss->etag;
150153 $request_headers['If-Last-Modified'] = $rss->last_modified;
150154 }
150155 }
150156
150157 $resp = _fetch_remote_file( $url, $request_headers );
150158
150159 if (isset($resp) and $resp) {
150160 if ($resp->status == '304' ) {
150161 // we have the most current copy
150162 if ( MAGPIE_DEBUG > 1) {
150163 debug("Got 304 for $url");
150164 }
150165 // reset cache on 304 (at minutillo insistent prodding)
150166 $cache->set($url, $rss);
150167 return $rss;
150168 }
150169 elseif ( is_success( $resp->status ) ) {
150170 $rss = _response_to_rss( $resp );
150171 if ( $rss ) {
150172 if (MAGPIE_DEBUG > 1) {
150173 debug("Fetch successful");
150174 }
150175 // add object to cache
150176 $cache->set( $url, $rss );
150177 return $rss;
150178 }
150179 }
150180 else {
150181 $errormsg = "Failed to fetch $url. ";
150182 if ( $resp->error ) {
150183 # compensate for Snoopy's annoying habbit to tacking
150184 # on '\n'
150185 $http_error = substr($resp->error, 0, -2);
150186 $errormsg .= "(HTTP Error: $http_error)";
150187 }
150188 else {
150189 $errormsg .= "(HTTP Response: " . $resp->response_code .')';
150190 }
150191 }
150192 }
150193 else {
150194 $errormsg = "Unable to retrieve RSS file for unknown reasons.";
150195 }
150196
150197 // else fetch failed
150198
150199 // attempt to return cached object
150200 if ($rss) {
150201 if ( MAGPIE_DEBUG ) {
150202 debug("Returning STALE object for $url");
150203 }
150204 return $rss;
150205 }
150206
150207 // else we totally failed
150208 // error( $errormsg );
150209
150210 return false;
150211
150212 } // end if ( !MAGPIE_CACHE_ON ) {
150213 } // end fetch_rss()
150214 endif;
150215
150216 /**
150217 * Retrieve URL headers and content using WP HTTP Request API.
150218 *
150219 * @since unknown
150220 * @package External
150221 * @subpackage MagpieRSS
150222 *
150223 * @param string $url URL to retrieve
150224 * @param array $headers Optional. Headers to send to the URL.
150225 * @return Snoopy style response
150226 */
150227 function _fetch_remote_file ($url, $headers = "" ) {
150228 $resp = wp_remote_request($url, array('headers' => $headers, 'timeout' => MAGPIE_FETCH_TIME_OUT));
150229 if ( is_wp_error($resp) ) {
150230 $error = array_shift($resp->errors);
150231
150232 $resp = new stdClass;
150233 $resp->status = 500;
150234 $resp->response_code = 500;
150235 $resp->error = $error[0] . "\n"; //\n = Snoopy compatibility
150236 return $resp;
150237 }
150238 $response = new stdClass;
150239 $response->status = $resp['response']['code'];
150240 $response->response_code = $resp['response']['code'];
150241 $response->headers = $resp['headers'];
150242 $response->results = $resp['body'];
150243
150244 return $response;
150245 }
150246
150247 /**
150248 * Retrieve
150249 *
150250 * @since unknown
150251 * @package External
150252 * @subpackage MagpieRSS
150253 *
150254 * @param unknown_type $resp
150255 * @return unknown
150256 */
150257 function _response_to_rss ($resp) {
150258 $rss = new MagpieRSS( $resp->results );
150259
150260 // if RSS parsed successfully
150261 if ( $rss && (!isset($rss->ERROR) || !$rss->ERROR) ) {
150262
150263 // find Etag, and Last-Modified
150264 foreach( (array) $resp->headers as $h) {
150265 // 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1"
150266 if (strpos($h, ": ")) {
150267 list($field, $val) = explode(": ", $h, 2);
150268 }
150269 else {
150270 $field = $h;
150271 $val = "";
150272 }
150273
150274 if ( $field == 'ETag' ) {
150275 $rss->etag = $val;
150276 }
150277
150278 if ( $field == 'Last-Modified' ) {
150279 $rss->last_modified = $val;
150280 }
150281 }
150282
150283 return $rss;
150284 } // else construct error message
150285 else {
150286 $errormsg = "Failed to parse RSS file.";
150287
150288 if ($rss) {
150289 $errormsg .= " (" . $rss->ERROR . ")";
150290 }
150291 // error($errormsg);
150292
150293 return false;
150294 } // end if ($rss and !$rss->error)
150295 }
150296
150297 /**
150298 * Setup constants with default values, unless user overrides.
150299 *
150300 * @since unknown
150301 * @package External
150302 * @subpackage MagpieRSS
150303 */
150304 function init () {
150305 if ( defined('MAGPIE_INITALIZED') ) {
150306 return;
150307 }
150308 else {
150309 define('MAGPIE_INITALIZED', 1);
150310 }
150311
150312 if ( !defined('MAGPIE_CACHE_ON') ) {
150313 define('MAGPIE_CACHE_ON', 1);
150314 }
150315
150316 if ( !defined('MAGPIE_CACHE_DIR') ) {
150317 define('MAGPIE_CACHE_DIR', './cache');
150318 }
150319
150320 if ( !defined('MAGPIE_CACHE_AGE') ) {
150321 define('MAGPIE_CACHE_AGE', 60*60); // one hour
150322 }
150323
150324 if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) {
150325 define('MAGPIE_CACHE_FRESH_ONLY', 0);
150326 }
150327
150328 if ( !defined('MAGPIE_DEBUG') ) {
150329 define('MAGPIE_DEBUG', 0);
150330 }
150331
150332 if ( !defined('MAGPIE_USER_AGENT') ) {
150333 $ua = 'WordPress/' . $GLOBALS['wp_version'];
150334
150335 if ( MAGPIE_CACHE_ON ) {
150336 $ua = $ua . ')';
150337 }
150338 else {
150339 $ua = $ua . '; No cache)';
150340 }
150341
150342 define('MAGPIE_USER_AGENT', $ua);
150343 }
150344
150345 if ( !defined('MAGPIE_FETCH_TIME_OUT') ) {
150346 define('MAGPIE_FETCH_TIME_OUT', 2); // 2 second timeout
150347 }
150348
150349 // use gzip encoding to fetch rss files if supported?
150350 if ( !defined('MAGPIE_USE_GZIP') ) {
150351 define('MAGPIE_USE_GZIP', true);
150352 }
150353 }
150354
150355 function is_info ($sc) {
150356 return $sc >= 100 && $sc < 200;
150357 }
150358
150359 function is_success ($sc) {
150360 return $sc >= 200 && $sc < 300;
150361 }
150362
150363 function is_redirect ($sc) {
150364 return $sc >= 300 && $sc < 400;
150365 }
150366
150367 function is_error ($sc) {
150368 return $sc >= 400 && $sc < 600;
150369 }
150370
150371 function is_client_error ($sc) {
150372 return $sc >= 400 && $sc < 500;
150373 }
150374
150375 function is_server_error ($sc) {
150376 return $sc >= 500 && $sc < 600;
150377 }
150378
150379 class RSSCache {
150380 var $BASE_CACHE; // where the cache files are stored
150381 var $MAX_AGE = 43200; // when are files stale, default twelve hours
150382 var $ERROR = ''; // accumulate error messages
150383
150384 function RSSCache ($base='', $age='') {
150385 $this->BASE_CACHE = WP_CONTENT_DIR . '/cache';
150386 if ( $base ) {
150387 $this->BASE_CACHE = $base;
150388 }
150389 if ( $age ) {
150390 $this->MAX_AGE = $age;
150391 }
150392
150393 }
150394
150395 /*=======================================================================*\
150396 Function: set
150397 Purpose: add an item to the cache, keyed on url
150398 Input: url from wich the rss file was fetched
150399 Output: true on sucess
150400 \*=======================================================================*/
150401 function set ($url, $rss) {
150402 global $wpdb;
150403 $cache_option = 'rss_' . $this->file_name( $url );
150404 $cache_timestamp = 'rss_' . $this->file_name( $url ) . '_ts';
150405
150406 // shouldn't these be using get_option() ?
150407 if ( !$wpdb->get_var( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name = %s", $cache_option ) ) )
150408 add_option($cache_option, '', '', 'no');
150409 if ( !$wpdb->get_var( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name = %s", $cache_timestamp ) ) )
150410 add_option($cache_timestamp, '', '', 'no');
150411
150412 update_option($cache_option, $rss);
150413 update_option($cache_timestamp, time() );
150414
150415 return $cache_option;
150416 }
150417
150418 /*=======================================================================*\
150419 Function: get
150420 Purpose: fetch an item from the cache
150421 Input: url from wich the rss file was fetched
150422 Output: cached object on HIT, false on MISS
150423 \*=======================================================================*/
150424 function get ($url) {
150425 $this->ERROR = "";
150426 $cache_option = 'rss_' . $this->file_name( $url );
150427
150428 if ( ! get_option( $cache_option ) ) {
150429 $this->debug(
150430 "Cache doesn't contain: $url (cache option: $cache_option)"
150431 );
150432 return 0;
150433 }
150434
150435 $rss = get_option( $cache_option );
150436
150437 return $rss;
150438 }
150439
150440 /*=======================================================================*\
150441 Function: check_cache
150442 Purpose: check a url for membership in the cache
150443 and whether the object is older then MAX_AGE (ie. STALE)
150444 Input: url from wich the rss file was fetched
150445 Output: cached object on HIT, false on MISS
150446 \*=======================================================================*/
150447 function check_cache ( $url ) {
150448 $this->ERROR = "";
150449 $cache_option = $this->file_name( $url );
150450 $cache_timestamp = 'rss_' . $this->file_name( $url ) . '_ts';
150451
150452 if ( $mtime = get_option($cache_timestamp) ) {
150453 // find how long ago the file was added to the cache
150454 // and whether that is longer then MAX_AGE
150455 $age = time() - $mtime;
150456 if ( $this->MAX_AGE > $age ) {
150457 // object exists and is current
150458 return 'HIT';
150459 }
150460 else {
150461 // object exists but is old
150462 return 'STALE';
150463 }
150464 }
150465 else {
150466 // object does not exist
150467 return 'MISS';
150468 }
150469 }
150470
150471 /*=======================================================================*\
150472 Function: serialize
150473 \*=======================================================================*/
150474 function serialize ( $rss ) {
150475 return serialize( $rss );
150476 }
150477
150478 /*=======================================================================*\
150479 Function: unserialize
150480 \*=======================================================================*/
150481 function unserialize ( $data ) {
150482 return unserialize( $data );
150483 }
150484
150485 /*=======================================================================*\
150486 Function: file_name
150487 Purpose: map url to location in cache
150488 Input: url from wich the rss file was fetched
150489 Output: a file name
150490 \*=======================================================================*/
150491 function file_name ($url) {
150492 return md5( $url );
150493 }
150494
150495 /*=======================================================================*\
150496 Function: error
150497 Purpose: register error
150498 \*=======================================================================*/
150499 function error ($errormsg, $lvl=E_USER_WARNING) {
150500 // append PHP's error message if track_errors enabled
150501 if ( isset($php_errormsg) ) {
150502 $errormsg .= " ($php_errormsg)";
150503 }
150504 $this->ERROR = $errormsg;
150505 if ( MAGPIE_DEBUG ) {
150506 trigger_error( $errormsg, $lvl);
150507 }
150508 else {
150509 error_log( $errormsg, 0);
150510 }
150511 }
150512 function debug ($debugmsg, $lvl=E_USER_NOTICE) {
150513 if ( MAGPIE_DEBUG ) {
150514 $this->error("MagpieRSS [debug] $debugmsg", $lvl);
150515 }
150516 }
150517 }
150518
150519 if ( !function_exists('parse_w3cdtf') ) :
150520 function parse_w3cdtf ( $date_str ) {
150521
150522 # regex to match wc3dtf
150523 $pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/";
150524
150525 if ( preg_match( $pat, $date_str, $match ) ) {
150526 list( $year, $month, $day, $hours, $minutes, $seconds) =
150527 array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[7]);
150528
150529 # calc epoch for current date assuming GMT
150530 $epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year);
150531
150532 $offset = 0;
150533 if ( $match[11] == 'Z' ) {
150534 # zulu time, aka GMT
150535 }
150536 else {
150537 list( $tz_mod, $tz_hour, $tz_min ) =
150538 array( $match[8], $match[9], $match[10]);
150539
150540 # zero out the variables
150541 if ( ! $tz_hour ) { $tz_hour = 0; }
150542 if ( ! $tz_min ) { $tz_min = 0; }
150543
150544 $offset_secs = (($tz_hour*60)+$tz_min)*60;
150545
150546 # is timezone ahead of GMT? then subtract offset
150547 #
150548 if ( $tz_mod == '+' ) {
150549 $offset_secs = $offset_secs * -1;
150550 }
150551
150552 $offset = $offset_secs;
150553 }
150554 $epoch = $epoch + $offset;
150555 return $epoch;
150556 }
150557 else {
150558 return -1;
150559 }
150560 }
150561 endif;
150562
150563 if ( !function_exists('wp_rss') ) :
150564 /**
150565 * Display all RSS items in a HTML ordered list.
150566 *
150567 * @since unknown
150568 * @package External
150569 * @subpackage MagpieRSS
150570 *
150571 * @param string $url URL of feed to display. Will not auto sense feed URL.
150572 * @param int $num_items Optional. Number of items to display, default is all.
150573 */
150574 function wp_rss( $url, $num_items = -1 ) {
150575 if ( $rss = fetch_rss( $url ) ) {
150576 echo '<ul>';
150577
150578 if ( $num_items !== -1 ) {
150579 $rss->items = array_slice( $rss->items, 0, $num_items );
150580 }
150581
150582 foreach ( (array) $rss->items as $item ) {
150583 printf(
150584 '<li><a href="%1$s" title="%2$s">%3$s</a></li>',
150585 clean_url( $item['link'] ),
150586 attribute_escape( strip_tags( $item['description'] ) ),
150587 htmlentities( $item['title'] )
150588 );
150589 }
150590
150591 echo '</ul>';
150592 } else {
150593 _e( 'An error has occurred, which probably means the feed is down. Try again later.' );
150594 }
150595 }
150596 endif;
150597
150598 if ( !function_exists('get_rss') ) :
150599 /**
150600 * Display RSS items in HTML list items.
150601 *
150602 * You have to specify which HTML list you want, either ordered or unordered
150603 * before using the function. You also have to specify how many items you wish
150604 * to display. You can't display all of them like you can with wp_rss()
150605 * function.
150606 *
150607 * @since unknown
150608 * @package External
150609 * @subpackage MagpieRSS
150610 *
150611 * @param string $url URL of feed to display. Will not auto sense feed URL.
150612 * @param int $num_items Optional. Number of items to display, default is all.
150613 * @return bool False on failure.
150614 */
150615 function get_rss ($url, $num_items = 5) { // Like get posts, but for RSS
150616 $rss = fetch_rss($url);
150617 if ( $rss ) {
150618 $rss->items = array_slice($rss->items, 0, $num_items);
150619 foreach ( (array) $rss->items as $item ) {
150620 echo "<li>\n";
150621 echo "<a href='$item[link]' title='$item[description]'>";
150622 echo htmlentities($item['title']);
150623 echo "</a><br />\n";
150624 echo "</li>\n";
150625 }
150626 } else {
150627 return false;
150628 }
150629 }
150630 endif;
150631
150632 ?>