diff options
| -rw-r--r-- | plugins/vcard_attachments/package.xml | 71 | ||||
| -rw-r--r-- | plugins/vcard_attachments/vcard_attachments.php | 239 | ||||
| -rw-r--r-- | plugins/vcard_attachments/vcardattach.js | 5 |
3 files changed, 215 insertions, 100 deletions
diff --git a/plugins/vcard_attachments/package.xml b/plugins/vcard_attachments/package.xml new file mode 100644 index 000000000..e10b4a84c --- /dev/null +++ b/plugins/vcard_attachments/package.xml @@ -0,0 +1,71 @@ +<?xml version="1.0" encoding="UTF-8"?> +<package xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" packagerversion="1.9.0" version="2.0" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 + http://pear.php.net/dtd/tasks-1.0.xsd + http://pear.php.net/dtd/package-2.0 + http://pear.php.net/dtd/package-2.0.xsd"> + <name>vcard_attachments</name> + <channel>pear.roundcube.net</channel> + <summary>vCard handler for Roundcube</summary> + <description>This plugin detects vCard attachments/bodies and shows a button(s) to add them to address book</description> + <lead> + <name>Thomas Bruederli</name> + <user>thomasb</user> + <email>roundcube@gmail.com</email> + <active>yes</active> + </lead> + <lead> + <name>Aleksander Machniak</name> + <user>alec</user> + <email>alec@alec.pl</email> + <active>yes</active> + </lead> + <date>2010-04-28</date> + <time>12:00:00</time> + <version> + <release>2.0</release> + <api>2.0</api> + </version> + <stability> + <release>stable</release> + <api>stable</api> + </stability> + <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license> + <notes> +- Added support for Content-Type: text/directory; profile=vCard +- Added handler for message bodies of type vCard (#1486683) +- Added support for more than one vCard attachment/body +- Added support for more than one contact in one vCard file +- Created package.xml + </notes> + <contents> + <dir baseinstalldir="/" name="/"> + <file name="vcard_attachments.php" role="php"> + <tasks:replace from="@name@" to="name" type="package-info"/> + <tasks:replace from="@package_version@" to="version" type="package-info"/> + </file> + <file name="vcardattach.js" role="data"> + <tasks:replace from="@name@" to="name" type="package-info"/> + <tasks:replace from="@package_version@" to="version" type="package-info"/> + </file> + <file name="localization/en_US.inc" role="data"></file> + <file name="localization/de_CH.inc" role="data"></file> + <file name="localization/de_DE.inc" role="data"></file> + <file name="localization/pl_PL.inc" role="data"></file> + <file name="localization/ru_RU.inc" role="data"></file> + <file name="localization/sv_SE.inc" role="data"></file> + <file name="vcard_add_contact.png" role="data"></file> + </dir> + <!-- / --> + </contents> + <dependencies> + <required> + <php> + <min>5.2.1</min> + </php> + <pearinstaller> + <min>1.7.0</min> + </pearinstaller> + </required> + </dependencies> + <phprelease/> +</package> diff --git a/plugins/vcard_attachments/vcard_attachments.php b/plugins/vcard_attachments/vcard_attachments.php index d23cf37b1..9706bb2db 100644 --- a/plugins/vcard_attachments/vcard_attachments.php +++ b/plugins/vcard_attachments/vcard_attachments.php @@ -3,117 +3,158 @@ /** * Detect VCard attachments and show a button to add them to address book * - * @version 1.0 - * @author Thomas Bruederli + * @version @package_version@ + * @author Thomas Bruederli, Aleksander Machniak */ class vcard_attachments extends rcube_plugin { - public $task = 'mail'; - - private $message; - private $vcard_part; + public $task = 'mail'; - function init() - { - $rcmail = rcmail::get_instance(); - if ($rcmail->action == 'show' || $rcmail->action == 'preview') { - $this->add_hook('message_load', array($this, 'message_load')); - $this->add_hook('template_object_messagebody', array($this, 'html_output')); + private $message; + private $vcard_parts = array(); + private $vcard_bodies = array(); + + function init() + { + $rcmail = rcmail::get_instance(); + if ($rcmail->action == 'show' || $rcmail->action == 'preview') { + $this->add_hook('message_load', array($this, 'message_load')); + $this->add_hook('template_object_messagebody', array($this, 'html_output')); + } + + $this->register_action('plugin.savevcard', array($this, 'save_vcard')); } + + /** + * Check message attachments for vcards + */ + function message_load($p) + { + $this->message = $p['object']; - $this->register_action('plugin.savevcard', array($this, 'save_vcard')); - } - - /** - * Check message attachments for vcards - */ - function message_load($p) - { - $this->message = $p['object']; - - foreach ((array)$this->message->attachments as $attachment) { - if (in_array($attachment->mimetype, array('text/vcard', 'text/x-vcard'))) - $this->vcard_part = $attachment->mime_id; + // handle attachments with specified content type: + // Content-Type: text/vcard; + // Content-Type: text/x-vcard; + // Content-Type: text/directory; profile=vCard; + foreach ((array)$this->message->attachments as $attachment) { + if ($attachment->mimetype == 'text/vcard' || + $attachment->mimetype == 'text/x-vcard' || + ($attachment->mimetype == 'text/directory' && $attachment->ctype_parameters['profile'] + && strtolower($attachment->ctype_parameters['profile']) == 'vcard') + ) { + $this->vcard_parts[] = $attachment->mime_id; + } + } + // the same with message bodies + foreach ((array)$this->message->parts as $idx => $part) { + if ($part->mimetype == 'text/vcard' || + $part->mimetype == 'text/x-vcard' || + ($part->mimetype == 'text/directory' && $part->ctype_parameters['profile'] + && strtolower($part->ctype_parameters['profile']) == 'vcard') + ) { + $this->vcard_parts[] = $part->mime_id; + $this->vcard_bodies[] = $part->mime_id; + } + } + + if ($this->vcard_parts) + $this->add_texts('localization'); } - if ($this->vcard_part) - $this->add_texts('localization'); - } - - /** - * This callback function adds a box below the message content - * if there is a vcard attachment available - */ - function html_output($p) - { - if ($this->vcard_part) { - $vcard = new rcube_vcard($this->message->get_part_content($this->vcard_part)); - - // successfully parsed vcard - if ($vcard->displayname) { - $display = $vcard->displayname; - if ($vcard->email[0]) - $display .= ' <'.$vcard->email[0].'>'; - - // add box below messsage body - $p['content'] .= html::p(array('style' => "margin:1em; padding:0.5em; border:1px solid #999; border-radius:4px; -moz-border-radius:4px; -webkit-border-radius:4px; width: auto;"), - html::a(array( - 'href' => "#", - 'onclick' => "return plugin_vcard_save_contact('".JQ($this->vcard_part)."')", - 'title' => $this->gettext('addvardmsg')), - html::img(array('src' => $this->url('vcard_add_contact.png'), 'align' => "middle"))) - . ' ' . html::span(null, Q($display))); - - $this->include_script('vcardattach.js'); - } + /** + * This callback function adds a box below the message content + * if there is a vcard attachment available + */ + function html_output($p) + { + $attach_script = false; + + foreach ($this->vcard_parts as $part) { + $vcards = rcube_vcard::import($this->message->get_part_content($part)); + + // successfully parsed vcards? + if (empty($vcards)) + continue; + + // remove part's body + if (in_array($part, $this->vcard_bodies)) + $p['content'] = ''; + + foreach ($vcards as $idx => $vcard) { + $display = $vcard->displayname; + if ($vcard->email[0]) + $display .= ' <'.$vcard->email[0].'>'; + + // add box below messsage body + $p['content'] .= html::p(array('style' => "margin:0.5em 1em; padding:0.2em 0.5em; border:1px solid #999; border-radius:4px; -moz-border-radius:4px; -webkit-border-radius:4px; width: auto"), + html::a(array( + 'href' => "#", + 'onclick' => "return plugin_vcard_save_contact('".JQ($part.':'.$idx)."')", + 'title' => $this->gettext('addvardmsg')), + html::img(array('src' => $this->url('vcard_add_contact.png'), + 'style' => "vertical-align:middle"))) + . ' ' . html::span(null, Q($display))); + } + + $attach_script = true; + } + + if ($attach_script) + $this->include_script('vcardattach.js'); + + return $p; } - - return $p; - } - - /** - * Handler for request action - */ - function save_vcard() - { - $this->add_texts('localization', true); - $uid = get_input_value('_uid', RCUBE_INPUT_POST); - $mbox = get_input_value('_mbox', RCUBE_INPUT_POST); - $mime_id = get_input_value('_part', RCUBE_INPUT_POST); - - $rcmail = rcmail::get_instance(); - $part = $uid && $mime_id ? $rcmail->imap->get_message_part($uid, $mime_id) : null; - - $error_msg = $this->gettext('vcardsavefailed'); + /** + * Handler for request action + */ + function save_vcard() + { + $this->add_texts('localization', true); + + $uid = get_input_value('_uid', RCUBE_INPUT_POST); + $mbox = get_input_value('_mbox', RCUBE_INPUT_POST); + $mime_id = get_input_value('_part', RCUBE_INPUT_POST); + + $rcmail = rcmail::get_instance(); + + if ($uid && $mime_id) { + list($mime_id, $index) = explode(':', $mime_id); + $part = $rcmail->imap->get_message_part($uid, $mime_id); + } + + $error_msg = $this->gettext('vcardsavefailed'); - if ($part && ($vcard = new rcube_vcard($part)) && $vcard->displayname && $vcard->email) { - $contacts = $rcmail->get_address_book(null, true); + if ($part && ($vcards = rcube_vcard::import($part)) + && ($vcard = $vcards[$index]) && $vcard->displayname && $vcard->email) { + + $contacts = $rcmail->get_address_book(null, true); - // check for existing contacts - $existing = $contacts->search('email', $vcard->email[0], true, false); - if ($done = $existing->count) { - $rcmail->output->command('display_message', $this->gettext('contactexists'), 'warning'); - } - else { - // add contact - $success = $contacts->insert(array( - 'name' => $vcard->displayname, - 'firstname' => $vcard->firstname, - 'surname' => $vcard->surname, - 'email' => $vcard->email[0], - 'vcard' => $vcard->export(), - )); - - if ($success) - $rcmail->output->command('display_message', $this->gettext('addedsuccessfully'), 'confirmation'); + // check for existing contacts + $existing = $contacts->search('email', $vcard->email[0], true, false); + if ($existing->count) { + $rcmail->output->command('display_message', $this->gettext('contactexists'), 'warning'); + } + else { + // add contact + $success = $contacts->insert(array( + 'name' => $vcard->displayname, + 'firstname' => $vcard->firstname, + 'surname' => $vcard->surname, + 'email' => $vcard->email[0], + 'vcard' => $vcard->export(), + )); + + if ($success) + $rcmail->output->command('display_message', $this->gettext('addedsuccessfully'), 'confirmation'); + else + $rcmail->output->command('display_message', $error_msg, 'error'); + } + } else - $rcmail->output->command('display_message', $error_msg, 'error'); - } - } - else - $rcmail->output->command('display_message', $error_msg, 'error'); + $rcmail->output->command('display_message', $error_msg, 'error'); - $rcmail->output->send(); - } + $rcmail->output->send(); + } + } diff --git a/plugins/vcard_attachments/vcardattach.js b/plugins/vcard_attachments/vcardattach.js index e03e5084d..021087edc 100644 --- a/plugins/vcard_attachments/vcardattach.js +++ b/plugins/vcard_attachments/vcardattach.js @@ -1,4 +1,7 @@ - +/* + * vcard_attachments plugin script + * @version @package_version@ + */ function plugin_vcard_save_contact(mime_id) { rcmail.set_busy(true, 'loading'); |
