Add vcards from addressbook into an opened mail compose if there's any

This commit is contained in:
Hadi Nategh 2018-02-28 17:30:29 +01:00
parent a799abb0a0
commit 8ac7684f66
5 changed files with 166 additions and 63 deletions

View File

@ -713,7 +713,7 @@ app.classes.addressbook = AppJS.extend(
// Don't get rows here, let applyFilters() do it
return false;
}
return true;
},
@ -771,6 +771,11 @@ app.classes.addressbook = AppJS.extend(
{
var app_registry = egw.link_get_registry('mail');
var link = egw().link("/index.php","menuaction="+app_registry['add']['menuaction']);
var content = {vcard:{file:[], type:[]}};
// Get open compose windows
var compose = egw.getOpenWindows("mail", "(^compose_)|(^mail.compose)");
for (var i = 0; i < _elems.length; i++)
{
var idToUse = _elems[i].id;
@ -778,8 +783,52 @@ app.classes.addressbook = AppJS.extend(
idToUse = idToUseArray[1];
link += "&preset[type][]="+encodeURIComponent("text/vcard; charset="+(egw.preference('vcard_charset', 'addressbook') || 'utf-8'));
link += "&preset[file][]="+encodeURIComponent("vfs://default/apps/addressbook/"+idToUse+"/.entry");
content.vcard.file.push("vfs://default/apps/addressbook/"+idToUse+"/.entry");
content.vcard.type.push("text/vcard; charset="+(egw.preference('vcard_charset', 'addressbook') || 'utf-8'));
}
if (typeof app_registry['view'] != 'undefined' && typeof app_registry['view_popup'] != 'undefined' )
if(compose.length == 1)
{
var popup = egw.open_link('',compose[0],'100x100','mail');
popup.app.mail.setCompose(compose[0], content);
}
else if (compose.length > 1)
{
var buttons = [
{text: this.egw.lang("Add"), id: "add", "class": "ui-priority-primary", "default": true},
{text: this.egw.lang("Cancel"), id:"cancel"}
];
var c = [];
for(var i = 0; i < compose.length; i++)
{
var w = window.open('',compose[i],'100x100');
if(w.closed) continue;
w.blur();
c.push({label:w.document.title || egw.lang("compose"), compose:compose[i]});
}
et2_createWidget("dialog",
{
callback: function(_button_id, _value) {
if (_value && _value.grid)
{
switch (_button_id)
{
case "add":
var w = egw.open_link('', _value.grid.compose,'100x100','mail');
w.app.mail.setCompose(w.name, content);
return;
case "cancel":
}
}
},
title: this.egw.lang("Select an opened compose dialog"),
buttons: buttons,
value:{content:{grid:c}},
template: egw.webserverUrl+'/addressbook/templates/default/promptOpenedComposeDialog.xet?1',
resizable: false
}, et2_dialog._create_parent('addressbook'));
}
else if (typeof app_registry['view'] != 'undefined' && typeof app_registry['view_popup'] != 'undefined' )
{
var w_h =app_registry['view_popup'].split('x');
if (w_h[1] == 'egw_getWindowOuterHeight()') w_h[1] = (screen.availHeight>egw_getWindowOuterHeight()?screen.availHeight:egw_getWindowOuterHeight());
@ -1007,7 +1056,7 @@ app.classes.addressbook = AppJS.extend(
}
// Check to see if it's not there
if(options && (options.find &&
if(options && (options.find &&
!options.find(function(e) {console.log(e); return e.value === state.state.grouped_view;}) ||
typeof options.find === 'undefined' && !options[state.state.grouped_view]
))

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE overlay PUBLIC "-//EGroupware GmbH//eTemplate 2//EN" "http://www.egroupware.org/etemplate2.dtd">
<!-- $Id$ -->
<overlay>
<template id="addressbook.promptOpenedComposeDialog" template="" lang="" group="0" version="17.1">
<grid id="grid">
<columns>
<column/>
<column/>
</columns>
<rows>
<row>
<radio id="compose" options="$row_cont[compose]" />
<description id="${row}[label]"/>
</row>
</rows>
</grid>
</template>
</overlay>

View File

@ -780,6 +780,20 @@ class mail_compose
// do not double insert a signature on a server roundtrip
if ($buttonClicked) $suppressSigOnTop = true;
// On submit reads vcard_from_ab widget's value and addes them as attachments.
// this happens when we send vcards from addressbook to an opened compose
// dialog.
if ($_content['vcard_from_ab'])
{
$vcard = json_decode($_content['vcard_from_ab'], true);
$_REQUEST['preset']['file'] = $vcard['file'];
$_REQUEST['preset']['type'] = $vcard['type'];
$suppressSigOnTop = true;
unset($_content['attachments']);
$this->addPresetFiles($content, $insertSigOnTop, true);
}
if ($isFirstLoad)
{
$alwaysAttachVCardAtCompose = false; // we use this to eliminate double attachments, if users VCard is already present/attached
@ -944,65 +958,7 @@ class mail_compose
isset(Vfs\Sharing::$modes[$_REQUEST['preset']['filemode']]) ?
$_REQUEST['preset']['filemode'] : Vfs\Sharing::ATTACH;
$names = (array)$_REQUEST['preset']['name'];
$types = (array)$_REQUEST['preset']['type'];
//if (!empty($types) && in_array('text/calendar; method=request',$types))
$files = (array)$_REQUEST['preset']['file'];
foreach($files as $k => $path)
{
if (!empty($types[$k]) && stripos($types[$k],'text/calendar')!==false)
{
$insertSigOnTop = 'below';
}
//error_log(__METHOD__.__LINE__.$path.'->'.array2string(parse_url($path,PHP_URL_SCHEME == 'vfs')));
if (parse_url($path,PHP_URL_SCHEME == 'vfs'))
{
//Vfs::load_wrapper('vfs');
$type = Vfs::mime_content_type($path);
// special handling for attaching vCard of iCal --> use their link-title as name
if (substr($path,-7) != '/.entry' ||
!(list($app,$id) = array_slice(explode('/',$path),-3)) ||
!($name = Link::title($app, $id)))
{
$name = Vfs::decodePath(Vfs::basename($path));
}
else
{
$name .= '.'.Api\MimeMagic::mime2ext($type);
}
// use type specified by caller, if Vfs reports only default, or contains specified type (eg. "text/vcard; charset=utf-8")
if (!empty($types[$k]) && ($type == 'application/octet-stream' || stripos($types[$k], $type) === 0))
{
$type = $types[$k];
}
$path = str_replace('+','%2B',$path);
$formData = array(
'name' => $name,
'type' => $type,
'file' => Vfs::decodePath($path),
'size' => filesize(Vfs::decodePath($path)),
);
if ($formData['type'] == Vfs::DIR_MIME_TYPE && $content['filemode'] == Vfs\Sharing::ATTACH)
{
$content['filemode'] = Vfs\Sharing::READONLY;
Framework::message(lang('Directories have to be shared.'), 'info');
}
}
elseif(is_readable($path))
{
$formData = array(
'name' => isset($names[$k]) ? $names[$k] : basename($path),
'type' => isset($types[$k]) ? $types[$k] : (function_exists('mime_content_type') ? mime_content_type($path) : Api\MimeMagic::filename2mime($path)),
'file' => $path,
'size' => filesize($path),
);
}
else
{
continue;
}
$this->addAttachment($formData,$content,($alwaysAttachVCardAtCompose?true:false));
}
$this->addPresetFiles($content, $insertSigOnTop, $alwaysAttachVCardAtCompose);
$remember = array();
if (isset($_REQUEST['preset']['mailto']) || (isset($_REQUEST['app']) && isset($_REQUEST['method']) && isset($_REQUEST['id'])))
{
@ -1396,6 +1352,77 @@ class mail_compose
$etpl->exec('mail.mail_compose.compose',$content,$sel_options,array(),$preserv,2);
}
/**
* Add preset files like vcard as attachments into content array
*
* @param array $_content content
* @param string $_insertSigOnTop
* @param boolean $_eliminateDoubleAttachments
*/
function addPresetFiles (&$_content, &$_insertSigOnTop, $_eliminateDoubleAttachments)
{
$names = (array)$_REQUEST['preset']['name'];
$types = (array)$_REQUEST['preset']['type'];
//if (!empty($types) && in_array('text/calendar; method=request',$types))
$files = (array)$_REQUEST['preset']['file'];
foreach($files as $k => $path)
{
if (!empty($types[$k]) && stripos($types[$k],'text/calendar')!==false)
{
$_insertSigOnTop = 'below';
}
//error_log(__METHOD__.__LINE__.$path.'->'.array2string(parse_url($path,PHP_URL_SCHEME == 'vfs')));
if (parse_url($path,PHP_URL_SCHEME == 'vfs'))
{
//Vfs::load_wrapper('vfs');
$type = Vfs::mime_content_type($path);
// special handling for attaching vCard of iCal --> use their link-title as name
if (substr($path,-7) != '/.entry' ||
!(list($app,$id) = array_slice(explode('/',$path),-3)) ||
!($name = Link::title($app, $id)))
{
$name = Vfs::decodePath(Vfs::basename($path));
}
else
{
$name .= '.'.Api\MimeMagic::mime2ext($type);
}
// use type specified by caller, if Vfs reports only default, or contains specified type (eg. "text/vcard; charset=utf-8")
if (!empty($types[$k]) && ($type == 'application/octet-stream' || stripos($types[$k], $type) === 0))
{
$type = $types[$k];
}
$path = str_replace('+','%2B',$path);
$formData = array(
'name' => $name,
'type' => $type,
'file' => Vfs::decodePath($path),
'size' => filesize(Vfs::decodePath($path)),
);
if ($formData['type'] == Vfs::DIR_MIME_TYPE && $_content['filemode'] == Vfs\Sharing::ATTACH)
{
$_content['filemode'] = Vfs\Sharing::READONLY;
Framework::message(lang('Directories have to be shared.'), 'info');
}
}
elseif(is_readable($path))
{
$formData = array(
'name' => isset($names[$k]) ? $names[$k] : basename($path),
'type' => isset($types[$k]) ? $types[$k] : (function_exists('mime_content_type') ? mime_content_type($path) : Api\MimeMagic::filename2mime($path)),
'file' => $path,
'size' => filesize($path),
);
}
else
{
continue;
}
$this->addAttachment($formData,$_content, $_eliminateDoubleAttachments);
}
}
/**
* Get pre-fill a new compose based on an existing email
*
@ -3596,7 +3623,7 @@ class mail_compose
* Get list of matching distribution lists when searching for email addresses
*
* The results are limited to 10 each of group lists and normal lists
*
*
* @param String $_searchString
* @param Contacts $contacts_obj
* @return array

View File

@ -686,6 +686,13 @@ app.classes.mail = AppJS.extend(
{
try
{
if (field == 'vcard')
{
var vcard_from_ab = compose_et2[0].widgetContainer.getWidgetById('vcard_from_ab');
vcard_from_ab.set_value(JSON.stringify(content.vcard));
return compose_et2[0].widgetContainer._inst.submit();
}
var widget = compose_et2[0].widgetContainer.getWidgetById(field);
// Merge array values, replace strings

View File

@ -14,6 +14,7 @@
<checkbox statustext="check to receive a notification when the message is read (note: not all clients support this and/or the receiver may not authorize the notification)" id="disposition" options="on,off"/>
<checkbox statustext="check to sign the message on send" id="smime_sign" options="on,off"/>
<checkbox statustext="check to encrypt the message on send" id="smime_encrypt" options="on,off"/>
<textbox id="vcard_from_ab"/>
<passwd id="smime_passphrase"/>
<taglist id="to_integrate_ids"/>
<menulist>