diff --git a/felamimail/inc/class.ajaxfelamimail.inc.php b/felamimail/inc/class.ajaxfelamimail.inc.php index 4eda827ba7..a960bb476a 100644 --- a/felamimail/inc/class.ajaxfelamimail.inc.php +++ b/felamimail/inc/class.ajaxfelamimail.inc.php @@ -738,6 +738,11 @@ $_messageID ); $headerData = $headerData['header'][0]; + foreach ($headerData as $key => $val) + { + $headerData[$key] = bofelamimail::htmlentities($val); + } + $headerData['subject'] = $this->bofelamimail->decode_subject($headerData['subject'],false); $this->sessionData['previewMessage'] = $headerData['uid']; $this->saveSessionData(); //error_log(print_r($headerData,true)); diff --git a/felamimail/inc/class.bocompose.inc.php b/felamimail/inc/class.bocompose.inc.php index 5b2598aba7..c8d3a304a7 100644 --- a/felamimail/inc/class.bocompose.inc.php +++ b/felamimail/inc/class.bocompose.inc.php @@ -65,60 +65,21 @@ */ function addAttachment($_formData) { -#echo "addattachment
"; -#_debug_array($_formData); + $attachfailed = false; // to gard against exploits the file must be either uploaded or be in the temp_dir - if ($_formData['size'] != 0 && (is_uploaded_file($_formData['file']) || - realpath(dirname($_formData['file'])) == realpath($GLOBALS['egw_info']['server']['temp_dir'])) || - parse_url($_formData['file'],PHP_URL_SCHEME) == 'vfs') + // check if formdata meets basic restrictions (in tmp dir, or vfs, mimetype, etc.) + try { - // ensure existance of eGW temp dir - // note: this is different from apache temp dir, - // and different from any other temp file location set in php.ini - if (!file_exists($GLOBALS['egw_info']['server']['temp_dir'])) - { - @mkdir($GLOBALS['egw_info']['server']['temp_dir'],0700); - } + $tmpFileName = bofelamimail::checkFileBasics($_formData,$this->composeID,false); + } + catch (egw_exception_wrong_userinput $e) + { + $attachfailed = true; + $alert_msg = $e->getMessage(); + } - // if we were NOT able to create this temp directory, then make an ERROR report - if (!file_exists($GLOBALS['egw_info']['server']['temp_dir'])) - { - $alert_msg .= 'Error:'.'
' - .'Server is unable to access phpgw tmp directory'.'
' - .$GLOBALS['egw_info']['server']['temp_dir'].'
' - .'Please check your configuration'.'
' - .'
'; - } - - // sometimes PHP is very clue-less about MIME types, and gives NO file_type - // rfc default for unknown MIME type is: - $mime_type_default = 'application/octet-stream'; - // so if PHP did not pass any file_type info, then substitute the rfc default value - if (trim($_formData['type']) == '') - { - $_formData['type'] = $mime_type_default; - } - - $tmpFileName = $GLOBALS['egw_info']['server']['temp_dir']. - SEP. - md5(time().$GLOBALS['egw_info']['user']['account_id'].$this->composeID.basename($_formData['file'])); - - if (parse_url($_formData['file'],PHP_URL_SCHEME) == 'vfs') - { - $tmpFileName = $_formData['file']; // no need to store it somewhere - } - elseif (is_uploaded_file($_formData['file'])) - { - //error_log(__METHOD__." Uploaded File:".$_formData['file']." with filesize:".filesize($_formData['file'])); - move_uploaded_file($_formData['file'],$tmpFileName); // requirement for safe_mode! - //error_log(__METHOD__." copy to :".$tmpFileName." with filesize:".filesize($tmpFileName)); - } - else - { - rename($_formData['file'],$tmpFileName); - } - //$attachmentID = $this->getRandomString(); - //error_log(__METHOD__." add Attachment with ID (random String):".$attachmentID); + if ($attachfailed === false) + { $buffer = array( 'name' => $_formData['name'], 'type' => $_formData['type'], @@ -131,6 +92,10 @@ $this->sessionData['attachments'][$attachmentID] = $buffer; unset($buffer); } + else + { + error_log(__METHOD__.__LINE__.array2string($alert_msg)); + } $this->saveSessionData(); #print"
";
@@ -580,24 +545,33 @@
 			$bodyParts = $bofelamimail->getMessageBody($_uid, $this->preferencesArray['always_display'], $_partID);
 			//_debug_array($bodyParts);
 
-			$fromAddress = ($headers['FROM'][0]['PERSONAL_NAME'] != 'NIL') ? $headers['FROM'][0]['RFC822_EMAIL'] : $headers['FROM'][0]['EMAIL'];
+			$fromAddress = bofelamimail::htmlspecialchars($bofelamimail->decode_header(($headers['FROM'][0]['PERSONAL_NAME'] != 'NIL') ? $headers['FROM'][0]['RFC822_EMAIL'] : $headers['FROM'][0]['EMAIL']));
+
 			$toAddressA = array();
 			$toAddress = '';
 			foreach ($headers['TO'] as $mailheader) {
 				$toAddressA[] =  ($mailheader['PERSONAL_NAME'] != 'NIL') ? $mailheader['RFC822_EMAIL'] : $mailheader['EMAIL'];
 			}
-			if (count($toAddressA)>0) $toAddress = @htmlspecialchars(lang("to").": ".$bofelamimail->decode_header(implode(', ', $toAddressA)),ENT_QUOTES).($bodyParts['0']['mimeType'] == 'text/html'?"\r\n
":"\r\n"); + if (count($toAddressA)>0) + { + $toAddress = bofelamimail::htmlspecialchars($bofelamimail->decode_header(implode(', ', $toAddressA))); + $toAddress = @htmlspecialchars(lang("to")).": ".$toAddress.($bodyParts['0']['mimeType'] == 'text/html'?"\r\n
":"\r\n");; + } $ccAddressA = array(); $ccAddress = ''; foreach ($headers['CC'] as $mailheader) { $ccAddressA[] = ($mailheader['PERSONAL_NAME'] != 'NIL') ? $mailheader['RFC822_EMAIL'] : $mailheader['EMAIL']; } - if (count($ccAddressA)>0) $ccAddress = @htmlspecialchars(lang("cc").": ".$bofelamimail->decode_header(implode(', ', $ccAddressA)),ENT_QUOTES).($bodyParts['0']['mimeType'] == 'text/html'?"\r\n
":"\r\n"); + if (count($ccAddressA)>0) + { + $ccAddress = bofelamimail::htmlspecialchars($bofelamimail->decode_header(implode(', ', $ccAddressA))); + $ccAddress = @htmlspecialchars(lang("cc")).": ".$ccAddressA.($bodyParts['0']['mimeType'] == 'text/html'?"\r\n
":"\r\n"); + } if($bodyParts['0']['mimeType'] == 'text/html') { $this->sessionData['body'] = "
 \r\n

".'----------------'.lang("original message").'-----------------'."\r\n".'
'. - @htmlspecialchars(lang("from").": ".$bofelamimail->decode_header($fromAddress),ENT_QUOTES)."\r\n
". + @htmlspecialchars(lang("from")).": ".$fromAddress."\r\n
". $toAddress.$ccAddress. - @htmlspecialchars(lang("date").": ".$headers['DATE'],ENT_QUOTES)."\r\n
". + @htmlspecialchars(lang("date").": ".$headers['DATE'],ENT_QUOTES | ENT_IGNORE,bofelamimail::$displayCharset, false)."\r\n
". '----------------------------------------------------------'."\r\n

"; $this->sessionData['mimeType'] = 'html'; $this->sessionData['body'] .= '
'; @@ -619,9 +593,9 @@ } else { #$this->sessionData['body'] = @htmlspecialchars(lang("on")." ".$headers['DATE']." ".$bofelamimail->decode_header($fromAddress), ENT_QUOTES) . " ".lang("wrote").":\r\n"; $this->sessionData['body'] = " \r\n \r\n".'----------------'.lang("original message").'-----------------'."\r\n". - @htmlspecialchars(lang("from").": ".$bofelamimail->decode_header($fromAddress),ENT_QUOTES)."\r\n". + @htmlspecialchars(lang("from")).": ".$fromAddress."\r\n". $toAddress.$ccAddress. - @htmlspecialchars(lang("date").": ".$headers['DATE'], ENT_QUOTES)."\r\n". + @htmlspecialchars(lang("date").": ".$headers['DATE'], ENT_QUOTES | ENT_IGNORE,bofelamimail::$displayCharset, false)."\r\n". '-------------------------------------------------'."\r\n \r\n "; $this->sessionData['mimeType'] = 'plain'; diff --git a/felamimail/inc/class.bofelamimail.inc.php b/felamimail/inc/class.bofelamimail.inc.php index 7e8c2a7867..7903648335 100644 --- a/felamimail/inc/class.bofelamimail.inc.php +++ b/felamimail/inc/class.bofelamimail.inc.php @@ -3024,6 +3024,60 @@ } return preg_match("$needle",$string); } + + /** + * htmlspecialchars + * helperfunction to cope with wrong encoding in strings + * @param string $_string input to be converted + * @param mixed $charset false or string -> Target charset, if false bofelamimail displayCharset will be used + * @return string + */ + static function htmlspecialchars($_string, $_charset=false) + { + //setting the charset (if not given) + if ($_charset===false) $_charset = bofelamimail::$displayCharset; + $_stringORG = $_string; + $_string = @htmlspecialchars($_string,ENT_QUOTES,$_charset, false); + if (empty($_string) && !empty($_stringORG)) $_string = @htmlspecialchars($GLOBALS['egw']->translation->convert($_stringORG,bofelamimail::detect_encoding($_stringORG),$_charset),ENT_QUOTES | ENT_IGNORE,$_charset, false); + return $_string; + } + + /** + * htmlentities + * helperfunction to cope with wrong encoding in strings + * @param string $_string input to be converted + * @param mixed $charset false or string -> Target charset, if false bofelamimail displayCharset will be used + * @return string + */ + static function htmlentities($_string, $_charset=false) + { + //setting the charset (if not given) + if ($_charset===false) $_charset = bofelamimail::$displayCharset; + $_stringORG = $_string; + $_string = @htmlentities($_string,ENT_QUOTES,$_charset, false); + if (empty($_string) && !empty($_stringORG)) $_string = @htmlentities($GLOBALS['egw']->translation->convert($_stringORG,bofelamimail::detect_encoding($_stringORG),$_charset),ENT_QUOTES | ENT_IGNORE,$_charset, false); + return $_string; + } + + /** + * detect_encoding - try to detect the encoding + * only to be used if the string in question has no structure that determines his encoding + * @param string - to be evaluated + * @returns mixed string/boolean (encoding or false + */ + static function detect_encoding($string) { + static $list = array('utf-8', 'iso-8859-1', 'windows-1251'); // list may be extended + if (function_exists('iconv')) + { + foreach ($list as $item) { + $sample = iconv($item, $item, $string); + if (md5($sample) == md5($string)) + return $item; + } + } + return false; // we may choose to return iso-8859-1 as default at some point + } + static function detect_qp(&$sting) { $needle = '/(=[0-9][A-F])|(=[A-F][0-9])|(=[A-F][A-F])|(=[0-9][0-9])/'; return preg_match("$needle",$string); @@ -3053,4 +3107,295 @@ } return $date2return; } + + /** + * checkFileBasics + * check if formdata meets basic restrictions (in tmp dir, or vfs, mimetype, etc.) + * + * @param array $_formData passed by reference Array with information of name, type, file and size, mimetype may be adapted + * @param string $IDtoAddToFileName id to enrich the returned tmpfilename + * @param string $reqMimeType /(default message/rfc822, if set to false, mimetype check will not be performed + * @return mixed $fullPathtoFile or exception + */ + static function checkFileBasics(&$_formData, $IDtoAddToFileName='', $reqMimeType='message/rfc822') + { + //error_log(__METHOD__.__FILE__.array2string($_formData).' Id:'.$IDtoAddToFileName.' ReqMimeType:'.$reqMimeType); + $importfailed = $tmpFileName = false; + if ($_formData['size'] != 0 && (is_uploaded_file($_formData['file']) || + realpath(dirname($_formData['file'])) == realpath($GLOBALS['egw_info']['server']['temp_dir']) || + parse_url($_formData['file'],PHP_URL_SCHEME) == 'vfs')) + { + // ensure existance of eGW temp dir + // note: this is different from apache temp dir, + // and different from any other temp file location set in php.ini + if (!file_exists($GLOBALS['egw_info']['server']['temp_dir'])) + { + @mkdir($GLOBALS['egw_info']['server']['temp_dir'],0700); + } + + // if we were NOT able to create this temp directory, then make an ERROR report + if (!file_exists($GLOBALS['egw_info']['server']['temp_dir'])) + { + $alert_msg .= 'Error:'.'
' + .'Server is unable to access phpgw tmp directory'.'
' + .$GLOBALS['egw_info']['server']['temp_dir'].'
' + .'Please check your configuration'.'
' + .'
'; + } + + // sometimes PHP is very clue-less about MIME types, and gives NO file_type + // rfc default for unknown MIME type is: + if ($reqMimeType == 'message/rfc822') + { + $mime_type_default = 'message/rfc'; + } + else + { + $mime_type_default = $reqMimeType; + } + if (trim($_formData['type']) == '') + { + $_formData['type'] = 'application/octet-stream'; + } + // if reqMimeType is set to false do not test for that + if ($reqMimeType) + { + // so if PHP did not pass any file_type info, then substitute the rfc default value + if (substr(strtolower(trim($_formData['type'])),0,strlen($mime_type_default)) != $mime_type_default) + { + // maybe its application/octet-stream -> this may mean that we could not determine the type + // so we check for the suffix too + $buff = explode('.',$_formData['name']); + $suffix = ''; + if (is_array($buff)) $suffix = array_pop($buff); // take the last extension to check with ext2mime + if (!(strtolower(trim($_formData['type'])) == "application/octet-stream" && mime_magic::ext2mime($suffix)== $reqMimeType)) + { + //error_log("Message rejected, no message/rfc. Is:".$_formData['type']); + $importfailed = true; + $alert_msg .= lang("File rejected, no %2. Is:%1",$_formData['type'],$reqMimeType); + } + if ((strtolower(trim($_formData['type'])) != $reqMimeType && mime_magic::ext2mime($suffix)== $reqMimeType)) + { + $_formData['type'] = mime_magic::ext2mime($suffix); + } + } + } + + $tmpFileName = $GLOBALS['egw_info']['server']['temp_dir']. + SEP. + $GLOBALS['egw_info']['user']['account_id']. + trim($IDtoAddToFileName).basename($_formData['file']); + + if (parse_url($_formData['file'],PHP_URL_SCHEME) == 'vfs') + { + $tmpFileName = $_formData['file']; // no need to store it somewhere + } + elseif (is_uploaded_file($_formData['file'])) + { + move_uploaded_file($_formData['file'],$tmpFileName); // requirement for safe_mode! + } + else + { + rename($_formData['file'],$tmpFileName); + } + } else { + //error_log("Import of message ".$_formData['file']." failes to meet basic restrictions"); + $importfailed = true; + $alert_msg .= lang("Processing of file %1 failed. Failed to meet basic restrictions.",$_formData['name']); + } + if ($importfailed == true) + { + throw new egw_exception_wrong_userinput($alert_msg); + } + else + { + if (parse_url($tmpFileName,PHP_URL_SCHEME) == 'vfs') + { + egw_vfs::load_wrapper('vfs'); + } + return $tmpFileName; + } + } + + /** + * getRandomString - function to be used to fetch a random string and md5 encode that one + * @param none + * @return string - a random number which is md5 encoded + */ + static function getRandomString() { + mt_srand((float) microtime() * 1000000); + return md5(mt_rand (100000, 999999)); + } + + /** + * functions to allow access to mails through other apps to fetch content + * used in infolog, tracker + */ + + /** + * get_mailcontent - fetches the actual mailcontent, and returns it as well defined array + * @param bofelamimail the bofelamimailobject to be used + * @param uid the uid of the email to be processed + * @param partid the partid of the email + * @param mailbox the mailbox, that holds the message + * @returns array with 'mailaddress'=>$mailaddress, + * 'subject'=>$subject, + * 'message'=>$message, + * 'attachments'=>$attachments, + * 'headers'=>$headers, + */ + static function get_mailcontent(&$bofelamimail,$uid,$partid='',$mailbox='') + { + //echo __METHOD__." called for $uid,$partid
"; + $headers = $bofelamimail->getMessageHeader($uid,$partid,true); + // dont force retrieval of the textpart, let felamimail preferences decide + $bodyParts = $bofelamimail->getMessageBody($uid,'',$partid); + $attachments = $bofelamimail->getMessageAttachments($uid,$partid); + + if ($bofelamimail->isSentFolder($mailbox)) $mailaddress = $headers['TO']; + elseif (isset($headers['FROM'])) $mailaddress = $headers['FROM']; + elseif (isset($headers['SENDER'])) $mailaddress = $headers['SENDER']; + if (isset($headers['CC'])) $mailaddress .= ','.$headers['CC']; + //_debug_array($headers); + $subject = $headers['SUBJECT']; + + $message = self::getdisplayableBody($bofelamimail, $bodyParts); + $headdata = self::createHeaderInfoSection($headers); + $message = $headdata.$message; + //echo __METHOD__.'
'; + //_debug_array($attachments); + if (is_array($attachments)) + { + foreach ($attachments as $num => $attachment) + { + if ($attachment['mimeType'] == 'MESSAGE/RFC822') + { + //_debug_array($bofelamimail->getMessageHeader($uid, $attachment['partID'])); + //_debug_array($bofelamimail->getMessageBody($uid,'', $attachment['partID'])); + //_debug_array($bofelamimail->getMessageAttachments($uid, $attachment['partID'])); + $mailcontent = self::get_mailcontent($bofelamimail,$uid,$attachment['partID']); + $headdata =''; + if ($mailcontent['headers']) + { + $headdata = self::createHeaderInfoSection($mailcontent['headers']); + } + if ($mailcontent['message']) + { + $tempname =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_"); + $attachedMessages[] = array( + 'type' => 'TEXT/PLAIN', + 'name' => $mailcontent['subject'].'.txt', + 'tmp_name' => $tempname, + ); + $tmpfile = fopen($tempname,'w'); + fwrite($tmpfile,$headdata.$mailcontent['message']); + fclose($tmpfile); + } + foreach($mailcontent['attachments'] as $tmpattach => $tmpval) + { + $attachedMessages[] = $tmpval; + } + unset($attachments[$num]); + } + else + { + $attachments[$num] = array_merge($attachments[$num],$bofelamimail->getAttachment($uid, $attachment['partID'])); + if (isset($attachments[$num]['charset'])) { + if ($attachments[$num]['charset']===false) $attachments[$num]['charset'] = self::detect_encoding($attachments[$num]['attachment']); + $GLOBALS['egw']->translation->convert($attachments[$num]['attachment'],$attachments[$num]['charset']); + } + $attachments[$num]['type'] = $attachments[$num]['mimeType']; + $attachments[$num]['tmp_name'] = tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_"); + $tmpfile = fopen($attachments[$num]['tmp_name'],'w'); + fwrite($tmpfile,$attachments[$num]['attachment']); + fclose($tmpfile); + unset($attachments[$num]['attachment']); + } + } + if (is_array($attachedMessages)) $attachments = array_merge($attachments,$attachedMessages); + } + return array( + 'mailaddress'=>$mailaddress, + 'subject'=>$subject, + 'message'=>$message, + 'attachments'=>$attachments, + 'headers'=>$headers, + ); + } + + /** + * createHeaderInfoSection - creates a textual headersection from headerobject + * @params header headerarray may contain SUBJECT,FROM,SENDER,TO,CC,BCC,DATE,PRIORITY,IMPORTANCE + * @returns string a preformatted string with the information of the header worked into it + */ + static function createHeaderInfoSection($header,$headline='') + { + $headdata = null; + if ($header['SUBJECT']) $headdata = lang('subject').': '.$header['SUBJECT']."\n"; + if ($header['FROM']) $headdata .= lang('from').': '.$header['FROM']."\n"; + if ($header['SENDER']) $headdata .= lang('sender').': '.$header['SENDER']."\n"; + if ($header['TO']) $headdata .= lang('to').': '.$header['TO']."\n"; + if ($header['CC']) $headdata .= lang('cc').': '.$header['CC']."\n"; + if ($header['BCC']) $headdata .= lang('bcc').': '.$header['BCC']."\n"; + if ($header['DATE']) $headdata .= lang('date').': '.$header['DATE']."\n"; + if ($header['PRIORITY'] && $header['PRIORITY'] != 'normal') $headdata .= lang('priority').': '.$header['PRIORITY']."\n"; + if ($header['IMPORTANCE'] && $header['IMPORTANCE'] !='normal') $headdata .= lang('importance').': '.$header['IMPORTANCE']."\n"; + //if ($mailcontent['headers']['ORGANIZATION']) $headdata .= lang('organization').': '.$mailcontent['headers']['ORGANIZATION']."\ + if (!empty($headdata)) + { + if (!empty($headline)) $headdata = "---------------------------- $headline ----------------------------\n".$headdata; + if (empty($headline)) $headdata = "--------------------------------------------------------\n".$headdata; + $headdata .= "--------------------------------------------------------\n"; + } + else + { + $headdata = "--------------------------------------------------------\n"; + } + return $headdata; + } + + /** + * getdisplayableBody - creates the bodypart of the email as textual representation + * @param bofelamimail the bofelamimailobject to be used + * @params bodyPorts array with the bodyparts + * @returns string a preformatted string with the mails converted to text + */ + static function &getdisplayableBody(&$bofelamimail, $bodyParts) + { + for($i=0; $itranslation->convert($bodyParts[$i]['body'], $bodyParts[$i]['charSet']); + + if ($bodyParts[$i]['mimeType'] == 'text/html') { + // convert HTML to text, as we dont want HTML in infologs + $newBody = html::purify($newBody); + $newBody = $bofelamimail->convertHTMLToText($newBody,true); + $bofelamimail->getCleanHTML($newBody); // new Body passed by reference + $message .= $newBody; + continue; + } + $newBody = strip_tags($newBody); + $newBody = explode("\n",$newBody); + // create it new, with good line breaks + reset($newBody); + while(list($key,$value) = @each($newBody)) + { + if (trim($value) != '') { + #if ($value != "\r") $value .= "\n"; + } else { + // if you want to strip all empty lines uncomment the following + #continue; + } + $message .= $bofelamimail->wordwrap($value,75,"\n"); + } + } + return $message; + } } diff --git a/felamimail/inc/class.uicompose.inc.php b/felamimail/inc/class.uicompose.inc.php new file mode 100644 index 0000000000..cf71d32dce --- /dev/null +++ b/felamimail/inc/class.uicompose.inc.php @@ -0,0 +1,715 @@ + True, + 'compose' => True, + 'composeFromDraft' => True, + 'getAttachment' => True, + 'fileSelector' => True, + 'forward' => True, + 'composeAsNew' => True, + 'composeAsForward'=> True, + 'reply' => True, + 'replyAll' => True, + 'selectFolder' => True, + ); + + var $destinations = array( + 'to' => 'to', + 'cc' => 'cc', + 'bcc' => 'bcc', + 'replyto' => 'replyto', + 'folder' => 'folder' + ); + var $bofelamimail; + + function uicompose() + { + $this->displayCharset = $GLOBALS['egw']->translation->charset(); + if (!isset($_POST['composeid']) && !isset($_GET['composeid'])) + { + // create new compose session + $this->bocompose = CreateObject('felamimail.bocompose','',$this->displayCharset); + $this->composeID = $this->bocompose->getComposeID(); + } + else + { + // reuse existing compose session + if (isset($_POST['composeid'])) + $this->composeID = $_POST['composeid']; + else + $this->composeID = $_GET['composeid']; + $this->bocompose = CreateObject('felamimail.bocompose',$this->composeID,$this->displayCharset); + } + $this->t = CreateObject('phpgwapi.Template',EGW_APP_TPL); + $this->bofelamimail = CreateObject('felamimail.bofelamimail',$this->displayCharset); + $this->mailPreferences = ExecMethod('felamimail.bopreferences.getPreferences'); + + $this->t->set_unknowns('remove'); + + $this->rowColor[0] = $GLOBALS['egw_info']["theme"]["bg01"]; + $this->rowColor[1] = $GLOBALS['egw_info']["theme"]["bg02"]; + + + } + + function unhtmlentities ($string) + { + $trans_tbl = get_html_translation_table (HTML_ENTITIES); + $trans_tbl = array_flip ($trans_tbl); + return strtr ($string, $trans_tbl); + } + + function action() + { + $formData['identity'] = (int)$_POST['identity']; + + foreach($_POST['destination'] as $key => $destination) { + if(!empty($_POST['address'][$key])) { + if($destination == 'folder') { + $formData[$destination][] = $GLOBALS['egw']->translation->convert($_POST['address'][$key], $this->charset, 'UTF7-IMAP'); + } else { + $formData[$destination][] = $_POST['address'][$key]; + } + } + } + + $formData['subject'] = $this->bocompose->stripSlashes($_POST['subject']); + $formData['body'] = $this->bocompose->stripSlashes($_POST['body']); + // if the body is empty, maybe someone pasted something with scripts, into the message body + if(empty($formData['body'])) + { + // this is to be found with the egw_unset_vars array for the _POST['body'] array + $name='_POST'; + $key='body'; + #error_log($GLOBALS['egw_unset_vars'][$name.'['.$key.']']); + if (isset($GLOBALS['egw_unset_vars'][$name.'['.$key.']'])) + { + $formData['body'] = bocompose::_getCleanHTML( $GLOBALS['egw_unset_vars'][$name.'['.$key.']']); + } + } + $formData['priority'] = $this->bocompose->stripSlashes($_POST['priority']); + $formData['signatureID'] = (int)$_POST['signatureID']; + $formData['stationeryID'] = $_POST['stationeryID']; + $formData['mimeType'] = $this->bocompose->stripSlashes($_POST['mimeType']); + $formData['disposition'] = (bool)$_POST['disposition']; + $formData['to_infolog'] = $_POST['to_infolog']; + //$formData['mailbox'] = $_GET['mailbox']; + if((bool)$_POST['printit'] == true) { + $formData['printit'] = 1; + $formData['isDraft'] = 1; + // pint the composed message. therefore save it as draft and reopen it as plain printwindow + $formData['subject'] = "[".lang('printview').":]".$formData['subject']; + $messageUid = $this->bocompose->saveAsDraft($formData); + if (!$messageUid) { + print ""; + return; + } + $uidisplay = CreateObject('felamimail.uidisplay'); + $uidisplay->printMessage($messageUid, $formData['printit']); + //$GLOBALS['egw']->link('/index.php',array('menuaction' => 'felamimail.uidisplay.printMessage','uid'=>$messageUid)); + return; + } + if((bool)$_POST['saveAsDraft'] == true) { + $formData['isDraft'] = 1; + // save as draft + $messageUid = $this->bocompose->saveAsDraft($formData); + if (!$messageUid) { + print ""; + } + } else { + if(!$this->bocompose->send($formData)) { + $this->compose(); + return; + } + } + + #$GLOBALS['egw']->common->egw_exit(); + print ""; + } + + function composeAsForward($_focusElement='to') + { + if (isset($_GET['forwardmails'])) + { + unset($_GET['forwardmails']); + $replyID = $_GET['reply_id']; + $replyIds = explode(',',$replyID); + $icServer = 0; //(int)$_GET['icServer']; + $folder = base64_decode($_GET['folder']); + //_debug_array(array('reply_id'=>$replyIds,'folder'=>$folder)); + if (!empty($folder) && !empty($replyID) ) { + // this fill the session data with the values from the original email + $buff = $this->bocompose->preferencesArray['message_forwarding']; + $this->bocompose->preferencesArray['message_forwarding'] = 'asmail'; + foreach($replyIds as $key => $id) + { + $this->bocompose->getForwardData($icServer, $folder, $id,NULL); + } + $this->bocompose->preferencesArray['message_forwarding'] = $buff; + } + } + $this->compose($_focusElement); + } + + function compose($_focusElement='to') + { + // read the data from session + // all values are empty for a new compose window + $sessionData = $this->bocompose->getSessionData(); + if (is_array($_REQUEST['preset'])) + { + //_debug_array($_REQUEST); + if ($_REQUEST['preset']['mailto']) { + // handle mailto strings such as + // mailto:larry,dan?cc=mike&bcc=sue&subject=test&body=type+your&body=message+here + // the above string may be htmlentyty encoded, then multiple body tags are supported + // first, strip the mailto: string out of the mailto URL + $tmp_send_to = trim(substr(html_entity_decode($_REQUEST['preset']['mailto']),7)); + // check if there is more than the to address + $mailtoArray = explode('?',$tmp_send_to,2); + if ($mailtoArray[1]) { + // check if there are more than one requests + $addRequests = explode('&',$mailtoArray[1]); + foreach ($addRequests as $key => $reqval) { + // the additional requests should have a =, to separate key from value. + $keyValuePair = explode('=',$reqval,2); + $sessionData[$keyValuePair[0]] .= (strlen($sessionData[$keyValuePair[0]])>0 ? ' ':'') . $keyValuePair[1]; + } + } + $sessionData['to']=$mailtoArray[0]; + // if the mailto string is not htmlentity decoded the arguments are passed as simple requests + foreach(array('cc','bcc','subject','body') as $name) { + if ($_REQUEST[$name]) $sessionData[$name] .= (strlen($sessionData[$name])>0 ? ( $name == 'cc' || $name == 'bcc' ? ',' : ' ') : '') . $_REQUEST[$name]; + } + } + if ($_REQUEST['preset']['file'] && is_readable($_REQUEST['preset']['file'])) + { + $this->bocompose->addAttachment(array_merge($sessionData,$_REQUEST['preset'])); + $sessionData = $this->bocompose->getSessionData(); + } + foreach(array('to','cc','bcc','subject','body') as $name) + { + if ($_REQUEST['preset'][$name]) $sessionData[$name] = $_REQUEST['preset'][$name]; + } + } + + // is the to address set already? + if (!empty($_REQUEST['send_to'])) + { + $sessionData['to'] = base64_decode($_REQUEST['send_to']); + } + + //is the MimeType set/requested + if (!empty($_REQUEST['mimeType'])) + { + $sessionData['mimeType'] = $_REQUEST['mimeType']; + } + // is a certain signature requested? + // only the following values are supported (and make sense) + // no => means -2 + // system => means -1 + // default => fetches the default, which is standard behavior + if (!empty($_REQUEST['signature']) && (strtolower($_REQUEST['signature']) == 'no' || strtolower($_REQUEST['signature']) == 'system')) + { + $presetSig = (strtolower($_REQUEST['signature']) == 'no' ? -2 : -1); + } + if ($sessionData['isDraft'] && !empty($sessionData['signatureID'])) $presetSig = (int)$sessionData['signatureID']; + if ($sessionData['isDraft'] && !empty($sessionData['stationeryID'])) $presetStationery = $sessionData['stationeryID']; + $presetId = NULL; + if ($sessionData['isDraft'] && !empty($sessionData['identity'])) $presetId = (int)$sessionData['identity']; + $this->display_app_header(); + + $this->t->set_file(array("composeForm" => "composeForm.tpl")); + $this->t->set_block('composeForm','header','header'); + $this->t->set_block('composeForm','body_input'); + $this->t->set_block('composeForm','attachment','attachment'); + $this->t->set_block('composeForm','attachment_row','attachment_row'); + $this->t->set_block('composeForm','attachment_row_bold'); + $this->t->set_block('composeForm','destination_row'); + $this->t->set_block('composeForm','simple_text'); + + $this->translate(); + + if ($GLOBALS['egw_info']['user']['apps']['addressbook']) { + $this->t->set_var("link_addressbook",$GLOBALS['egw']->link('/index.php',array( + 'menuaction' => 'addressbook.addressbook_ui.emailpopup', + ))); + } else { + $this->t->set_var("link_addressbook",''); + } + $this->t->set_var("focusElement",$_focusElement); + + $linkData = array + ( + 'menuaction' => 'felamimail.uicompose.selectFolder', + ); + $this->t->set_var('folder_select_url',$GLOBALS['egw']->link('/index.php',$linkData)); + + $linkData = array + ( + 'menuaction' => 'felamimail.uicompose.fileSelector', + 'composeid' => $this->composeID + ); + $this->t->set_var('file_selector_url',$GLOBALS['egw']->link('/index.php',$linkData)); + + $this->t->set_var('vfs_selector_url',egw::link('/index.php',array( + 'menuaction' => 'filemanager.filemanager_select.select', + 'mode' => 'open-multiple', + 'method' => 'felamimail.uicompose.vfsSelector', + 'id' => $this->composeID, + 'label' => lang('Attach'), + ))); + if ($GLOBALS['egw_info']['user']['apps']['filemanager']) + { + $this->t->set_var('vfs_attach_button',' + '); + } + else + { + $this->t->set_var('vfs_attach_button',''); + } + $linkData = array + ( + 'menuaction' => 'felamimail.uicompose.action', + 'composeid' => $this->composeID + ); + $this->t->set_var("link_action",$GLOBALS['egw']->link('/index.php',$linkData)); + $this->t->set_var('folder_name',$this->bofelamimail->sessionData['mailbox']); + $this->t->set_var('compose_id',$this->composeID); + + // check for some error messages from last posting attempt + if($errorInfo = $this->bocompose->getErrorInfo()) + { + $this->t->set_var('errorInfo',"$errorInfo"); + } + else + { + $this->t->set_var('errorInfo',' '); + } + + // header + $allIdentities = $this->mailPreferences->getIdentity(); + //_debug_array($allIdentities); + $defaultIdentity = 0; + foreach($allIdentities as $key => $singleIdentity) { + #$identities[$singleIdentity->id] = $singleIdentity->realName.' <'.$singleIdentity->emailAddress.'>'; + $identities[$key] = $singleIdentity->realName.' <'.$singleIdentity->emailAddress.'>'; + if(!empty($singleIdentity->default)) { + #$defaultIdentity = $singleIdentity->id; + $defaultIdentity = $key; + $sessionData['signatureID'] = (!empty($singleIdentity->signature) ? $singleIdentity->signature : $sessionData['signatureID']); + } + } + $selectFrom = html::select('identity', ($presetId ? $presetId : $defaultIdentity), $identities, true, "style='width:100%;' onchange='changeIdentity(this);'"); + $this->t->set_var('select_from', $selectFrom); + + // navbar(, kind of) + $this->t->set_var('img_clear_left', $GLOBALS['egw']->common->image('felamimail','clear_left')); + $this->t->set_var('img_fileopen', $GLOBALS['egw']->common->image('phpgwapi','fileopen')); + $this->t->set_var('img_mail_send', $GLOBALS['egw']->common->image('felamimail','mail_send')); + $this->t->set_var('img_attach_file', $GLOBALS['egw']->common->image('felamimail','attach')); + $this->t->set_var('ajax-loader', $GLOBALS['egw']->common->image('felamimail','ajax-loader')); + $this->t->set_var('img_fileexport', $GLOBALS['egw']->common->image('felamimail','fileexport')); + // prepare print url/button + $this->t->set_var('img_print_it', $GLOBALS['egw']->common->image('felamimail','fileprint')); + $this->t->set_var('lang_print_it', lang('print it')); + $this->t->set_var('print_it', $printURL); + // from, to, cc, replyto + $destinationRows = 0; + foreach(array('to','cc','bcc','replyto','folder') as $destination) { + foreach((array)$sessionData[$destination] as $key => $value) { + $selectDestination = html::select('destination[]', $destination, $this->destinations, false, "style='width: 100%;' onchange='fm_compose_changeInputType(this)'"); + $this->t->set_var('select_destination', $selectDestination); + $address = bofelamimail::htmlentities($value, $this->displayCharset); + $this->t->set_var('address', $address); + $this->t->parse('destinationRows','destination_row',True); + $destinationRows++; + } + } + while($destinationRows < 3) { + // and always add one empty row + $selectDestination = html::select('destination[]', 'to', $this->destinations, false, "style='width: 100%;' onchange='fm_compose_changeInputType(this)'"); + $this->t->set_var('select_destination', $selectDestination); + $this->t->set_var('address', ''); + $this->t->parse('destinationRows','destination_row',True); + $destinationRows++; + } + // and always add one empty row + $selectDestination = html::select('destination[]', 'to', $this->destinations, false, "style='width: 100%;' onchange='fm_compose_changeInputType(this)'"); + $this->t->set_var('select_destination', $selectDestination); + $this->t->set_var('address', ''); + $this->t->parse('destinationRows','destination_row',True); + + // handle subject + $subject = bofelamimail::htmlentities($sessionData['subject'],$this->displayCharset); + $this->t->set_var("subject",$subject); + + if ($GLOBALS['egw_info']['user']['apps']['addressbook']) { + $this->t->set_var('addressbookButton',''); + } else { + $this->t->set_var('addressbookButton',''); + } + if ($GLOBALS['egw_info']['user']['apps']['infolog']) { + $this->t->set_var('infologImage',html::image('felamimail','to_infolog',lang('Save as infolog'),'width="17px" height="17px" valign="middle"' )); + $this->t->set_var('lang_save_as_infolog',lang('Save as infolog')); + $this->t->set_var('infolog_checkbox',''); + } else { + $this->t->set_var('infologImage',''); + $this->t->set_var('lang_save_as_infolog',''); + $this->t->set_var('infolog_checkbox',''); + } + $this->t->set_var('lang_no_recipient',lang('No recipient address given!')); + $this->t->set_var('lang_no_subject',lang('No subject given!')); + $this->t->pparse("out","header"); + + // body + if($sessionData['mimeType'] == 'html') { + $mode = 'simple'; + #if (isset($GLOBALS['egw_info']['server']['enabled_spellcheck'])) $mode = 'egw_simple_spellcheck'; + $style="border:0px; width:100%; height:400px;"; + // dont run purify, as we already did that (getCleanHTML). + $this->t->set_var('tinymce', html::fckEditorQuick('body', $mode, $sessionData['body'],'400px','100%',false)); + $this->t->set_var('mimeType', 'html'); + $ishtml=1; + } else { + $style="border:0px; width:100%; height:400px;"; + $this->t->set_var('tinymce', html::fckEditorQuick('body', 'ascii', $sessionData['body'],'400px','99%')); + $this->t->set_var('mimeType', 'text'); + $ishtml=0; + } + + require_once(EGW_INCLUDE_ROOT.'/felamimail/inc/class.felamimail_bosignatures.inc.php'); + $boSignatures = new felamimail_bosignatures(); + $signatures = $boSignatures->getListOfSignatures(); + if (empty($sessionData['signatureID'])) { + if ($signatureData = $boSignatures->getDefaultSignature()) { + if (is_array($signatureData)) { + $sessionData['signatureID'] = $signatureData['signatureid']; + } else { + $sessionData['signatureID'] =$signatureData; + } + } + } + + $selectSignatures = array( + '-2' => lang('no signature') + ); + foreach($signatures as $signature) { + $selectSignatures[$signature['fm_signatureid']] = lang('Signature').': '.$signature['fm_description']; + } + + $bostationery = new felamimail_bostationery(); + $selectStationeries = array( + '0' => lang('no stationery') + ); + $showStationaries = false; + $validStationaries = $bostationery->get_valid_templates(); + if (is_array($validStationaries) && count($validStationaries)>0) + { + $showStationaries = true; + $selectStationeries += $validStationaries; + } + $selectBoxSignature = html::select('signatureID', ($presetSig ? $presetSig : $sessionData['signatureID']), $selectSignatures, true, "style='width: 35%;' onchange='fm_compose_changeInputType(this)'"); + $selectBoxStationery = html::select('stationeryID', ($presetStationery ? $presetStationery : 0), $selectStationeries, true, "style='width: 35%;'"); + $this->t->set_var("select_signature", $selectBoxSignature); + $this->t->set_var("select_stationery", ($showStationaries ? $selectBoxStationery:'')); + $this->t->set_var("lang_editormode",lang("Editor type")); + $this->t->set_var("toggle_editormode", lang("Editor type").": "); + $this->t->pparse("out","body_input"); + + // attachments + if (is_array($sessionData['attachments']) && count($sessionData['attachments']) > 0) + { + $imgClearLeft = $GLOBALS['egw']->common->image('felamimail','clear_left'); + foreach((array)$sessionData['attachments'] as $id => $attachment) { + $tempArray = array ( + '1' => $attachment['name'], '.1' => 'width="40%"', + '2' => mime_magic::mime2label($attachment['type']), + '3' => egw_vfs::hsize($attachment['size']), '.3' => "style='text-align:right;'", + '4' => ' ', '.4' => 'width="10%"', + '5' => "composeID."','$id')\">", + ); + $tableRows[] = $tempArray; + } + + if(count($tableRows) > 0) { + $table = html::table($tableRows, "style='width:100%'"); + } + $this->t->set_var('attachment_rows',$table); + } + else + { + $this->t->set_var('attachment_rows',''); + } + + $this->t->pparse("out","attachment"); + } + + function composeFromDraft() { + $icServer = (int)$_GET['icServer']; + $folder = base64_decode($_GET['folder']); + $replyID = $_GET['uid']; + + if (!empty($folder) && !empty($replyID) ) { + // this fill the session data with the values from the original email + $this->bocompose->getDraftData($icServer, $folder, $replyID); + } + $this->compose('body'); + } + + + function display_app_header() + { + $GLOBALS['egw']->js->validate_file('jscode','composeMessage','felamimail'); + $GLOBALS['egw']->js->set_onload('javascript:initAll();'); + $GLOBALS['egw_info']['flags']['include_xajax'] = True; + + $GLOBALS['egw']->common->egw_header(); + } + + /** + * Callback for filemanagers select file dialog + * + * @param string $composeid + * @param string|array $files path of file(s) in vfs (no egw_vfs::PREFIX, just the path) + * @return string javascript output by the file select dialog, usually to close it + */ + function vfsSelector($composeid,$files) + { + $this->bocompose = CreateObject('felamimail.bocompose',$this->composeID=$composeid,$this->displayCharset); + + foreach((array) $files as $path) + { + $formData = array( + 'name' => egw_vfs::basename($path), + 'type' => egw_vfs::mime_content_type($path), + 'file' => egw_vfs::PREFIX.$path, + 'size' => filesize(egw_vfs::PREFIX.$path), + ); + $this->bocompose->addAttachment($formData); + } + return 'window.close();'; + } + + function fileSelector() + { + if(is_array($_FILES["addFileName"])) { + #phpinfo(); + //_debug_array($_FILES); + if($_FILES['addFileName']['error'] == $UPLOAD_ERR_OK) { + $formData['name'] = $_FILES['addFileName']['name']; + $formData['type'] = $_FILES['addFileName']['type']; + $formData['file'] = $_FILES['addFileName']['tmp_name']; + $formData['size'] = $_FILES['addFileName']['size']; + $this->bocompose->addAttachment($formData); + print ""; + } else { + print ""; + } + } + + if(!@is_object($GLOBALS['egw']->js)) + { + $GLOBALS['egw']->js = CreateObject('phpgwapi.javascript'); + } + $GLOBALS['egw']->js->validate_file('dhtmlxtree','js/dhtmlXCommon'); + $GLOBALS['egw']->js->validate_file('dhtmlxtree','js/dhtmlXTree'); + $GLOBALS['egw']->js->validate_file('jscode','composeMessage','felamimail'); + $GLOBALS['egw']->common->egw_header(); + + #$uiwidgets =& CreateObject('felamimail.uiwidgets'); + + $this->t->set_file(array("composeForm" => "composeForm.tpl")); + $this->t->set_block('composeForm','fileSelector','fileSelector'); + + $this->translate(); + + $linkData = array + ( + 'menuaction' => 'felamimail.uicompose.fileSelector', + 'composeid' => $this->composeID + ); + $this->t->set_var('file_selector_url', $GLOBALS['egw']->link('/index.php',$linkData)); + + $maxUploadSize = ini_get('upload_max_filesize'); + $this->t->set_var('max_uploadsize', $maxUploadSize); + + $this->t->set_var('ajax-loader', $GLOBALS['egw']->common->image('felamimail','ajax-loader')); + + $this->t->pparse("out","fileSelector"); + } + + function forward() { + $icServer = (int)$_GET['icServer']; + $folder = base64_decode($_GET['folder']); + $replyID = $_GET['reply_id']; + $partID = $_GET['part_id']; + + if (!empty($replyID)) + { + // this fill the session data with the values from the original email + $this->bocompose->getForwardData($icServer, $folder, $replyID, $partID); + } + $this->compose(); + } + + function getAttachment() + { + $bocompose = CreateObject('felamimail.bocompose', $_GET['_composeID']); + $attachment = $bocompose->sessionData['attachments'][$_GET['attID']] ; + if (!empty($attachment['folder'])) + { + $is_winmail = $_GET['is_winmail'] ? $_GET['is_winmail'] : 0; + $this->mailbox = $attachment['folder']; + $this->bofelamimail->reopen($this->mailbox); + #$attachment = $this->bofelamimail->getAttachment($this->uid,$part); + $attachmentData = $this->bofelamimail->getAttachment($attachment['uid'],$attachment['partID'],$is_winmail); + $this->bofelamimail->closeConnection(); + } + + if (parse_url($attachment['file'],PHP_URL_SCHEME) == 'vfs') + { + egw_vfs::load_wrapper('vfs'); + } + //error_log(print_r($attachmentData,true)); + header ("Content-Type: ".$attachment['type']."; name=\"". $this->bofelamimail->decode_header($attachment['name']) ."\""); + header ("Content-Disposition: inline; filename=\"". $this->bofelamimail->decode_header($attachment['name']) ."\""); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Pragma: public"); + if (!empty($attachment['file'])) + { + $fp = fopen($attachment['file'], 'rb'); + fpassthru($fp); + fclose($fp); + } + else + { + echo $attachmentData['attachment']; + } + $GLOBALS['egw']->common->egw_exit(); + exit; + + } + + + function selectFolder() + { + $GLOBALS['egw']->js->validate_file('dhtmlxtree','js/dhtmlXCommon'); + $GLOBALS['egw']->js->validate_file('dhtmlxtree','js/dhtmlXTree'); + $GLOBALS['egw']->js->validate_file('jscode','composeMessage','felamimail'); + $GLOBALS['egw']->common->egw_header(); + + $bofelamimail =& $this->bofelamimail; //CreateObject('felamimail.bofelamimail',$this->displayCharset); + $uiwidgets = CreateObject('felamimail.uiwidgets'); + $connectionStatus = $bofelamimail->openConnection(); + + $folderObjects = $bofelamimail->getFolderObjects(true,false); + $folderTree = $uiwidgets->createHTMLFolder + ( + $folderObjects, + 'INBOX', + 0, + lang('IMAP Server'), + $mailPreferences['username'].'@'.$mailPreferences['imapServerAddress'], + 'divFolderTree', + false, + true + ); + print '
'; + print $folderTree; + } + + function composeAsNew() { + $icServer = (int)$_GET['icServer']; + $folder = base64_decode($_GET['folder']); + $replyID = $_GET['reply_id']; + $partID = $_GET['part_id']; + if (!empty($folder) && !empty($replyID) ) { + // this fill the session data with the values from the original email + $this->bocompose->getDraftData($icServer, $folder, $replyID, $partID); + } + $this->compose('body'); + } + + function reply() { + $icServer = (int)$_GET['icServer']; + $folder = base64_decode($_GET['folder']); + $replyID = $_GET['reply_id']; + $partID = $_GET['part_id']; + if (!empty($folder) && !empty($replyID) ) { + // this fill the session data with the values from the original email + $this->bocompose->getReplyData('single', $icServer, $folder, $replyID, $partID); + } + $this->compose('body'); + } + + function replyAll() { + $icServer = (int)$_GET['icServer']; + $folder = base64_decode($_GET['folder']); + $replyID = $_GET['reply_id']; + $partID = $_GET['part_id']; + if (!empty($folder) && !empty($replyID) ) { + // this fill the session data with the values from the original email + $this->bocompose->getReplyData('all', $icServer, $folder, $replyID, $partID); + } + $this->compose('body'); + } + + function translate() { + $this->t->set_var("lang_message_list",lang('Message List')); + $this->t->set_var("lang_to",lang('to')); + $this->t->set_var("lang_cc",lang('cc')); + $this->t->set_var("lang_bcc",lang('bcc')); + $this->t->set_var("lang_identity",lang('identity')); + $this->t->set_var("lang_reply_to",lang('reply to')); + $this->t->set_var("lang_subject",lang('subject')); + $this->t->set_var("lang_addressbook",lang('addressbook')); + $this->t->set_var("lang_search",lang('search')); + $this->t->set_var("lang_send",lang('send')); + $this->t->set_var('lang_save_as_draft',lang('save as draft')); + $this->t->set_var("lang_back_to_folder",lang('back to folder')); + $this->t->set_var("lang_attachments",lang('attachments')); + $this->t->set_var("lang_add",lang('add')); + $this->t->set_var("lang_remove",lang('remove')); + $this->t->set_var("lang_priority",lang('priority')); + $this->t->set_var("lang_normal",lang('normal')); + $this->t->set_var("lang_high",lang('high')); + $this->t->set_var("lang_low",lang('low')); + $this->t->set_var("lang_signature",lang('signature')); + $this->t->set_var("lang_stationery",lang('stationery')); + $this->t->set_var("lang_select_folder",lang('select folder')); + $this->t->set_var('lang_max_uploadsize',lang('max uploadsize')); + $this->t->set_var('lang_adding_file_please_wait',lang('Adding file to message. Please wait!')); + $this->t->set_var('lang_receive_notification',lang('Receive notification')); + $this->t->set_var('lang_no_address_set',lang('can not send message. no recipient defined!')); + + $this->t->set_var("th_bg",$GLOBALS['egw_info']["theme"]["th_bg"]); + $this->t->set_var("bg01",$GLOBALS['egw_info']["theme"]["bg01"]); + $this->t->set_var("bg02",$GLOBALS['egw_info']["theme"]["bg02"]); + $this->t->set_var("bg03",$GLOBALS['egw_info']["theme"]["bg03"]); + } + +} + +?> diff --git a/felamimail/inc/class.uidisplay.inc.php b/felamimail/inc/class.uidisplay.inc.php index 3edb079fec..90c8189149 100644 --- a/felamimail/inc/class.uidisplay.inc.php +++ b/felamimail/inc/class.uidisplay.inc.php @@ -273,7 +273,7 @@ #_debug_array($rawheaders);exit; $attachments = $this->bofelamimail->getMessageAttachments($this->uid, $partID); #_debug_array($attachments); exit; - $envelope = $this->bofelamimail->getMessageEnvelope($this->uid, $partIDi,true); + $envelope = $this->bofelamimail->getMessageEnvelope($this->uid, $partID,true); #_debug_array($envelope); exit; // if not using iFrames, we need to retrieve the messageBody here // by now this is a fixed value and controls the use/loading of the template and how the vars are set. @@ -454,10 +454,10 @@ $this->t->set_var("date_received", @htmlspecialchars(bofelamimail::_strtotime($headers['DATE'],$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']).' - '.bofelamimail::_strtotime($headers['DATE'],'H:i:s'), ENT_QUOTES,$this->displayCharset)); - - $this->t->set_var("subject_data", - @htmlspecialchars($this->bofelamimail->decode_subject(preg_replace($nonDisplayAbleCharacters,'',$envelope['SUBJECT']),false), - ENT_QUOTES,$this->displayCharset)); + //echo 'Envelope:'.preg_replace($nonDisplayAbleCharacters,'',$envelope['SUBJECT']).'#0
'; + $subject = bofelamimail::htmlspecialchars($this->bofelamimail->decode_subject(preg_replace($nonDisplayAbleCharacters,'',$envelope['SUBJECT']),false), + $this->displayCharset); + $this->t->set_var("subject_data",$subject); $this->t->parse("header","message_header",True); @@ -720,7 +720,7 @@ // (regis) seems to be necessary to reopen... $this->bofelamimail->reopen($this->mailbox); $headers = $this->bofelamimail->getMessageHeader($this->uid, $partID); - $envelope = $this->bofelamimail->getMessageEnvelope($this->uid, $partID); + $envelope = $this->bofelamimail->getMessageEnvelope($this->uid, $partID,true); if (PEAR::isError($headers)) { print lang("ERROR: Message could not be displayed.")."
"; print "In Mailbox: $this->mailbox, with ID: $this->uid, and PartID: $partID
"; @@ -741,9 +741,9 @@ $this->t->egroupware_hack = False; $this->translate(); - $this->t->set_var("subject_data", - @htmlspecialchars($this->bofelamimail->decode_subject(preg_replace($nonDisplayAbleCharacters,'',$envelope['SUBJECT'])), - ENT_QUOTES,$this->displayCharset)); + $subject = bofelamimail::htmlspecialchars($this->bofelamimail->decode_subject(preg_replace($nonDisplayAbleCharacters,'',$envelope['SUBJECT']),false), + $this->displayCharset); + $this->t->set_var("subject_data",$subject); // attachments if(is_array($attachments) && count($attachments) > 0) { @@ -953,7 +953,7 @@ } static function emailAddressToHTML($_emailAddress, $_organisation='', $allwaysShowMailAddress=false, $showAddToAdrdessbookLink=true, $decode=true) { - #_debug_array($_emailAddress); + //_debug_array($_emailAddress); // create some nice formated HTML for senderaddress #if($_emailAddress['EMAIL'] == 'undisclosed-recipients: ;') # return $_emailAddress['EMAIL']; @@ -976,18 +976,24 @@ } if($addressData['PERSONAL_NAME'] != 'NIL') { - $newSenderAddress = $addressData['RFC822_EMAIL'] != 'NIL' ? $addressData['RFC822_EMAIL'] : $addressData['EMAIL']; - if ($decode) $newSenderAddress = bofelamimail::decode_header($newSenderAddress); - $decodedPersonalName = ($decode ? bofelamimail::decode_header($addressData['PERSONAL_NAME']):$addressData['PERSONAL_NAME']); - + $newSenderAddressORG = $newSenderAddress = $addressData['RFC822_EMAIL'] != 'NIL' ? $addressData['RFC822_EMAIL'] : $addressData['EMAIL']; + $decodedPersonalNameORG = $decodedPersonalName = $addressData['PERSONAL_NAME']; + if ($decode) + { + $newSenderAddress = bofelamimail::decode_header($newSenderAddressORG); + $decodedPersonalName = bofelamimail::decode_header($decodedPersonalName); + $addressData['EMAIL'] = bofelamimail::decode_header($addressData['EMAIL']); + } $realName = $decodedPersonalName; // add mailaddress if ($allwaysShowMailAddress) { $realName .= ' <'.$addressData['EMAIL'].'>'; + $decodedPersonalNameORG .= ' <'.$addressData['EMAIL'].'>'; } // add organization if(!empty($_organisation)) { $realName .= ' ('. $_organisation . ')'; + $decodedPersonalNameORG .= ' ('. $_organisation . ')'; } $linkData = array ( @@ -995,10 +1001,14 @@ 'send_to' => base64_encode($newSenderAddress) ); $link = $GLOBALS['egw']->link('/index.php',$linkData); + + $newSenderAddress = bofelamimail::htmlentities($newSenderAddress); + $realName = bofelamimail::htmlentities($realName); + $senderAddress .= sprintf('%s', $link, - @htmlentities($newSenderAddress,ENT_QUOTES,bofelamimail::$displayCharset), - @htmlentities($realName, ENT_QUOTES, bofelamimail::$displayCharset)); + $newSenderAddress, + $realName); $linkData = array ( 'menuaction' => 'addressbook.addressbook_ui.edit', @@ -1006,6 +1016,8 @@ 'presets[org_name]' => $_organisation, 'referer' => $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'] ); + + $decodedPersonalName = $realName; if (!empty($decodedPersonalName)) { if($spacePos = strrpos($decodedPersonalName, ' ')) { $linkData['presets[n_family]'] = substr($decodedPersonalName, $spacePos+1); @@ -1015,6 +1027,7 @@ } $linkData['presets[n_fn]'] = $decodedPersonalName; } + if ($showAddToAdrdessbookLink && $GLOBALS['egw_info']['user']['apps']['addressbook']) { $urlAddToAddressbook = $GLOBALS['egw']->link('/index.php',$linkData); $onClick = "window.open(this,this.target,'dependent=yes,width=850,height=440,location=no,menubar=no,toolbar=no,scrollbars=yes,status=yes'); return false;"; @@ -1030,19 +1043,22 @@ lang('add to addressbook')); } } else { + $addrEMailORG = $addrEMail = $addressData['EMAIL']; + if ($decode) $addrEMail = bofelamimail::decode_header($addrEMail); $linkData = array ( 'menuaction' => 'felamimail.uicompose.compose', 'send_to' => base64_encode($addressData['EMAIL']) ); $link = $GLOBALS['egw']->link('/index.php',$linkData); + $senderEMail = bofelamimail::htmlentities($addrEMail); $senderAddress .= sprintf('%s', - $link,@htmlentities($addressData['EMAIL'], ENT_QUOTES, bofelamimail::$displayCharset)); + $link,$senderEMail); //TODO: This uses old addressbook code, which should be removed in Version 1.4 //Please use addressbook.addressbook_ui.edit with proper paramenters $linkData = array ( 'menuaction' => 'addressbook.addressbook_ui.edit', - 'presets[email]' => $addressData['EMAIL'], + 'presets[email]' => $senderEMail, //$addressData['EMAIL'], 'presets[org_name]' => $_organisation, 'referer' => $_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'] ); @@ -1443,9 +1459,8 @@ } $this->t->set_var("date_data", @htmlspecialchars(bofelamimail::_strtotime($headers['DATE'],$GLOBALS['egw_info']['user']['preferences']['common']['dateformat']).' - '.bofelamimail::_strtotime($headers['DATE'],'H:i:s'), ENT_QUOTES,$this->displayCharset)); - // link to go back to the message view. the link differs if the print was called from a normal viewing window, or from compose - $subject = @htmlspecialchars($this->bofelamimail->decode_subject(preg_replace($nonDisplayAbleCharacters, '', $envelope['SUBJECT']),false), ENT_QUOTES, $this->displayCharset); + $subject = bofelamimail::htmlspecialchars($this->bofelamimail->decode_subject(preg_replace($nonDisplayAbleCharacters, '', $envelope['SUBJECT']),false), $this->displayCharset); $this->t->set_var("subject_data", $subject); $this->t->set_var("full_subject_data", $subject); $linkData = array ( diff --git a/felamimail/inc/class.uiwidgets.inc.php b/felamimail/inc/class.uiwidgets.inc.php index dbaeb11958..875fdde022 100644 --- a/felamimail/inc/class.uiwidgets.inc.php +++ b/felamimail/inc/class.uiwidgets.inc.php @@ -351,7 +351,9 @@ $replace = ''; $header['subject'] = preg_replace($search,$replace,$header['subject']); - $header['subject'] = @htmlspecialchars($header['subject'],ENT_QUOTES,$this->displayCharset); + $headerSubject = @htmlentities($header['subject'],ENT_QUOTES,$this->charset,false); + if (empty($headerSubject)) $headerSubject = @htmlentities($GLOBALS['egw']->translation->convert($header['subject'], bofelamimail::detect_encoding($header['subject']), $this->charset),ENT_QUOTES | ENT_IGNORE,$this->charset,false); + $header['subject'] = $headerSubject; // curly brackets get messed up by the template! $header['subject'] = str_replace(array('{','}'),array('{','}'),$header['subject']); @@ -366,7 +368,7 @@ #$this->t->set_var('attachments', $header['attachment']); $this->t->set_var('full_subject', $fullSubject); } else { - $this->t->set_var('header_subject', @htmlspecialchars('('. lang('no subject') .')', ENT_QUOTES, $this->displayCharset)); + $this->t->set_var('header_subject', @htmlspecialchars('('. lang('no subject') .')', ENT_QUOTES, $this->charset)); } #_debug_array($header); @@ -391,7 +393,14 @@ if ($_folderType > 0) { // sent or drafts or template folder + $header2add = @htmlentities($header['to_address'],ENT_QUOTES,$this->charset,false); + if (empty($header2add)) $header2add = @htmlentities($GLOBALS['egw']->translation->convert($header['to_address'], bofelamimail::detect_encoding($header['to_address']), $this->charset),ENT_QUOTES | ENT_IGNORE,$this->charset,false); + $header['to_address'] = $header2add; if (!empty($header['to_name'])) { + $header2name = @htmlentities($header['to_name'],ENT_QUOTES,$this->charset,false); + if (empty($header2name)) $header2name = @htmlentities($GLOBALS['egw']->translation->convert($header['to_name'], bofelamimail::detect_encoding($header['to_name']), $this->charset),ENT_QUOTES | ENT_IGNORE,$this->charset,false); + $header['to_name'] = $header2name; + $sender_name = $header['to_name']; $full_address = $header['to_name'].' <'.$header['to_address'].'>'; } else { @@ -399,7 +408,14 @@ $full_address = $header['to_address']; } } else { + $header2add = @htmlentities($header['sender_address'],ENT_QUOTES,$this->charset,false); + if (empty($header2add)) $header2add = @htmlentities($GLOBALS['egw']->translation->convert($header['sender_address'], bofelamimail::detect_encoding($header['sender_address']), $this->charset),ENT_QUOTES | ENT_IGNORE,$this->charset,false); + $header['sender_address'] = $header2add; if (!empty($header['sender_name'])) { + $header2name = @htmlentities($header['sender_name'],ENT_QUOTES,$this->charset,false); + if (empty($header2name)) $header2name = @htmlentities($GLOBALS['egw']->translation->convert($header['sender_name'], bofelamimail::detect_encoding($header['sender_name']), $this->charset),ENT_QUOTES | ENT_IGNORE,$this->charset,false); + $header['sender_name'] = $header2name; + $sender_name = $header['sender_name']; $full_address = $header['sender_name'].' <'.$header['sender_address'].'>'; } else { @@ -408,8 +424,8 @@ } } - $this->t->set_var('sender_name', @htmlspecialchars($sender_name, ENT_QUOTES, $this->charset)); - $this->t->set_var('full_address', @htmlspecialchars($full_address, ENT_QUOTES, $this->charset)); + $this->t->set_var('sender_name', @htmlspecialchars($sender_name, ENT_QUOTES | ENT_IGNORE, $this->charset,false)); + $this->t->set_var('full_address', @htmlspecialchars($full_address, ENT_QUOTES | ENT_IGNORE, $this->charset,false)); $this->t->set_var('message_counter', $i); $this->t->set_var('message_uid', $header['uid']); @@ -579,6 +595,7 @@ $full_address = $headerData['sender_address']; } } + //$fromAddress = uidisplay::emailAddressToHTML(array('PERSONAL_NAME'=>$sender_name,'EMAIL'=>$sender_address,'RFC822_EMAIL'=>$full_address),''); if ($GLOBALS['egw_info']['user']['apps']['addressbook']) { $addresslinkData = array ( @@ -626,6 +643,7 @@ 'id' => $headerData['id'], ); $windowName = 'displayMessage_'.$headerData['uid']; + if($headerData['mimetype'] == 'multipart/mixed' || $headerData['mimetype'] == 'multipart/related' || substr($headerData['mimetype'],0,11) == 'application' ||