W.I.P. of new approach for mail winmail.dat attachment handling

- Restructure save attachments to vfs, and try to read the winmail.dat only once and store them all, as fetching content of winmail.dat is very expensive operation
- Fix failure of save all embedded attachments into filemanager
This commit is contained in:
Hadi Nategh 2015-12-02 11:10:26 +00:00
parent 7aabcd31a3
commit 97d240fcab

View File

@ -2493,7 +2493,7 @@ class mail_ui
function vfsSaveAttachment($ids,$path) function vfsSaveAttachment($ids,$path)
{ {
//error_log(__METHOD__.__LINE__.'("'.array2string($ids).'","'.$path."\")');"); //error_log(__METHOD__.__LINE__.'("'.array2string($ids).'","'.$path."\")');");
if (is_array($ids) && !egw_vfs::is_writable($path) || !is_array($ids) && !egw_vfs::is_writable(dirname($path))) if (is_array($ids) && !egw_vfs::is_writable($path) || !is_array($ids) && !egw_vfs::is_writable(dirname($path)))
{ {
return 'alert("'.addslashes(lang('%1 is NOT writable by you!',$path)).'"); egw(window).close();'; return 'alert("'.addslashes(lang('%1 is NOT writable by you!',$path)).'"); egw(window).close();';
@ -2501,34 +2501,79 @@ class mail_ui
$err=null; $err=null;
$dupe_count = array(); $dupe_count = array();
$rememberServerID = $this->mail_bo->profileID; $rememberServerID = $this->mail_bo->profileID;
foreach((array)$ids as $id)
{ /**
* Extract all parameteres from the given id
* @param int $id message id ('::' delimited mailbox::uid::part-id::is_winmail::name)
*
* @return array an array of parameters
*/
$getParams = function ($id) {
list($app,$user,$serverID,$mailbox,$uid,$part,$is_winmail,$name) = explode('::',$id,8); list($app,$user,$serverID,$mailbox,$uid,$part,$is_winmail,$name) = explode('::',$id,8);
$lId = implode('::',array($app,$user,$serverID,$mailbox,$uid)); $lId = implode('::',array($app,$user,$serverID,$mailbox,$uid));
$hA = self::splitRowID($lId); $hA = self::splitRowID($lId);
$uid = $hA['msgUID']; return array(
$mailbox = $hA['folder']; 'is_winmail' => $is_winmail == "null" || !$is_winmail?false:$is_winmail,
$icServerID = $hA['profileID']; 'user' => $user,
if ($icServerID && $icServerID != $this->mail_bo->profileID) 'name' => $name,
'part' => $part,
'uid' => $hA['msgUID'],
'mailbox' => $hA['folder'],
'icServer' => $hA['profileID']
);
};
//Examine the first attachment to see if attachment
//is winmail.dat embedded attachments.
$p = $getParams($ids[0]);
if ($p['is_winmail'])
{
if ($p['icServer'] && $p['icServer'] != $this->mail_bo->profileID)
{
$this->changeProfile($p['icServer']);
}
$this->mail_bo->reopen($p['mailbox']);
// Retrive all embedded attachments at once
// avoids to fetch heavy winmail.dat content
// for each file.
$attachments = $this->mail_bo->getTnefAttachments($p['uid'],$p['part']);
}
foreach((array)$ids as $id)
{
$params = $getParams($id);
if ($params['icServer'] && $params['icServer'] != $this->mail_bo->profileID)
{ {
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID); //error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
$this->changeProfile($icServerID); $this->changeProfile($params['icServer']);
} }
//error_log(__METHOD__.__LINE__.array2string($hA)); //error_log(__METHOD__.__LINE__.array2string($hA));
$this->mail_bo->reopen($mailbox); $this->mail_bo->reopen($params['mailbox']);
$attachment = $this->mail_bo->getAttachment($uid,$part,$is_winmail,false);
if ($params['is_winmail'])
{
// 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);
}
$file = $name; $file = $params['name'];
while(egw_vfs::file_exists($path.($file ? '/'.$file : ''))) while(egw_vfs::file_exists($path.($file ? '/'.$file : '')))
{ {
$dupe_count[$name]++; $dupe_count[$params['name']]++;
$file = pathinfo($name, PATHINFO_FILENAME) . $file = pathinfo($params['name'], PATHINFO_FILENAME) .
' ('.($dupe_count[$name] + 1).')' . '.' . ' ('.($dupe_count[$params['name']] + 1).')' . '.' .
pathinfo($name, PATHINFO_EXTENSION); pathinfo($params['name'], PATHINFO_EXTENSION);
} }
$name = $file; $params['name'] = $file;
//error_log(__METHOD__.__LINE__.array2string($attachment)); //error_log(__METHOD__.__LINE__.array2string($attachment));
if (!($fp = egw_vfs::fopen($file=$path.($name ? '/'.$name : ''),'wb')) || if (!($fp = egw_vfs::fopen($file=$path.($params['name'] ? '/'.$params['name'] : ''),'wb')) ||
!fwrite($fp,$attachment['attachment'])) !fwrite($fp,$attachment['attachment']))
{ {
$err .= lang('Error saving %1!',$file); $err .= lang('Error saving %1!',$file);
@ -2536,7 +2581,6 @@ class mail_ui
if ($fp) if ($fp)
{ {
fclose($fp); fclose($fp);
$file_list[] = $name;
} }
} }
$this->mail_bo->closeConnection(); $this->mail_bo->closeConnection();
@ -3660,7 +3704,7 @@ class mail_ui
/** /**
* ResolveWinmail fetches the encoded attachments * ResolveWinmail fetches the encoded attachments
* from winmail.data and will response expected structure back * from winmail.dat and will response expected structure back
* to client in order to display them. * to client in order to display them.
* *
* Note: this ajax function should only be called via * Note: this ajax function should only be called via
@ -3686,7 +3730,7 @@ class mail_ui
} }
else else
{ {
$response->call('egw.message', lang('Can not resolve the winmail.data attachment!')); $response->call('egw.message', lang('Can not resolve the winmail.dat attachment!'));
} }
} }