root/trunk/gregarius/admin/plugins.php

Revision 1561, 13.3 kB (checked in by mbonetti, 2 years ago)

Yay for gettext localization! This will probably break things big time.
Note that until intl/*.php isn't adapted the the new method, the trunk
won't be localized!

  • Property svn:eol-style set to native
Line 
1<?php
2###############################################################################
3# Gregarius - A PHP based RSS aggregator.
4# Copyright (C) 2003 - 2006 Marco Bonetti
5#
6###############################################################################
7# This program is free software and open source software; you can redistribute
8# it and/or modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the License,
10# or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful, but WITHOUT
13# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14# FITNESS FOR A PARTICULAR PURPOSE.      See the GNU General Public License for
15# more details.
16#
17# You should have received a copy of the GNU General Public License along
18# with this program; if not, write to the Free Software Foundation, Inc.,
19# 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  or visit
20# http://www.gnu.org/licenses/gpl.html
21#
22###############################################################################
23# E-mail:          mbonetti at gmail dot com
24# Web page:        http://gregarius.net/
25#
26###############################################################################
27
28
29function plugins_admin() {
30    return CST_ADMIN_DOMAIN_PLUGINS;
31}
32
33function plugin_options_admin() {
34    if (array_key_exists('plugin_name',$_REQUEST)) {
35        return CST_ADMIN_DOMAIN_PLUGIN_OPTIONS;
36    } else {
37        return CST_ADMIN_DOMAIN_PLUGINS;
38    }
39}
40
41function plugins() {
42
43    // Submit changes
44    if (isset($_POST['admin_plugin_submit_changes'])) {
45        $old_active_plugins = getConfig('rss.config.plugins');
46        $active_plugins=array();
47        foreach($_REQUEST as $rkey=>$rentry) {
48            if (preg_match('/_gregarius_plugin.([a-zA-Z0-9_\/\-]+).php/',$rkey,$matches)) {
49                $active_plugins[] = ($matches[1] .".php");
50            }
51        }
52
53        $value = serialize($active_plugins);
54        $sql = "update " . getTable('config') . " set value_='$value' where key_='rss.config.plugins'";
55        rss_query($sql);
56        rss_invalidate_cache();
57
58        // deactivate
59        $to_deactivate = array_diff($old_active_plugins, $active_plugins);
60        foreach($to_deactivate as $deactivatethis) {
61            rss_load_plugin($deactivatethis);
62            rss_plugin_hook("rss.plugins.admin.deactivate", "", $deactivatethis);
63        }
64
65        //activate
66        $to_activate = array_diff($active_plugins, $old_active_plugins);
67        foreach($to_activate as $activatethis) {
68            rss_load_plugin($activatethis);
69            rss_plugin_hook("rss.plugins.admin.activate", "", $activatethis);
70        }
71    } else {
72        $active_plugins = getConfig('rss.config.plugins');
73    }
74
75    // Check for updates
76    $doUpdates = false;
77    $updates = array();
78    if  (isset($_POST['admin_plugin_check_for_updates'])) {
79        $updates = plugins_check_for_updates();
80        $doUpdates = true;
81    }
82
83
84
85    // Rendering
86    echo "<h2 class=\"trigger\">".__('Plugins')."</h2>\n"
87    ."<div id=\"admin_plugins\">\n";
88
89
90    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>');
91
92    echo "<form method=\"post\" action=\"" .$_SERVER['PHP_SELF'] ."\">\n";
93    echo "<p><input type=\"hidden\" name=\"".CST_ADMIN_DOMAIN."\" value=\"".CST_ADMIN_DOMAIN_PLUGINS."\" /></p>\n";
94    echo "\n<table id=\"plugintable\">\n<tr>\n"
95    ."<th>".__('Active')."</th>\n"
96    ."<th>".__('Name')."</th>\n"
97    ."<th>".__('Version')."</th>\n"
98    ."<th>".__('Author')."</th>\n"
99    ."<th>".__('Description')."</th>\n"
100    ."<th>".__('Options')."</th>\n";
101    if ($doUpdates) {
102        echo "<th>".__('Update Available')."</th>\n";
103    }
104
105    echo "</tr>\n";
106
107
108
109    $rss_plugins = getPlugins();
110    $cntr = 0;
111    if ($rss_plugins) {
112        foreach($rss_plugins as $entry => $info ) {
113            $active= in_array($entry,$active_plugins);
114            if (count($info)) {
115                $updateDl = null;
116                if (is_array($updates) && array_key_exists($info['file'],$updates)) {
117                    $lastV = $updates[$info['file']][0];
118                    $thisV = $info['version'];
119                    if ($lastV > $thisV) {
120                        $updateDl = str_replace("&","&amp;",$updates[$info['file']][1]);
121                    }
122                }
123
124                $class = (($cntr++ % 2 == 0)?"even":"odd") .
125                         ($updateDl? " hilite":($active?" active":""));
126
127                echo "<tr class=\"$class\">\n";
128                echo "<td class=\"cntr\">"
129                ."<input type=\"checkbox\" name=\"_gregarius_plugin_$entry\" "
130                ." id=\"_gregarius_plugin_$entry\" value=\"1\" "
131                .($active?"checked=\"checked\"":"")." />\n"
132                ."</td>\n";
133                echo "<td><label
134                for=\"_gregarius_plugin_$entry\">".(array_key_exists('name',$info)?$info['name']:"&nbsp;").
135                "</label></td>\n";
136                echo "<td class=\"cntr\">"
137                .(array_key_exists('version',$info)?$info['version']:"&nbsp;"). "</td>\n";
138                echo "<td>"     .(array_key_exists('author',$info)?$info['author']:"&nbsp;"). "</td>\n";
139                echo "<td>"     .(array_key_exists('description',$info)?$info['description']:"&nbsp;"). "</td>\n";
140
141                // output the column to call a plugin's config page.
142                echo "<td  class=\"cntr\">";
143                if(array_key_exists('configuration',$info)) {
144                    $escaped_plugin_name = str_replace("/", "%2F", $entry);
145                    echo "<a href=\"".$_SERVER['PHP_SELF']. "?".CST_ADMIN_DOMAIN."=".
146                    CST_ADMIN_DOMAIN_PLUGIN_OPTIONS
147                    ."&amp;action=". CST_ADMIN_EDIT_ACTION. "&amp;plugin_name=".$escaped_plugin_name
148                    ."&amp;" .CST_ADMIN_VIEW ."=" .CST_ADMIN_DOMAIN_PLUGIN_OPTIONS
149                    ."\">" . __('edit')
150                    ."</a>";
151                } else {
152                    echo "&nbsp;";
153                }
154                echo "</td>\n";
155
156                if ($doUpdates && $updateDl) {
157                    echo "<td class=\"cntr\">";
158                    echo "<a href=\"$updateDl\">$lastV</a>";
159                    echo "</td>";
160                }
161                elseif($doUpdates) {
162                    echo "<td>&nbsp;</td>";
163                }
164                echo "</tr>\n";
165            }
166        }
167    }
168    echo "</table>\n";
169    echo "<p><input type=\"hidden\" name=\"". CST_ADMIN_METAACTION ."\" value=\"ACT_ADMIN_SUBMIT_CHANGES\"/>\n";
170    echo "<input type=\"submit\" name=\"admin_plugin_submit_changes\" value=\"".__('Submit Changes')."\" />\n";
171    echo "<input type=\"submit\" name=\"admin_plugin_check_for_updates\" value=\"".__('Check for Updates')."\" /></p></form>\n";
172    echo "</div>";
173}
174
175function plugin_options() {
176    if (!array_key_exists('plugin_name',$_REQUEST) ||
177            array_key_exists('admin_plugin_options_cancel_changes', $_REQUEST)) {
178        plugins();
179        return;
180    }
181    // TBD
182    $plugin_filename = $_REQUEST['plugin_name'];
183    $plugin_filename = str_replace("%2F", "/", $plugin_filename);
184    $plugin_output = "";
185    if (preg_match('/([a-zA-Z0-9_\/\-]+).php/',$plugin_filename,$matches)) {
186        $plugin_filename = $matches[1] .".php"; // sanitize input
187        $plugin_info = getPluginInfo($plugin_filename);
188        if($plugin_info && array_key_exists('configuration', $plugin_info)) {
189            $plugin_config_func = $plugin_info['configuration'];
190            ob_start();
191            rss_load_plugin($plugin_filename);
192            if(function_exists($plugin_config_func)) {
193                call_user_func($plugin_config_func); // Are you happy now?
194                $plugin_output = ob_get_contents();
195
196            }
197            ob_end_clean();
198            rss_invalidate_cache();
199        }
200        if ($plugin_output) { // Let us set up a form
201            echo "<h2
202            class=\"trigger\">".__('Plugin Options')." ".TITLE_SEP." ". $plugin_info['name']. "</h2>\n"
203            ."<div id=\"admin_plugin_options\">\n";
204            echo "<form method=\"post\" action=\"" .$_SERVER['PHP_SELF'] ."\">\n";
205            echo "<p><input type=\"hidden\" name=\"".CST_ADMIN_DOMAIN
206            ."\" value=\"".CST_ADMIN_DOMAIN_PLUGIN_OPTIONS."\" /></p>\n";
207            echo $plugin_output;
208            echo "<p><input type=\"hidden\" name=\"plugin_name\" value=\"".$plugin_filename."\"/>\n";
209            echo "<p><input type=\"hidden\" name=\"". CST_ADMIN_METAACTION
210            ."\" value=\"ACT_ADMIN_SUBMIT_CHANGES\"/>\n";
211            echo "<input type=\"submit\" name=\"admin_plugin_options_submit_changes\" value=\""
212            .__('Submit Changes')."\" />\n";
213            echo "<input type=\"submit\" name=\"admin_plugin_options_cancel_changes\"
214            value=\"".__('Cancel')."\" /></p></form>\n";
215            echo "</div>";
216        } else {
217            plugins();
218        }
219    }
220}
221
222
223/**
224 * fetches information for the given plugin,
225 * which should contain:
226 *
227 *      /// Name: Url filter
228 *      /// Author: Marco Bonetti
229 *      /// Description: This plugin will try to make ugly URL links look better
230 *      /// Version: 1.0
231 *
232 */
233function getPluginInfo($file) {
234    $info = array();
235    $path = "../".RSS_PLUGINS_DIR."/$file";
236    if (file_exists($path)) {
237        $f = @fopen($path,'r');
238        $contents = "";
239        if ($f) {
240            $contents .= fread($f, filesize($path));
241            @fclose($f);
242        } else {
243            $contents = "";
244        }
245
246        if ($contents && preg_match_all("/\/\/\/\s?([^:]+):(.*)/",$contents,$matches,PREG_SET_ORDER)) {
247            foreach($matches as $match) {
248                $key = trim(strtolower($match[1]));
249                $val = trim($match[2]);
250                if ($key == 'version') {
251                    $val=preg_replace('/[^0-9\.]+/','',$val);
252                }
253
254                $info[$key] = $val;
255            }
256        }
257
258        $info['file'] = preg_replace('/\..+$/','',$file);
259    }
260
261    return $info;
262}
263
264/**
265* This function returns an associative array with all the php files that are
266* plugins and their plugin info.
267*
268* Following the wordpress model (and code) we search for plugins in the plugins
269* directory and each subdirectory 1 level deep.
270*/
271function getPlugins() {
272
273    $plugin_dir_files = array();
274    $rss_plugins = array();
275    $plugin_dir = '../' . RSS_PLUGINS_DIR;
276
277    $d = @dir($plugin_dir);
278    //Put all the *.php files in the plugin dir and 1 level below into $plugin_dir_files
279    while (($file = $d->read()) !== false) {
280        if ( $file != "CVS" && (substr($file,0,1) != ".")) {
281            if(is_dir($plugin_dir . '/' . $file)) {
282                $plugins_subdir = @dir($plugin_dir . '/' . $file);
283                if ($plugins_subdir) {
284                    while(($subfile = $plugins_subdir->read()) !== false) {
285                        if ( preg_match('|^\.+$|', $subfile) ) {
286                            continue;
287                        }
288                        if ( preg_match('|\.php$|', $subfile) ) {
289                            $plugin_dir_files[] = "$file/$subfile";
290                        }
291                    }
292                }
293            } else {
294                if ( preg_match('|\.php$|', $file) ) {
295                    $plugin_dir_files[] =  $file;
296                }
297            }
298        }
299    }
300
301    // See which of the php files in $plugin_dir_files are really plugins
302    foreach($plugin_dir_files as $plugin_dir_file) {
303        $info = getPluginInfo($plugin_dir_file);
304        // $info will have the filename in it. Does it have anything else?
305        if (count($info) > 1) {
306            $rss_plugins[$plugin_dir_file] = $info;
307        }
308    }
309
310    ksort($rss_plugins);
311
312    //return an associative array with the plugin files and their info
313    return $rss_plugins;
314}
315
316function plugins_check_for_updates() {
317    $pluginsxml = array();
318    global $pluginsxml;
319    $xml = getUrl('http://plugins.gregarius.net/api.php');
320    $xml = str_replace("\r", '', $xml);
321    $xml = str_replace("\n", '', $xml);
322
323    $xp = xml_parser_create() or rss_error("couldn't create parser");
324
325    xml_set_element_handler($xp, 'plugins_xml_startElement', 'plugins_xml_endElement')
326    or rss_error("couldnt set XML handlers");
327
328    xml_parse($xp, $xml, true) or rss_error("failed parsing xml");
329    xml_parser_free($xp) or rss_error("failed freeing the parser");
330    return $pluginsxml;
331}
332
333function plugins_xml_startElement($xp, $element, $attr) {
334    global $pluginsxml;
335
336    if ($element == 'PLUGIN' &&
337            array_key_exists('PID',$attr) &&
338            array_key_exists('URL',$attr) &&
339            array_key_exists('VERSION',$attr)) {
340
341        $pluginsxml[$attr['PID']] = array($attr['VERSION'],$attr['URL']);
342    }
343}
344
345function plugins_xml_endElement($xp, $element) {
346    ///global $pluginsxml;
347    return;
348}
349
350
351function rss_plugins_redirect_to_admin() {
352    rss_redirect("/admin/index.php?" . CST_ADMIN_VIEW . "=" . CST_ADMIN_DOMAIN_PLUGINS);
353}
354
355function rss_plugins_redirect_to_plugin_config($filename) {
356    rss_redirect("/admin/index.php" . "?".CST_ADMIN_DOMAIN."=". CST_ADMIN_DOMAIN_PLUGIN_OPTIONS ."&amp;action=". CST_ADMIN_EDIT_ACTION. "&amp;plugin_name=" . $filename);
357}
358
359
360function rss_plugins_is_submit() {
361    return array_key_exists("admin_plugin_options_submit_changes", $_REQUEST);
362}
363
364?>
Note: See TracBrowser for help on using the browser.