initial FoF 0.5

master
vitalif 2009-08-03 12:42:04 +00:00
parent 4c5bbb6da1
commit 44558d2303
56 changed files with 21369 additions and 0 deletions

340
LICENSE Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

21
add-single.php Normal file
View File

@ -0,0 +1,21 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* add-single.php - adds a single feed
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
$url = $_REQUEST['url'];
$unread = $_REQUEST['unread'];
print(fof_subscribe(fof_current_user(), $url, $unread));
?>

32
add-tag.php Normal file
View File

@ -0,0 +1,32 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* add-tag.php - adds (or removes) a tag to an item
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
$tags = $_GET['tag'];
$item = $_GET['item'];
$remove = $_GET['remove'];
foreach(explode(" ", $tags) as $tag)
{
if($remove == 'true')
{
fof_untag_item(fof_current_user(), $item, $tag);
}
else
{
fof_tag_item(fof_current_user(), $item, $tag);
}
}
?>

103
add.php Normal file
View File

@ -0,0 +1,103 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* add.php - displays form to add a feed
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include("header.php");
$url = $_POST['rss_url'];
if(!$url) $url = $_GET['rss_url'];
$opml = $_POST['opml_url'];
$file = $_POST['opml_file'];
$unread = $_POST['unread'];
$feeds = array();
if($url) $feeds[] = $url;
if($opml)
{
$sfile = new SimplePie_File($opml);
if(!$sfile->success)
{
echo "Cannot open $opml<br>";
return false;
}
$content = $sfile->body;
$feeds = fof_opml_to_array($content);
}
if($_FILES['opml_file']['tmp_name'])
{
if(!$content_array = file($_FILES['opml_file']['tmp_name']))
{
echo "Cannot open uploaded file<br>";
}
else
{
$content = implode("", $content_array);
$feeds = fof_opml_to_array($content);
}
}
$add_feed_url = "http";
if($_SERVER["HTTPS"] == "on")
{
$add_feed_url = "https";
}
$add_feed_url .= "://" . $_SERVER["HTTP_HOST"] . $_SERVER["SCRIPT_NAME"];
?>
<div style="background: #eee; border: 1px solid black; padding: 1.5em; margin: 1.5em;">If your browser is cool, you can <a href='javascript:window.navigator.registerContentHandler("application/vnd.mozilla.maybe.feed", "<?php echo $add_feed_url ?>?rss_url=%s", "Feed on Feeds")'>register Feed on Feeds as a Feed Reader</a>. If it is not cool, you can still use the <a href="javascript:void(location.href='<?php echo $add_feed_url ?>?rss_url='+escape(location))">FoF subscribe</a> bookmarklet to subscribe to any page with a feed. Just add it as a bookmark and then click on it when you are at a page you'd like to subscribe to!</div>
<form method="post" action="opml.php">
<input type="submit" value="Export subscriptions as OPML">
</form>
<br>
<form method="post" name="addform" action="add.php" enctype="multipart/form-data">
When adding feeds, mark <select name="unread"><option value=today <?php if($unread == "today") echo "selected" ?> >today's</option><option value=all <?php if($unread == "all") echo "selected" ?> >all</option><option value=no <?php if($unread == "no") echo "selected" ?> >no</option></select> items as unread<br><br>
RSS or weblog URL: <input type="text" name="rss_url" size="40" value="<?php echo $url ?>"><input type="Submit" value="Add a feed"><br><br>
OPML URL: <input type="hidden" name="MAX_FILE_SIZE" value="100000">
<input type="text" name="opml_url" size="40" value="<?php echo $opml ?>"><input type="Submit" value="Add feeds from OPML file on the Internet"><br><br>
<input type="hidden" name="MAX_FILE_SIZE" value="100000">
OPML filename: <input type="file" name="opml_file" size="40" value="<?php echo $file ?>"><input type="Submit" value="Upload an OPML file">
</form>
<?php
if(count($feeds))
{
print("<script>\nwindow.onload = ajaxadd;\nfeedslist = [");
foreach($feeds as $feed)
{
$feedjson[] = "{'url': '" . addslashes($feed) . "'}";
}
print(join($feedjson, ", "));
print("];\n</script>");
}
print("<br>");
include("footer.php");
?>

109
classes/fof-prefs.php Normal file
View File

@ -0,0 +1,109 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* fof-prefs.php - Preferences class
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
class FoF_Prefs
{
var $user_id;
var $prefs;
var $admin_prefs;
function FoF_Prefs($user_id)
{
global $FOF_USER_TABLE;
$this->user_id = $user_id;
$result = fof_safe_query("select user_prefs from $FOF_USER_TABLE where user_id = %d", $user_id);
$row = mysql_fetch_array($result);
$prefs = unserialize($row['user_prefs']);
if(!is_array($prefs)) $prefs = array();
$this->prefs = $prefs;
if($user_id != 1)
{
$result = fof_safe_query("select user_prefs from $FOF_USER_TABLE where user_id = 1");
$row = mysql_fetch_array($result);
$admin_prefs = unserialize($row['user_prefs']);
if(!is_array($admin_prefs)) $admin_prefs = array();
$this->admin_prefs = $admin_prefs;
}
else
{
$this->admin_prefs = $prefs;
}
$this->populate_defaults();
if($user_id == 1)
{
$this->prefs = array_merge($this->prefs, $this->admin_prefs);
}
}
function &instance()
{
static $instance;
if(!isset($instance)) $instance = new FoF_Prefs(fof_current_user());
return $instance;
}
function populate_defaults()
{
$defaults = array(
"favicons" => true,
"keyboard" => false,
"direction" => "desc",
"howmany" => 50,
"sharing" => "no",
"feed_order" => "feed_title",
"feed_direction" => "asc",
);
$admin_defaults = array(
"purge" => 30,
"autotimeout" => 30,
"manualtimeout" => 15,
"logging" => false,
);
$this->stuff_array($this->prefs, $defaults);
$this->stuff_array($this->admin_prefs, $admin_defaults);
}
function stuff_array(&$array, $defaults)
{
foreach($defaults as $k => $v)
{
if(!isset($array[$k])) $array[$k] = $v;
}
}
function get($k)
{
return $this->prefs[$k];
}
function set($k, $v)
{
$this->prefs[$k] = $v;
}
function save()
{
fof_db_save_prefs($this->user_id, $this->prefs);
}
}
?>

26
delete.php Normal file
View File

@ -0,0 +1,26 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* delete.php - deletes a feed and all items
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
$feed = $_GET['feed'];
fof_delete_subscription(fof_current_user(), $feed);
include("header.php");
?>
Deleted.
<?php include("footer.php") ?>

24
favicon.php Normal file
View File

@ -0,0 +1,24 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* favicon.php - displays an image cached by SimplePie
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
require_once('simplepie/simplepie.inc');
if(file_exists("./cache/" . md5($_GET[i]) . ".spi"))
{
SimplePie_Misc::display_cached_file($_GET['i'], './cache', 'spi');
}
else
{
header("Location: image/feed-icon.png");
}
?>

48
fof-config-sample.php Normal file
View File

@ -0,0 +1,48 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* config.php - modify this file with your database settings
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
// Database connection information. Host, username, password, database name.
define('FOF_DB_HOST', "host.example.com");
define('FOF_DB_USER', "username");
define('FOF_DB_PASS', "password");
define('FOF_DB_DBNAME', "database");
// The rest you should not need to change
// DB table names
define('FOF_DB_PREFIX', "fof_");
define('FOF_FEED_TABLE', FOF_DB_PREFIX . "feed");
define('FOF_ITEM_TABLE', FOF_DB_PREFIX . "item");
define('FOF_ITEM_TAG_TABLE', FOF_DB_PREFIX . "item_tag");
define('FOF_SUBSCRIPTION_TABLE', FOF_DB_PREFIX . "subscription");
define('FOF_TAG_TABLE', FOF_DB_PREFIX . "tag");
define('FOF_USER_TABLE', FOF_DB_PREFIX . "user");
// Find ourselves and the cache dir
if (!defined('DIR_SEP')) {
define('DIR_SEP', DIRECTORY_SEPARATOR);
}
if (!defined('FOF_DIR')) {
define('FOF_DIR', dirname(__FILE__) . DIR_SEP);
}
?>

790
fof-db.php Normal file
View File

@ -0,0 +1,790 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* fof-db.php - (nearly) all of the DB specific code
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
$FOF_FEED_TABLE = FOF_FEED_TABLE;
$FOF_ITEM_TABLE = FOF_ITEM_TABLE;
$FOF_ITEM_TAG_TABLE = FOF_ITEM_TAG_TABLE;
$FOF_SUBSCRIPTION_TABLE = FOF_SUBSCRIPTION_TABLE;
$FOF_TAG_TABLE = FOF_TAG_TABLE;
$FOF_USER_TABLE = FOF_USER_TABLE;
////////////////////////////////////////////////////////////////////////////////
// Utilities
////////////////////////////////////////////////////////////////////////////////
function fof_db_connect()
{
global $fof_connection;
$fof_connection = mysql_connect(FOF_DB_HOST, FOF_DB_USER, FOF_DB_PASS) or die("<br><br>Cannot connect to database. Please update configuration in <b>fof-config.php</b>. Mysql says: <i>" . mysql_error() . "</i>");
mysql_select_db(FOF_DB_DBNAME, $fof_connection) or die("<br><br>Cannot select database. Please update configuration in <b>fof-config.php</b>. Mysql says: <i>" . mysql_error() . "</i>");
}
function fof_db_optimize()
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_TAG_TABLE, $FOF_USER_TABLE;
fof_db_query("optimize table $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_TAG_TABLE, $FOF_USER_TABLE");
}
function fof_safe_query(/* $query, [$args...]*/)
{
$args = func_get_args();
$query = array_shift($args);
if(is_array($args[0])) $args = $args[0];
$args = array_map('mysql_real_escape_string', $args);
$query = vsprintf($query, $args);
return fof_db_query($query);
}
function fof_db_query($sql, $live=0)
{
global $fof_connection;
list($usec, $sec) = explode(" ", microtime());
$t1 = (float)$sec + (float)$usec;
$result = mysql_query($sql, $fof_connection);
if(is_resource($result)) $num = mysql_num_rows($result);
if($result) $affected = mysql_affected_rows();
list($usec, $sec) = explode(" ", microtime());
$t2 = (float)$sec + (float)$usec;
$elapsed = $t2 - $t1;
$logmessage = sprintf("%.3f: [%s] (%d / %d)", $elapsed, $sql, $num, $affected);
fof_log($logmessage, "query");
if($live)
{
return $result;
}
else
{
if(mysql_errno())
{
//echo "<pre>";
//print_r(debug_backtrace());
//echo "</pre>";
die("Cannot query database. Have you run <a href=\"install.php\"><code>install.php</code></a> to create or upgrade your installation? MySQL says: <b>". mysql_error() . "</b>");
}
return $result;
}
}
function fof_db_get_row($result)
{
return mysql_fetch_array($result);
}
////////////////////////////////////////////////////////////////////////////////
// Feed level stuff
////////////////////////////////////////////////////////////////////////////////
function fof_db_feed_mark_cached($feed_id)
{
global $FOF_FEED_TABLE;
$result = fof_safe_query("update $FOF_FEED_TABLE set feed_cache_date = %d where feed_id = %d", time(), $feed_id);
}
function fof_db_feed_mark_attempted_cache($feed_id)
{
global $FOF_FEED_TABLE;
$result = fof_safe_query("update $FOF_FEED_TABLE set feed_cache_attempt_date = %d where feed_id = %d", time(), $feed_id);
}
function fof_db_feed_update_metadata($feed_id, $url, $title, $link, $description, $image, $image_cache_date)
{
global $FOF_FEED_TABLE;
$sql = "update $FOF_FEED_TABLE set feed_url = '%s', feed_title = '%s', feed_link = '%s', feed_description = '%s'";
$args = array($url, $title, $link, $description);
if($image)
{
$sql .= ", feed_image = '%s' ";
$args[] = $image;
}
else
{
$sql .= ", feed_image = NULL ";
}
$sql .= ", feed_image_cache_date = %d ";
$args[] = $image_cache_date;
$sql .= "where feed_id = %d";
$args[] = $feed_id;
$result = fof_safe_query($sql, $args);
}
function fof_db_get_latest_item_age($user_id)
{
global $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TABLE;
$result = fof_db_query("SELECT max( item_cached ) AS \"max_date\", $FOF_ITEM_TABLE.feed_id as \"id\" FROM $FOF_ITEM_TABLE GROUP BY $FOF_ITEM_TABLE.feed_id");
return $result;
}
function fof_db_get_subscriptions($user_id)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE;
return(fof_safe_query("select * from $FOF_FEED_TABLE, $FOF_SUBSCRIPTION_TABLE where $FOF_SUBSCRIPTION_TABLE.user_id = %d and $FOF_FEED_TABLE.feed_id = $FOF_SUBSCRIPTION_TABLE.feed_id order by feed_title", $user_id));
}
function fof_db_get_feeds()
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE;
return(fof_db_query("select * from $FOF_FEED_TABLE order by feed_title"));
}
function fof_db_get_item_count($user_id)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE;
return(fof_safe_query("select count(*) as count, $FOF_ITEM_TABLE.feed_id as id from $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE where $FOF_SUBSCRIPTION_TABLE.user_id = %d and $FOF_ITEM_TABLE.feed_id = $FOF_SUBSCRIPTION_TABLE.feed_id group by id", $user_id));
}
function fof_db_get_unread_item_count($user_id)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE;
return(fof_safe_query("select count(*) as count, $FOF_ITEM_TABLE.feed_id as id from $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE, $FOF_FEED_TABLE where $FOF_ITEM_TABLE.item_id = $FOF_ITEM_TAG_TABLE.item_id and $FOF_SUBSCRIPTION_TABLE.user_id = $user_id and $FOF_ITEM_TAG_TABLE.tag_id = 1 and $FOF_ITEM_TAG_TABLE.user_id = %d and $FOF_FEED_TABLE.feed_id = $FOF_SUBSCRIPTION_TABLE.feed_id and $FOF_ITEM_TABLE.feed_id = $FOF_FEED_TABLE.feed_id group by id", $user_id));
}
function fof_db_get_starred_item_count($user_id)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE;
return(fof_safe_query("select count(*) as count, $FOF_ITEM_TABLE.feed_id as id from $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE, $FOF_FEED_TABLE where $FOF_ITEM_TABLE.item_id = $FOF_ITEM_TAG_TABLE.item_id and $FOF_SUBSCRIPTION_TABLE.user_id = $user_id and $FOF_ITEM_TAG_TABLE.tag_id = 2 and $FOF_ITEM_TAG_TABLE.user_id = %d and $FOF_FEED_TABLE.feed_id = $FOF_SUBSCRIPTION_TABLE.feed_id and $FOF_ITEM_TABLE.feed_id = $FOF_FEED_TABLE.feed_id group by id", $user_id));
}
function fof_db_get_subscribed_users($feed_id)
{
global $FOF_SUBSCRIPTION_TABLE;
return(fof_safe_query("select user_id from $FOF_SUBSCRIPTION_TABLE where $FOF_SUBSCRIPTION_TABLE.feed_id = %d", $feed_id));
}
function fof_db_is_subscribed($user_id, $feed_url)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE;
$result = fof_safe_query("select $FOF_SUBSCRIPTION_TABLE.feed_id from $FOF_FEED_TABLE, $FOF_SUBSCRIPTION_TABLE where feed_url='%s' and $FOF_SUBSCRIPTION_TABLE.feed_id = $FOF_FEED_TABLE.feed_id and $FOF_SUBSCRIPTION_TABLE.user_id = %d", $feed_url, $user_id);
if(mysql_num_rows($result) == 0)
{
return false;
}
return true;
}
function fof_db_get_feed_by_url($feed_url)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE;
$result = fof_safe_query("select * from $FOF_FEED_TABLE where feed_url='%s'", $feed_url);
if(mysql_num_rows($result) == 0)
{
return NULL;
}
$row = mysql_fetch_array($result);
return $row;
}
function fof_db_get_feed_by_id($feed_id)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE;
$result = fof_safe_query("select * from $FOF_FEED_TABLE where feed_id=%d", $feed_id);
$row = mysql_fetch_array($result);
return $row;
}
function fof_db_add_feed($url, $title, $link, $description)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $fof_connection;
fof_safe_query("insert into $FOF_FEED_TABLE (feed_url,feed_title,feed_link,feed_description) values ('%s', '%s', '%s', '%s')", $url, $title, $link, $description);
return(mysql_insert_id($fof_connection));
}
function fof_db_add_subscription($user_id, $feed_id)
{
global $FOF_SUBSCRIPTION_TABLE;
fof_safe_query("insert into $FOF_SUBSCRIPTION_TABLE (feed_id, user_id) values (%d, %d)", $feed_id, $user_id);
}
function fof_db_delete_subscription($user_id, $feed_id)
{
global $FOF_SUBSCRIPTION_TABLE, $FOF_ITEM_TAG_TABLE;
$result = fof_db_get_items($user_id, $feed_id, $what="all", NULL, NULL);
foreach($result as $r)
{
$items[] = $r['item_id'];
}
$itemclause = join(", ", $items);
fof_safe_query("delete from $FOF_SUBSCRIPTION_TABLE where feed_id = %d and user_id = %d", $feed_id, $user_id);
fof_safe_query("delete from $FOF_ITEM_TAG_TABLE where user_id = %d and item_id in ($itemclause)", $user_id);
}
function fof_db_delete_feed($feed_id)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE;
fof_safe_query("delete from $FOF_FEED_TABLE where feed_id = %d", $feed_id);
fof_safe_query("delete from $FOF_ITEM_TABLE where feed_id = %d", $feed_id);
}
////////////////////////////////////////////////////////////////////////////////
// Item level stuff
////////////////////////////////////////////////////////////////////////////////
function fof_db_find_item($feed_id, $item_guid)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $fof_connection;
$result = fof_safe_query("select item_id from $FOF_ITEM_TABLE where feed_id=%d and item_guid='%s'", $feed_id, $item_guid);
$row = mysql_fetch_array($result);
if(mysql_num_rows($result) == 0)
{
return NULL;
}
else
{
return($row['item_id']);
}
}
function fof_db_add_item($feed_id, $guid, $link, $title, $content, $cached, $published, $updated)
{
global $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_SUBSCRIPTION_TABLE, $fof_connection;
fof_safe_query("insert into $FOF_ITEM_TABLE (feed_id, item_link, item_guid, item_title, item_content, item_cached, item_published, item_updated) values (%d, '%s', '%s' ,'%s', '%s', %d, %d, %d)",
$feed_id, $link, $guid, $title, $content, $cached, $published, $updated);
return(mysql_insert_id($fof_connection));
}
function fof_db_get_items($user_id=1, $feed=NULL, $what="unread", $when=NULL, $start=NULL, $limit=NULL, $order="desc", $search=NULL)
{
global $FOF_SUBSCRIPTION_TABLE, $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE, $FOF_TAG_TABLE;
$prefs = fof_prefs();
$offset = $prefs['tzoffset'];
if(!is_null($when) && $when != "")
{
if($when == "today")
{
$whendate = fof_todays_date();
}
else
{
$whendate = $when;
}
$whendate = explode("/", $whendate);
$begin = gmmktime(0, 0, 0, $whendate[1], $whendate[2], $whendate[0]) - ($offset * 60 * 60);
$end = $begin + (24 * 60 * 60);
}
if(is_numeric($start))
{
if(!is_numeric($limit))
{
$limit = $prefs["howmany"];
}
$limit_clause = " limit $start, $limit ";
}
$args = array();
$select = "SELECT i.* , f.* ";
$from = "FROM $FOF_FEED_TABLE f, $FOF_ITEM_TABLE i, $FOF_SUBSCRIPTION_TABLE s ";
$where = sprintf("WHERE s.user_id = %d AND s.feed_id = f.feed_id AND f.feed_id = i.feed_id ", $user_id);
if(!is_null($feed) && $feed != "")
{
$where .= sprintf("AND f.feed_id = %d ", $feed);
}
if(!is_null($when) && $when != "")
{
$where .= sprintf("AND i.item_published > %d and i.item_published < %d ", $begin, $end);
}
if($what != "all")
{
$tags = split(" ", $what);
$in = implode(", ", array_fill(0, count($tags), "'%s'"));
$from .= ", $FOF_TAG_TABLE t, $FOF_ITEM_TAG_TABLE it ";
$where .= sprintf("AND it.user_id = %d ", $user_id);
$where .= "AND it.tag_id = t.tag_id AND ( t.tag_name IN ( $in ) ) AND i.item_id = it.item_id ";
$group = sprintf("GROUP BY i.item_id HAVING COUNT( i.item_id ) = %d ", count($tags));
$args = array_merge($args, $tags);
}
if(!is_null($search) && $search != "")
{
$where .= "AND (i.item_title like '%%%s%%' or i.item_content like '%%%s%%' )";
$args[] = $search;
$args[] = $search;
}
$order_by = "order by i.item_published desc $limit_clause ";
$query = $select . $from . $where . $group . $order_by;
$result = fof_safe_query($query, $args);
if(mysql_num_rows($result) == 0)
{
return array();
}
while($row = mysql_fetch_assoc($result))
{
$array[] = $row;
}
$array = fof_multi_sort($array, 'item_published', $order != "asc");
$i = 0;
foreach($array as $item)
{
$ids[] = $item['item_id'];
$lookup[$item['item_id']] = $i;
$array[$i]['tags'] = array();
$i++;
}
$items = join($ids, ", ");
$result = fof_safe_query("select $FOF_TAG_TABLE.tag_name, $FOF_ITEM_TAG_TABLE.item_id from $FOF_TAG_TABLE, $FOF_ITEM_TAG_TABLE where $FOF_TAG_TABLE.tag_id = $FOF_ITEM_TAG_TABLE.tag_id and $FOF_ITEM_TAG_TABLE.item_id in (%s) and $FOF_ITEM_TAG_TABLE.user_id = %d", $items, $user_id);
while($row = fof_db_get_row($result))
{
$item_id = $row['item_id'];
$tag = $row['tag_name'];
$array[$lookup[$item_id]]['tags'][] = $tag;
}
return $array;
}
function fof_db_get_item($user_id, $item_id)
{
global $FOF_SUBSCRIPTION_TABLE, $FOF_FEED_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE, $FOF_TAG_TABLE;
$query = "select $FOF_FEED_TABLE.feed_image as feed_image, $FOF_FEED_TABLE.feed_title as feed_title, $FOF_FEED_TABLE.feed_link as feed_link, $FOF_FEED_TABLE.feed_description as feed_description, $FOF_ITEM_TABLE.item_id as item_id, $FOF_ITEM_TABLE.item_link as item_link, $FOF_ITEM_TABLE.item_title as item_title, $FOF_ITEM_TABLE.item_cached, $FOF_ITEM_TABLE.item_published, $FOF_ITEM_TABLE.item_updated, $FOF_ITEM_TABLE.item_content as item_content from $FOF_FEED_TABLE, $FOF_ITEM_TABLE where $FOF_ITEM_TABLE.feed_id=$FOF_FEED_TABLE.feed_id and $FOF_ITEM_TABLE.item_id = %d";
$result = fof_safe_query($query, $item_id);
$item = mysql_fetch_assoc($result);
$item['tags'] = array();
if($user_id)
{
$result = fof_safe_query("select $FOF_TAG_TABLE.tag_name from $FOF_TAG_TABLE, $FOF_ITEM_TAG_TABLE where $FOF_TAG_TABLE.tag_id = $FOF_ITEM_TAG_TABLE.tag_id and $FOF_ITEM_TAG_TABLE.item_id = %d and $FOF_ITEM_TAG_TABLE.user_id = %d", $item_id, $user_id);
while($row = fof_db_get_row($result))
{
$item['tags'][] = $row['tag_name'];
}
}
return $item;
}
////////////////////////////////////////////////////////////////////////////////
// Tag stuff
////////////////////////////////////////////////////////////////////////////////
function fof_db_get_subscription_to_tags()
{
$r = array();
global $FOF_SUBSCRIPTION_TABLE;
$result = fof_safe_query("select * from $FOF_SUBSCRIPTION_TABLE");
while($row = fof_db_get_row($result))
{
$prefs = unserialize($row['subscription_prefs']);
$tags = $prefs['tags'];
if(!is_array($r[$row['feed_id']])) $r[$row['feed_id']] = array();
$r[$row['feed_id']][$row['user_id']] = $tags;
}
return $r;
}
function fof_db_tag_feed($user_id, $feed_id, $tag_id)
{
global $FOF_SUBSCRIPTION_TABLE;
$result = fof_safe_query("select subscription_prefs from $FOF_SUBSCRIPTION_TABLE where feed_id = %d and user_id = %d", $feed_id, $user_id);
$row = fof_db_get_row($result);
$prefs = unserialize($row['subscription_prefs']);
if(!is_array($prefs['tags']) || !in_array($tag_id, $prefs['tags'])) $prefs['tags'][] = $tag_id;
fof_safe_query("update $FOF_SUBSCRIPTION_TABLE set subscription_prefs = '%s' where feed_id = %d and user_id = %d", serialize($prefs), $feed_id, $user_id);
}
function fof_db_untag_feed($user_id, $feed_id, $tag_id)
{
global $FOF_SUBSCRIPTION_TABLE;
$result = fof_safe_query("select subscription_prefs from $FOF_SUBSCRIPTION_TABLE where feed_id = %d and user_id = %d", $feed_id, $user_id);
$row = fof_db_get_row($result);
$prefs = unserialize($row['subscription_prefs']);
if(is_array($prefs['tags']))
{
$prefs['tags'] = array_diff($prefs['tags'], array($tag_id));
}
fof_safe_query("update $FOF_SUBSCRIPTION_TABLE set subscription_prefs = '%s' where feed_id = %d and user_id = %d", serialize($prefs), $feed_id, $user_id);
}
function fof_db_get_item_tags($user_id, $item_id)
{
global $FOF_TAG_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE, $fof_connection;
$result = fof_safe_query("select $FOF_TAG_TABLE.tag_name from $FOF_TAG_TABLE, $FOF_ITEM_TAG_TABLE where $FOF_TAG_TABLE.tag_id = $FOF_ITEM_TAG_TABLE.tag_id and $FOF_ITEM_TAG_TABLE.item_id = %d and $FOF_ITEM_TAG_TABLE.user_id = %d", $item_id, $user_id);
return $result;
}
function fof_db_item_has_tags($item_id)
{
global $FOF_TAG_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE, $fof_connection;
$result = fof_safe_query("select count(*) as \"count\" from $FOF_ITEM_TAG_TABLE where item_id=%d and tag_id <= 2", $item_id);
$row = mysql_fetch_array($result);
return $row["count"];
}
function fof_db_get_unread_count($user_id)
{
global $FOF_ITEM_TAG_TABLE;
$result = fof_safe_query("select count(*) as \"count\" from $FOF_ITEM_TAG_TABLE where tag_id = 1 and user_id = %d", $user_id);
$row = mysql_fetch_array($result);
return $row["count"];
}
function fof_db_get_tag_unread($user_id)
{
global $FOF_TAG_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE;
$result = fof_safe_query("SELECT count(*) as count, it2.tag_id FROM $FOF_ITEM_TABLE i, $FOF_ITEM_TAG_TABLE it , $FOF_ITEM_TAG_TABLE it2 where it.item_id = it2.item_id and it.tag_id = 1 and i.item_id = it.item_id and i.item_id = it2.item_id and it.user_id = %d and it2.user_id = %d group by it2.tag_id", $user_id, $user_id);
$counts = array();
while($row = fof_db_get_row($result))
{
$counts[$row['tag_id']] = $row['count'];
}
return $counts;
}
function fof_db_get_tags($user_id)
{
global $FOF_TAG_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE, $fof_connection;
$sql = "SELECT $FOF_TAG_TABLE.tag_id, $FOF_TAG_TABLE.tag_name, count( $FOF_ITEM_TAG_TABLE.item_id ) as count
FROM $FOF_TAG_TABLE
LEFT JOIN $FOF_ITEM_TAG_TABLE ON $FOF_TAG_TABLE.tag_id = $FOF_ITEM_TAG_TABLE.tag_id
WHERE $FOF_ITEM_TAG_TABLE.user_id = %d
GROUP BY $FOF_TAG_TABLE.tag_id order by $FOF_TAG_TABLE.tag_name";
$result = fof_safe_query($sql, $user_id);
return $result;
}
function fof_db_get_tag_id_map()
{
global $FOF_TAG_TABLE;
$sql = "select * from $FOF_TAG_TABLE";
$result = fof_safe_query($sql);
$tags = array();
while($row = fof_db_get_row($result))
{
$tags[$row['tag_id']] = $row['tag_name'];
}
return $tags;
}
function fof_db_create_tag($user_id, $tag)
{
global $FOF_TAG_TABLE, $fof_connection;
fof_safe_query("insert into $FOF_TAG_TABLE (tag_name) values ('%s')", $tag);
return(mysql_insert_id($fof_connection));
}
function fof_db_get_tag_by_name($user_id, $tag)
{
global $FOF_TAG_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE, $fof_connection;
$result = fof_safe_query("select $FOF_TAG_TABLE.tag_id from $FOF_TAG_TABLE where $FOF_TAG_TABLE.tag_name = '%s'", $tag);
if(mysql_num_rows($result) == 0)
{
return NULL;
}
$row = mysql_fetch_array($result);
return $row['tag_id'];
}
function fof_db_mark_unread($user_id, $items)
{
fof_db_tag_items($user_id, 1, $items);
}
function fof_db_mark_read($user_id, $items)
{
fof_db_untag_items($user_id, 1, $items);
}
function fof_db_mark_feed_read($user_id, $feed_id)
{
global $FOF_ITEM_TAG_TABLE;
$result = fof_db_get_items($user_id, $feed_id, $what="all");
foreach($result as $r)
{
$items[] = $r['item_id'];
}
fof_db_untag_items($user_id, 1, $items);
}
function fof_db_mark_feed_unread($user_id, $feed, $what)
{
global $FOF_ITEM_TAG_TABLE;
fof_log("fof_db_mark_feed_unread($user_id, $feed, $what)");
if($what == "all")
{
$result = fof_db_get_items($user_id, $feed, "all");
}
if($what == "today")
{
$result = fof_db_get_items($user_id, $feed, "all", "today");
}
foreach((array)$result as $r)
{
$items[] = $r['item_id'];
}
fof_db_tag_items($user_id, 1, $items);
}
function fof_db_mark_item_unread($users, $id)
{
global $FOF_ITEM_TAG_TABLE;
if(count($users) == 0) return;
foreach($users as $user)
{
$sql[] = sprintf("(%d, 1, %d)", $user, $id);
}
$values = implode ( ",", $sql );
$sql = "insert into $FOF_ITEM_TAG_TABLE (user_id, tag_id, item_id) values " . $values;
$result = fof_db_query($sql, 1);
if(!$result && (mysql_errno() != 1062))
{
die("Cannot query database. Have you run <a href=\"install.php\"><code>install.php</code></a> to create or upgrade your installation? MySQL says: <b>". mysql_error() . "</b>");
}
}
function fof_db_tag_items($user_id, $tag_id, $items)
{
global $FOF_ITEM_TAG_TABLE;
if(!$items) return;
if(!is_array($items)) $items = array($items);
foreach($items as $item)
{
$sql[] = sprintf("(%d, %d, %d)", $user_id, $tag_id, $item);
}
$values = implode ( ",", $sql );
$sql = "insert into $FOF_ITEM_TAG_TABLE (user_id, tag_id, item_id) values " . $values;
$result = fof_db_query($sql, 1);
if(!$result && (mysql_errno() != 1062))
{
die("Cannot query database. Have you run <a href=\"install.php\"><code>install.php</code></a> to create or upgrade your installation? MySQL says: <b>". mysql_error() . "</b>");
}
}
function fof_db_untag_items($user_id, $tag_id, $items)
{
global $FOF_ITEM_TAG_TABLE;
if(!$items) return;
if(!is_array($items)) $items = array($items);
foreach($items as $item)
{
$sql[] = " item_id = %d ";
$args[] = $item;
}
$values = implode ( " or ", $sql );
$sql = "delete from $FOF_ITEM_TAG_TABLE where user_id = %d and tag_id = %d and ( $values )";
array_unshift($args, $tag_id);
array_unshift($args, $user_id);
fof_safe_query($sql, $args);
}
////////////////////////////////////////////////////////////////////////////////
// User stuff
////////////////////////////////////////////////////////////////////////////////
function fof_db_get_users()
{
global $FOF_USER_TABLE;
$result = fof_safe_query("select user_name, user_id, user_prefs from $FOF_USER_TABLE");
while($row = fof_db_get_row($result))
{
$users[$row['user_id']['user_name']] = $row['user_name'];
$users[$row['user_id']['user_prefs']] = unserialize($row['user_prefs']);
}
}
function fof_db_add_user($username, $password)
{
global $FOF_USER_TABLE;
$password_hash = md5($password . $username);
fof_safe_query("insert into $FOF_USER_TABLE (user_name, user_password_hash) values ('%s', '%s')", $username, $password_hash);
}
function fof_db_change_password($username, $password)
{
global $FOF_USER_TABLE;
$password_hash = md5($password . $username);
fof_safe_query("update $FOF_USER_TABLE set user_password_hash = '%s' where user_name = '%s'", $password_hash, $username);
}
function fof_db_get_user_id($username)
{
global $FOF_USER_TABLE;
$result = fof_safe_query("select user_id from $FOF_USER_TABLE where user_name = '%s'", $username);
$row = mysql_fetch_array($result);
return $row['user_id'];
}
function fof_db_delete_user($username)
{
global $FOF_USER_TABLE, $FOF_ITEM_TAG_TABLE, $FOF_SUBSCRIPTION_TABLE;
$user_id = fof_db_get_user_id($username);
fof_safe_query("delete from $FOF_SUBSCRIPTION_TABLE where user_id = %d", $user_id);
fof_safe_query("delete from $FOF_ITEM_TAG_TABLE where user_id = %d", $user_id);
fof_safe_query("delete from $FOF_USER_TABLE where user_id = %d", $user_id);
}
function fof_db_save_prefs($user_id, $prefs)
{
global $FOF_USER_TABLE;
$prefs = serialize($prefs);
fof_safe_query("update $FOF_USER_TABLE set user_prefs = '%s' where user_id = %d", $prefs, $user_id);
}
function fof_db_authenticate($user_name, $user_password_hash)
{
global $FOF_USER_TABLE, $FOF_ITEM_TABLE, $FOF_ITEM_TAG_TABLE, $fof_connection, $fof_user_id, $fof_user_name, $fof_user_level;
$result = fof_safe_query("select * from $FOF_USER_TABLE where user_name = '%s' and user_password_hash = '%s'", $user_name, $user_password_hash);
if(mysql_num_rows($result) == 0)
{
return false;
}
$row = mysql_fetch_array($result);
$fof_user_name = $row['user_name'];
$fof_user_id = $row['user_id'];
$fof_user_level = $row['user_level'];
return true;
}
?>

1152
fof-main.php Normal file

File diff suppressed because it is too large Load Diff

201
fof-render.php Normal file
View File

@ -0,0 +1,201 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* fof-render.php - contains function used to render a single item
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
// From Brian Suda @ http://suda.co.uk/projects/SEHL/
function do_highlight($full_body, $q, $class){
/* seperate tags and data from the HTML file INCLUDING comments, avoiding HTML in the comments */
$pat = '/((<[^!][\/]*?[^<>]*?>)([^<]*))|((<!--[ \r\n\t]*)(.*)[ \r\n\t]*-->([^<]*))/si';
preg_match_all($pat,$full_body,$tag_matches);
/* loop through and highlight $q value in data and recombine with tags */
for ($i=0; $i< count($tag_matches[0]); $i++) {
/* ignore all text within these tags */
if (
(preg_match('/<!/i', $tag_matches[0][$i])) or
(preg_match('/<textarea/i', $tag_matches[2][$i])) or
(preg_match('/<script/i', $tag_matches[2][$i]))
){
/* array[0] is everything the REGEX found */
$full_body_hl .= $tag_matches[0][$i];
} else {
$full_body_hl .= $tag_matches[2][$i];
/* the slash-i is for case-insensitive and the slash-b's are for word boundries */
/* this one ALMOST works, except if the string is at the start or end of a string*/
$holder = preg_replace('/(.*?)(\W)('.preg_quote($q).')(\W)(.*?)/iu',"\$1\$2<span class=\"$class\">\$3</span>\$4\$5",' '.$tag_matches[3][$i].' ');
$full_body_hl .= substr($holder,1,(strlen($holder)-2));
}
}
/* return tagged text */
return $full_body_hl;
}
function fof_render_item($item)
{
$items = true;
$feed_link = $item['feed_link'];
$feed_title = $item['feed_title'];
$feed_image = $item['feed_image'];
$feed_description = $item['feed_description'];
$item_link = $item['item_link'];
$item_id = $item['item_id'];
$item_title = $item['item_title'];
$item_content = $item['item_content'];
$item_read = $item['item_read'];
$prefs = fof_prefs();
$offset = $prefs['tzoffset'];
$item_published = gmdate("Y-n-d g:ia", $item['item_published'] + $offset*60*60);
$item_cached = gmdate("Y-n-d g:ia", $item['item_cached'] + $offset*60*60);
$item_updated = gmdate("Y-n-d g:ia", $item['item_updated'] + $offset*60*60);
if(!$item_title) $item_title = "[no title]";
if($_GET['search'])
{
$item_content = do_highlight("<span>$item_content</span>", $_GET['search'], "highlight");
$item_title = do_highlight("<span>$item_title</span>", $_GET['search'], "highlight");
}
$tags = $item['tags'];
$star = in_array("star", $tags) ? true : false;
$star_image = $star ? "image/star-on.gif" : "image/star-off.gif";
$unread = in_array("unread", $tags) ? true : false;
?>
<div class="header">
<span class="controls">
<a class='uparrow' href='javascript:hide_body("<?php echo $item_id ?>")'>&uarr;</a>
<a class='downarrow' href='javascript:show_body("<?php echo $item_id ?>")'>&darr;</a>
<input
type="checkbox"
name="c<?php echo $item_id ?>"
id="c<?php echo $item_id ?>"
value="checked"
ondblclick='flag_upto("c<?php echo $item_id?>");'
onclick='return checkbox(event);'
title='shift-click or double-click to flag all items up to this one'
/>
</span>
<h1 <?php if($unread) echo "class='unread-item'" ?> >
<img
height="16"
width="16"
src="<?php echo $star_image ?>"
id="fav<?php echo $item_id ?>"
onclick="return toggle_favorite('<?php echo $item_id ?>')"
/>
<script>
document.getElementById('fav<?php echo $item_id ?>').star = <?php if($star) echo 'true'; else echo 'false'; ?>;
</script>
<a href="<?php echo $item_link ?>">
<?php echo $item_title ?>
</a>
</h1>
<span class="tags">
<?php
if($tags)
{
foreach($tags as $tag)
{
if($tag == "unread" || $tag == "star") continue;
?>
<a href='?what=<?php echo $tag ?>'><?php echo $tag ?></a>
<a href='<?php echo $tag ?>' onclick='return remove_tag("<?php echo $item_id ?>", "<?php echo $tag ?>");'>[x]</a>
<?php
}
}
?>
<a
href=""
onclick="document.getElementById('addtag<?php echo $item_id ?>').style.display = '';
this.style.display = 'none';
return false;">
add tag
</a>
<div id="addtag<?php echo $item_id ?>" style="display: none !important">
<input
onfocus="this.value=''"
onkeypress="if(event.keyCode == 13) add_tag('<?php echo $item_id ?>', document.getElementById('tag<?php echo $item_id ?>').value);"
type="text"
id="tag<?php echo $item_id ?>"
size="12"
value="enter tag here"
>
<input
type="button"
name="add tag"
value="tag"
onclick="add_tag('<?php echo $item_id ?>', document.getElementById('tag<?php echo $item_id ?>').value);"
>
</div>
</span>
<span class='dash'> - </span>
<h2>
<?php $prefs = fof_prefs(); if($feed_image && $prefs['favicons']) { ?>
<a href="<?php echo $feed_link ?>" title='<?php echo $feed_description ?>'><img src="<?php echo $feed_image ?>" height="16" width="16" border="0" /></a>
<?php } ?>
<a href="<?php echo $feed_link ?>" title='<?php echo $feed_description ?>'><?php echo $feed_title ?></a>
</h2>
<span class="meta">on <?php echo $item_published ?></span>
</div>
<div class="body"><?php echo $item_content ?></div>
<?php
$widgets = fof_get_widgets($item);
if($widgets) {
?>
<div class="clearer"></div>
<div class="widgets">
<?php
foreach($widgets as $widget)
{
echo "<span class='widget'>$widget</span> ";
}
?>
</div>
<?php } ?>
<?php
}
?>

377
fof.css Normal file
View File

@ -0,0 +1,377 @@
p
{
margin: 0;
padding: 5px;
}
.clearer
{
clear: both;
}
#view-page
{
font-family: georgia;
margin-top: 0;
}
.header
{
background: #dddddd;
padding: 5px;
}
.widgets
{
font-family: verdana, arial;
background: #f0f0f0;
font-size: 12px;
padding: 4px;
text-align: right;
}
.widget
{
margin-left: 10px;
}
#handle
{
top: 0px;
bottom: 0px;
position: fixed;
width: 10px;
background: grey;
cursor: e-resize;
background-image: url(image/grippy.png);
}
#sidebar
{
font-family: verdana, arial;
font-size: 10px;
margin: 0;
top: 0px;
left: 0px;
height: 100%;
position: fixed;
overflow: scroll;
}
#nav
{
font-size: 11px;
}
#sidebar ul
{
padding-left: 2em;
}
#sidebar form
{
display: inline;
}
#sidebar p
{
margin: 5px;
}
#sidebar table
{
border-collapse: collapse;
width: 100%;
}
.heading a
{
text-decoration: none;
}
.heading
{
background: #ccc;
border-bottom: 1px solid grey;
}
#sidebar td
{
font-size: 10px;
padding: 2px;
}
.odd-row
{
background: #dddddd;
}
.unread
{
font-weight: bold;
color: red;
}
.unread-item
{
font-weight: bold;
}
#items
{
font-family: georgia;
}
.highlight-on .highlight
{
background: yellow;
}
h1
{
font-size: 110%;
margin: 0px;
margin-bottom: 5px;
font-weight: normal;
}
h2
{
font-size: 100%;
margin: 0px;
margin-bottom: 5px;
font-weight: normal;
display: inline;
}
.meta
{
font-size: 80%;
display: inline;
}
.header
{
background-color: #ddd;
padding: 5px;
}
body
{
margin: 0px;
padding: 0px;
}
.body
{
margin: 0px;
padding: 10px 10px 10px 10px;
}
.item
{
border: 2px solid #ddd;
margin: 10px;
margin-bottom: 20px;
clear: both;
overflow: hidden;
}
.item.selected
{
border: 1px solid #888;
background-color: #eee;
}
.selected .header
{
background-color: #ccc;
}
#menu-page
{
margin: 0;
padding: 0;
font-family: verdana;
font-size: 60%;
background: #eee;
}
#menu-page .menu ul
{
padding: 1px;
margin: 0;
}
#menu-page .menu li
{
display: inline;
padding: 5px;
}
#menu-page .menu
{
text-align: center;
background: #eee;
}
#menu-page a:hover
{
background: #fff;
}
.nowrap
{
white-space: nowrap;
}
.controls
{
float: right;
}
.tags
{
font-size: 70%;
float: right;
}
.item.hidden
{
margin-bottom: 10px;
}
.hidden .body
{
display: none;
}
.hidden .widgets
{
display: none;
}
.shown .downarrow
{
display: none;
}
.hidden .uparrow
{
display: none;
}
.hidden h1
{
font-size: 90%;
display: inline;
}
.hidden h2
{
font-size: 80%;
}
.hidden .tags
{
display: none;
}
.hidden .meta
{
display: none;
}
.hidden .dash
{
display: inline;
}
.shown .dash
{
display: none;
}
#welcome
{
font: normal 10px Verdana;
background: #ddd;
border-bottom: 1px solid #666;
padding: 5px 7px;
}
#item-display-controls
{
font: normal 10px Verdana;
position: fixed;
top: 0;
left: 0;
right: 0;
margin: 0;
padding: 0 5px;
background: #ddd;
border-bottom: 1px solid #666;
z-index: 1;
}
#item-display-controls li
{
padding: 5px 4px;
}
#item-display-controls li a
{
padding: 0;
}
#item-display-controls-spacer
{
font: normal 10px Verdana;
top: 0;
left: 0;
right: 0;
margin: 0;
padding: 0;
}
#item-display-controls-spacer li
{
padding: 5px 4px;
}
#item-display-controls-spacer li a
{
padding: 0;
}
.item-date-nav
{
text-align: center;
clear: both;
padding: 7px 0 0 0;
}
.inline-list
{
margin: auto;
padding: 0;
list-style: none;
}
.inline-list li
{
float: left;
margin: 0;
padding: 0;
}
.inline-list li a
{
display: block;
padding: 2px 5px;
}

908
fof.js Normal file
View File

@ -0,0 +1,908 @@
var curWidth = 0;
var curPos = 0;
var drag = false;
var what;
var when;
var firstItem;
var item;
var itemElement;
var itemElements;
// magic from http://peter.michaux.ca/article/3556
var getScrollY = function() {
if (typeof window.pageYOffset == 'number') {
getScrollY = function() {
return window.pageYOffset;
};
} else if ((typeof document.compatMode == 'string') &&
(document.compatMode.indexOf('CSS') >= 0) &&
(document.documentElement) &&
(typeof document.documentElement.scrollTop == 'number')) {
getScrollY = function() {
return document.documentElement.scrollTop;
};
} else if ((document.body) &&
(typeof document.body.scrollTop == 'number')) {
getScrollY = function() {
return document.body.scrollTop;
}
} else {
getScrollY = function() {
return NaN;
};
}
return getScrollY();
}
var getY = function(e)
{
var y = NaN;
if (e.offsetParent) {
y = e.offsetTop
while (e = e.offsetParent) {
y += e.offsetTop
}
}
return y;
}
function getWindowHeight()
{
if( typeof( window.innerHeight ) == 'number' ) {
//Non-IE
return window.innerHeight;
} else if( document.documentElement && document.documentElement.clientHeight ) {
//IE 6+ in 'standards compliant mode'
return document.documentElement.clientHeight;
} else if( document.body && document.body.clientHeight ) {
//IE 4 compatible
return document.body.clientHeight;
}
return NaN;
}
function embed_odeo(link) {
document.writeln('<embed src="http://odeo.com/flash/audio_player_fullsize.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="440" height="80" wmode="transparent" allowScriptAccess="any" flashvars="valid_sample_rate=true&external_url='+link+'"></embed>');
}
function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
if (placeholder != '') {
document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
}
else {
document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
}
}
function embed_flash(bgcolor, width, height, link, loop, type) {
document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');
}
function embed_flv(width, height, link, placeholder, loop, player) {
document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');
}
function embed_wmedia(width, height, link) {
document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
}
function itemClicked(event)
{
if(!event) event = window.event;
target = window.event ? window.event.srcElement : event.target;
if(event.altKey)
{
Event.stop(event);
unselect(itemElement);
while(target.parentNode)
{
if(Element.hasClassName(target, "item"))
{
break;
}
target = target.parentNode;
}
if(itemElement == target)
{
itemElement = null;
return false;
}
Element.addClassName(target, 'selected');
itemElement = target;
i = itemElements.indexOf(target);
if(i == -1)
{
// in case page was partially loaded when itemElements was initialized
itemElements = $$('.item');
i = itemElements.indexOf(target);
}
n = itemElements.length;
i++;
document.title = "Feed on Feeds - " + i + " of " + n;
return false;
}
return true;
}
function checkbox(event)
{
if(!event) event = window.event;
target = window.event ? window.event.srcElement : event.target;
if(!event.shiftKey)
return true;
flag_upto(target.id);
return true;
}
function select(item)
{
Element.addClassName(item, 'selected');
y = getY(item);
bar = $('item-display-controls').getHeight();
window.scrollTo(0, y - (bar + 10));
i = itemElements.indexOf(item);
if(i == -1)
{
// in case page was partially loaded when itemElements was initialized
itemElements = $$('.item');
i = itemElements.indexOf(item);
}
n = itemElements.length;
i++;
document.title = "Feed on Feeds - " + i + " of " + n;
}
function unselect(item)
{
Element.removeClassName(item, 'selected');
document.title = "Feed on Feeds";
}
function show_enclosure(e)
{
if (!e) e = window.event;
target = window.event ? window.event.srcElement : e.target;
Element.extend(target);
div = target.nextSiblings().first();
Element.show(div);
Element.hide(target);
return false;
}
function keyboard(e)
{
if (!e) e = window.event;
target = window.event ? window.event.srcElement : e.target;
if(target != null && target.type != null && (target.type == "textarea" || target.type=="text" || target.type=="password"))
{
return true;
}
if (e.keyCode) keycode=e.keyCode;
else keycode=e.which;
if(e.ctrlKey || e.altKey || e.metaKey) return true;
key = String.fromCharCode(keycode);
if(!itemElements) itemElements = $$('.item');
windowHeight = getWindowHeight();
if(key == "H")
{
itemElements.each(
function(i) {
Element.toggleClassName(i, "shown");
Element.toggleClassName(i, "hidden");
}
);
if(itemElement)
select(itemElement);
return false;
}
if(key == "h")
{
if(itemElement)
{
Element.toggleClassName(itemElement, "shown");
Element.toggleClassName(itemElement, "hidden");
select(itemElement);
return false;
}
}
if(key == "s")
{
if(itemElement)
{
toggle_favorite(itemElement.id.substring(1));
select(itemElement);
return false;
}
}
if(key == "f")
{
if(itemElement)
{
checkbox = ($('c' + itemElement.id.substring(1)));
checkbox.checked = true;
return false;
}
}
if(key == "F")
{
itemElements.each(
function(i) {
if(itemElement)
{
if(itemElements.indexOf(i) > itemElements.indexOf(itemElement))
return;
}
checkbox = ($('c' + i.id.substring(1)));
checkbox.checked = true;
}
);
return false;
}
if(key == "U")
{
itemElements.each(
function(i) {
checkbox = ($('c' + i.id.substring(1)));
checkbox.checked = false;
}
);
return false;
}
if(key == "j")
{
if(itemElement)
{
// is the next element visible yet? scroll if not.
if(itemElement.nextSibling.id && itemElement.nextSibling.id != "end-of-items")
{
nextElement = itemElement.nextSibling;
scrollHeight = getScrollY();
y = getY(nextElement);
if(y > scrollHeight + windowHeight)
{
window.scrollTo(0, scrollHeight + (.8 * windowHeight));
return false;
}
}
unselect(itemElement);
checkbox = ($('c' + itemElement.id.substring(1)));
checkbox.checked = true;
next = itemElement.nextSibling;
if(next.id && next.id != "end-of-items")
{
itemElement = next;
}
else
{
scrollHeight = getScrollY();
e = $('end-of-items');
if (e.offsetParent) {
y = e.offsetTop
while (e = e.offsetParent) {
y += e.offsetTop
}
}
if(y - 10 > scrollHeight + windowHeight)
{
window.scrollTo(0, scrollHeight + (.8 * windowHeight));
return false;
}
else
{
if(confirm("No more items! Mark flagged as read?"))
{
mark_read();
}
else
{
item = firstItem;
itemElement = $(item);
select(itemElement);
return false;
}
}
}
item = itemElement.id;
itemElement = $(item);
select(itemElement);
return false;
}
else
{
item = firstItem;
itemElement = $(item);
itemElements = $$('.item');
select(itemElement);
return false;
}
}
if(key == "J")
{
if(itemElement)
{
unselect(itemElement);
checkbox = ($('c' + itemElement.id.substring(1)));
checkbox.checked = true;
next = itemElement.nextSibling;
if(next.id)
{
itemElement = next;
}
else
{
if(confirm("No more items! Mark flagged as read?"))
{
mark_read();
}
else
{
item = firstItem;
itemElement = $(item);
}
}
item = itemElement.id;
itemElement = $(item);
select(itemElement);
return false;
}
else
{
item = firstItem;
itemElement = $(item);
itemElements = $$('.item');
select(itemElement);
return false;
}
}
if(key == "n")
{
if(itemElement)
{
unselect(itemElement);
next = itemElement.nextSibling;
if(next.id)
{
itemElement = next;
}
else
{
item = firstItem;
itemElement = $(item);
}
item = itemElement.id;
itemElement = $(item);
select(itemElement);
return false;
}
else
{
item = firstItem;
itemElement = $(item);
itemElements = $$('.item');
select(itemElement);
return false;
}
}
if(key == "N")
{
if(itemElement) unselect(itemElement);
item = itemElements.last().id;
itemElement = $(item);
select(itemElement);
return false;
}
if(key == "P")
{
if(itemElement) unselect(itemElement);
item = firstItem;
itemElement = $(item);
itemElements = $$('.item');
select(itemElement);
return false;
}
if(key == "p")
{
if(itemElement)
{
unselect(itemElement);
next = itemElement.previousSibling;
if(next.id)
{
itemElement = next;
}
else
{
item = itemElements.last().id;
itemElement = $(item);
}
item = itemElement.id;
itemElement = $(item);
select(itemElement);
return false;
}
else
{
itemElements = $$('.item');
item = itemElements.last().id;
itemElement = $(item);
select(itemElement);
return false;
}
}
return true;
}
function startResize(e)
{
if (!e) e = window.event;
Event.stop(e);
drag = true;
curPos=e.clientX;
curWidth=$('sidebar').offsetWidth;
return false;
}
function dragResize(e)
{
if (!e) e = window.event;
if(drag)
{
Event.stop(e);
newPos=e.clientX;
var x=newPos-curPos;
var w=curWidth+x;
newWidth=(w<5?5:w);
$('handle').style.left=newWidth+'px';
return false;
}
}
function completeDrag(e)
{
if (!e) e = window.event;
if(drag)
{
Event.stop(e);
drag = false;
newPos=e.clientX;
var x=newPos-curPos;
var w=curWidth+x;
newWidth=(w<5?5:w);
$('sidebar').style.width=newWidth+'px';
$('handle').style.left=newWidth+'px';
$('items').style.marginLeft=(newWidth+20)+'px';
$('item-display-controls').style.left=(newWidth+10)+'px';
if(isIE)
{
tables = $$('#sidebar table');
for(i=0;i<tables.length;i++){
tables[i].style.width=(newWidth-20)+'px';
}
}
var today = new Date();
var expire = new Date();
expire.setTime(today.getTime() + 3600000*24*100);
document.cookie = "fof_sidebar_width="+newWidth+ "; expires="+expire.toGMTString()+";";
return false;
}
}
function hide_all()
{
items = document.getElementsByClassName("item", "items");
items.each( function(e) { e.className = "item hidden"; });
}
function show_all()
{
items = document.getElementsByClassName("item", "items");
items.each( function(e) { e.className = "item shown"; });
}
function hide_body(id)
{
$('i' + id).className = 'item hidden';
}
function show_body(id)
{
$('i' + id).className = 'item shown';
}
function flag_upto(id)
{
elements = $A(Form.getInputs('itemform', 'checkbox'));
for(i=0; i<elements.length; i++)
{
elements[i].checked = true;
if(elements[i].name == id)
{
break;
}
}
}
function toggle_highlight()
{
if(document.body.className == '')
{
document.body.className = 'highlight-on';
}
else
{
document.body.className = '';
}
}
function flag_all()
{
elements = $A(Form.getInputs('itemform', 'checkbox'));
elements.each( function(e) { e.checked = true; });
}
function toggle_all()
{
elements = $A(Form.getInputs('itemform', 'checkbox'));
elements.each( function(e) { e.checked = !e.checked; });
}
function unflag_all()
{
elements = $A(Form.getInputs('itemform', 'checkbox'));
elements.each( function(e) { e.checked = false; });
}
function mark_read()
{
document.items['action'].value = 'read';
document.items['return'].value = escape(location);
document.items.submit();
}
function mark_unread()
{
document.items['action'].value = 'unread';
document.items['return'].value = escape(location);
document.items.submit();
}
function mark_feed_read(id)
{
throb();
var url = "view-action.php";
var params = "feed=" + id;
var complete = function () { refreshlist(); };
var options = { method: 'post', parameters: params, onComplete: complete };
new Ajax.Request(url, options);
return false;
}
function add_tag(id, tag)
{
throb();
var url = "add-tag.php";
var params = "tag=" + tag + "&item=" + id;
var complete = function () { refreshlist(); refreshitem(id); };
var options = { method: 'get', parameters: params, onComplete: complete };
new Ajax.Request(url, options);
return false;
}
function remove_tag(id, tag)
{
throb();
var url = "add-tag.php";
var params = "remove=true&tag=" + tag + "&item=" + id;
var complete = function () { refreshlist(); refreshitem(id); };
var options = { method: 'get', parameters: params, onComplete: complete };
new Ajax.Request(url, options);
return false;
}
function delete_tag(tag)
{
throb();
var url = "view-action.php";
var params = "deltag=" + tag;
var complete = function () { refreshlist(); };
var options = { method: 'get', parameters: params, onComplete: complete };
new Ajax.Request(url, options);
return false;
}
function change_feed_order(order, direction)
{
throb();
var url = "set-prefs.php";
var params = "feed_order=" + order + "&feed_direction=" + direction;
var complete = function () { refreshlist(); };
var options = { method: 'post', parameters: params, onComplete: complete };
new Ajax.Request(url, options);
return false;
}
function toggle_favorite(id)
{
throb();
var image = $('fav' + id);
var url = "add-tag.php?tag=star";
var params = "&item=" + id;
image.src = 'image/star-pending.gif';
if(image.star)
{
params += "&remove=true";
var complete = function()
{
image.src='image/star-off.gif';
image.star = false;
starred--;
if(starred)
{
$('starredcount').update('(' + starred + ')');
}
else
{
$('starredcount').update('');
}
unthrob();
};
}
else
{
var complete = function()
{
image.src='image/star-on.gif';
image.star = true;
starred++;
if(starred)
{
$('starredcount').update('(' + starred + ')');
}
else
{
$('starredcount').update('');
}
unthrob();
};
}
var options = { method: 'get', parameters: params, onComplete: complete };
new Ajax.Request(url, options);
return false;
}
function refreshitem(id)
{
throb();
var url = 'item.php';
var params = 'id=' + id;
new Ajax.Updater($("i"+id), url, {method: 'get', parameters: params });
}
function refreshlist()
{
throb();
var url = 'sidebar.php';
var params = "what=" + what + "&when=" + when;
new Ajax.Updater($('sidebar'), url, {method: 'get', parameters: params, evalScripts: true });
}
function throb()
{
Element.show('throbber');
}
function unthrob()
{
Element.hide('throbber');
}
// this fancy bit of computer science from Aristotle Pagaltzis @ http://plasmasturm.org/log/311/
function iterate( iterable ) {
var i = -1;
var getter = function() { return i < 0 ? null : i < iterable.length ? iterable[ i ] : null; };
return function() { return ++i < iterable.length ? getter : null };
}
function continueupdate()
{
if(feed = feedi())
{
f = feed();
new Insertion.Bottom($('items'), 'Updating ' + f['title'] + "... ");
$('items').childElements().last().scrollTo();
new Ajax.Updater('items', 'update-single.php', {
method: 'get',
parameters: 'feed=' + f['id'],
insertion: Insertion.Bottom,
onComplete: continueupdate
});
}
else
{
new Insertion.Bottom($('items'), '<br>Update complete!');
refreshlist();
}
}
function continueadd()
{
if(feed = feedi())
{
f = feed();
new Insertion.Bottom($('items'), 'Adding ' + f['url'] + "... ");
$('items').childElements().last().scrollTo();
parameters = 'url=' + encodeURIComponent(f['url']) + "&unread=" + document.addform.unread.value;
new Ajax.Updater('items', 'add-single.php', {
method: 'get',
parameters: parameters,
insertion: Insertion.Bottom,
onComplete: continueadd
});
}
else
{
new Insertion.Bottom($('items'), '<br>Done!');
refreshlist();
}
}
function ajaxupdate()
{
throb();
feedi = iterate(feedslist);
continueupdate();
}
function ajaxadd()
{
throb();
feedi = iterate(feedslist);
continueadd();
}

4
footer.php Normal file
View File

@ -0,0 +1,4 @@
</div>
</body>
</html>

93
header.php Normal file
View File

@ -0,0 +1,93 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* header.php - common header for all pages
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
fof_set_content_type();
if(isset($_COOKIE['fof_sidebar_width']))
{
$width = $_COOKIE['fof_sidebar_width'];
}
else
{
$width = 250;
}
$unread_count = fof_get_unread_count(fof_current_user());
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Feed on Feeds<?php if($unread_count) echo " ($unread_count)";?></title>
<link rel="stylesheet" href="fof.css" media="screen" />
<script src="prototype/prototype.js" type="text/javascript"></script>
<script src="fof.js" type="text/javascript"></script>
<script>
document.onmousemove = dragResize;
document.onmouseup = completeDrag;
<?php if($fof_prefs_obj->get('keyboard')) { ?>
document.onkeypress = keyboard;
<?php } ?>
isIE = false;
</script>
<style>
#sidebar
{
width: <?php echo $width ?>px;
}
#handle
{
left:<?php echo $width ?>px;
}
#items
{
margin-left: <?php echo $width+20 ?>px;
}
#item-display-controls { left: <?php echo $width+10 ?>px; }
</style>
<!--[if IE]>
<style>
#sidebar table
{
width: <?php echo $width - 20?>px;
}
</style>
<script>isIE = true;</script>
<![endif]-->
</head>
<body class="highlight-on"> <!--onkeypress="keyboard(event)"-->
<div id="sidebar">
<?php include("sidebar.php") ?>
</div>
<div id="handle" onmousedown="startResize(event)"></div>
<div id="items">

BIN
image/feed-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

BIN
image/grippy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

BIN
image/star-off.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 585 B

BIN
image/star-on.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 B

BIN
image/star-pending.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

BIN
image/throbber.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

20
index.php Normal file
View File

@ -0,0 +1,20 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* index.php - main viewer page
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include("header.php");
include("items.php");
include("footer.php");
?>

363
install.php Normal file
View File

@ -0,0 +1,363 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* install.php - creates tables and cache directory, if they don't exist
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
$fof_no_login = true;
$fof_installer = true;
include_once("fof-main.php");
fof_set_content_type();
// compatibility testing code lifted from SimplePie
function get_curl_version()
{
if (is_array($curl = curl_version()))
{
$curl = $curl['version'];
}
else if (preg_match('/curl\/(\S+)(\s|$)/', $curl, $match))
{
$curl = $match[1];
}
else
{
$curl = 0;
}
return $curl;
}
$php_ok = (function_exists('version_compare') && version_compare(phpversion(), '4.3.2', '>='));
$xml_ok = extension_loaded('xml');
$pcre_ok = extension_loaded('pcre');
$mysql_ok = extension_loaded('mysql');
$curl_ok = (extension_loaded('curl') && version_compare(get_curl_version(), '7.10.5', '>='));
$zlib_ok = extension_loaded('zlib');
$mbstring_ok = extension_loaded('mbstring');
$iconv_ok = extension_loaded('iconv');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>feed on feeds - installation</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="fof.css" media="screen" />
<script src="fof.js" type="text/javascript"></script>
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW" />
<style>
body
{
font-family: georgia;
font-size: 16px;
}
div
{
background: #eee;
border: 1px solid black;
width: 75%;
margin: 5em auto;
padding: 1.5em;
}
hr
{
height:0;
border:0;
border-top:1px solid #999;
}
.fail { color: red; }
.pass { color: green; }
.warn { color: #a60; }
</style>
</head>
<body><div> <center style="font-size: 20px;"><a href="http://feedonfeeds.com/">Feed on Feeds</a> - Installation</center><br>
<?php
if($_GET['password'] && $_GET['password'] == $_GET['password2'] )
{
$password_hash = md5($_GET['password'] . 'admin');
fof_safe_query("insert into $FOF_USER_TABLE (user_id, user_name, user_password_hash, user_level) values (1, 'admin', '%s', 'admin')", $password_hash);
echo '<center><b>OK! Setup complete! <a href=".">Login as admin</a>, and start subscribing!</center></b></div></body></html>';
}
else
{
if($_GET['password'] != $_GET['password2'] )
{
echo '<center><font color="red">Passwords do not match!</font></center><br><br>';
}
?>
Checking compatibility...
<?php
if($php_ok) echo "<span class='pass'>PHP ok...</span> ";
else
{
echo "<br><span class='fail'>Your PHP version is too old!</span> Feed on Feeds requires at least PHP 4.3.2. Sorry!";
echo "</div></body></html>";
exit;
}
if($xml_ok) echo "<span class='pass'>XML ok...</span> ";
else
{
echo "<br><span class='fail'>Your PHP installation is missing the XML extension!</span> This is required by Feed on Feeds. Sorry!";
echo "</div></body></html>";
exit;
}
if($pcre_ok) echo "<span class='pass'>PCRE ok...</span> ";
else
{
echo "<br><span class='fail'>Your PHP installation is missing the PCRE extension!</span> This is required by Feed on Feeds. Sorry!";
echo "</div></body></html>";
exit;
}
if($mysql_ok) echo "<span class='pass'>MySQL ok...</span> ";
else
{
echo "<br><span class='fail'>Your PHP installation is missing the MySQL extension!</span> This is required by Feed on Feeds. Sorry!";
echo "</div></body></html>";
exit;
}
if($curl_ok) echo "<span class='pass'>cURL ok...</span> ";
else
{
echo "<br><span class='warn'>Your PHP installation is either missing the cURL extension, or it is too old!</span> cURL version 7.10.5 or later is required to be able to subscribe to https or digest authenticated feeds.<br>";
}
if($zlib_ok) echo "<span class='pass'>Zlib ok...</span> ";
else
{
echo "<br><span class='warn'>Your PHP installation is missing the Zlib extension!</span> Feed on Feeds will not be able to save bandwidth by requesting compressed feeds.<br>";
}
if($iconv_ok) echo "<span class='pass'>iconv ok...</span> ";
else
{
echo "<br><span class='warn'>Your PHP installation is missing the iconv extension!</span> The number of international languages that Feed on Feeds can handle will be reduced.<br>";
}
if($mbstring_ok) echo "<span class='pass'>mbstring ok...</span> ";
else
{
echo "<br><span class='warn'>Your PHP installation is missing the mbstring extension!</span> The number of international languages that Feed on Feeds can handle will be reduced.<br>";
}
?>
<br>Minimum requirements met!
<hr>
Creating tables...
<?php
$tables[] = <<<EOQ
CREATE TABLE IF NOT EXISTS `$FOF_FEED_TABLE` (
`feed_id` int(11) NOT NULL auto_increment,
`feed_url` text NOT NULL,
`feed_title` text NOT NULL,
`feed_link` text NOT NULL,
`feed_description` text NOT NULL,
`feed_image` text,
`feed_image_cache_date` int(11) default '0',
`feed_cache_date` int(11) default '0',
`feed_cache_attempt_date` int(11) default '0',
`feed_cache` text,
PRIMARY KEY (`feed_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
EOQ;
$tables[] = <<<EOQ
CREATE TABLE IF NOT EXISTS `$FOF_ITEM_TABLE` (
`item_id` int(11) NOT NULL auto_increment,
`feed_id` int(11) NOT NULL default '0',
`item_guid` text NOT NULL,
`item_link` text NOT NULL,
`item_cached` int(11) NOT NULL default '0',
`item_published` int(11) NOT NULL default '0',
`item_updated` int(11) NOT NULL default '0',
`item_title` text NOT NULL,
`item_content` text NOT NULL,
PRIMARY KEY (`item_id`),
KEY `feed_id` (`feed_id`),
KEY `item_guid` (`item_guid`(255)),
KEY `feed_id_item_cached` (`feed_id`,`item_cached`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
EOQ;
$tables[] = <<<EOQ
CREATE TABLE IF NOT EXISTS `$FOF_ITEM_TAG_TABLE` (
`user_id` int(11) NOT NULL default '0',
`item_id` int(11) NOT NULL default '0',
`tag_id` int(11) NOT NULL default '0',
PRIMARY KEY (`user_id`,`item_id`,`tag_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
EOQ;
$tables[] = <<<EOQ
CREATE TABLE IF NOT EXISTS `$FOF_SUBSCRIPTION_TABLE` (
`feed_id` int(11) NOT NULL default '0',
`user_id` int(11) NOT NULL default '0',
`subscription_prefs` text,
PRIMARY KEY (`feed_id`,`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
EOQ;
$tables[] = <<<EOQ
CREATE TABLE IF NOT EXISTS `$FOF_TAG_TABLE` (
`tag_id` int(11) NOT NULL auto_increment,
`tag_name` char(100) NOT NULL default '',
PRIMARY KEY (`tag_id`),
UNIQUE KEY (`tag_name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
EOQ;
$tables[] = <<<EOQ
CREATE TABLE IF NOT EXISTS `$FOF_USER_TABLE` (
`user_id` int(11) NOT NULL auto_increment,
`user_name` varchar(100) NOT NULL default '',
`user_password_hash` varchar(32) NOT NULL default '',
`user_level` enum('user','admin') NOT NULL default 'user',
`user_prefs` text,
PRIMARY KEY (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
EOQ;
foreach($tables as $table)
{
if(!fof_db_query($table, 1))
{
exit ("Can't create table. MySQL says: <b>" . mysql_error() . "</b><br>" );
}
}
?>
Tables exist.<hr>
<?php
$result = fof_db_query("show columns from $FOF_FEED_TABLE like 'feed_image_cache_date'");
if(mysql_num_rows($result) == 0)
{
print "Upgrading schema...";
fof_db_query("ALTER TABLE $FOF_FEED_TABLE ADD `feed_image_cache_date` INT( 11 ) DEFAULT '0' AFTER `feed_image` ;");
print "Done.<hr>";
}
?>
<?php
$result = fof_db_query("show columns from $FOF_USER_TABLE like 'user_password_hash'");
if(mysql_num_rows($result) == 0)
{
print "Upgrading schema...";
fof_db_query("ALTER TABLE $FOF_USER_TABLE CHANGE `user_password` `user_password_hash` VARCHAR( 32 ) NOT NULL");
fof_db_query("update $FOF_USER_TABLE set user_password_hash = md5(concat(user_password_hash, user_name))");
print "Done.<hr>";
}
?>
<?php
$result = fof_db_query("show columns from $FOF_FEED_TABLE like 'feed_cache_attempt_date'");
if(mysql_num_rows($result) == 0)
{
print "Upgrading schema...";
fof_db_query("ALTER TABLE $FOF_FEED_TABLE ADD `feed_cache_attempt_date` INT( 11 ) DEFAULT '0' AFTER `feed_cache_date` ;");
print "Done.<hr>";
}
?>
Inserting initial data...
<?php
fof_db_query("insert into $FOF_TAG_TABLE (tag_id, tag_name) values (1, 'unread')", 1);
fof_db_query("insert into $FOF_TAG_TABLE (tag_id, tag_name) values (2, 'star')", 1);
?>
Done.<hr>
Checking cache directory...
<?php
if ( ! file_exists( "cache" ) )
{
$status = @mkdir( "cache", 0755 );
if ( ! $status )
{
echo "<font color='red'>Can't create directory <code>" . getcwd() . "/cache/</code>.<br>You will need to create it yourself, and make it writeable by your PHP process.<br>Then, reload this page.</font>";
echo "</div></body></html>";
exit;
}
}
if(!is_writable( "cache" ))
{
echo "<font color='red'>The directory <code>" . getcwd() . "/cache/</code> exists, but is not writable.<br>You will need to make it writeable by your PHP process.<br>Then, reload this page.</font>";
echo "</div></body></html>";
exit;
}
?>
Cache directory exists and is writable.<hr>
<?php
$result = fof_db_query("select * from $FOF_USER_TABLE where user_name = 'admin'");
if(mysql_num_rows($result) == 0) {
?>
You now need to choose an initial password for the 'admin' account:<br>
<form>
<table>
<tr><td>Password:</td><td><input type=password name=password></td></tr>
<tr><td>Password again:</td><td><input type=password name=password2></td></tr>
</table>
<input type=submit value="Set Password">
</form>
<?php } else { ?>
'admin' account already exists.<br>
<br><b><center>OK! Setup complete! <a href=".">Login as admin</a>, and start subscribing!</center></b>
<?php } } ?>
</div></body></html>

24
item.php Normal file
View File

@ -0,0 +1,24 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* item.php - renders a single item (useful for Ajax)
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
include_once("fof-render.php");
fof_set_content_type();
$row = fof_get_item(fof_current_user(), $_GET['id']);
fof_render_item($row);
?>

136
items.php Normal file
View File

@ -0,0 +1,136 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* items.php - displays right hand side "frame"
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
include_once("fof-render.php");
if($_GET['how'] == 'paged' && !isset($_GET['which']))
{
$which = 0;
}
else
{
$which = $_GET['which'];
}
$order = $_GET['order'];
if(!isset($_GET['what']))
{
$what = "unread";
}
else
{
$what = $_GET['what'];
}
if(!isset($_GET['order']))
{
$order = $fof_prefs_obj->get("order");
}
$how = $_GET['how'];
$feed = $_GET['feed'];
$when = $_GET['when'];
$howmany = $_GET['howmany'];
$title = fof_view_title($_GET['feed'], $what, $_GET['when'], $which, $_GET['howmany'], $_GET['search']);
$noedit = $_GET['noedit'];
?>
<ul id="item-display-controls-spacer" class="inline-list">
<li class="orderby">[new to old]</li>
<li class="orderby">[old to new]</li>
<li><a href="javascript:flag_all();mark_read()"><strong>Mark all read</strong></a></li>
<li><a href="javascript:flag_all()">Flag all</a></li>
<li><a href="javascript:unflag_all()">Unflag all</a></li>
<li><a href="javascript:toggle_all()">Toggle all</a></li>
<li><a href="javascript:mark_read()">Mark flagged read</a></li>
<li><a href="javascript:mark_unread()">Mark flagged unread</a></li>
<li><a href="javascript:show_all()">Show all</a></li>
<li><a href="javascript:hide_all()">Hide all</a></li>
</ul>
<br style="clear: both"><br>
<p><?php echo $title?></p>
<ul id="item-display-controls" class="inline-list">
<li class="orderby"><?php
echo ($order == "desc") ? '[new to old]' : "<a href=\".?feed=$feed&amp;what=$what&amp;when=$when&amp;how=$how&amp;howmany=$howmany&amp;order=desc\">[new to old]</a>" ;
?></li>
<li class="orderby"><?php
echo ($order == "asc") ? '[old to new]' : "<a href=\".?feed=$feed&amp;what=$what&amp;when=$when&amp;how=$how&amp;howmany=$howmany&amp;order=asc\">[old to new]</a>" ;
?></li>
<li><a href="javascript:flag_all();mark_read()"><strong>Mark all read</strong></a></li>
<li><a href="javascript:flag_all()">Flag all</a></li>
<li><a href="javascript:unflag_all()">Unflag all</a></li>
<li><a href="javascript:toggle_all()">Toggle all</a></li>
<li><a href="javascript:mark_read()">Mark flagged read</a></li>
<li><a href="javascript:mark_unread()">Mark flagged unread</a></li>
<li><a href="javascript:show_all()">Show all</a></li>
<li><a href="javascript:hide_all()">Hide all</a></li>
</ul>
<!-- close this form to fix first item! -->
<form id="itemform" name="items" action="view-action.php" method="post" onSubmit="return false;">
<input type="hidden" name="action" />
<input type="hidden" name="return" />
<?php
$links = fof_get_nav_links($_GET['feed'], $what, $_GET['when'], $which, $_GET['howmany']);
if($links)
{
?>
<center><?php echo $links ?></center>
<?php
}
$result = fof_get_items(fof_current_user(), $_GET['feed'], $what, $_GET['when'], $which, $_GET['howmany'], $order, $_GET['search']);
$first = true;
foreach($result as $row)
{
$item_id = $row['item_id'];
if($first) print "<script>firstItem = 'i$item_id'; </script>";
$first = false;
print '<div class="item shown" id="i' . $item_id . '" onclick="return itemClicked(event)">';
fof_render_item($row);
print '</div>';
}
if(count($result) == 0)
{
echo "<p><i>No items found.</i></p>";
}
?>
</form>
<div id="end-of-items"></div>
<script>itemElements = $$('.item');</script>

73
login.php Normal file
View File

@ -0,0 +1,73 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* login.php - username / password entry
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
ob_start();
$fof_no_login = true;
include_once("fof-main.php");
fof_set_content_type();
if(isset($_POST["user_name"]) && isset($_POST["user_password"]))
{
if(fof_authenticate($_POST['user_name'], md5($_POST['user_password'] . $_POST['user_name'])))
{
Header("Location: .");
exit();
}
else
{
$failed = true;
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Feed on Feeds - Log on</title>
<style>
body
{
font-family: georgia;
font-size: 16px;
}
div
{
background: #eee;
border: 1px solid black;
width: 20em;
margin: 5em auto;
padding: 1.5em;
}
</style>
</head>
<body>
<div>
<form action="login.php" method="POST" style="display: inline">
<center><a href="http://feedonfeeds.com/" style="font-size: 20px; font-family: georgia;">Feed on Feeds</a></center><br>
User name:<br><input type=string name=user_name style='font-size: 16px'><br><br>
Password:<br><input type=password name=user_password style='font-size: 16px'><br><br>
<input type=submit value="Log on!" style='font-size: 16px; float: right;'><br>
<?php if($failed) echo "<br><center><font color=red><b>Incorrect user name or password</b></font></center>"; ?>
</form>
</div>
</body>
</html>

22
logout.php Normal file
View File

@ -0,0 +1,22 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* logout.php - kills user cookie, redirects to login page
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
ob_start();
include_once("fof-main.php");
fof_logout();
header("Location: login.php");
?>

48
opml.php Normal file
View File

@ -0,0 +1,48 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* ompl.php - exports subscription list as OPML
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
header("Content-Type: text/xml; charset=utf-8");
include_once("fof-main.php");
echo '<?xml version="1.0"?>';
?>
<opml version="1.1">
<head>
<title>Feed on Feeds Subscriptions</title>
</head>
<body>
<?php
$result = fof_db_get_subscriptions(fof_current_user());
while($row = fof_db_get_row($result))
{
$url = htmlspecialchars($row['feed_url']);
$title = htmlspecialchars($row['feed_title']);
$link = htmlspecialchars($row['feed_link']);
echo <<<HEYO
<outline type="rss"
text="$title"
title="$title"
htmlUrl="$link"
xmlUrl="$url"
/>
HEYO;
}
?>
</body>
</opml>

24
plugins/autotag.php Normal file
View File

@ -0,0 +1,24 @@
<?php
fof_add_tag_prefilter('fof_autotag', 'fof_autotag');
fof_add_pref('Automatically tag these keywords', 'plugin_autotag_tags');
function fof_autotag($link, $title, $content)
{
$tags = array();
$prefs = fof_prefs();
$autotag = $prefs['plugin_autotag_tags'];
if($autotag)
{
$shebang = strip_tags($title . " " . $content);
foreach(explode(" ", $autotag) as $tag)
if(preg_match("/\b" . preg_quote($tag) . "\b/i", $shebang))
$tags[] = $tag;
}
return $tags;
}
?>

123
plugins/balancetags.php Normal file
View File

@ -0,0 +1,123 @@
<?php
fof_add_item_filter('fof_balancetags');
/*
balanceTags
Balances Tags of string using a modified stack.
@param text Text to be balanced
@param force Forces balancing, ignoring the value of the option
@return Returns balanced text
@author Leonard Lin (leonard@acm.org)
@version v1.1
@date November 4, 2001
@license GPL v2.0
@notes
@changelog
--- Modified by Scott Reilly (coffee2code) 02 Aug 2004
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})#', '&lt;$1', $text);
while (preg_match("/<(\/?\w*)\s*([^>]*)>/",$text,$regex)) {
$newtext .= $tagqueue;
$i = strpos($text,$regex[0]);
$l = 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
// If self-closing or '', don't do anything.
if((substr($regex[2],-1) == '/') || ($tag == '')) {
}
// ElseIf it's a known single-entity tag but it doesn't close itself, do so
elseif ($tag == 'br' || $tag == 'img' || $tag == 'hr' || $tag == 'input') {
$regex[2] .= '/';
} else { // Push the tag onto the stack
// If the top of the stack is the same as the tag we want to push, close previous tag
if (($stacksize > 0) && ($tag != 'div') && ($tagstack[$stacksize - 1] == $tag)) {
$tagqueue = '</' . array_pop ($tagstack) . '>';
$stacksize--;
}
$stacksize = array_push ($tagstack, $tag);
}
// Attributes
$attributes = $regex[2];
if($attributes) {
$attributes = ' '.$attributes;
}
$tag = '<'.$tag.$attributes.'>';
//If already queuing a close tag, then put this tag on, too
if ($tagqueue) {
$tagqueue .= $tag;
$tag = '';
}
}
$newtext .= substr($text,0,$i) . $tag;
$text = substr($text,$i+$l);
}
// Clear Tag Queue
$newtext .= $tagqueue;
// Add Remaining text
$newtext .= $text;
// Empty Stack
while($x = array_pop($tagstack)) {
$newtext .= '</' . $x . '>'; // Add remaining tags to close
}
// WP fix for the bug with HTML comments
$newtext = str_replace("< !--","<!--",$newtext);
$newtext = str_replace("< !--","< !--",$newtext);
return $newtext;
}
?>

13
plugins/delicious.php Normal file
View File

@ -0,0 +1,13 @@
<?php
fof_add_item_widget('fof_delicious');
function fof_delicious($item)
{
$url = urlencode(html_entity_decode($item['item_link']));
$title = urlencode($item['item_title']);
return "<a href='http://del.icio.us/post?v=4;url=$url;title=$title'><img src='plugins/delicious.png' height=12 width=12 border=0 /></a> <a href='http://del.icio.us/post?v=4;url=$url;title=$title'>bookmark</a>";
}
?>

BIN
plugins/delicious.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

29
plugins/enclosures.php Normal file
View File

@ -0,0 +1,29 @@
<?php
fof_add_item_prefilter('fof_enclosures');
function fof_enclosures($item, $link, $title, $content)
{
if ($enclosure = $item->get_enclosure(0))
{
$html = '<br><br><a href="#" onclick="show_enclosure(event); return false;">show enclosure</a><div style="display: none" align="center" width="auto">';
$html .= '<p>' . $enclosure->embed(array(
'audio' => 'plugins/place_audio.png',
'video' => 'plugins/place_video.png',
'mediaplayer' => 'plugins/mediaplayer.swf',
'alt' => '<img src="plugins/mini_podcast.png" class="download" border="0" title="Download the Podcast (' . $enclosure->get_extension() . '; ' . $enclosure->get_size() . ' MB)" />',
'altclass' => 'download'
)) . '</p>';
$html .= '<i align="center">(' . $enclosure->get_type();
if ($enclosure->get_size())
{
$html .= '; ' . $enclosure->get_size() . ' MB';
}
$html .= ')</i>';
$html .= '</div>';
}
return array($link, $title, $content . $html);
}
?>

11
plugins/fixdivs.php Normal file
View File

@ -0,0 +1,11 @@
<?php
fof_add_item_filter('fof_fixdivs');
function fof_fixdivs($text)
{
$text = str_ireplace('<div"', '<div "', $text);
$text = str_ireplace('<div ...', '', $text);
return $text;
}
?>

BIN
plugins/mediaplayer.swf Normal file

Binary file not shown.

BIN
plugins/mini_podcast.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
plugins/place_audio.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

BIN
plugins/place_video.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

15
plugins/plain.php Normal file
View File

@ -0,0 +1,15 @@
<?php
fof_add_item_filter('fof_plain');
fof_add_pref('Strip (most) markup from items', 'plugin_plain_enable', 'boolean');
function fof_plain($text)
{
$prefs = fof_prefs();
$enable = $prefs['plugin_plain_enable'];
if(!$enable) return $text;
return strip_tags($text, "<a><b><i><blockquote>");
}
?>

BIN
plugins/share-off.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

BIN
plugins/share-on.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

20
plugins/sharing.php Normal file
View File

@ -0,0 +1,20 @@
<?php
fof_add_item_widget('fof_sharing');
function fof_sharing($item)
{
$prefs = fof_prefs();
$sharing = $prefs['sharing'];
if($sharing != "tagged") return false;
$tags = $item['tags'];
$id = $item['item_id'];
$shared = in_array("shared", $tags) ? true : false;
$shared_image = $shared ? "plugins/share-on.gif" : "plugins/share-off.gif";
$shared_link = $shared ? "javascript:remove_tag($id, 'shared')" : "javascript:add_tag($id, 'shared')";
$shared_text = $shared ? "shared" : "not shared";
return "<a href=\"$shared_link\"><img src=\"$shared_image\" width=\"12\" height=\"12\" border=\"0\"/></a> <a href=\"$shared_link\">$shared_text</a> ";
}
?>

21
plugins/wordpress.php Normal file
View File

@ -0,0 +1,21 @@
<?php
fof_add_item_widget('fof_wordpress');
fof_add_pref('WordPress URL', 'plugin_wordpressurl');
function fof_wordpress($item)
{
$prefs = fof_prefs();
$wordpress = $prefs['plugin_wordpressurl'];
if(!$wordpress) return false;
$url = urlencode(html_entity_decode($item['item_link']));
$title = urlencode($item['item_title']);
$text = urlencode('<blockquote>' . $item['item_content'] . '</blockquote>');
$link = "$wordpress/wp-admin/post-new.php?text=$text&popupurl=$url&popuptitle=$title";
return "<a href='$link'><img src='plugins/wordpress.png' height=12 width=12 border=0 /></a> <a href='$link'>blog it</a>";
}
?>

BIN
plugins/wordpress.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

345
prefs.php Normal file
View File

@ -0,0 +1,345 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* prefs.php - display and change preferences
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
$prefs =& FoF_Prefs::instance();
if(isset($_POST['adminprefs']))
{
$prefs->set('purge', $_POST['purge']);
$prefs->set('manualtimeout', $_POST['manualtimeout']);
$prefs->set('autotimeout', $_POST['autotimeout']);
$prefs->set('logging', $_POST['logging']);
$prefs->save();
$message .= ' Saved admin prefs.';
if($prefs->get('logging') && !@fopen("fof.log", 'a'))
{
$message .= ' Warning: could not write to log file!';
}
}
if(isset($_POST['tagfeed']))
{
$tags = $_POST['tag'];
$feed_id = $_POST['feed_id'];
$title = $_POST['title'];
foreach(explode(" ", $tags) as $tag)
{
fof_tag_feed(fof_current_user(), $feed_id, $tag);
$message .= " Tagged '$title' as $tag.";
}
}
if(isset($_GET['untagfeed']))
{
$feed_id = $_GET['untagfeed'];
$tags = $_GET['tag'];
$title = $_GET['title'];
foreach(explode(" ", $tags) as $tag)
{
fof_untag_feed(fof_current_user(), $feed_id, $tag);
$message .= " Dropped $tag from '$title'.";
}
}
if(isset($_POST['prefs']))
{
$prefs->set('favicons', isset($_POST['favicons']));
$prefs->set('keyboard', isset($_POST['keyboard']));
$prefs->set('tzoffset', intval($_POST['tzoffset']));
$prefs->set('howmany', intval($_POST['howmany']));
$prefs->set('order', $_POST['order']);
$prefs->set('sharing', $_POST['sharing']);
$prefs->set('sharedname', $_POST['sharedname']);
$prefs->set('sharedurl', $_POST['sharedurl']);
$prefs->save(fof_current_user());
if($_POST['password'] && ($_POST['password'] == $_POST['password2']))
{
fof_db_change_password($fof_user_name, $_POST['password']);
setcookie ( "user_password_hash", md5($_POST['password'] . $fof_user_name), time()+60*60*24*365*10 );
$message = "Updated password.";
}
else if($_POST['password'] || $_POST['password2'])
{
$message = "Passwords do not match!";
}
$message .= ' Saved prefs.';
}
if(isset($_POST['plugins']))
{
foreach(fof_get_plugin_prefs() as $plugin_pref)
{
$key = $plugin_pref[1];
$prefs->set($key, $_POST[$key]);
}
$plugins = array();
$dirlist = opendir(FOF_DIR . "/plugins");
while($file=readdir($dirlist))
{
if(ereg('\.php$',$file))
{
$plugins[] = substr($file, 0, -4);
}
}
closedir();
foreach($plugins as $plugin)
{
$prefs->set("plugin_" . $plugin, $_POST[$plugin] != "on");
}
$prefs->save(fof_current_user());
$message .= ' Saved plugin prefs.';
}
if(isset($_POST['changepassword']))
{
if($_POST['password'] != $_POST['password2'])
{
$message = "Passwords do not match!";
}
else
{
$username = $_POST['username'];
$password = $_POST['password'];
fof_db_change_password($username, $password);
$message = "Changed password for $username.";
}
}
if(isset($_POST['adduser']) && $_POST['username'] && $_POST['password'])
{
$username = $_POST['username'];
$password = $_POST['password'];
fof_db_add_user($username, $password);
$message = "User '$username' added.";
}
if(isset($_POST['deleteuser']) && $_POST['username'])
{
$username = $_POST['username'];
fof_db_delete_user($username);
$message = "User '$username' deleted.";
}
include("header.php");
?>
<?php if(isset($message)) { ?>
<br><font color="red"><?php echo $message ?></font><br>
<?php } ?>
<br><h1>Feed on Feeds - Preferences</h1>
<form method="post" action="prefs.php" style="border: 1px solid black; margin: 10px; padding: 10px;">
Default display order: <select name="order"><option value=desc>new to old</option><option value=asc <?php if($prefs->get('order') == "asc") echo "selected";?>>old to new</option></select><br><br>
Number of items in paged displays: <input type="string" name="howmany" value="<?php echo $prefs->get('howmany') ?>"><br><br>
Display custom feed favicons? <input type="checkbox" name="favicons" <?php if($prefs->get('favicons')) echo "checked=true";?> ><br><br>
Use keyboard shortcuts? <input type="checkbox" name="keyboard" <?php if($prefs->get('keyboard')) echo "checked=true";?> ><br><br>
Time offset in hours: <input size=3 type=string name=tzoffset value="<?php echo $prefs->get('tzoffset')?>"> (UTC time: <?php echo gmdate("Y-n-d g:ia") ?>, local time: <?php echo gmdate("Y-n-d g:ia", time() + $prefs->get("tzoffset")*60*60) ?>)<br><br>
<table border=0 cellspacing=0 cellpadding=2><tr><td>New password:</td><td><input type=password name=password> (leave blank to not change)</td></tr>
<tr><td>Repeat new password:</td><td><input type=password name=password2></td></tr></table>
<br>
Share
<select name="sharing">
<option value=no>no</option>
<option value=all <?php if($prefs->get('sharing') == "all") echo "selected";?>>all</option>
<option value=tagged <?php if($prefs->get('sharing') == "tagged") echo "selected";?>>tagged as "shared"</option>
</select>
items.
<?php if($prefs->get('sharing') != "no") echo " <small><i>(your shared page is <a href='./shared.php?user=$fof_user_id'>here</a>)</i></small>";?><br><br>
Name to be shown on shared page: <input type=string name=sharedname value="<?php echo $prefs->get('sharedname')?>"><br><br>
URL to be linked on shared page: <input type=string name=sharedurl value="<?php echo $prefs->get('sharedurl')?>">
<br><br>
<input type=submit name=prefs value="Save Preferences">
</form>
<br><h1>Feed on Feeds - Plugin Preferences</h1>
<form method="post" action="prefs.php" style="border: 1px solid black; margin: 10px; padding: 10px;">
<?php
$plugins = array();
$dirlist = opendir(FOF_DIR . "/plugins");
while($file=readdir($dirlist))
{
fof_log("considering " . $file);
if(ereg('\.php$',$file))
{
$plugins[] = substr($file, 0, -4);
}
}
closedir();
?>
<?php foreach($plugins as $plugin) { ?>
<input type=checkbox name=<?php echo $plugin ?> <?php if(!$prefs->get("plugin_" . $plugin)) echo "checked"; ?>> Enable plugin <tt><?php echo $plugin?></tt>?<br>
<?php } ?>
<br>
<?php foreach(fof_get_plugin_prefs() as $plugin_pref) { $name = $plugin_pref[0]; $key = $plugin_pref[1]; $type = $plugin_pref[2]; ?>
<?php echo $name ?>:
<?php if($type == "boolean") { ?>
<input name="<?php echo $key ?>" type="checkbox" <?php if($prefs->get($key)) echo "checked" ?>><br>
<?php } else { ?>
<input name="<?php echo $key ?>" value="<?php echo $prefs->get($key)?>"><br>
<?php } } ?>
<br>
<input type=submit name=plugins value="Save Plugin Preferences">
</form>
<br><h1>Feed on Feeds - Feeds and Tags</h1>
<div style="border: 1px solid black; margin: 10px; padding: 10px; font-size: 12px; font-family: verdana, arial;">
<table cellpadding=3 cellspacing=0>
<?php
foreach($feeds as $row)
{
$id = $row['feed_id'];
$url = $row['feed_url'];
$title = $row['feed_title'];
$link = $row['feed_link'];
$description = $row['feed_description'];
$age = $row['feed_age'];
$unread = $row['feed_unread'];
$starred = $row['feed_starred'];
$items = $row['feed_items'];
$agestr = $row['agestr'];
$agestrabbr = $row['agestrabbr'];
$lateststr = $row['lateststr'];
$lateststrabbr = $row['lateststrabbr'];
$tags = $row['tags'];
if(++$t % 2)
{
print "<tr class=\"odd-row\">";
}
else
{
print "<tr>";
}
if($row['feed_image'] && $prefs->get('favicons'))
{
print "<td><a href=\"$url\" title=\"feed\"><img src='" . $row['feed_image'] . "' width='16' height='16' border='0' /></a></td>";
}
else
{
print "<td><a href=\"$url\" title=\"feed\"><img src='image/feed-icon.png' width='16' height='16' border='0' /></a></td>";
}
print "<td><a href=\"$link\" title=\"home page\">$title</a></td>";
print "<td align=right>";
if($tags)
{
foreach($tags as $tag)
{
$utag = urlencode($tag);
$utitle = urlencode($title);
print "$tag <a href='prefs.php?untagfeed=$id&tag=$utag&title=$utitle'>[x]</a> ";
}
}
else
{
}
print "</td>";
$title = htmlspecialchars($title);
print "<td><form method=post action=prefs.php><input type=hidden name=title value=\"$title\"><input type=hidden name=feed_id value=$id><input type=string name=tag> <input type=submit name=tagfeed value='Tag Feed'> <small><i>(separate tags with spaces)</i></small></form></td></tr>";
}
?>
</table>
</div>
<?php if(fof_is_admin()) { ?>
<br><h1>Feed on Feeds - Admin Options</h1>
<form method="post" action="prefs.php" style="border: 1px solid black; margin: 10px; padding: 10px;">
Enable logging? <input type=checkbox name=logging <?php if($prefs->get('logging')) echo "checked" ?>><br><br>
Purge read items after <input size=4 type=string name=purge value="<?php echo $prefs->get('purge')?>"> days (leave blank to never purge)<br><br>
Allow automatic feed updates every <input size=4 type=string name=autotimeout value="<?php echo $prefs->get('autotimeout')?>"> minutes<br><br>
Allow manual feed updates every <input size=4 type=string name=manualtimeout value="<?php echo $prefs->get('manualtimeout')?>"> minutes<br><br>
<input type=submit name=adminprefs value="Save Options">
</form>
<br><h1>Add User</h1>
<form method="post" action="prefs.php" style="border: 1px solid black; margin: 10px; padding: 10px;">
Username: <input type=string name=username> Password: <input type=string name=password> <input type=submit name=adduser value="Add user">
</form>
<?php
$result = fof_db_query("select user_name from $FOF_USER_TABLE where user_id > 1");
while($row = fof_db_get_row($result))
{
$username = $row['user_name'];
$delete_options .= "<option value=$username>$username</option>";
}
if(isset($delete_options))
{
?>
<br><h1>Delete User</h1>
<form method="post" action="prefs.php" style="border: 1px solid black; margin: 10px; padding: 10px;" onsubmit="return confirm('Delete User - Are you sure?')">
<select name=username><?php echo $delete_options ?></select>
<input type=submit name=deleteuser value="Delete user"><br>
</form>
<br><h1>Change User's Password</h1>
<form method="post" action="prefs.php" style="border: 1px solid black; margin: 10px; padding: 10px;" onsubmit="return confirm('Change Password - Are you sure?')">
<table border=0 cellspacing=0 cellpadding=2>
<tr><td>Select user:</td><td><select name=username><?php echo $delete_options ?></select></td></tr>
<tr><td>New password:</td><td><input type=password name=password></td></tr>
<tr><td>Repeat new password:</td><td><input type=password name=password2></td></tr></table>
<input type=submit name=changepassword value="Change"><br>
</form>
<?php } ?>
<br>
<form method="get" action="uninstall.php" onsubmit="return confirm('Really? This will delete all the database tables!')">
<center><input type=submit name=uninstall value="Uninstall Feed on Feeds" style="background-color: #ff9999"></center>
</form>
<?php } ?>
<?php include("footer.php") ?>

4184
prototype/prototype.js vendored Normal file

File diff suppressed because it is too large Load Diff

26
set-prefs.php Normal file
View File

@ -0,0 +1,26 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* set-prefs.php - interface for changing prefs from javascript
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
$prefs =& FoF_Prefs::instance();
foreach($_POST as $k => $v)
{
$prefs->set($k, $v);
}
$prefs->save();
?>

231
shared.php Normal file
View File

@ -0,0 +1,231 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* shared.php - display shared items for a user
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
$fof_no_login = true;
include_once("fof-main.php");
include_once("fof-render.php");
$user = $_GET['user'];
if(!isset($user)) die;
$format = $_GET['format'];
$prefs = new FoF_Prefs($user);
$sharing = $prefs->get("sharing");
if($sharing == "no") die;
$name = $prefs->get("sharedname");
$url = $prefs->get("sharedurl");
$which = ($sharing == "all") ? "all" : "shared";
if(isset($_GET['which']))
{
$which = ($sharing == "all") ? $_GET['which'] : "shared " . $_GET['which'];
$extratitle = " items tagged " . $_GET['which'];
}
$feed = NULL;
if(isset($_GET['feed']))
{
$feed = $_GET['feed'];
$r = fof_db_get_feed_by_id($feed);
$extratitle .= " from <a href='" . $r['feed_link'] . "'>" . $r['feed_title'] . "</a>";
}
$result = fof_get_items($user, $feed, $which, NULL, 0, 100);
$shared_feed = htmlspecialchars("http://" . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'] . "?user=$user&format=atom");
$shared_link = htmlspecialchars("http://" . $_SERVER['SERVER_NAME'] . $_SERVER['PHP_SELF'] . "?user=$user");
if(isset($_GET['which']))
{
$shared_feed .= '&which=' . $_GET['which'];
$shared_link .= '&which=' . $_GET['which'];
}
if(isset($_GET['feed']))
{
$shared_feed .= '&feed=' . $_GET['feed'];
$shared_link .= '&feed=' . $_GET['feed'];
}
if($format == "atom")
{
header("Content-Type: application/atom+xml; charset=utf-8");
echo '<?xml version="1.0"?>';
?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Feed on Feeds - Shared Items<?php if($name) echo " from $name"; if($extratitle) echo " " . strip_tags($extratitle) ?></title>
<updated><?php echo gmdate('Y-m-d\TH:i:s\Z')?></updated>
<generator uri="http://feedonfeeds.com/">Feed on Feeds</generator>
<?php if($name) echo "<author><name>$name</name></author>"; ?>
<id><?php echo $shared_feed ?></id>
<link href="<?php echo $shared_feed ?>" rel="self" type="application/atom+xml"/>
<link href="<?php echo $shared_link ?>" rel="alternate"/>
<?php
foreach($result as $item)
{
$feed_link = htmlspecialchars($item['feed_link']);
$feed_url = htmlspecialchars($item['feed_url']);
$feed_title = htmlspecialchars($item['feed_title']);
$item_link = htmlspecialchars($item['item_link']);
$item_guid = $item['item_guid'];
if(!ereg("^[a-z0-9\.\+\-]+:", $item_guid))
{
$item_guid = $feed_link . '#' . $item_guid;
}
$item_guid = htmlspecialchars($item_guid);
$item_title = htmlspecialchars($item['item_title']);
$item_content = htmlspecialchars($item['item_content']);
$item_published = gmdate('Y-m-d\TH:i:s\Z', $item['item_published']);
$item_cached = gmdate('Y-m-d\TH:i:s\Z', $item['item_cached']);
$item_updated = gmdate('Y-m-d\TH:i:s\Z', $item['item_updated']);
if(!$item_title) $item_title = "[no title]";
?>
<entry>
<id><?php echo $item_guid ?></id>
<link href="<?php echo $item_link ?>" rel="alternate" type="text/html"/>
<title type="html"><?php echo $item_title ?></title>
<summary type="html"><?php echo $item_content ?></summary>
<updated><?php echo $item_updated ?></updated>
<source>
<id><?php echo $feed_link ?></id>
<link href="<?php echo $feed_link ?>" rel="alternate" type="text/html"/>
<link href="<?php echo $feed_url ?>" rel="self" type="application/atom+xml"/>
<title><?php echo $feed_title ?></title>
</source>
</entry>
<?php
}
echo '</feed>';
}
else
{
header("Content-Type: text/html; charset=utf-8");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="alternate" href="<?php echo $shared_feed?>" type="application/atom+xml"/>
<title>Feed on Feeds - Shared Items<?php if($name) echo " from $name"; if($extratitle) echo " " . strip_tags($extratitle) ?></title>
<link rel="stylesheet" href="fof.css" media="screen" />
<style>
.box
{
font-family: georgia;
background: #eee;
border: 1px solid black;
width: 30em;
margin: 10px auto 20px;
padding: 1em;
text-align: center;
}
</style>
</head>
<body>
<h1 class="box"><a href="http://feedonfeeds.com/">Feed on Feeds</a> - Shared Items
<?php if($name) echo " from ";
if($url) echo "<a href='$url'>";
if($name) echo "$name";
if($url) echo "</a>";
if($extratitle) echo "<br><i>$extratitle</i>" ?>
</h1>
<div id="items">
<?php
$first = true;
foreach($result as $item)
{
$item_id = $item['item_id'];
print '<div class="item shown" id="i' . $item_id . '">';
$feed_link = $item['feed_link'];
$feed_title = $item['feed_title'];
$feed_image = $item['feed_image'];
$feed_description = $item['feed_description'];
$item_link = $item['item_link'];
$item_id = $item['item_id'];
$item_title = $item['item_title'];
$item_content = $item['item_content'];
$item_read = $item['item_read'];
$item_published = gmdate("Y-n-d g:ia", $item['item_published'] + $offset*60*60);
$item_cached = gmdate("Y-n-d g:ia", $item['item_cached'] + $offset*60*60);
$item_updated = gmdate("Y-n-d g:ia", $item['item_updated'] + $offset*60*60);
if(!$item_title) $item_title = "[no title]";
?>
<div class="header">
<h1>
<a href="<?php echo $item_link ?>">
<?php echo $item_title ?>
</a>
</h1>
<span class='dash'> - </span>
<h2>
<a href="<?php echo $feed_link ?>" title='<?php echo $feed_description ?>'><img src="<?php echo $feed_image ?>" height="16" width="16" border="0" /></a>
<a href="<?php echo $feed_link ?>" title='<?php echo $feed_description ?>'><?php echo $feed_title ?></a>
</h2>
<span class="meta">on <?php echo $item_published ?> GMT</span>
</div>
<div class="body"><?php echo $item_content ?></div>
<div class="clearer"></div>
</div>
<?php
}
if(count($result) == 0)
{
echo "<p><i>No shared items.</i></p>";
}
?>
</div></body></html>
<?php } ?>

309
sidebar.php Normal file
View File

@ -0,0 +1,309 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* sidebar.php - sidebar for all pages
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
fof_set_content_type();
?>
<img id="throbber" src="image/throbber.gif" align="left" style="position: fixed; left: 0; top: 0; display: none;">
<center id="welcome">Welcome <b><?php echo $fof_user_name ?></b>! <a href="prefs.php">prefs</a> | <a href="logout.php">log out</a> | <a href="http://feedonfeeds.com/">about</a></center>
<br>
<center><a href="add.php"><b>Add Feeds</b></a> / <a href="update.php"><b>Update Feeds</b></a></center>
<ul id="nav">
<?php
$order = $fof_prefs_obj->get('feed_order');
$direction = $fof_prefs_obj->get('feed_direction');
if(!isset($_GET['what']))
{
$what = "unread";
}
else
{
$what = $_GET['what'];
}
$when = $_GET['when'];
$search = $_GET['search'];
echo "<script>what='$what'; when='$when';</script>";
$feeds = fof_get_feeds(fof_current_user(), $order, $direction);
foreach($feeds as $row)
{
$n++;
$unread += $row['feed_unread'];
$starred += $row['feed_starred'];
$total += $row['feed_items'];
}
if($unread)
{
echo "<script>document.title = 'Feed on Feeds ($unread)';</script>";
}
else
{
echo "<script>document.title = 'Feed on Feeds';</script>";
}
echo "<script>starred = $starred;</script>";
?>
<li <?php if($what == "unread") echo "style='background: #ddd'" ?> ><a href=".?what=unread"><font color=red><b>Unread <?php if($unread) echo "($unread)" ?></b></font></a></li>
<li <?php if($what == "star") echo "style='background: #ddd'" ?> ><a href=".?what=star"><img src="image/star-on.gif" border="0" height="10" width="10"> Starred <span id="starredcount"><?php if($starred) echo "($starred)" ?></span></a></li>
<li <?php if($what == "all" && isset($when)) echo "style='background: #ddd'" ?> ><a href=".?what=all&when=today">&lt; Today</a></li>
<li <?php if($what == "all" && !isset($when)) echo "style='background: #ddd'" ?> ><a href=".?what=all&how=paged">All Items <?php if($total) echo "($total)" ?></a></li>
<li <?php if(isset($search)) echo "style='background: #ddd'" ?> ><a href="javascript:Element.toggle('search'); Field.focus('searchfield');void(0);">Search</a>
<form action="." id="search" <?php if(!isset($search)) echo 'style="display: none"' ?>>
<input id="searchfield" name="search" value="<?php echo $search?>">
<?php
if($what == "unread")
echo "<input type='hidden' name='what' value='all'>";
else
echo "<input type='hidden' name='what' value='$what'>";
?>
<?php if(isset($_GET['when'])) echo "<input type='hidden' name='what' value='${_GET['when']}'>" ?>
</form>
</li>
</ul>
<?php
$tags = fof_get_tags(fof_current_user());
$n = 0;
foreach($tags as $tag)
{
$tag_id = $tag['tag_id'];
if($tag_id == 1 || $tag_id == 2) continue;
$n++;
}
if($n)
{
?>
<div id="tags">
<table cellspacing="0" cellpadding="1" border="0" id="taglist">
<tr class="heading">
<td><span class="unread">#</span></td><td>tag name</td><td>untag all items</td>
</tr>
<?php
foreach($tags as $tag)
{
$tag_name = $tag['tag_name'];
$tag_id = $tag['tag_id'];
$count = $tag['count'];
$unread = $tag['unread'];
if($tag_id == 1 || $tag_id == 2) continue;
if(++$t % 2)
{
print "<tr class=\"odd-row\">";
}
else
{
print "<tr>";
}
print "<td>";
if($unread) print "<a class='unread' href='.?what=$tag_name+unread'>$unread</a>/";
print "<a href='.?what=$tag_name'>$count</a></td>";
print "<td><b><a href='.?what=$tag_name'>$tag_name</a></b></td>";
print "<td><a href=\"#\" title=\"untag all items\" onclick=\"if(confirm('Untag all [$tag_name] items --are you SURE?')) { delete_tag('$tag_name'); return false; } else { return false; }\">[x]</a></td>";
print "</tr>";
}
?>
</table>
</div>
<br>
<?php } ?>
<div id="feeds">
<div id="feedlist">
<table cellspacing="0" cellpadding="1" border="0">
<tr class="heading">
<?php
$title["feed_age"] = "sort by last update time";
$title["max_date"] = "sort by last new item";
$title["feed_unread"] = "sort by number of unread items";
$title["feed_url"] = "sort by feed URL";
$title["feed_title"] = "sort by feed title";
$name["feed_age"] = "age";
$name["max_date"] = "latest";
$name["feed_unread"] = "#";
$name["feed_url"] = "feed";
$name["feed_title"] = "title";
foreach (array("feed_age", "max_date", "feed_unread", "feed_url", "feed_title") as $col)
{
if($col == $order)
{
$url = "return change_feed_order('$col', '" . ($direction == "asc" ? "desc" : "asc") . "')";
}
else
{
$url = "return change_feed_order('$col', 'asc')";
}
echo "<td><nobr><a href='#' title='$title[$col]' onclick=\"$url\">";
if($col == "feed_unread")
{
echo "<span class=\"unread\">#</span>";
}
else
{
echo $name[$col];
}
if($col == $order)
{
echo ($direction == "asc") ? "&darr;" : "&uarr;";
}
echo "</a></nobr></td>";
}
?>
<td></td>
</tr>
<?php
foreach($feeds as $row)
{
$id = $row['feed_id'];
$url = $row['feed_url'];
$title = $row['feed_title'];
$link = $row['feed_link'];
$description = $row['feed_description'];
$age = $row['feed_age'];
$unread = $row['feed_unread'];
$starred = $row['feed_starred'];
$items = $row['feed_items'];
$agestr = $row['agestr'];
$agestrabbr = $row['agestrabbr'];
$lateststr = $row['lateststr'];
$lateststrabbr = $row['lateststrabbr'];
if(++$t % 2)
{
print "<tr class=\"odd-row\">";
}
else
{
print "<tr>";
}
$u = ".?feed=$id";
$u2 = ".?feed=$id&amp;what=all&amp;how=paged";
print "<td><span title=\"$agestr\" id=\"${id}-agestr\">$agestrabbr</span></td>";
print "<td><span title=\"$lateststr\" id=\"${id}-lateststr\">$lateststrabbr</span></td>";
print "<td class=\"nowrap\" id=\"${id}-items\">";
if($unread)
{
print "<a class=\"unread\" title=\"new items\" href=\"$u\">$unread</a>/";
}
print "<a href=\"$u2\" title=\"all items\">$items</a>";
print "</td>";
print "<td align='center'>";
if($row['feed_image'] && $fof_prefs_obj->get('favicons'))
{
print "<a href=\"$url\" title=\"feed\"><img src='" . $row['feed_image'] . "' width='16' height='16' border='0' /></a>";
}
else
{
print "<a href=\"$url\" title=\"feed\"><img src='image/feed-icon.png' width='16' height='16' border='0' /></a>";
}
print "</td>";
print "<td>";
print "<a href=\"$link\" title=\"home page\"><b>$title</b></a></td>";
print "<td><nobr>";
print "<a href=\"update.php?feed=$id\" title=\"update\">u</a>";
$stitle = htmlspecialchars(addslashes($title));
print " <a href=\"#\" title=\"mark all read\" onclick=\"if(confirm('Mark all [$stitle] items as read --are you SURE?')) { mark_feed_read($id); return false; } else { return false; }\">m</a>";
print " <a href=\"delete.php?feed=$id\" title=\"delete\" onclick=\"return confirm('Unsubscribe [$stitle] --are you SURE?')\">d</a>";
print "</nobr></td>";
print "</tr>";
}
?>
</table>
</div>
</div>
<?php
$order = $_GET['order'];
$direction = $_GET['direction'];
if(!isset($order))
{
$order = "title";
}
if(!isset($direction))
{
$direction = "asc";
}
?>

10781
simplepie/simplepie.inc Normal file

File diff suppressed because one or more lines are too long

15
simplepie/simplepie.patch Normal file
View File

@ -0,0 +1,15 @@
Index: simplepie.inc
===================================================================
--- simplepie.inc (revision 810)
+++ simplepie.inc (working copy)
@@ -6495,6 +6495,10 @@
curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
}
+
+ // added by FoF to enable https and digest authentication
+ curl_setopt($fp, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($fp, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
$this->headers = curl_exec($fp);
if (curl_errno($fp) == 23 || curl_errno($fp) == 61)

87
uninstall.php Normal file
View File

@ -0,0 +1,87 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* uninstall.php - if confirmed, drops FoF's tables
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
fof_set_content_type();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>feed on feeds - uninstallation</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="fof.css" media="screen" />
<script src="fof.js" type="text/javascript"></script>
<meta name="ROBOTS" content="NOINDEX, NOFOLLOW" />
</head>
<body id="panel-page">
<?php
if($_GET['really'])
{
$query = <<<EOQ
DROP TABLE `$FOF_FEED_TABLE`;
EOQ;
fof_db_query($query);
$query = <<<EOQ
DROP TABLE `$FOF_ITEM_TABLE`;
EOQ;
fof_db_query($query);
$query = <<<EOQ
DROP TABLE `$FOF_TAG_TABLE`;
EOQ;
fof_db_query($query);
$query = <<<EOQ
DROP TABLE `$FOF_ITEM_TAG_TABLE`;
EOQ;
fof_db_query($query);
$query = <<<EOQ
DROP TABLE `$FOF_SUBSCRIPTION_TABLE`;
EOQ;
fof_db_query($query);
$query = <<<EOQ
DROP TABLE `$FOF_USER_TABLE`;
EOQ;
fof_db_query($query);
echo 'Done. Now just delete this entire directory and we\'ll forget this ever happened.';
}
else
{
?>
<script>
if(confirm('This is your last chance. Do you really want to uninstall Feed on Feeds?'))
{
document.location = './uninstall.php?really=really';
}
</script>
<a href="."><b>phew!</b></a>
</body></html>
<?php } ?>

60
update-quiet.php Normal file
View File

@ -0,0 +1,60 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* update-quiet.php - updates all feeds without producing output
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
set_time_limit(60*10);
ob_start();
$fof_no_login = true;
$fof_user_id = 1;
include_once("fof-main.php");
$p =& FoF_Prefs::instance();
$fof_admin_prefs = $p->prefs;
fof_log("=== update started, timeout = $fof_admin_prefs[autotimeout], purge = $fof_admin_prefs[purge] ===", "update");
$result = fof_db_get_feeds();
$feeds = array();
while($feed = fof_db_get_row($result))
{
if((time() - $feed["feed_cache_date"]) > ($fof_admin_prefs["autotimeout"] * 60))
{
$feeds[] = $feed;
}
else
{
fof_log("skipping $feed[feed_url]", "update");
}
}
$feeds = fof_multi_sort($feeds, 'feed_cache_attempt_date', false);
foreach($feeds as $feed)
{
$id = $feed['feed_id'];
fof_log("updating $feed[feed_url]", "update");
fof_update_feed($id);
}
fof_log("optimizing database", "update");
fof_db_optimize();
fof_log("=== update complete ===", "update");
ob_end_clean();
?>

35
update-single.php Normal file
View File

@ -0,0 +1,35 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* update-single.php - updates a single feed
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
$feed = $_GET['feed'];
list ($count, $error) = fof_update_feed($feed);
if($count)
{
print "<b><font color=red>$count new items</font></b>";
}
if($error)
{
print " $error <br>";
}
else
{
print " Done.<br>";
}
?>

73
update.php Normal file
View File

@ -0,0 +1,73 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* update.php - updates feeds with feedback
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include("header.php");
print("<br>");
$feed = $_GET['feed'];
$feeds = array();
$p =& FoF_Prefs::instance();
$admin_prefs = $p->admin_prefs;
if($feed)
{
$feed = fof_db_get_feed_by_id($feed);
$feeds[] = $feed;
}
else
{
if($fof_user_id == 1)
{
$result = fof_db_get_feeds();
}
else
{
$result = fof_db_get_subscriptions(fof_current_user());
}
while($feed = fof_db_get_row($result))
{
if((time() - $feed["feed_cache_date"]) < ($admin_prefs["manualtimeout"] * 60))
{
$title = $feed['feed_title'];
list($timestamp, ) = fof_nice_time_stamp($feed['feed_cache_date']);
print "$title was just updated $timestamp!<br>";
}
else
{
$feeds[] = $feed;
}
}
}
$feeds = fof_multi_sort($feeds, 'feed_cache_attempt_date', false);
print("<script>\nwindow.onload = ajaxupdate;\nfeedslist = [");
foreach($feeds as $feed)
{
$title = $feed['feed_title'];
$id = $feed['feed_id'];
$feedjson[] = "{'id': $id, 'title': '" . addslashes($title) . "'}";
}
print(join($feedjson, ", "));
print("];\n</script>");
include("footer.php");
?>

53
view-action.php Normal file
View File

@ -0,0 +1,53 @@
<?php
/*
* This file is part of FEED ON FEEDS - http://feedonfeeds.com/
*
* view-action.php - marks selected items as read (or unread)
*
*
* Copyright (C) 2004-2007 Stephen Minutillo
* steve@minutillo.com - http://minutillo.com/steve/
*
* Distributed under the GPL - see LICENSE
*
*/
include_once("fof-main.php");
while (list ($key, $val) = each ($_POST))
{
$first = false;
if($val == "checked")
{
$key = substr($key, 1);
$items[] = $key;
}
}
if($_REQUEST['deltag'])
{
fof_untag(fof_current_user(), $_REQUEST['deltag']);
}
else if($_POST['feed'])
{
fof_db_mark_feed_read(fof_current_user(), $_POST['feed']);
}
else
{
if($items)
{
if($_POST['action'] == 'read')
{
fof_db_mark_read(fof_current_user(), $items);
}
if($_POST['action'] == 'unread')
{
fof_db_mark_unread(fof_current_user(), $items);
}
}
header("Location: " . urldecode($_POST['return']));
}
?>