". __('Feeds:') ."\n"; echo "
\n"; echo "
\n"; echo "

\n"; echo "\n"; echo "\n"; echo "\n"; echo rss_toolkit_folders_combo('add_channel_to_folder'); echo "\n"; echo "\n"; echo "\n"; echo "

\n"; echo "

".__('(Enter either the URL of an RSS feed or of a Website whose feed you wish to subscribe to)')."

"; echo "
\n\n"; // bookmarklet $b_url = guessTransportProto() . $_SERVER["HTTP_HOST"] . getPath() . "admin/index.php"; $b_url .= "?domain=feeds&add_channel_to_folder=0&action=Add&new_channel="; $bookmarklet = "javascript:void(document.location = " ."('$b_url'.concat(escape(document.location).replace(/\s/,'%2520'))))"; echo "

" . __('Subscription bookmarklet [?]:') . " ".__('Subscribe in Gregarius!')."

\n"; // feed handler - similar to bookmarklet, but with %s $feedhandler_url = "javascript:navigator.registerContentHandler(\'application/vnd.mozilla.maybe.feed\',\'$b_url%s\',\'Gregarius\');"; echo "\n"; // feeds echo "\n"; echo "
\n"; echo "\n" ."\n" ."\t\n" ."\t\n" ."\t\n" ."\t\n" ."\t\n" ."\t\n"; if (getConfig('rss.config.absoluteordering')) { echo "\t\n"; } echo "\t\n" ."\n"; $sql = "select " ." c.id, c.title, c.url, c.siteurl, d.name, c.descr, c.parent, c.icon, c.mode, c.daterefreshed " ." from " .getTable("channels") ." c " ." inner join " . getTable("folders") ." d " ." on d.id = c.parent "; if (getConfig('rss.config.absoluteordering')) { $sql .=" order by d.position asc, c.position asc"; } else { $sql .=" order by d.name asc, c.title asc"; } $res = rss_query($sql); $cntr = 0; while (list($id, $title, $url, $siteurl, $parent, $descr, $pid, $icon, $mode, $daterefreshed) = rss_fetch_row($res)) { if (getConfig('rss.output.usemodrewrite')) { $outUrl = getPath() . preg_replace("/[^A-Za-z0-9\.]/","_","$title") ."/"; } else { $outUrl = getPath() . "feed.php?channel=$id"; } $parentLabel = $parent == ''? __('Root'):$parent; $class_ = (($cntr++ % 2 == 0)?"even":"odd"); // get feed's tags $tags = ""; $sql2 = "select t.id, t.tag from " . getTable('tag') . " t " . "inner join " . getTable('metatag') . " m " . " on m.tid = t.id " . "where m.ttype = 'channel' and m.fid = $id"; $res2 = rss_query($sql2); while(list ($id_, $name_) = rss_fetch_row($res2)) { if (getConfig('rss.output.usemodrewrite')) { $tags .= "$name_ "; } else { $tags .= "$name_ "; } } if(NULL == $daterefreshed) { $dead = true; } else { $dead = (time() - strtotime($daterefreshed) > getConfig('rss.config.deadthreshhold')*60*60 ? true : false); } $fmode = array(); if ($mode & RSS_MODE_PRIVATE_STATE) { $fmode[] = "P"; } if ($mode & RSS_MODE_DELETED_STATE) { $fmode[] = "D"; $dead = false; } $slabel = count($fmode)?implode(", ",$fmode):" "; if ($icon && substr($icon,0,5) == 'blob:') { $icon = getPath() . "extlib/favicon.php?url=" .rss_real_escape_string(substr($icon,5)); } echo "\n" ."\t\n" ."\t\n" ."\t\n" ."\t\n" ."\t\n" ."\t\n"; if (getConfig('rss.config.absoluteordering')) { echo "\t\n"; } echo "\t\n" ."\n"; } echo "
". __('Title') ."". __('Folder') ."". __('Description') ."". __('Categories')."". __('Flags')."".__('Move')."". __('Action') ."
" .((getConfig('rss.output.showfavicons') && $icon != "")? "\"\"":"") ."" ."".preg_replace('/ /',' ',$parentLabel)."$descr$tags$slabel". __('↑') ." - ".__('↓') ."" . __('edit') ."|" . __('delete') ."
\n"; echo "
\n" ."Selected...\n" ."

\n" ."\n" .rss_toolkit_folders_combo('me_folder',null); echo "\n" ." " ."\n" ."\n" ."\n" ."\n" ."\n" ."\n" ." " ."\n" ."\n" ."\n" ."\n" ."\n" ."

\n" ."
\n"; echo "
\n\n\n"; } /** * Performs all the feed-related admin actions */ function channel_admin() { // Fix for #16: Admin (et al.) should not rely on l10n labels for actions: // Look for a meta-action first, which should be the (untranslated) *name* of // the (translated) action constant. // Fixme: should replace 'action's with a constant if (array_key_exists(CST_ADMIN_METAACTION,$_REQUEST)) { $__action__ = $_REQUEST[CST_ADMIN_METAACTION]; } elseif (array_key_exists('action',$_REQUEST)) { $__action__ = $_REQUEST['action']; } else { $__action__ = ""; } $ret__ = CST_ADMIN_DOMAIN_NONE; switch ($__action__) { case __('Add'): case 'ACT_ADMIN_ADD': case 'Add': $label = trim(sanitize($_REQUEST['new_channel'], RSS_SANITIZER_URL)); $fid = trim(sanitize($_REQUEST['add_channel_to_folder'], RSS_SANITIZER_NUMERIC)); list($flabel) = rss_fetch_row(rss_query( "select name from " . getTable('folders') . " where id=$fid")); // handle "feed:" urls if (substr($label, 0,5) == 'feed:') { if (substr($label, 0, 11 ) == "feed://http") { $label = substr($label,5); } else { // handle feed://example.com/rss.xml urls $label = "http:" . substr($label,5); } } if ($label != 'http://' && substr($label, 0,4) == "http") { $tags = @$_REQUEST['channel_tags']; $ret = add_channel($label,$fid,null,null,$tags); //var_dump($ret); if (is_array($ret) && $ret[0] > -1) { update($ret[0]); rss_invalidate_cache(); // feedback $newCid = $ret[0]; rss_error(sprintf( __('Adding %s to %s... '), htmlentities($label),"/$flabel") . __('OK') . " [" . __('edit') ."]", RSS_ERROR_ERROR,true); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; } elseif (is_array($ret) && $ret[0] > -2) { // okay, something went wrong, maybe thats a html url after all? // let's try and see if we can extract some feeds $feeds = extractFeeds($label); if (!is_array($feeds) || sizeof($feeds) == 0) { rss_error($ret[1], RSS_ERROR_ERROR,true); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; } else { //one single feed in the html doc, add that if (is_array($feeds) && sizeof($feeds) == 1 && array_key_exists('href',$feeds[0])) { $ret = add_channel($feeds[0]['href'],$fid); if (is_array($ret) && $ret[0] > -1) { update($ret[0]); rss_invalidate_cache(); // feedback $newCid = $ret[0]; rss_error(sprintf( __('Adding %s to %s... '), htmlentities($label),"/$flabel") . __('OK') . " [" . __('edit') ."]", RSS_ERROR_ERROR,true); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; } else { // failure rss_error($ret[1], RSS_ERROR_ERROR,true); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; } } else { // multiple feeds in the channel echo "
\n" ."

".sprintf(__('The following feeds were found in %s, which one would you like to subscribe?'),$label,$label)."

\n"; $cnt = 0; while(list($id,$feedarr) = each($feeds)) { // we need an URL if (!array_key_exists('href',$feedarr)) { continue; } else { $href = $feedarr['href']; } if (array_key_exists('type',$feedarr)) { $typeLbl = " [" . $feedarr['type'] . "]"; } $cnt++; if (array_key_exists('title',$feedarr)) { $lbl = $feedarr['title']; } elseif (array_key_exists('type',$feedarr)) { $lbl = $feedarr['type']; $typeLbl = ""; } elseif (array_key_exists('href',$feedarr)) { $lbl = $feedarr['href']; } else { $lbl = "Resource $cnt"; } echo "

\n\t\n" ."\t\n" ."

\n"; } echo "

\n" ."\n" ."\n" ."\n" ."

\n
\n\n"; } } } elseif (is_array($ret)) { rss_error($ret[1], RSS_ERROR_ERROR,true); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; } else { rss_error(sprintf(__("I'm sorry, I don't think I can handle this URL: '%s'"),$label), RSS_ERROR_ERROR,true); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; } } else { rss_error(sprintf(__("I'm sorry, I don't think I can handle this URL: '%s'"),$label), RSS_ERROR_ERROR,true); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; } break; case CST_ADMIN_EDIT_ACTION: $id = sanitize($_REQUEST['cid'],RSS_SANITIZER_NUMERIC); channel_edit_form($id); break; case CST_ADMIN_DELETE_ACTION: $id = sanitize($_REQUEST['cid'],RSS_SANITIZER_NUMERIC); if (array_key_exists(CST_ADMIN_CONFIRMED,$_POST) && $_POST[CST_ADMIN_CONFIRMED] == __('Yes')) { $rs = rss_query("select distinct id from " .getTable("item") . " where cid=$id"); $ids = array(); while (list($did) = rss_fetch_row($rs)) { $ids[] = $did; } if (count($ids)) { $sqldel = "delete from " .getTable('metatag') . " where fid in (" . implode(",",$ids) .")"; rss_query($sqldel); } $sql = "delete from " . getTable("item") ." where cid=$id"; rss_query($sql); $sql = "delete from " . getTable("channels") ." where id=$id"; rss_query($sql); // Delete properties deleteProperty($id,'rss.input.allowupdates'); // Invalidate cache rss_invalidate_cache(); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; } elseif (array_key_exists(CST_ADMIN_CONFIRMED,$_REQUEST) && $_REQUEST[CST_ADMIN_CONFIRMED] == __('No')) { $ret__ = CST_ADMIN_DOMAIN_CHANNEL; } else { list($cname) = rss_fetch_row(rss_query("select title from " . getTable("channels") ." where id = $id")); echo "
\n" ."

"; printf(__("Are you sure you wish to delete '%s'?"),$cname); echo "

\n" ."

\n" ."\n" ."\n" ."\n" ."\n" ."

\n
\n"; } break; case __('Import'): case 'ACT_ADMIN_IMPORT': if (array_key_exists('opml',$_POST) && strlen(trim($_POST['opml'])) > 7) { $url = trim( sanitize($_POST['opml'],RSS_SANITIZER_NO_SPACES) ); } elseif (array_key_exists('opmlfile',$_FILES) && $_FILES['opmlfile']['tmp_name']) { if (is_uploaded_file($_FILES['opmlfile']['tmp_name'])) { $url = $_FILES['opmlfile']['tmp_name']; } else { $url = ''; } } else { $url = ''; } if (!$url) { $ret__ = CST_ADMIN_DOMAIN_OPML; break; } if (array_key_exists('opml_import_option',$_POST)) { $import_opt = $_POST['opml_import_option']; } else { $import_opt = CST_ADMIN_OPML_IMPORT_MERGE; } if ($import_opt == CST_ADMIN_OPML_IMPORT_FOLDER) { $opmlfid = sanitize($_POST['opml_import_to_folder'], RSS_SANITIZER_NUMERIC); } else { $opmlfid = getRootFolder(); } @set_time_limit(0); @ini_set('max_execution_time', 300); // Parse into and OPML object $opml=getOpml($url); if (sizeof($opml) > 0) { if ($import_opt == CST_ADMIN_OPML_IMPORT_WIPE) { rss_query("delete from " . getTable("metatag")); rss_query("delete from " . getTable("channels")); rss_query("delete from " . getTable("item")); rss_query("delete from " . getTable("folders") ." where id > 0"); } if ($import_opt == CST_ADMIN_OPML_IMPORT_FOLDER) { $fid = $opmlfid; list($prev_folder) = rss_fetch_row(rss_query( "select name from " .getTable('folders') ." where id= $opmlfid ")); } else { $prev_folder = __('Root'); $fid = 0; } echo "
\n

".__('Updating') ."...

\n"; echo "
\n"; flush(); //update all the feeds update(""); rss_invalidate_cache(); } $ret__ = CST_ADMIN_DOMAIN_CHANNEL; break; case CST_ADMIN_SUBMIT_EDIT: $cid = sanitize($_POST['cid'],RSS_SANITIZER_NUMERIC); rss_plugin_hook('rss.plugins.admin.feed.properties.submit', null); // TBD $title= strip_tags(rss_real_escape_string(real_strip_slashes($_POST['c_name']))); $url= rss_real_escape_string($_POST['c_url']); $siteurl= rss_real_escape_string($_POST['c_siteurl']); $parent= rss_real_escape_string($_POST['c_parent']); $descr= strip_tags(rss_real_escape_string(real_strip_slashes($_POST['c_descr']))); $icon = rss_real_escape_string($_POST['c_icon']); $priv = (array_key_exists('c_private',$_POST) && $_POST['c_private'] == '1'); $tags = rss_real_escape_string($_POST['c_tags']); $old_priv = ($_POST['old_priv'] == '1'); // Feed Properties $prop_rss_input_allowupdates = rss_real_escape_string($_POST['prop_rss_input_allowupdates']); if ($prop_rss_input_allowupdates == 'default') { deleteProperty($cid,'rss.input.allowupdates'); } else { setProperty($cid, 'rss.input.allowupdates' , 'feed', ($prop_rss_input_allowupdates == 1)); } if ($priv != $old_priv) { $mode = ", mode = mode "; if ($priv) { $mode .= " | " . RSS_MODE_PRIVATE_STATE; rss_query ('update ' . getTable('item') ." set unread = unread | " . RSS_MODE_PRIVATE_STATE ." where cid=$cid"); } else { $mode .= " & " .SET_MODE_PUBLIC_STATE; rss_query ('update ' . getTable('item') ." set unread = unread & " . SET_MODE_PUBLIC_STATE ." where cid=$cid"); } rss_invalidate_cache(); } else { $mode = ""; } $del = (array_key_exists('c_deleted',$_POST) && $_POST['c_deleted'] == '1'); $old_del = ($_POST['old_del'] == '1'); if ($del != $old_del) { if ($mode == "") { $mode = ", mode = mode "; } if ($del) { $mode .= " | " . RSS_MODE_DELETED_STATE; } else { $mode .= " & " . SET_MODE_AVAILABLE_STATE; } } if ($url == '' || substr($url,0,4) != "http") { rss_error(sprintf(__("I'm sorry, I don't think I can handle this URL: '%s'"),$url), RSS_ERROR_ERROR,true); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; break; } if ($icon && cacheFavicon($icon)) { $icon = 'blob:'.$icon; } $sql = "update " .getTable("channels") ." set title='$title', url='$url', siteurl='$siteurl', " ." parent=$parent, descr='$descr', icon='$icon' " ." $mode where id=$cid"; rss_query($sql); __exp__submitTag($cid,$tags,"'channel'"); rss_invalidate_cache(); $ret__ = CST_ADMIN_DOMAIN_CHANNEL; break; case CST_ADMIN_MOVE_UP_ACTION: case CST_ADMIN_MOVE_DOWN_ACTION: $id = sanitize($_REQUEST['cid'],RSS_SANITIZER_NUMERIC); $res = rss_query("select parent,position from " . getTable("channels") ." where id=$id"); list($parent,$position) = rss_fetch_row($res); $res = rss_query( "select id, position from " .getTable("channels") ." where parent=$parent and id != $id order by abs($position-position) limit 2" ); // Let's look for a lower/higher position than the one we got. $switch_with_position=$position; while (list($oid,$oposition) = rss_fetch_row($res)) { if ( // found none yet? ($switch_with_position == $position) && ( // move up: we look for a lower position ($_REQUEST['action'] == CST_ADMIN_MOVE_UP_ACTION && $oposition < $switch_with_position) || // move up: we look for a higher position ($_REQUEST['action'] == CST_ADMIN_MOVE_DOWN_ACTION && $oposition > $switch_with_position) ) ) { $switch_with_position = $oposition; $switch_with_id = $oid; } } // right, lets! if ($switch_with_position != $position) { rss_query( "update " .getTable("channels") ." set position = $switch_with_position where id=$id" ); rss_query( "update " .getTable("channels") ." set position = $position where id=$switch_with_id" ); rss_invalidate_cache(); } $ret__ = CST_ADMIN_DOMAIN_CHANNEL; break; case CST_ADMIN_MULTIEDIT: $ret__ = CST_ADMIN_DOMAIN_CHANNEL; $ids = array(); foreach($_REQUEST as $key => $val) { if (preg_match('/^fcb([0-9]+)$/',$key,$match)) { if (($id = (int) $_REQUEST[$key]) > 0) { $ids[] = $id; } } } // no feed selected? if (count($ids) == 0) { break; } else { $sqlids=" (" .implode(',',$ids) .")"; } // MOVE TO FOLDER if (array_key_exists('me_move_to_folder',$_REQUEST)) { $fid= sanitize($_REQUEST['me_folder'],RSS_SANITIZER_NUMERIC); $sql = "update " .getTable('channels') . " set parent=$fid where id in $sqlids"; rss_query($sql); /// STATE } elseif (array_key_exists('me_state',$_REQUEST)) { $deprecated = array_key_exists('me_deprecated',$_REQUEST)?$_REQUEST['me_deprecated']:false; $private = array_key_exists('me_private',$_REQUEST)?$_REQUEST['me_private']:false; if ($private) { rss_query ('update ' . getTable('channels') ." set mode = mode | " . RSS_MODE_PRIVATE_STATE ." where id in $sqlids"); rss_query ('update ' . getTable('item') ." set unread = unread | " . RSS_MODE_PRIVATE_STATE ." where cid in $sqlids"); } else { rss_query ('update ' . getTable('channels') ." set mode = mode & " . SET_MODE_PUBLIC_STATE ." where id in $sqlids"); rss_query ('update ' . getTable('item') ." set unread = unread & " . SET_MODE_PUBLIC_STATE ." where cid in $sqlids"); } if ($deprecated) { rss_query ('update ' . getTable('channels') ." set mode = mode | " . RSS_MODE_DELETED_STATE ." where id in $sqlids"); } else { rss_query ('update ' . getTable('channels') ." set mode = mode & " . SET_MODE_AVAILABLE_STATE ." where id in $sqlids"); } // DELETE } elseif (array_key_exists('me_delete',$_REQUEST)) { if ( array_key_exists('me_do_delete',$_REQUEST) && $_REQUEST['me_do_delete'] == "1") { $sql = "delete from " . getTable('channels') ." where id in $sqlids"; rss_query($sql); } } rss_invalidate_cache(); break; case 'dump': // Make sure this is a POST if(!isset($_POST['dumpact'])) { die('Sorry, you can\'t access this via a GET'); } $tbl = array('"','"'); error_reporting(E_ALL); rss_require('schema.php'); $tables=getExpectedTables(); unset($tables['cache']); //$tables=array('channels','tag','config'); $bfr=''; $bfr .= '<'.'?xml version="1.0" encoding="UTF-8"?'.'>'."\n"; $bfr .= ''."\n"; foreach($tables as $table => $prefixed) { $rs = rss_query("select * from $prefixed"); $bfr .="<$table>\n"; while($row=rss_fetch_assoc($rs)) { $r=" $val) { $val=htmlspecialchars($val); $r.=" $key=\"$val\" "; } $r .= "/>\n"; $bfr .=$r; } $bfr .="\n"; } $bfr .=''."\n"; $gzdata = gzencode($bfr, 9); // Delete the output buffer. This is probably a bad thing to do, if the ob'ing is turned off. // e.g. data was already sent to the brwoser. while (@ob_end_clean()); // Send the dump to the browser: header("Pragma: public"); // required header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Connection: close"); header("Content-Transfer-Encoding: binary"); header("Content-Length: " . strlen($gzdata)); header('Content-type: application/x-gzip'); header('Content-disposition: inline; filename="gregarius.dump.'.date('MjSY').'.xml.gz"'); die($gzdata); break; default: break; } return $ret__; } function channel_edit_form($cid) { $sql = "select id, title, url, siteurl, parent, descr, icon, mode, daterefreshed, dateadded from " .getTable("channels") ." where id=$cid"; $res = rss_query($sql); list ($id, $title, $url, $siteurl, $parent, $descr, $icon, $mode, $daterefreshed, $dateadded) = rss_fetch_row($res); // get tags $sql = "select t.tag from " . getTable('tag')." t " . " inner join " . getTable('metatag') . " m " . " on m.tid = t.id " . "where m.ttype = 'channel' and m.fid = $cid"; $res = rss_query($sql); $tags = ""; while($r = rss_fetch_assoc($res)) { $tags .= $r['tag'] . " "; } echo "
\n"; echo "\n\n

".__('Edit the feed ')." '$title'

\n"; echo "
\n"; echo "
"; // Timestamps if(!empty($daterefreshed)) { echo "

" ."

\n"; } else { echo "

" ."

\n"; } // Item name echo "

\n" ."" ."\n" ."\n" ."

\n" // RSS URL ."

\n" ."" . __('(visit)') . "\n" ."

" // Site URL ."

\n" ."" . __('(visit)') . "\n" ."

" // Folder ."

\n" .rss_toolkit_folders_combo('c_parent',$parent) ."

\n"; // Tags echo "

\n" ."

"; // Items state if ($mode & RSS_MODE_PRIVATE_STATE) { $pchk = " checked=\"checked\" "; $old_priv = "1"; } else { $pchk = ""; $old_priv = "0"; } if ($mode & RSS_MODE_DELETED_STATE) { $dchk = " checked=\"checked\" "; $old_del = "1"; } else { $dchk = ""; $old_del = "0"; } echo "

\n" ."\n" ."\n" ."\n" ."

\n"; echo "

\n" ."\n" ."\n" ."\n" ."

\n"; // Description $descr = trim(strip_tags($descr)); echo "

\n" ."

\n"; // Icon if (getConfig('rss.output.showfavicons')) { echo "

\n"; if (trim($icon) != "") { if (substr($icon,0,5) == 'blob:') { $icon = substr($icon,5); } echo "\"$title\"\n"; echo "" . __('(Leave blank for no icon)') .""; } echo "

\n"; } else { echo "

\n"; } rss_plugin_hook('rss.plugins.admin.feed.properties', $cid); echo "
\n"; // Feed properties echo "
"; echo "

" ."Allow Gregarius to look for updates in existing items for this feed?" ."[Edit the global option]\n" ." " ."

"; $rss_input_allowupdates_default_current = getProperty($cid,'rss.input.allowupdates'); $rss_input_allowupdates_default_value = $rss_input_allowupdates_default = ("Use global option (" . (getConfig('rss.input.allowupdates')?"Yes":"No") .")"); echo "

" ."\n" ."\n" ."\n" ."" ."\n" ."" ."

\n"; echo "
\n"; echo "

"; echo "
\n"; } ?>