From 2965a981b7ec22866fbdf2d567d87e2d068d3617 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli <thomas@roundcube.net> Date: Fri, 31 Jul 2015 16:04:08 -0400 Subject: [PATCH] Allow to search and import missing PGP pubkeys from keyservers using Publickey.js --- program/lib/Roundcube/rcube_plugin_api.php | 119 ++++++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 77 insertions(+), 42 deletions(-) diff --git a/program/lib/Roundcube/rcube_plugin_api.php b/program/lib/Roundcube/rcube_plugin_api.php index 346e832..ce727e2 100644 --- a/program/lib/Roundcube/rcube_plugin_api.php +++ b/program/lib/Roundcube/rcube_plugin_api.php @@ -34,6 +34,8 @@ public $dir; public $url = 'plugins/'; public $task = ''; + public $initialized = false; + public $output; public $handlers = array(); public $allowed_prefs = array(); @@ -41,6 +43,7 @@ public $active_plugins = array(); protected $plugins = array(); + protected $plugins_initialized = array(); protected $tasks = array(); protected $actions = array(); protected $actionmap = array(); @@ -85,12 +88,21 @@ { $this->task = $task; $this->output = $app->output; - // register an internal hook $this->register_hook('template_container', array($this, 'template_container_hook')); - // maybe also register a shudown function which triggers // shutdown functions of all plugin objects + + foreach ($this->plugins as $plugin) { + // ... task, request type and framed mode + if (!$this->plugins_initialized[$plugin_name] && !$this->filter($plugin)) { + $plugin->init(); + $this->plugins_initialized[$plugin->ID] = $plugin; + } + } + + // we have finished initializing all plugins + $this->initialized = true; } /** @@ -136,7 +148,7 @@ /** * Load the specified plugin * - * @param string Plugin name + * @param string Plugin name * @param boolean Force loading of the plugin even if it doesn't match the filter * @param boolean Require loading of the plugin, error if it doesn't exist * @@ -151,55 +163,75 @@ $plugins_dir = unslashify($dir->path); } - // plugin already loaded - if ($this->plugins[$plugin_name]) { - return true; - } + // plugin already loaded? + if (!$this->plugins[$plugin_name]) { + $fn = "$plugins_dir/$plugin_name/$plugin_name.php"; - $fn = "$plugins_dir/$plugin_name/$plugin_name.php"; + if (!is_readable($fn)) { + if ($require) { + rcube::raise_error(array('code' => 520, 'type' => 'php', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Failed to load plugin file $fn"), true, false); + } - if (is_readable($fn)) { + return false; + } + if (!class_exists($plugin_name, false)) { include $fn; } // instantiate class if exists - if (class_exists($plugin_name, false)) { - $plugin = new $plugin_name($this); - $this->active_plugins[] = $plugin_name; - - // check inheritance... - if (is_subclass_of($plugin, 'rcube_plugin')) { - // ... task, request type and framed mode - if (($force || !$plugin->task || preg_match('/^('.$plugin->task.')$/i', $this->task)) - && (!$plugin->noajax || (is_object($this->output) && $this->output->type == 'html')) - && (!$plugin->noframe || empty($_REQUEST['_framed'])) - ) { - $plugin->init(); - $this->plugins[$plugin_name] = $plugin; - } - - if (!empty($plugin->allowed_prefs)) { - $this->allowed_prefs = array_merge($this->allowed_prefs, $plugin->allowed_prefs); - } - - return true; - } - } - else { + if (!class_exists($plugin_name, false)) { rcube::raise_error(array('code' => 520, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "No plugin class $plugin_name found in $fn"), true, false); + + return false; + } + + $plugin = new $plugin_name($this); + $this->active_plugins[] = $plugin_name; + + // check inheritance... + if (is_subclass_of($plugin, 'rcube_plugin')) { + // call onload method on plugin if it exists. + // this is useful if you want to be called early in the boot process + if (method_exists($plugin, 'onload')) { + $plugin->onload(); + } + + if (!empty($plugin->allowed_prefs)) { + $this->allowed_prefs = array_merge($this->allowed_prefs, $plugin->allowed_prefs); + } + + $this->plugins[$plugin_name] = $plugin; } } - else if ($require) { - rcube::raise_error(array('code' => 520, 'type' => 'php', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Failed to load plugin file $fn"), true, false); + + if ($plugin = $this->plugins[$plugin_name]) { + // init a plugin only if $force is set or if we're called after initialization + if (($force || $this->initialized) && !$this->plugins_initialized[$plugin_name] && ($force || !$this->filter($plugin))) { + $plugin->init(); + $this->plugins_initialized[$plugin_name] = $plugin; + } } - return false; + return true; + } + + /** + * check if we should prevent this plugin from initialising + * + * @param $plugin + * @return bool + */ + private function filter($plugin) + { + return ($plugin->noajax && !(is_object($this->output) && $this->output->type == 'html')) + || ($plugin->task && !preg_match('/^('.$plugin->task.')$/i', $this->task)) + || ($plugin->noframe && !empty($_REQUEST['_framed'])); } /** @@ -374,9 +406,11 @@ */ public function unregister_hook($hook, $callback) { - $callback_id = array_search($callback, $this->handlers[$hook]); + $callback_id = array_search($callback, (array) $this->handlers[$hook]); if ($callback_id !== false) { - unset($this->handlers[$hook][$callback_id]); + // array_splice() removes the element and re-indexes keys + // that is required by the 'for' loop in exec_hook() below + array_splice($this->handlers[$hook], $callback_id, 1); } } @@ -395,13 +429,14 @@ $args = array('arg' => $args); } - // TODO: avoid recusion by checking in_array($hook, $this->exec_stack) ? + // TODO: avoid recursion by checking in_array($hook, $this->exec_stack) ? $args += array('abort' => false); array_push($this->exec_stack, $hook); - foreach ((array)$this->handlers[$hook] as $callback) { - $ret = call_user_func($callback, $args); + // Use for loop here, so handlers added in the hook will be executed too + for ($i = 0; $i < count($this->handlers[$hook]); $i++) { + $ret = call_user_func($this->handlers[$hook][$i], $args); if ($ret && is_array($ret)) { $args = $ret + $args; } -- Gitblit v1.9.1