<?php
###############################################################################
# Gregarius - A PHP based RSS aggregator.
# Copyright (C) 2003 - 2006 Marco Bonetti
#
###############################################################################
# This program is free software and open source 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 or visit
# http://www.gnu.org/licenses/gpl.html
#
###############################################################################
# E-mail: mbonetti at gmail dot com
# Web page: http://gregarius.net/
#
###############################################################################
function plugins_admin() {
return CST_ADMIN_DOMAIN_PLUGINS;
}
function plugin_options_admin() {
if (array_key_exists('plugin_name',$_REQUEST)) {
return CST_ADMIN_DOMAIN_PLUGIN_OPTIONS;
} else {
return CST_ADMIN_DOMAIN_PLUGINS;
}
}
function plugins() {
// Submit changes
if (isset($_POST['admin_plugin_submit_changes'])) {
$old_active_plugins = getConfig('rss.config.plugins');
$active_plugins=array();
foreach($_REQUEST as $rkey=>$rentry) {
if (preg_match('/_gregarius_plugin.([a-zA-Z0-9_\/\-]+).php/',$rkey,$matches)) {
$active_plugins[] = ($matches[1] .".php");
}
}
$value = serialize($active_plugins);
$sql = "update " . getTable('config') . " set value_='$value' where key_='rss.config.plugins'";
rss_query($sql);
rss_invalidate_cache();
// deactivate
$to_deactivate = array_diff($old_active_plugins, $active_plugins);
foreach($to_deactivate as $deactivatethis) {
rss_load_plugin($deactivatethis);
rss_plugin_hook("rss.plugins.admin.deactivate", "", $deactivatethis);
}
//activate
$to_activate = array_diff($active_plugins, $old_active_plugins);
foreach($to_activate as $activatethis) {
rss_load_plugin($activatethis);
rss_plugin_hook("rss.plugins.admin.activate", "", $activatethis);
}
} else {
$active_plugins = getConfig('rss.config.plugins');
}
// Check for updates
$doUpdates = false;
$updates = array();
if (isset($_POST['admin_plugin_check_for_updates'])) {
$updates = plugins_check_for_updates();
$doUpdates = true;
}
// Rendering
echo "<h2 class=\"trigger\">".__('Plugins')."</h2>\n"
."<div id=\"admin_plugins\">\n";
echo __('<p style="font-size:small">Plugins are third-party scripts that offer extended functionalities. More plugins can be downloaded at the <a style="text-decoration:underline" href="http://plugins.gregarius.net/">Plugin Repository</a>.</p>');
echo "<form method=\"post\" action=\"" .$_SERVER['PHP_SELF'] ."\">\n";
echo "<p><input type=\"hidden\" name=\"".CST_ADMIN_DOMAIN."\" value=\"".CST_ADMIN_DOMAIN_PLUGINS."\" /></p>\n";
echo "\n<table id=\"plugintable\">\n<tr>\n"
."<th>".__('Active')."</th>\n"
."<th>".__('Name')."</th>\n"
."<th>".__('Version')."</th>\n"
."<th>".__('Author')."</th>\n"
."<th>".__('Description')."</th>\n"
."<th>".__('Options')."</th>\n";
if ($doUpdates) {
echo "<th>".__('Update Available')."</th>\n";
}
echo "</tr>\n";
$rss_plugins = getPlugins();
$cntr = 0;
if ($rss_plugins) {
foreach($rss_plugins as $entry => $info ) {
$active= in_array($entry,$active_plugins);
if (count($info)) {
$updateDl = null;
if (is_array($updates) && array_key_exists($info['file'],$updates)) {
$lastV = $updates[$info['file']][0];
$thisV = $info['version'];
if ($lastV > $thisV) {
$updateDl = str_replace("&","&",$updates[$info['file']][1]);
}
}
$class = (($cntr++ % 2 == 0)?"even":"odd") .
($updateDl? " hilite":($active?" active":""));
echo "<tr class=\"$class\">\n";
echo "<td class=\"cntr\">"
."<input type=\"checkbox\" name=\"_gregarius_plugin_$entry\" "
." id=\"_gregarius_plugin_$entry\" value=\"1\" "
.($active?"checked=\"checked\"":"")." />\n"
."</td>\n";
echo "<td><label
for=\"_gregarius_plugin_$entry\">".(array_key_exists('name',$info)?$info['name']:" ").
"</label></td>\n";
echo "<td class=\"cntr\">"
.(array_key_exists('version',$info)?$info['version']:" "). "</td>\n";
echo "<td>" .(array_key_exists('author',$info)?$info['author']:" "). "</td>\n";
echo "<td>" .(array_key_exists('description',$info)?$info['description']:" "). "</td>\n";
// output the column to call a plugin's config page.
echo "<td class=\"cntr\">";
if(array_key_exists('configuration',$info)) {
$escaped_plugin_name = str_replace("/", "%2F", $entry);
echo "<a href=\"".$_SERVER['PHP_SELF']. "?".CST_ADMIN_DOMAIN."=".
CST_ADMIN_DOMAIN_PLUGIN_OPTIONS
."&action=". CST_ADMIN_EDIT_ACTION. "&plugin_name=".$escaped_plugin_name
."&" .CST_ADMIN_VIEW ."=" .CST_ADMIN_DOMAIN_PLUGIN_OPTIONS
."\">" . __('edit')
."</a>";
} else {
echo " ";
}
echo "</td>\n";
if ($doUpdates && $updateDl) {
echo "<td class=\"cntr\">";
echo "<a href=\"$updateDl\">$lastV</a>";
echo "</td>";
}
elseif($doUpdates) {
echo "<td> </td>";
}
echo "</tr>\n";
}
}
}
echo "</table>\n";
echo "<p><input type=\"hidden\" name=\"". CST_ADMIN_METAACTION ."\" value=\"ACT_ADMIN_SUBMIT_CHANGES\"/>\n";
echo "<input type=\"submit\" name=\"admin_plugin_submit_changes\" value=\"".__('Submit Changes')."\" />\n";
echo "<input type=\"submit\" name=\"admin_plugin_check_for_updates\" value=\"".__('Check for Updates')."\" /></p></form>\n";
echo "</div>";
}
function plugin_options() {
if (!array_key_exists('plugin_name',$_REQUEST) ||
array_key_exists('admin_plugin_options_cancel_changes', $_REQUEST)) {
plugins();
return;
}
// TBD
$plugin_filename = $_REQUEST['plugin_name'];
$plugin_filename = str_replace("%2F", "/", $plugin_filename);
$plugin_output = "";
if (preg_match('/([a-zA-Z0-9_\/\-]+).php/',$plugin_filename,$matches)) {
$plugin_filename = $matches[1] .".php"; // sanitize input
$plugin_info = getPluginInfo($plugin_filename);
if($plugin_info && array_key_exists('configuration', $plugin_info)) {
$plugin_config_func = $plugin_info['configuration'];
ob_start();
rss_load_plugin($plugin_filename);
if(function_exists($plugin_config_func)) {
call_user_func($plugin_config_func); // Are you happy now?
$plugin_output = ob_get_contents();
}
ob_end_clean();
rss_invalidate_cache();
}
if ($plugin_output) { // Let us set up a form
echo "<h2
class=\"trigger\">".__('Plugin Options')." ".TITLE_SEP." ". $plugin_info['name']. "</h2>\n"
."<div id=\"admin_plugin_options\">\n";
echo "<form method=\"post\" action=\"" .$_SERVER['PHP_SELF'] ."\">\n";
echo "<p><input type=\"hidden\" name=\"".CST_ADMIN_DOMAIN
."\" value=\"".CST_ADMIN_DOMAIN_PLUGIN_OPTIONS."\" /></p>\n";
echo $plugin_output;
echo "<p><input type=\"hidden\" name=\"plugin_name\" value=\"".$plugin_filename."\"/>\n";
echo "<p><input type=\"hidden\" name=\"". CST_ADMIN_METAACTION
."\" value=\"ACT_ADMIN_SUBMIT_CHANGES\"/>\n";
echo "<input type=\"submit\" name=\"admin_plugin_options_submit_changes\" value=\""
.__('Submit Changes')."\" />\n";
echo "<input type=\"submit\" name=\"admin_plugin_options_cancel_changes\"
value=\"".__('Cancel')."\" /></p></form>\n";
echo "</div>";
} else {
plugins();
}
}
}
/**
* fetches information for the given plugin,
* which should contain:
*
* /// Name: Url filter
* /// Author: Marco Bonetti
* /// Description: This plugin will try to make ugly URL links look better
* /// Version: 1.0
*
*/
function getPluginInfo($file) {
$info = array();
$path = "../".RSS_PLUGINS_DIR."/$file";
if (file_exists($path)) {
$f = @fopen($path,'r');
$contents = "";
if ($f) {
$contents .= fread($f, filesize($path));
@fclose($f);
} else {
$contents = "";
}
if ($contents && preg_match_all("/\/\/\/\s?([^:]+):(.*)/",$contents,$matches,PREG_SET_ORDER)) {
foreach($matches as $match) {
$key = trim(strtolower($match[1]));
$val = trim($match[2]);
if ($key == 'version') {
$val=preg_replace('/[^0-9\.]+/','',$val);
}
$info[$key] = $val;
}
}
$info['file'] = preg_replace('/\..+$/','',$file);
}
return $info;
}
/**
* This function returns an associative array with all the php files that are
* plugins and their plugin info.
*
* Following the wordpress model (and code) we search for plugins in the plugins
* directory and each subdirectory 1 level deep.
*/
function getPlugins() {
$plugin_dir_files = array();
$rss_plugins = array();
$plugin_dir = '../' . RSS_PLUGINS_DIR;
$d = @dir($plugin_dir);
//Put all the *.php files in the plugin dir and 1 level below into $plugin_dir_files
while (($file = $d->read()) !== false) {
if ( $file != "CVS" && (substr($file,0,1) != ".")) {
if(is_dir($plugin_dir . '/' . $file)) {
$plugins_subdir = @dir($plugin_dir . '/' . $file);
if ($plugins_subdir) {
while(($subfile = $plugins_subdir->read()) !== false) {
if ( preg_match('|^\.+$|', $subfile) ) {
continue;
}
if ( preg_match('|\.php$|', $subfile) ) {
$plugin_dir_files[] = "$file/$subfile";
}
}
}
} else {
if ( preg_match('|\.php$|', $file) ) {
$plugin_dir_files[] = $file;
}
}
}
}
// See which of the php files in $plugin_dir_files are really plugins
foreach($plugin_dir_files as $plugin_dir_file) {
$info = getPluginInfo($plugin_dir_file);
// $info will have the filename in it. Does it have anything else?
if (count($info) > 1) {
$rss_plugins[$plugin_dir_file] = $info;
}
}
ksort($rss_plugins);
//return an associative array with the plugin files and their info
return $rss_plugins;
}
function plugins_check_for_updates() {
$pluginsxml = array();
global $pluginsxml;
$xml = getUrl('http://plugins.gregarius.net/api.php');
$xml = str_replace("\r", '', $xml);
$xml = str_replace("\n", '', $xml);
$xp = xml_parser_create() or rss_error("couldn't create parser");
xml_set_element_handler($xp, 'plugins_xml_startElement', 'plugins_xml_endElement')
or rss_error("couldnt set XML handlers");
xml_parse($xp, $xml, true) or rss_error("failed parsing xml");
xml_parser_free($xp) or rss_error("failed freeing the parser");
return $pluginsxml;
}
function plugins_xml_startElement($xp, $element, $attr) {
global $pluginsxml;
if ($element == 'PLUGIN' &&
array_key_exists('PID',$attr) &&
array_key_exists('URL',$attr) &&
array_key_exists('VERSION',$attr)) {
$pluginsxml[$attr['PID']] = array($attr['VERSION'],$attr['URL']);
}
}
function plugins_xml_endElement($xp, $element) {
///global $pluginsxml;
return;
}
function rss_plugins_redirect_to_admin() {
rss_redirect("/admin/index.php?" . CST_ADMIN_VIEW . "=" . CST_ADMIN_DOMAIN_PLUGINS);
}
function rss_plugins_redirect_to_plugin_config($filename) {
rss_redirect("/admin/index.php" . "?".CST_ADMIN_DOMAIN."=". CST_ADMIN_DOMAIN_PLUGIN_OPTIONS ."&action=". CST_ADMIN_EDIT_ACTION. "&plugin_name=" . $filename);
}
function rss_plugins_is_submit() {
return array_key_exists("admin_plugin_options_submit_changes", $_REQUEST);
}
?>