2013-07-20 09:23:55 +02:00
< ? php
/**
* EGroupware - Mail - interface class for compose mails in popup
*
* @ link http :// www . egroupware . org
* @ package mail
2013-10-24 09:15:48 +02:00
* @ author Stylite AG [ info @ stylite . de ]
2014-01-13 14:06:29 +01:00
* @ copyright ( c ) 2013 - 2014 by Stylite AG < info - AT - stylite . de >
2013-07-20 09:23:55 +02:00
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
* @ version $Id $
*/
/**
* Mail interface class for compose mails in popup
*/
class mail_compose
{
var $public_functions = array
(
'compose' => True ,
2014-01-30 10:35:56 +01:00
'getAttachment' => True ,
2013-07-20 09:23:55 +02:00
);
2013-10-07 14:17:33 +02:00
/**
* class vars for destination , priorities , mimeTypes
*/
static $destinations = array (
2013-11-27 15:36:15 +01:00
'to' => 'to' , // lang('to')
'cc' => 'cc' , // lang('cc')
'bcc' => 'bcc' , // lang('bcc')
'replyto' => 'replyto' , // lang('replyto')
'folder' => 'folder' // lang('folder')
2013-07-20 09:23:55 +02:00
);
2013-10-07 14:17:33 +02:00
static $priorities = array (
2013-11-27 15:36:15 +01:00
1 => " high " , // lang('high')
3 => " normal " , // lang('normal')
5 => " low " // lang('low')
2013-10-07 14:17:33 +02:00
);
static $mimeTypes = array (
" plain " => " plain " ,
" html " => " html "
);
2013-07-20 09:23:55 +02:00
/**
* Instance of mail_bo
*
* @ var mail_bo
*/
var $mail_bo ;
/**
* Active preferences , reference to $this -> mail_bo -> mailPreferences
*
* @ var array
*/
var $mailPreferences ;
var $attachments ; // Array of attachments
var $displayCharset ;
2013-10-07 14:17:33 +02:00
var $composeID ;
2013-07-20 09:23:55 +02:00
var $sessionData ;
2014-01-18 15:00:19 +01:00
function __construct ()
2013-07-20 09:23:55 +02:00
{
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'flags' ][ 'js_link_registry' ]))
{
//error_log(__METHOD__.__LINE__.' js_link_registry not set, force it:'.array2string($GLOBALS['egw_info']['flags']['js_link_registry']));
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'js_link_registry' ] = true ;
}
2014-11-20 18:53:52 +01:00
$this -> displayCharset = translation :: charset ();
$profileID = ( int ) $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'ActiveProfileID' ];
2013-07-20 09:23:55 +02:00
$this -> mail_bo = mail_bo :: getInstance ( true , $profileID );
2014-11-20 18:53:52 +01:00
$GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'ActiveProfileID' ] = $this -> mail_bo -> profileID ;
2013-07-20 15:10:17 +02:00
2014-05-13 15:10:53 +02:00
$this -> mailPreferences =& $this -> mail_bo -> mailPreferences ;
2013-07-20 09:23:55 +02:00
//force the default for the forwarding -> asmail
2014-11-20 18:53:52 +01:00
if ( ! is_array ( $this -> mailPreferences ) || empty ( $this -> mailPreferences [ 'message_forwarding' ]))
{
2014-05-13 15:10:53 +02:00
$this -> mailPreferences [ 'message_forwarding' ] = 'asmail' ;
2013-07-20 09:23:55 +02:00
}
if ( is_null ( mail_bo :: $mailConfig )) mail_bo :: $mailConfig = config :: read ( 'mail' );
$this -> mailPreferences =& $this -> mail_bo -> mailPreferences ;
}
2013-10-08 16:23:46 +02:00
/**
* changeProfile
*
2014-10-23 13:28:36 +02:00
* @ param int $_icServerID
2013-10-08 16:23:46 +02:00
*/
function changeProfile ( $_icServerID )
{
if ( $this -> mail_bo -> profileID != $_icServerID )
{
if ( mail_bo :: $debug ) error_log ( __METHOD__ . __LINE__ . '->' . $this -> mail_bo -> profileID . '<->' . $_icServerID );
$this -> mail_bo = mail_bo :: getInstance ( false , $_icServerID );
if ( mail_bo :: $debug ) error_log ( __METHOD__ . __LINE__ . ' Fetched IC Server:' . $this -> mail_bo -> profileID . ':' . function_backtrace ());
// no icServer Object: something failed big time
if ( ! isset ( $this -> mail_bo -> icServer )) exit ; // ToDo: Exception or the dialog for setting up a server config
2013-11-22 14:55:09 +01:00
$this -> mail_bo -> openConnection ( $this -> mail_bo -> profileID );
2013-10-08 16:23:46 +02:00
$this -> mailPreferences =& $this -> mail_bo -> mailPreferences ;
}
}
2013-07-20 09:23:55 +02:00
/**
* function compose
2013-11-27 14:07:54 +01:00
* this function is used to fill the compose dialog with the content provided by $_content
2013-07-20 09:23:55 +02:00
*
2013-09-02 17:15:35 +02:00
* @ var _content array the etemplate content array
2013-08-21 12:47:20 +02:00
* @ var msg string a possible message to be passed and displayed to the userinterface
2013-07-20 09:23:55 +02:00
* @ var _focusElement varchar subject , to , body supported
* @ var suppressSigOnTop boolean
* @ var isReply boolean
*/
2013-09-02 17:15:35 +02:00
function compose ( array $_content = null , $msg = null , $_focusElement = 'to' , $suppressSigOnTop = false , $isReply = false )
2013-07-20 09:23:55 +02:00
{
2014-11-20 18:53:52 +01:00
unset ( $msg ); // not used
if ( ! empty ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'LastSignatureIDUsed' ]))
2014-05-02 12:33:54 +02:00
{
$sigPref = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'LastSignatureIDUsed' ];
}
else
{
$sigPref = array ();
}
2014-11-25 00:38:37 +01:00
// split mailaccount (acc_id) and identity (ident_id)
2014-11-20 18:53:52 +01:00
if ( $_content && isset ( $_content [ 'mailaccount' ]))
{
2014-11-25 00:38:37 +01:00
list ( $_content [ 'mailaccount' ], $_content [ 'mailidentity' ]) = explode ( ':' , $_content [ 'mailaccount' ]);
2014-11-20 18:53:52 +01:00
}
2014-05-02 12:33:54 +02:00
//error_log(__METHOD__.__LINE__.array2string($sigPref));
2013-11-27 15:36:15 +01:00
//lang('compose'),lang('from') // needed to be found by translationtools
2014-03-21 11:37:09 +01:00
//error_log(__METHOD__.__LINE__.array2string($_REQUEST).function_backtrace());
2013-10-10 13:44:01 +02:00
//error_log(__METHOD__.__LINE__.array2string($_content).function_backtrace());
2014-11-25 00:38:37 +01:00
$_contentHasSigID = array_key_exists ( 'mailidentity' ,( array ) $_content );
2014-01-18 15:52:21 +01:00
$_contentHasMimeType = array_key_exists ( 'mimeType' ,( array ) $_content );
2013-07-20 09:23:55 +02:00
if ( isset ( $_GET [ 'reply_id' ])) $replyID = $_GET [ 'reply_id' ];
2013-10-04 19:45:33 +02:00
if ( ! $replyID && isset ( $_GET [ 'id' ])) $replyID = $_GET [ 'id' ];
2014-01-16 16:58:27 +01:00
2013-10-04 19:45:33 +02:00
// Process different places we can use as a start for composing an email
2014-03-04 16:19:48 +01:00
$actionToProcess = 'compose' ;
2013-10-04 19:45:33 +02:00
if ( $_GET [ 'from' ] && $replyID )
{
$_content = array_merge (( array ) $_content , $this -> getComposeFrom (
// Parameters needed for fetching appropriate data
$replyID , $_GET [ 'part_id' ], $_GET [ 'from' ],
// Additionally may be changed
$_focusElement , $suppressSigOnTop , $isReply
));
2014-03-04 16:19:48 +01:00
$actionToProcess = $_GET [ 'from' ];
2013-10-08 16:23:46 +02:00
unset ( $_GET [ 'from' ]);
unset ( $_GET [ 'reply_id' ]);
unset ( $_GET [ 'part_id' ]);
unset ( $_GET [ 'id' ]);
unset ( $_GET [ 'mode' ]);
2014-01-30 12:28:20 +01:00
if ( is_array ( $_content [ 'attachments' ]))
{
foreach ( $_content [ 'attachments' ] as $i => & $upload )
{
if ( is_numeric ( $upload [ 'size' ])) $upload [ 'size' ] = mail_bo :: show_readable_size ( $upload [ 'size' ]);
}
}
2013-10-10 16:56:30 +02:00
//error_log(__METHOD__.__LINE__.array2string($_content));
2013-10-04 19:45:33 +02:00
}
2014-04-01 13:41:34 +02:00
2013-10-10 13:44:01 +02:00
$composeCache = array ();
if ( isset ( $_content [ 'composeID' ]) &&! empty ( $_content [ 'composeID' ]))
2013-10-07 14:17:33 +02:00
{
2014-03-04 10:23:43 +01:00
$isFirstLoad = false ;
2013-10-10 13:44:01 +02:00
$composeCache = egw_cache :: getCache ( egw_cache :: SESSION , 'mail' , 'composeCache' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]) . '_' . $_content [ 'composeID' ], $callback = null , $callback_params = array (), $expiration = 60 * 60 * 2 );
$this -> composeID = $_content [ 'composeID' ];
//error_log(__METHOD__.__LINE__.array2string($composeCache));
2013-10-07 14:17:33 +02:00
}
else
{
2014-03-04 16:19:48 +01:00
// as we use isFirstLoad to trigger the initalStyle on ckEditor, we
// respect that composeasnew may not want that, as we assume there
// is some style already set and our initalStyle always adds a span with
// and we want to avoid that
$isFirstLoad = ! ( $actionToProcess == 'composeasnew' ); //true;
2014-11-21 10:33:34 +01:00
$this -> composeID = $_content [ 'composeID' ] = $this -> generateComposeID ();
2013-10-10 13:44:01 +02:00
if ( ! is_array ( $_content ))
{
$_content = $this -> setDefaults ();
}
else
{
$_content = $this -> setDefaults ( $_content );
}
2013-10-07 14:17:33 +02:00
}
2013-10-02 16:50:24 +02:00
// VFS Selector was used
if ( is_array ( $_content [ 'selectFromVFSForCompose' ]))
{
2013-10-03 18:09:25 +02:00
$suppressSigOnTop = true ;
2013-10-02 16:50:24 +02:00
foreach ( $_content [ 'selectFromVFSForCompose' ] as $i => $path )
{
$_content [ 'uploadForCompose' ][] = array (
'name' => egw_vfs :: basename ( $path ),
'type' => egw_vfs :: mime_content_type ( $path ),
'file' => egw_vfs :: PREFIX . $path ,
'size' => filesize ( egw_vfs :: PREFIX . $path ),
);
}
unset ( $_content [ 'selectFromVFSForCompose' ]);
}
// check everything that was uploaded
2013-10-01 13:29:54 +02:00
if ( is_array ( $_content [ 'uploadForCompose' ]))
{
2013-10-03 18:09:25 +02:00
$suppressSigOnTop = true ;
2013-10-01 13:29:54 +02:00
foreach ( $_content [ 'uploadForCompose' ] as $i => & $upload )
{
if ( ! isset ( $upload [ 'file' ])) $upload [ 'file' ] = $upload [ 'tmp_name' ];
2013-10-02 16:50:24 +02:00
try
{
$tmp_filename = mail_bo :: checkFileBasics ( $upload , $this -> composeID , false );
}
catch ( egw_exception_wrong_userinput $e )
{
2014-10-23 13:28:36 +02:00
error_log ( __METHOD__ . __LINE__ . " " . $e -> getMessage ());
2013-10-02 16:50:24 +02:00
}
2013-10-01 13:29:54 +02:00
$upload [ 'file' ] = $upload [ 'tmp_name' ] = $tmp_filename ;
2013-10-02 16:50:24 +02:00
$upload [ 'size' ] = mail_bo :: show_readable_size ( $upload [ 'size' ]);
}
}
// check if someone did hit delete on the attachments list
if ( ! empty ( $_content [ 'attachments' ][ 'delete' ]))
{
2014-01-31 11:21:58 +01:00
//error_log(__METHOD__.__LINE__.':'.array2string($_content['attachments']));
//error_log(__METHOD__.__LINE__.':'.array2string($_content['attachments']['delete']));
2013-10-03 18:09:25 +02:00
$suppressSigOnTop = true ;
2013-10-02 16:50:24 +02:00
$toDelete = $_content [ 'attachments' ][ 'delete' ];
unset ( $_content [ 'attachments' ][ 'delete' ]);
$attachments = $_content [ 'attachments' ];
unset ( $_content [ 'attachments' ]);
foreach ( $attachments as $i => $att )
{
$remove = false ;
2014-11-20 18:53:52 +01:00
foreach ( array_keys ( $toDelete ) as $k )
2013-10-02 16:50:24 +02:00
{
if ( $att [ 'tmp_name' ] == $k ) $remove = true ;
}
if ( ! $remove ) $_content [ 'attachments' ][] = $att ;
2013-10-01 13:29:54 +02:00
}
}
2013-10-03 12:05:05 +02:00
// someone clicked something like send, or saveAsDraft
2013-10-08 16:23:46 +02:00
// make sure, we are connected to the correct server for sending and storing the send message
$activeProfile = $composeProfile = $this -> mail_bo -> profileID ; // active profile may not be the profile uised in/for compose
2014-04-01 13:41:34 +02:00
$activeFolderCache = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'activeMailbox' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), $callback = null , $callback_params = array (), $expiration = 60 * 60 * 10 );
if ( ! empty ( $activeFolderCache [ $this -> mail_bo -> profileID ]))
{
//error_log(__METHOD__.__LINE__.' CurrentFolder:'.$activeFolderCache[$this->mail_bo->profileID]);
$activeFolder = $activeFolderCache [ $this -> mail_bo -> profileID ];
}
2014-05-23 14:21:17 +02:00
//error_log(__METHOD__.__LINE__.array2string($_content));
2013-10-08 16:23:46 +02:00
if ( ! empty ( $_content [ 'serverID' ]) && $_content [ 'serverID' ] != $this -> mail_bo -> profileID &&
( $_content [ 'button' ][ 'send' ] || $_content [ 'button' ][ 'saveAsDraft' ] || $_content [ 'button' ][ 'saveAsDraftAndPrint' ])
)
{
$this -> changeProfile ( $_content [ 'serverID' ]);
$composeProfile = $this -> mail_bo -> profileID ;
}
2013-10-03 18:09:25 +02:00
$buttonClicked = false ;
2013-10-03 12:05:05 +02:00
if ( $_content [ 'button' ][ 'send' ])
{
2013-10-03 18:09:25 +02:00
$buttonClicked = $suppressSigOnTop = true ;
2013-10-03 12:05:05 +02:00
$sendOK = true ;
2013-12-09 10:57:03 +01:00
$_content [ 'body' ] = ( $_content [ 'body' ] ? $_content [ 'body' ] : $_content [ 'mail_' . ( $_content [ 'mimeType' ] == 'html' ? 'html' : 'plain' ) . 'text' ]);
/*
perform some simple checks , before trying to send on :
$_content [ 'to' ]; $_content [ 'cc' ]; $_content [ 'bcc' ];
trim ( $_content [ 'subject' ]);
trim ( strip_tags ( str_replace ( ' ' , '' , $_content [ 'body' ])));
*/
if ( strlen ( trim ( strip_tags ( str_replace ( ' ' , '' , $_content [ 'body' ])))) == 0 && count ( $_content [ 'attachments' ]) == 0 )
2013-10-03 12:05:05 +02:00
{
2013-12-09 10:57:03 +01:00
$sendOK = false ;
$_content [ 'msg' ] = $message = lang ( " no message body supplied " );
2013-10-03 12:05:05 +02:00
}
2013-12-09 10:57:03 +01:00
if ( $sendOK && strlen ( trim ( $_content [ 'subject' ])) == 0 )
2013-10-03 12:05:05 +02:00
{
$sendOK = false ;
2013-12-09 10:57:03 +01:00
$_content [ 'msg' ] = $message = lang ( " no subject supplied " );
}
if ( $sendOK && empty ( $_content [ 'to' ]) && empty ( $_content [ 'cc' ]) && empty ( $_content [ 'bcc' ]))
{
$sendOK = false ;
$_content [ 'msg' ] = $message = lang ( " no adress, to send this mail to, supplied " );
}
if ( $sendOK )
{
try
{
$success = $this -> send ( $_content );
if ( $success == false )
{
$sendOK = false ;
$message = $this -> errorInfo ;
}
2014-11-25 00:38:37 +01:00
if ( ! empty ( $_content [ 'mailidentity' ]) && $_content [ 'mailidentity' ] != $sigPref [ $this -> mail_bo -> profileID ])
2014-05-02 12:33:54 +02:00
{
2014-11-25 00:38:37 +01:00
$sigPref [ $this -> mail_bo -> profileID ] = $_content [ 'mailidentity' ];
2014-05-02 12:33:54 +02:00
$GLOBALS [ 'egw' ] -> preferences -> add ( 'mail' , 'LastSignatureIDUsed' , $sigPref , 'user' );
// save prefs
$GLOBALS [ 'egw' ] -> preferences -> save_repository ( true );
}
2013-12-09 10:57:03 +01:00
}
catch ( egw_exception_wrong_userinput $e )
{
$sendOK = false ;
$message = $e -> getMessage ();
}
2013-10-03 12:05:05 +02:00
}
2013-10-08 16:23:46 +02:00
if ( $activeProfile != $composeProfile )
{
$this -> changeProfile ( $activeProfile );
$activeProfile = $this -> mail_bo -> profileID ;
}
2013-10-03 12:05:05 +02:00
if ( $sendOK )
{
2014-04-01 13:41:34 +02:00
$workingFolder = $activeFolder ;
$mode = 'compose' ;
2014-04-03 11:07:55 +02:00
$idsForRefresh = array ();
2014-04-01 13:41:34 +02:00
if ( isset ( $_content [ 'mode' ]) && ! empty ( $_content [ 'mode' ]))
{
$mode = $_content [ 'mode' ];
if ( $_content [ 'mode' ] == 'forward' && ! empty ( $_content [ 'processedmail_id' ]))
{
$_content [ 'processedmail_id' ] = explode ( ',' , $_content [ 'processedmail_id' ]);
foreach ( $_content [ 'processedmail_id' ] as $k => $rowid )
{
$fhA = mail_ui :: splitRowID ( $rowid );
//$this->sessionData['uid'][] = $fhA['msgUID'];
//$this->sessionData['forwardedUID'][] = $fhA['msgUID'];
2014-04-03 11:07:55 +02:00
$idsForRefresh [] = mail_ui :: generateRowID ( $fhA [ 'profileID' ], $fhA [ 'folder' ], $fhA [ 'msgUID' ], $_prependApp = false );
2014-04-01 13:41:34 +02:00
if ( ! empty ( $fhA [ 'folder' ])) $workingFolder = $fhA [ 'folder' ];
}
}
if ( $_content [ 'mode' ] == 'reply' && ! empty ( $_content [ 'processedmail_id' ]))
{
$rhA = mail_ui :: splitRowID ( $_content [ 'processedmail_id' ]);
//$this->sessionData['uid'] = $rhA['msgUID'];
2014-04-03 11:07:55 +02:00
$idsForRefresh [] = mail_ui :: generateRowID ( $rhA [ 'profileID' ], $rhA [ 'folder' ], $rhA [ 'msgUID' ], $_prependApp = false );
2014-04-01 13:41:34 +02:00
$workingFolder = $rhA [ 'folder' ];
}
}
2014-04-03 11:07:55 +02:00
//the line/condition below should not be needed
if ( empty ( $idsForRefresh ) && ! empty ( $_content [ 'processedmail_id' ]))
{
$rhA = mail_ui :: splitRowID ( $_content [ 'processedmail_id' ]);
$idsForRefresh [] = mail_ui :: generateRowID ( $rhA [ 'profileID' ], $rhA [ 'folder' ], $rhA [ 'msgUID' ], $_prependApp = false );
}
2014-04-01 13:41:34 +02:00
$response = egw_json_response :: get ();
if ( $activeProfile != $composeProfile )
{
// we need a message only, when account ids (composeProfile vs. activeProfile) differ
$response -> call ( 'opener.egw_message' , lang ( 'Message send successfully.' ));
}
elseif ( $activeProfile == $composeProfile && ( $workingFolder == $activeFolder && $mode != 'compose' ) || ( $this -> mail_bo -> isSentFolder ( $workingFolder ) || $this -> mail_bo -> isDraftFolder ( $workingFolder )))
{
if ( $this -> mail_bo -> isSentFolder ( $workingFolder ) || $this -> mail_bo -> isDraftFolder ( $workingFolder ))
{
// we may need a refresh when on sent folder or in drafts, as drafted messages will/should be deleted after succeeded send action
$response -> call ( 'opener.egw_refresh' , lang ( 'Message send successfully.' ), 'mail' );
}
else
{
2014-04-03 11:07:55 +02:00
//error_log(__METHOD__.__LINE__.array2string($idsForRefresh));
$response -> call ( 'opener.egw_refresh' , lang ( 'Message send successfully.' ), 'mail' , $idsForRefresh , 'update' );
2014-04-01 13:41:34 +02:00
}
}
else
{
$response -> call ( 'opener.egw_message' , lang ( 'Message send successfully.' ));
}
//egw_framework::refresh_opener(lang('Message send successfully.'),'mail');
2013-10-03 12:05:05 +02:00
egw_framework :: window_close ();
}
2013-10-05 11:47:34 +02:00
if ( $sendOK == false )
{
2014-05-16 13:52:44 +02:00
egw_framework :: message ( lang ( 'Message send failed: %1' , $message ), 'error' ); // maybe error is more appropriate
2013-10-05 11:47:34 +02:00
}
2013-10-03 12:05:05 +02:00
}
2014-09-12 13:52:38 +02:00
2013-10-08 16:23:46 +02:00
if ( $activeProfile != $composeProfile ) $this -> changeProfile ( $activeProfile );
2013-07-20 09:23:55 +02:00
$insertSigOnTop = false ;
2013-10-03 12:05:05 +02:00
$content = ( is_array ( $_content ) ? $_content : array ());
2014-01-18 15:52:21 +01:00
if ( $_contentHasMimeType )
{
2014-02-04 12:31:13 +01:00
// mimeType is now a checkbox; convert it here to match expectations
// ToDo: match Code to meet checkbox value
2014-01-18 15:52:21 +01:00
if ( $content [ 'mimeType' ] == 1 )
{
$_content [ 'mimeType' ] = $content [ 'mimeType' ] = 'html' ;
}
else
{
$_content [ 'mimeType' ] = $content [ 'mimeType' ] = 'plain' ;
}
}
2013-10-04 11:33:44 +02:00
// user might have switched desired mimetype, so we should convert
if ( $content [ 'is_html' ] && $content [ 'mimeType' ] == 'plain' )
{
2013-10-04 13:02:12 +02:00
//error_log(__METHOD__.__LINE__.$content['mail_htmltext']);
2013-10-04 11:33:44 +02:00
$suppressSigOnTop = true ;
2013-10-04 13:02:12 +02:00
if ( stripos ( $content [ 'mail_htmltext' ], '<pre>' ) !== false )
{
$contentArr = html :: splithtmlByPRE ( $content [ 'mail_htmltext' ]);
2014-09-09 16:04:40 +02:00
if ( is_array ( $contentArr ))
2013-10-04 13:02:12 +02:00
{
2014-09-09 16:04:40 +02:00
foreach ( $contentArr as $k =>& $elem )
{
if ( stripos ( $elem , '<pre>' ) !== false ) $elem = str_replace ( array ( " \r \n " , " \n " , " \r " ), array ( " <br> " , " <br> " , " <br> " ), $elem );
}
$content [ 'mail_htmltext' ] = implode ( '' , $contentArr );
2013-10-04 13:02:12 +02:00
}
}
$content [ 'mail_htmltext' ] = $this -> _getCleanHTML ( $content [ 'mail_htmltext' ], false , false );
2014-10-23 13:28:36 +02:00
$content [ 'mail_htmltext' ] = translation :: convertHTMLToText ( $content [ 'mail_htmltext' ], $charset = false , false , true );
2013-10-04 13:02:12 +02:00
2013-10-04 11:33:44 +02:00
$content [ 'body' ] = $content [ 'mail_htmltext' ];
2013-10-04 13:02:12 +02:00
unset ( $content [ 'mail_htmltext' ]);
2013-10-04 11:33:44 +02:00
$content [ 'is_html' ] = false ;
$content [ 'is_plain' ] = true ;
}
if ( $content [ 'is_plain' ] && $content [ 'mimeType' ] == 'html' )
{
2014-03-04 10:23:43 +01:00
// the possible font span should only be applied on first load or on switch plain->html
2014-03-07 15:54:44 +01:00
$isFirstLoad = " switchedplaintohtml " ;
2013-10-04 13:02:12 +02:00
//error_log(__METHOD__.__LINE__.$content['mail_plaintext']);
2013-10-04 11:33:44 +02:00
$suppressSigOnTop = true ;
2013-10-04 13:02:12 +02:00
$content [ 'mail_plaintext' ] = str_replace ( array ( " \r \n " , " \n " , " \r " ), array ( " <br> " , " <br> " , " <br> " ), $content [ 'mail_plaintext' ]);
//$this->replaceEmailAdresses($content['mail_plaintext']);
2013-10-04 11:33:44 +02:00
$content [ 'body' ] = $content [ 'mail_plaintext' ];
2013-10-04 13:02:12 +02:00
unset ( $content [ 'mail_plaintext' ]);
2013-10-04 11:33:44 +02:00
$content [ 'is_html' ] = true ;
$content [ 'is_plain' ] = false ;
}
2013-10-10 13:44:01 +02:00
2013-10-03 18:09:25 +02:00
$content [ 'body' ] = ( $content [ 'body' ] ? $content [ 'body' ] : $content [ 'mail_' . ( $content [ 'mimeType' ] == 'html' ? 'html' : 'plain' ) . 'text' ]);
2013-10-10 16:56:30 +02:00
unset ( $_content [ 'body' ]);
unset ( $_content [ 'mail_htmltext' ]);
unset ( $_content [ 'mail_plaintext' ]);
2013-10-10 13:44:01 +02:00
2013-10-07 17:02:35 +02:00
// form was submitted either by clicking a button or by changing one of the triggering selectboxes
2013-11-22 14:55:09 +01:00
// identity and signatureid; this might trigger that the signature in mail body may have to be altered
2013-10-07 17:02:35 +02:00
if ( ! empty ( $content [ 'body' ]) &&
2014-01-13 16:40:34 +01:00
( ! empty ( $composeCache [ 'mailaccount' ]) && ! empty ( $_content [ 'mailaccount' ]) && $_content [ 'mailaccount' ] != $composeCache [ 'mailaccount' ]) ||
2014-11-25 00:38:37 +01:00
( ! empty ( $composeCache [ 'mailidentity' ]) && ! empty ( $_content [ 'mailidentity' ]) && $_content [ 'mailidentity' ] != $composeCache [ 'mailidentity' ])
2013-10-07 17:02:35 +02:00
)
{
$buttonClicked = true ;
$suppressSigOnTop = true ;
2014-01-13 16:40:34 +01:00
if ( ! empty ( $composeCache [ 'mailaccount' ]) && ! empty ( $_content [ 'mailaccount' ]) && $_content [ 'mailaccount' ] != $composeCache [ 'mailaccount' ])
2013-10-10 13:44:01 +02:00
{
2014-01-13 16:40:34 +01:00
$acc = emailadmin_account :: read ( $_content [ 'mailaccount' ]);
//error_log(__METHOD__.__LINE__.array2string($acc));
$Identities = emailadmin_account :: read_identity ( $acc [ 'ident_id' ], true );
2013-11-22 14:55:09 +01:00
//error_log(__METHOD__.__LINE__.array2string($Identities));
if ( $Identities [ 'ident_id' ])
2013-10-10 13:44:01 +02:00
{
2013-11-22 14:55:09 +01:00
$newSig = $Identities [ 'ident_id' ];
2013-10-10 13:44:01 +02:00
}
else
{
2013-12-17 10:55:47 +01:00
$newSig = $this -> mail_bo -> getDefaultIdentity ();
2013-11-22 14:55:09 +01:00
if ( $newSig === false ) $newSig = - 2 ;
2013-10-10 13:44:01 +02:00
}
}
2014-11-25 00:38:37 +01:00
$_oldSig = $composeCache [ 'mailidentity' ];
$_signatureid = ( $newSig ? $newSig : $_content [ 'mailidentity' ]);
2013-10-10 13:44:01 +02:00
$_currentMode = $_content [ 'mimeType' ];
2013-11-22 14:55:09 +01:00
if ( $_oldSig != $_signatureid )
2013-10-10 13:44:01 +02:00
{
2013-11-22 14:55:09 +01:00
if ( $this -> _debug ) error_log ( __METHOD__ . __LINE__ . ' old,new ->' . $_oldSig . ',' . $_signatureid . '#' . $content [ 'body' ]);
2013-10-10 13:44:01 +02:00
// prepare signatures, the selected sig may be used on top of the body
2013-11-22 14:55:09 +01:00
try
{
$oldSignature = emailadmin_account :: read_identity ( $_oldSig , true );
//error_log(__METHOD__.__LINE__.'Old:'.array2string($oldSignature).'#');
$oldSigText = $oldSignature [ 'ident_signature' ];
}
catch ( Exception $e )
{
$oldSignature = array ();
$oldSigText = null ;
}
try
{
$signature = emailadmin_account :: read_identity ( $_signatureid , true );
//error_log(__METHOD__.__LINE__.'New:'.array2string($signature).'#');
$sigText = $signature [ 'ident_signature' ];
}
catch ( Exception $e )
{
$signature = array ();
$sigText = null ;
}
//error_log(__METHOD__.'Old:'.$oldSigText.'#');
//error_log(__METHOD__.'New:'.$sigText.'#');
2013-10-10 13:44:01 +02:00
if ( $_currentMode == 'plain' )
{
$oldSigText = $this -> convertHTMLToText ( $oldSigText , true , true );
$sigText = $this -> convertHTMLToText ( $sigText , true , true );
if ( $this -> _debug ) error_log ( __METHOD__ . " Old signature: " . $oldSigText );
}
2013-11-22 14:55:09 +01:00
//$oldSigText = mail_bo::merge($oldSigText,array($GLOBALS['egw']->accounts->id2name($GLOBALS['egw_info']['user']['account_id'],'person_id')));
2013-10-10 13:44:01 +02:00
//error_log(__METHOD__.'Old+:'.$oldSigText.'#');
2013-11-22 14:55:09 +01:00
//$sigText = mail_bo::merge($sigText,array($GLOBALS['egw']->accounts->id2name($GLOBALS['egw_info']['user']['account_id'],'person_id')));
2013-10-10 13:44:01 +02:00
//error_log(__METHOD__.'new+:'.$sigText.'#');
$_htmlConfig = mail_bo :: $htmLawed_config ;
mail_bo :: $htmLawed_config [ 'comment' ] = 2 ;
mail_bo :: $htmLawed_config [ 'transform_anchor' ] = false ;
2014-11-20 18:53:52 +01:00
$oldSigTextCleaned = str_replace ( array ( " \r " , " \t " , " <br /> \n " , " : " ), array ( " " , " " , " <br /> " , " : " ),( $_currentMode == 'html' ? html :: purify ( $oldSigText , null , array (), true ) : $oldSigText ));
//error_log(__METHOD__.'Old(clean):'.$oldSigTextCleaned.'#');
2013-10-10 13:44:01 +02:00
if ( $_currentMode == 'html' )
{
$content [ 'body' ] = str_replace ( " \n " , '\n' , $content [ 'body' ]); // dont know why, but \n screws up preg_replace
$styles = mail_bo :: getStyles ( array ( array ( 'body' => $content [ 'body' ])));
2014-10-23 13:28:36 +02:00
if ( stripos ( $content [ 'body' ], 'style' ) !== false ) translation :: replaceTagsCompletley ( $content [ 'body' ], 'style' , $endtag = '' , true ); // clean out empty or pagewide style definitions / left over tags
2013-10-10 13:44:01 +02:00
}
$content [ 'body' ] = str_replace ( array ( " \r " , " \t " , " <br /> \n " , " : " ), array ( " " , " " , " <br /> " , " : " ),( $_currentMode == 'html' ? html :: purify ( $content [ 'body' ], mail_bo :: $htmLawed_config , array (), true ) : $content [ 'body' ]));
mail_bo :: $htmLawed_config = $_htmlConfig ;
if ( $_currentMode == 'html' )
{
2014-11-20 18:53:52 +01:00
$replaced = null ;
2013-10-10 13:44:01 +02:00
$content [ 'body' ] = preg_replace ( $reg = '|' . preg_quote ( '<!-- HTMLSIGBEGIN -->' , '|' ) . '.*' . preg_quote ( '<!-- HTMLSIGEND -->' , '|' ) . '|u' ,
$rep = '<!-- HTMLSIGBEGIN -->' . $sigText . '<!-- HTMLSIGEND -->' , $in = $content [ 'body' ], - 1 , $replaced );
$content [ 'body' ] = str_replace ( array ( '\n' , " \xe2 \x80 \x93 " , " \xe2 \x80 \x94 " , " \xe2 \x82 \xac " ), array ( " \n " , '–' , '—' , '€' ), $content [ 'body' ]);
//error_log(__METHOD__."() preg_replace('$reg', '$rep', '$in', -1)='".$content['body']."', replaced=$replaced");
2014-11-20 18:53:52 +01:00
unset ( $rep , $in );
2013-10-10 13:44:01 +02:00
if ( $replaced )
{
2014-11-25 00:38:37 +01:00
$content [ 'mailidentity' ] = $_content [ 'mailidentity' ] = $presetSig = $_signatureid ;
2013-10-10 13:44:01 +02:00
$found = false ; // this way we skip further replacement efforts
}
else
{
// try the old way
2014-11-20 18:53:52 +01:00
$found = ( strlen ( trim ( $oldSigTextCleaned )) > 0 ? strpos ( $content [ 'body' ], trim ( $oldSigTextCleaned )) : false );
2013-10-10 13:44:01 +02:00
}
}
else
{
2014-11-20 18:53:52 +01:00
$found = ( strlen ( trim ( $oldSigTextCleaned )) > 0 ? strpos ( $content [ 'body' ], trim ( $oldSigTextCleaned )) : false );
2013-10-10 13:44:01 +02:00
}
2014-11-20 18:53:52 +01:00
if ( $found !== false && $_oldSig != - 2 && ! ( empty ( $oldSigTextCleaned ) || trim ( $this -> convertHTMLToText ( $oldSigTextCleaned , true , true )) == '' ))
2013-10-10 13:44:01 +02:00
{
//error_log(__METHOD__.'Old Content:'.$content['body'].'#');
2014-11-20 18:53:52 +01:00
$_oldSigText = preg_quote ( $oldSigTextCleaned , '~' );
2013-10-10 13:44:01 +02:00
//error_log(__METHOD__.'Old(masked):'.$_oldSigText.'#');
$content [ 'body' ] = preg_replace ( '~' . $_oldSigText . '~mi' , $sigText , $content [ 'body' ], 1 );
//error_log(__METHOD__.'new Content:'.$content['body'].'#');
}
2014-11-20 18:53:52 +01:00
if ( $_oldSig == - 2 && ( empty ( $oldSigTextCleaned ) || trim ( $this -> convertHTMLToText ( $oldSigTextCleaned , true , true )) == '' ))
2013-10-10 13:44:01 +02:00
{
// if there is no sig selected, there is no way to replace a signature
}
if ( $found === false )
{
2014-11-20 18:53:52 +01:00
if ( $this -> _debug ) error_log ( __METHOD__ . " Old Signature failed to match: " . $oldSigTextCleaned );
2013-10-10 13:44:01 +02:00
if ( $this -> _debug ) error_log ( __METHOD__ . " Compare content: " . $content [ 'body' ]);
}
else
{
2014-11-25 00:38:37 +01:00
$content [ 'mailidentity' ] = $_content [ 'mailidentity' ] = $presetSig = $_signatureid ;
2013-10-10 13:44:01 +02:00
}
if ( $styles )
{
//error_log($styles);
$content [ 'body' ] = $styles . $content [ 'body' ];
}
}
2013-10-07 17:02:35 +02:00
}
2013-10-10 13:44:01 +02:00
// do not double insert a signature on a server roundtrip
if ( $buttonClicked ) $suppressSigOnTop = true ;
2014-04-29 11:53:47 +02:00
if ( $isFirstLoad )
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
$alwaysAttachVCardAtCompose = false ; // we use this to eliminate double attachments, if users VCard is already present/attached
2014-05-13 15:10:53 +02:00
if ( isset ( $GLOBALS [ 'egw_info' ][ 'apps' ][ 'stylite' ]) && ( isset ( $this -> mailPreferences [ 'attachVCardAtCompose' ]) &&
$this -> mailPreferences [ 'attachVCardAtCompose' ]))
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
$alwaysAttachVCardAtCompose = true ;
if ( ! is_array ( $_REQUEST [ 'preset' ][ 'file' ]) && ! empty ( $_REQUEST [ 'preset' ][ 'file' ]))
{
$f = $_REQUEST [ 'preset' ][ 'file' ];
$_REQUEST [ 'preset' ][ 'file' ] = array ( $f );
}
$_REQUEST [ 'preset' ][ 'file' ][] = " vfs://default/apps/addressbook/ " . $GLOBALS [ 'egw' ] -> accounts -> id2name ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ], 'person_id' ) . " /.entry " ;
2013-07-20 09:23:55 +02:00
}
2014-04-29 11:53:47 +02:00
// an app passed the request for fetching and mailing an entry
if ( isset ( $_REQUEST [ 'app' ]) && isset ( $_REQUEST [ 'method' ]) && isset ( $_REQUEST [ 'id' ]))
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
$app = $_REQUEST [ 'app' ];
$mt = $_REQUEST [ 'method' ];
$id = $_REQUEST [ 'id' ];
// passed method MUST be registered
$method = egw_link :: get_registry ( $app , $mt );
//error_log(__METHOD__.__LINE__.array2string($method));
if ( $method )
{
$res = ExecMethod ( $method , array ( $id , 'html' ));
//_debug_array($res);
if ( ! empty ( $res ))
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
$insertSigOnTop = 'below' ;
if ( isset ( $res [ 'attachments' ]) && is_array ( $res [ 'attachments' ]))
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
foreach ( $res [ 'attachments' ] as $f )
{
$_REQUEST [ 'preset' ][ 'file' ][] = $f ;
}
2013-07-20 09:23:55 +02:00
}
2014-04-29 11:53:47 +02:00
$content [ 'subject' ] = lang ( $app ) . ' #' . $res [ 'id' ] . ': ' ;
foreach ( array ( 'subject' , 'body' , 'mimetype' ) as $name ) {
$sName = $name ;
if ( $name == 'mimetype' )
{
$sName = 'mimeType' ;
$content [ $sName ] = $res [ $name ];
}
else
{
if ( $res [ $name ]) $content [ $sName ] .= ( strlen ( $content [ $sName ]) > 0 ? ' ' : '' ) . $res [ $name ];
}
2013-07-20 09:23:55 +02:00
}
}
}
}
2014-04-29 11:53:47 +02:00
// handle preset info/values
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 = ( stripos ( $_REQUEST [ 'preset' ][ 'mailto' ], 'mailto' ) === false ? $_REQUEST [ 'preset' ][ 'mailto' ] : 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 );
$content [ $keyValuePair [ 0 ]] .= ( strlen ( $content [ $keyValuePair [ 0 ]]) > 0 ? ' ' : '' ) . $keyValuePair [ 1 ];
}
}
$content [ '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 ]) $content [ $name ] .= ( strlen ( $content [ $name ]) > 0 ? ( $name == 'cc' || $name == 'bcc' ? ',' : ' ' ) : '' ) . $_REQUEST [ $name ];
2013-07-20 09:23:55 +02:00
}
}
2014-04-29 11:53:47 +02:00
if ( $_REQUEST [ 'preset' ][ 'mailtocontactbyid' ]) {
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'addressbook' ]) {
$addressbookprefs =& $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'addressbook' ];
if ( method_exists ( $GLOBALS [ 'egw' ] -> contacts , 'search' )) {
2013-07-20 09:23:55 +02:00
2014-04-29 11:53:47 +02:00
$addressArray = explode ( ',' , $_REQUEST [ 'preset' ][ 'mailtocontactbyid' ]);
foreach (( array ) $addressArray as $id => $addressID )
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
$addressID = ( int ) $addressID ;
if ( ! ( $addressID > 0 ))
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
unset ( $addressArray [ $id ]);
2013-07-20 09:23:55 +02:00
}
2014-04-29 11:53:47 +02:00
}
if ( count ( $addressArray ))
{
$_searchCond = array ( 'contact_id' => $addressArray );
//error_log(__METHOD__.__LINE__.$_searchString);
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'addressbook' ][ 'hide_accounts' ]) $showAccounts = false ;
$filter = ( $showAccounts ? array () : array ( 'account_id' => null ));
$filter [ 'cols_to_search' ] = array ( 'n_fn' , 'email' , 'email_home' );
$contacts = $GLOBALS [ 'egw' ] -> contacts -> search ( $_searchCond , array ( 'n_fn' , 'email' , 'email_home' ), 'n_fn' , '' , '%' , false , 'OR' , array ( 0 , 100 ), $filter );
// additionally search the accounts, if the contact storage is not the account storage
if ( $showAccounts &&
$GLOBALS [ 'egw_info' ][ 'server' ][ 'account_repository' ] == 'ldap' &&
$GLOBALS [ 'egw_info' ][ 'server' ][ 'contact_repository' ] == 'sql' )
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
$accounts = $GLOBALS [ 'egw' ] -> contacts -> search ( $_searchCond , array ( 'n_fn' , 'email' , 'email_home' ), 'n_fn' , '' , '%' , false , 'OR' , array ( 0 , 100 ), array ( 'owner' => 0 ));
if ( $contacts && $accounts )
{
$contacts = array_merge ( $contacts , $accounts );
usort ( $contacts , create_function ( '$a,$b' , 'return strcasecmp($a["n_fn"],$b["n_fn"]);' ));
}
elseif ( $accounts )
{
$contacts =& $accounts ;
}
unset ( $accounts );
2013-07-20 09:23:55 +02:00
}
}
2014-04-29 11:53:47 +02:00
if ( is_array ( $contacts )) {
$mailtoArray = array ();
$primary = $addressbookprefs [ 'distributionListPreferredMail' ];
if ( $primary != 'email' && $primary != 'email_home' ) $primary = 'email' ;
$secondary = ( $primary == 'email' ? 'email_home' : 'email' );
//error_log(__METHOD__.__LINE__.array2string($contacts));
foreach ( $contacts as $contact ) {
$innerCounter = 0 ;
foreach ( array ( $contact [ $primary ], $contact [ $secondary ]) as $email ) {
// use pref distributionListPreferredMail for the primary address
// avoid wrong addresses, if an rfc822 encoded address is in addressbook
$email = preg_replace ( " /(^.*<)([a-zA-Z0-9_ \ -]+@[a-zA-Z0-9_ \ - \ .]+)(.*)/ " , '$2' , $email );
$contact [ 'n_fn' ] = str_replace ( array ( ',' , '@' ), ' ' , $contact [ 'n_fn' ]);
$completeMailString = addslashes ( trim ( $contact [ 'n_fn' ] ? $contact [ 'n_fn' ] : $contact [ 'fn' ]) . ' <' . trim ( $email ) . '>' );
if ( $innerCounter == 0 && ! empty ( $email ) && in_array ( $completeMailString , $mailtoArray ) === false ) {
$i ++ ;
$innerCounter ++ ;
$mailtoArray [ $i ] = $completeMailString ;
}
2013-07-20 09:23:55 +02:00
}
}
}
2014-04-29 11:53:47 +02:00
//error_log(__METHOD__.__LINE__.array2string($mailtoArray));
$content [ 'to' ] = $mailtoArray ;
2013-07-20 09:23:55 +02:00
}
}
}
2014-04-29 11:53:47 +02:00
if ( isset ( $_REQUEST [ 'preset' ][ 'file' ]))
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
$names = ( array ) $_REQUEST [ 'preset' ][ 'name' ];
$types = ( array ) $_REQUEST [ 'preset' ][ 'type' ];
//if (!empty($types) && in_array('text/calendar; method=request',$types))
$files = ( array ) $_REQUEST [ 'preset' ][ 'file' ];
foreach ( $files as $k => $path )
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
if ( ! empty ( $types [ $k ]) && stripos ( $types [ $k ], 'text/calendar' ) !== false )
{
$insertSigOnTop = 'below' ;
}
//error_log(__METHOD__.__LINE__.$path.'->'.array2string(parse_url($path,PHP_URL_SCHEME == 'vfs')));
if ( parse_url ( $path , PHP_URL_SCHEME == 'vfs' ))
{
//egw_vfs::load_wrapper('vfs');
$type = egw_vfs :: mime_content_type ( $path );
// special handling for attaching vCard of iCal --> use their link-title as name
if ( substr ( $path , - 7 ) != '/.entry' ||
! ( list ( $app , $id ) = array_slice ( explode ( '/' , $path ), - 3 )) ||
! ( $name = egw_link :: title ( $app , $id )))
{
$name = egw_vfs :: decodePath ( egw_vfs :: basename ( $path ));
}
else
{
$name .= '.' . mime_magic :: mime2ext ( $type );
}
$path = str_replace ( '+' , '%2B' , $path );
$formData = array (
'name' => $name ,
'type' => $type ,
'file' => egw_vfs :: decodePath ( $path ),
'size' => filesize ( egw_vfs :: decodePath ( $path )),
);
if ( $formData [ 'type' ] == egw_vfs :: DIR_MIME_TYPE ) continue ; // ignore directories
}
elseif ( is_readable ( $path ))
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
$formData = array (
'name' => isset ( $names [ $k ]) ? $names [ $k ] : basename ( $path ),
'type' => isset ( $types [ $k ]) ? $types [ $k ] : ( function_exists ( 'mime_content_type' ) ? mime_content_type ( $path ) : mime_magic :: filename2mime ( $path )),
'file' => $path ,
'size' => filesize ( $path ),
);
2013-07-20 09:23:55 +02:00
}
else
{
2014-04-29 11:53:47 +02:00
continue ;
2013-07-20 09:23:55 +02:00
}
2014-04-29 11:53:47 +02:00
$this -> addAttachment ( $formData , $content ,( $alwaysAttachVCardAtCompose ? true : false ));
2013-07-20 09:23:55 +02:00
}
2014-04-29 11:53:47 +02:00
$remember = array ();
if ( isset ( $_REQUEST [ 'preset' ][ 'mailto' ]) || ( isset ( $_REQUEST [ 'app' ]) && isset ( $_REQUEST [ 'method' ]) && isset ( $_REQUEST [ 'id' ])))
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
foreach ( array_keys ( $content ) as $k )
{
if ( in_array ( $k , array ( 'to' , 'cc' , 'bcc' , 'subject' , 'body' , 'mimeType' )) && isset ( $this -> sessionData [ $k ])) $remember [ $k ] = $this -> sessionData [ $k ];
}
2013-07-20 09:23:55 +02:00
}
2014-04-29 11:53:47 +02:00
if ( ! empty ( $remember )) $content = array_merge ( $content , $remember );
2013-07-20 09:23:55 +02:00
}
2014-04-29 11:53:47 +02:00
foreach ( array ( 'to' , 'cc' , 'bcc' , 'subject' , 'body' ) as $name )
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
if ( $_REQUEST [ 'preset' ][ $name ]) $content [ $name ] = $_REQUEST [ 'preset' ][ $name ];
2013-07-20 09:23:55 +02:00
}
}
2014-04-29 11:53:47 +02:00
// is the to address set already?
if ( ! empty ( $_REQUEST [ 'send_to' ]))
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
$content [ 'to' ] = base64_decode ( $_REQUEST [ 'send_to' ]);
// first check if there is a questionmark or ampersand
if ( strpos ( $content [ 'to' ], '?' ) !== false ) list ( $content [ 'to' ], $rest ) = explode ( '?' , $content [ 'to' ], 2 );
$content [ 'to' ] = html_entity_decode ( $content [ 'to' ]);
if (( $at_pos = strpos ( $content [ 'to' ], '@' )) !== false )
{
if (( $amp_pos = strpos ( substr ( $content [ 'to' ], $at_pos ), '&' )) !== false )
{
//list($email,$addoptions) = explode('&',$value,2);
$email = substr ( $content [ 'to' ], 0 , $amp_pos + $at_pos );
$rest = substr ( $content [ 'to' ], $amp_pos + $at_pos + 1 );
//error_log(__METHOD__.__LINE__.$email.' '.$rest);
$content [ 'to' ] = $email ;
}
}
if ( strpos ( $content [ 'to' ], '%40' ) !== false ) $content [ 'to' ] = html :: purify ( str_replace ( '%40' , '@' , $content [ 'to' ]));
$rarr = array ( html :: purify ( $rest ));
if ( isset ( $rest ) &&! empty ( $rest ) && strpos ( $rest , '&' ) !== false ) $rarr = explode ( '&' , $rest );
//error_log(__METHOD__.__LINE__.$content['to'].'->'.array2string($rarr));
$karr = array ();
2014-10-23 13:28:36 +02:00
foreach ( $rarr as & $rval )
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
//must contain =
if ( strpos ( $rval , '=' ) !== false )
{
list ( $k , $v ) = explode ( '=' , $rval , 2 );
2014-11-20 18:53:52 +01:00
$karr [ $k ] = ( string ) $v ;
unset ( $k , $v );
2014-04-29 11:53:47 +02:00
}
2013-07-20 09:23:55 +02:00
}
2014-04-29 11:53:47 +02:00
//error_log(__METHOD__.__LINE__.$content['to'].'->'.array2string($karr));
foreach ( array ( 'cc' , 'bcc' , 'subject' , 'body' ) as $name )
2013-07-20 09:23:55 +02:00
{
2014-04-29 11:53:47 +02:00
if ( $karr [ $name ]) $content [ $name ] = $karr [ $name ];
2013-07-20 09:23:55 +02:00
}
2014-04-29 11:53:47 +02:00
if ( ! empty ( $_REQUEST [ 'subject' ])) $content [ 'subject' ] = html :: purify ( trim ( html_entity_decode ( $_REQUEST [ 'subject' ])));
2013-07-20 09:23:55 +02:00
}
}
//is the MimeType set/requested
2014-04-29 11:53:47 +02:00
if ( $isFirstLoad && ! empty ( $_REQUEST [ 'mimeType' ]))
2013-07-20 09:23:55 +02:00
{
2014-02-04 12:31:13 +01:00
if (( $_REQUEST [ 'mimeType' ] == " text " || $_REQUEST [ 'mimeType' ] == " plain " ) && $content [ 'mimeType' ] == 'html' )
{
$_content [ 'mimeType' ] = $content [ 'mimeType' ] = 'plain' ;
$content [ 'body' ] = $this -> convertHTMLToText ( str_replace ( array ( " \n \r " , " \n " ), ' ' , $content [ 'body' ]));
}
if ( $_REQUEST [ 'mimeType' ] == " html " && $content [ 'mimeType' ] != 'html' )
{
$_content [ 'mimeType' ] = $content [ 'mimeType' ] = 'html' ;
$content [ 'body' ] = " <pre> " . $content [ 'body' ] . " </pre> " ;
// take care this assumption is made on the creation of the reply header in bocompose::getReplyData
if ( strpos ( $content [ 'body' ], " <pre> \r \n \r \n --- " ) === 0 ) $content [ 'body' ] = substr_replace ( $content [ 'body' ], " <br> \r \n <pre>--- " , 0 , strlen ( " <pre> \r \n \r \n --- " ) - 1 );
}
2013-07-20 09:23:55 +02:00
}
else
{
// try to enforce a mimeType on reply ( if type is not of the wanted type )
if ( $isReply )
{
2014-05-13 15:10:53 +02:00
if ( ! empty ( $this -> mailPreferences [ 'replyOptions' ]) && $this -> mailPreferences [ 'replyOptions' ] == " text " &&
2013-10-02 16:50:24 +02:00
$content [ 'mimeType' ] == 'html' )
2013-07-20 09:23:55 +02:00
{
2014-02-04 12:31:13 +01:00
$_content [ 'mimeType' ] = $content [ 'mimeType' ] = 'plain' ;
2013-10-02 16:50:24 +02:00
$content [ 'body' ] = $this -> convertHTMLToText ( str_replace ( array ( " \n \r " , " \n " ), ' ' , $content [ 'body' ]));
2013-07-20 09:23:55 +02:00
}
2014-05-13 15:10:53 +02:00
if ( ! empty ( $this -> mailPreferences [ 'replyOptions' ]) && $this -> mailPreferences [ 'replyOptions' ] == " html " &&
2013-10-02 16:50:24 +02:00
$content [ 'mimeType' ] != 'html' )
2013-07-20 09:23:55 +02:00
{
2014-02-04 12:31:13 +01:00
$_content [ 'mimeType' ] = $content [ 'mimeType' ] = 'html' ;
2013-10-02 16:50:24 +02:00
$content [ 'body' ] = " <pre> " . $content [ 'body' ] . " </pre> " ;
2013-07-20 09:23:55 +02:00
// take care this assumption is made on the creation of the reply header in bocompose::getReplyData
2013-10-02 16:50:24 +02:00
if ( strpos ( $content [ 'body' ], " <pre> \r \n \r \n --- " ) === 0 ) $content [ 'body' ] = substr_replace ( $content [ 'body' ], " <br> \r \n <pre>--- " , 0 , strlen ( " <pre> \r \n \r \n --- " ) - 1 );
2013-07-20 09:23:55 +02:00
}
}
}
2013-10-10 13:44:01 +02:00
2013-10-02 16:50:24 +02:00
if ( $content [ 'mimeType' ] == 'html' && html :: htmlarea_availible () === false )
2013-07-20 09:23:55 +02:00
{
2014-02-04 12:31:13 +01:00
$_content [ 'mimeType' ] = $content [ 'mimeType' ] = 'plain' ;
2013-10-02 16:50:24 +02:00
$content [ 'body' ] = $this -> convertHTMLToText ( $content [ 'body' ]);
2013-07-20 09:23:55 +02:00
}
// 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 );
}
2014-11-25 00:38:37 +01:00
if (( $suppressSigOnTop || $content [ 'isDraft' ]) && ! empty ( $content [ 'mailidentity' ])) $presetSig = ( int ) $content [ 'mailidentity' ];
2013-11-22 14:55:09 +01:00
//if (($suppressSigOnTop || $content['isDraft']) && !empty($content['stationeryID'])) $presetStationery = $content['stationeryID'];
2013-07-20 09:23:55 +02:00
$presetId = NULL ;
2014-01-13 16:40:34 +01:00
if (( $suppressSigOnTop || $content [ 'isDraft' ]) && ! empty ( $content [ 'mailaccount' ])) $presetId = ( int ) $content [ 'mailaccount' ];
2014-11-25 00:38:37 +01:00
if ( ! empty ( $sigPref [ $this -> mail_bo -> profileID ]) && ( empty ( $presetSig ) || $presetSig ==- 1 || empty ( $content [ 'mailidentity' ]) || $content [ 'mailidentity' ] ==- 1 )) $presetSig = $sigPref [ $this -> mail_bo -> profileID ];
2013-07-20 09:23:55 +02:00
2013-08-21 12:47:20 +02:00
// fetch the signature, prepare the select box, ...
2014-11-25 00:38:37 +01:00
if ( empty ( $content [ 'mailidentity' ])) {
$content [ 'mailidentity' ] = $acc [ 'ident_id' ];
2013-07-20 09:23:55 +02:00
}
$disableRuler = false ;
2014-11-25 00:38:37 +01:00
//_debug_array(($presetSig ? $presetSig : $content['mailidentity']));
2013-11-22 14:55:09 +01:00
try
{
2014-11-25 00:38:37 +01:00
$signature = emailadmin_account :: read_identity (( $presetSig ? $presetSig : $content [ 'mailidentity' ]), true );
2013-11-22 14:55:09 +01:00
}
catch ( Exception $e )
{
//PROBABLY NOT FOUND
$signature = array ();
}
2014-05-13 15:10:53 +02:00
if (( isset ( $this -> mailPreferences [ 'disableRulerForSignatureSeparation' ]) &&
$this -> mailPreferences [ 'disableRulerForSignatureSeparation' ]) ||
2013-11-22 14:55:09 +01:00
empty ( $signature [ 'ident_signature' ]) || trim ( $this -> convertHTMLToText ( $signature [ 'ident_signature' ], true , true )) == '' )
2013-07-20 09:23:55 +02:00
{
$disableRuler = true ;
}
2014-03-07 15:54:44 +01:00
$font_span = $font_part = '' ;
2013-10-02 16:50:24 +02:00
if ( $content [ 'mimeType' ] == 'html' /*&& trim($content['body'])==''*/ ) {
2013-07-20 09:23:55 +02:00
// User preferences for style
$font = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'rte_font' ];
$font_size = egw_ckeditor_config :: font_size_from_prefs ();
2014-03-04 10:23:43 +01:00
$font_part = '<span ' . ( $font || $font_size ? 'style="' : '' ) . ( $font ? 'font-family:' . $font . '; ' : '' ) . ( $font_size ? 'font-size:' . $font_size . '; ' : '' ) . '">' ;
$font_span = $font_part . ' ' . '</span>' ;
2013-07-20 09:23:55 +02:00
if ( empty ( $font ) && empty ( $font_size )) $font_span = '' ;
}
2014-03-04 10:23:43 +01:00
// the font span should only be applied on first load or on switch plain->html and the absence of the font_part of the span
if ( ! $isFirstLoad && ! empty ( $font_span ) && stripos ( $content [ 'body' ], $font_part ) === false ) $font_span = '' ;
2013-07-20 09:23:55 +02:00
//remove possible html header stuff
2013-10-02 16:50:24 +02:00
if ( stripos ( $content [ 'body' ], '<html><head></head><body>' ) !== false ) $content [ 'body' ] = str_ireplace ( array ( '<html><head></head><body>' , '</body></html>' ), array ( '' , '' ), $content [ 'body' ]);
2014-05-13 15:10:53 +02:00
//error_log(__METHOD__.__LINE__.array2string($this->mailPreferences));
2013-07-20 09:23:55 +02:00
$blockElements = array ( 'address' , 'blockquote' , 'center' , 'del' , 'dir' , 'div' , 'dl' , 'fieldset' , 'form' , 'h1' , 'h2' , 'h3' , 'h4' , 'h5' , 'h6' , 'hr' , 'ins' , 'isindex' , 'menu' , 'noframes' , 'noscript' , 'ol' , 'p' , 'pre' , 'table' , 'ul' );
2014-05-13 15:10:53 +02:00
if ( isset ( $this -> mailPreferences [ 'insertSignatureAtTopOfMessage' ]) &&
$this -> mailPreferences [ 'insertSignatureAtTopOfMessage' ] &&
2013-07-20 09:23:55 +02:00
! ( isset ( $_POST [ 'mySigID' ]) && ! empty ( $_POST [ 'mySigID' ]) ) && ! $suppressSigOnTop
)
{
$insertSigOnTop = ( $insertSigOnTop ? $insertSigOnTop : true );
2013-11-22 14:55:09 +01:00
$sigText = mail_bo :: merge ( $signature [ 'ident_signature' ], array ( $GLOBALS [ 'egw' ] -> accounts -> id2name ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ], 'person_id' )));
2013-10-02 16:50:24 +02:00
if ( $content [ 'mimeType' ] == 'html' )
2013-07-20 09:23:55 +02:00
{
$sigTextStartsWithBlockElement = ( $disableRuler ? false : true );
foreach ( $blockElements as $e )
{
if ( $sigTextStartsWithBlockElement ) break ;
if ( stripos ( trim ( $sigText ), '<' . $e ) === 0 ) $sigTextStartsWithBlockElement = true ;
}
}
2013-10-02 16:50:24 +02:00
if ( $content [ 'mimeType' ] == 'html' ) {
2013-07-20 09:23:55 +02:00
$before = ( ! empty ( $font_span ) && ! ( $insertSigOnTop === 'below' ) ? $font_span : ' ' ) . ( $disableRuler ? '' /*($sigTextStartsWithBlockElement?'':'<p style="margin:0px;"/>')*/ : '<hr style="border:1px dotted silver; width:90%;">' );
$inbetween = ' <br>' ;
} else {
$before = ( $disableRuler ? " \r \n \r \n " : " \r \n \r \n -- \r \n " );
$inbetween = " \r \n " ;
}
2013-10-02 16:50:24 +02:00
if ( $content [ 'mimeType' ] == 'html' )
2013-07-20 09:23:55 +02:00
{
$sigText = ( $sigTextStartsWithBlockElement ? '' : " <div> " ) . " <!-- HTMLSIGBEGIN --> " . $sigText . " <!-- HTMLSIGEND --> " . ( $sigTextStartsWithBlockElement ? '' : " </div> " );
}
if ( $insertSigOnTop === 'below' )
{
2013-10-02 16:50:24 +02:00
$content [ 'body' ] = $font_span . $content [ 'body' ] . $before . ( $content [ 'mimeType' ] == 'html' ? $sigText : $this -> convertHTMLToText ( $sigText , true , true ));
2013-07-20 09:23:55 +02:00
}
else
{
2013-10-02 16:50:24 +02:00
$content [ 'body' ] = $before . ( $content [ 'mimeType' ] == 'html' ? $sigText : $this -> convertHTMLToText ( $sigText , true , true )) . $inbetween . $content [ 'body' ];
2013-07-20 09:23:55 +02:00
}
}
else
{
2014-10-23 12:27:58 +02:00
$content [ 'body' ] = ( $font_span ? ( $isFirstLoad === " switchedplaintohtml " ? $font_part : $font_span ) :/* ( $content [ 'mimeType' ] == 'html' ? ' ' : '' ) */ '' ) . $content [ 'body' ] . ( $isFirstLoad === " switchedplaintohtml " ? " </span> " : " " );
2013-07-20 09:23:55 +02:00
}
2013-10-02 16:50:24 +02:00
//error_log(__METHOD__.__LINE__.$content['body']);
2013-08-21 12:47:20 +02:00
2013-07-20 09:23:55 +02:00
// prepare body
// in a way, this tests if we are having real utf-8 (the displayCharset) by now; we should if charsets reported (or detected) are correct
if ( strtoupper ( $this -> displayCharset ) == 'UTF-8' )
{
2013-10-02 16:50:24 +02:00
$test = @ json_encode ( $content [ 'body' ]);
2013-07-20 09:23:55 +02:00
//error_log(__METHOD__.__LINE__.' ->'.strlen($singleBodyPart['body']).' Error:'.json_last_error().'<- BodyPart:#'.$test.'#');
//if (json_last_error() != JSON_ERROR_NONE && strlen($singleBodyPart['body'])>0)
2013-10-02 16:50:24 +02:00
if ( $test == " null " && strlen ( $content [ 'body' ]) > 0 )
2013-07-20 09:23:55 +02:00
{
// try to fix broken utf8
2013-10-02 16:50:24 +02:00
$x = ( function_exists ( 'mb_convert_encoding' ) ? mb_convert_encoding ( $content [ 'body' ], 'UTF-8' , 'UTF-8' ) : ( function_exists ( 'iconv' ) ? @ iconv ( " UTF-8 " , " UTF-8//IGNORE " , $content [ 'body' ]) : $content [ 'body' ]));
2013-07-20 09:23:55 +02:00
$test = @ json_encode ( $x );
2013-10-02 16:50:24 +02:00
if ( $test == " null " && strlen ( $content [ 'body' ]) > 0 )
2013-07-20 09:23:55 +02:00
{
// this should not be needed, unless something fails with charset detection/ wrong charset passed
2013-10-02 16:50:24 +02:00
error_log ( __METHOD__ . __LINE__ . ' Charset problem detected; Charset Detected:' . mail_bo :: detect_encoding ( $content [ 'body' ]));
$content [ 'body' ] = utf8_encode ( $content [ 'body' ]);
2013-07-20 09:23:55 +02:00
}
else
{
2013-10-02 16:50:24 +02:00
$content [ 'body' ] = $x ;
2013-07-20 09:23:55 +02:00
}
}
}
2014-02-14 14:38:08 +01:00
//error_log(__METHOD__.__LINE__.array2string($content));
2014-11-20 18:53:52 +01:00
// get identities of all accounts as "$acc_id:$ident_id" => $identity
$sel_options [ 'mailaccount' ] = $identities = array ();
foreach ( emailadmin_account :: search () as $acc_id => $account )
{
foreach ( emailadmin_account :: identities ( $acc_id ) as $ident_id => $identity )
{
$sel_options [ 'mailaccount' ][ $acc_id . ':' . $ident_id ] = $identity ;
$identities [ $ident_id ] = $identity ;
}
unset ( $account );
}
2013-08-21 12:47:20 +02:00
// signature stuff set earlier
2014-11-25 00:38:37 +01:00
if ( $presetSig ) $content [ 'mailidentity' ] = $presetSig ;
2013-08-21 12:47:20 +02:00
// end signature stuff
2013-10-02 16:50:24 +02:00
//$content['bcc'] = array('kl@stylite.de','kl@leithoff.net');
2013-08-21 12:47:20 +02:00
// address stuff like from, to, cc, replyto
$destinationRows = 0 ;
2013-10-07 14:17:33 +02:00
foreach ( self :: $destinations as $destination ) {
2013-10-07 18:33:56 +02:00
if ( ! is_array ( $content [ $destination ]))
{
if ( ! empty ( $content [ $destination ])) $content [ $destination ] = ( array ) $content [ $destination ];
}
2014-04-01 16:56:13 +02:00
$addr_content = $content [ strtolower ( $destination )];
// we clear the given address array and rebuild it
unset ( $content [ strtolower ( $destination )]);
foreach (( array ) $addr_content as $key => $value ) {
2013-08-21 12:47:20 +02:00
if ( $value == " NIL@NIL " ) continue ;
2014-11-20 18:53:52 +01:00
if ( $destination == 'replyto' && str_replace ( '"' , '' , $value ) ==
str_replace ( '"' , '' , $identities [ $presetId ? $presetId : $this -> mail_bo -> getDefaultIdentity ()]))
2014-04-01 16:56:13 +02:00
{
// preserve/restore the value to content.
$content [ strtolower ( $destination )][] = $value ;
continue ;
}
2013-10-10 16:56:30 +02:00
//error_log(__METHOD__.__LINE__.array2string(array('key'=>$key,'value'=>$value)));
2014-11-20 18:53:52 +01:00
$value = str_replace ( " \" \" " , '"' , htmlspecialchars_decode ( $value , ENT_COMPAT ));
2014-10-18 18:30:39 +02:00
foreach ( emailadmin_imapbase :: parseAddressList ( $value ) as $addressObject ) {
2013-08-21 12:47:20 +02:00
if ( $addressObject -> host == '.SYNTAX-ERROR.' ) continue ;
$address = imap_rfc822_write_address ( $addressObject -> mailbox , $addressObject -> host , $addressObject -> personal );
//$address = mail_bo::htmlentities($address, $this->displayCharset);
2013-10-05 11:47:34 +02:00
$content [ strtolower ( $destination )][] = $address ;
2013-08-21 12:47:20 +02:00
$destinationRows ++ ;
}
}
}
2013-09-02 17:15:35 +02:00
if ( $_content )
2013-08-21 12:47:20 +02:00
{
2013-11-22 14:55:09 +01:00
//input array of _content had no signature information but was seeded later, and content has a valid setting
2014-11-25 00:38:37 +01:00
if ( ! $_contentHasSigID && $content [ 'mailidentity' ] && array_key_exists ( 'mailidentity' , $_content )) unset ( $_content [ 'mailidentity' ]);
2013-09-02 17:15:35 +02:00
$content = array_merge ( $content , $_content );
2013-10-05 11:47:34 +02:00
if ( ! empty ( $content [ 'folder' ])) $sel_options [ 'folder' ] = $this -> ajax_searchFolder ( 0 , true );
2014-11-20 18:53:52 +01:00
if ( empty ( $content [ 'mailaccount' ])) $content [ 'mailaccount' ] = $this -> mail_bo -> profileID ;
2013-08-21 12:47:20 +02:00
}
else
{
2014-01-13 16:40:34 +01:00
//error_log(__METHOD__.__LINE__.array2string(array($sel_options['mailaccount'],$selectedSender)));
2014-11-20 18:53:52 +01:00
$content [ 'mailaccount' ] = $this -> mail_bo -> profileID ;
2013-10-02 16:50:24 +02:00
//error_log(__METHOD__.__LINE__.$content['body']);
2013-08-21 12:47:20 +02:00
}
2013-10-03 18:09:25 +02:00
$content [ 'is_html' ] = ( $content [ 'mimeType' ] == 'html' ? true : '' );
$content [ 'is_plain' ] = ( $content [ 'mimeType' ] == 'html' ? '' : true );
$content [ 'mail_' . ( $content [ 'mimeType' ] == 'html' ? 'html' : 'plain' ) . 'text' ] = $content [ 'body' ];
2013-09-11 15:46:00 +02:00
$content [ 'showtempname' ] = 0 ;
2013-10-08 16:23:46 +02:00
//if (is_array($content['attachments']))error_log(__METHOD__.__LINE__.'before merging content with uploadforCompose:'.array2string($content['attachments']));
2013-10-02 16:50:24 +02:00
$content [ 'attachments' ] = ( is_array ( $content [ 'attachments' ]) && is_array ( $content [ 'uploadForCompose' ]) ? array_merge ( $content [ 'attachments' ],( ! empty ( $content [ 'uploadForCompose' ]) ? $content [ 'uploadForCompose' ] : array ())) : ( is_array ( $content [ 'uploadForCompose' ]) ? $content [ 'uploadForCompose' ] : ( is_array ( $content [ 'attachments' ]) ? $content [ 'attachments' ] : null )));
2013-09-11 15:46:00 +02:00
//if (is_array($content['attachments'])) foreach($content['attachments'] as $k => &$file) $file['delete['.$file['tmp_name'].']']=0;
$content [ 'no_griddata' ] = empty ( $content [ 'attachments' ]);
$preserv [ 'attachments' ] = $content [ 'attachments' ];
2013-10-02 16:50:24 +02:00
2013-10-08 16:23:46 +02:00
//if (is_array($content['attachments']))error_log(__METHOD__.__LINE__.' Attachments:'.array2string($content['attachments']));
2013-10-07 17:02:35 +02:00
// if no filemanager -> no vfsFileSelector
if ( ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'filemanager' ])
{
2013-10-11 11:28:33 +02:00
$content [ 'vfsNotAvailable' ] = " mail_DisplayNone " ;
2013-10-07 17:02:35 +02:00
}
// if no infolog -> no save as infolog
if ( ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'infolog' ])
{
2013-10-11 11:28:33 +02:00
$content [ 'noInfologAvailable' ] = " mail_DisplayNone " ;
2013-10-07 17:02:35 +02:00
}
// if no tracker -> no save as tracker
if ( ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'tracker' ])
{
2013-10-11 11:28:33 +02:00
$content [ 'noTrackerAvailable' ] = " mail_DisplayNone " ;
2013-10-07 17:02:35 +02:00
}
if ( ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'infolog' ] && ! $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'tracker' ])
{
2013-10-11 11:28:33 +02:00
$content [ 'noSaveAsAvailable' ] = " mail_DisplayNone " ;
2013-10-07 17:02:35 +02:00
}
// composeID to detect if we have changes to certain content
2013-10-07 14:17:33 +02:00
$preserv [ 'composeID' ] = $content [ 'composeID' ] = $this -> composeID ;
//error_log(__METHOD__.__LINE__.' ComposeID:'.$preserv['composeID']);
2013-09-02 17:15:35 +02:00
$preserv [ 'is_html' ] = $content [ 'is_html' ];
$preserv [ 'is_plain' ] = $content [ 'is_plain' ];
2013-10-03 18:09:25 +02:00
if ( isset ( $content [ 'mimeType' ])) $preserv [ 'mimeType' ] = $content [ 'mimeType' ];
2013-10-07 14:17:33 +02:00
$sel_options [ 'mimeType' ] = self :: $mimeTypes ;
$sel_options [ 'priority' ] = self :: $priorities ;
if ( ! isset ( $content [ 'priority' ]) || empty ( $content [ 'priority' ])) $content [ 'priority' ] = 3 ;
2014-01-17 11:47:35 +01:00
//$GLOBALS['egw_info']['flags']['currentapp'] = 'mail';//should not be needed
2013-10-10 13:44:01 +02:00
$etpl = new etemplate_new ( 'mail.compose' );
if ( $content [ 'mimeType' ] == 'html' )
{
//mode="$cont[rtfEditorFeatures]" validation_rules="$cont[validation_rules]" base_href="$cont[upload_dir]"
$_htmlConfig = mail_bo :: $htmLawed_config ;
mail_bo :: $htmLawed_config [ 'comment' ] = 2 ;
mail_bo :: $htmLawed_config [ 'transform_anchor' ] = false ;
2014-02-03 08:59:51 +01:00
// it is intentional to use that simple-withimage configuration for the ckeditor
// and not the eGroupware wide pref to prevent users from trying things that will potentially not work
// or not work as expected, as a full featured editor that may be wanted in other apps
// is way overloading the "normal" needs for composing mails
2013-10-10 13:44:01 +02:00
$content [ 'rtfEditorFeatures' ] = 'simple-withimage' ; //egw_ckeditor_config::get_ckeditor_config();
2014-02-14 14:38:08 +01:00
//$content['rtfEditorFeatures']='advanced';//egw_ckeditor_config::get_ckeditor_config();
2013-10-10 13:44:01 +02:00
$content [ 'validation_rules' ] = json_encode ( mail_bo :: $htmLawed_config );
$etpl -> setElementAttribute ( 'mail_htmltext' , 'mode' , $content [ 'rtfEditorFeatures' ]);
$etpl -> setElementAttribute ( 'mail_htmltext' , 'validation_rules' , $content [ 'validation_rules' ]);
mail_bo :: $htmLawed_config = $_htmlConfig ;
}
if ( isset ( $content [ 'composeID' ]) &&! empty ( $content [ 'composeID' ]))
2013-10-07 14:17:33 +02:00
{
$composeCache = $content ;
2013-10-10 13:44:01 +02:00
unset ( $composeCache [ 'body' ]);
unset ( $composeCache [ 'mail_htmltext' ]);
unset ( $composeCache [ 'mail_plaintext' ]);
egw_cache :: setCache ( egw_cache :: SESSION , 'mail' , 'composeCache' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]) . '_' . $this -> composeID , $composeCache , $expiration = 60 * 60 * 2 );
2013-10-07 14:17:33 +02:00
}
2013-10-08 16:23:46 +02:00
if ( ! isset ( $_content [ 'serverID' ]) || empty ( $_content [ 'serverID' ]))
{
$content [ 'serverID' ] = $this -> mail_bo -> profileID ;
}
$preserv [ 'serverID' ] = $content [ 'serverID' ];
2014-04-01 13:41:34 +02:00
$preserv [ 'lastDrafted' ] = $content [ 'lastDrafted' ];
2014-01-23 12:56:34 +01:00
$preserv [ 'processedmail_id' ] = $content [ 'processedmail_id' ];
2014-09-09 16:04:40 +02:00
$preserv [ 'references' ] = $content [ 'references' ];
$preserv [ 'in-reply-to' ] = $content [ 'in-reply-to' ];
2014-09-11 13:51:07 +02:00
$preserv [ 'thread-topic' ] = $content [ 'thread-topic' ];
$preserv [ 'thread-index' ] = $content [ 'thread-index' ];
$preserv [ 'list-id' ] = $content [ 'list-id' ];
2014-01-23 12:56:34 +01:00
$preserv [ 'mode' ] = $content [ 'mode' ];
2014-01-18 15:52:21 +01:00
// convert it back to checkbox expectations
if ( $content [ 'mimeType' ] == 'html' ) {
$content [ 'mimeType' ] = 1 ;
} else {
$content [ 'mimeType' ] = 0 ;
}
2014-04-01 16:56:13 +02:00
2014-11-25 00:38:37 +01:00
// join again mailaccount and identity
$content [ 'mailaccount' ] .= ':' . $content [ 'mailidentity' ];
2014-11-20 18:53:52 +01:00
2014-01-30 12:28:20 +01:00
//error_log(__METHOD__.__LINE__.array2string($content));
2014-09-12 13:52:38 +02:00
$etpl -> exec ( 'mail.mail_compose.compose' , $content , $sel_options , array (), $preserv , 2 );
2013-07-20 09:23:55 +02:00
}
2014-01-16 16:58:27 +01:00
2013-10-04 19:45:33 +02:00
/**
* Get pre - fill a new compose based on an existing email
*
* @ param type $mail_id If composing based on an existing mail , this is the ID of the mail
* @ param type $part_id For multi - part mails , indicates which part
* @ param type $from Indicates what the mail is based on , and how to extract data .
2014-01-15 17:29:30 +01:00
* One of 'compose' , 'composeasnew' , 'reply' , 'reply_all' , 'forward' or 'merge'
2013-10-04 19:45:33 +02:00
* @ param boolean $_focusElement varchar subject , to , body supported
* @ param boolean $suppressSigOnTop
* @ param boolean $isReply
*
* @ return mixed [] Content array pre - filled according to source mail
*/
private function getComposeFrom ( $mail_id , $part_id , $from , & $_focusElement , & $suppressSigOnTop , & $isReply )
{
$content = array ();
2013-10-08 16:23:46 +02:00
//error_log(__METHOD__.__LINE__.array2string($mail_id).", $part_id, $from, $_focusElement, $suppressSigOnTop, $isReply");
// on forward we may have to support multiple ids
if ( $from == 'forward' )
{
$replyIds = explode ( ',' , $mail_id );
$mail_id = $replyIds [ 0 ];
}
2013-10-04 19:45:33 +02:00
$hA = mail_ui :: splitRowID ( $mail_id );
$msgUID = $hA [ 'msgUID' ];
2013-10-03 12:05:05 +02:00
$folder = $hA [ 'folder' ];
2013-10-08 16:23:46 +02:00
$icServerID = $hA [ 'profileID' ];
if ( $icServerID != $this -> mail_bo -> profileID )
{
2014-01-21 09:26:59 +01:00
$this -> changeProfile ( $icServerID );
2013-10-08 16:23:46 +02:00
}
$icServer = $this -> mail_bo -> icServer ;
2013-10-04 19:45:33 +02:00
if ( ! empty ( $folder ) && ! empty ( $msgUID ) )
2013-07-20 09:23:55 +02:00
{
// this fill the session data with the values from the original email
2013-10-04 19:45:33 +02:00
switch ( $from )
{
case 'composeasnew' :
case 'composefromdraft' :
$content = $this -> getDraftData ( $icServer , $folder , $msgUID , $part_id );
2014-01-30 10:35:56 +01:00
$content [ 'processedmail_id' ] = $mail_id ;
2014-01-16 16:58:27 +01:00
2013-10-04 19:45:33 +02:00
$_focusElement = 'body' ;
$suppressSigOnTop = true ;
break ;
case 'reply' :
2013-10-05 11:03:51 +02:00
case 'reply_all' :
2013-10-04 19:45:33 +02:00
$content = $this -> getReplyData ( $from == 'reply' ? 'single' : 'all' , $icServer , $folder , $msgUID , $part_id );
2014-01-23 12:56:34 +01:00
$content [ 'processedmail_id' ] = $mail_id ;
$content [ 'mode' ] = 'reply' ;
2013-10-04 19:45:33 +02:00
$_focusElement = 'body' ;
2013-10-10 16:56:30 +02:00
$suppressSigOnTop = false ;
2013-10-04 19:45:33 +02:00
$isReply = true ;
break ;
case 'forward' :
2013-10-08 16:23:46 +02:00
$mode = ( $_GET [ 'mode' ] == 'forwardinline' ? 'inline' : 'asmail' );
// this fill the session data with the values from the original email
2014-10-23 13:28:36 +02:00
foreach ( $replyIds as & $mail_id )
2013-10-08 16:23:46 +02:00
{
//error_log(__METHOD__.__LINE__.' ID:'.$mail_id.' Mode:'.$mode);
$hA = mail_ui :: splitRowID ( $mail_id );
$msgUID = $hA [ 'msgUID' ];
$folder = $hA [ 'folder' ];
$content = $this -> getForwardData ( $icServer , $folder , $msgUID , $part_id , $mode );
}
2014-01-23 12:56:34 +01:00
$content [ 'processedmail_id' ] = implode ( ',' , $replyIds );
$content [ 'mode' ] = 'forward' ;
2014-05-13 15:10:53 +02:00
$isReply = ( $mode ? $mode == 'inline' : $this -> mailPreferences [ 'message_forwarding' ] == 'inline' );
2013-10-10 16:56:30 +02:00
$suppressSigOnTop = false ; // ($mode && $mode=='inline'?true:false);// may be a better solution
2013-10-04 19:45:33 +02:00
$_focusElement = 'to' ;
break ;
default :
error_log ( 'Unhandled compose source: ' . $from );
}
2013-07-20 09:23:55 +02:00
}
2014-01-15 17:29:30 +01:00
else if ( $from == 'merge' && $_REQUEST [ 'document' ])
{
/*
2014-01-16 15:05:07 +01:00
* Special merge from everywhere else because all other apps merge gives
* a document to be downloaded , this opens a compose dialog .
* Use ajax_merge to merge & send multiple
2014-01-15 17:29:30 +01:00
*/
// Merge selected ID (in mailtocontactbyid or $mail_id) into given document
2014-11-20 18:53:52 +01:00
$merge_class = preg_match ( '/^([a-z_-]+_merge)$/' , $_REQUEST [ 'merge' ]) ? $_REQUEST [ 'merge' ] : 'addressbook_merge' ;
2014-08-12 18:58:07 +02:00
$document_merge = new $merge_class ();
2014-01-15 17:29:30 +01:00
$this -> mail_bo -> openConnection ();
$merge_ids = $_REQUEST [ 'preset' ][ 'mailtocontactbyid' ] ? $_REQUEST [ 'preset' ][ 'mailtocontactbyid' ] : $mail_id ;
2014-11-20 18:53:52 +01:00
if ( ! is_array ( $merge_ids )) $merge_ids = explode ( ',' , $merge_ids );
2014-01-15 17:29:30 +01:00
try
{
$merged_mail_id = '' ;
$folder = '' ;
2014-11-20 18:53:52 +01:00
if (( $error = $document_merge -> check_document ( $_REQUEST [ 'document' ], '' )))
2014-01-15 17:29:30 +01:00
{
$content [ 'msg' ] = $error ;
return $content ;
}
// Merge does not work correctly (missing to) if current app is not addressbook
2014-01-17 11:47:35 +01:00
//$GLOBALS['egw_info']['flags']['currentapp'] = 'addressbook';
2014-01-15 17:29:30 +01:00
// Actually do the merge
if ( count ( $merge_ids ) <= 1 )
{
2014-01-16 15:05:07 +01:00
$results = $this -> mail_bo -> importMessageToMergeAndSend (
$document_merge , egw_vfs :: PREFIX . $_REQUEST [ 'document' ], $merge_ids , $folder , $merged_mail_id
);
// Open compose
2014-01-15 17:29:30 +01:00
$merged_mail_id = trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]) . mail_ui :: $delimiter .
$this -> mail_bo -> profileID . mail_ui :: $delimiter .
base64_encode ( $folder ) . mail_ui :: $delimiter . $merged_mail_id ;
$content = $this -> getComposeFrom ( $merged_mail_id , $part_id , 'composefromdraft' , $_focusElement , $suppressSigOnTop , $isReply );
}
else
{
$success = implode ( ', ' , $results [ 'success' ]);
$fail = implode ( ', ' , $results [ 'failed' ]);
if ( $success ) egw_framework :: message ( $success , 'success' );
egw_framework :: window_close ( $fail );
}
}
catch ( egw_exception_wrong_userinput $e )
{
// if this returns with an exeption, something failed big time
$content [ 'msg' ] = $e -> getMessage ();
}
}
2013-10-04 19:45:33 +02:00
return $content ;
2013-07-20 09:23:55 +02:00
}
/**
* previous bocompose stuff
*/
/**
* replace emailaddresses eclosed in <> ( eg .: < me @ you . de > ) with the emailaddress only ( e . g : me @ you . de )
* always returns 1
*/
static function replaceEmailAdresses ( & $text )
{
// replace emailaddresses eclosed in <> (eg.: <me@you.de>) with the emailaddress only (e.g: me@you.de)
mail_bo :: replaceEmailAdresses ( $text );
return 1 ;
}
function convertHTMLToText ( & $_html , $sourceishtml = true , $stripcrl = false )
{
$stripalltags = true ;
// third param is stripalltags, we may not need that, if the source is already in ascii
if ( ! $sourceishtml ) $stripalltags = false ;
return translation :: convertHTMLToText ( $_html , $this -> displayCharset , $stripcrl , $stripalltags );
}
function generateRFC822Address ( $_addressObject )
{
2014-10-20 08:49:23 +02:00
if ( $_addressObject -> personal && $_addressObject -> mailbox && $_addressObject -> host ) {
2013-07-20 09:23:55 +02:00
return sprintf ( '"%s" <%s@%s>' , $this -> mail_bo -> decode_header ( $_addressObject -> personal ), $_addressObject -> mailbox , $this -> mail_bo -> decode_header ( $_addressObject -> host , 'FORCE' ));
2014-10-20 08:49:23 +02:00
} elseif ( $_addressObject -> mailbox && $_addressObject -> host ) {
2013-07-20 09:23:55 +02:00
return sprintf ( " %s@%s " , $_addressObject -> mailbox , $this -> mail_bo -> decode_header ( $_addressObject -> host , 'FORCE' ));
} else {
return $this -> mail_bo -> decode_header ( $_addressObject -> mailbox , true );
}
}
2014-11-21 10:33:34 +01:00
/**
* create a unique id , to keep track of different compose windows
*/
function generateComposeID ()
2013-07-20 09:23:55 +02:00
{
2014-11-21 10:33:34 +01:00
return mail_bo :: getRandomString ();
2013-07-20 09:23:55 +02:00
}
// $_mode can be:
// single: for a reply to one address
// all: for a reply to all
function getDraftData ( $_icServer , $_folder , $_uid , $_partID = NULL )
{
2014-11-20 18:53:52 +01:00
unset ( $_icServer ); // not used
2013-07-20 09:23:55 +02:00
$this -> sessionData [ 'to' ] = array ();
$mail_bo = $this -> mail_bo ;
$mail_bo -> openConnection ();
$mail_bo -> reopen ( $_folder );
// get message headers for specified message
#$headers = $mail_bo->getMessageHeader($_folder, $_uid);
$headers = $mail_bo -> getMessageEnvelope ( $_uid , $_partID );
2014-02-04 12:31:13 +01:00
//_debug_array($headers); exit;
2013-07-20 09:23:55 +02:00
$addHeadInfo = $mail_bo -> getMessageHeader ( $_uid , $_partID );
//error_log(__METHOD__.__LINE__.array2string($headers));
if ( ! empty ( $addHeadInfo [ 'X-MAILFOLDER' ])) {
foreach ( explode ( '|' , $addHeadInfo [ 'X-MAILFOLDER' ]) as $val ) {
2014-01-24 11:30:45 +01:00
if ( $mail_bo -> folderExists ( $val )) $this -> sessionData [ 'folder' ][] = $val ;
2013-07-20 09:23:55 +02:00
}
}
2014-11-25 00:38:37 +01:00
if ( ! empty ( $addHeadInfo [ 'X-MAILIDENTITY' ])) {
2014-01-24 11:30:45 +01:00
// with the new system it would be the identity
try
{
2014-11-25 00:38:37 +01:00
emailadmin_account :: read_identity ( $addHeadInfo [ 'X-MAILIDENTITY' ]);
$this -> sessionData [ 'mailidentity' ] = $addHeadInfo [ 'X-MAILIDENTITY' ];
2014-01-24 11:30:45 +01:00
}
catch ( Exception $e )
{
}
2013-07-20 09:23:55 +02:00
}
2013-11-22 14:55:09 +01:00
/*
2013-07-20 09:23:55 +02:00
if ( ! empty ( $addHeadInfo [ 'X-STATIONERY' ])) {
$this -> sessionData [ 'stationeryID' ] = $addHeadInfo [ 'X-STATIONERY' ];
}
2013-11-22 14:55:09 +01:00
*/
2014-11-25 00:38:37 +01:00
if ( ! empty ( $addHeadInfo [ 'X-MAILACCOUNT' ])) {
2014-01-24 11:30:45 +01:00
// with the new system it would the identity is the account id
try
{
2014-11-25 00:38:37 +01:00
emailadmin_account :: read ( $addHeadInfo [ 'X-MAILACCOUNT' ]);
$this -> sessionData [ 'mailaccount' ] = $addHeadInfo [ 'X-MAILACCOUNT' ];
2014-01-24 11:30:45 +01:00
}
catch ( Exception $e )
{
// fail silently
$this -> sessionData [ 'mailaccount' ] = $mail_bo -> profileID ;
}
2013-07-20 09:23:55 +02:00
}
// if the message is located within the draft folder, add it as last drafted version (for possible cleanup on abort))
2014-04-01 13:41:34 +02:00
if ( $mail_bo -> isDraftFolder ( $_folder )) $this -> sessionData [ 'lastDrafted' ] = mail_ui :: createRowID ( $_folder , $_uid ); //array('uid'=>$_uid,'folder'=>$_folder);
2013-07-20 09:23:55 +02:00
$this -> sessionData [ 'uid' ] = $_uid ;
$this -> sessionData [ 'messageFolder' ] = $_folder ;
$this -> sessionData [ 'isDraft' ] = true ;
2014-11-20 18:53:52 +01:00
$foundAddresses = array ();
2013-07-20 09:23:55 +02:00
foreach (( array ) $headers [ 'CC' ] as $val ) {
2014-10-18 18:30:39 +02:00
$rfcAddr = emailadmin_imapbase :: parseAddressList ( $val );
2014-01-24 11:30:45 +01:00
$_rfcAddr = $rfcAddr [ 0 ];
2014-10-18 18:30:39 +02:00
if ( ! $_rfcAddr -> valid ) continue ;
2014-10-20 08:49:23 +02:00
if ( $_rfcAddr -> mailbox == 'undisclosed-recipients' || ( ! $_rfcAddr -> mailbox && ! $_rfcAddr -> host ) ) {
2013-07-20 09:23:55 +02:00
continue ;
}
2014-01-24 11:30:45 +01:00
$keyemail = $_rfcAddr -> mailbox . '@' . $_rfcAddr -> host ;
if ( ! $foundAddresses [ $keyemail ]) {
2014-11-20 18:53:52 +01:00
$address = $this -> mail_bo -> decode_header ( $val , true );
2014-01-24 11:30:45 +01:00
$this -> sessionData [ 'cc' ][] = $val ;
$foundAddresses [ $keyemail ] = true ;
2013-07-20 09:23:55 +02:00
}
}
foreach (( array ) $headers [ 'TO' ] as $val ) {
2014-01-15 17:29:30 +01:00
if ( ! is_array ( $val ))
{
$this -> sessionData [ 'to' ][] = $val ;
continue ;
}
2014-10-18 18:30:39 +02:00
$rfcAddr = emailadmin_imapbase :: parseAddressList ( $val );
2014-01-24 11:30:45 +01:00
$_rfcAddr = $rfcAddr [ 0 ];
2014-10-18 18:30:39 +02:00
if ( ! $_rfcAddr -> valid ) continue ;
2014-10-20 08:49:23 +02:00
if ( $_rfcAddr -> mailbox == 'undisclosed-recipients' || ( ! $_rfcAddr -> mailbox && ! $_rfcAddr -> host ) ) {
2013-07-20 09:23:55 +02:00
continue ;
}
2014-01-24 11:30:45 +01:00
$keyemail = $_rfcAddr -> mailbox . '@' . $_rfcAddr -> host ;
if ( ! $foundAddresses [ $keyemail ]) {
2014-11-20 18:53:52 +01:00
$address = $this -> mail_bo -> decode_header ( $val , true );
2014-01-24 11:30:45 +01:00
$this -> sessionData [ 'to' ][] = $val ;
$foundAddresses [ $keyemail ] = true ;
2013-07-20 09:23:55 +02:00
}
}
2014-04-15 12:42:30 +02:00
foreach (( array ) $headers [ 'REPLY-TO' ] as $val ) {
2014-10-18 18:30:39 +02:00
$rfcAddr = emailadmin_imapbase :: parseAddressList ( $val );
2014-01-24 11:30:45 +01:00
$_rfcAddr = $rfcAddr [ 0 ];
2014-10-18 18:30:39 +02:00
if ( ! $_rfcAddr -> valid ) continue ;
2014-01-24 11:30:45 +01:00
if ( $_rfcAddr -> mailbox == 'undisclosed-recipients' || ( empty ( $_rfcAddr -> mailbox ) && empty ( $_rfcAddr -> host )) ) {
2013-07-20 09:23:55 +02:00
continue ;
}
2014-01-24 11:30:45 +01:00
$keyemail = $_rfcAddr -> mailbox . '@' . $_rfcAddr -> host ;
if ( ! $foundAddresses [ $keyemail ]) {
2014-11-20 18:53:52 +01:00
$address = $this -> mail_bo -> decode_header ( $val , true );
2014-01-24 11:30:45 +01:00
$this -> sessionData [ 'replyto' ][] = $val ;
$foundAddresses [ $keyemail ] = true ;
2013-07-20 09:23:55 +02:00
}
}
foreach (( array ) $headers [ 'BCC' ] as $val ) {
2014-10-18 18:30:39 +02:00
$rfcAddr = emailadmin_imapbase :: parseAddressList ( $val );
2014-01-24 11:30:45 +01:00
$_rfcAddr = $rfcAddr [ 0 ];
2014-10-18 18:30:39 +02:00
if ( ! $_rfcAddr -> valid ) continue ;
2014-01-24 11:30:45 +01:00
if ( $_rfcAddr -> mailbox == 'undisclosed-recipients' || ( empty ( $_rfcAddr -> mailbox ) && empty ( $_rfcAddr -> host )) ) {
2013-07-20 09:23:55 +02:00
continue ;
}
2014-01-24 11:30:45 +01:00
$keyemail = $_rfcAddr -> mailbox . '@' . $_rfcAddr -> host ;
if ( ! $foundAddresses [ $keyemail ]) {
2014-11-20 18:53:52 +01:00
$address = $this -> mail_bo -> decode_header ( $val , true );
2014-01-24 11:30:45 +01:00
$this -> sessionData [ 'bcc' ][] = $val ;
$foundAddresses [ $keyemail ] = true ;
2013-07-20 09:23:55 +02:00
}
}
2014-02-04 12:31:13 +01:00
//_debug_array($this->sessionData);
2013-07-20 09:23:55 +02:00
$this -> sessionData [ 'subject' ] = $mail_bo -> decode_header ( $headers [ 'SUBJECT' ]);
// remove a printview tag if composing
$searchfor = '/^\[' . lang ( 'printview' ) . ':\]/' ;
$this -> sessionData [ 'subject' ] = preg_replace ( $searchfor , '' , $this -> sessionData [ 'subject' ]);
2014-05-13 15:10:53 +02:00
$bodyParts = $mail_bo -> getMessageBody ( $_uid , $this -> mailPreferences [ 'always_display' ], $_partID );
2013-07-20 09:23:55 +02:00
//_debug_array($bodyParts);
#$fromAddress = ($headers['FROM'][0]['PERSONAL_NAME'] != 'NIL') ? $headers['FROM'][0]['RFC822_EMAIL'] : $headers['FROM'][0]['EMAIL'];
if ( $bodyParts [ '0' ][ 'mimeType' ] == 'text/html' ) {
$this -> sessionData [ 'mimeType' ] = 'html' ;
for ( $i = 0 ; $i < count ( $bodyParts ); $i ++ ) {
if ( $i > 0 ) {
$this -> sessionData [ 'body' ] .= '<hr>' ;
}
if ( $bodyParts [ $i ][ 'mimeType' ] == 'text/plain' ) {
#$bodyParts[$i]['body'] = nl2br($bodyParts[$i]['body']);
$bodyParts [ $i ][ 'body' ] = " <pre> " . $bodyParts [ $i ][ 'body' ] . " </pre> " ;
}
if ( $bodyParts [ $i ][ 'charSet' ] === false ) $bodyParts [ $i ][ 'charSet' ] = mail_bo :: detect_encoding ( $bodyParts [ $i ][ 'body' ]);
$bodyParts [ $i ][ 'body' ] = translation :: convert ( $bodyParts [ $i ][ 'body' ], $bodyParts [ $i ][ 'charSet' ]);
#error_log( "GetDraftData (HTML) CharSet:".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
$this -> sessionData [ 'body' ] .= ( $i > 0 ? " <br> " : " " ) . $bodyParts [ $i ][ 'body' ] ;
}
} else {
$this -> sessionData [ 'mimeType' ] = 'plain' ;
for ( $i = 0 ; $i < count ( $bodyParts ); $i ++ ) {
if ( $i > 0 ) {
$this -> sessionData [ 'body' ] .= " <hr> " ;
}
if ( $bodyParts [ $i ][ 'charSet' ] === false ) $bodyParts [ $i ][ 'charSet' ] = mail_bo :: detect_encoding ( $bodyParts [ $i ][ 'body' ]);
$bodyParts [ $i ][ 'body' ] = translation :: convert ( $bodyParts [ $i ][ 'body' ], $bodyParts [ $i ][ 'charSet' ]);
#error_log( "GetDraftData (Plain) CharSet".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
$this -> sessionData [ 'body' ] .= ( $i > 0 ? " \r \n " : " " ) . $bodyParts [ $i ][ 'body' ] ;
}
}
2014-10-23 13:28:36 +02:00
if (( $attachments = $mail_bo -> getMessageAttachments ( $_uid , $_partID ))) {
2013-07-20 09:23:55 +02:00
foreach ( $attachments as $attachment ) {
$this -> addMessageAttachment ( $_uid , $attachment [ 'partID' ],
$_folder ,
$attachment [ 'name' ],
$attachment [ 'mimeType' ],
$attachment [ 'size' ]);
}
}
$mail_bo -> closeConnection ();
2013-10-10 13:44:01 +02:00
return $this -> sessionData ;
2013-07-20 09:23:55 +02:00
}
function getErrorInfo ()
{
if ( isset ( $this -> errorInfo )) {
$errorInfo = $this -> errorInfo ;
unset ( $this -> errorInfo );
return $errorInfo ;
}
return false ;
}
function getForwardData ( $_icServer , $_folder , $_uid , $_partID , $_mode = false )
{
if ( $_mode )
{
2014-05-13 15:10:53 +02:00
$modebuff = $this -> mailPreferences [ 'message_forwarding' ];
$this -> mailPreferences [ 'message_forwarding' ] = $_mode ;
2013-07-20 09:23:55 +02:00
}
2014-05-13 15:10:53 +02:00
if ( $this -> mailPreferences [ 'message_forwarding' ] == 'inline' ) {
2013-07-20 09:23:55 +02:00
$this -> getReplyData ( 'forward' , $_icServer , $_folder , $_uid , $_partID );
}
$mail_bo = $this -> mail_bo ;
$mail_bo -> openConnection ();
$mail_bo -> reopen ( $_folder );
// get message headers for specified message
$headers = $mail_bo -> getMessageEnvelope ( $_uid , $_partID );
2013-10-08 16:23:46 +02:00
//error_log(__METHOD__.__LINE__.array2string($headers));
2013-07-20 09:23:55 +02:00
//_debug_array($headers); exit;
// check for Re: in subject header
$this -> sessionData [ 'subject' ] = " [FWD] " . $mail_bo -> decode_header ( $headers [ 'SUBJECT' ]);
2014-04-01 13:41:34 +02:00
// the three attributes below are substituted by processedmail_id and mode
2014-01-23 12:56:34 +01:00
//$this->sessionData['sourceFolder']=$_folder;
//$this->sessionData['forwardFlag']='forwarded';
//$this->sessionData['forwardedUID']=$_uid;
2014-05-13 15:10:53 +02:00
if ( $this -> mailPreferences [ 'message_forwarding' ] == 'asmail' ) {
$this -> sessionData [ 'mimeType' ] = $this -> mailPreferences [ 'composeOptions' ];
2013-07-20 09:23:55 +02:00
if ( $headers [ 'SIZE' ])
$size = $headers [ 'SIZE' ];
else
$size = lang ( 'unknown' );
$this -> addMessageAttachment ( $_uid , $_partID , $_folder ,
2014-07-03 12:16:23 +02:00
$mail_bo -> decode_header (( $headers [ 'SUBJECT' ] ? $headers [ 'SUBJECT' ] : lang ( 'no subject' ))) . '.eml' ,
2013-07-20 09:23:55 +02:00
'MESSAGE/RFC822' , $size );
}
else
{
unset ( $this -> sessionData [ 'in-reply-to' ]);
unset ( $this -> sessionData [ 'to' ]);
unset ( $this -> sessionData [ 'cc' ]);
2014-10-23 13:28:36 +02:00
if (( $attachments = $mail_bo -> getMessageAttachments ( $_uid , $_partID ))) {
2014-01-30 12:28:20 +01:00
//error_log(__METHOD__.__LINE__.':'.array2string($attachments));
2013-07-20 09:23:55 +02:00
foreach ( $attachments as $attachment ) {
$this -> addMessageAttachment ( $_uid , $attachment [ 'partID' ],
$_folder ,
$attachment [ 'name' ],
$attachment [ 'mimeType' ],
$attachment [ 'size' ]);
}
}
}
$mail_bo -> closeConnection ();
if ( $_mode )
{
2014-05-13 15:10:53 +02:00
$this -> mailPreferences [ 'message_forwarding' ] = $modebuff ;
2013-07-20 09:23:55 +02:00
}
2013-10-08 16:23:46 +02:00
//error_log(__METHOD__.__LINE__.array2string($this->sessionData));
return $this -> sessionData ;
}
2014-02-04 12:31:13 +01:00
/**
* adds uploaded files or files in eGW ' s temp directory as attachments
*
* passes the given $_formData representing an attachment to $_content
*
2014-04-15 12:42:30 +02:00
* @ param array $_formData fields of the compose form ( to , cc , bcc , reply - to , subject , body , priority , signature ), plus data of the file ( name , file , size , type )
2014-02-04 12:31:13 +01:00
* @ param array $_content the content passed to the function and to be modified
* @ return void
*/
function addAttachment ( $_formData , & $_content , $eliminateDoubleAttachments = false )
{
2014-03-21 11:37:09 +01:00
//error_log(__METHOD__.__LINE__.' Formdata:'.array2string($_formData).' Content:'.array2string($_content));
2014-02-04 12:31:13 +01:00
$attachfailed = false ;
// to guard against exploits the file must be either uploaded or be in the temp_dir
// check if formdata meets basic restrictions (in tmp dir, or vfs, mimetype, etc.)
try
{
$tmpFileName = mail_bo :: checkFileBasics ( $_formData , $this -> composeID , false );
}
catch ( egw_exception_wrong_userinput $e )
{
$attachfailed = true ;
$alert_msg = $e -> getMessage ();
}
2014-03-21 11:37:09 +01:00
//error_log(__METHOD__.__LINE__.array2string($tmpFileName));
2014-02-04 12:31:13 +01:00
if ( $eliminateDoubleAttachments == true )
2014-11-20 18:53:52 +01:00
{
foreach (( array ) $_content [ 'attachments' ] as $attach )
{
2014-02-04 12:31:13 +01:00
if ( $attach [ 'name' ] && $attach [ 'name' ] == $_formData [ 'name' ] &&
strtolower ( $_formData [ 'type' ]) == strtolower ( $attach [ 'type' ]) &&
stripos ( $_formData [ 'file' ], 'vfs://' ) !== false ) return ;
2014-11-20 18:53:52 +01:00
}
}
2014-02-04 12:31:13 +01:00
if ( $attachfailed === false )
{
$buffer = array (
'name' => $_formData [ 'name' ],
'type' => $_formData [ 'type' ],
'file' => $tmpFileName ,
2014-03-21 13:56:34 +01:00
'tmp_name' => $tmpFileName ,
2014-02-04 12:31:13 +01:00
'size' => $_formData [ 'size' ]
);
if ( ! is_array ( $_content [ 'attachments' ])) $_content [ 'attachments' ] = array ();
2014-03-21 11:37:09 +01:00
$_content [ 'attachments' ][] = $buffer ;
2014-02-04 12:31:13 +01:00
unset ( $buffer );
}
else
{
error_log ( __METHOD__ . __LINE__ . array2string ( $alert_msg ));
}
}
2013-10-08 16:23:46 +02:00
function addMessageAttachment ( $_uid , $_partID , $_folder , $_name , $_type , $_size )
{
$this -> sessionData [ 'attachments' ][] = array (
'uid' => $_uid ,
'partID' => $_partID ,
'name' => $_name ,
'type' => $_type ,
'size' => $_size ,
2014-01-31 11:21:58 +01:00
'folder' => $_folder ,
2014-03-17 13:54:01 +01:00
'tmp_name' => mail_ui :: generateRowID ( $this -> mail_bo -> profileID , $_folder , $_uid ) . '_' . ( ! empty ( $_partID ) ? $_partID : count ( $this -> sessionData [ 'attachments' ]) + 1 ),
2013-10-08 16:23:46 +02:00
);
2013-07-20 09:23:55 +02:00
}
2014-01-30 10:35:56 +01:00
function getAttachment ()
{
if ( isset ( $_GET [ 'tmpname' ])) $attachment [ 'tmp_name' ] = $_GET [ 'tmpname' ];
if ( isset ( $_GET [ 'name' ])) $attachment [ 'name' ] = $_GET [ 'name' ];
//if(isset($_GET['size'])) $attachment['size'] = $_GET['size'];
if ( isset ( $_GET [ 'type' ])) $attachment [ 'type' ] = $_GET [ 'type' ];
2014-01-31 11:21:58 +01:00
//error_log(__METHOD__.__LINE__.array2string($_GET));
2014-10-20 20:08:03 +02:00
if ( isset ( $attachment [ 'tmp_name' ]) && parse_url ( $attachment [ 'tmp_name' ], PHP_URL_SCHEME ) == 'vfs' )
2014-01-30 10:35:56 +01:00
{
egw_vfs :: load_wrapper ( 'vfs' );
2014-10-20 20:08:03 +02:00
$attachment [ 'attachment' ] = file_get_contents ( $attachment [ 'tmp_name' ]);
}
// attachment data in temp_dir, only use basename of given name, to not allow path traversal
elseif ( ! file_exists ( $tmp_path = $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ] . SEP . basename ( $attachment [ 'tmp_name' ])))
{
header ( 'HTTP/1.1 404 Not found' );
die ( 'Attachment ' . htmlspecialchars ( $attachment [ 'tmp_name' ]) . ' NOT found!' );
}
else
{
$attachment [ 'attachment' ] = file_get_contents ( $tmp_path );
2014-01-30 10:35:56 +01:00
}
//error_log(__METHOD__.__LINE__.' FileSize:'.filesize($attachment['tmp_name']));
if ( $_GET [ 'mode' ] != " save " )
{
if ( strtoupper ( $attachment [ 'type' ]) == 'TEXT/DIRECTORY' )
{
$sfxMimeType = $attachment [ 'type' ];
2014-10-20 20:08:03 +02:00
$buff = explode ( '.' , $attachment [ 'tmp_name' ]);
2014-01-30 10:35:56 +01:00
$suffix = '' ;
if ( is_array ( $buff )) $suffix = array_pop ( $buff ); // take the last extension to check with ext2mime
if ( ! empty ( $suffix )) $sfxMimeType = mime_magic :: ext2mime ( $suffix );
$attachment [ 'type' ] = $sfxMimeType ;
if ( strtoupper ( $sfxMimeType ) == 'TEXT/VCARD' || strtoupper ( $sfxMimeType ) == 'TEXT/X-VCARD' ) $attachment [ 'type' ] = strtoupper ( $sfxMimeType );
}
//error_log(__METHOD__.print_r($attachment,true));
if ( strtoupper ( $attachment [ 'type' ]) == 'TEXT/CALENDAR' || strtoupper ( $attachment [ 'type' ]) == 'TEXT/X-VCALENDAR' )
{
//error_log(__METHOD__."about to call calendar_ical");
$calendar_ical = new calendar_ical ();
$eventid = $calendar_ical -> search ( $attachment [ 'attachment' ], - 1 );
//error_log(__METHOD__.array2string($eventid));
if ( ! $eventid ) $eventid = - 1 ;
$event = $calendar_ical -> importVCal ( $attachment [ 'attachment' ],( is_array ( $eventid ) ? $eventid [ 0 ] : $eventid ), null , true );
//error_log(__METHOD__.$event);
if (( int ) $event > 0 )
{
$vars = array (
'menuaction' => 'calendar.calendar_uiforms.edit' ,
'cal_id' => $event ,
);
$GLOBALS [ 'egw' ] -> redirect_link ( '../index.php' , $vars );
}
//Import failed, download content anyway
}
if ( strtoupper ( $attachment [ 'type' ]) == 'TEXT/X-VCARD' || strtoupper ( $attachment [ 'type' ]) == 'TEXT/VCARD' )
{
$addressbook_vcal = new addressbook_vcal ();
// double \r\r\n seems to end a vcard prematurely, so we set them to \r\n
//error_log(__METHOD__.__LINE__.$attachment['attachment']);
$attachment [ 'attachment' ] = str_replace ( " \r \r \n " , " \r \n " , $attachment [ 'attachment' ]);
$vcard = $addressbook_vcal -> vcardtoegw ( $attachment [ 'attachment' ]);
if ( $vcard [ 'uid' ])
{
$vcard [ 'uid' ] = trim ( $vcard [ 'uid' ]);
//error_log(__METHOD__.__LINE__.print_r($vcard,true));
$contact = $addressbook_vcal -> find_contact ( $vcard , false );
}
if ( ! $contact ) $contact = null ;
// if there are not enough fields in the vcard (or the parser was unable to correctly parse the vcard (as of VERSION:3.0 created by MSO))
if ( $contact || count ( $vcard ) > 2 )
{
$contact = $addressbook_vcal -> addVCard ( $attachment [ 'attachment' ],( is_array ( $contact ) ? array_shift ( $contact ) : $contact ), true );
}
if (( int ) $contact > 0 )
{
$vars = array (
'menuaction' => 'addressbook.addressbook_ui.edit' ,
'contact_id' => $contact ,
);
$GLOBALS [ 'egw' ] -> redirect_link ( '../index.php' , $vars );
}
//Import failed, download content anyway
}
}
2014-02-12 11:56:44 +01:00
//error_log(__METHOD__.__LINE__.'->'.array2string($attachment));
2014-10-20 20:08:03 +02:00
html :: content_header ( $attachment [ 'name' ], $attachment [ 'type' ], 0 , True , $_GET [ 'mode' ] == " save " );
2014-01-30 10:35:56 +01:00
echo $attachment [ 'attachment' ];
2014-10-20 20:08:03 +02:00
common :: egw_exit ();
2014-01-30 10:35:56 +01:00
}
2013-07-20 09:23:55 +02:00
/**
2014-11-21 10:33:34 +01:00
* Test if string contains one of the keys of an array
2014-11-20 18:53:52 +01:00
*
2013-11-20 16:05:25 +01:00
* @ param array arrayToTestAgainst to test its keys against haystack
* @ param string haystack
* @ return boolean
*/
function testIfOneKeyInArrayDoesExistInString ( $arrayToTestAgainst , $haystack ) {
2014-11-20 18:53:52 +01:00
foreach ( array_keys ( $arrayToTestAgainst ) as $k )
2013-11-20 16:05:25 +01:00
{
//error_log(__METHOD__.__LINE__.':'.$k.'<->'.$haystack);
if ( stripos ( $haystack , $k ) !== false )
{
//error_log(__METHOD__.__LINE__.':FOUND:'.$k.'<->'.$haystack.function_backtrace());
return true ;
}
}
return false ;
}
2013-07-20 09:23:55 +02:00
/**
2014-11-20 18:53:52 +01:00
* Gather the replyData and save it with the session , to be used then
*
2013-07-20 09:23:55 +02:00
* @ param $_mode can be :
* single : for a reply to one address
* all : for a reply to all
* forward : inlineforwarding of a message with its attachments
* @ param $_icServer number ( 0 as it is the active Profile )
* @ param $_folder string
* @ param $_uid number
* @ param $_partID number
*/
function getReplyData ( $_mode , $_icServer , $_folder , $_uid , $_partID )
{
2014-11-20 18:53:52 +01:00
unset ( $_icServer ); // not used
2013-07-20 09:23:55 +02:00
$foundAddresses = array ();
2013-11-20 16:05:25 +01:00
$mail_bo = $this -> mail_bo ;
2013-07-20 09:23:55 +02:00
$mail_bo -> openConnection ();
$mail_bo -> reopen ( $_folder );
2013-12-17 10:55:47 +01:00
$userEMailAddresses = $mail_bo -> getUserEMailAddresses ();
2013-07-20 09:23:55 +02:00
// get message headers for specified message
2013-10-05 16:15:29 +02:00
//print "AAAA: $_folder, $_uid, $_partID<br>";
2014-04-15 12:42:30 +02:00
$headers = $mail_bo -> getMessageEnvelope ( $_uid , $_partID , false , $_folder , $useHeaderInsteadOfEnvelope = true );
//$headers = $mail_bo->getMessageHeader($_uid, $_partID, true, true, $_folder);
2013-07-20 09:23:55 +02:00
$this -> sessionData [ 'uid' ] = $_uid ;
$this -> sessionData [ 'messageFolder' ] = $_folder ;
2014-09-09 16:04:40 +02:00
$this -> sessionData [ 'in-reply-to' ] = ( $headers [ 'IN-REPLY-TO' ] ? $headers [ 'IN-REPLY-TO' ] : $headers [ 'MESSAGE_ID' ]);
$this -> sessionData [ 'references' ] = ( $headers [ 'REFERENCES' ] ? $headers [ 'REFERENCES' ] : $headers [ 'MESSAGE_ID' ]);
2014-09-11 13:51:07 +02:00
if ( $headers [ 'THREAD-TOPIC' ]) $this -> sessionData [ 'thread-topic' ] = $headers [ 'THREAD-TOPIC' ];
if ( $headers [ 'THREAD-INDEX' ]) $this -> sessionData [ 'thread-index' ] = $headers [ 'THREAD-INDEX' ];
if ( $headers [ 'LIST-ID' ]) $this -> sessionData [ 'list-id' ] = $headers [ 'LIST-ID' ];
2014-01-24 11:30:45 +01:00
//error_log(__METHOD__.__LINE__.' Mode:'.$_mode.':'.array2string($headers));
2013-07-20 09:23:55 +02:00
// check for Reply-To: header and use if available
2014-04-15 12:42:30 +02:00
if ( ! empty ( $headers [ 'REPLY-TO' ]) && ( $headers [ 'REPLY-TO' ] != $headers [ 'FROM' ])) {
foreach ( $headers [ 'REPLY-TO' ] as $val ) {
2013-11-20 16:05:25 +01:00
if ( ! $foundAddresses [ $val ]) {
$oldTo [] = $val ;
$foundAddresses [ $val ] = true ;
2013-07-20 09:23:55 +02:00
}
}
2014-04-15 12:42:30 +02:00
$oldToAddress = ( is_array ( $headers [ 'REPLY-TO' ]) ? $headers [ 'REPLY-TO' ][ 0 ] : $headers [ 'REPLY-TO' ]);
2013-07-20 09:23:55 +02:00
} else {
foreach ( $headers [ 'FROM' ] as $val ) {
2013-11-20 16:05:25 +01:00
if ( ! $foundAddresses [ $val ]) {
$oldTo [] = $val ;
$foundAddresses [ $val ] = true ;
2013-07-20 09:23:55 +02:00
}
}
2014-01-24 11:30:45 +01:00
$oldToAddress = ( is_array ( $headers [ 'FROM' ]) ? $headers [ 'FROM' ][ 0 ] : $headers [ 'FROM' ]);
2013-07-20 09:23:55 +02:00
}
2013-11-20 16:05:25 +01:00
//error_log(__METHOD__.__LINE__.' OldToAddress:'.$oldToAddress.'#');
if ( $_mode != 'all' || ( $_mode == 'all' && ! empty ( $oldToAddress ) && ! $this -> testIfOneKeyInArrayDoesExistInString ( $userEMailAddresses , $oldToAddress )) ) {
2013-07-20 09:23:55 +02:00
$this -> sessionData [ 'to' ] = $oldTo ;
}
if ( $_mode == 'all' ) {
// reply to any address which is cc, but not to my self
#if($headers->cc) {
foreach ( $headers [ 'CC' ] as $val ) {
2013-11-20 16:05:25 +01:00
if ( $this -> testIfOneKeyInArrayDoesExistInString ( $userEMailAddresses , $val )) {
2013-07-20 09:23:55 +02:00
continue ;
}
2013-11-20 16:05:25 +01:00
if ( ! $foundAddresses [ $val ]) {
$this -> sessionData [ 'cc' ][] = $val ;
$foundAddresses [ $val ] = true ;
2013-07-20 09:23:55 +02:00
}
}
#}
// reply to any address which is to, but not to my self
#if($headers->to) {
foreach ( $headers [ 'TO' ] as $val ) {
2013-11-20 16:05:25 +01:00
if ( $this -> testIfOneKeyInArrayDoesExistInString ( $userEMailAddresses , $val )) {
2013-07-20 09:23:55 +02:00
continue ;
}
2013-11-20 16:05:25 +01:00
if ( ! $foundAddresses [ $val ]) {
$this -> sessionData [ 'to' ][] = $val ;
$foundAddresses [ $val ] = true ;
2013-07-20 09:23:55 +02:00
}
}
#}
#if($headers->from) {
foreach ( $headers [ 'FROM' ] as $val ) {
2013-11-20 16:05:25 +01:00
if ( $this -> testIfOneKeyInArrayDoesExistInString ( $userEMailAddresses , $val )) {
2013-07-20 09:23:55 +02:00
continue ;
}
2013-11-20 16:05:25 +01:00
//error_log(__METHOD__.__LINE__.' '.$val);
if ( ! $foundAddresses [ $val ]) {
$this -> sessionData [ 'to' ][] = $val ;
$foundAddresses [ $val ] = true ;
2013-07-20 09:23:55 +02:00
}
}
#}
}
// check for Re: in subject header
if ( strtolower ( substr ( trim ( $mail_bo -> decode_header ( $headers [ 'SUBJECT' ])), 0 , 3 )) == " re: " ) {
$this -> sessionData [ 'subject' ] = $mail_bo -> decode_header ( $headers [ 'SUBJECT' ]);
} else {
$this -> sessionData [ 'subject' ] = " Re: " . $mail_bo -> decode_header ( $headers [ 'SUBJECT' ]);
}
//_debug_array($headers);
2014-05-13 15:10:53 +02:00
//error_log(__METHOD__.__LINE__.'->'.array2string($this->mailPreferences['htmlOptions']));
$bodyParts = $mail_bo -> getMessageBody ( $_uid , ( $this -> mailPreferences [ 'htmlOptions' ] ? $this -> mailPreferences [ 'htmlOptions' ] : '' ), $_partID );
2013-07-20 09:23:55 +02:00
//_debug_array($bodyParts);
$styles = mail_bo :: getStyles ( $bodyParts );
2014-09-30 14:36:46 +02:00
$fromAddress = implode ( ', ' , str_replace ( array ( '<' , '>' ), array ( '[' , ']' ), $headers [ 'FROM' ]));
2013-07-20 09:23:55 +02:00
$toAddressA = array ();
$toAddress = '' ;
foreach ( $headers [ 'TO' ] as $mailheader ) {
2013-11-20 16:05:25 +01:00
$toAddressA [] = $mailheader ;
2013-07-20 09:23:55 +02:00
}
if ( count ( $toAddressA ) > 0 )
{
2014-09-30 14:36:46 +02:00
$toAddress = implode ( ', ' , str_replace ( array ( '<' , '>' ), array ( '[' , ']' ), $toAddressA ));
2013-07-20 09:23:55 +02:00
$toAddress = @ htmlspecialchars ( lang ( " to " )) . " : " . $toAddress . ( $bodyParts [ '0' ][ 'mimeType' ] == 'text/html' ? " <br> " : " \r \n " );
}
$ccAddressA = array ();
$ccAddress = '' ;
foreach ( $headers [ 'CC' ] as $mailheader ) {
2013-11-20 16:05:25 +01:00
$ccAddressA [] = $mailheader ;
2013-07-20 09:23:55 +02:00
}
if ( count ( $ccAddressA ) > 0 )
{
2014-09-30 14:36:46 +02:00
$ccAddress = implode ( ', ' , str_replace ( array ( '<' , '>' ), array ( '[' , ']' ), $ccAddressA ));
2013-07-20 09:23:55 +02:00
$ccAddress = @ htmlspecialchars ( lang ( " cc " )) . " : " . $ccAddress . ( $bodyParts [ '0' ][ 'mimeType' ] == 'text/html' ? " <br> " : " \r \n " );
}
if ( $bodyParts [ '0' ][ 'mimeType' ] == 'text/html' ) {
$this -> sessionData [ 'body' ] = /*"<br>".*/ /*" ".*/ " <div> " . '----------------' . lang ( " original message " ) . '-----------------' . " " . '<br>' .
@ htmlspecialchars ( lang ( " from " )) . " : " . $fromAddress . " <br> " .
$toAddress . $ccAddress .
@ htmlspecialchars ( lang ( " date " ) . " : " . $headers [ 'DATE' ], ENT_QUOTES | ENT_IGNORE , mail_bo :: $displayCharset , false ) . " <br> " .
'----------------------------------------------------------' . " </div> " ;
$this -> sessionData [ 'mimeType' ] = 'html' ;
if ( ! empty ( $styles )) $this -> sessionData [ 'body' ] .= $styles ;
$this -> sessionData [ 'body' ] .= '<blockquote type="cite">' ;
for ( $i = 0 ; $i < count ( $bodyParts ); $i ++ ) {
if ( $i > 0 ) {
$this -> sessionData [ 'body' ] .= '<hr>' ;
}
if ( $bodyParts [ $i ][ 'mimeType' ] == 'text/plain' ) {
#$bodyParts[$i]['body'] = nl2br($bodyParts[$i]['body'])."<br>";
$bodyParts [ $i ][ 'body' ] = " <pre> " . $bodyParts [ $i ][ 'body' ] . " </pre> " ;
}
if ( $bodyParts [ $i ][ 'charSet' ] === false ) $bodyParts [ $i ][ 'charSet' ] = mail_bo :: detect_encoding ( $bodyParts [ $i ][ 'body' ]);
$_htmlConfig = mail_bo :: $htmLawed_config ;
mail_bo :: $htmLawed_config [ 'comment' ] = 2 ;
mail_bo :: $htmLawed_config [ 'transform_anchor' ] = false ;
$this -> sessionData [ 'body' ] .= " <br> " . self :: _getCleanHTML ( translation :: convert ( $bodyParts [ $i ][ 'body' ], $bodyParts [ $i ][ 'charSet' ]));
mail_bo :: $htmLawed_config = $_htmlConfig ;
#error_log( "GetReplyData (HTML) CharSet:".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
}
$this -> sessionData [ 'body' ] .= '</blockquote><br>' ;
} else {
//$this->sessionData['body'] = @htmlspecialchars(lang("on")." ".$headers['DATE']." ".$mail_bo->decode_header($fromAddress), ENT_QUOTES) . " ".lang("wrote").":\r\n";
// take care the way the ReplyHeader is created here, is used later on in uicompose::compose, in case you force replys to be HTML (prefs)
$this -> sessionData [ 'body' ] = " \r \n \r \n " . '----------------' . lang ( " original message " ) . '-----------------' . " \r \n " .
@ htmlspecialchars ( lang ( " from " )) . " : " . $fromAddress . " \r \n " .
$toAddress . $ccAddress .
@ htmlspecialchars ( lang ( " date " ) . " : " . $headers [ 'DATE' ], ENT_QUOTES | ENT_IGNORE , mail_bo :: $displayCharset , false ) . " \r \n " .
'-------------------------------------------------' . " \r \n \r \n " ;
$this -> sessionData [ 'mimeType' ] = 'plain' ;
for ( $i = 0 ; $i < count ( $bodyParts ); $i ++ ) {
if ( $i > 0 ) {
$this -> sessionData [ 'body' ] .= " <hr> " ;
}
// add line breaks to $bodyParts
if ( $bodyParts [ $i ][ 'charSet' ] === false ) $bodyParts [ $i ][ 'charSet' ] = mail_bo :: detect_encoding ( $bodyParts [ $i ][ 'body' ]);
$newBody = translation :: convert ( $bodyParts [ $i ][ 'body' ], $bodyParts [ $i ][ 'charSet' ]);
#error_log( "GetReplyData (Plain) CharSet:".mb_detect_encoding($bodyParts[$i]['body'] . 'a' , strtoupper($bodyParts[$i]['charSet']).','.strtoupper($this->displayCharset).',UTF-8, ISO-8859-1'));
$this -> sessionData [ 'body' ] .= " \r \n " ;
// create body new, with good line breaks and indention
2014-11-20 18:53:52 +01:00
foreach ( explode ( " \n " , $newBody ) as $value ) {
2013-07-20 09:23:55 +02:00
// the explode is removing the character
if ( trim ( $value ) != '' ) {
#if ($value != "\r") $value .= "\n";
}
$numberOfChars = strspn ( trim ( $value ), " > " );
$appendString = str_repeat ( '>' , $numberOfChars + 1 );
$bodyAppend = $this -> mail_bo -> wordwrap ( $value , 76 - strlen ( " \r \n $appendString " ), " \r \n $appendString " , '>' );
if ( $bodyAppend [ 0 ] == '>' ) {
$bodyAppend = '>' . $bodyAppend ;
} else {
$bodyAppend = '> ' . $bodyAppend ;
}
$this -> sessionData [ 'body' ] .= $bodyAppend ;
}
}
}
$mail_bo -> closeConnection ();
2013-10-03 12:05:05 +02:00
return $this -> sessionData ;
2013-07-20 09:23:55 +02:00
}
static function _getCleanHTML ( $_body , $usepurify = false , $cleanTags = true )
{
static $nonDisplayAbleCharacters = array ( '[\016]' , '[\017]' ,
'[\020]' , '[\021]' , '[\022]' , '[\023]' , '[\024]' , '[\025]' , '[\026]' , '[\027]' ,
'[\030]' , '[\031]' , '[\032]' , '[\033]' , '[\034]' , '[\035]' , '[\036]' , '[\037]' );
mail_bo :: getCleanHTML ( $_body , $usepurify , $cleanTags );
2014-11-20 18:53:52 +01:00
return preg_replace ( $nonDisplayAbleCharacters , '' , $_body );
2013-07-20 09:23:55 +02:00
}
2014-09-11 16:10:01 +02:00
static function _getHostName ()
{
if ( isset ( $_SERVER [ 'SERVER_NAME' ])) {
$result = $_SERVER [ 'SERVER_NAME' ];
} else {
$result = 'localhost.localdomain' ;
}
return $result ;
}
2014-11-22 14:17:41 +01:00
/**
* Create a message from given data and identity
*
* @ param egw_mailer $_mailObject
* @ param array $_formData
* @ param array $_identity
* @ param boolean $_convertLinks
*/
function createMessage ( egw_mailer $_mailObject , array $_formData , array $_identity , $_convertLinks = false )
2013-07-20 09:23:55 +02:00
{
$mail_bo = $this -> mail_bo ;
2013-11-21 14:22:34 +01:00
$activeMailProfile = emailadmin_account :: read ( $this -> mail_bo -> profileID );
2014-09-11 16:10:01 +02:00
2013-07-20 09:23:55 +02:00
// you need to set the sender, if you work with different identities, since most smtp servers, dont allow
// sending in the name of someone else
2013-11-21 14:22:34 +01:00
if ( $_identity [ 'ident_id' ] != $activeMailProfile [ 'ident_id' ] && ! empty ( $_identity [ 'ident_email' ]) && strtolower ( $activeMailProfile [ 'ident_email' ]) != strtolower ( $_identity [ 'ident_email' ]))
{
error_log ( __METHOD__ . __LINE__ . ' Faking From/SenderInfo for ' . $activeMailProfile [ 'ident_email' ] . ' with ID:' . $activeMailProfile [ 'ident_id' ] . '. Identitiy to use for sending:' . array2string ( $_identity ));
}
2014-11-25 00:38:37 +01:00
$_mailObject -> setFrom ( $_identity [ 'ident_email' ] ? $_identity [ 'ident_email' ] : $activeMailProfile [ 'ident_email' ],
mail_bo :: generateIdentityString ( $_identity , false ));
2014-11-22 14:17:41 +01:00
2014-11-25 00:38:37 +01:00
$_mailObject -> addHeader ( 'X-Priority' , $_formData [ 'priority' ]);
$_mailObject -> addHeader ( 'X-Mailer' , 'EGroupware-Mail' );
2014-11-22 14:17:41 +01:00
if ( ! empty ( $_formData [ 'in-reply-to' ])) {
2014-09-11 13:51:07 +02:00
if ( stripos ( $_formData [ 'in-reply-to' ], '<' ) === false ) $_formData [ 'in-reply-to' ] = '<' . trim ( $_formData [ 'in-reply-to' ]) . '>' ;
2014-11-25 00:38:37 +01:00
//error_log(__METHOD__.__LINE__.'$_mailObject->addHeader(In-Reply-To', $_formData['in-reply-to'].")");
$_mailObject -> addHeader ( 'In-Reply-To' , $_formData [ 'in-reply-to' ]);
2013-07-20 09:23:55 +02:00
}
2014-11-22 14:17:41 +01:00
if ( ! empty ( $_formData [ 'references' ])) {
2014-09-11 13:51:07 +02:00
if ( stripos ( $_formData [ 'references' ], '<' ) === false ) $_formData [ 'references' ] = '<' . trim ( $_formData [ 'references' ]) . '>' ;
2014-11-25 00:38:37 +01:00
//error_log(__METHOD__.__LINE__.'$_mailObject->addHeader(References', $_formData['references'].")");
$_mailObject -> addHeader ( 'References' , $_formData [ 'references' ]);
2014-09-11 11:21:07 +02:00
}
2014-11-22 14:17:41 +01:00
if ( ! empty ( $_formData [ 'thread-topic' ])) {
2014-11-25 00:38:37 +01:00
//error_log(__METHOD__.__LINE__.'$_mailObject->addHeader(Tread-Topic', $_formData['thread-topic'].")");
$_mailObject -> addHeader ( 'Thread-Topic' , $_formData [ 'thread-topic' ]);
2014-09-11 13:51:07 +02:00
}
2014-11-22 14:17:41 +01:00
if ( ! empty ( $_formData [ 'thread-index' ])) {
2014-11-25 00:38:37 +01:00
//error_log(__METHOD__.__LINE__.'$_mailObject->addHeader(Tread-Index', $_formData['thread-index'].")");
$_mailObject -> addHeader ( 'Thread-Index' , $_formData [ 'thread-index' ]);
2014-09-11 13:51:07 +02:00
}
2014-11-22 14:17:41 +01:00
if ( ! empty ( $_formData [ 'list-id' ])) {
2014-11-25 00:38:37 +01:00
//error_log(__METHOD__.__LINE__.'$_mailObject->addHeader(List-Id', $_formData['list-id'].")");
$_mailObject -> addHeader ( 'List-Id' , $_formData [ 'list-id' ]);
2014-09-11 13:51:07 +02:00
}
2014-11-20 16:51:36 +01:00
//error_log(__METHOD__.__LINE__.' notify to:'.$_identity['ident_email'].'->'.array2string($_formData));
if ( $_formData [ 'disposition' ] == 'on' ) {
2014-11-25 00:38:37 +01:00
$_mailObject -> addHeader ( 'Disposition-Notification-To' , $_identity [ 'ident_email' ]);
2013-07-20 09:23:55 +02:00
}
if ( ! empty ( $_identity -> organization ) && ( mail_bo :: $mailConfig [ 'how2displayIdentities' ] == '' || mail_bo :: $mailConfig [ 'how2displayIdentities' ] == 'orgNemail' )) {
2014-11-25 00:38:37 +01:00
$_mailObject -> addHeader ( 'Organization' , $_identity [ 'ident_org' ]);
2013-07-20 09:23:55 +02:00
}
2013-11-21 23:29:57 +01:00
// Expand any mailing lists
2014-11-25 00:38:37 +01:00
foreach ( array ( 'to' , 'cc' , 'bcc' , 'replyto' ) as $field )
2013-11-21 23:29:57 +01:00
{
2014-10-18 18:30:39 +02:00
if ( $field != 'replyto' ) $_formData [ $field ] = self :: resolveEmailAddressList ( $_formData [ $field ]);
2013-07-20 09:23:55 +02:00
2014-11-25 00:38:37 +01:00
if ( $_formData [ $field ]) $_mailObject -> addAddress ( $_formData [ $field ], '' , $field );
2013-07-20 09:23:55 +02:00
}
2014-11-25 00:38:37 +01:00
$_mailObject -> addHeader ( 'Subject' , $_formData [ 'subject' ]);
2013-07-20 09:23:55 +02:00
// this should never happen since we come from the edit dialog
if ( mail_bo :: detect_qp ( $_formData [ 'body' ])) {
2014-10-23 13:28:36 +02:00
//error_log("Error: bocompose::createMessage found QUOTED-PRINTABLE while Composing Message. Charset:$realCharset Message:".print_r($_formData['body'],true));
2013-07-20 09:23:55 +02:00
$_formData [ 'body' ] = preg_replace ( '/=\r\n/' , '' , $_formData [ 'body' ]);
$_formData [ 'body' ] = quoted_printable_decode ( $_formData [ 'body' ]);
}
$disableRuler = false ;
2014-11-22 14:17:41 +01:00
$signature = $_identity [ 'ident_signature' ];
2013-07-20 09:23:55 +02:00
2014-05-13 15:10:53 +02:00
if (( isset ( $this -> mailPreferences [ 'insertSignatureAtTopOfMessage' ]) && $this -> mailPreferences [ 'insertSignatureAtTopOfMessage' ]))
2013-07-20 09:23:55 +02:00
{
// note: if you use stationery ' s the insert signatures at the top does not apply here anymore, as the signature
// is already part of the body, so the signature part of the template will not be applied.
$signature = null ; // note: no signature, no ruler!!!!
}
2014-05-13 15:10:53 +02:00
if (( isset ( $this -> mailPreferences [ 'disableRulerForSignatureSeparation' ]) &&
$this -> mailPreferences [ 'disableRulerForSignatureSeparation' ]) ||
2013-07-20 09:23:55 +02:00
empty ( $signature ) || trim ( $this -> convertHTMLToText ( $signature )) == '' )
{
$disableRuler = true ;
}
if ( $signature )
{
$signature = mail_bo :: merge ( $signature , array ( $GLOBALS [ 'egw' ] -> accounts -> id2name ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ], 'person_id' )));
}
2014-11-25 00:38:37 +01:00
if ( $_formData [ 'mimeType' ] == 'html' )
{
$body = $_formData [ 'body' ];
if ( ! empty ( $signature ))
{
$body .= ( $disableRuler ? '<br>' : '<hr style="border:1px dotted silver; width:90%;">' ) . $signature ;
$_mailObject -> setBody ( $this -> convertHTMLToText ( $_formData [ 'body' ], true , true ) .
2013-07-20 09:23:55 +02:00
( $disableRuler ? " \r \n " : " \r \n -- \r \n " ) .
2014-11-25 00:38:37 +01:00
$this -> convertHTMLToText ( $signature , true , true ));
}
else
{
$body = $_formData [ 'body' ];
$_mailObject -> setBody ( $this -> convertHTMLToText ( $_formData [ 'body' ], true , true ));
2013-07-20 09:23:55 +02:00
}
// convert URL Images to inline images - if possible
2014-11-25 00:38:37 +01:00
if ( $_convertLinks ) mail_bo :: processURL2InlineImages ( $_mailObject , $body );
if ( strpos ( $body , " <!-- HTMLSIGBEGIN --> " ) !== false )
2013-07-20 09:23:55 +02:00
{
2014-11-25 00:38:37 +01:00
$body = str_replace ( array ( '<!-- HTMLSIGBEGIN -->' , '<!-- HTMLSIGEND -->' ), '' , $body );
2013-07-20 09:23:55 +02:00
}
2014-11-25 00:38:37 +01:00
$_mailObject -> setHtmlBody ( $body , null , false ); // false = no automatic alternative, we called setBody()
2013-07-20 09:23:55 +02:00
} else {
2014-11-25 00:38:37 +01:00
$body = $this -> convertHTMLToText ( $_formData [ 'body' ], false );
2013-07-20 09:23:55 +02:00
#$_mailObject->Body = $_formData['body'];
if ( ! empty ( $signature )) {
2014-11-25 00:38:37 +01:00
$body .= ( $disableRuler ? " \r \n " : " \r \n -- \r \n " ) .
2013-07-20 09:23:55 +02:00
$this -> convertHTMLToText ( $signature , true , true );
}
2014-11-25 00:38:37 +01:00
$_mailObject -> setBody ( $body );
2013-07-20 09:23:55 +02:00
}
// add the attachments
2013-10-08 16:23:46 +02:00
if ( is_array ( $_formData ) && isset ( $_formData [ 'attachments' ]))
2013-07-20 09:23:55 +02:00
{
2014-11-25 00:38:37 +01:00
$connection_opened = false ;
2014-01-30 12:28:20 +01:00
//error_log(__METHOD__.__LINE__.array2string($_formData['attachments']));
2013-07-20 09:23:55 +02:00
$tnfattachments = null ;
2013-10-08 16:23:46 +02:00
foreach (( array ) $_formData [ 'attachments' ] as $attachment ) {
2013-07-20 09:23:55 +02:00
if ( is_array ( $attachment ))
{
if ( ! empty ( $attachment [ 'uid' ]) && ! empty ( $attachment [ 'folder' ])) {
2014-01-30 12:28:20 +01:00
/* Example :
Array ([ 0 ] => Array (
[ uid ] => 21178
[ partID ] => 2
[ name ] => [ Untitled ] . pdf
[ type ] => application / pdf
[ size ] => 622379
[ folder ] => INBOX ))
*/
2014-11-25 00:38:37 +01:00
if ( ! $connection_opened )
{
$mail_bo -> openConnection ();
$connection_opened = true ;
}
2013-07-20 09:23:55 +02:00
$mail_bo -> reopen ( $attachment [ 'folder' ]);
switch ( $attachment [ 'type' ]) {
case 'MESSAGE/RFC822' :
$rawHeader = '' ;
if ( isset ( $attachment [ 'partID' ])) {
2014-01-30 12:28:20 +01:00
$rawHeader = $mail_bo -> getMessageRawHeader ( $attachment [ 'uid' ], $attachment [ 'partID' ], $attachment [ 'folder' ]);
2013-07-20 09:23:55 +02:00
}
2014-01-30 12:28:20 +01:00
$rawBody = $mail_bo -> getMessageRawBody ( $attachment [ 'uid' ], $attachment [ 'partID' ], $attachment [ 'folder' ]);
2014-11-25 00:38:37 +01:00
$_mailObject -> AddStringAttachment ( $rawHeader . $rawBody , $attachment [ 'name' ], '7bit' , 'message/rfc822' );
2013-07-20 09:23:55 +02:00
break ;
default :
2014-01-30 12:28:20 +01:00
$attachmentData = $mail_bo -> getAttachment ( $attachment [ 'uid' ], $attachment [ 'partID' ], 0 , false );
2013-07-20 09:23:55 +02:00
if ( $attachmentData [ 'type' ] == 'APPLICATION/MS-TNEF' )
{
if ( ! is_array ( $tnfattachments )) $tnfattachments = $mail_bo -> decode_winmail ( $attachment [ 'uid' ], $attachment [ 'partID' ]);
foreach ( $tnfattachments as $k )
{
if ( $k [ 'name' ] == $attachment [ 'name' ])
{
$tnfpart = $mail_bo -> decode_winmail ( $attachment [ 'uid' ], $attachment [ 'partID' ], $k [ 'is_winmail' ]);
$attachmentData [ 'attachment' ] = $tnfpart [ 'attachment' ];
//error_log(__METHOD__.__LINE__.$k['name'].'<->'.$attachment['name'].':'.array2string($attachmentData['attachment']));
break ;
}
}
}
2014-11-25 00:38:37 +01:00
$_mailObject -> AddStringAttachment ( $attachmentData [ 'attachment' ], $attachment [ 'name' ], 'base64' , $attachment [ 'type' ]);
2013-07-20 09:23:55 +02:00
break ;
}
2014-10-20 20:08:03 +02:00
}
else
{
2013-07-20 09:23:55 +02:00
if ( isset ( $attachment [ 'file' ]) && parse_url ( $attachment [ 'file' ], PHP_URL_SCHEME ) == 'vfs' )
{
egw_vfs :: load_wrapper ( 'vfs' );
2014-10-20 20:08:03 +02:00
$tmp_path = $attachment [ 'file' ];
}
else // non-vfs file has to be in temp_dir
{
$tmp_path = $GLOBALS [ 'egw_info' ][ 'server' ][ 'temp_dir' ] . SEP . basename ( $attachment [ 'file' ]);
2013-07-20 09:23:55 +02:00
}
2014-11-25 00:38:37 +01:00
$_mailObject -> AddAttachment (
$tmp_path ,
$attachment [ 'name' ],
strtoupper ( $attachment [ 'type' ]) == 'MESSAGE/RFC822' ? '7bit' : 'base64' ,
$attachment [ 'type' ]
);
2013-07-20 09:23:55 +02:00
}
}
}
2014-11-25 00:38:37 +01:00
if ( $connection_opened ) $mail_bo -> closeConnection ();
2013-07-20 09:23:55 +02:00
}
}
2014-09-30 14:36:46 +02:00
2014-09-12 13:52:38 +02:00
/**
* Save compose mail as draft
*
* @ param array $content content sent from client - side
*/
public function ajax_saveAsDraft ( $content )
{
$response = egw_json_response :: get ();
$success = true ;
2014-09-30 14:36:46 +02:00
2014-09-12 13:52:38 +02:00
// check if default account is changed then we need to change profile
if ( ! empty ( $content [ 'serverID' ]) && $content [ 'serverID' ] != $this -> mail_bo -> profileID )
{
$this -> changeProfile ( $content [ 'serverID' ]);
}
2014-09-30 14:36:46 +02:00
2014-09-12 13:52:38 +02:00
$formData = array_merge ( $content , array (
2014-11-25 00:38:37 +01:00
'isDrafted' => 1 ,
'body' => $content [ 'mail_' . ( $content [ 'mimeType' ] ? 'htmltext' : 'plaintext' )],
'mimeType' => $content [ 'mimeType' ] ? 'html' : 'plain' // checkbox has only true|false value
2014-09-12 13:52:38 +02:00
));
2014-09-30 14:36:46 +02:00
2014-09-12 13:52:38 +02:00
//Saving draft procedure
try
{
$folder = $this -> mail_bo -> getDraftFolder ();
$this -> mail_bo -> reopen ( $folder );
$status = $this -> mail_bo -> getFolderStatus ( $folder );
if (( $messageUid = $this -> saveAsDraft ( $formData , $folder )))
{
// saving as draft, does not mean closing the message
$messageUid = ( $messageUid === true ? $status [ 'uidnext' ] : $messageUid );
if ( is_array ( $this -> mail_bo -> getMessageHeader ( $messageUid , '' , false , false , $folder )))
{
$draft_id = mail_ui :: createRowID ( $folder , $messageUid );
if ( $content [ 'lastDrafted' ] != $draft_id && isset ( $content [ 'lastDrafted' ]))
{
$dhA = mail_ui :: splitRowID ( $content [ 'lastDrafted' ]);
$duid = $dhA [ 'msgUID' ];
$dmailbox = $dhA [ 'folder' ];
try
{
$this -> mail_bo -> deleteMessages ( $duid , $dmailbox , 'remove_immediately' );
}
catch ( egw_exception $e )
{
$msg = str_replace ( '"' , " ' " , $e -> getMessage ());
$success = false ;
error_log ( __METHOD__ . __LINE__ . $msg );
}
}
}
}
else
{
throw new egw_exception_wrong_userinput ( lang ( " Error: Could not save Message as Draft " ));
}
}
catch ( egw_exception_wrong_userinput $e )
{
$msg = str_replace ( '"' , " ' " , $e -> getMessage ());
error_log ( __METHOD__ . __LINE__ . $msg );
$success = false ;
}
if ( $success ) $msg = lang ( 'Message saved successfully.' );
2014-09-30 14:36:46 +02:00
2014-09-12 13:52:38 +02:00
// Include new information to json respose, because we need them in client-side callback
$response -> data ( array (
'draftedId' => $draft_id ,
'message' => $msg ,
2014-09-22 11:07:48 +02:00
'success' => $success ,
'draftfolder' => $this -> mail_bo -> profileID . mail_ui :: $delimiter . $this -> mail_bo -> getDraftFolder ()
2014-09-12 13:52:38 +02:00
));
}
2014-09-23 10:23:10 +02:00
/**
* resolveEmailAddressList
* @ param array $_emailAddressList list of emailaddresses , may contain distributionlists
* @ return array return the list of emailaddresses with distributionlists resolved
*/
static function resolveEmailAddressList ( $_emailAddressList )
{
$addrFromList = array ();
2014-11-25 00:38:37 +01:00
foreach (( array ) $_emailAddressList as $ak => $address )
{
2014-09-23 10:23:10 +02:00
if ( is_int ( $address ))
{
// List was selected, expand to addresses
unset ( $_emailAddressList [ $ak ]);
$list = $GLOBALS [ 'egw' ] -> contacts -> search ( '' , array ( 'n_fn' , 'n_prefix' , 'n_given' , 'n_family' , 'org_name' , 'email' , 'email_home' ), '' , '' , '' , False , 'AND' , false , array ( 'list' => ( int ) $address ));
// Just add email addresses, they'll be checked below
foreach ( $list as $email )
{
$addrFromList [] = $email [ 'email' ] ? $email [ 'email' ] : $email [ 'email_home' ];
}
}
}
if ( ! empty ( $addrFromList ))
{
foreach ( $addrFromList as $addr )
{
if ( ! empty ( $addr )) $_emailAddressList [] = $addr ;
}
}
return $_emailAddressList ;
}
2014-09-30 14:36:46 +02:00
2014-09-12 13:52:38 +02:00
/**
* Save message as draft to specific folder
*
* @ param type $_formData content
* @ param type $savingDestination destination folder
* @ return boolean return messageUID | false due to an error
*/
2013-07-20 09:23:55 +02:00
function saveAsDraft ( $_formData , & $savingDestination = '' )
{
$mail_bo = $this -> mail_bo ;
2014-11-25 00:38:37 +01:00
$mail = new egw_mailer ( $this -> mail_bo -> profileID );
2013-07-20 09:23:55 +02:00
// preserve the bcc and if possible the save to folder information
$this -> sessionData [ 'folder' ] = $_formData [ 'folder' ];
$this -> sessionData [ 'bcc' ] = $_formData [ 'bcc' ];
2014-11-25 00:38:37 +01:00
$this -> sessionData [ 'mailidentity' ] = $_formData [ 'mailidentity' ];
2013-11-22 14:55:09 +01:00
//$this->sessionData['stationeryID'] = $_formData['stationeryID'];
2014-01-13 16:40:34 +01:00
$this -> sessionData [ 'mailaccount' ] = $_formData [ 'mailaccount' ];
2013-10-10 18:11:26 +02:00
$this -> sessionData [ 'attachments' ] = $_formData [ 'attachments' ];
2013-11-22 14:55:09 +01:00
try
{
2014-01-20 10:26:26 +01:00
$acc = emailadmin_account :: read ( $this -> sessionData [ 'mailaccount' ]);
//error_log(__METHOD__.__LINE__.array2string($acc));
$identity = emailadmin_account :: read_identity ( $acc [ 'ident_id' ], true );
2013-11-22 14:55:09 +01:00
}
catch ( Exception $e )
{
$identity = array ();
}
2013-07-20 09:23:55 +02:00
$flags = '\\Seen \\Draft' ;
$this -> createMessage ( $mail , $_formData , $identity );
2014-11-25 00:38:37 +01:00
2013-07-20 09:23:55 +02:00
// folder list as Customheader
if ( ! empty ( $this -> sessionData [ 'folder' ]))
{
$folders = implode ( '|' , array_unique ( $this -> sessionData [ 'folder' ]));
2014-11-25 00:38:37 +01:00
$mail -> addHeader ( 'X-Mailfolder' , $folders );
2013-07-20 09:23:55 +02:00
}
2014-11-25 00:38:37 +01:00
$mail -> addHeader ( 'X-Mailidentity' , $this -> sessionData [ 'mailidentity' ]);
//$mail->addHeader('X-Stationery', $this->sessionData['stationeryID']);
$mail -> addHeader ( 'X-Mailaccount' , ( int ) $this -> sessionData [ 'mailaccount' ]);
2013-07-20 09:23:55 +02:00
// decide where to save the message (default to draft folder, if we find nothing else)
// if the current folder is in draft or template folder save it there
// if it is called from printview then save it with the draft folder
$savingDestination = $mail_bo -> getDraftFolder ();
if ( empty ( $this -> sessionData [ 'messageFolder' ]) && ! empty ( $this -> sessionData [ 'mailbox' ]))
{
$this -> sessionData [ 'messageFolder' ] = $this -> sessionData [ 'mailbox' ];
}
if ( ! empty ( $this -> sessionData [ 'messageFolder' ]) && ( $mail_bo -> isDraftFolder ( $this -> sessionData [ 'messageFolder' ])
|| $mail_bo -> isTemplateFolder ( $this -> sessionData [ 'messageFolder' ])))
{
$savingDestination = $this -> sessionData [ 'messageFolder' ];
//error_log(__METHOD__.__LINE__.' SavingDestination:'.$savingDestination);
}
if ( ! empty ( $_formData [ 'printit' ]) && $_formData [ 'printit' ] == 0 ) $savingDestination = $mail_bo -> getDraftFolder ();
2014-11-25 00:38:37 +01:00
// normaly Bcc is only added to recipients, but not as header visible to all recipients
$mail -> forceBccHeader ();
2013-07-20 09:23:55 +02:00
$mail_bo -> openConnection ();
if ( $mail_bo -> folderExists ( $savingDestination , true )) {
try
{
2014-11-25 00:38:37 +01:00
$messageUid = $mail_bo -> appendMessage ( $savingDestination , $mail -> getRaw (), null , $flags );
2013-07-20 09:23:55 +02:00
}
catch ( egw_exception_wrong_userinput $e )
{
error_log ( __METHOD__ . __LINE__ . lang ( " Save of message %1 failed. Could not save message to folder %2 due to: %3 " , __METHOD__ , $savingDestination , $e -> getMessage ()));
return false ;
}
} else {
2013-10-10 18:11:26 +02:00
error_log ( __METHOD__ . __LINE__ . " -> " . lang ( " folder " ) . " " . $savingDestination . " " . lang ( " does not exist on IMAP Server. " ));
2013-07-20 09:23:55 +02:00
return false ;
}
$mail_bo -> closeConnection ();
return $messageUid ;
}
function send ( $_formData )
{
$mail_bo = $this -> mail_bo ;
2014-11-25 00:38:37 +01:00
$mail = new egw_mailer ( $this -> mail_bo -> profileID );
2013-07-20 09:23:55 +02:00
$messageIsDraft = false ;
2014-01-13 16:40:34 +01:00
$this -> sessionData [ 'mailaccount' ] = $_formData [ 'mailaccount' ];
2014-09-23 10:23:10 +02:00
$this -> sessionData [ 'to' ] = self :: resolveEmailAddressList ( $_formData [ 'to' ]);
$this -> sessionData [ 'cc' ] = self :: resolveEmailAddressList ( $_formData [ 'cc' ]);
$this -> sessionData [ 'bcc' ] = self :: resolveEmailAddressList ( $_formData [ 'bcc' ]);
2013-07-20 09:23:55 +02:00
$this -> sessionData [ 'folder' ] = $_formData [ 'folder' ];
$this -> sessionData [ 'replyto' ] = $_formData [ 'replyto' ];
$this -> sessionData [ 'subject' ] = trim ( $_formData [ 'subject' ]);
$this -> sessionData [ 'body' ] = $_formData [ 'body' ];
$this -> sessionData [ 'priority' ] = $_formData [ 'priority' ];
2014-11-25 00:38:37 +01:00
$this -> sessionData [ 'mailidentity' ] = $_formData [ 'mailidentity' ];
2013-11-22 14:55:09 +01:00
//$this->sessionData['stationeryID'] = $_formData['stationeryID'];
2013-07-20 09:23:55 +02:00
$this -> sessionData [ 'disposition' ] = $_formData [ 'disposition' ];
$this -> sessionData [ 'mimeType' ] = $_formData [ 'mimeType' ];
$this -> sessionData [ 'to_infolog' ] = $_formData [ 'to_infolog' ];
$this -> sessionData [ 'to_tracker' ] = $_formData [ 'to_tracker' ];
2014-01-29 11:59:14 +01:00
$this -> sessionData [ 'attachments' ] = $_formData [ 'attachments' ];
2014-04-01 13:41:34 +02:00
if ( isset ( $_formData [ 'lastDrafted' ]) && ! empty ( $_formData [ 'lastDrafted' ]))
2014-01-23 12:56:34 +01:00
{
2014-04-01 13:41:34 +02:00
$this -> sessionData [ 'lastDrafted' ] = $_formData [ 'lastDrafted' ];
2014-01-23 12:56:34 +01:00
}
//error_log(__METHOD__.__LINE__.' Mode:'.$_formData['mode'].' PID:'.$_formData['processedmail_id']);
if ( isset ( $_formData [ 'mode' ]) && ! empty ( $_formData [ 'mode' ]))
{
if ( $_formData [ 'mode' ] == 'forward' && ! empty ( $_formData [ 'processedmail_id' ]))
{
$this -> sessionData [ 'forwardFlag' ] = 'forwarded' ;
$_formData [ 'processedmail_id' ] = explode ( ',' , $_formData [ 'processedmail_id' ]);
$this -> sessionData [ 'uid' ] = array ();
foreach ( $_formData [ 'processedmail_id' ] as $k => $rowid )
{
$fhA = mail_ui :: splitRowID ( $rowid );
$this -> sessionData [ 'uid' ][] = $fhA [ 'msgUID' ];
$this -> sessionData [ 'forwardedUID' ][] = $fhA [ 'msgUID' ];
if ( ! empty ( $fhA [ 'folder' ])) $this -> sessionData [ 'sourceFolder' ] = $fhA [ 'folder' ];
}
}
if ( $_formData [ 'mode' ] == 'reply' && ! empty ( $_formData [ 'processedmail_id' ]))
{
$rhA = mail_ui :: splitRowID ( $_formData [ 'processedmail_id' ]);
$this -> sessionData [ 'uid' ] = $rhA [ 'msgUID' ];
$this -> sessionData [ 'messageFolder' ] = $rhA [ 'folder' ];
}
}
2013-07-20 09:23:55 +02:00
// if the body is empty, maybe someone pasted something with scripts, into the message body
// this should not happen anymore, unless you call send directly, since the check was introduced with the action command
if ( empty ( $this -> sessionData [ '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 . ']' ]))
{
$this -> sessionData [ 'body' ] = self :: _getCleanHTML ( $GLOBALS [ 'egw_unset_vars' ][ $name . '[' . $key . ']' ]);
$_formData [ 'body' ] = $this -> sessionData [ 'body' ];
}
#error_log($this->sessionData['body']);
}
if ( empty ( $this -> sessionData [ 'to' ]) && empty ( $this -> sessionData [ 'cc' ]) &&
empty ( $this -> sessionData [ 'bcc' ]) && empty ( $this -> sessionData [ 'folder' ])) {
$messageIsDraft = true ;
}
2013-11-22 14:55:09 +01:00
try
{
2014-11-25 00:38:37 +01:00
$identity = emailadmin_account :: read_identity (( int ) $this -> sessionData [ 'mailidentity' ], true );
2013-11-22 14:55:09 +01:00
}
catch ( Exception $e )
{
2014-11-22 14:17:41 +01:00
$identity = array ();
2013-11-22 14:55:09 +01:00
}
2014-01-13 16:40:34 +01:00
//error_log($this->sessionData['mailaccount']);
2014-11-25 00:38:37 +01:00
//error_log(__METHOD__.__LINE__.':'.array2string($this->sessionData['mailidentity']).'->'.array2string($identity));
2013-07-20 09:23:55 +02:00
// create the messages
2014-11-22 14:17:41 +01:00
$this -> createMessage ( $mail , $_formData , $identity , true );
2013-07-20 09:23:55 +02:00
// remember the identity
if ( $_formData [ 'to_infolog' ] == 'on' || $_formData [ 'to_tracker' ] == 'on' ) $fromAddress = $mail -> FromName . ( $mail -> FromName ? ' <' : '' ) . $mail -> From . ( $mail -> FromName ? '>' : '' );
#print "<pre>". $mail->getMessageHeader() ."</pre><hr><br>";
#print "<pre>". $mail->getMessageBody() ."</pre><hr><br>";
#exit;
2014-05-23 14:21:17 +02:00
// we use the authentication data of the choosen mailaccount
if ( $_formData [ 'serverID' ] != $_formData [ 'mailaccount' ])
{
$this -> changeProfile ( $_formData [ 'mailaccount' ]);
}
// sentFolder is account specific
$sentFolder = $this -> mail_bo -> getSentFolder ();
if ( ! $this -> mail_bo -> folderExists ( $sentFolder , true )) $sentFolder = false ;
2014-09-11 16:10:01 +02:00
2014-05-23 14:21:17 +02:00
// we switch back from authentication data to the account we used to work on
if ( $_formData [ 'serverID' ] != $_formData [ 'mailaccount' ])
{
$this -> changeProfile ( $_formData [ 'serverID' ]);
}
2013-07-20 09:23:55 +02:00
// check if there are folders to be used
2014-04-08 16:55:43 +02:00
$folderToCheck = ( array ) $this -> sessionData [ 'folder' ];
$folder = array ();
foreach ( $folderToCheck as $k => $f )
{
if ( $this -> mail_bo -> folderExists ( $f , true ))
{
$folder [] = $f ;
}
}
2014-05-23 14:21:17 +02:00
if ( isset ( $sentFolder ) && $sentFolder && $sentFolder != 'none' &&
2014-05-13 15:10:53 +02:00
$this -> mailPreferences [ 'sendOptions' ] != 'send_only' &&
2013-07-20 09:23:55 +02:00
$messageIsDraft == false )
{
2014-05-23 14:21:17 +02:00
if ( $sentFolder )
2013-07-20 09:23:55 +02:00
{
$folder [] = $sentFolder ;
}
else
{
$this -> errorInfo = lang ( " No (valid) Send Folder set in preferences " );
}
}
else
{
2014-05-13 15:10:53 +02:00
if ((( ! isset ( $sentFolder ) || $sentFolder == false ) && $this -> mailPreferences [ 'sendOptions' ] != 'send_only' ) ||
( $this -> mailPreferences [ 'sendOptions' ] != 'send_only' &&
2013-07-20 09:23:55 +02:00
$sentFolder != 'none' )) $this -> errorInfo = lang ( " No Send Folder set in preferences " );
}
if ( $messageIsDraft == true ) {
$draftFolder = $this -> mail_bo -> getDraftFolder ();
2014-04-08 16:55:43 +02:00
if ( ! empty ( $draftFolder ) && $this -> mail_bo -> folderExists ( $draftFolder , true )) {
2013-07-20 09:23:55 +02:00
$this -> sessionData [ 'folder' ] = array ( $draftFolder );
$folder [] = $draftFolder ;
}
}
2014-11-20 18:53:52 +01:00
if ( $folder ) $folder = array_unique ( $folder );
2014-05-13 15:10:53 +02:00
if (( $this -> mailPreferences [ 'sendOptions' ] != 'send_only' && $sentFolder != 'none' ) && ! ( count ( $folder ) > 0 ) &&
2013-07-20 09:23:55 +02:00
! ( $_formData [ 'to_infolog' ] == 'on' || $_formData [ 'to_tracker' ] == 'on' ))
{
$this -> errorInfo = lang ( " Error: " ) . lang ( " No Folder destination supplied, and no folder to save message or other measure to store the mail (save to infolog/tracker) provided, but required. " ) . ( $this -> errorInfo ? ' ' . $this -> errorInfo : '' );
#error_log($this->errorInfo);
return false ;
}
// set a higher timeout for big messages
@ set_time_limit ( 120 );
//$mail->SMTPDebug = 10;
//error_log("Folder:".count(array($this->sessionData['folder']))."To:".count((array)$this->sessionData['to'])."CC:". count((array)$this->sessionData['cc']) ."bcc:".count((array)$this->sessionData['bcc']));
if ( count (( array ) $this -> sessionData [ 'to' ]) > 0 || count (( array ) $this -> sessionData [ 'cc' ]) > 0 || count (( array ) $this -> sessionData [ 'bcc' ]) > 0 ) {
try {
$mail -> Send ();
}
2014-11-25 00:38:37 +01:00
catch ( Exception $e ) {
_egw_log_exception ( $e );
$this -> errorInfo = $e -> getMessage () . ( $e -> detail ? ': ' . $e -> detail : '' );
2013-07-20 09:23:55 +02:00
return false ;
}
} else {
if ( count ( array ( $this -> sessionData [ 'folder' ])) > 0 && ! empty ( $this -> sessionData [ 'folder' ])) {
//error_log(__METHOD__.__LINE__."Folders:".print_r($this->sessionData['folder'],true));
} else {
$this -> errorInfo = lang ( " Error: " ) . lang ( " No Address TO/CC/BCC supplied, and no folder to save message to provided. " );
//error_log(__METHOD__.__LINE__.$this->errorInfo);
return false ;
}
}
2014-02-03 12:29:12 +01:00
//error_log(__METHOD__.__LINE__."Mail Sent.!");
//error_log(__METHOD__.__LINE__."Number of Folders to move copy the message to:".count($folder));
//error_log(__METHOD__.__LINE__.array2string($folder));
2013-07-20 09:23:55 +02:00
if (( count ( $folder ) > 0 ) || ( isset ( $this -> sessionData [ 'uid' ]) && isset ( $this -> sessionData [ 'messageFolder' ]))
|| ( isset ( $this -> sessionData [ 'forwardFlag' ]) && isset ( $this -> sessionData [ 'sourceFolder' ]))) {
$mail_bo = $this -> mail_bo ;
$mail_bo -> openConnection ();
//$mail_bo->reopen($this->sessionData['messageFolder']);
#error_log("(re)opened Connection");
}
// if copying mail to folder, or saving mail to infolog, we need to gather the needed information
2013-10-16 13:25:46 +02:00
if ( count ( $folder ) > 0 || $_formData [ 'to_infolog' ] == 'on' || $_formData [ 'to_tracker' ] == 'on' ) {
2014-09-23 10:23:10 +02:00
//error_log(__METHOD__.__LINE__.array2string($this->sessionData['bcc']));
2014-11-25 00:38:37 +01:00
// normaly Bcc is only added to recipients, but not as header visible to all recipients
$mail -> forceBccHeader ();
2013-07-20 09:23:55 +02:00
}
// copying mail to folder
if ( count ( $folder ) > 0 )
{
foreach ( $folder as $folderName ) {
if ( is_array ( $folderName )) $folderName = array_shift ( $folderName ); // should not happen at all
2014-05-23 14:21:17 +02:00
// if $_formData['serverID']!=$_formData['mailaccount'] skip copying to sentfolder on serverID
if ( $mail_bo -> isSentFolder ( $folderName ) && $_formData [ 'serverID' ] != $_formData [ 'mailaccount' ]) continue ;
2013-07-20 09:23:55 +02:00
if ( $mail_bo -> isSentFolder ( $folderName )) {
$flags = '\\Seen' ;
} elseif ( $mail_bo -> isDraftFolder ( $folderName )) {
$flags = '\\Draft' ;
} else {
2014-02-03 12:29:12 +01:00
$flags = '\\Seen' ;
2013-07-20 09:23:55 +02:00
}
#$mailHeader=explode('From:',$mail->getMessageHeader());
#$mailHeader[0].$mail->AddrAppend("Bcc",$mailAddr).'From:'.$mailHeader[1],
2014-02-03 12:29:12 +01:00
//error_log(__METHOD__.__LINE__.array2string($folderName));
//$mail_bo->reopen($folderName);
2013-07-20 09:23:55 +02:00
if ( $mail_bo -> folderExists ( $folderName , true )) {
try
{
2014-02-03 12:29:12 +01:00
//error_log(__METHOD__.__LINE__.array2string($folderName));
2014-11-25 00:38:37 +01:00
$mail_bo -> appendMessage ( $folderName , $mail -> getRaw (), null , $flags );
2013-07-20 09:23:55 +02:00
}
catch ( egw_exception_wrong_userinput $e )
{
error_log ( __METHOD__ . __LINE__ . '->' . lang ( " Import of message %1 failed. Could not save message to folder %2 due to: %3 " , $this -> sessionData [ 'subject' ], $folderName , $e -> getMessage ()));
}
}
else
{
error_log ( __METHOD__ . __LINE__ . '->' . lang ( " Import of message %1 failed. Destination Folder %2 does not exist. " , $this -> sessionData [ 'subject' ], $folderName ));
}
}
2014-05-23 14:21:17 +02:00
// if we choose to send from a differing profile
if ( $_formData [ 'serverID' ] != $_formData [ 'mailaccount' ])
{
// we assume the intention is to see the sent mail in the sentfolder
// of that account, that is, if there is one at all, and our options
// suggest it
if ( isset ( $sentFolder ) && $sentFolder != 'none' &&
$this -> mailPreferences [ 'sendOptions' ] != 'send_only' )
{
$this -> changeProfile ( $_formData [ 'mailaccount' ]);
$sentFolder = $this -> mail_bo -> getSentFolder ();
try
{
$flags = '\\Seen' ;
//error_log(__METHOD__.__LINE__.array2string($folderName));
2014-11-25 00:38:37 +01:00
$this -> mail_bo -> appendMessage ( $sentFolder , $mail -> getRaw (), null , $flags );
2014-05-23 14:21:17 +02:00
}
catch ( egw_exception_wrong_userinput $e )
{
error_log ( __METHOD__ . __LINE__ . '->' . lang ( " Import of message %1 failed. Could not save message to folder %2 due to: %3 " , $this -> sessionData [ 'subject' ], $folderName , $e -> getMessage ()));
}
$this -> changeProfile ( $_formData [ 'serverID' ]);
}
}
2013-07-20 09:23:55 +02:00
//$mail_bo->closeConnection();
}
// handle previous drafted versions of that mail
$lastDrafted = false ;
if ( isset ( $this -> sessionData [ 'lastDrafted' ]))
{
2014-01-23 12:56:34 +01:00
$lastDrafted = array ();
2014-04-01 13:41:34 +02:00
$dhA = mail_ui :: splitRowID ( $this -> sessionData [ 'lastDrafted' ]);
2014-01-23 12:56:34 +01:00
$lastDrafted [ 'uid' ] = $dhA [ 'msgUID' ];
$lastDrafted [ 'folder' ] = $dhA [ 'folder' ];
2013-07-20 09:23:55 +02:00
if ( isset ( $lastDrafted [ 'uid' ]) && ! empty ( $lastDrafted [ 'uid' ])) $lastDrafted [ 'uid' ] = trim ( $lastDrafted [ 'uid' ]);
2014-01-23 12:56:34 +01:00
// manually drafted, do not delete
2013-07-20 09:23:55 +02:00
if ( isset ( $lastDrafted [ 'uid' ]) && ( empty ( $lastDrafted [ 'uid' ]) || $lastDrafted [ 'uid' ] == $this -> sessionData [ 'uid' ])) $lastDrafted = false ;
//error_log(__METHOD__.__LINE__.array2string($lastDrafted));
}
2014-01-23 12:56:34 +01:00
if ( $lastDrafted && is_array ( $lastDrafted ) && $mail_bo -> isDraftFolder ( $lastDrafted [ 'folder' ]))
{
try
{
$mail_bo -> deleteMessages ( $lastDrafted [ 'uid' ], $lastDrafted [ 'folder' ], 'remove_immediately' );
}
catch ( egw_exception $e )
{
2014-11-20 18:53:52 +01:00
//error_log(__METHOD__.__LINE__." ". str_replace('"',"'",$e->getMessage()));
unset ( $e );
2014-01-23 12:56:34 +01:00
}
}
2013-07-20 09:23:55 +02:00
unset ( $this -> sessionData [ 'lastDrafted' ]);
//error_log("handling draft messages, flagging and such");
if (( isset ( $this -> sessionData [ 'uid' ]) && isset ( $this -> sessionData [ 'messageFolder' ]))
|| ( isset ( $this -> sessionData [ 'forwardFlag' ]) && isset ( $this -> sessionData [ 'sourceFolder' ]))) {
// mark message as answered
$mail_bo -> openConnection ();
2014-01-23 12:56:34 +01:00
$mail_bo -> reopen (( $this -> sessionData [ 'messageFolder' ] ? $this -> sessionData [ 'messageFolder' ] : $this -> sessionData [ 'sourceFolder' ]));
2013-07-20 09:23:55 +02:00
// if the draft folder is a starting part of the messages folder, the draft message will be deleted after the send
// unless your templatefolder is a subfolder of your draftfolder, and the message is in there
if ( $mail_bo -> isDraftFolder ( $this -> sessionData [ 'messageFolder' ]) && ! $mail_bo -> isTemplateFolder ( $this -> sessionData [ 'messageFolder' ]))
{
$mail_bo -> deleteMessages ( array ( $this -> sessionData [ 'uid' ]), $this -> sessionData [ 'messageFolder' ]);
} else {
2014-01-23 12:56:34 +01:00
$mail_bo -> flagMessages ( " answered " , $this -> sessionData [ 'uid' ],( $this -> sessionData [ 'messageFolder' ] ? $this -> sessionData [ 'messageFolder' ] : $this -> sessionData [ 'sourceFolder' ]));
//error_log(__METHOD__.__LINE__.array2string(array_keys($this->sessionData)).':'.array2string($this->sessionData['forwardedUID']).' F:'.$this->sessionData['sourceFolder']);
2013-07-20 09:23:55 +02:00
if ( array_key_exists ( 'forwardFlag' , $this -> sessionData ) && $this -> sessionData [ 'forwardFlag' ] == 'forwarded' )
{
2014-01-23 12:56:34 +01:00
//error_log(__METHOD__.__LINE__.':'.array2string($this->sessionData['forwardedUID']).' F:'.$this->sessionData['sourceFolder']);
$mail_bo -> flagMessages ( " forwarded " , $this -> sessionData [ 'forwardedUID' ], $this -> sessionData [ 'sourceFolder' ]);
2013-07-20 09:23:55 +02:00
}
}
//$mail_bo->closeConnection();
}
if ( $mail_bo ) $mail_bo -> closeConnection ();
//error_log("performing Infolog Stuff");
//error_log(print_r($this->sessionData['to'],true));
//error_log(print_r($this->sessionData['cc'],true));
//error_log(print_r($this->sessionData['bcc'],true));
if ( is_array ( $this -> sessionData [ 'to' ]))
{
$mailaddresses [ 'to' ] = $this -> sessionData [ 'to' ];
}
else
{
$mailaddresses = array ();
}
if ( is_array ( $this -> sessionData [ 'cc' ])) $mailaddresses [ 'cc' ] = $this -> sessionData [ 'cc' ];
if ( is_array ( $this -> sessionData [ 'bcc' ])) $mailaddresses [ 'bcc' ] = $this -> sessionData [ 'bcc' ];
if ( ! empty ( $mailaddresses )) $mailaddresses [ 'from' ] = $GLOBALS [ 'egw' ] -> translation -> decodeMailHeader ( $fromAddress );
// attention: we dont return from infolog/tracker. You cannot check both. cleanups will be done there.
if ( $_formData [ 'to_infolog' ] == 'on' ) {
$uiinfolog =& CreateObject ( 'infolog.infolog_ui' );
$uiinfolog -> import_mail (
$mailaddresses ,
$this -> sessionData [ 'subject' ],
$this -> convertHTMLToText ( $this -> sessionData [ 'body' ]),
$this -> sessionData [ 'attachments' ],
false , // date
$sentMailHeader , // raw SentMailHeader
$sentMailBody // raw SentMailBody
);
}
if ( $_formData [ 'to_tracker' ] == 'on' ) {
$uitracker =& CreateObject ( 'tracker.tracker_ui' );
$uitracker -> import_mail (
$mailaddresses ,
$this -> sessionData [ 'subject' ],
$this -> convertHTMLToText ( $this -> sessionData [ 'body' ]),
$this -> sessionData [ 'attachments' ],
false , // date
$sentMailHeader , // raw SentMailHeader
$sentMailBody // raw SentMailBody
);
}
/*
if ( $_formData [ 'to_calendar' ] == 'on' ) {
$uical =& CreateObject ( 'calendar.calendar_uiforms' );
$uical -> import_mail (
$mailaddresses ,
$this -> sessionData [ 'subject' ],
$this -> convertHTMLToText ( $this -> sessionData [ 'body' ]),
$this -> sessionData [ 'attachments' ]
);
}
*/
if ( is_array ( $this -> sessionData [ 'attachments' ])) {
2014-11-25 00:38:37 +01:00
foreach ( $this -> sessionData [ 'attachments' ] as $value ) {
2013-07-20 09:23:55 +02:00
if ( ! empty ( $value [ 'file' ]) && parse_url ( $value [ 'file' ], PHP_URL_SCHEME ) != 'vfs' ) { // happens when forwarding mails
unlink ( $value [ 'file' ]);
}
}
}
$this -> sessionData = '' ;
return true ;
}
2013-10-10 13:44:01 +02:00
/**
* setDefaults , sets some defaults
*
* @ param array $content
* @ return array - the input , enriched with some not set attributes
*/
2013-10-10 16:56:30 +02:00
function setDefaults ( $content = array ())
2013-07-20 09:23:55 +02:00
{
// retrieve the signature accociated with the identity
2013-12-17 10:55:47 +01:00
$id = $this -> mail_bo -> getDefaultIdentity ();
2014-05-02 12:33:54 +02:00
if ( isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'LastSignatureIDUsed' ]) && ! empty ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'LastSignatureIDUsed' ]))
{
$sigPref = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'LastSignatureIDUsed' ];
if ( ! empty ( $sigPref [ $this -> mail_bo -> profileID ]) && $sigPref [ $this -> mail_bo -> profileID ] > 0 )
{
try
{
$id = $sigPref [ $this -> mail_bo -> profileID ];
}
catch ( Exception $e )
{
2014-11-20 18:53:52 +01:00
unset ( $e );
2014-05-02 12:33:54 +02:00
unset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'LastSignatureIDUsed' ][ $this -> mail_bo -> profileID ]);
}
}
}
2014-11-25 00:38:37 +01:00
if (( ! isset ( $content [ 'mailaccount' ]) || empty ( $content [ 'mailaccount' ])) && $id ) $content [ 'mailidentity' ] = $id ;
if ( ! isset ( $content [ 'mailidentity' ]) || empty ( $content [ 'mailidentity' ])) $content [ 'mailidentity' ] = $id ;
2013-10-10 16:56:30 +02:00
if ( ! isset ( $content [ 'mimeType' ]) || empty ( $content [ 'mimeType' ]))
{
$content [ 'mimeType' ] = 'html' ;
2014-05-13 15:10:53 +02:00
if ( ! empty ( $this -> mailPreferences [ 'composeOptions' ]) && $this -> mailPreferences [ 'composeOptions' ] == " text " ) $content [ 'mimeType' ] = 'plain' ;
2013-10-10 16:56:30 +02:00
}
2013-10-02 16:50:24 +02:00
return $content ;
2013-07-20 09:23:55 +02:00
}
function stripSlashes ( $_string )
{
if ( get_magic_quotes_gpc ()) {
return stripslashes ( $_string );
} else {
return $_string ;
}
}
2013-07-20 15:10:17 +02:00
2013-09-02 17:15:35 +02:00
function ajax_searchFolder ( $_searchStringLength = 2 , $_returnList = false ) {
2014-11-20 18:53:52 +01:00
static $useCacheIfPossible = null ;
2013-07-20 15:10:17 +02:00
if ( is_null ( $useCacheIfPossible )) $useCacheIfPossible = true ;
$_searchString = trim ( $_REQUEST [ 'query' ]);
2013-07-20 11:27:37 +02:00
$results = array ();
2013-09-02 17:15:35 +02:00
if ( strlen ( $_searchString ) >= $_searchStringLength && isset ( $this -> mail_bo -> icServer ))
2013-07-20 15:10:17 +02:00
{
//error_log(__METHOD__.__LINE__.':'.$this->mail_bo->icServer->ImapServerId);
2013-11-22 14:55:09 +01:00
$this -> mail_bo -> openConnection ( $this -> mail_bo -> icServer -> ImapServerId );
2013-07-20 15:10:17 +02:00
//error_log(__METHOD__.__LINE__.array2string($_searchString).'<->'.$searchString);
$folderObjects = $this -> mail_bo -> getFolderObjects ( true , false , true , $useCacheIfPossible );
if ( count ( $folderObjects ) <= 1 ) {
$useCacheIfPossible = false ;
}
else
{
$useCacheIfPossible = true ;
}
$searchString = translation :: convert ( $_searchString , mail_bo :: $displayCharset , 'UTF7-IMAP' );
foreach ( $folderObjects as $k => $fA )
{
2013-07-20 17:15:29 +02:00
//error_log(__METHOD__.__LINE__.$_searchString.'/'.$searchString.' in '.$k.'->'.$fA->displayName);
2013-07-20 15:10:17 +02:00
$f = false ;
2013-09-02 17:15:35 +02:00
if ( $_searchStringLength <= 0 )
{
$f = true ;
$results [] = array ( 'id' => $k , 'label' => htmlspecialchars ( $fA -> displayName ));
}
if ( $f == false && stripos ( $fA -> displayName , $_searchString ) !== false )
2013-07-20 15:10:17 +02:00
{
$f = true ;
$results [] = array ( 'id' => $k , 'label' => htmlspecialchars ( $fA -> displayName ));
}
if ( $f == false && stripos ( $k , $searchString ) !== false )
{
$results [] = array ( 'id' => $k , 'label' => htmlspecialchars ( $fA -> displayName ));
}
}
}
//error_log(__METHOD__.__LINE__.' IcServer:'.$this->mail_bo->icServer->ImapServerId.':'.array2string($results));
2013-09-02 17:15:35 +02:00
if ( $_returnList )
{
2014-10-23 13:28:36 +02:00
foreach (( array ) $results as $k => $_result )
{
$rL [ $_result [ 'id' ]] = $_result [ 'label' ];
}
2013-09-02 17:15:35 +02:00
return $rL ;
}
2014-02-24 20:12:37 +01:00
// switch regular JSON response handling off
egw_json_request :: isJSONRequest ( false );
2013-07-20 11:27:37 +02:00
header ( 'Content-Type: application/json; charset=utf-8' );
2013-10-08 16:23:46 +02:00
//error_log(__METHOD__.__LINE__);
2013-07-20 11:27:37 +02:00
echo json_encode ( $results );
common :: egw_exit ();
}
2013-10-18 11:58:25 +02:00
public static function ajax_searchAddress ( $_searchStringLength = 2 ) {
2013-08-21 12:47:20 +02:00
//error_log(__METHOD__. "request from seachAddress " . $_REQUEST['query']);
2013-07-20 11:27:37 +02:00
$_searchString = trim ( $_REQUEST [ 'query' ]);
2013-11-21 23:29:57 +01:00
$include_lists = ( boolean ) $_REQUEST [ 'include_lists' ];
2014-03-03 12:59:18 +01:00
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'addressbook' ] && strlen ( $_searchString ) >= $_searchStringLength )
{
2013-07-20 11:27:37 +02:00
//error_log(__METHOD__.__LINE__.array2string($_searchString));
2014-03-03 12:59:18 +01:00
$showAccounts = empty ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'addressbook' ][ 'hide_accounts' ]);
$search = explode ( ' ' , $_searchString );
foreach ( $search as $k => $v )
{
if ( mb_strlen ( $v ) < 3 ) unset ( $search [ $k ]);
}
$search_str = implode ( ' +' , $search ); // tell contacts/so_sql to AND search patterns
//error_log(__METHOD__.__LINE__.$_searchString);
$filter = $showAccounts ? array () : array ( 'account_id' => null );
$filter [ 'cols_to_search' ] = array ( 'n_prefix' , 'n_given' , 'n_family' , 'org_name' , 'email' , 'email_home' );
$cols = array ( 'n_fn' , 'n_prefix' , 'n_given' , 'n_family' , 'org_name' , 'email' , 'email_home' );
$contacts = $GLOBALS [ 'egw' ] -> contacts -> search ( $search_str , $cols , 'n_fn' , '' , '%' , false , 'OR' , array ( 0 , 100 ), $filter );
// additionally search the accounts, if the contact storage is not the account storage
if ( $showAccounts && $GLOBALS [ 'egw' ] -> contacts -> so_accounts )
{
$filter [ 'owner' ] = 0 ;
$accounts = $GLOBALS [ 'egw' ] -> contacts -> search ( $search_str , $cols , 'n_fn' , '' , '%' , false , 'OR' , array ( 0 , 100 ), $filter );
if ( $contacts && $accounts )
2013-07-20 11:27:37 +02:00
{
2014-03-03 12:59:18 +01:00
$contacts = array_merge ( $contacts , $accounts );
usort ( $contacts , function ( $a , $b )
2013-07-20 11:27:37 +02:00
{
2014-03-03 12:59:18 +01:00
return strcasecmp ( $a [ 'n_fn' ], $b [ 'n_fn' ]);
});
}
elseif ( $accounts )
{
$contacts =& $accounts ;
2013-07-20 11:27:37 +02:00
}
2014-03-03 12:59:18 +01:00
unset ( $accounts );
2013-07-20 11:27:37 +02:00
}
}
$results = array ();
if ( is_array ( $contacts )) {
foreach ( $contacts as $contact ) {
foreach ( array ( $contact [ 'email' ], $contact [ 'email_home' ]) as $email ) {
// avoid wrong addresses, if an rfc822 encoded address is in addressbook
$email = preg_replace ( " /(^.*<)([a-zA-Z0-9_ \ -]+@[a-zA-Z0-9_ \ - \ .]+)(.*)/ " , '$2' , $email );
if ( method_exists ( $GLOBALS [ 'egw' ] -> contacts , 'search' ))
{
$contact [ 'n_fn' ] = '' ;
if ( ! empty ( $contact [ 'n_prefix' ])) $contact [ 'n_fn' ] = $contact [ 'n_prefix' ];
if ( ! empty ( $contact [ 'n_given' ])) $contact [ 'n_fn' ] .= ( $contact [ 'n_fn' ] ? ' ' : '' ) . $contact [ 'n_given' ];
if ( ! empty ( $contact [ 'n_family' ])) $contact [ 'n_fn' ] .= ( $contact [ 'n_fn' ] ? ' ' : '' ) . $contact [ 'n_family' ];
if ( ! empty ( $contact [ 'org_name' ])) $contact [ 'n_fn' ] .= ( $contact [ 'n_fn' ] ? ' ' : '' ) . '(' . $contact [ 'org_name' ] . ')' ;
$contact [ 'n_fn' ] = str_replace ( array ( ',' , '@' ), ' ' , $contact [ 'n_fn' ]);
}
else
{
$contact [ 'n_fn' ] = str_replace ( array ( ',' , '@' ), ' ' , $contact [ 'n_fn' ]);
}
$completeMailString = trim ( $contact [ 'n_fn' ] ? $contact [ 'n_fn' ] : $contact [ 'fn' ]) . ' <' . trim ( $email ) . '>' ;
if ( ! empty ( $email ) && in_array ( $completeMailString , $results ) === false ) {
2013-07-30 16:20:23 +02:00
$results [] = array (
'id' => $completeMailString ,
2013-08-09 19:47:53 +02:00
'label' => $completeMailString ,
2013-07-30 16:20:23 +02:00
// Add just name for nice display, with title for hover
2013-08-09 19:47:53 +02:00
'name' => $contact [ 'n_fn' ],
2013-07-30 16:20:23 +02:00
'title' => $email
);
2013-07-20 11:27:37 +02:00
}
}
}
2013-11-21 23:29:57 +01:00
}
2013-07-20 11:27:37 +02:00
2013-11-21 23:29:57 +01:00
// Add up to 5 matching mailing lists
if ( $include_lists )
{
$lists = array_filter (
$GLOBALS [ 'egw' ] -> contacts -> get_lists ( EGW_ACL_READ ),
function ( $element ) use ( $_searchString ) {
2014-02-07 16:11:46 +01:00
return ( stripos ( $element , $_searchString ) !== false );
2013-11-21 23:29:57 +01:00
}
);
$list_count = 0 ;
foreach ( $lists as $key => $list_name )
{
$results [] = array (
'id' => $key ,
'name' => $list_name ,
2014-01-16 16:58:27 +01:00
'label' => $list_name ,
'class' => 'mailinglist' ,
'title' => lang ( 'Mailinglist' ),
2013-11-21 23:29:57 +01:00
);
if ( $list_count ++ > 5 ) break ;
}
2013-07-20 11:27:37 +02:00
}
2014-02-24 19:46:14 +01:00
// switch regular JSON response handling off
egw_json_request :: isJSONRequest ( false );
2013-11-21 23:29:57 +01:00
2013-07-20 17:15:29 +02:00
//error_log(__METHOD__.__LINE__.array2string($jsArray));
2013-07-20 11:27:37 +02:00
header ( 'Content-Type: application/json; charset=utf-8' );
echo json_encode ( $results );
common :: egw_exit ();
}
2013-07-20 09:23:55 +02:00
2014-01-16 15:05:07 +01:00
/**
* Merge the selected contact ID into the document given in $_REQUEST [ 'document' ]
* and send it .
*
* @ param int $contact_id
*/
public function ajax_merge ( $contact_id )
{
$response = egw_json_response :: get ();
$document_merge = new addressbook_merge ();
$this -> mail_bo -> openConnection ();
2014-01-18 15:00:19 +01:00
2014-11-20 18:53:52 +01:00
if (( $error = $document_merge -> check_document ( $_REQUEST [ 'document' ], '' )))
2014-01-16 15:05:07 +01:00
{
$response -> error ( $error );
return ;
}
// Merge does not work correctly (missing to) if current app is not addressbook
2014-01-17 11:47:35 +01:00
//$GLOBALS['egw_info']['flags']['currentapp'] = 'addressbook';
2014-01-16 15:05:07 +01:00
// Actually do the merge
2014-11-20 18:53:52 +01:00
$folder = $merged_mail_id = null ;
2014-01-16 15:05:07 +01:00
$results = $this -> mail_bo -> importMessageToMergeAndSend (
$document_merge , egw_vfs :: PREFIX . $_REQUEST [ 'document' ],
// Send an extra non-numeric ID to force actual send of document
// instead of save as draft
array (( int ) $contact_id , '' ),
$folder , $merged_mail_id
);
if ( $results [ 'success' ])
{
$response -> data ( implode ( ',' , $results [ 'success' ]));
}
if ( $results [ 'failed' ])
{
$response -> error ( implode ( ',' , $results [ 'failed' ]));
}
}
2014-11-21 14:37:30 +01:00
/**
* Wrapper for etemplate_new :: ajax_process_content to be able to identify send request to select different fpm pool
*
* @ param string $etemplate_exec_id
* @ param array $content
* @ param boolean $no_validation
* @ throws egw_exception_wrong_parameter
*/
static public function ajax_send ( $etemplate_exec_id , array $content , $no_validation )
{
// setting menuaction is required as it triggers different behavior eg. in egw_framework::window_close()
$_GET [ 'menuaction' ] = 'etemplate_new::ajax_process_content' ;
return etemplate_new :: ajax_process_content ( $etemplate_exec_id , $content , $no_validation );
}
2013-07-20 11:27:37 +02:00
}