From a63f14ec4045e82f47b237663bcf09939a0eadc5 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Sat, 29 Aug 2015 01:52:57 -0400 Subject: [PATCH] Emoticons-related code refactoring --- plugins/emoticons/emoticons.php | 208 +++++++++++++++++++++++++++++++++++++++------------ 1 files changed, 158 insertions(+), 50 deletions(-) diff --git a/plugins/emoticons/emoticons.php b/plugins/emoticons/emoticons.php index f3f987a..cb90b6f 100644 --- a/plugins/emoticons/emoticons.php +++ b/plugins/emoticons/emoticons.php @@ -1,9 +1,10 @@ <?php /** - * Display Emoticons + * Emoticons * - * Sample plugin to replace emoticons in plain text message body with real icons + * Plugin to replace emoticons in plain text message body with real icons. + * Also it enables emoticons in HTML compose editor. Both features are optional. * * @version @package_version@ * @license GNU GPLv3+ @@ -13,66 +14,173 @@ */ class emoticons extends rcube_plugin { - public $task = 'mail'; + public $task = 'mail|settings|utils'; + + /** + * Plugin initilization. + */ function init() { - $this->add_hook('message_part_after', array($this, 'replace')); + $rcube = rcube::get_instance(); + + $this->add_hook('message_part_after', array($this, 'message_part_after')); + $this->add_hook('message_outgoing_body', array($this, 'message_outgoing_body')); + $this->add_hook('html2text', array($this, 'html2text')); + $this->add_hook('html_editor', array($this, 'html_editor')); + + if ($rcube->task == 'settings') { + $this->add_hook('preferences_list', array($this, 'preferences_list')); + $this->add_hook('preferences_save', array($this, 'preferences_save')); + } } - function replace($args) + /** + * 'message_part_after' hook handler to replace common plain text emoticons + * with emoticon images (<img>) + */ + function message_part_after($args) { - // This is a lookbehind assertion which will exclude html entities - // E.g. situation when ";)" in "")" shouldn't be replaced by the icon - // It's so long because of assertion format restrictions - $entity = '(?<!&' - . '[a-zA-Z0-9]{2}' . '|' . '#[0-9]{2}' . '|' - . '[a-zA-Z0-9]{3}' . '|' . '#[0-9]{3}' . '|' - . '[a-zA-Z0-9]{4}' . '|' . '#[0-9]{4}' . '|' - . '[a-zA-Z0-9]{5}' . '|' - . '[a-zA-Z0-9]{6}' . '|' - . '[a-zA-Z0-9]{7}' - . ')'; - - // map of emoticon replacements - $map = array( - '/(?<!mailto):D/' => $this->img_tag('smiley-laughing.gif', ':D' ), - '/:-D/' => $this->img_tag('smiley-laughing.gif', ':-D' ), - '/:\(/' => $this->img_tag('smiley-frown.gif', ':(' ), - '/:-\(/' => $this->img_tag('smiley-frown.gif', ':-(' ), - '/'.$entity.';\)/' => $this->img_tag('smiley-wink.gif', ';)' ), - '/'.$entity.';-\)/' => $this->img_tag('smiley-wink.gif', ';-)' ), - '/8\)/' => $this->img_tag('smiley-cool.gif', '8)' ), - '/8-\)/' => $this->img_tag('smiley-cool.gif', '8-)' ), - '/(?<!mailto):O/i' => $this->img_tag('smiley-surprised.gif', ':O' ), - '/(?<!mailto):-O/i' => $this->img_tag('smiley-surprised.gif', ':-O' ), - '/(?<!mailto):P/i' => $this->img_tag('smiley-tongue-out.gif', ':P' ), - '/(?<!mailto):-P/i' => $this->img_tag('smiley-tongue-out.gif', ':-P' ), - '/(?<!mailto):@/i' => $this->img_tag('smiley-yell.gif', ':@' ), - '/(?<!mailto):-@/i' => $this->img_tag('smiley-yell.gif', ':-@' ), - '/O:\)/i' => $this->img_tag('smiley-innocent.gif', 'O:)' ), - '/O:-\)/i' => $this->img_tag('smiley-innocent.gif', 'O:-)' ), - '/(?<!O):\)/' => $this->img_tag('smiley-smile.gif', ':)' ), - '/(?<!O):-\)/' => $this->img_tag('smiley-smile.gif', ':-)' ), - '/(?<!mailto):\$/' => $this->img_tag('smiley-embarassed.gif', ':$' ), - '/(?<!mailto):-\$/' => $this->img_tag('smiley-embarassed.gif', ':-$' ), - '/(?<!mailto):\*/i' => $this->img_tag('smiley-kiss.gif', ':*' ), - '/(?<!mailto):-\*/i' => $this->img_tag('smiley-kiss.gif', ':-*' ), - '/(?<!mailto):S/i' => $this->img_tag('smiley-undecided.gif', ':S' ), - '/(?<!mailto):-S/i' => $this->img_tag('smiley-undecided.gif', ':-S' ), - ); - if ($args['type'] == 'plain') { - $args['body'] = preg_replace( - array_keys($map), array_values($map), $args['body']); + $this->load_config(); + + $rcube = rcube::get_instance(); + if (!$rcube->config->get('emoticons_display', false)) { + return $args; + } + + require_once __DIR__ . '/emoticons_engine.php'; + + $args['body'] = emoticons_engine::text2icons($args['body']); } return $args; } - private function img_tag($ico, $title) + /** + * 'message_outgoing_body' hook handler to replace image emoticons from TinyMCE + * editor with image attachments. + */ + function message_outgoing_body($args) { - $path = './program/js/tinymce/plugins/emoticons/img/'; - return html::img(array('src' => $path.$ico, 'title' => $title)); + if ($args['type'] == 'html') { + $this->load_config(); + + $rcube = rcube::get_instance(); + if (!$rcube->config->get('emoticons_compose', true)) { + return $args; + } + + require_once __DIR__ . '/emoticons_engine.php'; + + // look for "emoticon" images from TinyMCE and change their src paths to + // be file paths on the server instead of URL paths. + $images = emoticons_engine::replace($args['body']); + + // add these images as attachments to the MIME message + foreach ($images as $img_name => $img_file) { + $args['message']->addHTMLImage($img_file, 'image/gif', '', true, $img_name); + } + } + + return $args; + } + + /** + * 'html2text' hook handler to replace image emoticons from TinyMCE + * editor with plain text emoticons. + * + * This is executed on html2text action, i.e. when switching from HTML to text + * in compose window (or similiar place). Also when generating alternative + * text/plain part. + */ + function html2text($args) + { + $rcube = rcube::get_instance(); + + if ($rcube->action == 'html2text' || $rcube->action == 'send') { + $this->load_config(); + + if (!$rcube->config->get('emoticons_compose', true)) { + return $args; + } + + require_once __DIR__ . '/emoticons_engine.php'; + + $args['body'] = emoticons_engine::icons2text($args['body']); + } + + return $args; + } + + /** + * 'html_editor' hook handler, where we enable emoticons in TinyMCE + */ + function html_editor($args) + { + $rcube = rcube::get_instance(); + + $this->load_config(); + + if (!$rcube->config->get('emoticons_compose', true)) { + $args['disabled_plugins'][] = 'emoticons'; + $args['disabled_buttons'][] = 'emoticons'; + } + + return $args; + } + + /** + * 'preferences_list' hook handler + */ + function preferences_list($args) + { + $rcube = rcube::get_instance(); + $dont_override = $rcube->config->get('dont_override', array()); + + if ($args['section'] == 'mailview' && !in_array('emoticons_display', $dont_override)) { + $this->load_config(); + $this->add_texts('localization'); + + $field_id = 'emoticons_display'; + $checkbox = new html_checkbox(array('name' => '_' . $field_id, 'id' => $field_id, 'value' => 1)); + + $args['blocks']['main']['options']['emoticons_display'] = array( + 'title' => $this->gettext('emoticonsdisplay'), + 'content' => $checkbox->show(intval($rcube->config->get('emoticons_display', false))) + ); + } + else if ($args['section'] == 'compose' && !in_array('emoticons_compose', $dont_override)) { + $this->load_config(); + $this->add_texts('localization'); + + $field_id = 'emoticons_compose'; + $checkbox = new html_checkbox(array('name' => '_' . $field_id, 'id' => $field_id, 'value' => 1)); + + $args['blocks']['main']['options']['emoticons_compose'] = array( + 'title' => $this->gettext('emoticonscompose'), + 'content' => $checkbox->show(intval($rcube->config->get('emoticons_compose', true))) + ); + } + + return $args; + } + + /** + * 'preferences_save' hook handler + */ + function preferences_save($args) + { + $rcube = rcube::get_instance(); + $dont_override = $rcube->config->get('dont_override', array()); + + if ($args['section'] == 'mailview' && !in_array('emoticons_display', $dont_override)) { + $args['prefs']['emoticons_display'] = rcube_utils::get_input_value('_emoticons_display', rcube_utils::INPUT_POST) ? true : false; + } + else if ($args['section'] == 'compose' && !in_array('emoticons_compose', $dont_override)) { + $args['prefs']['emoticons_compose'] = rcube_utils::get_input_value('_emoticons_compose', rcube_utils::INPUT_POST) ? true : false; + } + + return $args; } } -- Gitblit v1.9.1