populate($updatePrivateAlso, $cid);
}
// Script timeout: ten seconds per feed should be a good upper limit
@set_time_limit(0);
@ini_set('max_execution_time', (10 * count($this->chans) + 300));
}
function populate($updatePrivateAlso = false, $cid) {
$cid = (int)$cid;
$sql = "select c.id, c.url, c.title from ".getTable("channels") . " c "
. " inner join " . getTable('folders') . " f on f.id = c.parent "
. " where (c.mode & ".RSS_MODE_DELETED_STATE.")=0 ";
if (hidePrivate() && !$updatePrivateAlso) {
$sql .= " and (mode & ".RSS_MODE_PRIVATE_STATE.")=0 ";
}
if(DEFAULT_CID != $cid) {
$sql .= " and c.id = " . $cid . " ";
} else {
if (getConfig('rss.config.absoluteordering')) {
$sql .= " order by f.position asc, c.position asc";
} else {
$sql .= " order by f.name, c.title asc";
}
}
$res = rss_query($sql);
while (list ($cid, $url, $title) = rss_fetch_row($res)) {
$this->chans[] = array ($cid, $url, $title);
}
}
function cleanUp($newIds, $ignorePrivate = false) {
if (!hidePrivate() || $ignorePrivate) {
if (count($newIds) > 0 && getConfig('rss.config.markreadonupdate')) {
rss_query("update ".getTable("item")." set unread = unread & "
.SET_MODE_READ_STATE." where (unread & ".RSS_MODE_UNREAD_STATE.")!=0 "
." and id not in (".implode(",", $newIds).")");
}
}
setProperty('__meta__','meta.lastupdate','misc',time());
if (count($newIds) > 0) {
rss_invalidate_cache();
}
rss_plugin_hook('rss.plugins.updates.after', null);
}
function magpieError($error) {
if (is_numeric($error) && ($error & MAGPIE_FEED_ORIGIN_CACHE)) {
if ($error & MAGPIE_FEED_ORIGIN_HTTP_304) {
$label = __('OK (304 Not modified)');
$cls = ERROR_NOERROR;
}
elseif ($error & MAGPIE_FEED_ORIGIN_HTTP_TIMEOUT) {
$label = __('HTTP Timeout (Local cache)');
$cls = ERROR_ERROR;
}
elseif ($error & MAGPIE_FEED_ORIGIN_NOT_FETCHED) {
$label = __('OK (Local cache)');
$cls = ERROR_NOERROR;
}
elseif ($error & MAGPIE_FEED_ORIGIN_HTTP_404) {
$label = __('404 Not Found (Local cache)');
$cls = ERROR_ERROR;
}
elseif ($error & MAGPIE_FEED_ORIGIN_HTTP_403) {
$label = __('403 Forbidden (Local cache)');
$cls = ERROR_ERROR;
}
else {
$label = $error;
$cls = ERROR_ERROR;
}
}
elseif ($error & MAGPIE_FEED_ORIGIN_HTTP_200) {
$label = __('OK (HTTP 200)');
$cls = ERROR_NOERROR;
}
else {
if (is_numeric($error)) {
$label = __('ERROR') ." $error";
$cls = ERROR_ERROR;
} else {
// shoud contain MagpieError at this point
$label = $error;
$cls = ERROR_ERROR;
}
}
return array( $label, $cls);
}
}
/**
* HTTP Server Push update
*/
class HTTPServerPushUpdate extends Update {
function HTTPServerPushUpdate($cid) {
parent::Update($doPopulate = true, $updatePrivateAlso = false, $cid);
$GLOBALS['rss']->header->appendHeader("Connection: close");
$GLOBALS['rss']->header->appendHeader("Content-type: multipart/x-mixed-replace;boundary=\"".PUSH_BOUNDARY."\"");
$GLOBALS['rss']->header->options |= HDR_NO_OUPUTBUFFERING;
rss_set_hook('rss.plugins.bodystart', "pushHeaderCallBack");
rss_set_hook('rss.plugins.bodyend', "pushFooterCallBack");
ob_implicit_flush();
}
function render() {
$newIds = array ();
echo
"
".sprintf(__('Updating %d Feeds...'), count($this -> chans))."
\n"
."\n"
."\n"
."| ".__('Feed')." | \n"
."".__('Status')." | \n"
."".__('New Items')." | \n"
."
";
foreach ($this->chans as $chan) {
list ($cid, $url, $title) = $chan;
echo "\n";
echo "| $title | \n";
flush();
$ret = update($cid);
if (is_array($ret)) {
list ($error, $unreadIds) = $ret;
$newIds = array_merge($newIds, $unreadIds);
} else {
$error = 0;
$unreadIds = array ();
}
$unread = count($unreadIds);
list($label,$cls) = parent::magpieError($error);
if ($cls == ERROR_ERROR && !defined("UPDATE_ERROR")) {
define("UPDATE_ERROR", true);
}
echo "$label | \n";
echo "". ($unread > 0 ? $unread : NO_NEW_ITEMS)." | \n";
echo "
\n";
flush();
}
echo "
\n";
echo "Redirecting...
\n";
flush();
// Sleep two seconds
sleep(2);
parent::cleanUp($newIds);
}
}
/**
* AJAXUpdate updates feeds via AJAX. It's a bit more server-intesive
* than HTTP Server Push
*/
class AJAXUpdate extends Update {
function AJAXUpdate($cid) {
parent::Update($doPopulate = true, $updatePrivateAlso = false, $cid);
$GLOBALS['rss']->header->extraHTML .= "\n";
}
function render() {
echo "". sprintf(__('Updating %d Feeds...'),count($this -> chans)) ."
\n";
echo "\n"
."\n"
."| ".__('Feed')." | \n"
."".__('Status')." | \n"
."".__('New Items')." | \n"
."
\n";
foreach ($this->chans as $chan) {
list ($cid, $url, $title) = $chan;
echo "\n";
echo "| $title | \n";
echo " | \n";
echo " | \n";
echo "
\n";
}
echo "
\n";
echo "\n";
}
}
class CommandLineUpdate extends Update {
function CommandLineUpdate($cid) {
parent::Update($doPopulate = true, $updatePrivateAlso = true, $cid);
}
function render() {
$newIds = array();
foreach ($this->chans as $chan) {
list ($cid, $url, $title) = $chan;
echo "$title ...\t";
flush();
$ret = update($cid);
if (is_array($ret)) {
list ($error, $unreadIds) = $ret;
$newIds = array_merge($newIds, $unreadIds);
} else {
$error = 0;
$unreadIds = array ();
}
$unread = count($unreadIds);
list($label,$cls) = parent::magpieError($error);
echo "\n$label, $unread " . __('New Items') . "\n\n";
flush();
}
parent::cleanUp($newIds, $ignorePrivate = true);
}
}
class MobileUpdate extends Update {
function MobileUpdate($cid) {
parent::Update($doPopulate = true, $updatePrivateAlso = false, $cid);
}
function render() {
$newIds = array();
foreach ($this->chans as $chan) {
list ($cid, $url, $title) = $chan;
echo "$title ...\t";
flush();
$ret = update($cid);
if (is_array($ret)) {
list ($error, $unreadIds) = $ret;
$newIds = array_merge($newIds, $unreadIds);
} else {
$error = 0;
$unreadIds = array ();
}
$unread = count($unreadIds);
list($label,$cls) = parent::magpieError($error);
echo "\n$label, $unread " . __('New Items') . "
";
flush();
}
}
}
/**
* CommandLineUpdateNews updates the feeds and displays only feeds with
* errors or new items.
*/
class CommandLineUpdateNews extends CommandLineUpdate {
function render() {
$newIds = array();
foreach ($this->chans as $chan) {
list ($cid, $url, $title) = $chan;
$ret = update($cid);
if (is_array($ret)) {
list ($error, $unreadIds) = $ret;
$newIds = array_merge($newIds, $unreadIds);
} else {
$error = 0;
$unreadIds = array();
}
$unread = count($unreadIds);
list($label, $cls) = parent::magpieError($error);
if (($cls != ERROR_NOERROR) || ($unread > 0)) {
echo "$title ...\t";
flush();
echo "\n$label, $unread " . __('New Items') . "\n\n";
flush();
}
}
if (!hidePrivate()) {
parent::cleanUp($newIds);
}
}
}
/**
* SilentUpdate updates the feeds silently for those lame
* browsers out there that do not support HTTP Server Push
* or AJAX
*/
class SilentUpdate extends Update {
function SilentUpdate($cid) {
parent::Update($doPopulate = false, $updatePrivateAlso = false, $cid);
}
function render() {
$newIds = array();
$ret = update("");
if (is_array($ret)) {
$newIds = $ret[1];
}
parent::cleanUp($newIds);
if (!array_key_exists('silent', $_GET)) {
rss_redirect();
}
}
}
function pushHeaderCallBack() {
echo "WARNING: YOUR BROWSER DOESN'T SUPPORT THIS SERVER-PUSH TECHNOLOGY.";
echo "\n".PUSH_BOUNDARY."\n";
echo "Content-Type: text/html\n\n";
flush();
}
function pushFooterCallBack() {
if (defined("UPDATE_ERROR") && UPDATE_ERROR) {
sleep(10);
}
echo "\n".PUSH_BOUNDARY."\n";
echo "Content-Type: text/html\n\n"
."\n"
."\n"."\n"."Redirecting...\n"
."\n"
."\n"."