Fix VFS save action in mail

This commit is contained in:
Hadi Nategh 2017-11-08 19:07:04 +01:00
parent 1b5e992f43
commit 977d5db61b
4 changed files with 190 additions and 180 deletions

View File

@ -2343,9 +2343,6 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
}
if (is_array($attachments) && count($attachments) > 0) {
$url_img_vfs = Api\Html::image('filemanager','navbar', lang('Filemanager'), ' height="16"');
$url_img_vfs_save_all = Api\Html::image('mail','save_all', lang('Save all'));
foreach ($attachments as $key => $value)
{
if (Mail\Smime::isSmime($value['mimeType'])) continue;
@ -2770,36 +2767,62 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
}
/**
* Ajax function to save message(s) in the vfs
* Ajax function to save message(s)/attachment(s) in the vfs
*
* @param array $ids array of mail ids
* @param array $params array of mail ids and action name
* params = array (
* ids => array of string
* action => string
* )
* @param string $path path to save the emails
*/
function ajax_vfsSaveMessage ($ids,$path)
function ajax_vfsSave ($params,$path)
{
$result = $this->vfsSaveMessage($ids, $path);
$response = Api\Json\Response::get();
$response->data($result);
switch ($params['action'])
{
case 'message':
$result = $this->vfsSaveMessages($params['ids'], $path);
break;
case 'attachment':
$result = $this->vfsSaveAttachments($params['ids'], $path);
break;
}
$response->call('app.mail.vfsSaveCallback', $result);
}
/**
* Save an Message in the vfs
* Save Message(s) in the vfs
*
* @param string|array $ids use splitRowID, to separate values
* @param string $path path in vfs (no Vfs::PREFIX!), only directory for multiple id's ($ids is an array)
* @return string|boolean javascript eg. to close the selector window if $close is true, or success/fail if $close is false
*
* @return array returns an array including message and success result
* array (
* 'msg' => STRING,
* 'success' => BOOLEAN
* )
*/
function vfsSaveMessage($ids,$path)
function vfsSaveMessages($ids,$path)
{
//error_log(__METHOD__.' IDs:'.array2string($ids).' SaveToPath:'.$path);
if (is_array($ids) && !Vfs::is_writable($path) || !is_array($ids) && !Vfs::is_writable(dirname($path)))
{
return 'alert("'.addslashes(lang('%1 is NOT writable by you!',$path)).'"); Egw(window).close();';
}
// add mail translation
Api\Translation::add_app('mail');
$res = array ();
$rememberServerID = $this->mail_bo->profileID;
// extract dir from the path
$dir = Vfs::is_dir($path) ? $path : Vfs::dirname($path);
// exit if user has no right to the dir
if (!Vfs::is_writable($dir))
{
return array (
'msg' => lang('%1 is NOT writable by you!',$path),
'success' => false
);
}
$preservedServerID = $this->mail_bo->profileID;
foreach((array)$ids as $id)
{
$hA = self::splitRowID($id);
@ -2808,31 +2831,44 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
$icServerID = $hA['profileID'];
if ($icServerID && $icServerID != $this->mail_bo->profileID)
{
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
$this->changeProfile($icServerID);
}
$message = $this->mail_bo->getMessageRawBody($uid, $partID='', $mailbox);
$err=null;
if(Vfs::is_dir($path))
// is multiple messages
if (Vfs::is_dir($path))
{
$headers = $this->mail_bo->getMessageHeader($uid,$partID,true,false,$mailbox);
$file = $path . '/'.preg_replace('/[\f\n\t\v\\:*#?<>\|]/',"_",$headers['SUBJECT']).'.eml';
$file = $dir . '/'.preg_replace('/[\f\n\t\v\\:*#?<>\|]/',"_",$headers['SUBJECT']).'.eml';
}
else
{
$file = $path;
}
// Check if file already exists, then try to assign a none existance filename
$counter = 1;
$tmp_file = $file;
while (Vfs::file_exists($tmp_file))
{
$tmp_file = $file;
$pathinfo = pathinfo(Vfs::basename($tmp_file));
$tmp_file = $dir . '/' . $pathinfo['filename'] . '(' . $counter . ')' . '.' . $pathinfo['extension'];
$counter++;
}
$file = $tmp_file;
if (!($fp = Vfs::fopen($file,'wb')) || !fwrite($fp,$message))
{
$err .= lang('Error saving %1!',$file);
$succeeded = false;
$res['msg'] = lang('Error saving %1!',$file);
$res['success'] = false;
}
else
{
$succeeded = true;
$res['success'] = true;
}
if ($fp) fclose($fp);
if ($succeeded)
if ($res['success'])
{
unset($headers['SUBJECT']);//already in filename
$infoSection = Mail::createHeaderInfoSection($headers, 'SUPPRESS', false);
@ -2840,45 +2876,44 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
Vfs::proppatch($file,$props);
}
}
if ($rememberServerID != $this->mail_bo->profileID)
if ($preservedServerID != $this->mail_bo->profileID)
{
//error_log(__METHOD__.__LINE__.' change Profile back to where we came from ->'.$rememberServerID);
$this->changeProfile($rememberServerID);
//change Profile back to where we came from
$this->changeProfile($preservedServerID);
}
return $succeeded;
return $res;
}
/**
* Ajax function to store attachments in the vfs
* @param string|array $ids '::' delimited mailbox::uid::part-id::is_winmail::name (::name for multiple id's)
* @param string $path path in vfs (no Vfs::PREFIX!), only directory for multiple id's ($ids is an array)
*/
function ajax_vfsSaveAttachment($ids,$path)
{
$result = $this->vfsSaveAttachment($ids, $path);
$response = Api\Json\Response::get();
$response->data($result);
}
/**
* Save an attachment in the vfs
* Save attachment(s) in the vfs
*
* @param string|array $ids '::' delimited mailbox::uid::part-id::is_winmail::name (::name for multiple id's)
* @param string $path path in vfs (no Vfs::PREFIX!), only directory for multiple id's ($ids is an array)
* @return string javascript eg. to close the selector window
*
* @return array returns an array including message and success result
* array (
* 'msg' => STRING,
* 'success' => BOOLEAN
* )
*/
function vfsSaveAttachment($ids,$path)
function vfsSaveAttachments($ids,$path)
{
//error_log(__METHOD__.__LINE__.'("'.array2string($ids).'","'.$path."\")');");
$res = array (
'msg' => 'Attachment has been saved successfully.',
'success' => true
);
if (is_array($ids) && !Vfs::is_writable($path) || !is_array($ids) && !Vfs::is_writable(dirname($path)))
$dir = Vfs::is_dir($path) ? $path : Vfs::dirname($path);
if (!Vfs::is_writable($dir))
{
return 'alert("'.addslashes(lang('%1 is NOT writable by you!',$path)).'"); Egw(window).close();';
return array (
'msg' => lang('%1 is NOT writable by you!',$path),
'success' => false
);
}
$err=null;
$dupe_count = array();
$rememberServerID = $this->mail_bo->profileID;
$preservedServerID = $this->mail_bo->profileID;
/**
* Extract all parameteres from the given id
@ -2903,7 +2938,6 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
//Examine the first attachment to see if attachment
//is winmail.dat embedded attachments.
$isMultipleDownload=is_array($ids);
$p = $getParams((is_array($ids)?$ids[0]:$ids));
if ($p['is_winmail'])
{
@ -2921,21 +2955,27 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
foreach((array)$ids as $id)
{
$params = $getParams($id);
// when downloading a single file, name is not set
if (!$params['name']&&isset($_GET['name'])&&!$isMultipleDownload) $params['name'] = $_GET['name'];
if ($params['icServer'] && $params['icServer'] != $this->mail_bo->profileID)
{
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
$this->changeProfile($params['icServer']);
}
//error_log(__METHOD__.__LINE__.array2string($hA));
$this->mail_bo->reopen($params['mailbox']);
if ($params['is_winmail'])
// is multiple attachments
if (Vfs::is_dir($path) || $params['is_winmail'])
{
// Try to find the right content for file id
foreach ($attachments as $key => $val)
if ($params['is_winmail'])
{
if ($key == $params['is_winmail']) $attachment = $val;
// Try to find the right content for file id
foreach ($attachments as $key => $val)
{
if ($key == $params['is_winmail']) $attachment = $val;
}
}
else
{
$attachment = $this->mail_bo->getAttachment($params['uid'],$params['part'],$params['is_winmail'],false);
}
}
else
@ -2943,35 +2983,39 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
$attachment = $this->mail_bo->getAttachment($params['uid'],$params['part'],$params['is_winmail'],false);
}
$file = $params['name'];
// when $isMultipleDownload the path holds no filename
while(Vfs::file_exists($path.($file && $isMultipleDownload ? '/'.$file : '')))
$file = $dir. '/' . $attachment['filename'];
$counter = 1;
$tmp_file = $file;
while (Vfs::file_exists($tmp_file))
{
$dupe_count[$params['name']]++;
$file = pathinfo($params['name'], PATHINFO_FILENAME) .
' ('.($dupe_count[$params['name']] + 1).')' . '.' .
pathinfo($params['name'], PATHINFO_EXTENSION);
$tmp_file = $file;
$pathinfo = pathinfo(Vfs::basename($tmp_file));
$tmp_file = $dir . '/' . $pathinfo['filename'] . '(' . $counter . ')' . '.' . $pathinfo['extension'];
$counter++;
}
$params['name'] = $file;
//error_log(__METHOD__.__LINE__.array2string($attachment));
// when $isMultipleDownload the path holds no filename
if (!($fp = Vfs::fopen($file=$path.($params['name'] && $isMultipleDownload ? '/'.$params['name'] : ''),'wb')) ||
$file = $tmp_file;
if (!($fp = Vfs::fopen($file,'wb')) ||
!fwrite($fp,$attachment['attachment']))
{
$err .= lang('Error saving %1!',$file);
$res['msg'] = lang('Error saving %1!',$file);
$res['success'] = false;
}
if ($fp)
{
fclose($fp);
}
}
$this->mail_bo->closeConnection();
if ($rememberServerID != $this->mail_bo->profileID)
if ($preservedServerID != $this->mail_bo->profileID)
{
//error_log(__METHOD__.__LINE__.' change Profile back to where we came from ->'.$rememberServerID);
$this->changeProfile($rememberServerID);
//change Profile back to where we came from
$this->changeProfile($preservedServerID);
}
Framework::window_close(($err?$err:null));
return $res;
}
/**

View File

@ -2893,113 +2893,79 @@ app.classes.mail = AppJS.extend(
egw.openPopup(egw.link('/index.php', get_param), width, height, windowName);
},
saveAttachment: function(tag_info, widget)
/**
* Callback function to handle vfsSave response messages
*
* @param {type} _data
*/
vfsSaveCallback: function (_data)
{
var mailid;
var attgrid;
if (this.mail_isMainWindow)
{
mailid = this.mail_currentlyFocussed;//this.et2.getArrayMgr("content").getEntry('mail_id');
var p = widget.getParent();
var cont = p.getArrayMgr("content").data;
attgrid = cont[widget.id.replace(/\[save\]/,'')];
}
else
{
mailid = this.et2.getArrayMgr("content").getEntry('mail_id');
attgrid = this.et2.getArrayMgr("content").getEntry('mail_displayattachments')[widget.id.replace(/\[save\]/,'')];
}
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=mail.mail_ui.getAttachment'; // todo compose for Draft folder
url += '&mode=save';
url += '&id='+mailid;
url += '&part='+attgrid.partID;
url += '&is_winmail='+attgrid.winmailFlag;
url += '&smime_type='+ (attgrid.smime_type?attgrid.smime_type:'');
this.et2._inst.download(url);
egw.message(_data.msg, _data.success ? "success": "error");
},
saveAllAttachmentsToZip: function(tag_info, widget)
/**
* A handler for saving to VFS/downloading attachments
*
* @param {type} widget
* @param {type} action
* @param {type} row_id
*/
saveAttachmentHandler: function (widget, action, row_id)
{
var mailid;
var attgrid;
var mail_id, attachments;
if (this.mail_isMainWindow)
{
mailid = this.mail_currentlyFocussed;//this.et2.getArrayMgr("content").getEntry('mail_id');
mail_id = this.mail_currentlyFocussed;
var p = widget.getParent();
var cont = p.getArrayMgr("content").data;
attgrid = cont[widget.id.replace(/\[save_zip\]/,'')];
attachments = p.getArrayMgr("content").data;
}
else
{
mailid = this.et2.getArrayMgr("content").getEntry('mail_id');
attgrid = this.et2.getArrayMgr("content").getEntry('mail_displayattachments')[widget.id.replace(/\[save\]/,'')];
}
var url = window.egw_webserverUrl+'/index.php?';
url += 'menuaction=mail.mail_ui.download_zip'; // todo compose for Draft folder
url += '&mode=save';
url += '&id='+mailid;
url += '&smime_type='+ (attgrid.smime_type?attgrid.smime_type:'');
this.et2._inst.download(url);
},
saveAttachmentToVFS: function(tag_info, widget)
{
var mailid;
var attgrid;
if (this.mail_isMainWindow)
{
mailid = this.mail_currentlyFocussed;//this.et2.getArrayMgr("content").getEntry('mail_id');
var p = widget.getParent();
var cont = p.getArrayMgr("content").data;
attgrid = cont[widget.id.replace(/\[saveAsVFS\]/,'')];
}
else
{
mailid = this.et2.getArrayMgr("content").getEntry('mail_id');
attgrid = this.et2.getArrayMgr("content").getEntry('mail_displayattachments')[widget.id.replace(/\[saveAsVFS\]/,'')];
}
var vfs_select = et2_createWidget('vfs-select', {
mode: 'saveas',
method: 'mail.mail_ui.ajax_vfsSaveAttachment',
button_label: egw.lang('Save'),
dialog_title: "Save attchment",
method_id: mailid+'::'+attgrid.partID+'::'+attgrid.winmailFlag,
name: attgrid.filename
});
vfs_select.click();
},
saveAllAttachmentsToVFS: function(tag_info, widget)
{
var mailid;
var attgrid;
if (this.mail_isMainWindow)
{
mailid = this.mail_currentlyFocussed;//this.et2.getArrayMgr("content").getEntry('mail_id');
var p = widget.getParent();
attgrid = p.getArrayMgr("content").data;
}
else
{
mailid = this.et2.getArrayMgr("content").getEntry('mail_id');
attgrid = this.et2.getArrayMgr("content").getEntry('mail_displayattachments');
mail_id = this.et2.getArrayMgr("content").getEntry('mail_id');
attachments = this.et2.getArrayMgr("content").getEntry('mail_displayattachments');
}
var ids = [];
for (var i=0;i<attgrid.length;i++)
switch (action)
{
if (attgrid[i] != null) ids.push(mailid+'::'+attgrid[i].partID+'::'+attgrid[i].winmailFlag+'::'+attgrid[i].filename);
}
case 'saveOneToVfs':
case 'saveAllToVfs':
var ids = [];
attachments = action === 'saveOneToVfs' ? [attachments[row_id]] : attachments;
for (var i=0;i<attachments.length;i++)
{
if (attachments[i] != null)
{
ids.push(mail_id+'::'+attachments[i].partID+'::'+attachments[i].winmailFlag+'::'+attachments[i].filename);
}
}
var vfs_select = et2_createWidget('vfs-select', {
mode: action === 'saveOneToVfs' ? 'saveas' : 'select-dir',
method: 'mail.mail_ui.ajax_vfsSave',
button_label: egw.lang(action === 'saveOneToVfs' ? 'Save' : 'Save all'),
dialog_title: egw.lang(action === 'saveOneToVfs' ? 'Save attchment' : 'Save attchments'),
method_id: ids.length > 1 ? {ids:ids, action:'attachment'} : {ids: ids[0], action: 'attachment'},
name: action === 'saveOneToVfs' ? attachments[0]['filename'] : null
});
vfs_select.click();
break;
var vfs_select = et2_createWidget('vfs-select', {
mode: 'select-dir',
method: 'mail.mail_ui.ajax_vfsSaveAttachment',
button_label: egw.lang('Save all'),
dialog_title: "Save attchments",
method_id: ids.length > 1 ? ids: ids[0]
});
vfs_select.click();
case 'downloadOneAsFile':
case 'downloadAllToZip':
var attachment = attachments[row_id];
var url = window.egw_webserverUrl+'/index.php?';
url += jQuery.param({
menuaction: action === 'downloadOneAsFile' ?
'mail.mail_ui.getAttachment' : 'mail.mail_ui.download_zip',
mode: 'save',
id: mail_id,
part: attachment.partID,
is_winmail: attachment.winmailFlag,
smime_type: (attachment.smime_type ? attachment.smime_type : '')
});
this.et2._inst.download(url);
break;
}
},
/**
@ -3039,10 +3005,10 @@ app.classes.mail = AppJS.extend(
var vfs_select = et2_createWidget('vfs-select', {
mode: _elems.length > 1 ? 'select-dir' : 'saveas',
mime: 'message/rfc822',
method: 'mail.mail_ui.ajax_vfsSaveMessage',
method: 'mail.mail_ui.ajax_vfsSave',
button_label: _elems.length>1 ? egw.lang('Save all') : egw.lang('save'),
dialog_title: "Save email",
method_id: _elems.length > 1 ? ids: ids[0],
method_id: _elems.length > 1 ? {ids:ids, action:'message'}: {ids: ids[0], action: 'message'},
name: _elems.length > 1 ? names : names[0],
});
vfs_select.click();

View File

@ -78,10 +78,10 @@
<description id="${row}[winmailFlag]" />
<description class="useEllipsis et2_link" id="${row}[filename]" extra_link_target="$row_cont[windowName]" extra_link_popup="$row_cont[popup]" expose_view="true" mime="$row_cont[type]" no_lang="1" mime_data="$row_cont[mime_data]" href="$row_cont[mime_url]"/>
<description align="right" id="${row}[size]" />
<buttononly id="${row}[save]" value="save" image="fileexport" onclick="app.mail.saveAttachment"/>
<buttononly id="${row}[saveAsVFS]" value="save" image="filemanager/navbar" onclick="app.mail.saveAttachmentToVFS"/>
<buttononly class="$row_cont[classSaveAllPossiblyDisabled]" id="${row}[save_all]" value="save_all" image="mail/save_all" onclick="app.mail.saveAllAttachmentsToVFS"/>
<buttononly class="$row_cont[classSaveAllPossiblyDisabled]" id="${row}[save_zip]" value="save_zip" image="mail/save_zip" onclick="app.mail.saveAllAttachmentsToZip" label="Save as Zip"/>
<buttononly id="${row}[save]" value="save" image="fileexport" onclick="app.mail.saveAttachmentHandler(widget,'downloadOneAsFile', ${row})"/>
<buttononly id="${row}[saveAsVFS]" value="save" image="filemanager/navbar" onclick="app.mail.saveAttachmentHandler(widget,'saveOneToVfs', ${row})"/>
<buttononly class="$row_cont[classSaveAllPossiblyDisabled]" id="${row}[save_all]" value="save_all" image="mail/save_all" onclick="app.mail.saveAttachmentHandler(widget,'saveAllToVfs', ${row})"/>
<buttononly class="$row_cont[classSaveAllPossiblyDisabled]" id="${row}[save_zip]" value="save_zip" image="mail/save_zip" onclick="app.mail.saveAttachmentHandler(widget,'downloadAllToZip', ${row})" label="Save as Zip"/>
</row>
</rows>
</grid>

View File

@ -62,10 +62,10 @@
<description id="${row}[winmailFlag]" />
<description class="et2_link useEllipsis" id="${row}[filename]" extra_link_target="$row_cont[windowName]" extra_link_popup="$row_cont[popup]" no_lang="1" expose_view="true" mime="$row_cont[type]" mime_data="$row_cont[mime_data]" href="$row_cont[mime_url]"/>
<description align="right" id="${row}[size]"/>
<buttononly id="${row}[save]" image="fileexport" onclick="app.mail.saveAttachment"/>
<buttononly id="${row}[saveAsVFS]" image="filemanager/navbar" onclick="app.mail.saveAttachmentToVFS"/>
<buttononly class="$row_cont[classSaveAllPossiblyDisabled]" id="${row}[save_all]" image="mail/save_all" onclick="app.mail.saveAllAttachmentsToVFS"/>
<buttononly class="$row_cont[classSaveAllPossiblyDisabled]" id="${row}[save_zip]" image="mail/save_zip" onclick="app.mail.saveAllAttachmentsToZip" label="Save as Zip"/>
<buttononly id="${row}[save]" image="fileexport" onclick="app.mail.saveAttachmentHandler(widget,'downloadOneAsFile', ${row})"/>
<buttononly id="${row}[saveAsVFS]" image="filemanager/navbar" onclick="app.mail.saveAttachmentHandler(widget,'saveOneToVfs', ${row})"/>
<buttononly class="$row_cont[classSaveAllPossiblyDisabled]" id="${row}[save_all]" image="mail/save_all" onclick="app.mail.saveAttachmentHandler(widget,'saveAllToVfs', ${row})"/>
<buttononly class="$row_cont[classSaveAllPossiblyDisabled]" id="${row}[save_zip]" image="mail/save_zip" onclick="app.mail.saveAttachmentHandler(widget,'downloadAllToZip', ${row})" label="Save as Zip"/>
</row>
</rows>
</grid>