Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2531037
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/plugins/vcard_attachments/package.xml b/plugins/vcard_attachments/package.xml
index 82b750ad5..9fdf0acf2 100644
--- a/plugins/vcard_attachments/package.xml
+++ b/plugins/vcard_attachments/package.xml
@@ -1,141 +1,187 @@
<?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>2012-04-13</date>
- <time>12:00</time>
+ <date>2012-11-18</date>
<version>
- <release>3.1</release>
- <api>3.1</api>
+ <release>3.2</release>
+ <api>3.2</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>
-- Fixed doble urlencoding of vcard identifier
-- Fixed encoding when default charset is different than vcard charset
-- Improved vcards import to work as addressbook::import procedure (with validation and autofix)
-- Support IDNA
-- Import contacts to default addressbook
+- Skip invalid vcards (#1488788)
</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/be_BE.inc" role="data"></file>
+ <file name="localization/bs_BA.inc" role="data"></file>
+ <file name="localization/ca_ES.inc" role="data"></file>
<file name="localization/cs_CZ.inc" role="data"></file>
+ <file name="localization/cy_GB.inc" role="data"></file>
+ <file name="localization/da_DK.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/en_GB.inc" role="data"></file>
<file name="localization/en_US.inc" role="data"></file>
+ <file name="localization/eo.inc" role="data"></file>
<file name="localization/es_ES.inc" role="data"></file>
<file name="localization/et_EE.inc" role="data"></file>
+ <file name="localization/fa_IR.inc" role="data"></file>
+ <file name="localization/fi_FI.inc" role="data"></file>
+ <file name="localization/fr_FR.inc" role="data"></file>
<file name="localization/gl_ES.inc" role="data"></file>
+ <file name="localization/he_IL.inc" role="data"></file>
+ <file name="localization/hr_HR.inc" role="data"></file>
+ <file name="localization/hu_HU.inc" role="data"></file>
+ <file name="localization/hy_AM.inc" role="data"></file>
+ <file name="localization/id_ID.inc" role="data"></file>
<file name="localization/it_IT.inc" role="data"></file>
<file name="localization/ja_JP.inc" role="data"></file>
+ <file name="localization/ko_KR.inc" role="data"></file>
+ <file name="localization/lt_LT.inc" role="data"></file>
+ <file name="localization/lv_LV.inc" role="data"></file>
+ <file name="localization/ml_IN.inc" role="data"></file>
+ <file name="localization/mr_IN.inc" role="data"></file>
+ <file name="localization/nb_NB.inc" role="data"></file>
+ <file name="localization/nl_NL.inc" role="data"></file>
<file name="localization/pl_PL.inc" role="data"></file>
<file name="localization/pt_BR.inc" role="data"></file>
+ <file name="localization/pt_PT.inc" role="data"></file>
+ <file name="localization/ro_RO.inc" role="data"></file>
<file name="localization/ru_RU.inc" role="data"></file>
+ <file name="localization/si_LK.inc" role="data"></file>
+ <file name="localization/sk_SK.inc" role="data"></file>
+ <file name="localization/sl_SI.inc" role="data"></file>
+ <file name="localization/sr_CS.inc" role="data"></file>
<file name="localization/sv_SE.inc" role="data"></file>
+ <file name="localization/tr_TR.inc" role="data"></file>
+ <file name="localization/uk_UA.inc" role="data"></file>
+ <file name="localization/vi_VN.inc" role="data"></file>
+ <file name="localization/zh_CN.inc" role="data"></file>
<file name="localization/zh_TW.inc" role="data"></file>
<file name="skins/classic/style.css" role="data"></file>
<file name="skins/classic/vcard_add_contact.png" role="data"></file>
<file name="skins/classic/vcard.png" role="data"></file>
<file name="skins/larry/style.css" role="data"></file>
<file name="skins/larry/vcard_add_contact.png" role="data"></file>
<file name="skins/larry/vcard.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/>
<changelog>
<release>
<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>
</release>
<release>
<date>2012-03-11</date>
<time>19:00:00</time>
<version>
<release>3.1</release>
<api>3.1</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>
- Add styles for new skin "Larry"
</notes>
</release>
<release>
<date>2012-03-11</date>
<time>19:00</time>
<version>
<release>3.1-beta</release>
<api>3.1-beta</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>
- Add styles for new skin "Larry"
- Exec contact_create hook when adding contact (#1486964)
- Make icons skinable
- Display vcard icon on messages list when message is of type vcard
- </notes>
- </release>
- </changelog>
+ </notes>
+ </release>
+ <release>
+ <date>2012-04-13</date>
+ <version>
+ <release>3.1</release>
+ <api>3.1</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
+ <notes>
+- Fixed doble urlencoding of vcard identifier
+- Fixed encoding when default charset is different than vcard charset
+- Improved vcards import to work as addressbook::import procedure (with validation and autofix)
+- Support IDNA
+- Import contacts to default addressbook
+ </notes>
+ </release>
+ </changelog>
</package>
diff --git a/plugins/vcard_attachments/vcard_attachments.php b/plugins/vcard_attachments/vcard_attachments.php
index ed6d45325..e7f7d5f1f 100644
--- a/plugins/vcard_attachments/vcard_attachments.php
+++ b/plugins/vcard_attachments/vcard_attachments.php
@@ -1,223 +1,228 @@
<?php
/**
* Detect VCard attachments and show a button to add them to address book
*
* @version @package_version@
* @license GNU GPLv3+
* @author Thomas Bruederli, Aleksander Machniak
*/
class vcard_attachments extends rcube_plugin
{
public $task = 'mail';
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'));
}
else if (!$rcmail->output->framed && (!$rcmail->action || $rcmail->action == 'list')) {
$icon = 'plugins/vcard_attachments/' .$this->local_skin_path(). '/vcard.png';
$rcmail->output->set_env('vcard_icon', $icon);
$this->include_script('vcardattach.js');
}
$this->register_action('plugin.savevcard', array($this, 'save_vcard'));
}
/**
* Check message bodies and attachments for vcards
*/
function message_load($p)
{
$this->message = $p['object'];
// handle attachments vcard attachments
foreach ((array)$this->message->attachments as $attachment) {
if ($this->is_vcard($attachment)) {
$this->vcard_parts[] = $attachment->mime_id;
}
}
// the same with message bodies
foreach ((array)$this->message->parts as $idx => $part) {
if ($this->is_vcard($part)) {
$this->vcard_parts[] = $part->mime_id;
$this->vcard_bodies[] = $part->mime_id;
}
}
if ($this->vcard_parts)
$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)
{
$attach_script = false;
$icon = 'plugins/vcard_attachments/' .$this->local_skin_path(). '/vcard_add_contact.png';
foreach ($this->vcard_parts as $part) {
$vcards = rcube_vcard::import($this->message->get_part_content($part, null, true));
// successfully parsed vcards?
- if (empty($vcards))
+ if (empty($vcards)) {
continue;
+ }
// remove part's body
- if (in_array($part, $this->vcard_bodies))
+ 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].'>';
+ // skip invalid vCards
+ if (empty($vcard->email) || empty($vcard->email[0])) {
+ continue;
+ }
+
+ $display = $vcard->displayname . ' <'.$vcard->email[0].'>';
// add box below message body
$p['content'] .= html::p(array('class' => 'vcardattachment'),
html::a(array(
'href' => "#",
'onclick' => "return plugin_vcard_save_contact('" . JQ($part.':'.$idx) . "')",
'title' => $this->gettext('addvcardmsg'),
),
html::span(null, Q($display)))
);
}
$attach_script = true;
}
if ($attach_script) {
$this->include_script('vcardattach.js');
$this->include_stylesheet($this->local_skin_path() . '/style.css');
}
return $p;
}
/**
* Handler for request action
*/
function save_vcard()
{
- $this->add_texts('localization', true);
+ $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();
$storage = $rcmail->get_storage();
$storage->set_folder($mbox);
if ($uid && $mime_id) {
list($mime_id, $index) = explode(':', $mime_id);
$part = $storage->get_message_part($uid, $mime_id, null, null, null, true);
}
$error_msg = $this->gettext('vcardsavefailed');
if ($part && ($vcards = rcube_vcard::import($part))
&& ($vcard = $vcards[$index]) && $vcard->displayname && $vcard->email
) {
$CONTACTS = $this->get_address_book();
$email = $vcard->email[0];
$contact = $vcard->get_assoc();
$valid = true;
// skip entries without an e-mail address or invalid
if (empty($email) || !$CONTACTS->validate($contact, true)) {
$valid = false;
}
else {
// We're using UTF8 internally
$email = rcube_idn_to_utf8($email);
// compare e-mail address
$existing = $CONTACTS->search('email', $email, 1, false);
// compare display name
if (!$existing->count && $vcard->displayname) {
$existing = $CONTACTS->search('name', $vcard->displayname, 1, false);
}
if ($existing->count) {
$rcmail->output->command('display_message', $this->gettext('contactexists'), 'warning');
$valid = false;
}
}
if ($valid) {
$plugin = $rcmail->plugins->exec_hook('contact_create', array('record' => $contact, 'source' => null));
$contact = $plugin['record'];
if (!$plugin['abort'] && $CONTACTS->insert($contact))
$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');
}
$rcmail->output->send();
}
/**
* Checks if specified message part is a vcard data
*
* @param rcube_message_part Part object
*
* @return boolean True if part is of type vcard
*/
function is_vcard($part)
{
return (
// Content-Type: text/vcard;
$part->mimetype == 'text/vcard' ||
// Content-Type: text/x-vcard;
$part->mimetype == 'text/x-vcard' ||
// Content-Type: text/directory; profile=vCard;
($part->mimetype == 'text/directory' && (
($part->ctype_parameters['profile'] &&
strtolower($part->ctype_parameters['profile']) == 'vcard')
// Content-Type: text/directory; (with filename=*.vcf)
|| ($part->filename && preg_match('/\.vcf$/i', $part->filename))
)
)
);
}
/**
* Getter for default (writable) addressbook
*/
private function get_address_book()
{
if ($this->abook) {
return $this->abook;
}
$rcmail = rcmail::get_instance();
$abook = $rcmail->config->get('default_addressbook');
// Get configured addressbook
$CONTACTS = $rcmail->get_address_book($abook, true);
// Get first writeable addressbook if the configured doesn't exist
// This can happen when user deleted the addressbook (e.g. Kolab folder)
if ($abook === null || $abook === '' || !is_object($CONTACTS)) {
$source = reset($rcmail->get_address_sources(true));
$CONTACTS = $rcmail->get_address_book($source['id'], true);
}
return $this->abook = $CONTACTS;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Feb 3, 2:36 PM (15 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
427352
Default Alt Text
(16 KB)
Attached To
Mode
R3 roundcubemail
Attached
Detach File
Event Timeline
Log In to Comment