" . mysql_error());
mysql_select_db(FOF_DB_DBNAME, $fof_connection) or die("Cannot select database. Check your configuration. Mysql says: " . mysql_error());
if(!$installing) is_writable( FOF_CACHE_DIR ) or die("Cache directory is not writable or does not exist. Have you run install.php?");
$FEED_TABLE = FEED_TABLE;
$ITEM_TABLE = ITEM_TABLE;
$fof_rss_cache = new RSSCache( MAGPIE_CACHE_DIR );
function fof_get_feeds($order = 'link_name', $direction = 'asc')
{
global $FEED_TABLE, $ITEM_TABLE;
$result = fof_do_query("select link_id, link_url, link_name, link_rss, link_description from $FEED_TABLE order by link_name");
$i = 0;
while($row = mysql_fetch_array($result))
{
$id = $row['link_id'];
$age = fof_rss_age($row['link_updated']);
$feeds[$i]['id'] = $id;
$feeds[$i]['url'] = $row['link_url'];
$feeds[$i]['title'] = $row['link_name'];
$feeds[$i]['link'] = $row['link_rss'];
$feeds[$i]['description'] = $row['link_description'];
$feeds[$i]['age'] = $age;
if($age == FOF_MAX_INT)
{
$agestr = "never";
$agestrabbr = "∞";
}
else
{
$seconds = $age % 60;
$minutes = $age / 60 % 60;
$hours = $age / 60 / 60 % 24;
$days = floor($age / 60 / 60 / 24);
if($seconds)
{
$agestr = "$seconds second";
if($seconds != 1) $agestr .= "s";
$agestr .= " ago";
$agestrabbr = $seconds . "s";
}
if($minutes)
{
$agestr = "$minutes minute";
if($minutes != 1) $agestr .= "s";
$agestr .= " ago";
$agestrabbr = $minutes . "m";
}
if($hours)
{
$agestr = "$hours hour";
if($hours != 1) $agestr .= "s";
$agestr .= " ago";
$agestrabbr = $hours . "h";
}
if($days)
{
$agestr = "$days day";
if($days != 1) $agestr .= "s";
$agestr .= " ago";
$agestrabbr = $days . "d";
}
}
$feeds[$i]['agestr'] = $agestr;
$feeds[$i]['agestrabbr'] = $agestrabbr;
$i++;
}
$result = fof_do_query("select count( ID ) as count, ID as id from $FEED_TABLE, $ITEM_TABLE where $FEED_TABLE.link_id = $ITEM_TABLE.ID group by link_id order by $FEED_TABLE.link_name");
while($row = mysql_fetch_array($result))
{
for($i=0; $i[« $yesterday] ";
if($when != "today") $string .= "[today] ";
if($when != "today") $string .= "[$tomorrow »] ";
}
if(is_numeric($start))
{
if(!is_numeric($limit)) $limit = FOF_HOWMANY;
$earlier = $start + $limit;
$later = $start - $limit;
$string .= "[« previous $limit] ";
if($later >= 0) $string .= "[current items] ";
if($later >= 0) $string .= "[next $limit »] ";
}
return $string;
}
function fof_do_query($sql, $live=0)
{
global $fof_connection, $fof_query_log;
if (defined('FOF_QUERY_LOG') && FOF_QUERY_LOG)
{
list($usec, $sec) = explode(" ", microtime());
$t1 = (float)$sec + (float)$usec;
}
$result = mysql_query($sql, $fof_connection);
if (defined('FOF_QUERY_LOG') && FOF_QUERY_LOG)
{
list($usec, $sec) = explode(" ", microtime());
$t2 = (float)$sec + (float)$usec;
$elapsed = $t2 - $t1;
$fof_query_log .= "[$sql]: $elapsed\n";
}
if($live)
{
return $result;
}
else
{
if(mysql_errno()) die("Cannot query database. Have you run install.php? MySQL says: ". mysql_error() . "");
return $result;
}
}
function fof_rss_age($url)
{
global $fof_rss_cache;
$filename = $fof_rss_cache->file_name( $url . MAGPIE_OUTPUT_ENCODING );
if ( file_exists( $filename ) )
{
// find how long ago the file was added to the cache
// and whether that is longer then MAX_AGE
$mtime = filemtime( $filename );
$age = time() - $mtime;
return $age;
}
else
{
return FOF_MAX_INT;
}
}
function fof_getRSSLocation($html, $location){
if(!$html or !$location){
return false;
}else{
#search through the HTML, save all tags
# and store each link's attributes in an associative array
preg_match_all('//si', $html, $matches);
$links = $matches[1];
$final_links = array();
$link_count = count($links);
for($n=0; $n<$link_count; $n++){
$attributes = preg_split('/\s+/s', $links[$n]);
foreach($attributes as $attribute){
$att = preg_split('/\s*=\s*/s', $attribute, 2);
if(isset($att[1])){
$att[1] = preg_replace('/([\'"]?)(.*)\1/', '$2', $att[1]);
$final_link[strtolower($att[0])] = $att[1];
}
}
$final_links[$n] = $final_link;
}
#now figure out which one points to the RSS file
for($n=0; $n<$link_count; $n++){
if(strtolower($final_links[$n]['rel']) == 'alternate'){
if(strtolower($final_links[$n]['type']) == 'application/rss+xml'){
$href = $final_links[$n]['href'];
}
if(!$href and strtolower($final_links[$n]['type']) == 'text/xml'){
#kludge to make the first version of this still work
$href = $final_links[$n]['href'];
}
if($href){
if(strstr($href, "http://") !== false){ #if it's absolute
$full_url = $href;
}else{ #otherwise, 'absolutize' it
$url_parts = parse_url($location);
#only made it work for http:// links. Any problem with this?
$full_url = "http://$url_parts[host]";
if(isset($url_parts['port'])){
$full_url .= ":$url_parts[port]";
}
if($href{0} != '/'){ #it's a relative link on the domain
$full_url .= dirname($url_parts['path']);
if(substr($full_url, -1) != '/'){
#if the last character isn't a '/', add it
$full_url .= '/';
}
}
$full_url .= $href;
}
return $full_url;
}
}
}
return false;
}
}
function fof_render_feed_link($row)
{
$link = htmlspecialchars($row['link']);
$description = htmlspecialchars($row['description']);
$title = htmlspecialchars($row['title']);
$url = htmlspecialchars($row['url']);
$s = "$title ";
$s .= "(rss)";
return $s;
}
function fof_opml_to_array($opml)
{
$rx = "/xmlurl=\"(.*?)\"/mi";
if (preg_match_all($rx, $opml, $m))
{
for($i = 0; $i < count($m[0]) ; $i++)
{
$r[] = $m[1][$i];
}
}
return $r;
}
function fof_add_feed($url)
{
if(!$url) return;
$url = trim($url);
if(substr($url, 0, 7) != 'http://' && substr($url, 0, 8) != 'https://')
{
$url = 'http://' . $url;
}
print "Attempting to subscribe to $url...
";
if($row = fof_is_subscribed($url))
{
print "You are already subscribed to " . fof_render_feed_link($row) . "
";
return true;
}
$rss = fetch_rss( $url );
if(!$rss->channel && !$rss->items)
{
echo " URL is not RSS or is invalid.
";
if(!$rss) echo " (error was: " . magpie_error() . ")
";
echo " The validator may give more information.
";
echo "
Attempting autodiscovery...
";
$r = _fetch_remote_file ($url);
$c = $r->results;
if($c && $r->status >= 200 && $r->status < 300)
{
$l = fof_getRSSLocation($c, $url);
if($l)
{
echo "Autodiscovery found $l.
";
echo "Attempting to subscribe to $l...
";
if($row = fof_is_subscribed($l))
{
print "
You are already subscribed to " . fof_render_feed_link($row) . "
";
return true;
}
$rss = fetch_rss( $l );
if(!$rss->channel && !$rss->items)
{
echo " URL is not RSS, giving up.
";
echo " (error was: " . magpie_error() . ")
";
echo " The validator may give more information.
";
}
else
{
fof_actually_add_feed($l, $rss);
echo " Subscribed.
";
}
}
else
{
echo "Autodiscovery failed. Giving up.
";
}
}
else
{
echo "Can't load URL. Giving up.
";
}
}
else
{
fof_actually_add_feed($url, $rss);
echo "Subscribed.
";
}
}
function fof_actually_add_feed($url, $rss)
{
global $FEED_TABLE, $ITEM_TABLE;
$title = mysql_escape_string($rss->channel['title']);
$link = mysql_escape_string($rss->channel['link']);
$description = mysql_escape_string($rss->channel['description']);
$pubdate = mysql_escape_string($rss->channel['pubDate']);
$sql = "insert into $FEED_TABLE (link_url,link_name,link_rss,link_description,link_updated) values ('$link','$title','$url','$description','$pubdate')";
fof_do_query($sql);
fof_update_feed($url, 0);
}
function fof_is_subscribed($url)
{
global $FEED_TABLE, $ITEM_TABLE;
$safe_url = mysql_escape_string($url);
$result = fof_do_query("select link_url, link_name, link_rss, link_id from $FEED_TABLE where link_url = '$safe_url'");
if(mysql_num_rows($result) == 0)
{
return false;
}
else
{
$row = mysql_fetch_array($result);
return $row;
}
}
function fof_feed_row($id)
{
global $FEED_TABLE, $ITEM_TABLE;
$result = fof_do_query("select link_url, link_name, link_rss, link_id from $FEED_TABLE where id = '$id'");
if(mysql_num_rows($result) == 0)
{
return false;
}
else
{
$row = mysql_fetch_array($result);
return $row;
}
}
function fof_update_feed($url)
{
global $FEED_TABLE, $ITEM_TABLE;
if(!$url) return 0;
$rss = fetch_rss( $url );
if(!$rss)
{
print "Error: " . magpie_error() . " ";
print "try to validate it? ";
return 0;
}
$title = mysql_escape_string($rss->channel['title']);
$link = $rss->channel['link'];
$description = mysql_escape_string($rss->channel['description']);
$safeurl = mysql_escape_string( $url );
$result = fof_do_query("select link_id, link_url from $FEED_TABLE where link_url='$safeurl'");
$row = mysql_fetch_array($result);
$feed_id = $row['ID'];
$items = $rss->items;
foreach ($items as $item)
{
$link = mysql_escape_string($item['link']);
$title = mysql_escape_string($item['title']);
$content = mysql_escape_string($item['description']);
if($item['content']['encoded'])
{
$content = mysql_escape_string($item['content']['encoded']);
}
if($item['atom_content'])
{
$content = mysql_escape_string($item['atom_content']);
}
$dcdate = mysql_escape_string($item['dc']['date']);
$dccreator = mysql_escape_string($item['dc']['creator']);
$dcsubject = mysql_escape_string($item['dc']['subject']);
if(!$link)
{
$link = $item['guid'];
}
if(!$title)
{
$title = "[no title]";
}
$result = fof_do_query("select id from $ITEM_TABLE where ID='$feed_id' and guid='$link'");
$row = mysql_fetch_array($result);
$id = $row['id'];
if(mysql_num_rows($result) == 0)
{
$n++;
$sql = "insert into $ITEM_TABLE (ID,guid,post_title,post_content,post_date,post_author,post_name) values ('$feed_id','$link','$title','$content','$dcdate','$dccreator','$dcsubject')";
$result = fof_do_query($sql);
}
else
{
$ids[] = $id;
}
}
if(defined('FOF_KEEP_DAYS'))
{
$keep_days = FOF_KEEP_DAYS;
if(count($ids) != 0)
{
$first = 1;
foreach ($ids as $id)
{
if($first)
{
$stat = "($id";
$first = 0;
}
else
{
$stat .= ", $id";
}
}
$stat .= ")";
$sql = "delete from $ITEM_TABLE where ID = $feed_id and `read`=1 and id not in $stat and to_days( CURDATE( ) ) - to_days( timestamp ) > $keep_days";
fof_do_query($sql);
}
}
return $n;
}
/*
balanceTags
Balances Tags of string using a modified stack.
@param text Text to be balanced
@return Returns balanced text
@author Leonard Lin (leonard@acm.org)
@version v1.1
@date November 4, 2001
@license GPL v2.0
@notes
@changelog
1.2 ***TODO*** Make better - change loop condition to $text
1.1 Fixed handling of append/stack pop order of end text
Added Cleaning Hooks
1.0 First Version
*/
function fof_balanceTags($text) {
$tagstack = array(); $stacksize = 0; $tagqueue = ''; $newtext = '';
# WP bug fix for comments - in case you REALLY meant to type '< !--'
$text = str_replace('< !--', '< !--', $text);
# WP bug fix for LOVE <3 (and other situations with '<' before a number)
$text = preg_replace('#<([0-9]{1})#', '<$1', $text);
while (preg_match("/<(\/?\w*)\s*([^>]*)>/",$text,$regex)) {
$newtext = $newtext . $tagqueue;
$i = strpos($text,$regex[0]);
$l = strlen($tagqueue) + strlen($regex[0]);
// clear the shifter
$tagqueue = '';
// Pop or Push
if ($regex[1][0] == "/") { // End Tag
$tag = strtolower(substr($regex[1],1));
// if too many closing tags
if($stacksize <= 0) {
$tag = '';
//or close to be safe $tag = '/' . $tag;
}
// if stacktop value = tag close value then pop
else if ($tagstack[$stacksize - 1] == $tag) { // found closing tag
$tag = '' . $tag . '>'; // Close Tag
// Pop
array_pop ($tagstack);
$stacksize--;
} else { // closing tag not at top, search for it
for ($j=$stacksize-1;$j>=0;$j--) {
if ($tagstack[$j] == $tag) {
// add tag to tagqueue
for ($k=$stacksize-1;$k>=$j;$k--){
$tagqueue .= '' . array_pop ($tagstack) . '>';
$stacksize--;
}
break;
}
}
$tag = '';
}
} else { // Begin Tag
$tag = strtolower($regex[1]);
// Tag Cleaning
// Push if not img or br or hr
if($tag != 'br' && $tag != 'img' && $tag != 'hr') {
$stacksize = array_push ($tagstack, $tag);
}
// Attributes
// $attributes = $regex[2];
$attributes = $regex[2];
if($attributes) {
$attributes = ' '.$attributes;
}
$tag = '<'.$tag.$attributes.'>';
}
$newtext .= substr($text,0,$i) . $tag;
$text = substr($text,$i+$l);
}
// Clear Tag Queue
$newtext = $newtext . $tagqueue;
// Add Remaining text
$newtext .= $text;
// Empty Stack
while($x = array_pop($tagstack)) {
$newtext = $newtext . '' . $x . '>'; // Add remaining tags to close
}
// WP fix for the bug with HTML comments
$newtext = str_replace("< !--","