* email: improvement regarding notification handling; using htmLawed now instead of purify as fallback when there is no tidy;

This commit is contained in:
Klaus Leithoff 2012-04-17 09:23:14 +00:00
parent 77bc5da6ef
commit 5785287917
4 changed files with 99 additions and 74 deletions

View File

@ -48,7 +48,7 @@ class ajaxfelamimail
if($this->_debug) error_log("ajaxfelamimail::ajaxfelamimail");
if (isset($GLOBALS['egw_info']['user']['preferences']['felamimail']['ActiveProfileID']))
$this->imapServerID = (int)$GLOBALS['egw_info']['user']['preferences']['felamimail']['ActiveProfileID'];
//error_log("ajaxfelamimail::ajaxfelamimail ActiveProfile:".$this->imapServerID );
$this->charset = translation::charset();
$this->bofelamimail = felamimail_bo::getInstance(true,$this->imapServerID);
$this->imapServerID = $GLOBALS['egw_info']['user']['preferences']['felamimail']['ActiveProfileID'] = $this->bofelamimail->profileID;
@ -60,9 +60,9 @@ class ajaxfelamimail
$this->sessionData =& $GLOBALS['egw']->session->appsession('session_data','felamimail');
if (!is_array($this->sessionDataAjax)) $this->sessionDataAjax = array();
if(!isset($this->sessionDataAjax['folderName'])) {
$this->sessionDataAjax['folderName'] = 'INBOX';
$this->sessionDataAjax['folderName'] = $this->sessionData['mailbox']?$this->sessionData['mailbox']:'INBOX';
}
//error_log("ajaxfelamimail::ajaxfelamimail ActiveProfile:".$this->imapServerID.' activeFolder:'.$this->sessionDataAjax['folderName'].'./.'.$this->sessionData['mailbox'].' ConnectionStatus:'.array2string($this->_connectionStatus));
}
function addACL($_accountName, $_aclData, $_recursive=false)
@ -331,7 +331,7 @@ class ajaxfelamimail
$lastDrafted = false;
if (isset($bocompose->sessionData['lastDrafted'])) $lastDrafted = $bocompose->sessionData['lastDrafted'];
$messageUid = $bocompose->saveAsDraft($formData,$folder); // folder may change
if ($lastDrafted && is_array($lastDrafted) && isset($lastDrafted['uid']) && !empty($lastDrafted['uid'])) $lastDrafted['uid'] = trim($lastDrafted['uid']);
if ($lastDrafted && is_array($lastDrafted) && isset($lastDrafted['uid']) && !empty($lastDrafted['uid'])) $lastDrafted['uid'] = trim($lastDrafted['uid']);
if ($lastDrafted && is_array($lastDrafted) && isset($lastDrafted['uid']) && !empty($lastDrafted['uid'])) $this->bofelamimail->deleteMessages((array)$lastDrafted['uid'],$lastDrafted['folder']);
if ($_autoSave)
{
@ -355,7 +355,7 @@ class ajaxfelamimail
$folder = ($this->bofelamimail->mailPreferences->ic_server[$this->bofelamimail->profileID]->draftfolder ? $this->bofelamimail->mailPreferences->ic_server[$this->bofelamimail->profileID]->draftfolder : $this->bofelamimail->mailPreferences->preferences['draftFolder']);
$this->bofelamimail->reopen($folder);
if (isset($bocompose->sessionData['lastDrafted'])) $lastDrafted = $bocompose->sessionData['lastDrafted'];
if ($lastDrafted && is_array($lastDrafted) && isset($lastDrafted['uid']) && !empty($lastDrafted['uid'])) $lastDrafted['uid'] = trim($lastDrafted['uid']);
if ($lastDrafted && is_array($lastDrafted) && isset($lastDrafted['uid']) && !empty($lastDrafted['uid'])) $lastDrafted['uid'] = trim($lastDrafted['uid']);
if ($lastDrafted && is_array($lastDrafted) && isset($lastDrafted['uid']) && !empty($lastDrafted['uid'])) $this->bofelamimail->deleteMessages((array)$lastDrafted['uid'],$lastDrafted['folder']);
if($this->_debug) error_log(__METHOD__.__LINE__.' removed last drafted:'.$lastDrafted['uid'].' in '.$lastDrafted['folder']);
}
@ -583,7 +583,7 @@ class ajaxfelamimail
function sendNotify ($_uid, $_ret)
{
if($this->_debug) error_log(__METHOD__." with $_uid,$_ret");
if($this->_debug) error_log(__METHOD__." with $_uid,$_ret for Folder:".$this->sessionDataAjax['folderName'].'./.'.$this->sessionData['mailbox']);
$response = new xajaxResponse();
if ($_ret==='true' || $_ret===1 || $_ret == "1,") {
if ( $this->bofelamimail->sendMDN($_uid) )
@ -733,7 +733,7 @@ class ajaxfelamimail
$response->addScript("egw_topWindow().tree.selectItem('".$_folderName. "',false);");
if($this->_debug) error_log('generateMessageList done');
if ($this->sessionData['previewMessage']>0)
if ($this->sessionData['previewMessage']>0)
{
$response->addScript('fm_previewMessageID = "";');
$response->addScript('mail_focusGridElement('.$this->sessionData['previewMessage'].');');

View File

@ -150,15 +150,28 @@ class felamimail_bo
else
{
// make sure the prefs are up to date for the profile to load
$loadfailed = false;
self::$instances[$_profileID]->mailPreferences = self::$instances[$_profileID]->bopreferences->getPreferences(true,$_profileID);
//error_log(__METHOD__.__LINE__." ReRead the Prefs for ProfileID ".$_profileID.' called from:'.function_backtrace());
if (self::$instances[$_profileID]->mailPreferences) {
self::$instances[$_profileID]->icServer = self::$instances[$_profileID]->mailPreferences->getIncomingServer($_profileID);
// if we do not get an icServer object, session restore failed on bopreferences->getPreferences
if (!self::$instances[$_profileID]->icServer) $loadfailed=true;
if ($_profileID != 0) self::$instances[$_profileID]->mailPreferences->setIncomingServer(self::$instances[$_profileID]->icServer,0);
self::$instances[$_profileID]->ogServer = self::$instances[$_profileID]->mailPreferences->getOutgoingServer($_profileID);
if ($_profileID != 0) self::$instances[$_profileID]->mailPreferences->setOutgoingServer(self::$instances[$_profileID]->ogServer,0);
self::$instances[$_profileID]->htmlOptions = self::$instances[$_profileID]->mailPreferences->preferences['htmlOptions'];
}
else
{
$loadfailed=true;
}
if ($loadfailed)
{
error_log(__METHOD__.__LINE__." ReRead of the Prefs for ProfileID ".$_profileID.' failed for icServer; trigger new instance. called from:'.function_backtrace());
// restore session seems to provide an incomplete session
self::$instances[$_profileID] = new felamimail_bo('utf-8',false,$_profileID);
}
}
self::$instances[$_profileID]->profileID = $_profileID;
//error_log(__METHOD__.__LINE__.' RestoreSession:'.$_restoreSession.' ProfileId:'.$_profileID);
@ -361,6 +374,17 @@ class felamimail_bo
{
foreach($nameSpace as $type => $singleNameSpace)
{
/*
if($type == 'personal' && ($singleNameSpace[2]['name'] == '#mh/' || count($nameSpace) == 1) && ($this->icServer->mailboxExist('Mail')||$this->icServer->mailboxExist('INBOX'))) {
// uw-imap server with mailbox prefix or dovecot maybe
return ($this->icServer->mailboxExist('Mail')?'Mail':'');
} elseif($type == 'personal' && ($singleNameSpace[2]['name'] == '#mh/' || count($nameSpace) == 1) && $this->icServer->mailboxExist('mail')) {
// uw-imap server with mailbox prefix or dovecot maybe
return 'mail';
} else {
return $singleNameSpace[0]['name'];
}
*/
if($type == 'personal' && substr($singleNameSpace[2]['name'],0,strlen($folderName))==$folderName && ($singleNameSpace[2]['name'] == '#mh/' || count($nameSpace) == 1) && $this->icServer->mailboxExist('Mail')) {
// uw-imap server with mailbox prefix or dovecot maybe
return 'Mail';
@ -962,8 +986,9 @@ class felamimail_bo
return $flags;
}
function getNotifyFlags ($_messageUID) {
$flags = $this->icServer->getFlags($_messageUID, true);
function getNotifyFlags ($_messageUID, $flags=null)
{
if($flags===null) $flags = $this->icServer->getFlags($_messageUID, true);
if (self::$debug) error_log(__METHOD__.$_messageUID.array2string($flags));
if (PEAR::isError($flags)) {
return null;
@ -990,7 +1015,7 @@ class felamimail_bo
*/
function flagMessages($_flag, $_messageUID,$_folder=NULL)
{
//error_log(__METHOD__.__LINE__.'->' .$_flag."$_messageUID,$_folder");
//error_log(__METHOD__.__LINE__.'->' .$_flag." ".array2string($_messageUID).",$_folder");
if(!is_array($_messageUID)) {
#return false;
if ($_messageUID=='all')
@ -1069,6 +1094,7 @@ class felamimail_bo
$this->sessionData['folderStatus'][$this->profileID][$this->sessionData['mailbox']]['uidValidity'] = 0;
$this->saveSessionData();
//error_log(__METHOD__.__LINE__.'->' .$_flag." ".array2string($_messageUID).",".($_folder?$_folder:$this->sessionData['mailbox']));
return true; // as we do not catch/examine setFlags returnValue
}
@ -1190,51 +1216,9 @@ class felamimail_bo
$usepurify = false;
if ($usepurify)
{
// we may need a customized config, as we may allow external images, $GLOBALS['egw_info']['user']['preferences']['felamimail']['allowExternalIMGs']
$config = html::purifyCreateDefaultConfig();
$config->set('Core.Encoding', (self::$displayCharset?self::$displayCharset:'UTF-8'));
// maybe the two following lines are useful for caching???
$config->set('HTML.DefinitionID', 'felamimail');
$config->set('HTML.DefinitionRev', 1);
// doctype and tidylevel
$config->set('HTML.Doctype', 'XHTML 1.0 Transitional');
$config->set('HTML.TidyLevel', 'light');
// EnableID is needed for anchor tags
$config->set('Attr.EnableID',true);
// actual allowed tags and attributes
$config->set('URI.AllowedSchemes', array('http'=>true, 'https'=>true, 'ftp'=>true, 'file'=>true, 'cid'=>true, 'data'=>true));
//$config->set('AutoFormat.RemoveEmpty', true);
$config->set('HTML.Allowed', 'br,p[class|align],b,i,u,s,em,pre,tt,strong,strike,center,div[class|align],hr[class|style],'.
'font[size|color],'.
'ul[class|type],ol[class|type|start],li,'.
'h1,h2,h3,'.
'span[class|style],'.
'table[class|border|cellpadding|cellspacing|width|style|align|bgcolor|align],'.
'tbody,thead,tfoot,colgroup,'.
'col[width|span],'.
'blockquote[class|cite|dir],'.
'tr[class|style|align|bgcolor|align|valign],'.
'td[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],'.
'th[class|colspan|rowspan|width|style|align|bgcolor|align|valign|nowrap],'.
'a[class|href|target|name|title],'.
'img[class|src|alt|title]');
$DisableExternalResources = true;
if ($GLOBALS['egw_info']['user']['preferences']['felamimail']['allowExternalIMGs']) $DisableExternalResources = false;
$config->set('URI.DisableExternalResources',$DisableExternalResources);
$config->set('Core.RemoveInvalidImg', false);
//$config->set('Attr.DefaultInvalidImage', 'Image removed by htmlpurify');
$config->set('Core.HiddenElements', array('script','style','head')); // strips script, style, head copletely
$config->set('Cache.SerializerPath', ($GLOBALS['egw_info']['server']['temp_dir']?$GLOBALS['egw_info']['server']['temp_dir']:sys_get_temp_dir()));
//$config->set('HTML.MaxImgLength',null);
$config->set('Cache.DefinitionImpl', null); // remove this later!
//$purifier = new HTMLPurifier($config);
//$_html = $purifier->purify( $_html );
// we need a customized config, as we may allow external images, $GLOBALS['egw_info']['user']['preferences']['felamimail']['allowExternalIMGs']
if (get_magic_quotes_gpc() === 1) $_html = stripslashes($_html);
$_html = html::purify($_html,$config);
// no scripts allowed
$_html = html::purify($_html);
// clean out comments , should not be needed as purify should do the job.
$search = array(
'@url\(http:\/\/[^\)].*?\)@si', // url calls e.g. in style definitions
@ -1458,7 +1442,7 @@ class felamimail_bo
$_html = preg_replace('/([\000-\012])/','',$_html);
//error_log($_html);
}
// using purify above should have tidied the tags already sufficiently
// using purify above should have tidied the tags already sufficiently
if ($usepurify == false && $cleanTags==true)
{
if (extension_loaded('tidy'))
@ -1479,7 +1463,15 @@ class felamimail_bo
{
//$to = ini_get('max_execution_time');
//@set_time_limit(10);
$_html = html::purify($_html,html::purifyCreateHTMLTidyConfig());
//$p = microtime(true);
$htmLawed = new egw_htmLawed();
//$pela = microtime(true);
$_html = $htmLawed->egw_htmLawed($_html);
//$le = microtime(true);
//$a=$pela-$p;
//$b=$le-$pela;
//error_log(__METHOD__.__LINE__.' new egw_htmLawed:'.$a.' htmlLawed took:'.$b);
//error_log(__METHOD__.__LINE__.$_html);
//@set_time_limit($to);
}
}
@ -1882,7 +1874,7 @@ class felamimail_bo
if($type == 'personal' && ($singleNameSpace[2]['name'] == '#mh/' || count($nameSpace) == 1) && ($this->icServer->mailboxExist('Mail')||$this->icServer->mailboxExist('INBOX'))) {
$prefix_present = 'forced';
// uw-imap server with mailbox prefix or dovecot maybe
$foldersNameSpace[$type]['prefix'] = ($this->icServer->mailboxExist('Mail')?'Mail':'');
$foldersNameSpace[$type]['prefix'] = ($this->icServer->mailboxExist('Mail')?'Mail':'');
} elseif($type == 'personal' && ($singleNameSpace[2]['name'] == '#mh/' || count($nameSpace) == 1) && $this->icServer->mailboxExist('mail')) {
$prefix_present = 'forced';
// uw-imap server with mailbox prefix or dovecot maybe
@ -3478,7 +3470,7 @@ class felamimail_bo
if(($this->icServer instanceof defaultimap)) $folderInfo[$this->profileID][$_folder] = $this->icServer->mailboxExist($_folder);
//error_log(__METHOD__.__LINE__.' Folder Exists:'.$folderInfo[$this->profileID][$_folder].function_backtrace());
if(!empty($folderInfo) && isset($folderInfo[$this->profileID][$_folder]) &&
if(!empty($folderInfo) && isset($folderInfo[$this->profileID][$_folder]) &&
($folderInfo[$this->profileID][$_folder] instanceof PEAR_Error) || $folderInfo[$this->profileID][$_folder] !== true)
{
$folderInfo[$this->profileID][$_folder] = false; // set to false, whatever it was (to have a valid returnvalue for the static return)
@ -3557,7 +3549,7 @@ class felamimail_bo
static $isError;
//error_log(__METHOD__.__LINE__.'->'.$_icServerID.' called from '.function_backtrace());
if (is_null($isError)) $isError = egw_cache::getCache(egw_cache::INSTANCE,'email','icServerIMAP_connectionError'.trim($GLOBALS['egw_info']['user']['account_id']),null,array(),$expiration=60*5);
if ( isset($isError[$_icServerID]) || (($this->icServer instanceof defaultimap) && PEAR::isError($this->icServer->_connectionErrorObject)))
if ( isset($isError[$_icServerID]) || (($this->icServer instanceof defaultimap) && PEAR::isError($this->icServer->_connectionErrorObject)))
{
if (trim($isError[$_icServerID])==',' || trim($this->icServer->_connectionErrorObject->message) == ',')
{
@ -3657,7 +3649,7 @@ class felamimail_bo
function reopen($_foldername)
{
//error_log( "------------------------reopen-<br>");
//error_log(print_r($this->icServer->_connected,true));
//error_log(__METHOD__.__LINE__.' Connected with icServer for Profile:'.$this->profileID.'?'.print_r($this->icServer->_connected,true));
if ($this->icServer->_connected == 1) {
$tretval = $this->icServer->selectMailbox($_foldername);
} else {
@ -3867,7 +3859,8 @@ class felamimail_bo
return ($_reverse?'REVERSE ':'').$retValue;
}
function sendMDN($uid) {
function sendMDN($uid)
{
$identities = $this->mailPreferences->getIdentity();
$headers = $this->getMessageHeader($uid);
$send = CreateObject('phpgwapi.send');
@ -3881,7 +3874,7 @@ class felamimail_bo
if ( preg_match('/\b'.$identity->emailAddress.'\b/',$headers['TO']) ) {
$send->From = $identity->emailAddress;
$send->FromName = $identity->realName;
error_log(__METHOD__.__LINE__.' using identity for send from:'.$send->From.' to match header information:'.$headers['TO']);
error_log(__METHOD__.__LINE__.' using identity for send from:'.$send->From.' to match header information:'.$headers['TO'].' ProfileID:'.$this->profileID.' Folder:'.$this->sessionData['mailbox']);
break;
}
if($identity->default) {
@ -4309,11 +4302,11 @@ class felamimail_bo
{
$headdata = null;
if ($header['SUBJECT']) $headdata = lang('subject').': '.$header['SUBJECT'].($createHTML?"<br />":"\n");
if ($header['FROM']) $headdata .= lang('from').': '.self::convertAddressArrayToString($header['FROM']).($createHTML?"<br />":"\n");
if ($header['SENDER']) $headdata .= lang('sender').': '.self::convertAddressArrayToString($header['SENDER']).($createHTML?"<br />":"\n");
if ($header['TO']) $headdata .= lang('to').': '.self::convertAddressArrayToString($header['TO']).($createHTML?"<br />":"\n");
if ($header['CC']) $headdata .= lang('cc').': '.self::convertAddressArrayToString($header['CC']).($createHTML?"<br />":"\n");
if ($header['BCC']) $headdata .= lang('bcc').': '.self::convertAddressArrayToString($header['BCC']).($createHTML?"<br />":"\n");
if ($header['FROM']) $headdata .= lang('from').': '.self::convertAddressArrayToString($header['FROM'], $createHTML).($createHTML?"<br />":"\n");
if ($header['SENDER']) $headdata .= lang('sender').': '.self::convertAddressArrayToString($header['SENDER'], $createHTML).($createHTML?"<br />":"\n");
if ($header['TO']) $headdata .= lang('to').': '.self::convertAddressArrayToString($header['TO'], $createHTML).($createHTML?"<br />":"\n");
if ($header['CC']) $headdata .= lang('cc').': '.self::convertAddressArrayToString($header['CC'], $createHTML).($createHTML?"<br />":"\n");
if ($header['BCC']) $headdata .= lang('bcc').': '.self::convertAddressArrayToString($header['BCC'], $createHTML).($createHTML?"<br />":"\n");
if ($header['DATE']) $headdata .= lang('date').': '.$header['DATE'].($createHTML?"<br />":"\n");
if ($header['PRIORITY'] && $header['PRIORITY'] != 'normal') $headdata .= lang('priority').': '.$header['PRIORITY'].($createHTML?"<br />":"\n");
if ($header['IMPORTANCE'] && $header['IMPORTANCE'] !='normal') $headdata .= lang('importance').': '.$header['IMPORTANCE'].($createHTML?"<br />":"\n");
@ -4336,7 +4329,7 @@ class felamimail_bo
* @param array $rfcAddressArray an addressarray as provided by felamimail retieved via egw_pear....
* @return string a comma separated string with the mailaddress(es) converted to text
*/
static function convertAddressArrayToString($rfcAddressArray)
static function convertAddressArrayToString($rfcAddressArray, $createHTML = false)
{
//error_log(__METHOD__.__LINE__.array2string($rfcAddressArray));
$returnAddr ='';
@ -4367,14 +4360,18 @@ class felamimail_bo
//$p = (string)$addressObject->personal;
$returnAddr .= (strlen($returnAddr)>0?',':'');
//error_log(__METHOD__.__LINE__.$p.' <'.$mb.'@'.$h.'>');
$returnAddr .= imap_rfc822_write_address($addressObject->mailbox, $addressObject->host, $addressObject->personal);
$buff = imap_rfc822_write_address($addressObject->mailbox, $addressObject->host, $addressObject->personal);
$buff = str_replace(array('<','>'),array('[',']'),$buff);
if ($createHTML) $buff = felamimail_bo::htmlspecialchars($buff);
//error_log(__METHOD__.__LINE__.' Address: '.$returnAddr);
$returnAddr .= $buff;
}
}
else
{
// do not mess with strings, return them untouched /* ToDo: validate string as Address */
if (is_string($rfcAddressArray)) return $rfcAddressArray;
$rfcAddressArray = str_replace(array('<','>'),array('[',']'),$rfcAddressArray);
if (is_string($rfcAddressArray)) return ($createHTML ? felamimail_bo::htmlspecialchars($rfcAddressArray) : $rfcAddressArray);
}
return $returnAddr;
}
@ -4448,6 +4445,32 @@ class felamimail_bo
}
if (isset($bodyParts[$i]['error'])) continue;
if (empty($bodyParts[$i]['body'])) continue;
// some characterreplacements, as they fail to translate
$sar = array(
'@(\x84|\x93|\x94)@',
'@(\x96|\x97|\x1a)@',
'@(\x82|\x91|\x92)@',
'@(\x85)@',
'@(\x86)@',
'@(\x99)@',
'@(\xae)@',
);
$rar = array(
'"',
'-',
'\'',
'...',
'&',
'(TM)',
'(R)',
);
if(($bodyParts[$i]['mimeType'] == 'text/html' || $bodyParts[$i]['mimeType'] == 'text/plain') &&
strtoupper($bodyParts[$i]['charSet']) != 'UTF-8')
{
$bodyParts[$i]['body'] = preg_replace($sar,$rar,$bodyParts[$i]['body']);
}
if ($bodyParts[$i]['charSet']===false) $bodyParts[$i]['charSet'] = self::detect_encoding($bodyParts[$i]['body']);
// add line breaks to $bodyParts
//error_log(__METHOD__.__LINE__.' Charset:'.$bodyParts[$i]['charSet'].'->'.$bodyParts[$i]['body']);
@ -4487,7 +4510,9 @@ class felamimail_bo
}
else
{
$newBody = html::purify($newBody,html::purifyCreateHTMLTidyConfig());
$htmLawed = new egw_htmLawed();
$newBody = $htmLawed->egw_htmLawed($newBody);
//$newBody = html::purify($newBody,html::purifyCreateHTMLTidyConfig());
}
//error_log(__METHOD__.__LINE__.' after purify:'.$newBody);
if ($preserveHTML==false) $newBody = $bofelamimail->convertHTMLToText($newBody,true);

View File

@ -354,7 +354,7 @@
$this->t->set_var('charset',$GLOBALS['egw']->translation->charset());
}
// only notify when requested, notify flag (MDNSent/MDNnotSent) not set, and message not already seen (some servers do not support the MDNSent/MDNnotSent flag)
if ( $sent_not != "" && $this->bofelamimail->getNotifyFlags($this->uid) === null && strpos( array2string($flags),'Seen')===false) {
if ( $sent_not != "" && $this->bofelamimail->getNotifyFlags($this->uid,($flags?$flags:null)) === null && strpos( array2string($flags),'Seen')===false) {
$this->t->set_var('sentNotify','sendNotify("'.$this->uid.'");');
$this->t->set_var('lang_sendnotify',lang('The message sender has requested a response to indicate that you have read this message. Would you like to send a receipt?'));
} else {

View File

@ -1464,7 +1464,7 @@ $j(document).ready(function() {
$this->bofelamimail->openConnection($_icServer);
$this->bofelamimail->reopen($_folderName);
$flags = $this->bofelamimail->getFlags($headerData['uid']);
if ($this->bofelamimail->getNotifyFlags($headerData['uid']) === null)
if ($this->bofelamimail->getNotifyFlags($headerData['uid'],($flags?$flags:null)) === null)
{
$headers = $this->bofelamimail->getMessageHeader($headerData['uid']);
if ( isset($headers['DISPOSITION-NOTIFICATION-TO']) ) {
@ -1749,7 +1749,7 @@ $j(document).ready(function() {
),
);
// display only the correct icon: revert on deleted messages, delete on all others
if ($_headerData['deleted'])
if ($_headerData['deleted'])
{
unset($navbarImages['delete']);
} else {