'http://feeds.feedburner.com/tekArtist', 'Slashdot' => 'http://rss.slashdot.org/Slashdot/slashdot', 'Digg' => 'http://www.digg.com/rss/index.xml', 'Google News' => 'http://news.google.com/?output=rss'); // Define a default number of item per page // Start with a small number as a default view, because many // small devices have drastic memory requirements that lead // to easily lead to http errors (413: Request entity too large). // Options: 1, 5, 10, 15, 20, 25 $defaultLimit = 5; // Define how many character we want to see from each entry // description, to provide only an excerpt when the feed // publishes very long content. $descLimit = 1024; ### END USER CONFIGURABLE OPTIONS ############################################# $defaultOffset = 0; // start the xhtml interface print '<'.'?xml version="1.0"?'.">\n"; print "\n"; print "\n"; print "\n"; // Define a default xml source key $sourceKeys = array_keys($xmlSourceList); $defaultSource = $sourceKeys[0]; // Get and clean user input $sourceChoice = rawurldecode($_GET['src']); $limit = intval($_GET['lmt']); $offset = intval($_GET['ofst']); // If no valid source key choice, then use default if($sourceChoice == ''){ $sourceChoice = $defaultSource; } elseif(!isset($xmlSourceList[$sourceChoice])){ $sourceChoice = $defaultSource; } // Get the url of the chosen source $xmlSource = $xmlSourceList[$sourceChoice]; // Cleanup the source key for display in the header $cleanSourceChoice = htmlspecialchars($sourceChoice); // Set page title and header $title .= $appName.' » '.$cleanSourceChoice; // Cleanup the selected page offset and item limit if( ($limit < 1) or ($limit > 25) ) $limit = $defaultLimit; if( ($offset < 1) or ($offset > 100) ) $offset = $defaultOffset; // Print head block w/ defined and clean info print "
\n"; print "Sorry, but the cache directory cannot be found.
\n"; print "Please create a writable directory at {$cacheDir}.
\n"; } elseif(!is_dir($cacheDir)){ print "Sorry, but the cache location is not a directory.
\n"; print "Please create a writable directory at {$cacheDir}.
\n"; } elseif(!is_writable($cacheDir)){ print "Sorry, but the cache directory is not writable.
\n"; print "Please make the directory writable: {$cacheDir}.
\n"; } else{ // Define the name and location of the local xml cache file $cacheFileName = str_replace('%','_',rawurlencode($xmlSource)).'.cache.xml'; $cacheDestination = "./cache/{$cacheFileName}"; // Set the cache creation/modification time $cacheMtime = time(); // Define if we should get new content from the source, // or use the local cache instead if(!file_exists($cacheDestination)){ file_put_contents($cacheDestination, file_get_contents($xmlSource)); } elseif(filemtime($cacheDestination) < strtotime($cacheTTL.' ago')){ file_put_contents($cacheDestination, file_get_contents($xmlSource)); } else{ $cacheMtime = filemtime($cacheDestination); } // Load and test xml content from RSS or Atom feed if(($xml = simplexml_load_file($cacheDestination)) === false){ print "Sorry, but \"{$cleanSourceChoice}\" cannot be parsed at this time.
\n"; } else{ // Use the ParseFeed function (see below) to parse // whichever xml format we got into a clean, standard // structure, taking in consideration the current // paging preferences (offset, limit) $displayData = ParseFeed($xml); // Print the file body header print "| \n"; $link = $_SERVER['REQUEST_URI']; if(strstr($link, 'ofst=') === false) $link .= '?'; // "Previous" link if($offset > 0){ if(strstr($link, 'ofst=')) $link = preg_replace('/(\&ofst=\d{1,2})/','',$link); $link .= '&ofst='.($offset - $limit); print " « previous\n"; } // "Next" link if($displayData['entryCount'] > ($limit + $offset)){ if($offset > 0) print " | \n"; if(strstr($link, 'ofst=')) $link = preg_replace('/(\&ofst=\d{1,2})/','',$link); $link .= '&ofst='.($limit + $offset); print " next »\n"; } print " |
\n"; } // Print the cache specs print " \n"; } // Now let's display the preference form // List the available sources print " \n"; } // Close the xhtml file print " \n"; print "\n"; // And we're done with the processing! exit; // Now let's move on to the parsing functions /** * ParseFeed is a simple decisional wrapper. It simply * defines type of feed we are dealing with (RSS or Atom) * and calls the approriate xml parser. * * @param object $xml SimpleXML object (http://php.net/simplexml) * @return array $displayData Associative array to be used for display * * $displayData => feedTitle * ............ => feedLink * ............ => feedEntries => idx => link * .................................. => title * .................................. => description * ............ => entryCount */ function ParseFeed(&$xml){ $displayData = array(); if(isset($xml->channel)){ ParseRSS($xml, $displayData); } elseif(isset($xml->entry)){ ParseAtom($xml, $displayData); } return $displayData; } /** * ParseRSS, as the name implies, will parse an RSS * feed into the standard array we expect for display. * See http://en.wikipedia.org/wiki/RSS_%28file_format%29 * * @param object $xml RSS, SimpleXML object (http://php.net/simplexml) * @param array $displayData Empty array, see ParseFeed * @global int $limit Only list x items per page * @global int $offset Start listing from item number x * @global int $descLimit show only x characters from the descrition * @return array $displayData Associative array to be used for display */ function ParseRSS(&$xml, &$displayData){ global $limit, $offset, $descLimit; // Get the feed basic info $displayData['feedTitle'] = $xml->channel->title; $displayData['feedLink'] = $xml->channel->link; $displayData['feedEntries'] = array(); $displayData['entryCount'] = 0; // Test for the doc entries structure, depending on // the RSS version (items in/outside of channel) if(isset($xml->item)){ $feedEntries = $xml->item; } elseif(isset($xml->channel->item)){ $feedEntries = $xml->channel->item; } else{ $feedEntries = false; } // Loop on the found entries, based on paging prefs if(is_object($feedEntries)){ $displayData['entryCount'] = count($feedEntries); $i=0; foreach($feedEntries as $entry){ if($i >= $offset){ $displayData['feedEntries'][$i] = array(); $displayData['feedEntries'][$i]['link'] = $entry->link; $displayData['feedEntries'][$i]['title'] = $entry->title; $displayData['feedEntries'][$i]['description'] = substr(strip_tags(str_replace("\n",' ', $entry->description)),0,$descLimit); if(strlen($entry->description) >= $descLimit) $displayData['feedEntries'][$i]['description'] .= '...'; } $i++; if($i >= ($limit + $offset)) break; } } return $displayData; } /** * ParseAtom, as the name implies, will parse an Atom * feed into the standard array we expect for display. * See http://en.wikipedia.org/wiki/Atom_%28standard%29 * * @param object $xml Atom, SimpleXML object (http://php.net/simplexml) * @param array $displayData Empty array, see ParseFeed * @global int $limit Only list x items per page * @global int $offset Start listing from item number x * @global int $descLimit show only x characters from the descrition * @return array $displayData Associative array to be used for display */ function ParseAtom(&$xml, &$displayData){ global $limit, $offset, $descLimit; // Get the feed basic info $displayData['feedTitle'] = $xml->title; $feedLinkAttributes = $xml->link->attributes(); $displayData['feedLink'] = $feedLinkAttributes['href']; $displayData['feedEntries'] = array(); $displayData['entryCount'] = 0; // Test for the doc entries structure if(isset($xml->entry)){ $feedEntries = $xml->entry; } else{ $feedEntries = false; } // Loop on the found entries, based on paging prefs if(is_object($feedEntries)){ $displayData['entryCount'] = count($feedEntries); $i=0; foreach($feedEntries as $entry){ if($i >= $offset){ $displayData['feedEntries'][$i] = array(); $entryAttributes = $entry->link->attributes(); $displayData['feedEntries'][$i]['link'] = $entryAttributes['href']; $displayData['feedEntries'][$i]['title'] = $entry->title; $displayData['feedEntries'][$i]['description'] = substr(strip_tags(str_replace("\n",' ', $entry->content)),0,$descLimit); if(strlen($displayData['feedEntries'][$i]['description']) >= $descLimit) $displayData['feedEntries'][$i]['description'] .= strlen($entry->content).'...'; } $i++; if($i >= ($limit + $offset)) break; } } return $displayData; } // Fin ?>