Update of /cvsroot/php-blog/serendipity/include
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10943/include
Modified Files:
plugin_api.inc.php
Log Message:
Rewrote how s9y fetches external plugins: The path setting is now irrelevant,
only filenames count. They can be placed in any subdirectory as long as their
name matches *_(plugin|event)_*.php. This allows plugin authors to put one
ore more event/sidebar plugin into one bundled directory and reduces swamping
the plugins directory.
Needed to adjust several calls, but it seems to work well.
Requires DB scheme update.
Index: plugin_api.inc.php
===================================================================
RCS file: /cvsroot/php-blog/serendipity/include/plugin_api.inc.php,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- plugin_api.inc.php 27 Nov 2004 22:14:14 -0000 1.6
+++ plugin_api.inc.php 6 Dec 2004 10:46:32 -0000 1.7
@@ -57,7 +57,7 @@
* of the same class, then the persistent state will be copied.
* This allows the user to clone a plugin.
*/
- function create_plugin_instance($plugin_class_id, $copy_from_instance = null, $default_placement = 'right', $authorid = '0')
+ function create_plugin_instance($plugin_class_id, $copy_from_instance = null, $default_placement = 'right', $authorid = '0', $pluginPath = '')
{
global $serendipity;
@@ -65,6 +65,9 @@
$key = $plugin_class_id . ':' . $id;
+ // Secure Plugin path. Only one directory level allowed.
+ $pluginPath = str_replace('/', '', serendipity_db_escape_string($pluginPath));
+
$rs = serendipity_db_query("SELECT MAX(sort_order) as sort_order_max FROM {$serendipity['dbPrefix']}plugins WHERE placement = '$default_placement'", true, 'num');
if (is_array($rs)) {
@@ -73,15 +76,19 @@
$nextidx = 0;
}
- serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}plugins (name, sort_order, placement, authorid) values ('$key', $nextidx, '$default_placement', '$authorid')");
+ serendipity_db_query("INSERT INTO {$serendipity['dbPrefix']}plugins (name, sort_order, placement, authorid, path) values ('$key', $nextidx, '$default_placement', '$authorid', '$pluginPath')");
/* Check for multiple dependencies */
- $plugin =& serendipity_plugin_api::load_plugin($key, $authorid);
- $bag = new serendipity_property_bag;
- $plugin->introspect($bag);
- serendipity_plugin_api::get_event_plugins(false, true); // Refresh static list of plugins to allow execution of added plugin
- $plugin->register_dependencies(false, $authorid);
- $plugin->install();
+ $plugin =& serendipity_plugin_api::load_plugin($key, $authorid, $pluginPath);
+ if (is_object($plugin)) {
+ $bag = new serendipity_property_bag;
+ $plugin->introspect($bag);
+ serendipity_plugin_api::get_event_plugins(false, true); // Refresh static list of plugins to allow execution of added plugin
+ $plugin->register_dependencies(false, $authorid);
+ $plugin->install();
+ } else {
+ echo ERROR . ': ' . $key . ' (' . $pluginPath . ')<br />';
+ }
return $key;
}
@@ -117,7 +124,7 @@
}
/* Retrieves a list of available plugins */
- function enum_plugin_classes($event_only = false)
+ function &enum_plugin_classes($event_only = false)
{
global $serendipity;
@@ -135,80 +142,71 @@
$p = get_parent_class($p);
}
- if ($p == 'serendipity_plugin' && $class_name != 'serendipity_event' && !$event_only ) {
- $classes[] = '@' . $class_name;
- } elseif ($p == 'serendipity_event' && $class_name != 'serendipity_event' && $event_only) {
- $classes[] = '@' . $class_name;
+ if ($p == 'serendipity_plugin' && $class_name != 'serendipity_event' && (!$event_only || is_null($event_only))) {
+ $classes[$class_name] = array('name' => '@' . $class_name,
+ 'pluginPath' => '');
+ } elseif ($p == 'serendipity_event' && $class_name != 'serendipity_event' && ($event_only || is_null($event_only))) {
+ $classes[$class_name] = array('name' => '@' . $class_name,
+ 'pluginPath' => '');
}
}
/* GLOBAL third-party classes next */
$ppath = serendipity_getRealDir(__FILE__) . 'plugins';
- $d = opendir($ppath);
+ serendipity_plugin_api::traverse_plugin_dir($ppath, $classes, $event_only);
+
+ /* LOCAL third-party classes next */
+ $local_ppath = $serendipity['serendipityPath'] . 'plugins';
+ if ($ppath != $local_ppath) {
+ serendipity_plugin_api::traverse_plugin_dir($local_path, $classes, $event_only);
+ }
+
+ return $classes;
+ }
+
+ function traverse_plugin_dir($ppath, &$classes, $event_only) {
+ $d = @opendir($ppath);
if ($d) {
while (($f = readdir($d)) !== false) {
- if ($f{0} == '.' || $f == 'CVS') {
- continue;
- }
-
- if ($event_only && !serendipity_plugin_api::is_event_plugin($f)) {
+ if ($f{0} == '.' || $f == 'CVS' || !is_dir($ppath . '/' . $f)) {
continue;
}
- if (!$event_only && serendipity_plugin_api::is_event_plugin($f)) {
+ $subd = opendir($ppath . '/' . $f);
+ if (!$subd) {
continue;
}
- $existing = array_search('@' . $f, $classes);
- if ($existing !== null && $existing !== false) {
- // If an external plugin/event already exists as internal, remove the internal reference because its redundant
- unset($classes[$existing]);
- }
-
- if (file_exists($ppath . '/' . $f . '/' . $f . '.php')) {
- $classes[] = $f;
- }
- }
- }
-
- /* LOCAL third-party classes next */
- $local_ppath = $serendipity['serendipityPath'] . 'plugins';
- if ($ppath != $local_ppath) {
- $d = @opendir($local_ppath);
- if ($d) {
- while (($f = readdir($d)) !== false) {
- if ($f{0} == '.' || $f == 'CVS') {
+ // Instead of only looking for directories, search for whiles within subdirectories
+ while (($subf = readdir($subd)) !== false) {
+ if (!preg_match('@^[^_]+_(event|plugin)_.+\.php$@i', $subf)) {
continue;
}
- if ($event_only && !serendipity_plugin_api::is_event_plugin($f)) {
- continue;
+ // If an external plugin/event already exists as internal, remove the internal reference because its redundant
+ if (isset($classes['@' . $subf])) {
+ unset($classes['@' . $subf]);
}
- if (!$event_only && serendipity_plugin_api::is_event_plugin($f)) {
- continue;
+ // A local plugin will be preferred over general plugins [used when calling this function the second time]
+ if (isset($classes[$subf])) {
+ unset($classes[$subf]);
}
- $existing = array_search('@' . $f, $classes);
- if ($existing !== null && $existing !== false) {
- // If an external plugin/event already exists as internal, remove the internal reference because its redundant
- unset($classes[$existing]);
+ if (!is_null($event_only) && $event_only && !serendipity_plugin_api::is_event_plugin($subf)) {
+ continue;
}
- $existing = array_search($f, $classes);
- if ($existing !== null && $existing !== false) {
- // A local plugin will be preferred over general plugins
- unset($classes[$existing]);
+ if (!is_null($event_only) && !$event_only && serendipity_plugin_api::is_event_plugin($subf)) {
+ continue;
}
- if (file_exists($local_ppath . '/' . $f . '/' . $f . '.php')) {
- $classes[] = $f;
- }
+ $class_name = str_replace('.php', '', $subf);
+ $classes[$class_name] = array('name' => $class_name,
+ 'pluginPath' => $f);
}
}
}
-
- return $classes;
}
function get_installed_plugins($filter = '*') {
@@ -268,7 +266,7 @@
}
/* Creates an instance of a named plugin */
- function &load_plugin($instance_id, $authorid = null)
+ function &load_plugin($instance_id, $authorid = null, $pluginPath = '')
{
global $serendipity;
@@ -280,11 +278,23 @@
} else {
/* plugin from the plugins/ dir */
if (!class_exists($name)) {
+ if (empty($pluginPath)) {
+ $sql = "SELECT path from {$serendipity['dbPrefix']}plugins WHERE name = '" . $instance_id . "'";
+ $plugdata = serendipity_db_query($sql, true);
+ if (is_array($plugdata) && isset($plugdata[0])) {
+ $pluginPath = $plugdata[0];
+ }
+
+ if (empty($pluginPath)) {
+ $pluginPath = $name;
+ }
+ }
+
// First try the local path, and then (if existing) a shared library repository ...
- if (file_exists($serendipity['serendipityPath'] . 'plugins/' . $name . '/' . $name . '.php')) {
- include $serendipity['serendipityPath'] . 'plugins/' . $name . '/' . $name . '.php';
- } elseif (file_exists(S9Y_INCLUDE_PATH . 'plugins/' . $name . '/' . $name . '.php')) {
- include S9Y_INCLUDE_PATH . 'plugins/' . $name . '/' . $name . '.php';
+ if (file_exists($serendipity['serendipityPath'] . 'plugins/' . $pluginPath . '/' . $name . '.php')) {
+ include $serendipity['serendipityPath'] . 'plugins/' . $pluginPath . '/' . $name . '.php';
+ } elseif (file_exists(S9Y_INCLUDE_PATH . 'plugins/' . $pluginPath . '/' . $name . '.php')) {
+ include S9Y_INCLUDE_PATH . 'plugins/' . $pluginPath . '/' . $name . '.php';
}
if (!class_exists($name)) {
@@ -301,7 +311,9 @@
} else {
$sql = "SELECT authorid from {$serendipity['dbPrefix']}plugins WHERE name = '" . $instance_id . "'";
$owner = serendipity_db_query($sql, true);
- $p->serendipity_owner = $owner[0];
+ if (is_array($owner) && isset($owner[0])) {
+ $p->serendipity_owner = $owner[0];
+ }
}
return $p;
@@ -352,7 +364,7 @@
$pluginData = array();
foreach ($plugins as $plugin_data) {
- $plugin =& serendipity_plugin_api::load_plugin($plugin_data['name'], $plugin_data['authorid']);
+ $plugin =& serendipity_plugin_api::load_plugin($plugin_data['name'], $plugin_data['authorid'], $plugin_data['path']);
$class = get_class($plugin);
$title = '';
@@ -438,7 +450,7 @@
$event_plugins = array();
foreach($plugins AS $plugin_data) {
- if ($event_plugins[$plugin_data['name']]['p'] = &serendipity_plugin_api::load_plugin($plugin_data['name'], $plugin_data['authorid'])) {
+ if ($event_plugins[$plugin_data['name']]['p'] = &serendipity_plugin_api::load_plugin($plugin_data['name'], $plugin_data['authorid'], $plugin_data['path'])) {
/* query for its name, description and configuration data */
$event_plugins[$plugin_data['name']]['b'] = new serendipity_property_bag;
$event_plugins[$plugin_data['name']]['p']->introspect($event_plugins[$plugin_data['name']]['b']);
@@ -502,6 +514,21 @@
return false;
}
+
+ function &autodetect_instance($plugin_name, $authorid, $is_event_plugin = false) {
+ if ($is_event_plugin) {
+ $side = 'event';
+ } else {
+ $side = 'right';
+ }
+
+ $classes = serendipity_plugin_api::enum_plugin_classes(null);
+ if (isset($classes[$plugin_name])) {
+ return serendipity_plugin_api::create_plugin_instance($plugin_name, null, $side, $authorid, $classes[$plugin_name]['pluginPath']);
+ } else {
+ return false;
+ }
+ }
}
/* holds a bunch of properties; since serendipity 0.8 only one value per key is allowed [was never really useful] */
@@ -668,9 +695,9 @@
$exists = serendipity_plugin_api::exists($dependency);
if (!$exists) {
if (serendipity_plugin_api::is_event_plugin($dependency)) {
- $keys[] = serendipity_plugin_api::create_plugin_instance($dependency, null, 'event', $authorid);
+ $keys[] = serendipity_plugin_api::autodetect_instance($dependency, $authorid, true);
} else {
- $keys[] = serendipity_plugin_api::create_plugin_instance($dependency, null, 'right', $authorid);
+ $keys[] = serendipity_plugin_api::autodetect_instance($dependency, $authorid, false);
}
} else {
$keys[] = $exists;
|