" . 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 = ''; // 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 .= ''; $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 . ''; // Add remaining tags to close } // WP fix for the bug with HTML comments $newtext = str_replace("< !--","