From de89d46be24f6b3454a0c0e62973af947b22ff29 Mon Sep 17 00:00:00 2001 From: corbosman Date: Tue, 6 Jan 2015 21:48:39 +0100 Subject: Load plugins before sessions have started Move the plugin loading phase to before sessions have started allowing plugins to add session drivers. Plugins that want to use this should define an "onload" method in their plugins. This method does not have access to variables like $task as they are not yet initialised at that time. --- program/include/rcmail.php | 8 ++++-- program/lib/Roundcube/rcube_plugin_api.php | 45 +++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/program/include/rcmail.php b/program/include/rcmail.php index a16319f72..306e5938a 100644 --- a/program/include/rcmail.php +++ b/program/include/rcmail.php @@ -93,6 +93,10 @@ class rcmail extends rcube $this->filename = $basename; } + // load all configured plugins + $this->plugins->load_plugins((array)$this->config->get('plugins', array()), + array('filesystem_attachments', 'jqueryui')); + // start session $this->session_init(); @@ -124,10 +128,8 @@ class rcmail extends rcube $GLOBALS['OUTPUT'] = $this->load_gui(!empty($_REQUEST['_framed'])); } - // load plugins + // run init method on all the plugins $this->plugins->init($this, $this->task); - $this->plugins->load_plugins((array)$this->config->get('plugins', array()), - array('filesystem_attachments', 'jqueryui')); } /** diff --git a/program/lib/Roundcube/rcube_plugin_api.php b/program/lib/Roundcube/rcube_plugin_api.php index c74162619..ba5dffefd 100644 --- a/program/lib/Roundcube/rcube_plugin_api.php +++ b/program/lib/Roundcube/rcube_plugin_api.php @@ -34,6 +34,8 @@ class rcube_plugin_api public $dir; public $url = 'plugins/'; public $task = ''; + public $initialized = false; + public $output; public $handlers = array(); public $allowed_prefs = array(); @@ -117,12 +119,20 @@ class rcube_plugin_api { $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->filter($plugin)) { + $plugin->init(); + } + } + + // we have finished initializing all plugins + $this->initialized = true; } /** @@ -203,14 +213,22 @@ class rcube_plugin_api // 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'])) - ) { + + // 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(); + } + + // init a plugin only if $force is set or if we're called after initialization + if (($force || $this->initialized) + && !$this->filter($plugin)) + { $plugin->init(); - $this->plugins[$plugin_name] = $plugin; } + $this->plugins[$plugin_name] = $plugin; + if (!empty($plugin->allowed_prefs)) { $this->allowed_prefs = array_merge($this->allowed_prefs, $plugin->allowed_prefs); } @@ -234,6 +252,19 @@ class rcube_plugin_api return false; } + /** + * 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']))) ? true : false; + } + /** * Get information about a specific plugin. * This is either provided my a plugin's info() method or extracted from a package.xml or a composer.json file -- cgit v1.2.3 From 3e0ad293e118a078d227ca15aaab7cf6cbdb0851 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 18 Feb 2015 07:30:48 -0500 Subject: Fix PHP fatal error when visiting Vacation interface and there's no sieve script yet --- plugins/managesieve/Changelog | 2 + .../lib/Roundcube/rcube_sieve_engine.php | 6 +- .../lib/Roundcube/rcube_sieve_vacation.php | 94 ++++++++++++---------- 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog index 5255d5b6b..8ce63c811 100644 --- a/plugins/managesieve/Changelog +++ b/plugins/managesieve/Changelog @@ -1,3 +1,5 @@ +- Fix PHP fatal error when visiting Vacation interface and there's no sieve script yet + * version 8.2 [2015-01-14] ----------------------------------------------------------- - Fix bug where actions without if/elseif/else in sieve scripts were skipped diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php index d412e17db..69ae4b8a6 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php @@ -2344,12 +2344,12 @@ class rcube_sieve_engine */ protected function init_script() { - $this->script = $this->sieve->script->as_array(); - - if (!$this->script) { + if (!$this->sieve->script) { return; } + $this->script = $this->sieve->script->as_array(); + $headers = array(); $exceptions = array('date', 'currentdate', 'size', 'body'); diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php index 28fd80125..8d865008f 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php @@ -562,62 +562,74 @@ class rcube_sieve_vacation extends rcube_sieve_engine $this->script_name = 'roundcube'; } - $this->script = array($rule); - $script_active = false; + // use default script contents + if (!$this->rc->config->get('managesieve_kolab_master')) { + $script_file = $this->rc->config->get('managesieve_default'); + if ($script_file && is_readable($script_file)) { + $content = file_get_contents($script_file); + } + } + + // create and load script + if ($this->sieve->save_script($this->script_name, $content)) { + $this->sieve->load($this->script_name); + } } - // if script exists - else { - $script_active = in_array($this->script_name, $this->active); - // re-order rules if needed - if (isset($rule['after']) && $rule['after'] !== '') { - // reset original vacation rule - if (isset($this->vacation['idx'])) { - $this->script[$this->vacation['idx']] = null; - } + $script_active = in_array($this->script_name, $this->active); - // add at target position - if ($rule['after'] >= count($this->script) - 1) { - $this->script[] = $rule; - } - else { - $script = array(); + // re-order rules if needed + if (isset($rule['after']) && $rule['after'] !== '') { + // reset original vacation rule + if (isset($this->vacation['idx'])) { + $this->script[$this->vacation['idx']] = null; + } - foreach ($this->script as $idx => $r) { - if ($r) { - $script[] = $r; - } + // add at target position + if ($rule['after'] >= count($this->script) - 1) { + $this->script[] = $rule; + } + else { + $script = array(); - if ($idx == $rule['after']) { - $script[] = $rule; - } + foreach ($this->script as $idx => $r) { + if ($r) { + $script[] = $r; } - $this->script = $script; + if ($idx == $rule['after']) { + $script[] = $rule; + } } - $this->script = array_values(array_filter($this->script)); - } - // update original vacation rule if it exists - else if (isset($this->vacation['idx'])) { - $this->script[$this->vacation['idx']] = $rule; - } - // otherwise put vacation rule on top - else { - array_unshift($this->script, $rule); + $this->script = $script; } - // if the script was not active, we need to de-activate - // all rules except the vacation rule, but only if it is not disabled - if (!$script_active && !$rule['disabled']) { - foreach ($this->script as $idx => $r) { - if (empty($r['actions']) || $r['actions'][0]['type'] != 'vacation') { - $this->script[$idx]['disabled'] = true; - } + $this->script = array_values(array_filter($this->script)); + } + // update original vacation rule if it exists + else if (isset($this->vacation['idx'])) { + $this->script[$this->vacation['idx']] = $rule; + } + // otherwise put vacation rule on top + else { + array_unshift($this->script, $rule); + } + + // if the script was not active, we need to de-activate + // all rules except the vacation rule, but only if it is not disabled + if (!$script_active && !$rule['disabled']) { + foreach ($this->script as $idx => $r) { + if (empty($r['actions']) || $r['actions'][0]['type'] != 'vacation') { + $this->script[$idx]['disabled'] = true; } } } + if (!$this->sieve->script) { + return false; + } + $this->sieve->script->content = $this->script; // save the script -- cgit v1.2.3 From d67071f228ea39e22d5109f800b68efaf7146d4b Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 18 Feb 2015 08:47:08 -0500 Subject: Fix saving/sending emoticon images when assets_dir is set (Kolab #4608) --- program/steps/mail/sendmail.inc | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc index 715ee32cf..5843de43f 100644 --- a/program/steps/mail/sendmail.inc +++ b/program/steps/mail/sendmail.inc @@ -765,8 +765,10 @@ function rcmail_fix_emoticon_paths($mime_message) // remove any null-byte characters before parsing $body = preg_replace('/\x00/', '', $body); - $searchstr = 'program/js/tinymce/plugins/emoticons/img/'; - $offset = 0; + $searchstr = 'program/js/tinymce/plugins/emoticons/img/'; + $assets_dir = $RCMAIL->config->get('assets_dir'); + $path = ($assets_dir ?: INSTALL_PATH) . '/' . $searchstr; + $offset = 0; // keep track of added images, so they're only added once $included_images = array(); @@ -779,12 +781,14 @@ function rcmail_fix_emoticon_paths($mime_message) // sanitize image name so resulting attachment doesn't leave images dir $image_name = preg_replace('/[^a-zA-Z0-9_\.\-]/i', '', $image_name); - $img_file = INSTALL_PATH . '/' . $searchstr . $image_name; + $img_file = $path . $image_name; - if (! in_array($image_name, $included_images)) { + if (!in_array($image_name, $included_images)) { // add the image to the MIME message - if (!$mime_message->addHTMLImage($img_file, 'image/gif', '', true, $image_name)) { + $res = $mime_message->addHTMLImage($img_file, 'image/gif', '', true, $image_name); + if (PEAR::isError($res)) { $RCMAIL->output->show_message("emoticonerror", 'error'); + continue; } array_push($included_images, $image_name); -- cgit v1.2.3 From 31ed9162d1995b7603844ee49164744e16f1033b Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Wed, 18 Feb 2015 08:49:11 -0500 Subject: Update changelog --- CHANGELOG | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index ec400f2ad..f0f61fb73 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,8 @@ CHANGELOG Roundcube Webmail - Add possibility to print contact information (of a single contact) - Fix refreshing of drafts list when sending a message which was saved in meantime (#1490238) +- Fix saving/sending emoticon images when assets_dir is set +- Fix PHP fatal error when visiting Vacation interface and there's no sieve script yet RELEASE 1.1.0 ------------- -- cgit v1.2.3