2013-02-08 20:11:44 +01:00
< ? php
/**
* EGroupware - Mail - interface class
*
* @ 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-02-08 20:11:44 +01:00
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
* @ version $Id $
*/
2013-04-12 15:10:27 +02:00
include_once ( EGW_INCLUDE_ROOT . '/etemplate/inc/class.etemplate.inc.php' );
2013-02-08 20:11:44 +01:00
/**
* Mail Interface class
*/
class mail_ui
{
/**
* Methods callable via menuaction
*
* @ var array
*/
var $public_functions = array
(
'index' => True ,
2013-02-28 10:28:08 +01:00
'displayHeader' => True ,
2013-06-05 16:24:56 +02:00
'displayMessage' => True ,
2013-06-12 13:50:30 +02:00
'displayImage' => True ,
'getAttachment' => True ,
2014-07-08 14:01:29 +02:00
'download_zip' => True ,
2013-02-28 10:28:08 +01:00
'saveMessage' => True ,
2013-07-15 15:37:28 +02:00
'vfsSaveAttachment' => True ,
2013-03-05 15:09:35 +01:00
'vfsSaveMessage' => True ,
2013-04-12 15:10:27 +02:00
'loadEmailBody' => True ,
2013-04-12 11:22:23 +02:00
'importMessage' => True ,
2014-01-24 11:30:45 +01:00
'importMessageFromVFS2DraftAndDisplay' => True ,
2014-02-06 18:18:12 +01:00
'subscription' => True ,
2013-02-08 20:11:44 +01:00
);
2013-02-20 17:27:10 +01:00
/**
* current icServerID
*
* @ var int
*/
static $icServerID ;
/**
* delimiter - used to separate profileID from foldertreestructure , and separate keyinformation in rowids
*
* @ var string
*/
static $delimiter = '::' ;
2013-08-21 12:47:20 +02:00
/**
* nextMatch name for index
*
* @ var string
*/
static $nm_index = 'nm' ;
2013-02-08 20:11:44 +01:00
/**
* instance of mail_bo
*
2013-10-22 17:30:25 +02:00
* @ var mail_bo
2013-02-08 20:11:44 +01:00
*/
var $mail_bo ;
2013-07-17 14:01:01 +02:00
/**
* definition of available / supported search types
*
* @ var array
*/
var $searchTypes = array (
2013-07-20 09:23:55 +02:00
'quick' => 'quicksearch' , // lang('quicksearch')
'subject' => 'subject' , // lang('subject')
'body' => 'message body' , // lang('message body')
'from' => 'from' , // lang('from')
'to' => 'to' , // lang('to')
'cc' => 'cc' , // lang('cc')
2013-07-17 14:01:01 +02:00
);
/**
* definition of available / supported status types
*
* @ var array
*/
var $statusTypes = array (
2013-07-20 09:23:55 +02:00
'any' => 'any status' , // lang('any status')
2013-10-22 17:30:25 +02:00
'flagged' => 'flagged' , // lang('flagged')
2013-07-20 09:23:55 +02:00
'unseen' => 'unread' , // lang('unread')
'answered' => 'replied' , // lang('replied')
'seen' => 'read' , // lang('read')
'deleted' => 'deleted' , // lang('deleted')
2013-07-17 14:01:01 +02:00
);
2013-02-08 20:11:44 +01:00
/**
* Constructor
*
*/
function __construct ()
{
2014-02-27 16:32:14 +01:00
if ( mail_bo :: $debugTimes ) $starttime = microtime ( true );
2013-07-17 14:01:01 +02:00
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'flags' ][ 'js_link_registry' ]))
{
2013-07-18 10:12:09 +02:00
//error_log(__METHOD__.__LINE__.' js_link_registry not set, force it:'.array2string($GLOBALS['egw_info']['flags']['js_link_registry']));
2013-07-17 14:01:01 +02:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'js_link_registry' ] = true ;
}
2013-02-08 20:11:44 +01:00
// no autohide of the sidebox, as we use it for folderlist now.
unset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'auto_hide_sidebox' ]);
if ( ! empty ( $_GET [ " resetConnection " ])) $connectionReset = html :: purify ( $_GET [ " resetConnection " ]);
unset ( $_GET [ " resetConnection " ]);
2013-02-20 12:31:57 +01:00
if ( isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'ActiveProfileID' ]) && ! empty ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'ActiveProfileID' ]))
{
2013-02-20 17:27:10 +01:00
self :: $icServerID = ( int ) $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'ActiveProfileID' ];
2013-02-20 12:31:57 +01:00
}
2013-02-08 20:11:44 +01:00
if ( $connectionReset )
{
2013-02-28 10:28:08 +01:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . __LINE__ . ' Connection Reset triggered:' . $connectionReset . ' for Profile with ID:' . self :: $icServerID );
2014-04-08 17:19:06 +02:00
emailadmin_imapbase :: unsetCachedObjects ( self :: $icServerID );
2013-02-08 20:11:44 +01:00
}
2013-11-06 22:02:19 +01:00
try {
2013-11-19 13:03:53 +01:00
$this -> mail_bo = mail_bo :: getInstance ( true , self :: $icServerID );
2013-11-06 22:02:19 +01:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . __LINE__ . ' Fetched IC Server:' . self :: $icServerID . '/' . $this -> mail_bo -> profileID . ':' . function_backtrace ());
//error_log(__METHOD__.__LINE__.array2string($this->mail_bo->icServer));
2014-07-31 12:18:41 +02:00
// RegEx to minimize extra openConnection
$needle = '/mail.etemplate_widget_nextmatch.ajax_get_rows.etemplate|'
. 'mail.mail_ui.ajax_refreshQuotaDisplay|'
. 'mail.mail_ui.ajax_changeProfile|'
. '^(?!mail)/' ;
if ( ! preg_match ( $needle , $_GET [ 'menuaction' ]))
2014-02-27 16:32:14 +01:00
{
2014-05-09 14:43:57 +02:00
//error_log(__METHOD__.__LINE__.' Fetched IC Server openConnection:'.self::$icServerID.'/'.$this->mail_bo->profileID.':'.function_backtrace());
2014-02-27 16:32:14 +01:00
//openConnection gathers SpecialUseFolderInformation and Delimiter Info
$this -> mail_bo -> openConnection ( self :: $icServerID );
}
2013-11-06 22:02:19 +01:00
}
catch ( Exception $e )
{
// redirect to mail wizard to handle it (redirect works for ajax too)
2014-05-09 14:43:57 +02:00
self :: callWizard ( $e -> getMessage ());
2013-11-06 22:02:19 +01:00
}
2014-02-27 16:32:14 +01:00
if ( mail_bo :: $debugTimes ) mail_bo :: logRunTimes ( $starttime , null , '' , __METHOD__ . __LINE__ );
2013-02-08 20:11:44 +01:00
}
2014-05-09 14:43:57 +02:00
/**
* callWizard
*
* @ param string $message
2014-07-16 15:42:36 +02:00
* @ param boolean $exit If true , will call common :: egw_exit () after opening the wizardpopup
2014-05-09 14:43:57 +02:00
*/
2014-05-12 09:35:23 +02:00
static function callWizard ( $message , $exit = true )
2014-05-09 14:43:57 +02:00
{
2014-05-20 13:47:18 +02:00
//error_log(__METHOD__."('$message', $exit) ".function_backtrace());
2014-05-09 14:43:57 +02:00
$linkData = ( self :: $icServerID ? array (
'menuaction' => 'mail.mail_wizard.edit' ,
'acc_id' => self :: $icServerID ,
) : array (
'menuaction' => 'mail.mail_wizard.add' ,
)) + array (
2014-07-16 15:42:36 +02:00
'msg' => $message
2014-05-09 14:43:57 +02:00
);
2014-05-12 09:35:23 +02:00
if ( egw_json_response :: isJSONResponse ())
{
$response = egw_json_response :: get ();
$windowName = " editMailAccount " . self :: $icServerID ;
$response -> call ( " egw.open_link " , egw :: link ( '/index.php' , $linkData ), $windowName , " 600x480 " );
egw_framework :: message ( $message , 'error' );
2014-07-18 19:18:29 +02:00
if ( $_GET [ 'menuaction' ] == 'mail.mail_ui.index' )
{
$response -> call ( 'framework.setSidebox' , 'mail' , array (), 'md5' );
}
2014-05-12 09:35:23 +02:00
if ( $exit )
{
common :: egw_exit ();
}
}
else // regular GET request eg. in idots template
{
2014-06-20 11:28:45 +02:00
egw_framework :: popup ( egw_framework :: link ( '/index.php' , $linkData ));
2014-06-23 13:38:42 +02:00
$GLOBALS [ 'egw' ] -> framework -> render ( $message , '' , true );
2014-06-30 17:48:49 +02:00
if ( $exit )
{
common :: egw_exit ();
2014-07-08 13:09:31 +02:00
}
2014-05-12 09:35:23 +02:00
}
2014-05-09 14:43:57 +02:00
}
2013-02-20 12:31:57 +01:00
/**
* changeProfile
*
2014-07-16 15:42:36 +02:00
* @ param int $_icServerID
* @ param boolean $unsetCache
2013-02-20 12:31:57 +01:00
*/
2013-06-04 17:29:53 +02:00
function changeProfile ( $_icServerID , $unsetCache = false )
2013-02-20 12:31:57 +01:00
{
2014-02-27 16:32:14 +01:00
if ( mail_bo :: $debugTimes ) $starttime = microtime ( true );
2013-10-08 16:23:46 +02:00
if ( self :: $icServerID != $_icServerID )
{
2014-06-30 17:48:49 +02:00
self :: $icServerID = $_icServerID ;
2013-10-08 16:23:46 +02:00
}
2013-06-04 17:29:53 +02:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . __LINE__ . '->' . self :: $icServerID . '<->' . $_icServerID );
2014-07-08 13:09:31 +02:00
2014-04-08 17:19:06 +02:00
if ( $unsetCache ) emailadmin_imapbase :: unsetCachedObjects ( self :: $icServerID );
2013-02-20 17:27:10 +01:00
$this -> mail_bo = mail_bo :: getInstance ( false , self :: $icServerID );
2013-10-30 14:27:26 +01:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . __LINE__ . ' Fetched IC Server:' . self :: $icServerID . '/' . $this -> mail_bo -> profileID . ':' . function_backtrace ());
2013-02-20 12:31:57 +01:00
// no icServer Object: something failed big time
2014-06-30 17:48:49 +02:00
if ( ! isset ( $this -> mail_bo -> icServer ) || $this -> mail_bo -> icServer -> ImapServerId <> $_icServerID )
{
self :: $icServerID = $_icServerID ;
throw new egw_exception ( 'Profile change failed!' );
}
2014-07-08 13:09:31 +02:00
2013-02-20 12:31:57 +01:00
// save session varchar
2013-02-20 13:04:29 +01:00
$oldicServerID =& egw_cache :: getSession ( 'mail' , 'activeProfileID' );
2014-05-12 09:35:23 +02:00
if ( $oldicServerID <> self :: $icServerID ) $this -> mail_bo -> openConnection ( self :: $icServerID );
$oldicServerID = self :: $icServerID ;
2014-05-09 14:43:57 +02:00
if ( ! emailadmin_imapbase :: storeActiveProfileIDToPref ( $this -> mail_bo -> icServer , self :: $icServerID , true ))
{
throw new egw_exception ( __METHOD__ . " failed to change Profile to $_icServerID " );
}
2014-07-08 13:09:31 +02:00
2014-02-27 16:32:14 +01:00
if ( mail_bo :: $debugTimes ) mail_bo :: logRunTimes ( $starttime , null , '' , __METHOD__ . __LINE__ );
2013-02-20 12:31:57 +01:00
}
2014-04-24 11:23:06 +02:00
2014-02-17 17:11:28 +01:00
/**
* Subscribe or Unsubscribe to a folder
* also it is consider if the folder is valid to un / subscribe
*
2014-05-22 16:46:50 +02:00
* @ param boolean $folderName subscribe if true and unsubscribe if false
* @ param string $status folder name
2014-02-17 17:11:28 +01:00
*
* @ example setSubscribe ( 'INBOX' , true ) subscribe to folder INBOX
*
*/
function setSubscribe ( $folderName , $status = true )
{
$validFolder = true ;
2014-02-17 17:36:16 +01:00
$result = true ;
2014-02-17 17:11:28 +01:00
$nameSpaces = $this -> mail_bo -> _getNameSpaces ();
2014-02-19 09:01:37 +01:00
2014-07-16 18:34:15 +02:00
foreach ( $nameSpaces as & $value )
2014-02-17 17:11:28 +01:00
{
if ( str_replace ( $value [ 'delimiter' ], " " , $value [ 'prefix' ]) == $folderName &&
2014-05-08 10:50:48 +02:00
$value [ 'type' ] == 'others' || $value [ 'type' ] == 'shared' )
2014-02-17 17:11:28 +01:00
{
$validFolder = false ;
}
}
if ( $status && $validFolder )
{
try
{
$this -> mail_bo -> subscribe ( $folderName , $status );
2014-05-08 10:50:48 +02:00
} catch ( Exception $e )
2014-02-17 17:11:28 +01:00
{
2014-02-17 17:36:16 +01:00
$result = false ;
2014-05-08 10:50:48 +02:00
error_log ( __METHOD__ . __LINE__ . " () error " . $e -> getMessage () . " happend while subscribing to folder " . $folderName );
2014-02-17 17:11:28 +01:00
}
}
else if ( $validFolder )
{
try
{
$this -> mail_bo -> subscribe ( $folderName , $status );
2014-05-08 10:50:48 +02:00
} catch ( Exception $e )
2014-02-17 17:11:28 +01:00
{
2014-02-17 17:36:16 +01:00
$result = false ;
2014-05-08 10:50:48 +02:00
error_log ( __METHOD__ . __LINE__ . " () error " . $e -> getMessage () . " happend while unsubscribing of folder " . $folderName );
2014-02-17 17:11:28 +01:00
}
}
2014-02-17 17:36:16 +01:00
return $result ;
2014-02-17 17:11:28 +01:00
}
2014-05-20 16:28:23 +02:00
2014-02-06 18:18:12 +01:00
/**
* Subscription popup window
*
* @ param array $content
* @ param type $msg
*/
function subscription ( array $content = null , $msg = '' )
{
$stmpl = new etemplate_new ( 'mail.subscribe' );
2014-02-19 09:01:37 +01:00
2014-02-07 17:29:20 +01:00
$profileId = $_GET [ 'acc_id' ];
2014-02-19 09:01:37 +01:00
2014-05-20 15:39:04 +02:00
$allFolders = $this -> mail_bo -> getFolderObjects ( false , false , false , false );
2014-02-14 09:30:03 +01:00
$sel_options [ 'foldertree' ] = $this -> getFolderTree ( false , $profileId , false , false );
2014-02-19 09:01:37 +01:00
2014-02-06 18:18:12 +01:00
if ( ! is_array ( $content ))
{
2014-02-07 17:29:20 +01:00
if ( $profileId )
2014-02-06 18:18:12 +01:00
{
2014-02-19 09:01:37 +01:00
2014-02-07 17:29:20 +01:00
$content [ 'foldertree' ] = array ();
$content [ 'profileId' ] = $profileId ;
2014-02-19 09:01:37 +01:00
2014-02-07 17:29:20 +01:00
foreach ( $allFolders as $folder )
{
$folderName = $profileId . self :: $delimiter . $folder -> folderName ;
if ( $folder -> subscribed )
{
array_push ( $content [ 'foldertree' ], $folderName );
}
}
2014-02-06 18:18:12 +01:00
}
2014-05-09 14:43:57 +02:00
}
2014-02-06 18:18:12 +01:00
else
{
2014-02-07 17:29:20 +01:00
list ( $button ) = @ each ( $content [ 'button' ]);
switch ( $button )
{
case 'save' :
case 'apply' :
{
foreach ( $allFolders as $folder )
{
$folderName = $content [ 'profileId' ] . self :: $delimiter . $folder -> folderName ;
if ( ! in_array ( $folderName , $content [ 'foldertree' ]))
{
2014-02-17 17:36:16 +01:00
if ( $this -> setSubscribe ( $folder -> folderName , false ))
{
$msg = lang ( 'Subscription successfully saved!' );
}
else
{
$msg = lang ( 'Subscription faild!' );
}
2014-02-07 17:29:20 +01:00
}
else
{
2014-02-17 17:36:16 +01:00
if ( $this -> setSubscribe ( $folder -> folderName , true ))
{
$msg = lang ( 'Subscription successfully saved!' );
}
else
{
$msg = lang ( 'Subscription faild!' );
}
2014-02-07 17:29:20 +01:00
}
}
2014-04-24 11:23:06 +02:00
$parentFolder = 'INBOX' ;
2014-07-16 15:42:36 +02:00
2014-04-24 11:23:06 +02:00
$refreshData = array (
2014-07-16 15:42:36 +02:00
$content [ 'profileId' ] => lang ( $parentFolder )
2014-05-20 16:28:23 +02:00
);
2014-04-24 11:23:06 +02:00
// Send full info back in the response
$response = egw_json_response :: get ();
foreach ( $refreshData as $folder => & $name )
{
$name = $this -> getFolderTree ( true , $folder , true , true , false );
}
$response -> call ( 'opener.app.mail.mail_reloadNode' , $refreshData );
2014-02-17 17:36:16 +01:00
egw_framework :: refresh_opener ( $msg , 'mail' );
2014-02-07 17:29:20 +01:00
if ( $button == 'apply' ) break ;
}
case 'cancel' :
{
egw_framework :: window_close ();
}
}
2014-02-06 18:18:12 +01:00
}
2014-02-19 09:01:37 +01:00
2014-02-07 17:29:20 +01:00
$preserv [ 'profileId' ] = $content [ 'profileId' ];
2014-02-06 18:18:12 +01:00
$readonlys = array ();
2014-04-24 11:23:06 +02:00
2014-02-07 17:29:20 +01:00
$stmpl -> exec ( 'mail.mail_ui.subscription' , $content , $sel_options , $readonlys , $preserv , 2 );
2014-02-06 18:18:12 +01:00
}
2013-02-20 12:31:57 +01:00
2013-02-08 20:11:44 +01:00
/**
* Main mail page
*
2014-05-22 09:47:49 +02:00
* @ param array $content
* @ param string $msg
2013-02-08 20:11:44 +01:00
*/
function index ( array $content = null , $msg = null )
{
2014-07-18 19:18:29 +02:00
try {
//error_log(__METHOD__.__LINE__.function_backtrace());
if ( mail_bo :: $debugTimes ) $starttime = microtime ( true );
$this -> mail_bo -> restoreSessionData ();
$sessionFolder = $this -> mail_bo -> sessionData [ 'mailbox' ];
if ( $this -> mail_bo -> folderExists ( $sessionFolder ))
{
$this -> mail_bo -> reopen ( $sessionFolder ); // needed to fetch full set of capabilities
}
else
{
$sessionFolder = $this -> mail_bo -> sessionData [ 'mailbox' ] = 'INBOX' ;
}
//error_log(__METHOD__.__LINE__.' SessionFolder:'.$sessionFolder.' isToSchema:'.$toSchema);
if ( ! is_array ( $content ))
{
$content = array (
self :: $nm_index => egw_session :: appsession ( 'index' , 'mail' ),
);
if ( ! is_array ( $content [ self :: $nm_index ]))
{
$content [ self :: $nm_index ] = array (
'get_rows' => 'mail.mail_ui.get_rows' , // I method/callback to request the data for the rows eg. 'notes.bo.get_rows'
'filter' => 'any' , // filter is used to choose the mailbox
'no_filter2' => false , // I disable the 2. filter (params are the same as for filter)
'no_cat' => true , // I disable the cat-selectbox
//'cat_is_select' => 'no_lang', // true or no_lang
'lettersearch' => false , // I show a lettersearch
'searchletter' => false , // I0 active letter of the lettersearch or false for [all]
'start' => 0 , // IO position in list
'order' => 'date' , // IO name of the column to sort after (optional for the sortheaders)
'sort' => 'DESC' , // IO direction of the sort: 'ASC' or 'DESC'
//'default_cols' => 'status,attachments,subject,'.($toSchema?'toaddress':'fromaddress').',date,size', // I columns to use if there's no user or default pref (! as first char uses all but the named columns), default all columns
//'default_cols' => 'status,attachments,subject,address,date,size', // I columns to use if there's no user or default pref (! as first char uses all but the named columns), default all columns
//'csv_fields' => false, // I false=disable csv export, true or unset=enable it with auto-detected fieldnames,
//or array with name=>label or name=>array('label'=>label,'type'=>type) pairs (type is a eT widget-type)
'actions' => self :: get_actions (),
'row_id' => 'row_id' , // is a concatenation of trim($GLOBALS['egw_info']['user']['account_id']):profileID:base64_encode(FOLDERNAME):uid
'placeholder_actions' => array ( 'composeasnew' )
);
}
}
2014-07-28 23:21:23 +02:00
$content [ self :: $nm_index ][ 'num_rows' ] = 0 ; // Do not send any rows with initial request
2014-07-18 19:18:29 +02:00
$content [ self :: $nm_index ][ 'default_cols' ] = 'status,attachments,subject,address,date,size' ; // I columns to use if there's no user or default pref (! as first char uses all but the named columns), default all columns
$content [ self :: $nm_index ][ 'csv_fields' ] = false ;
if ( $msg )
{
$content [ 'msg' ] = $msg ;
}
else
{
unset ( $msg );
unset ( $content [ 'msg' ]);
}
2013-02-19 17:30:59 +01:00
2014-07-18 19:18:29 +02:00
$quota = $this -> mail_bo -> getQuotaRoot ();
2013-10-03 18:09:25 +02:00
2014-07-18 19:18:29 +02:00
if ( $quota !== false && $quota [ 'limit' ] != 'NOT SET' ) {
$quotainfo = $this -> quotaDisplay ( $quota [ 'usage' ], $quota [ 'limit' ]);
$content [ self :: $nm_index ][ 'quota' ] = $sel_options [ self :: $nm_index ][ 'quota' ] = $quotainfo [ 'text' ];
$content [ self :: $nm_index ][ 'quotainpercent' ] = $sel_options [ self :: $nm_index ][ 'quotainpercent' ] = ( string ) $quotainfo [ 'percent' ];
$content [ self :: $nm_index ][ 'quotaclass' ] = $sel_options [ self :: $nm_index ][ 'quotaclass' ] = $quotainfo [ 'class' ];
$content [ self :: $nm_index ][ 'quotanotsupported' ] = $sel_options [ self :: $nm_index ][ 'quotanotsupported' ] = " " ;
} else {
$content [ self :: $nm_index ][ 'quota' ] = $sel_options [ self :: $nm_index ][ 'quota' ] = lang ( " Quota not provided by server " );
$content [ self :: $nm_index ][ 'quotaclass' ] = $sel_options [ self :: $nm_index ][ 'quotaclass' ] = " mail_DisplayNone " ;
$content [ self :: $nm_index ][ 'quotanotsupported' ] = $sel_options [ self :: $nm_index ][ 'quotanotsupported' ] = " mail_DisplayNone " ;
}
2013-10-03 18:09:25 +02:00
2014-07-18 19:18:29 +02:00
$vacation = $this -> gatherVacation ();
//error_log(__METHOD__.__LINE__.' Server:'.self::$icServerID.' Sieve Enabled:'.array2string($vacation));
if ( $vacation ) {
if ( is_array ( $vacation ) && ( $vacation [ 'status' ] == 'on' || $vacation [ 'status' ] == 'by_date' ))
{
$dtfrmt = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ] /*.' '.($GLOBALS['egw_info']['user']['preferences']['common']['timeformat']!='24'?'h:i a':'H:i')*/ ;
$content [ self :: $nm_index ][ 'vacationnotice' ] = $sel_options [ self :: $nm_index ][ 'vacationnotice' ] = lang ( 'Vacation notice is active' );
$content [ self :: $nm_index ][ 'vacationrange' ] = $sel_options [ self :: $nm_index ][ 'vacationrange' ] = ( $vacation [ 'status' ] == 'by_date' ? common :: show_date ( $vacation [ 'start_date' ], $dtfrmt , true ) . ( $vacation [ 'end_date' ] > $vacation [ 'start_date' ] ? '->' . common :: show_date ( $vacation [ 'end_date' ] + 24 * 3600 - 1 , $dtfrmt , true ) : '' ) : '' );
}
}
if ( $vacation == false )
{
$content [ self :: $nm_index ][ 'vacationnotice' ] = $sel_options [ self :: $nm_index ][ 'vacationnotice' ] = '' ;
$content [ self :: $nm_index ][ 'vacationrange' ] = $sel_options [ self :: $nm_index ][ 'vacationrange' ] = '' ;
}
//$zstarttime = microtime (true);
$sel_options [ self :: $nm_index ][ 'foldertree' ] = $this -> getFolderTree ( 'initial' , null , ! $this -> mail_bo -> mailPreferences [ 'showAllFoldersInFolderPane' ]);
//$zendtime = microtime(true) - $zstarttime;
//error_log(__METHOD__.__LINE__. " time used: ".$zendtime);
$content [ self :: $nm_index ][ 'selectedFolder' ] = $this -> mail_bo -> profileID . self :: $delimiter . ( ! empty ( $this -> mail_bo -> sessionData [ 'mailbox' ]) ? $this -> mail_bo -> sessionData [ 'mailbox' ] : 'INBOX' );
// since we are connected,(and selected the folder) we check for capabilities SUPPORTS_KEYWORDS to eventually add the keyword filters
if ( $this -> mail_bo -> icServer -> hasCapability ( 'SUPPORTS_KEYWORDS' ))
{
$this -> statusTypes = array_merge ( $this -> statusTypes , array (
'keyword1' => 'important' , //lang('important'),
'keyword2' => 'job' , //lang('job'),
'keyword3' => 'personal' , //lang('personal'),
'keyword4' => 'to do' , //lang('to do'),
'keyword5' => 'later' , //lang('later'),
));
}
else
{
$keywords = array ( 'keyword1' , 'keyword2' , 'keyword3' , 'keyword4' , 'keyword5' );
foreach ( $keywords as & $k )
{
if ( array_key_exists ( $k , $this -> statusTypes )) unset ( $this -> statusTypes [ $k ]);
}
}
2013-02-12 18:48:04 +01:00
2014-07-18 19:18:29 +02:00
if ( ! isset ( $content [ self :: $nm_index ][ 'foldertree' ])) $content [ self :: $nm_index ][ 'foldertree' ] = $this -> mail_bo -> profileID . self :: $delimiter . 'INBOX' ;
if ( ! isset ( $content [ self :: $nm_index ][ 'selectedFolder' ])) $content [ self :: $nm_index ][ 'selectedFolder' ] = $this -> mail_bo -> profileID . self :: $delimiter . 'INBOX' ;
$content [ self :: $nm_index ][ 'foldertree' ] = $content [ self :: $nm_index ][ 'selectedFolder' ];
if ( is_null ( emailadmin_imapbase :: $supportsORinQuery ) || ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ]))
{
emailadmin_imapbase :: $supportsORinQuery = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'supportsORinQuery' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), 60 * 60 * 10 );
if ( ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ])) emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] = true ;
}
if ( ! emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ]) unset ( $this -> searchTypes [ 'quick' ]);
$sel_options [ 'filter2' ] = $this -> searchTypes ;
$sel_options [ 'filter' ] = $this -> statusTypes ;
$etpl = new etemplate_new ( 'mail.index' );
$group = 0 ;
// Set tree actions
$tree_actions = array (
'drop_move_mail' => array (
'type' => 'drop' ,
'acceptedTypes' => 'mail' ,
'icon' => 'move' ,
'caption' => 'Move to' ,
'onExecute' => 'javaScript:app.mail.mail_move'
),
'drop_copy_mail' => array (
'type' => 'drop' ,
'acceptedTypes' => 'mail' ,
'icon' => 'copy' ,
'caption' => 'Copy to' ,
'onExecute' => 'javaScript:app.mail.mail_copy'
),
'drop_cancel' => array (
'icon' => 'cancel' ,
'caption' => 'Cancel' ,
'acceptedTypes' => 'mail' ,
'type' => 'drop' ,
),
'drop_move_folder' => array (
'caption' => 'Move folder' ,
'hideOnDisabled' => true ,
'type' => 'drop' ,
'acceptedTypes' => 'mailFolder' ,
'onExecute' => 'javaScript:app.mail.mail_MoveFolder'
),
// Tree does support this one
'add' => array (
'caption' => 'Add Folder' ,
'onExecute' => 'javaScript:app.mail.mail_AddFolder' ,
'enabled' => 'javaScript:app.mail.mail_CheckFolderNoSelect' ,
),
'edit' => array (
'caption' => 'Rename Folder' ,
'onExecute' => 'javaScript:app.mail.mail_RenameFolder' ,
'enabled' => 'javaScript:app.mail.mail_CheckFolderNoSelect' ,
),
'move' => array (
'caption' => 'Move Folder' ,
'type' => 'drag' ,
'enabled' => 'javaScript:app.mail.mail_CheckFolderNoSelect' ,
'dragType' => array ( 'mailFolder' )
),
'delete' => array (
'caption' => 'Delete Folder' ,
'enabled' => 'javaScript:app.mail.mail_CheckFolderNoSelect' ,
'onExecute' => 'javaScript:app.mail.mail_DeleteFolder' ,
),
'subscribe' => array (
'caption' => 'Subscribe folder ...' ,
//'icon' => 'configure',
'enabled' => 'javaScript:app.mail.mail_CheckFolderNoSelect' ,
'onExecute' => 'javaScript:app.mail.edit_subscribe' ,
),
'unsubscribe' => array (
'caption' => 'Unsubscribe folder' ,
'enabled' => 'javaScript:app.mail.mail_CheckFolderNoSelect' ,
'onExecute' => 'javaScript:app.mail.unsubscribe_folder' ,
),
'sieve' => array (
'caption' => 'Mail filter' ,
'onExecute' => 'javaScript:app.mail.edit_sieve' ,
'group' => ++ $group , // new group for filter
'enabled' => 'javaScript:app.mail.sieve_enabled' ,
'icon' => 'etemplate/fav_filter' , // funnel
),
'vacation' => array (
'caption' => 'Vacation notice' ,
'icon' => 'mail/navbar' , // mail as in admin
'onExecute' => 'javaScript:app.mail.edit_vacation' ,
'group' => $group ,
'enabled' => 'javaScript:app.mail.sieve_enabled' ,
),
'edit_account' => array (
'caption' => 'Edit account ...' ,
'icon' => 'configure' ,
'onExecute' => 'javaScript:app.mail.edit_account' ,
'group' => ++ $group , // new groups for account & acl
),
'edit_acl' => array (
'caption' => 'Edit folder ACL ...' ,
'icon' => 'lock' ,
'enabled' => 'javaScript:app.mail.acl_enabled' ,
'onExecute' => 'javaScript:app.mail.edit_acl' ,
'group' => $group ,
),
2014-05-22 09:36:02 +02:00
);
2014-07-18 19:18:29 +02:00
// the preference prefaskformove controls actually if there is a popup on target or not
// if there are multiple options there is a popup on target, 0 for prefaskformove means
// that only move is available; 1 stands for move and cancel; 2 (should be the default if
// not set); so we are assuming this, when not set
if ( isset ( $this -> mail_bo -> mailPreferences [ 'prefaskformove' ]))
{
switch ( $this -> mail_bo -> mailPreferences [ 'prefaskformove' ])
{
case 0 :
unset ( $tree_actions [ 'drop_copy_mail' ]);
unset ( $tree_actions [ 'drop_cancel' ]);
break ;
case 1 :
unset ( $tree_actions [ 'drop_copy_mail' ]);
break ;
default :
// everything is fine
}
}
//error_log(__METHOD__.__LINE__.' showAllFoldersInFolderPane:'.$this->mail_bo->mailPreferences['showAllFoldersInFolderPane'].'/'.$GLOBALS['egw_info']['user']['preferences']['mail']['showAllFoldersInFolderPane']);
if ( $this -> mail_bo -> mailPreferences [ 'showAllFoldersInFolderPane' ])
{
unset ( $tree_actions [ 'subscribe' ]);
unset ( $tree_actions [ 'unsubscribe' ]);
}
++ $group ; // put delete in own group
switch ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'deleteOptions' ])
{
case 'move_to_trash' :
$tree_actions [ 'empty_trash' ] = array (
'caption' => 'empty trash' ,
'icon' => 'dhtmlxtree/MailFolderTrash' ,
'onExecute' => 'javaScript:app.mail.mail_emptyTrash' ,
'group' => $group ,
);
break ;
case 'mark_as_deleted' :
$tree_actions [ 'compress_folder' ] = array (
'caption' => 'compress folder' ,
'icon' => 'dhtmlxtree/MailFolderTrash' ,
'onExecute' => 'javaScript:app.mail.mail_compressFolder' ,
'group' => $group ,
);
break ;
}
2013-11-16 12:24:52 +01:00
2014-07-18 19:18:29 +02:00
// enforce global (group-specific) ACL
if ( ! mail_hooks :: access ( 'aclmanagement' ))
{
unset ( $tree_actions [ 'edit_acl' ]);
}
if ( ! mail_hooks :: access ( 'editfilterrules' ))
{
unset ( $tree_actions [ 'sieve' ]);
}
if ( ! mail_hooks :: access ( 'absentnotice' ))
{
unset ( $tree_actions [ 'vacation' ]);
}
if ( ! mail_hooks :: access ( 'managefolders' ))
{
unset ( $tree_actions [ 'add' ]);
unset ( $tree_actions [ 'move' ]);
unset ( $tree_actions [ 'delete' ]);
// manage folders should not affect the ability to subscribe or unsubscribe
// to existing folders, it should only affect add/rename/move/delete
}
2013-12-20 17:23:45 +01:00
2014-07-18 19:18:29 +02:00
$etpl -> setElementAttribute ( self :: $nm_index . '[foldertree]' , 'actions' , $tree_actions );
2013-12-17 16:21:36 +01:00
2014-07-18 19:18:29 +02:00
// sending preview toolbar actions
$etpl -> setElementAttribute ( 'mailPreview[toolbar]' , 'actions' , $this -> get_toolbar_actions ());
2014-02-27 18:47:06 +01:00
2014-07-18 19:18:29 +02:00
if ( empty ( $content [ self :: $nm_index ][ 'filter2' ]) || empty ( $content [ self :: $nm_index ][ 'search' ])) $content [ self :: $nm_index ][ 'filter2' ] = ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] ? 'quick' : 'subject' );
$readonlys = $preserv = array ();
if ( mail_bo :: $debugTimes ) mail_bo :: logRunTimes ( $starttime , null , '' , __METHOD__ . __LINE__ );
}
catch ( Exception $e )
{
self :: callWizard ( $e -> getMessage ());
}
2013-02-08 20:11:44 +01:00
return $etpl -> exec ( 'mail.mail_ui.index' , $content , $sel_options , $readonlys , $preserv );
}
2013-12-20 17:23:45 +01:00
/**
* Ajax callback to subscribe / unsubscribe a Mailbox of an account
*
2014-02-07 17:29:20 +01:00
* @ param { int } $_acc_id profile Id of selected mailbox
* @ param { string } $_folderName name of mailbox needs to be subcribe or unsubscribed
* @ param { boolean } $_status set true for subscribe and false to unsubscribe
2013-12-20 17:23:45 +01:00
*/
public function ajax_foldersubscription ( $_acc_id , $_folderName , $_status )
{
//Change the mail_bo object to related profileId
$this -> changeProfile ( $_acc_id );
if ( $this -> mail_bo -> subscribe ( $_folderName , $_status ))
{
$this -> mail_bo -> resetFolderObjectCache ( $_acc_id );
2014-02-07 09:33:23 +01:00
$this -> ajax_reloadNode ( $_acc_id , ! $this -> mail_bo -> mailPreferences [ 'showAllFoldersInFolderPane' ]);
2013-12-20 17:23:45 +01:00
}
else
{
error_log ( __METHOD__ . __LINE__ . " () " . lang ( 'Folder %1 %2 failed!' , $_folderName , $_status ? 'subscribed' : 'unsubscribed' ));
}
}
2013-02-20 13:04:29 +01:00
/**
* Ajax callback to fetch folders for given profile
*
* We currently load all folders of a given profile , tree can also load parts of a tree .
*
2014-05-22 09:47:49 +02:00
* @ param string $_nodeID if of node whos children are requested
2013-12-19 11:32:42 +01:00
* @ param boolean $_subscribedOnly flag to tell wether to fetch all or only subscribed ( default )
2013-02-20 13:04:29 +01:00
*/
2014-02-07 09:33:23 +01:00
public function ajax_foldertree ( $_nodeID = null , $_subscribedOnly = null )
2013-02-20 13:04:29 +01:00
{
2014-02-05 14:02:51 +01:00
//error_log(__METHOD__.__LINE__.':'.$_nodeID.'->'.$_subscribedOnly);
2013-02-20 17:27:10 +01:00
$nodeID = $_GET [ 'id' ];
2013-05-21 10:46:54 +02:00
if ( ! is_null ( $_nodeID )) $nodeID = $_nodeID ;
2014-02-07 09:33:23 +01:00
$subscribedOnly = ( bool )( ! is_null ( $_subscribedOnly ) ? $_subscribedOnly :! $this -> mail_bo -> mailPreferences [ 'showAllFoldersInFolderPane' ]);
2013-05-21 12:57:07 +02:00
$fetchCounters = ! is_null ( $_nodeID );
list ( $_profileID , $_folderName ) = explode ( self :: $delimiter , $nodeID , 2 );
2014-07-16 18:34:15 +02:00
unset ( $_profileID );
2013-05-21 12:57:07 +02:00
if ( ! empty ( $_folderName )) $fetchCounters = true ;
2014-01-17 13:02:03 +01:00
//error_log(__METHOD__.__LINE__.':'.$nodeID.'->'.array2string($fetchCounters));
2014-06-18 13:23:54 +02:00
$data = $this -> getFolderTree ( $fetchCounters , $nodeID , $subscribedOnly , true , true , false );
2014-01-17 13:02:03 +01:00
//error_log(__METHOD__.__LINE__.':'.$nodeID.'->'.array2string($data));
2013-05-21 10:46:54 +02:00
if ( ! is_null ( $_nodeID )) return $data ;
2014-02-05 13:23:04 +01:00
etemplate_widget_tree :: send_quote_json ( $data );
2013-02-20 13:04:29 +01:00
}
2014-07-08 13:09:31 +02:00
2013-02-11 18:05:29 +01:00
/**
* getFolderTree , get folders from server and prepare the folder tree
2014-01-13 18:29:27 +01:00
* @ param mixed bool / string $_fetchCounters , wether to fetch extended information on folders
* if set to initial , only for initial level of seen ( unfolded ) folders
2014-05-22 09:47:49 +02:00
* @ param string $_nodeID nodeID to fetch and return
2013-12-19 11:32:42 +01:00
* @ param boolean $_subscribedOnly flag to tell wether to fetch all or only subscribed ( default )
2014-02-13 17:29:37 +01:00
* @ param boolean $_returnNodeOnly only effective if $_nodeID is set , and $_nodeID is_nummeric
2014-04-24 11:23:06 +02:00
* @ param boolean _useCacheIfPossible - if set to false cache will be ignored and reinitialized
2014-06-18 13:23:54 +02:00
* @ param boolean $_popWizard Check if getFoldertree is called via open account ( TRUE ) or via tree interaction ( FALSE ), to control wizard popup
2013-02-12 15:30:58 +01:00
* @ return array something like that : array ( 'id' => 0 ,
* 'item' => array (
* 'text' => 'INBOX' ,
* 'tooltip' => 'INBOX' . ' ' . lang ( '(not connected)' ),
* 'im0' => 'kfm_home.png'
* 'item' => array ( $MORE_ITEMS )
* )
2013-02-11 18:05:29 +01:00
* );
*/
2014-06-18 13:23:54 +02:00
function getFolderTree ( $_fetchCounters = false , $_nodeID = null , $_subscribedOnly = true , $_returnNodeOnly = true , $_useCacheIfPossible = true , $_popWizard = true )
2013-02-11 18:05:29 +01:00
{
2014-02-27 17:47:23 +01:00
if ( mail_bo :: $debugTimes ) $starttime = microtime ( true );
2013-05-23 10:16:25 +02:00
if ( ! is_null ( $_nodeID ) && $_nodeID != 0 )
2013-02-20 12:31:57 +01:00
{
2013-02-20 17:27:10 +01:00
list ( $_profileID , $_folderName ) = explode ( self :: $delimiter , $_nodeID , 2 );
2014-07-16 18:34:15 +02:00
unset ( $_folderName );
2013-02-20 17:27:10 +01:00
if ( is_numeric ( $_profileID ))
{
if ( $_profileID && $_profileID != $this -> mail_bo -> profileID )
{
2013-02-28 10:28:08 +01:00
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$_profileID);
2014-05-09 14:43:57 +02:00
try
{
$this -> changeProfile ( $_profileID );
}
catch ( Exception $e )
{
2014-06-30 17:48:49 +02:00
$out = array ( 'id' => $_profileID );
$oA = array ( 'id' => $_profileID . self :: $delimiter . 'INBOX' ,
'text' => $e -> getMessage (),
'tooltip' => $e -> getMessage (),
'im0' => " folderNoSelectClosed.gif " ,
'im1' => " folderNoSelectOpen.gif " ,
'im2' => " folderNoSelectClosed.gif " ,
'path' => array ( $_profileID ),
2014-05-09 14:43:57 +02:00
'parent' => ''
);
$this -> setOutStructure ( $oA , $out , self :: $delimiter );
2014-06-30 17:48:49 +02:00
return ( $out ? $out : array ( 'id' => 0 , 'item' => array ( 'text' => 'INBOX' , 'tooltip' => 'INBOX' . ' ' . lang ( '(not connected)' ), 'im0' => 'kfm_home.png' )));
2014-05-09 14:43:57 +02:00
}
2013-02-20 17:27:10 +01:00
}
}
2013-02-20 12:31:57 +01:00
}
2013-11-19 16:14:36 +01:00
//$starttime = microtime(true);
2014-05-12 09:35:23 +02:00
$c = 0 ;
2014-05-09 14:43:57 +02:00
try
{
$folderObjects = $this -> mail_bo -> getFolderObjects ( $_subscribedOnly , false , false , $_useCacheIfPossible );
//$endtime = microtime(true) - $starttime;
//error_log(__METHOD__.__LINE__.' Fetching folderObjects took: '.$endtime);
$trashFolder = $this -> mail_bo -> getTrashFolder ();
$templateFolder = $this -> mail_bo -> getTemplateFolder ();
$draftFolder = $this -> mail_bo -> getDraftFolder ();
$sentFolder = $this -> mail_bo -> getSentFolder ();
$userDefinedFunctionFolders = array ();
if ( isset ( $trashFolder ) && $trashFolder != 'none' ) $userDefinedFunctionFolders [ 'Trash' ] = $trashFolder ;
if ( isset ( $sentFolder ) && $sentFolder != 'none' ) $userDefinedFunctionFolders [ 'Sent' ] = $sentFolder ;
if ( isset ( $draftFolder ) && $draftFolder != 'none' ) $userDefinedFunctionFolders [ 'Drafts' ] = $draftFolder ;
if ( isset ( $templateFolder ) && $templateFolder != 'none' ) $userDefinedFunctionFolders [ 'Templates' ] = $templateFolder ;
}
catch ( Exception $e )
{
2014-05-12 09:35:23 +02:00
error_log ( __LINE__ . ': ' . __METHOD__ . " () " . $e -> getMessage ());
2014-05-09 14:43:57 +02:00
$folderObjects = array ();
2014-06-18 13:23:54 +02:00
if ( $_popWizard )
{
self :: callWizard ( $e -> getMessage (), false );
}
2014-05-12 09:35:23 +02:00
$c = 1 ;
2014-05-09 14:43:57 +02:00
}
2013-02-12 14:59:39 +01:00
$out = array ( 'id' => 0 );
2013-11-07 18:46:26 +01:00
2013-05-21 12:57:07 +02:00
//$starttime = microtime(true);
2014-05-22 09:47:49 +02:00
foreach ( emailadmin_account :: search ( $only_current_user = true , false ) as $acc_id => $accountObj )
2013-11-07 18:46:26 +01:00
{
2014-04-25 11:42:18 +02:00
if ( $_profileID && $acc_id != $_profileID )
{
//error_log(__METHOD__.__LINE__.' Fetching accounts '." $acc_id != $_profileID ".'->'.$identity_name);
continue ;
}
//error_log(__METHOD__.__LINE__.array2string($accountObj));
2014-07-08 13:09:31 +02:00
if ( ! $accountObj -> is_imap ())
2014-04-25 11:42:18 +02:00
{
// not to be used for IMAP Foldertree, as there is no Imap host
continue ;
}
$identity_name = emailadmin_account :: identity_name ( $accountObj );
2013-11-07 18:46:26 +01:00
$oA = array ( 'id' => $acc_id ,
2014-02-05 14:02:51 +01:00
'text' => str_replace ( array ( '<' , '>' ), array ( '[' , ']' ), $identity_name ), // as angle brackets are quoted, display in Javascript messages when used is ugly, so use square brackets instead
2013-11-07 18:46:26 +01:00
'tooltip' => '(' . $acc_id . ') ' . htmlspecialchars_decode ( $identity_name ),
'im0' => 'thunderbird.png' ,
'im1' => 'thunderbird.png' ,
'im2' => 'thunderbird.png' ,
'path' => array ( $acc_id ),
2014-05-12 09:35:23 +02:00
'child' => ( int )( $acc_id != $_profileID || $folderObjects ), // dynamic loading on unfold
2014-05-22 09:36:02 +02:00
'parent' => '' ,
// mark on account if Sieve is enabled
'data' => array ( 'sieve' => $accountObj -> acc_sieve_enabled ),
2013-11-07 18:46:26 +01:00
);
$this -> setOutStructure ( $oA , $out , self :: $delimiter );
2014-05-12 09:35:23 +02:00
// create a fake INBOX folder showing connection error (necessary that client UI unlocks tree!)
if ( $e && $acc_id == $_profileID && ! $folderObjects )
{
$oA = array (
'id' => $acc_id . self :: $delimiter . 'INBOX' ,
'text' => lang ( $e -> getMessage ()),
'tooltip' => '(' . $acc_id . ') ' . $e -> getMessage (),
'im0' => " folderNoSelectClosed.gif " ,
'im1' => " folderNoSelectOpen.gif " ,
'im2' => " folderNoSelectClosed.gif " ,
'path' => array ( $acc_id , 'INBOX' ),
'parent' => $acc_id ,
);
$this -> setOutStructure ( $oA , $out , self :: $delimiter );
}
2013-02-19 17:30:59 +01:00
}
2013-05-21 12:57:07 +02:00
//$endtime = microtime(true) - $starttime;
2014-07-08 13:09:31 +02:00
2014-05-09 14:43:57 +02:00
if ( ! empty ( $folderObjects ))
{
$delimiter = $this -> mail_bo -> getHierarchyDelimiter ();
$cmb = $this -> mail_bo -> icServer -> getCurrentMailbox ();
$cmblevels = explode ( $delimiter , $cmb );
$cmblevelsCt = count ( $cmblevels );
}
2014-01-13 18:29:27 +01:00
//error_log(__METHOD__.__LINE__.function_backtrace());
2013-02-11 18:05:29 +01:00
foreach ( $folderObjects as $key => $obj )
{
2014-01-13 18:29:27 +01:00
//error_log(__METHOD__.__LINE__.array2string($key));
$levels = explode ( $delimiter , $key );
$levelCt = count ( $levels );
$fetchCounters = ( bool ) $_fetchCounters ;
if ( $_fetchCounters === 'initial' )
{
if ( $levelCt > $cmblevelsCt + 1 ) $fetchCounters = false ;
}
//error_log(__METHOD__.__LINE__.' fc:'.$fetchCounters.'/'.$_fetchCounters.'('.$levelCt.'/'.$cmblevelsCt.')'.' for:'.array2string($key));
2014-07-31 12:10:07 +02:00
$fS = $this -> mail_bo -> getFolderStatus ( $key , false ,( $fetchCounters ? false : true ), false );
//error_log(__METHOD__.__LINE__.'Object:'.array2string($obj));
//error_log(__METHOD__.__LINE__.'Status:'.array2string($fS));
//error_log(__METHOD__.__LINE__."-------------------------");
2013-02-12 14:01:43 +01:00
$fFP = $folderParts = explode ( $obj -> delimiter , $key );
2013-11-27 14:07:54 +01:00
if ( in_array ( $key , $userDefinedFunctionFolders )) $obj -> shortDisplayName = lang ( $obj -> shortDisplayName );
2013-02-12 14:01:43 +01:00
//get rightmost folderpart
2014-05-22 09:47:49 +02:00
array_pop ( $folderParts );
2013-02-12 14:01:43 +01:00
// the rest of the array is the name of the parent
$parentName = implode (( array ) $folderParts , $obj -> delimiter );
2013-02-20 17:27:10 +01:00
$parentName = $this -> mail_bo -> profileID . self :: $delimiter . $parentName ;
2013-02-12 14:01:43 +01:00
$oA = array ( 'text' => $obj -> shortDisplayName , 'tooltip' => $obj -> displayName );
2013-02-19 17:30:59 +01:00
array_unshift ( $fFP , $this -> mail_bo -> profileID );
2013-02-12 14:01:43 +01:00
$oA [ 'path' ] = $fFP ;
2014-07-16 15:42:36 +02:00
$path = $key ;
2013-02-11 18:05:29 +01:00
if ( $path == 'INBOX' )
{
2013-02-12 15:30:58 +01:00
$oA [ 'im0' ] = $oA [ 'im1' ] = $oA [ 'im2' ] = " kfm_home.png " ;
2014-05-22 09:36:02 +02:00
// mark on inbox if ACL is supported
$oA [ 'data' ] = array ( 'acl' => $this -> mail_bo -> icServer -> queryCapability ( 'ACL' ));
2013-02-11 18:05:29 +01:00
}
elseif ( in_array ( $obj -> shortFolderName , mail_bo :: $autoFolders ))
{
2014-01-27 13:18:16 +01:00
$oA [ 'text' ] = lang ( $oA [ 'text' ]);
2014-07-16 15:42:36 +02:00
2013-02-12 15:30:58 +01:00
$oA [ 'im0' ] = $oA [ 'im1' ] = $oA [ 'im2' ] = " MailFolder " . $obj -> shortFolderName . " .png " ;
2013-02-11 18:05:29 +01:00
}
elseif ( in_array ( $key , $userDefinedFunctionFolders ))
{
$_key = array_search ( $key , $userDefinedFunctionFolders );
2013-02-12 15:30:58 +01:00
$oA [ 'im0' ] = $oA [ 'im1' ] = $oA [ 'im2' ] = " MailFolder " . $_key . " .png " ;
2013-02-11 18:05:29 +01:00
}
else
{
2014-01-09 09:36:22 +01:00
$oA [ 'im0' ] = " MailFolderPlain.png " ; // one Level
2013-02-12 09:28:04 +01:00
$oA [ 'im1' ] = " folderOpen.gif " ;
$oA [ 'im2' ] = " MailFolderClosed.png " ; // has Children
2013-02-11 18:05:29 +01:00
}
2014-02-05 13:23:04 +01:00
if ( $fS [ 'unseen' ])
{
$oA [ 'text' ] = $oA [ 'text' ] . ' (' . $fS [ 'unseen' ] . ')' ;
$oA [ 'style' ] = 'font-weight: bold' ;
}
2014-07-16 15:42:36 +02:00
$path = $this -> mail_bo -> profileID . self :: $delimiter . $key ;
2013-02-12 14:01:43 +01:00
$oA [ 'id' ] = $path ; // ID holds the PATH
2013-02-28 10:28:08 +01:00
if ( ! empty ( $fS [ 'attributes' ]) && stripos ( array2string ( $fS [ 'attributes' ]), '\noselect' ) !== false )
2013-02-13 15:02:02 +01:00
{
$oA [ 'im0' ] = " folderNoSelectClosed.gif " ; // one Level
$oA [ 'im1' ] = " folderNoSelectOpen.gif " ;
$oA [ 'im2' ] = " folderNoSelectClosed.gif " ; // has Children
}
2013-02-28 10:28:08 +01:00
if ( ! empty ( $fS [ 'attributes' ]) && stripos ( array2string ( $fS [ 'attributes' ]), '\hasnochildren' ) === false )
2013-02-12 14:01:43 +01:00
{
$oA [ 'child' ] = 1 ; // translates to: hasChildren -> dynamicLoading
}
$oA [ 'parent' ] = $parentName ;
2014-06-30 17:48:49 +02:00
2013-02-12 14:59:39 +01:00
$this -> setOutStructure ( $oA , $out , $obj -> delimiter );
2013-02-12 15:30:58 +01:00
$c ++ ;
2013-02-12 14:01:43 +01:00
}
2014-02-14 09:30:03 +01:00
if ( ! is_null ( $_nodeID ) && $_nodeID != 0 && $_returnNodeOnly == true )
2013-02-20 17:27:10 +01:00
{
$node = self :: findNode ( $out , $_nodeID );
2013-05-21 12:57:07 +02:00
//error_log(__METHOD__.__LINE__.':'.$_nodeID.'->'.array2string($node));
2014-02-27 17:47:23 +01:00
if ( mail_bo :: $debugTimes ) mail_bo :: logRunTimes ( $starttime , null , 'return subtree for:' . $_nodeID , __METHOD__ . __LINE__ );
2013-02-20 17:27:10 +01:00
return $node ;
}
2014-02-27 17:47:23 +01:00
if ( mail_bo :: $debugTimes ) mail_bo :: logRunTimes ( $starttime , null , function_backtrace (), __METHOD__ . __LINE__ );
2013-02-12 15:30:58 +01:00
return ( $c ? $out : array ( 'id' => 0 , 'item' => array ( 'text' => 'INBOX' , 'tooltip' => 'INBOX' . ' ' . lang ( '(not connected)' ), 'im0' => 'kfm_home.png' )));
2013-02-12 14:01:43 +01:00
}
2013-02-11 18:05:29 +01:00
2013-02-20 17:27:10 +01:00
/**
* findNode - helper function to return only a branch of the tree
*
2014-05-22 09:47:49 +02:00
* @ param array $_out out array ( to be searched )
* @ param string $_nodeID node to search for
* @ param boolean $childElements return node itself , or only its child items
2013-02-20 17:27:10 +01:00
* @ return array structured subtree
*/
static function findNode ( $_out , $_nodeID , $childElements = false )
{
foreach ( $_out [ 'item' ] as $node )
{
2013-05-28 11:32:23 +02:00
if ( strcmp ( $node [ 'id' ], $_nodeID ) === 0 )
2013-02-20 17:27:10 +01:00
{
2013-05-23 10:16:25 +02:00
//error_log(__METHOD__.__LINE__.':'.$_nodeID.'->'.$node['id']);
2013-02-20 17:27:10 +01:00
return ( $childElements ? $node [ 'item' ] : $node );
}
2013-05-21 10:46:54 +02:00
elseif ( is_array ( $node [ 'item' ]) && strncmp ( $node [ 'id' ], $_nodeID , strlen ( $node [ 'id' ])) === 0 && strlen ( $_nodeID ) > strlen ( $node [ 'id' ]))
{
//error_log(__METHOD__.__LINE__.' descend into '.$node['id']);
return self :: findNode ( $node , $_nodeID , $childElements );
}
2013-02-20 17:27:10 +01:00
}
}
2013-02-12 15:30:58 +01:00
/**
* setOutStructure - helper function to transform the folderObjectList to dhtmlXTreeObject requirements
*
2014-05-22 09:47:49 +02:00
* @ param array $data data to be processed
2013-02-12 15:30:58 +01:00
* @ param array & $out , out array
2014-05-22 09:47:49 +02:00
* @ param string $del needed as glue for parent / child operation / comparsion
2014-05-22 16:46:50 +02:00
* @ param boolean $createMissingParents a missing parent , instead of throwing an exception
2013-02-12 15:30:58 +01:00
* @ return void
*/
2013-02-12 16:10:50 +01:00
function setOutStructure ( $data , & $out , $del = '.' , $createMissingParents = true )
2013-02-12 14:01:43 +01:00
{
2013-02-12 15:30:58 +01:00
//error_log(__METHOD__."(".array2string($data).', '.array2string($out).", '$del')");
2013-02-12 14:59:39 +01:00
$components = $data [ 'path' ];
array_pop ( $components ); // remove own name
$insert = & $out ;
$parents = array ();
foreach ( $components as $component )
2013-02-12 14:01:43 +01:00
{
2013-02-20 17:27:10 +01:00
if ( count ( $parents ) > 1 )
{
$helper = array_slice ( $parents , 1 , null , true );
$parent = $parents [ 0 ] . self :: $delimiter . implode ( $del , $helper );
if ( $parent ) $parent .= $del ;
}
else
{
$parent = implode ( self :: $delimiter , $parents );
if ( $parent ) $parent .= self :: $delimiter ;
}
2013-07-20 15:46:17 +02:00
2013-02-19 17:30:59 +01:00
if ( ! is_array ( $insert ) || ! isset ( $insert [ 'item' ]))
{
2013-05-21 12:57:07 +02:00
// throwing an exeption here seems to be unrecoverable, even if the cause is a something that can be handeled by the mailserver
error_log ( __METHOD__ . ':' . __LINE__ . " id= $data[id] : Parent ' $parent ' of ' $component ' not found! " );
break ;
2013-02-19 17:30:59 +01:00
}
2013-02-12 15:30:58 +01:00
foreach ( $insert [ 'item' ] as & $item )
2013-02-12 14:01:43 +01:00
{
2013-02-12 14:59:39 +01:00
if ( $item [ 'id' ] == $parent . $component )
2013-02-12 14:01:43 +01:00
{
2013-02-12 15:30:58 +01:00
$insert =& $item ;
2013-02-12 14:59:39 +01:00
break ;
2013-02-12 14:01:43 +01:00
}
}
2013-02-12 16:10:50 +01:00
if ( $item [ 'id' ] != $parent . $component )
{
if ( $createMissingParents )
{
unset ( $item );
2014-02-11 16:28:14 +01:00
$item = array ( 'id' => $parent . $component , 'text' => $component , 'im0' => " folderNoSelectClosed.gif " , 'im1' => " folderNoSelectOpen.gif " , 'im2' => " folderNoSelectClosed.gif " , 'tooltip' => lang ( 'no access' ));
2013-02-12 16:10:50 +01:00
$insert [ 'item' ][] =& $item ;
$insert =& $item ;
}
else
{
throw new egw_exception_assertion_failed ( __METHOD__ . ':' . __LINE__ . " : id= $data[id] : Parent ' $parent ' ' $component ' not found! " );
}
}
2013-02-12 14:59:39 +01:00
$parents [] = $component ;
2013-02-11 18:05:29 +01:00
}
2013-02-12 14:59:39 +01:00
unset ( $data [ 'path' ]);
$insert [ 'item' ][] = $data ;
2013-02-12 15:30:58 +01:00
//error_log(__METHOD__."() leaving with out=".array2string($out));
2013-02-11 18:05:29 +01:00
}
2013-02-08 20:11:44 +01:00
/**
* Get actions / context menu for index
*
2013-08-21 12:47:20 +02:00
* Changes here , require to log out , as $content [ self :: $nm_index ] get stored in session !
2013-02-08 20:11:44 +01:00
* @ return array see nextmatch_widget :: egw_actions ()
*/
2014-07-16 18:34:15 +02:00
private function get_actions ()
2013-02-08 20:11:44 +01:00
{
2014-07-16 18:34:15 +02:00
static $accArray = array (); // buffer identity names on single request
2013-02-08 20:11:44 +01:00
// duplicated from mail_hooks
static $deleteOptions = array (
'move_to_trash' => 'move to trash' ,
'mark_as_deleted' => 'mark as deleted' ,
'remove_immediately' => 'remove immediately' ,
);
// todo: real hierarchical folder list
$lastFolderUsedForMove = null ;
2014-05-20 12:02:21 +02:00
$moveactions = array ();
$lastFoldersUsedForMoveCont = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'lastFolderUsedForMove' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), $expiration = 60 * 60 * 1 );
//error_log(__METHOD__.__LINE__." StoredFolders->".array2string($lastFoldersUsedForMoveCont));
2014-05-20 13:47:18 +02:00
//error_log(__METHOD__.__LINE__.' ProfileId:'.$this->mail_bo->profileID." StoredFolders->(".count($lastFoldersUsedForMoveCont[$this->mail_bo->profileID]).") ".array2string($lastFoldersUsedForMoveCont[$this->mail_bo->profileID]));
2014-05-20 12:02:21 +02:00
if ( is_null ( $accArray ))
2013-02-08 20:11:44 +01:00
{
2014-07-16 18:34:15 +02:00
foreach ( emailadmin_account :: search ( $only_current_user = true , false ) as $acc_id => $accountObj )
2013-02-08 20:11:44 +01:00
{
2014-05-20 12:02:21 +02:00
//error_log(__METHOD__.__LINE__.array2string($accountObj));
2014-07-08 13:09:31 +02:00
if ( ! $accountObj -> is_imap ())
2014-05-20 12:02:21 +02:00
{
// not to be used for IMAP Foldertree, as there is no Imap host
continue ;
}
$identity_name = emailadmin_account :: identity_name ( $accountObj );
$accArray [ $acc_id ] = str_replace ( array ( '<' , '>' ), array ( '[' , ']' ), $identity_name ); // as angle brackets are quoted, display in Javascript messages when used is ugly, so use square brackets instead
2013-02-08 20:11:44 +01:00
}
}
2014-05-20 12:02:21 +02:00
if ( ! is_array ( $lastFoldersUsedForMoveCont )) $lastFoldersUsedForMoveCont = array ();
foreach ( $lastFoldersUsedForMoveCont as $pid => $info )
{
if ( $this -> mail_bo -> profileID == $pid && isset ( $lastFoldersUsedForMoveCont [ $this -> mail_bo -> profileID ]))
{
$_folder = $this -> mail_bo -> icServer -> getCurrentMailbox ();
//error_log(__METHOD__.__LINE__.' '.$_folder."<->".$lastFoldersUsedForMoveCont[$this->mail_bo->profileID].function_backtrace());
$counter = 1 ;
foreach ( $lastFoldersUsedForMoveCont [ $this -> mail_bo -> profileID ] as $i => $lastFolderUsedForMoveCont )
{
$moveaction = 'move_' ;
if ( $_folder != $i )
{
$moveaction .= $lastFolderUsedForMoveCont ;
2014-05-21 13:24:34 +02:00
2014-07-16 15:42:36 +02:00
if ( $this -> mail_bo -> folderExists ( $i )) // only 4 entries per mailaccount.Control this on setting the buffered folders
2014-05-20 12:02:21 +02:00
{
$fS [ 'profileID' ] = $this -> mail_bo -> profileID ;
$fS [ 'profileName' ] = $accArray [ $this -> mail_bo -> profileID ];
$fS [ 'shortDisplayName' ] = $i ;
$moveactions [ $moveaction ] = $fS ;
$counter ++ ;
}
else
{
unset ( $lastFoldersUsedForMoveCont [ $this -> mail_bo -> profileID ][ $i ]);
}
//error_log(array2string($moveactions[$moveaction]));
}
}
}
elseif ( $this -> mail_bo -> profileID != $pid && isset ( $lastFoldersUsedForMoveCont [ $pid ]) && ! empty ( $lastFoldersUsedForMoveCont [ $pid ]))
{
$counter = 1 ;
foreach ( $lastFoldersUsedForMoveCont [ $pid ] as $i => $lastFolderUsedForMoveCont )
{
//error_log(__METHOD__.__LINE__."$i => $lastFolderUsedForMoveCont");
2014-07-16 15:42:36 +02:00
if ( ! empty ( $lastFolderUsedForMoveCont )) // only 4 entries per mailaccount.Control this on setting the buffered folders
2014-05-20 12:02:21 +02:00
{
$moveaction = 'move_' ;
$fS = array ();
$fS [ 'profileID' ] = $pid ;
$fS [ 'profileName' ] = $accArray [ $pid ];
$fS [ 'shortDisplayName' ] = $i ;
$moveactions [ $moveaction ] = $fS ;
$counter ++ ;
}
}
}
}
egw_cache :: setCache ( egw_cache :: INSTANCE , 'email' , 'lastFolderUsedForMove' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), $lastFoldersUsedForMoveCont , $expiration = 60 * 60 * 1 );
2014-07-16 18:34:15 +02:00
$group = 0 ;
2013-02-08 20:11:44 +01:00
$actions = array (
'open' => array (
'caption' => lang ( 'Open' ),
2013-10-10 13:44:01 +02:00
'icon' => 'view' ,
2013-02-08 20:11:44 +01:00
'group' => ++ $group ,
2013-04-12 12:35:40 +02:00
'onExecute' => 'javaScript:app.mail.mail_open' ,
2013-02-08 20:11:44 +01:00
'allowOnMultiple' => false ,
'default' => true ,
),
'reply' => array (
'caption' => 'Reply' ,
'icon' => 'mail_reply' ,
'group' => ++ $group ,
2013-04-09 16:43:55 +02:00
'onExecute' => 'javaScript:app.mail.mail_compose' ,
2013-02-08 20:11:44 +01:00
'allowOnMultiple' => false ,
2014-02-10 16:47:27 +01:00
'toolbarDefault' => true
2013-02-08 20:11:44 +01:00
),
'reply_all' => array (
'caption' => 'Reply All' ,
'icon' => 'mail_replyall' ,
'group' => $group ,
2013-04-09 16:43:55 +02:00
'onExecute' => 'javaScript:app.mail.mail_compose' ,
2013-02-08 20:11:44 +01:00
'allowOnMultiple' => false ,
),
'forward' => array (
'caption' => 'Forward' ,
'icon' => 'mail_forward' ,
'group' => $group ,
'children' => array (
'forwardinline' => array (
2014-02-13 12:30:05 +01:00
'caption' => 'Inline' ,
2013-02-08 20:11:44 +01:00
'icon' => 'mail_forward' ,
'group' => $group ,
2014-02-10 14:06:49 +01:00
'hint' => 'forward inline' ,
2013-04-09 16:43:55 +02:00
'onExecute' => 'javaScript:app.mail.mail_compose' ,
2013-02-08 20:11:44 +01:00
'allowOnMultiple' => false ,
2014-02-10 16:47:27 +01:00
'toolbarDefault' => true
2013-02-08 20:11:44 +01:00
),
'forwardasattach' => array (
2014-02-13 12:30:05 +01:00
'caption' => 'Attachment' ,
2014-02-10 14:06:49 +01:00
'hint' => 'forward as attachment' ,
2013-02-08 20:11:44 +01:00
'icon' => 'mail_forward' ,
'group' => $group ,
2013-04-09 16:43:55 +02:00
'onExecute' => 'javaScript:app.mail.mail_compose' ,
2013-02-08 20:11:44 +01:00
),
),
),
'composeasnew' => array (
2014-02-10 14:06:49 +01:00
'caption' => 'Compose' ,
2013-02-08 20:11:44 +01:00
'icon' => 'new' ,
2014-02-10 14:06:49 +01:00
'hint' => 'Compose as new' ,
2013-02-08 20:11:44 +01:00
'group' => $group ,
2013-04-09 16:43:55 +02:00
'onExecute' => 'javaScript:app.mail.mail_compose' ,
2013-02-08 20:11:44 +01:00
'allowOnMultiple' => false ,
2014-05-20 12:02:21 +02:00
)
);
$macounter = 0 ;
if ( ! empty ( $moveactions ))
{
//error_log(__METHOD__.__LINE__.array2string($moveactions));
$children = array ();
$pID = 0 ;
foreach ( $moveactions as $moveaction => $lastFolderUsedForMove )
{
$group = ( $pID != $lastFolderUsedForMove [ 'profileID' ] && $macounter > 0 ? $group + 1 : $group );
//error_log(__METHOD__.__LINE__."#$pID != ".$lastFolderUsedForMove['profileID']."#".$macounter.'#'.$groupCounter.'#');
$children = array_merge ( $children ,
array (
$moveaction => array (
'caption' => ( ! empty ( $lastFolderUsedForMove [ 'profileName' ]) ? $lastFolderUsedForMove [ 'profileName' ] : '(' . $lastFolderUsedForMove [ 'profileID' ] . ')' ) . ': ' . ( isset ( $lastFolderUsedForMove [ 'shortDisplayName' ]) ? $lastFolderUsedForMove [ 'shortDisplayName' ] : '' ),
'icon' => 'move' ,
'group' => $group ,
'onExecute' => 'javaScript:app.mail.mail_move2folder' ,
'allowOnMultiple' => true ,
)
)
);
$pID = $lastFolderUsedForMove [ 'profileID' ];
$macounter ++ ;
}
$actions = array_merge ( $actions , array ( 'moveto' =>
array (
'caption' => lang ( 'Move selected to' ),
'icon' => 'move' ,
'group' => $group ++ ,
'children' => $children ,
)
)
);
}
$actions = array_merge ( $actions ,
array (
'infolog' => array (
'caption' => 'InfoLog' ,
'hint' => 'Save as InfoLog' ,
'icon' => 'infolog/navbar' ,
'group' => ++ $group ,
'onExecute' => 'javaScript:app.mail.mail_infolog' ,
'url' => 'menuaction=infolog.infolog_ui.import_mail' ,
'popup' => egw_link :: get_registry ( 'infolog' , 'add_popup' ),
'allowOnMultiple' => false ,
'toolbarDefault' => true
2013-02-08 20:11:44 +01:00
),
2014-05-20 12:02:21 +02:00
'tracker' => array (
'caption' => 'Tracker' ,
'hint' => 'Save as ticket' ,
'group' => $group ,
'icon' => 'tracker/navbar' ,
'onExecute' => 'javaScript:app.mail.mail_tracker' ,
'url' => 'menuaction=tracker.tracker_ui.import_mail' ,
'popup' => egw_link :: get_registry ( 'tracker' , 'add_popup' ),
'allowOnMultiple' => false ,
),
'print' => array (
'caption' => 'Print' ,
'group' => ++ $group ,
'onExecute' => 'javaScript:app.mail.mail_print' ,
'allowOnMultiple' => false ,
),
'save' => array (
'caption' => 'Save' ,
'group' => $group ,
'icon' => 'fileexport' ,
'children' => array (
'save2disk' => array (
'caption' => 'Save to disk' ,
'hint' => 'Save message to disk' ,
'group' => $group ,
'icon' => 'fileexport' ,
'onExecute' => 'javaScript:app.mail.mail_save' ,
'allowOnMultiple' => false ,
),
'save2filemanager' => array (
'caption' => 'Filemanager' ,
'hint' => 'Save message to filemanager' ,
'group' => $group ,
'icon' => 'filemanager/navbar' ,
'onExecute' => 'javaScript:app.mail.mail_save2fm' ,
'allowOnMultiple' => false ,
),
2013-05-13 16:42:42 +02:00
),
2013-02-08 20:11:44 +01:00
),
2014-05-20 12:02:21 +02:00
'view' => array (
'caption' => 'View' ,
'group' => $group ,
'icon' => 'kmmsgread' ,
'children' => array (
'header' => array (
'caption' => 'Header' ,
'hint' => 'View header lines' ,
'group' => $group ,
'icon' => 'kmmsgread' ,
'onExecute' => 'javaScript:app.mail.mail_header' ,
'allowOnMultiple' => false ,
),
'mailsource' => array (
'caption' => 'Source' ,
'hint' => 'View full Mail Source' ,
'group' => $group ,
'icon' => 'source' ,
'onExecute' => 'javaScript:app.mail.mail_mailsource' ,
'allowOnMultiple' => false ,
),
'openastext' => array (
'caption' => lang ( 'Text mode' ),
'hint' => 'Open in Text mode' ,
'group' => ++ $group ,
'icon' => 'textmode' ,
'onExecute' => 'javaScript:app.mail.mail_openAsText' ,
'allowOnMultiple' => false ,
),
'openashtml' => array (
'caption' => lang ( 'HTML mode' ),
'hint' => 'Open in HTML mode' ,
'group' => $group ,
'icon' => 'htmlmode' ,
'onExecute' => 'javaScript:app.mail.mail_openAsHtml' ,
'allowOnMultiple' => false ,
2013-02-08 20:11:44 +01:00
),
),
2014-05-20 12:02:21 +02:00
),
'mark' => array (
'caption' => 'Set / Remove Flags' ,
'icon' => 'read_small' ,
'group' => ++ $group ,
'children' => array (
// icons used from http://creativecommons.org/licenses/by-sa/3.0/
// Artist: Led24
// Iconset Homepage: http://led24.de/iconset
// License: CC Attribution 3.0
'setLabel' => array (
'caption' => 'Set / Remove Labels' ,
'icon' => 'tag_message' ,
'group' => ++ $group ,
'children' => array (
'unlabel' => array (
'group' => ++ $group ,
'caption' => " <font color='#ff0000'> " . lang ( 'remove all' ) . " </font> " ,
'icon' => 'mail_label' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
'shortcut' => egw_keymanager :: shortcut ( egw_keymanager :: _0 , true , true ),
),
'label1' => array (
'group' => ++ $group ,
'caption' => " <font color='#ff0000'> " . lang ( 'important' ) . " </font> " ,
'icon' => 'mail_label1' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
'shortcut' => egw_keymanager :: shortcut ( egw_keymanager :: _1 , true , true ),
),
'label2' => array (
'group' => $group ,
'caption' => " <font color='#ff8000'> " . lang ( 'job' ) . " </font> " ,
'icon' => 'mail_label2' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
'shortcut' => egw_keymanager :: shortcut ( egw_keymanager :: _2 , true , true ),
),
'label3' => array (
'group' => $group ,
'caption' => " <font color='#008000'> " . lang ( 'personal' ) . " </font> " ,
'icon' => 'mail_label3' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
'shortcut' => egw_keymanager :: shortcut ( egw_keymanager :: _3 , true , true ),
),
'label4' => array (
'group' => $group ,
'caption' => " <font color='#0000ff'> " . lang ( 'to do' ) . " </font> " ,
'icon' => 'mail_label4' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
'shortcut' => egw_keymanager :: shortcut ( egw_keymanager :: _4 , true , true ),
),
'label5' => array (
'group' => $group ,
'caption' => " <font color='#8000ff'> " . lang ( 'later' ) . " </font> " ,
'icon' => 'mail_label5' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
'shortcut' => egw_keymanager :: shortcut ( egw_keymanager :: _5 , true , true ),
),
2013-02-08 20:11:44 +01:00
),
),
2014-05-20 12:02:21 +02:00
// modified icons from http://creativecommons.org/licenses/by-sa/3.0/
'flagged' => array (
'group' => ++ $group ,
'caption' => 'Flag / Unflag' ,
'icon' => 'unread_flagged_small' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
'hint' => 'Flag or Unflag a mail' ,
'shortcut' => egw_keymanager :: shortcut ( egw_keymanager :: F , true , true ),
'toolbarDefault' => true
),
'read' => array (
'group' => $group ,
'caption' => 'Read / Unread' ,
'icon' => 'read_small' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
'shortcut' => egw_keymanager :: shortcut ( egw_keymanager :: U , true , true ),
2013-12-06 11:35:39 +01:00
2014-05-20 12:02:21 +02:00
),
'undelete' => array (
'group' => $group ,
'caption' => 'Undelete' ,
'icon' => 'revert' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
),
2013-02-08 20:11:44 +01:00
),
),
2014-05-20 12:02:21 +02:00
'delete' => array (
'caption' => 'Delete' ,
'hint' => $deleteOptions [ $this -> mail_bo -> mailPreferences [ 'deleteOptions' ]],
'group' => ++ $group ,
'onExecute' => 'javaScript:app.mail.mail_delete' ,
'toolbarDefault' => true
),
'drag_mail' => array (
'dragType' => array ( 'mail' , 'file' ),
'type' => 'drag' ,
'onExecute' => 'javaScript:app.mail.mail_dragStart' ,
)
2013-04-12 12:35:40 +02:00
)
2013-02-08 20:11:44 +01:00
);
2014-05-20 12:02:21 +02:00
//error_log(__METHOD__.__LINE__.array2string(array_keys($actions)));
2013-02-08 20:11:44 +01:00
// save as tracker, save as infolog, as this are actions that are either available for all, or not, we do that for all and not via css-class disabling
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'infolog' ]))
{
unset ( $actions [ 'infolog' ]);
}
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'tracker' ]))
{
unset ( $actions [ 'tracker' ]);
}
// note this one is NOT a real CAPABILITY reported by the server, but added by selectMailbox
if ( ! $this -> mail_bo -> icServer -> hasCapability ( 'SUPPORTS_KEYWORDS' ))
{
unset ( $actions [ 'mark' ][ 'children' ][ 'setLabel' ]);
unset ( $actions [ 'mark' ][ 'children' ][ 'unsetLabel' ]);
}
2013-02-14 18:10:20 +01:00
return $actions ;
2013-02-08 20:11:44 +01:00
}
/**
* Callback to fetch the rows for the nextmatch widget
*
* @ param array $query
* @ param array & $rows
* @ param array & $readonlys
*/
function get_rows ( $query , & $rows , & $readonlys )
{
2014-05-22 09:47:49 +02:00
unset ( $query [ 'actions' ]);
2014-07-16 15:42:36 +02:00
//error_log(__METHOD__.__LINE__.' SelectedFolder:'.$query['selectedFolder'].' Start:'.$query['start'].' NumRows:'.$query['num_rows'].array2string($query['order']).'->'.array2string($query['sort']));
2014-02-27 13:16:23 +01:00
if ( mail_bo :: $debugTimes ) $starttime = microtime ( true );
2013-02-12 18:48:04 +01:00
//$query['search'] is the phrase in the searchbox
2013-02-08 20:11:44 +01:00
$this -> mail_bo -> restoreSessionData ();
$maxMessages = 50 ; // match the hardcoded setting for data retrieval as inital value
2013-11-19 12:17:32 +01:00
if ( isset ( $query [ 'selectedFolder' ])) $this -> mail_bo -> sessionData [ 'mailbox' ] = $query [ 'selectedFolder' ];
2013-02-12 18:48:04 +01:00
$this -> mail_bo -> saveSessionData ();
2013-02-08 20:11:44 +01:00
$sRToFetch = null ;
2013-11-19 12:17:32 +01:00
$_folderName = ( ! empty ( $query [ 'selectedFolder' ]) ? $query [ 'selectedFolder' ] : $this -> mail_bo -> profileID . self :: $delimiter . 'INBOX' );
2013-02-20 17:27:10 +01:00
list ( $_profileID , $folderName ) = explode ( self :: $delimiter , $_folderName , 2 );
2014-07-16 18:34:15 +02:00
if ( strpos ( $folderName , self :: $delimiter ) !== false )
{
list ( $app , $_profileID , $folderName ) = explode ( self :: $delimiter , $_folderName , 3 );
unset ( $app );
}
2013-02-20 17:27:10 +01:00
if ( is_numeric ( $_profileID ))
2013-02-19 17:30:59 +01:00
{
2013-02-20 17:27:10 +01:00
if ( $_profileID && $_profileID != $this -> mail_bo -> profileID )
{
2013-02-28 10:28:08 +01:00
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$_profileID);
2014-05-09 14:43:57 +02:00
try
{
$this -> changeProfile ( $_profileID );
}
catch ( Exception $e )
{
$rows = array ();
return 0 ;
}
2013-02-20 17:27:10 +01:00
}
2013-11-19 12:17:32 +01:00
$_folderName = ( ! empty ( $folderName ) ? $folderName : 'INBOX' );
2013-02-19 17:30:59 +01:00
}
//save selected Folder to sessionData (mailbox)->currentFolder
2013-11-19 12:17:32 +01:00
if ( isset ( $query [ 'selectedFolder' ])) $this -> mail_bo -> sessionData [ 'mailbox' ] = $_folderName ;
2013-12-10 16:59:54 +01:00
$toSchema = false ; //decides to select list schema with column to selected (if false fromaddress is default)
2014-02-05 10:14:05 +01:00
if ( $this -> mail_bo -> folderExists ( $_folderName , true ))
2013-12-10 16:59:54 +01:00
{
$toSchema = $this -> mail_bo -> isDraftFolder ( $_folderName ) || $this -> mail_bo -> isSentFolder ( $_folderName ) || $this -> mail_bo -> isTemplateFolder ( $_folderName );
}
2013-12-12 14:34:35 +01:00
else
{
2014-02-05 10:14:05 +01:00
error_log ( __METHOD__ . __LINE__ . ' Test on Folder:' . $_folderName . ' failed; Using INBOX instead' );
2013-12-12 14:34:35 +01:00
$query [ 'selectedFolder' ] = $this -> mail_bo -> sessionData [ 'mailbox' ] = $_folderName = 'INBOX' ;
}
$this -> mail_bo -> saveSessionData ();
2013-02-08 20:11:44 +01:00
$rowsFetched [ 'messages' ] = null ;
$offset = $query [ 'start' ] + 1 ; // we always start with 1
$maxMessages = $query [ 'num_rows' ];
2013-12-10 16:59:54 +01:00
//error_log(__METHOD__.__LINE__.$query['order']);
$sort = ( $query [ 'order' ] == 'address' ? ( $toSchema ? 'toaddress' : 'fromaddress' ) : $query [ 'order' ]);
2013-05-21 10:46:54 +02:00
if ( ! empty ( $query [ 'search' ]))
{
2014-04-11 15:52:58 +02:00
if ( is_null ( emailadmin_imapbase :: $supportsORinQuery ) || ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ]))
{
2014-05-22 09:47:49 +02:00
emailadmin_imapbase :: $supportsORinQuery = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'supportsORinQuery' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), 60 * 60 * 10 );
2014-07-16 15:42:36 +02:00
if ( ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ]))
{
emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] = true ;
}
2014-04-11 15:52:58 +02:00
}
2014-07-16 15:42:36 +02:00
$filter = array (
'filterName' => ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] ? lang ( 'quicksearch' ) : lang ( 'subject' )),
'type' => ( $query [ 'filter2' ] ? $query [ 'filter2' ] : ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] ? 'quick' : 'subject' )),
'string' => $query [ 'search' ],
'status' => 'any' );
2013-05-21 10:46:54 +02:00
}
else
{
$filter = array ();
}
2013-07-18 10:35:38 +02:00
if ( $query [ 'filter' ])
{
$filter [ 'status' ] = $query [ 'filter' ];
}
2013-09-23 10:33:30 +02:00
$reverse = ( $query [ 'sort' ] == 'ASC' ? false : true );
2013-02-08 20:11:44 +01:00
//error_log(__METHOD__.__LINE__.' maxMessages:'.$maxMessages.' Offset:'.$offset.' Filter:'.array2string($this->sessionData['messageFilter']));
2014-05-09 14:43:57 +02:00
try
2013-02-08 20:11:44 +01:00
{
2014-05-09 14:43:57 +02:00
if ( $maxMessages > 75 )
{
$_sR = $this -> mail_bo -> getSortedList (
$_folderName ,
$sort ,
$reverse ,
$filter ,
$rByUid = true
);
$rowsFetched [ 'messages' ] = $_sR [ 'count' ];
$sR = $_sR [ 'match' ] -> ids ;
// if $sR is false, something failed fundamentally
if ( $reverse === true ) $sR = ( $sR === false ? array () : array_reverse (( array ) $sR ));
$sR = array_slice (( array ) $sR ,( $offset == 0 ? 0 : $offset - 1 ), $maxMessages ); // we need only $maxMessages of uids
$sRToFetch = $sR ; //array_slice($sR,0,50); // we fetch only the headers of a subset of the fetched uids
//error_log(__METHOD__.__LINE__.' Rows fetched (UID only):'.count($sR).' Data:'.array2string($sR));
$maxMessages = 75 ;
$sortResultwH [ 'header' ] = array ();
if ( count ( $sRToFetch ) > 0 )
{
//error_log(__METHOD__.__LINE__.' Headers to fetch with UIDs:'.count($sRToFetch).' Data:'.array2string($sRToFetch));
$sortResult = array ();
// fetch headers
$sortResultwH = $this -> mail_bo -> getHeaders (
$_folderName ,
$offset ,
$maxMessages ,
$sort ,
$reverse ,
$filter ,
$sRToFetch
);
}
}
else
2013-02-08 20:11:44 +01:00
{
$sortResult = array ();
// fetch headers
$sortResultwH = $this -> mail_bo -> getHeaders (
$_folderName ,
$offset ,
$maxMessages ,
$sort ,
$reverse ,
2014-05-09 14:43:57 +02:00
$filter
2013-02-08 20:11:44 +01:00
);
2014-05-09 14:43:57 +02:00
$rowsFetched [ 'messages' ] = $sortResultwH [ 'info' ][ 'total' ];
2013-02-08 20:11:44 +01:00
}
}
2014-05-09 14:43:57 +02:00
catch ( Exception $e )
2013-02-08 20:11:44 +01:00
{
2014-05-09 14:43:57 +02:00
$sortResultwH = array ();
$sR = array ();
2014-05-12 09:35:23 +02:00
self :: callWizard ( $e -> getMessage (), false );
2013-02-08 20:11:44 +01:00
}
if ( is_array ( $sR ) && count ( $sR ) > 0 )
{
foreach (( array ) $sR as $key => $v )
{
if ( array_key_exists ( $key ,( array ) $sortResultwH [ 'header' ]) == true )
{
$sortResult [ 'header' ][] = $sortResultwH [ 'header' ][ $key ];
}
else
{
if ( ! empty ( $v )) $sortResult [ 'header' ][] = array ( 'uid' => $v );
}
}
}
else
{
$sortResult = $sortResultwH ;
}
$rowsFetched [ 'rowsFetched' ] = count ( $sortResult [ 'header' ]);
if ( empty ( $rowsFetched [ 'messages' ])) $rowsFetched [ 'messages' ] = $rowsFetched [ 'rowsFetched' ];
//error_log(__METHOD__.__LINE__.' Rows fetched:'.$rowsFetched.' Data:'.array2string($sortResult));
2013-12-10 16:59:54 +01:00
$cols = array ( 'row_id' , 'uid' , 'status' , 'attachments' , 'subject' , 'address' , 'toaddress' , 'fromaddress' , 'ccaddress' , 'additionaltoaddress' , 'date' , 'size' , 'modified' );
2013-02-08 20:11:44 +01:00
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'select_mode' ] == 'EGW_SELECTMODE_TOGGLE' ) unset ( $cols [ 0 ]);
2014-07-16 18:34:15 +02:00
$rows = $this -> header2gridelements ( $sortResult [ 'header' ], $cols , $_folderName , $folderType = $toSchema );
2013-02-08 20:11:44 +01:00
//error_log(__METHOD__.__LINE__.array2string($rows));
2013-11-19 12:17:32 +01:00
2014-02-27 13:16:23 +01:00
if ( mail_bo :: $debugTimes ) mail_bo :: logRunTimes ( $starttime , null , 'Folder:' . $_folderName . ' Start:' . $query [ 'start' ] . ' NumRows:' . $query [ 'num_rows' ], __METHOD__ . __LINE__ );
2014-01-21 12:28:43 +01:00
if ( stripos ( $_GET [ 'menuaction' ], 'ajax_get_rows' ) !== false )
{
$response = egw_json_response :: get ();
$response -> call ( 'app.mail.unlock_tree' );
}
2013-02-08 20:11:44 +01:00
return $rowsFetched [ 'messages' ];
}
2013-02-19 17:30:59 +01:00
/**
* function createRowID - create a unique rowID for the grid
*
2014-05-22 09:47:49 +02:00
* @ param string $_folderName used to ensure the uniqueness of the uid over all folders
* @ param string $message_uid the message_Uid to be used for creating the rowID
2014-05-22 16:46:50 +02:00
* @ param boolean $_prependApp to indicate that the app 'mail' is to be used for creating the rowID
2013-09-05 16:52:11 +02:00
* @ return string - a colon separated string in the form [ app : ] accountID : profileID : folder : message_uid
2013-02-19 17:30:59 +01:00
*/
2013-09-05 16:52:11 +02:00
function createRowID ( $_folderName , $message_uid , $_prependApp = false )
2013-02-19 17:30:59 +01:00
{
2014-01-31 10:47:17 +01:00
return self :: generateRowID ( $this -> mail_bo -> profileID , $_folderName , $message_uid , $_prependApp );
}
/**
* static function generateRowID - create a unique rowID for the grid
*
2014-05-22 09:47:49 +02:00
* @ param integer $_profileID profile ID for the rowid to be used
* @ param string $_folderName to ensure the uniqueness of the uid over all folders
* @ param string $message_uid the message_Uid to be used for creating the rowID
* @ param boolean $_prependApp to indicate that the app 'mail' is to be used for creating the rowID
2014-01-31 10:47:17 +01:00
* @ return string - a colon separated string in the form [ app : ] accountID : profileID : folder : message_uid
*/
static function generateRowID ( $_profileID , $_folderName , $message_uid , $_prependApp = false )
{
return ( $_prependApp ? 'mail' . self :: $delimiter : '' ) . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]) . self :: $delimiter . $_profileID . self :: $delimiter . base64_encode ( $_folderName ) . self :: $delimiter . $message_uid ;
2013-02-19 17:30:59 +01:00
}
/**
* function splitRowID - split the rowID into its parts
*
2014-05-22 09:47:49 +02:00
* @ param string $_rowID string - a colon separated string in the form accountID : profileID : folder : message_uid
2013-02-19 17:30:59 +01:00
* @ return array populated named result array ( accountID , profileID , folder , msgUID )
*/
2013-03-05 15:09:35 +01:00
static function splitRowID ( $_rowID )
2013-02-19 17:30:59 +01:00
{
2013-02-20 17:27:10 +01:00
$res = explode ( self :: $delimiter , $_rowID );
2013-03-05 15:09:35 +01:00
// as a rowID is perceeded by app::, should be mail!
2013-10-03 12:05:05 +02:00
//error_log(__METHOD__.__LINE__.array2string($res).' [0] isInt:'.is_int($res[0]).' [0] isNumeric:'.is_numeric($res[0]).' [0] isString:'.is_string($res[0]).' Count:'.count($res));
2013-09-05 16:52:11 +02:00
if ( count ( $res ) == 4 && is_numeric ( $res [ 0 ]) )
{
// we have an own created rowID; prepend app=mail
array_unshift ( $res , 'mail' );
}
2013-03-05 15:09:35 +01:00
return array ( 'app' => $res [ 0 ], 'accountID' => $res [ 1 ], 'profileID' => $res [ 2 ], 'folder' => base64_decode ( $res [ 3 ]), 'msgUID' => $res [ 4 ]);
2013-02-19 17:30:59 +01:00
}
2013-02-08 20:11:44 +01:00
/**
2014-02-27 18:47:06 +01:00
* Get actions for preview toolbar
2013-02-08 20:11:44 +01:00
*
2014-02-27 18:47:06 +01:00
* @ return array
2013-02-08 20:11:44 +01:00
*/
2014-02-27 18:47:06 +01:00
function get_toolbar_actions ()
2013-02-08 20:11:44 +01:00
{
2014-02-27 18:47:06 +01:00
$actions = $this -> get_actions ();
2014-07-16 18:34:15 +02:00
$arrActions = array ( 'composeasnew' , 'reply' , 'reply_all' , 'forward' , 'flagged' , 'delete' , 'print' , 'infolog' , 'tracker' , 'save' , 'view' );
foreach ( $arrActions as & $act )
2013-10-05 16:15:29 +02:00
{
//error_log(__METHOD__.__LINE__.' '.$act.'->'.array2string($actions[$act]));
switch ( $act )
{
case 'forward' :
2014-02-13 12:30:05 +01:00
$actionsenabled [ $act ] = $actions [ $act ];
2013-10-05 16:15:29 +02:00
break ;
case 'save' :
2014-02-13 12:30:05 +01:00
$actionsenabled [ $act ] = $actions [ $act ];
2013-10-05 16:15:29 +02:00
break ;
2014-02-13 12:30:05 +01:00
case 'view' :
$actionsenabled [ $act ] = $actions [ $act ];
2013-10-05 16:15:29 +02:00
break ;
case 'flagged' :
2014-02-10 15:03:19 +01:00
$actionsenabled [ $act ] = $actions [ 'mark' ][ 'children' ][ $act ];
2013-10-05 16:15:29 +02:00
break ;
default :
if ( isset ( $actions [ $act ])) $actionsenabled [ $act ] = $actions [ $act ];
}
}
2014-02-27 18:47:06 +01:00
unset ( $actionsenabled [ 'drag_mail' ]);
2014-03-07 15:26:16 +01:00
//error_log(array2string($actionsenabled['view']));
unset ( $actionsenabled [ 'view' ][ 'children' ][ 'openastext' ]); //not supported in preview
unset ( $actionsenabled [ 'view' ][ 'children' ][ 'openashtml' ]); //not supported in preview
2014-02-27 18:47:06 +01:00
return $actionsenabled ;
}
/**
* function header2gridelements - to populate the grid elements with the collected Data
*
2014-05-22 09:47:49 +02:00
* @ param array $_headers headerdata to process
* @ param array $cols cols to populate
* @ param array $_folderName to ensure the uniqueness of the uid over all folders
* @ param array $_folderType used to determine if we need to populate from / to
2014-02-27 18:47:06 +01:00
* @ return array populated result array
*/
2014-07-16 18:34:15 +02:00
public function header2gridelements ( $_headers , $cols , $_folderName , $_folderType = 0 )
2014-02-27 18:47:06 +01:00
{
if ( mail_bo :: $debugTimes ) $starttime = microtime ( true );
$rv = array ();
2013-02-08 20:11:44 +01:00
$i = 0 ;
foreach (( array ) $_headers as $header )
{
$i ++ ;
$data = array ();
//error_log(__METHOD__.array2string($header));
$message_uid = $header [ 'uid' ];
$data [ 'uid' ] = $message_uid ;
2013-02-19 17:30:59 +01:00
$data [ 'row_id' ] = $this -> createRowID ( $_folderName , $message_uid );
2013-02-08 20:11:44 +01:00
$flags = " " ;
if ( ! empty ( $header [ 'recent' ])) $flags .= " R " ;
if ( ! empty ( $header [ 'flagged' ])) $flags .= " F " ;
if ( ! empty ( $header [ 'answered' ])) $flags .= " A " ;
if ( ! empty ( $header [ 'forwarded' ])) $flags .= " W " ;
if ( ! empty ( $header [ 'deleted' ])) $flags .= " D " ;
if ( ! empty ( $header [ 'seen' ])) $flags .= " S " ;
if ( ! empty ( $header [ 'label1' ])) $flags .= " 1 " ;
if ( ! empty ( $header [ 'label2' ])) $flags .= " 2 " ;
if ( ! empty ( $header [ 'label3' ])) $flags .= " 3 " ;
if ( ! empty ( $header [ 'label4' ])) $flags .= " 4 " ;
if ( ! empty ( $header [ 'label5' ])) $flags .= " 5 " ;
$data [ " status " ] = " <span class= \" status_img \" ></span> " ;
//error_log(__METHOD__.array2string($header).' Flags:'.$flags);
// the css for this row
$is_recent = false ;
$css_styles = array ( " mail " );
if ( $header [ 'deleted' ]) {
$css_styles [] = 'deleted' ;
}
if ( $header [ 'recent' ] && ! ( $header [ 'deleted' ] || $header [ 'seen' ] || $header [ 'answered' ] || $header [ 'forwarded' ])) {
$css_styles [] = 'recent' ;
$is_recent = true ;
}
if ( $header [ 'priority' ] < 3 ) {
$css_styles [] = 'prio_high' ;
}
if ( $header [ 'flagged' ]) {
$css_styles [] = 'flagged' ;
}
if ( ! $header [ 'seen' ]) {
$css_styles [] = 'unseen' ; // different status image for recent // solved via css !important
}
if ( $header [ 'answered' ]) {
$css_styles [] = 'replied' ;
}
if ( $header [ 'forwarded' ]) {
$css_styles [] = 'forwarded' ;
}
if ( $header [ 'label1' ]) {
2013-02-19 17:30:59 +01:00
$css_styles [] = 'labelone' ;
2013-02-08 20:11:44 +01:00
}
if ( $header [ 'label2' ]) {
2013-02-19 17:30:59 +01:00
$css_styles [] = 'labeltwo' ;
2013-02-08 20:11:44 +01:00
}
if ( $header [ 'label3' ]) {
2013-02-19 17:30:59 +01:00
$css_styles [] = 'labelthree' ;
2013-02-08 20:11:44 +01:00
}
if ( $header [ 'label4' ]) {
2013-02-19 17:30:59 +01:00
$css_styles [] = 'labelfour' ;
2013-02-08 20:11:44 +01:00
}
if ( $header [ 'label5' ]) {
2013-02-19 17:30:59 +01:00
$css_styles [] = 'labelfive' ;
2013-02-08 20:11:44 +01:00
}
//error_log(__METHOD__.array2string($css_styles));
if ( in_array ( " subject " , $cols ))
{
// filter out undisplayable characters
$search = array ( '[\016]' , '[\017]' ,
'[\020]' , '[\021]' , '[\022]' , '[\023]' , '[\024]' , '[\025]' , '[\026]' , '[\027]' ,
'[\030]' , '[\031]' , '[\032]' , '[\033]' , '[\034]' , '[\035]' , '[\036]' , '[\037]' );
$replace = '' ;
$header [ 'subject' ] = preg_replace ( $search , $replace , $header [ 'subject' ]);
// curly brackets get messed up by the template!
if ( ! empty ( $header [ 'subject' ])) {
// make the subject shorter if it is to long
$subject = $header [ 'subject' ];
} else {
2013-10-08 16:55:20 +02:00
$subject = '(' . lang ( 'no subject' ) . ')' ;
2013-02-08 20:11:44 +01:00
}
2013-02-19 17:30:59 +01:00
$data [ " subject " ] = $subject ; // the mailsubject
2013-02-08 20:11:44 +01:00
}
2013-10-01 13:29:54 +02:00
$imageTag = '' ;
$imageHTMLBlock = '' ;
2013-11-05 15:16:40 +01:00
//error_log(__METHOD__.__LINE__.array2string($header));
2013-02-08 20:11:44 +01:00
if ( in_array ( " attachments " , $cols ))
{
if ( $header [ 'mimetype' ] == 'multipart/mixed' ||
$header [ 'mimetype' ] == 'multipart/signed' ||
$header [ 'mimetype' ] == 'multipart/related' ||
$header [ 'mimetype' ] == 'multipart/report' ||
$header [ 'mimetype' ] == 'text/calendar' ||
$header [ 'mimetype' ] == 'text/html' ||
substr ( $header [ 'mimetype' ], 0 , 11 ) == 'application' ||
substr ( $header [ 'mimetype' ], 0 , 5 ) == 'audio' ||
substr ( $header [ 'mimetype' ], 0 , 5 ) == 'video' ||
$header [ 'mimetype' ] == 'multipart/alternative' )
{
$image = html :: image ( 'mail' , 'attach' );
2013-10-01 13:29:54 +02:00
$imageTag = '' ;
$imageHTMLBlock = '' ;
2013-10-03 12:05:05 +02:00
$datarowid = $this -> createRowID ( $_folderName , $message_uid , true );
2014-06-03 09:51:39 +02:00
$attachments = $header [ 'attachments' ];
if ( count ( $attachments ) < 1 )
2013-02-08 20:11:44 +01:00
{
2014-06-03 09:51:39 +02:00
$image = ' ' ;
}
if ( count ( $attachments ) == 1 )
{
2014-07-17 16:56:37 +02:00
$imageHTMLBlock = self :: createAttachmentBlock ( $attachments , $datarowid , $header [ 'uid' ], $_folderName );
2014-06-03 09:51:39 +02:00
$imageTag = json_encode ( $attachments );
$image = html :: image ( 'mail' , 'attach' , $attachments [ 0 ][ 'name' ] . ( ! empty ( $attachments [ 0 ][ 'mimeType' ]) ? ' (' . $attachments [ 0 ][ 'mimeType' ] . ')' : '' ));
2013-10-01 13:29:54 +02:00
}
if ( count ( $attachments ) > 1 )
{
2014-07-17 16:56:37 +02:00
$imageHTMLBlock = self :: createAttachmentBlock ( $attachments , $datarowid , $header [ 'uid' ], $_folderName );
2013-10-01 13:29:54 +02:00
$imageTag = json_encode ( $attachments );
$image = html :: image ( 'mail' , 'attach' , lang ( '%1 attachments' , count ( $attachments )));
2013-02-08 20:11:44 +01:00
}
$attachmentFlag = $image ;
} else {
$attachmentFlag = ' ' ;
}
// show priority flag
if ( $header [ 'priority' ] < 3 ) {
$image = html :: image ( 'mail' , 'prio_high' );
} elseif ( $header [ 'priority' ] > 3 ) {
$image = html :: image ( 'mail' , 'prio_low' );
} else {
$image = '' ;
}
// show a flag for flagged messages
$imageflagged = '' ;
if ( $header [ 'flagged' ])
{
$imageflagged = html :: image ( 'mail' , 'unread_flagged_small' );
}
$data [ " attachments " ] = $image . $attachmentFlag . $imageflagged ; // icon for attachments available
}
// sent or draft or template folder -> to address
if ( in_array ( " toaddress " , $cols ))
{
// sent or drafts or template folder means foldertype > 0, use to address instead of from
2013-10-24 17:29:57 +02:00
$data [ " toaddress " ] = $header [ 'to_address' ]; //mail_bo::htmlentities($header['to_address'],$this->charset);
2013-02-08 20:11:44 +01:00
}
2013-12-03 15:38:50 +01:00
if ( in_array ( " additionaltoaddress " , $cols ))
{
2013-12-17 00:41:39 +01:00
$data [ 'additionaltoaddress' ] = $header [ 'additional_to_addresses' ];
2013-12-03 15:38:50 +01:00
}
2013-02-08 20:11:44 +01:00
//fromaddress
if ( in_array ( " fromaddress " , $cols ))
{
2014-07-16 15:42:36 +02:00
$data [ " fromaddress " ] = $header [ 'sender_address' ];
2013-02-08 20:11:44 +01:00
}
2013-12-03 15:38:50 +01:00
if ( in_array ( " ccaddress " , $cols ))
{
2013-12-17 00:41:39 +01:00
$data [ 'ccaddress' ] = $header [ 'cc_addresses' ];
2013-12-03 15:38:50 +01:00
}
2013-02-08 20:11:44 +01:00
if ( in_array ( " date " , $cols ))
{
2014-07-16 15:42:36 +02:00
$data [ " date " ] = $header [ 'date' ];
2013-02-08 20:11:44 +01:00
}
2013-02-11 14:04:49 +01:00
if ( in_array ( " modified " , $cols ))
{
$data [ " modified " ] = $header [ 'internaldate' ];
}
2013-02-08 20:11:44 +01:00
if ( in_array ( " size " , $cols ))
2013-02-12 15:30:58 +01:00
$data [ " size " ] = $header [ 'size' ]; /// size
2013-02-08 20:11:44 +01:00
2013-02-14 18:10:20 +01:00
$data [ " class " ] = implode ( ' ' , $css_styles );
2013-12-06 11:35:39 +01:00
//translate style-classes back to flags
2014-01-13 15:22:58 +01:00
$data [ 'flags' ] = Array ();
2013-12-06 11:35:39 +01:00
if ( $header [ 'seen' ]) $data [ " flags " ][ 'read' ] = 'read' ;
2014-07-16 18:34:15 +02:00
foreach ( $css_styles as & $flag ) {
2013-12-05 16:09:35 +01:00
if ( $flag != 'mail' )
{
if ( $flag == 'labelone' ) { $data [ " flags " ][ 'label1' ] = 'label1' ;}
elseif ( $flag == 'labeltwo' ) { $data [ " flags " ][ 'label2' ] = 'label2' ;}
elseif ( $flag == 'labelthree' ) { $data [ " flags " ][ 'label3' ] = 'label3' ;}
elseif ( $flag == 'labelfour' ) { $data [ " flags " ][ 'label4' ] = 'label4' ;}
elseif ( $flag == 'labelfive' ) { $data [ " flags " ][ 'label5' ] = 'label5' ;}
2014-01-13 15:22:58 +01:00
elseif ( $flag == 'unseen' ) { unset ( $data [ " flags " ][ 'read' ]);}
2013-12-05 16:09:35 +01:00
else $data [ " flags " ][ $flag ] = $flag ;
}
}
2014-03-27 10:25:11 +01:00
if ( $header [ 'disposition-notification-to' ]) $data [ 'dispositionnotificationto' ] = $header [ 'disposition-notification-to' ];
2014-03-25 17:20:28 +01:00
if (( $header [ 'mdnsent' ] || $header [ 'mdnnotsent' ] | $header [ 'seen' ]) && isset ( $data [ 'dispositionnotificationto' ])) unset ( $data [ 'dispositionnotificationto' ]);
2013-10-01 13:29:54 +02:00
$data [ 'attachmentsPresent' ] = $imageTag ;
$data [ 'attachmentsBlock' ] = $imageHTMLBlock ;
2013-12-10 16:59:54 +01:00
$data [ 'address' ] = ( $_folderType ? $data [ " toaddress " ] : $data [ " fromaddress " ]);
2013-02-08 20:11:44 +01:00
$rv [] = $data ;
2014-03-27 10:25:11 +01:00
//error_log(__METHOD__.__LINE__.array2string($data));
2013-02-08 20:11:44 +01:00
}
2014-02-27 13:16:23 +01:00
if ( mail_bo :: $debugTimes ) mail_bo :: logRunTimes ( $starttime , null , 'Folder:' . $_folderName , __METHOD__ . __LINE__ );
2014-02-27 18:47:06 +01:00
// ToDo: call this ONLY if labels change
etemplate_widget :: setElementAttribute ( 'toolbar' , 'actions' , $this -> get_toolbar_actions ());
2013-02-08 20:11:44 +01:00
return $rv ;
}
2013-02-28 10:28:08 +01:00
/**
* display messages header lines
*
* all params are passed as GET Parameters
*/
function displayHeader ()
{
if ( isset ( $_GET [ 'id' ])) $rowID = $_GET [ 'id' ];
if ( isset ( $_GET [ 'part' ])) $partID = $_GET [ 'part' ];
2013-03-05 15:09:35 +01:00
$hA = self :: splitRowID ( $rowID );
2013-02-28 10:28:08 +01:00
$uid = $hA [ 'msgUID' ];
$mailbox = $hA [ 'folder' ];
$this -> mail_bo -> reopen ( $mailbox );
$rawheaders = $this -> mail_bo -> getMessageRawHeader ( $uid , $partID );
// add line breaks to $rawheaders
$newRawHeaders = explode ( " \n " , $rawheaders );
reset ( $newRawHeaders );
// reset $rawheaders
$rawheaders = " " ;
// create it new, with good line breaks
reset ( $newRawHeaders );
while ( list ( $key , $value ) = @ each ( $newRawHeaders )) {
$rawheaders .= wordwrap ( $value , 90 , " \n " );
}
$this -> mail_bo -> closeConnection ();
header ( 'Content-type: text/html; charset=iso-8859-1' );
print '<pre>' . htmlspecialchars ( $rawheaders , ENT_NOQUOTES , 'iso-8859-1' ) . '</pre>' ;
}
2013-06-05 16:24:56 +02:00
/**
* display messages
2014-07-16 15:42:36 +02:00
* @ param array $_requesteddata
2013-09-05 16:52:11 +02:00
* all params are passed as GET Parameters , but can be passed via ExecMethod2 as array too
2013-06-05 16:24:56 +02:00
*/
2013-09-05 16:52:11 +02:00
function displayMessage ( $_requesteddata = null )
2013-06-05 16:24:56 +02:00
{
2013-09-05 16:52:11 +02:00
if ( ! is_null ( $_requesteddata ) && isset ( $_requesteddata [ 'id' ]))
{
$rowID = $_requesteddata [ 'id' ];
}
2014-01-24 12:48:24 +01:00
$preventRedirect = false ;
2013-06-05 16:24:56 +02:00
if ( isset ( $_GET [ 'id' ])) $rowID = $_GET [ 'id' ];
if ( isset ( $_GET [ 'part' ])) $partID = $_GET [ 'part' ];
2014-01-24 12:48:24 +01:00
if ( isset ( $_GET [ 'mode' ])) $preventRedirect = ( $_GET [ 'mode' ] == 'display' ? true : false );
2013-07-20 09:23:55 +02:00
$htmlOptions = $this -> mail_bo -> htmlOptions ;
if ( ! empty ( $_GET [ 'tryastext' ])) $htmlOptions = " only_if_no_text " ;
if ( ! empty ( $_GET [ 'tryashtml' ])) $htmlOptions = " always_display " ;
2013-06-05 16:24:56 +02:00
$hA = self :: splitRowID ( $rowID );
$uid = $hA [ 'msgUID' ];
$mailbox = $hA [ 'folder' ];
2013-09-05 16:52:11 +02:00
//error_log(__METHOD__.__LINE__.array2string($hA));
2014-01-24 12:48:24 +01:00
if ( ! $preventRedirect && ( $this -> mail_bo -> isDraftFolder ( $mailbox ) || $this -> mail_bo -> isTemplateFolder ( $mailbox )))
2014-01-21 09:26:59 +01:00
{
egw :: redirect_link ( '/index.php' , array ( 'menuaction' => 'mail.mail_compose.compose' , 'id' => $rowID , 'from' => 'composefromdraft' ));
}
2013-06-05 16:24:56 +02:00
$this -> mail_bo -> reopen ( $mailbox );
// retrieve the flags of the message, before touching it.
2014-01-31 10:47:17 +01:00
$headers = $this -> mail_bo -> getMessageHeader ( $uid , $partID , true , true , $mailbox );
2013-06-05 16:24:56 +02:00
if ( PEAR :: isError ( $headers )) {
$error_msg [] = lang ( " ERROR: Message could not be displayed. " );
$error_msg [] = lang ( " In Mailbox: %1, with ID: %2, and PartID: %3 " , $mailbox , $uid , $partID );
$error_msg [] = $headers -> message ;
$error_msg [] = array2string ( $headers -> backtrace [ 0 ]);
}
2014-07-16 18:34:15 +02:00
if ( ! empty ( $uid )) $this -> mail_bo -> getFlags ( $uid );
2014-01-20 09:55:07 +01:00
$envelope = $this -> mail_bo -> getMessageEnvelope ( $uid , $partID , true , $mailbox );
2014-01-31 10:47:17 +01:00
//error_log(__METHOD__.__LINE__.array2string($envelope));
2014-07-16 18:34:15 +02:00
$this -> mail_bo -> getMessageRawHeader ( $uid , $partID , $mailbox );
2013-06-05 16:24:56 +02:00
$fetchEmbeddedImages = false ;
if ( $htmlOptions != 'always_display' ) $fetchEmbeddedImages = true ;
2014-07-08 12:20:19 +02:00
$attachments = $this -> mail_bo -> getMessageAttachments ( $uid , $partID , null , $fetchEmbeddedImages , true , true , $mailbox );
2014-02-13 13:59:43 +01:00
//error_log(__METHOD__.__LINE__.array2string($attachments));
2013-06-17 16:25:20 +02:00
$attachmentHTMLBlock = self :: createAttachmentBlock ( $attachments , $rowID , $uid , $mailbox );
2013-06-05 16:24:56 +02:00
$nonDisplayAbleCharacters = array ( '[\016]' , '[\017]' ,
'[\020]' , '[\021]' , '[\022]' , '[\023]' , '[\024]' , '[\025]' , '[\026]' , '[\027]' ,
'[\030]' , '[\031]' , '[\032]' , '[\033]' , '[\034]' , '[\035]' , '[\036]' , '[\037]' );
2013-06-17 16:25:20 +02:00
//error_log(__METHOD__.__LINE__.$mailBody);
2013-06-05 16:24:56 +02:00
$this -> mail_bo -> closeConnection ();
2014-01-17 11:47:35 +01:00
//$GLOBALS['egw_info']['flags']['currentapp'] = 'mail';//should not be needed
2013-06-05 16:24:56 +02:00
$etpl = new etemplate_new ( 'mail.display' );
2014-07-16 15:42:36 +02:00
$subject = $this -> mail_bo -> decode_subject ( preg_replace ( $nonDisplayAbleCharacters , '' , $envelope [ 'SUBJECT' ]), false );
2013-07-15 14:31:02 +02:00
2013-07-19 17:13:01 +02:00
// Set up data for taglist widget(s)
2013-07-20 11:27:37 +02:00
if ( $envelope [ 'FROM' ] == $envelope [ 'SENDER' ]) unset ( $envelope [ 'SENDER' ]);
2013-07-19 17:13:01 +02:00
foreach ( array ( 'SENDER' , 'FROM' , 'TO' , 'CC' , 'BCC' ) as $field )
{
2013-07-20 15:10:17 +02:00
if ( ! isset ( $envelope [ $field ])) continue ;
2013-07-19 17:13:01 +02:00
foreach ( $envelope [ $field ] as $field_data )
{
2013-07-20 10:20:04 +02:00
//error_log(__METHOD__.__LINE__.array2string($field_data));
2014-07-16 15:42:36 +02:00
$content [ $field ][] = $field_data ;
2013-07-19 17:13:01 +02:00
$sel_options [ $field ][] = array (
2013-11-25 19:14:33 +01:00
// taglist requires these - not optional
'id' => $field_data ,
'label' => str_replace ( '"' , " ' " , $field_data ),
2013-11-10 21:53:51 +01:00
);
2013-07-19 17:13:01 +02:00
}
}
2013-10-05 16:15:29 +02:00
$actionsenabled = self :: get_actions ();
2013-10-10 13:44:01 +02:00
unset ( $actionsenabled [ 'open' ]);
2013-10-05 16:15:29 +02:00
unset ( $actionsenabled [ 'mark' ][ 'children' ][ 'setLabel' ]);
unset ( $actionsenabled [ 'mark' ][ 'children' ][ 'unsetLabel' ]);
unset ( $actionsenabled [ 'mark' ][ 'children' ][ 'read' ]);
unset ( $actionsenabled [ 'mark' ][ 'children' ][ 'unread' ]);
unset ( $actionsenabled [ 'mark' ][ 'children' ][ 'undelete' ]);
2014-02-25 14:50:58 +01:00
unset ( $actionsenabled [ 'drag_mail' ]);
2013-12-09 10:57:03 +01:00
$actionsenabled [ 'mark' ][ 'children' ][ 'flagged' ] = array (
'group' => $actionsenabled [ 'mark' ][ 'children' ][ 'flagged' ][ 'group' ],
'caption' => 'Flagged' ,
'icon' => 'unread_flagged_small' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
);
$actionsenabled [ 'mark' ][ 'children' ][ 'unflagged' ] = array (
'group' => $actionsenabled [ 'mark' ][ 'children' ][ 'flagged' ][ 'group' ],
'caption' => 'Unflagged' ,
'icon' => 'read_flagged_small' ,
'onExecute' => 'javaScript:app.mail.mail_flag' ,
);
2014-02-20 19:08:48 +01:00
$actionsenabled [ 'tracker' ][ 'toolbarDefault' ] = true ;
$actionsenabled [ 'mark' ][ 'toolbarDefault' ] = true ;
$actionsenabled [ 'forward' ][ 'toolbarDefault' ] = true ;
2013-10-10 13:44:01 +02:00
$cAN = $actionsenabled [ 'composeasnew' ];
unset ( $actionsenabled [ 'composeasnew' ]);
$actionsenabled = array_reverse ( $actionsenabled , true );
$actionsenabled [ 'composeasnew' ] = $cAN ;
$actionsenabled = array_reverse ( $actionsenabled , true );
2014-02-05 17:17:37 +01:00
$content [ 'displayToolbaractions' ] = json_encode ( $actionsenabled );
2013-06-05 16:24:56 +02:00
if ( empty ( $subject )) $subject = lang ( 'no subject' );
2013-07-17 14:01:01 +02:00
$content [ 'msg' ] = ( is_array ( $error_msg ) ? implode ( " <br> " , $error_msg ) : $error_msg );
2013-10-04 16:39:25 +02:00
// Send mail ID so we can use it for actions
$content [ 'mail_id' ] = $rowID ;
2013-07-15 14:31:02 +02:00
$content [ 'mail_displaydate' ] = mail_bo :: _strtotime ( $headers [ 'DATE' ], 'ts' , true );
2013-06-17 16:25:20 +02:00
$content [ 'mail_displaysubject' ] = $subject ;
2014-02-04 12:31:13 +01:00
$linkData = array ( 'menuaction' => " mail.mail_ui.loadEmailBody " , " _messageID " => $rowID );
if ( ! empty ( $partID )) $linkData [ '_partID' ] = $partID ;
if ( $htmlOptions != $this -> mail_bo -> htmlOptions ) $linkData [ '_htmloptions' ] = $htmlOptions ;
$content [ 'mailDisplayBodySrc' ] = egw :: link ( '/index.php' , $linkData );
2013-06-17 16:25:20 +02:00
$content [ 'mail_displayattachments' ] = $attachmentHTMLBlock ;
2013-10-05 11:03:51 +02:00
$content [ 'mail_id' ] = $rowID ;
2013-10-11 11:28:33 +02:00
$content [ 'mailDisplayContainerClass' ] = ( count ( $attachments ) ? " mailDisplayContainer mailDisplayContainerFixedHeight " : " mailDisplayContainer mailDisplayContainerFullHeight " );
$content [ 'mailDisplayAttachmentsClass' ] = ( count ( $attachments ) ? " mailDisplayAttachments " : " mail_DisplayNone " );
2014-07-14 22:50:08 +02:00
// DRAG attachments actions
$etpl -> setElementAttribute ( 'mail_displayattachments' , 'actions' , array (
'file_drag' => array (
'dragType' => 'file' ,
'type' => 'drag' ,
'onExecute' => 'javaScript:app.mail.drag_attachment'
)
));
2013-06-17 16:25:20 +02:00
$readonlys = $preserv = $content ;
2013-07-15 14:31:02 +02:00
$etpl -> exec ( 'mail.mail_ui.displayMessage' , $content , $sel_options , $readonlys , $preserv , 2 );
2013-06-05 16:24:56 +02:00
}
2013-06-17 16:25:20 +02:00
/**
* createAttachmentBlock
* helper function to create the attachment block / table
*
2014-05-22 09:47:49 +02:00
* @ param array $attachments array with the attachments information
* @ param string $rowID rowid of the message
* @ param int $uid uid of the message
* @ param string $mailbox mailbox identifier
* @ param boolean $_returnFullHTML flag wether to return HTML or data array
2013-10-16 13:25:46 +02:00
* @ return mixed array / string data array or html or empty string
2013-06-17 16:25:20 +02:00
*/
2013-10-16 13:25:46 +02:00
static function createAttachmentBlock ( $attachments , $rowID , $uid , $mailbox , $_returnFullHTML = false )
2013-06-17 16:25:20 +02:00
{
$attachmentHTMLBlock = '' ;
2014-07-16 18:34:15 +02:00
$attachmentHTML = array ();
2013-06-17 16:25:20 +02:00
if ( is_array ( $attachments ) && count ( $attachments ) > 0 ) {
$url_img_vfs = html :: image ( 'filemanager' , 'navbar' , lang ( 'Filemanager' ), ' height="16"' );
2014-04-08 16:55:43 +02:00
$url_img_vfs_save_all = html :: image ( 'mail' , 'save_all' , lang ( 'Save all' ));
2013-06-17 16:25:20 +02:00
foreach ( $attachments as $key => $value )
{
2014-07-29 10:13:34 +02:00
$attachmentHTML [ $key ][ 'filename' ] = ( $value [ 'name' ] ? ( $value [ 'filename' ] ? $value [ 'filename' ] : $value [ 'name' ] ) : lang ( '(no subject)' ));
$test = @ json_encode ( $attachmentHTML [ $key ][ 'filename' ]);
//error_log(__METHOD__.__LINE__.' ->'.strlen($singleBodyPart['body']).' Error:'.json_last_error().'<- BodyPart:#'.$test.'#');
if (( $test == " null " || $test === false || is_null ( $test )) && strlen ( $attachmentHTML [ $key ][ 'filename' ]) > 0 )
{
// try to fix broken utf8
$x = utf8_encode ( $attachmentHTML [ $key ][ 'filename' ]);
$test = @ json_encode ( $x );
if (( $test == " null " || $test === false || is_null ( $test )) && strlen ( $attachmentHTML [ $key ][ 'filename' ]) > 0 )
{
// this should not be needed, unless something fails with charset detection/ wrong charset passed
$attachmentHTML [ $key ][ 'filename' ] = ( function_exists ( 'mb_convert_encoding' ) ? mb_convert_encoding ( $attachmentHTML [ $key ][ 'filename' ], 'UTF-8' , 'UTF-8' ) : ( function_exists ( 'iconv' ) ? @ iconv ( " UTF-8 " , " UTF-8//IGNORE " , $attachmentHTML [ $key ][ 'filename' ]) : $attachmentHTML [ $key ][ 'filename' ]));
}
else
{
$attachmentHTML [ $key ][ 'filename' ] = $x ;
}
}
2013-10-16 13:25:46 +02:00
$attachmentHTML [ $key ][ 'type' ] = $value [ 'mimeType' ];
2013-06-17 16:25:20 +02:00
$attachmentHTML [ $key ][ 'mimetype' ] = mime_magic :: mime2label ( $value [ 'mimeType' ]);
$attachmentHTML [ $key ][ 'size' ] = egw_vfs :: hsize ( $value [ 'size' ]);
$attachmentHTML [ $key ][ 'attachment_number' ] = $key ;
2013-10-16 13:25:46 +02:00
$attachmentHTML [ $key ][ 'partID' ] = $value [ 'partID' ];
$attachmentHTML [ $key ][ 'winmailFlag' ] = $value [ 'is_winmail' ];
$attachmentHTML [ $key ][ 'classSaveAllPossiblyDisabled' ] = " mail_DisplayNone " ;
2014-07-14 22:50:08 +02:00
2013-06-17 16:25:20 +02:00
switch ( strtoupper ( $value [ 'mimeType' ]))
{
case 'MESSAGE/RFC822' :
$linkData = array
(
'menuaction' => 'mail.mail_ui.displayMessage' ,
2014-07-11 15:49:27 +02:00
//'mode' => 'display', //message/rfc822 attachments should be opened in display mode
2013-06-17 16:25:20 +02:00
'id' => $rowID ,
'part' => $value [ 'partID' ],
'is_winmail' => $value [ 'is_winmail' ]
);
$windowName = 'displayMessage_' . $rowID . '_' . $value [ 'partID' ];
2014-02-04 12:31:13 +01:00
$linkView = " egw_openWindowCentered(' " . egw :: link ( '/index.php' , $linkData ) . " ',' $windowName ',700,egw_getWindowOuterHeight()); " ;
2013-06-17 16:25:20 +02:00
break ;
case 'IMAGE/JPEG' :
case 'IMAGE/PNG' :
case 'IMAGE/GIF' :
case 'IMAGE/BMP' :
case 'APPLICATION/PDF' :
case 'TEXT/PLAIN' :
case 'TEXT/HTML' :
case 'TEXT/DIRECTORY' :
$sfxMimeType = $value [ 'mimeType' ];
$buff = explode ( '.' , $value [ 'name' ]);
$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 );
if ( strtoupper ( $sfxMimeType ) == 'TEXT/VCARD' || strtoupper ( $sfxMimeType ) == 'TEXT/X-VCARD' )
{
$attachments [ $key ][ 'mimeType' ] = $sfxMimeType ;
$value [ 'mimeType' ] = strtoupper ( $sfxMimeType );
}
case 'TEXT/X-VCARD' :
case 'TEXT/VCARD' :
case 'TEXT/CALENDAR' :
case 'TEXT/X-VCALENDAR' :
$linkData = array
(
'menuaction' => 'mail.mail_ui.getAttachment' ,
'id' => $rowID ,
'part' => $value [ 'partID' ],
'is_winmail' => $value [ 'is_winmail' ],
'mailbox' => base64_encode ( $mailbox ),
);
$windowName = 'displayAttachment_' . $uid ;
$reg = '800x600' ;
// handle calendar/vcard
if ( strtoupper ( $value [ 'mimeType' ]) == 'TEXT/CALENDAR' )
{
$windowName = 'displayEvent_' . $rowID ;
$reg2 = egw_link :: get_registry ( 'calendar' , 'view_popup' );
}
if ( strtoupper ( $value [ 'mimeType' ]) == 'TEXT/X-VCARD' || strtoupper ( $value [ 'mimeType' ]) == 'TEXT/VCARD' )
{
$windowName = 'displayContact_' . $rowID ;
$reg2 = egw_link :: get_registry ( 'addressbook' , 'add_popup' );
}
// apply to action
list ( $width , $height ) = explode ( 'x' ,( ! empty ( $reg2 ) ? $reg2 : $reg ));
2014-02-04 12:31:13 +01:00
$linkView = " egw_openWindowCentered(' " . egw :: link ( '/index.php' , $linkData ) . " ',' $windowName ', $width , $height ); " ;
2013-06-17 16:25:20 +02:00
break ;
default :
$linkData = array
(
'menuaction' => 'mail.mail_ui.getAttachment' ,
'id' => $rowID ,
'part' => $value [ 'partID' ],
'is_winmail' => $value [ 'is_winmail' ],
'mailbox' => base64_encode ( $mailbox ),
);
2014-02-04 12:31:13 +01:00
$linkView = " window.location.href = ' " . egw :: link ( '/index.php' , $linkData ) . " '; " ;
2013-06-17 16:25:20 +02:00
break ;
}
//error_log(__METHOD__.__LINE__.$linkView);
2013-10-01 13:29:54 +02:00
$attachmentHTML [ $key ][ 'link_view' ] = '<a href="#" ." title="' . $attachmentHTML [ $key ][ 'filename' ] . '" onclick="' . $linkView . ' return false;"><b>' .
2013-06-17 16:25:20 +02:00
( $value [ 'name' ] ? ( $filename ? $filename : $value [ 'name' ] ) : lang ( '(no subject)' )) .
'</b></a>' ;
$linkData = array
(
'menuaction' => 'mail.mail_ui.getAttachment' ,
'mode' => 'save' ,
'id' => $rowID ,
'part' => $value [ 'partID' ],
'is_winmail' => $value [ 'is_winmail' ],
'mailbox' => base64_encode ( $mailbox ),
);
2014-04-08 16:55:43 +02:00
$attachmentHTML [ $key ][ 'link_save' ] = " <a href=' " . egw :: link ( '/index.php' , $linkData ) . " ' title=' " . $attachmentHTML [ $key ][ 'filename' ] . " '> " . html :: image ( 'mail' , 'fileexport' ) . " </a> " ;
2013-06-17 16:25:20 +02:00
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'filemanager' ])
{
$link_vfs_save = egw :: link ( '/index.php' , array (
'menuaction' => 'filemanager.filemanager_select.select' ,
'mode' => 'saveas' ,
'name' => $value [ 'name' ],
'mime' => strtolower ( $value [ 'mimeType' ]),
2013-07-15 14:31:02 +02:00
'method' => 'mail.mail_ui.vfsSaveAttachment' ,
2013-07-15 15:37:28 +02:00
'id' => $rowID . '::' . $value [ 'partID' ] . '::' . $value [ 'is_winmail' ],
2013-06-17 16:25:20 +02:00
'label' => lang ( 'Save' ),
));
$vfs_save = " <a href='#' onclick= \" egw_openWindowCentered(' $link_vfs_save ','vfs_save_attachment','640','570',window.outerWidth/2,window.outerHeight/2); return false; \" > $url_img_vfs </a> " ;
// add save-all icon for first attachment
if ( ! $key && count ( $attachments ) > 1 )
{
2013-10-16 13:25:46 +02:00
$attachmentHTML [ $key ][ 'classSaveAllPossiblyDisabled' ] = " " ;
2013-06-17 16:25:20 +02:00
foreach ( $attachments as $ikey => $value )
{
//$rowID
$ids [ " id[ $ikey ] " ] = $rowID . '::' . $value [ 'partID' ] . '::' . $value [ 'is_winmail' ] . '::' . $value [ 'name' ];
}
$link_vfs_save = egw :: link ( '/index.php' , array (
'menuaction' => 'filemanager.filemanager_select.select' ,
'mode' => 'select-dir' ,
'method' => 'mail.mail_ui.vfsSaveAttachment' ,
'label' => lang ( 'Save all' ),
) + $ids );
$vfs_save .= " <a href='#' onclick= \" egw_openWindowCentered(' $link_vfs_save ','vfs_save_attachment','640','530',window.outerWidth/2,window.outerHeight/2); return false; \" > $url_img_vfs_save_all </a> " ;
}
$attachmentHTML [ $key ][ 'link_save' ] .= $vfs_save ;
//error_log(__METHOD__.__LINE__.$attachmentHTML[$key]['link_save']);
}
}
$attachmentHTMLBlock = " <table width='100%'> " ;
foreach (( array ) $attachmentHTML as $row )
{
2013-10-01 13:29:54 +02:00
$attachmentHTMLBlock .= " <tr><td><div class='useEllipsis'> " . $row [ 'link_view' ] . '</div></td>' ;
2013-06-17 16:25:20 +02:00
$attachmentHTMLBlock .= " <td> " . $row [ 'mimetype' ] . '</td>' ;
$attachmentHTMLBlock .= " <td> " . $row [ 'size' ] . '</td>' ;
$attachmentHTMLBlock .= " <td> " . $row [ 'link_save' ] . '</td></tr>' ;
}
$attachmentHTMLBlock .= " </table> " ;
}
2013-10-18 11:58:25 +02:00
if ( ! $_returnFullHTML )
{
foreach (( array ) $attachmentHTML as $ikey => $value )
{
unset ( $attachmentHTML [ $ikey ][ 'link_view' ]);
unset ( $attachmentHTML [ $ikey ][ 'link_save' ]);
}
}
2013-10-16 13:25:46 +02:00
return ( $_returnFullHTML ? $attachmentHTMLBlock : $attachmentHTML );
2013-06-17 16:25:20 +02:00
}
2013-10-03 18:09:25 +02:00
/**
2014-05-21 13:24:34 +02:00
* fetch vacation info from active Server using icServer object
2013-10-03 18:09:25 +02:00
*
2014-05-21 13:24:34 +02:00
* @ return array | boolean array with vacation on success or false on failure
2014-04-03 14:20:23 +02:00
*/
function gatherVacation ()
{
2014-04-07 14:52:50 +02:00
$vacation = $this -> mail_bo -> icServer -> acc_sieve_enabled && ( $this -> mail_bo -> icServer -> acc_sieve_host || $this -> mail_bo -> icServer -> acc_imap_host );
2014-04-03 14:20:23 +02:00
//error_log(__METHOD__.__LINE__.' Server:'.self::$icServerID.' Sieve Enabled:'.array2string($vacation));
2014-05-21 13:24:34 +02:00
2014-07-18 19:18:29 +02:00
if ( $vacation )
2014-05-21 13:24:34 +02:00
{
2014-05-13 19:09:05 +02:00
$sieveServer = $this -> mail_bo -> icServer ;
2014-07-18 19:18:29 +02:00
$sieveServer -> retrieveRules ();
$vacation = $sieveServer -> getVacation ();
2014-04-03 14:20:23 +02:00
}
2014-05-13 19:09:05 +02:00
//error_log(__METHOD__.__LINE__.' Server:'.self::$icServerID.' Vacation retrieved:'.array2string($vacation));
2014-04-03 14:20:23 +02:00
return $vacation ;
}
/**
* quotaDisplay
* gather Info on how to display the quota info
* @ param $_usage int
* @ param $_limit int
* @ return array - info used for quota array ( class => string , text => string , $percent => string )
2013-10-03 18:09:25 +02:00
*/
function quotaDisplay ( $_usage , $_limit )
{
if ( $_limit == 0 ) {
$quotaPercent = 100 ;
} else {
$quotaPercent = round (( $_usage * 100 ) / $_limit );
}
$quotaLimit = mail_bo :: show_readable_size ( $_limit * 1024 );
$quotaUsage = mail_bo :: show_readable_size ( $_usage * 1024 );
if ( $quotaPercent > 90 && $_limit > 0 ) {
$quotaBG = 'mail-index_QuotaRed' ;
} elseif ( $quotaPercent > 80 && $_limit > 0 ) {
$quotaBG = 'mail-index_QuotaYellow' ;
} else {
$quotaBG = 'mail-index_QuotaGreen' ;
}
if ( $_limit > 0 ) {
$quotaText = $quotaUsage . '/' . $quotaLimit ;
} else {
$quotaText = $quotaUsage ;
}
if ( $quotaPercent > 50 ) {
} else {
}
$quota [ 'class' ] = $quotaBG ;
2013-12-16 11:28:19 +01:00
$quota [ 'text' ] = lang ( 'Quota: %1' , $quotaText );
2014-07-16 15:42:36 +02:00
$quota [ 'percent' ] = ( string ) round (( $_usage * 100 ) / $_limit );
2013-10-03 18:09:25 +02:00
return $quota ;
}
2013-06-12 13:50:30 +02:00
/**
* display image
*
* all params are passed as GET Parameters
*/
function displayImage ()
{
$uid = $_GET [ 'uid' ];
$cid = base64_decode ( $_GET [ 'cid' ]);
$partID = urldecode ( $_GET [ 'partID' ]);
if ( ! empty ( $_GET [ 'mailbox' ])) $mailbox = base64_decode ( $_GET [ 'mailbox' ]);
2013-11-10 21:53:51 +01:00
2013-06-12 13:50:30 +02:00
//error_log(__METHOD__.__LINE__.":$uid, $cid, $partID");
$this -> mail_bo -> reopen ( $mailbox );
2013-11-10 21:53:51 +01:00
$attachment = $this -> mail_bo -> getAttachmentByCID ( $uid , $cid , $partID , true ); // true get contents as stream
2013-06-12 13:50:30 +02:00
$this -> mail_bo -> closeConnection ();
$GLOBALS [ 'egw' ] -> session -> commit_session ();
2013-11-10 21:53:51 +01:00
if ( $attachment )
{
2014-07-16 15:42:36 +02:00
header ( " Content-Type: " . $attachment -> getType ());
2013-11-10 21:53:51 +01:00
header ( 'Content-Disposition: inline; filename="' . $attachment -> getDispositionParameter ( 'filename' ) . '"' );
2014-02-04 13:31:11 +01:00
//header("Expires: 0");
2013-06-12 13:50:30 +02:00
// the next headers are for IE and SSL
2014-02-04 13:31:11 +01:00
//header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
//header("Pragma: public");
egw_session :: cache_control ( true );
2013-11-10 21:53:51 +01:00
echo $attachment -> getContents ();
2013-06-12 13:50:30 +02:00
}
2013-11-10 21:53:51 +01:00
else
{
// send a 404 Not found
header ( " HTTP/1.1 404 Not found " );
}
common :: egw_exit ();
2013-06-12 13:50:30 +02:00
}
function getAttachment ()
{
if ( isset ( $_GET [ 'id' ])) $rowID = $_GET [ 'id' ];
$hA = self :: splitRowID ( $rowID );
$uid = $hA [ 'msgUID' ];
$mailbox = $hA [ 'folder' ];
$part = $_GET [ 'part' ];
$is_winmail = $_GET [ 'is_winmail' ] ? $_GET [ 'is_winmail' ] : 0 ;
$this -> mail_bo -> reopen ( $mailbox );
2013-11-20 10:30:25 +01:00
$attachment = $this -> mail_bo -> getAttachment ( $uid , $part , $is_winmail , false );
2013-06-12 13:50:30 +02:00
$this -> mail_bo -> closeConnection ();
$GLOBALS [ 'egw' ] -> session -> commit_session ();
2014-02-10 14:24:08 +01:00
//error_log(__METHOD__.print_r($_GET,true));
2013-06-12 13:50:30 +02:00
if ( $_GET [ 'mode' ] != " save " )
{
2014-02-10 14:24:08 +01:00
if ( strtoupper ( $attachment [ 'type' ]) == 'TEXT/DIRECTORY' || empty ( $attachment [ 'type' ]))
2013-06-12 13:50:30 +02:00
{
$sfxMimeType = $attachment [ 'type' ];
$buff = explode ( '.' , $attachment [ 'filename' ]);
$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 ,
);
2014-02-04 12:31:13 +01:00
egw :: redirect_link ( '../index.php' , $vars );
2013-06-12 13:50:30 +02:00
}
//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 ,
);
2014-02-04 12:31:13 +01:00
egw :: redirect_link ( '../index.php' , $vars );
2013-06-12 13:50:30 +02:00
}
//Import failed, download content anyway
}
}
2014-02-10 14:24:08 +01:00
//error_log(__METHOD__.__LINE__.'->'.array2string($attachment));
2014-02-12 11:56:44 +01:00
$filename = ( $attachment [ 'name' ] ? $attachment [ 'name' ] : ( $attachment [ 'filename' ] ? $attachment [ 'filename' ] : $mailbox . '_uid' . $uid . '_part' . $part ));
2014-02-25 16:59:22 +01:00
html :: content_header ( $filename , $attachment [ 'type' ], 0 , True ,( $_GET [ 'mode' ] == " save " ));
2013-06-12 13:50:30 +02:00
echo $attachment [ 'attachment' ];
$GLOBALS [ 'egw' ] -> common -> egw_exit ();
exit ;
}
2013-02-28 10:28:08 +01:00
/**
* save messages on disk or filemanager , or display it in popup
*
* all params are passed as GET Parameters
*/
function saveMessage ()
{
$display = false ;
if ( isset ( $_GET [ 'id' ])) $rowID = $_GET [ 'id' ];
2014-07-16 18:34:15 +02:00
if ( isset ( $_GET [ 'part' ])) $partID = $_GET [ 'part' ];
2013-02-28 10:28:08 +01:00
if ( isset ( $_GET [ 'location' ]) && ( $_GET [ 'location' ] == 'display' || $_GET [ 'location' ] == 'filemanager' )) $display = $_GET [ 'location' ];
2013-03-05 15:09:35 +01:00
$hA = self :: splitRowID ( $rowID );
2013-02-28 10:28:08 +01:00
$uid = $hA [ 'msgUID' ];
$mailbox = $hA [ 'folder' ];
$this -> mail_bo -> reopen ( $mailbox );
2014-02-05 10:24:46 +01:00
$message = $this -> mail_bo -> getMessageRawBody ( $uid , $partID , $mailbox );
$headers = $this -> mail_bo -> getMessageHeader ( $uid , $partID , true , false , $mailbox );
2013-02-28 10:28:08 +01:00
$this -> mail_bo -> closeConnection ();
$GLOBALS [ 'egw' ] -> session -> commit_session ();
if ( $display == false )
{
$subject = str_replace ( '$$' , '__' , mail_bo :: decode_header ( $headers [ 'SUBJECT' ]));
2014-02-25 16:59:22 +01:00
html :: content_header ( $subject . " .eml " , 'message/rfc822' , 0 , True ,( $display == false ));
2013-02-28 10:28:08 +01:00
echo $message ;
$GLOBALS [ 'egw' ] -> common -> egw_exit ();
exit ;
}
else
{
header ( 'Content-type: text/html; charset=iso-8859-1' );
print '<pre>' . htmlspecialchars ( $message , ENT_NOQUOTES , 'iso-8859-1' ) . '</pre>' ;
}
}
2013-03-05 15:09:35 +01:00
/**
* Save an Message in the vfs
*
* @ param string | array $ids use splitRowID , to separate values
* @ param string $path path in vfs ( no egw_vfs :: PREFIX ! ), only directory for multiple id ' s ( $ids is an array )
* @ return string javascript eg . to close the selector window
*/
function vfsSaveMessage ( $ids , $path )
{
2013-04-12 11:22:23 +02:00
error_log ( __METHOD__ . ' IDs:' . array2string ( $ids ) . ' SaveToPath:' . $path );
2013-03-05 15:09:35 +01:00
if ( is_array ( $ids ) && ! egw_vfs :: is_writable ( $path ) || ! is_array ( $ids ) && ! egw_vfs :: is_writable ( dirname ( $path )))
{
return 'alert("' . addslashes ( lang ( '%1 is NOT writable by you!' , $path )) . '"); window.close();' ;
}
foreach (( array ) $ids as $id )
{
$hA = self :: splitRowID ( $id );
$uid = $hA [ 'msgUID' ];
$mailbox = $hA [ 'folder' ];
2014-02-05 10:24:46 +01:00
$message = $this -> mail_bo -> getMessageRawBody ( $uid , $partID = '' , $mailbox );
2014-02-14 15:09:56 +01:00
$err = null ;
2014-07-16 18:34:15 +02:00
if ( ! ( $fp = egw_vfs :: fopen ( $file = $path , 'wb' )) || ! fwrite ( $fp , $message ))
2013-03-05 15:09:35 +01:00
{
2014-02-14 15:09:56 +01:00
$err .= lang ( 'Error saving %1!' , $file );
2013-08-21 12:47:20 +02:00
$succeeded = false ;
}
else
{
$succeeded = true ;
2013-03-05 15:09:35 +01:00
}
if ( $fp ) fclose ( $fp );
2013-08-21 12:47:20 +02:00
if ( $succeeded )
{
translation :: add_app ( 'mail' );
2014-02-05 10:24:46 +01:00
$headers = $this -> mail_bo -> getMessageHeader ( $uid , $partID , true , false , $mailbox );
2013-08-21 12:47:20 +02:00
unset ( $headers [ 'SUBJECT' ]); //already in filename
$infoSection = mail_bo :: createHeaderInfoSection ( $headers , 'SUPPRESS' , false );
$props = array ( array ( 'name' => 'comment' , 'val' => $infoSection ));
egw_vfs :: proppatch ( $file , $props );
}
2013-03-05 15:09:35 +01:00
}
2014-02-14 15:09:56 +01:00
egw_framework :: window_close (( $err ? $err : null ));
2013-04-12 11:22:23 +02:00
}
2013-07-15 15:37:28 +02:00
/**
* Save an attachment in the vfs
*
* @ param string | array $ids '::' delimited mailbox :: uid :: part - id :: is_winmail :: name ( :: name for multiple id ' s )
* @ param string $path path in vfs ( no egw_vfs :: PREFIX ! ), only directory for multiple id ' s ( $ids is an array )
* @ return string javascript eg . to close the selector window
*/
function vfsSaveAttachment ( $ids , $path )
{
2014-02-14 13:20:25 +01:00
//error_log(__METHOD__.__LINE__.'("'.array2string($ids).'","'.$path."\")');");
2013-07-15 15:37:28 +02:00
if ( is_array ( $ids ) && ! egw_vfs :: is_writable ( $path ) || ! is_array ( $ids ) && ! egw_vfs :: is_writable ( dirname ( $path )))
{
return 'alert("' . addslashes ( lang ( '%1 is NOT writable by you!' , $path )) . '"); window.close();' ;
}
2014-02-14 15:09:56 +01:00
$err = null ;
2013-07-15 15:37:28 +02:00
foreach (( array ) $ids as $id )
{
list ( $app , $user , $serverID , $mailbox , $uid , $part , $is_winmail , $name ) = explode ( '::' , $id , 8 );
$lId = implode ( '::' , array ( $app , $user , $serverID , $mailbox , $uid ));
$hA = self :: splitRowID ( $lId );
$uid = $hA [ 'msgUID' ];
$mailbox = $hA [ 'folder' ];
2013-10-03 12:05:05 +02:00
//error_log(__METHOD__.__LINE__.array2string($hA));
$this -> mail_bo -> reopen ( $mailbox );
2014-02-14 13:20:25 +01:00
$attachment = $this -> mail_bo -> getAttachment ( $uid , $part , $is_winmail , false );
//error_log(__METHOD__.__LINE__.array2string($attachment));
2013-07-15 15:37:28 +02:00
if ( ! ( $fp = egw_vfs :: fopen ( $file = $path . ( $name ? '/' . $name : '' ), 'wb' )) ||
! fwrite ( $fp , $attachment [ 'attachment' ]))
{
2014-02-14 15:09:56 +01:00
$err .= lang ( 'Error saving %1!' , $file );
2013-07-15 15:37:28 +02:00
}
if ( $fp ) fclose ( $fp );
}
$this -> mail_bo -> closeConnection ();
2014-02-14 15:09:56 +01:00
egw_framework :: window_close (( $err ? $err : null ));
2013-07-15 15:37:28 +02:00
}
2014-07-03 18:57:14 +02:00
/**
* Zip all attachments and send to user
2014-07-16 18:34:15 +02:00
* @ param string $message_id = null
2014-07-03 18:57:14 +02:00
*/
2014-07-08 14:01:29 +02:00
function download_zip ( $message_id = null )
2014-07-03 18:57:14 +02:00
{
// First, get all attachment IDs
2014-07-08 14:01:29 +02:00
if ( isset ( $_GET [ 'id' ])) $message_id = $_GET [ 'id' ];
//error_log(__METHOD__.__LINE__.$message_id);
2014-07-03 19:17:54 +02:00
if ( ! is_numeric ( $message_id ))
{
$hA = self :: splitRowID ( $message_id );
$message_id = $hA [ 'msgUID' ];
$mailbox = $hA [ 'folder' ];
}
else
{
$mailbox = $this -> mail_bo -> sessionData [ 'mailbox' ];
}
2014-07-08 13:09:31 +02:00
2014-07-08 12:20:19 +02:00
$attachments = $this -> mail_bo -> getMessageAttachments ( $message_id , null , null , false , true , true , $mailbox );
2014-07-03 18:57:14 +02:00
// put them in VFS so they can be zipped
2014-07-08 12:20:19 +02:00
$header = $this -> mail_bo -> getMessageHeader ( $message_id , '' , true , false , $mailbox );
2014-07-03 18:57:14 +02:00
$temp_path = egw_vfs :: get_home_dir () . " /.mail_ $message_id " ;
if ( egw_vfs :: is_dir ( $temp_path )) egw_vfs :: remove ( $temp_path );
// Add subject to path, so it gets used as the file name
$path = $temp_path . '/' . ( $header [ 'SUBJECT' ] ? egw_vfs :: encodePathComponent ( $header [ 'SUBJECT' ]) : lang ( 'mail' )) . '/' ;
if ( ! egw_vfs :: mkdir ( $path , 0700 , true ))
{
egw_framework :: message ( " Unable to open temp directory $path " , 'error' );
return ;
}
$file_list = array ();
2014-07-03 19:17:54 +02:00
$this -> mail_bo -> reopen ( $mailbox );
2014-07-03 18:57:14 +02:00
foreach ( $attachments as $file )
{
$attachment = $this -> mail_bo -> getAttachment ( $message_id , $file [ 'partID' ], $file [ 'is_winmail' ], false );
if ( ! ( $fp = egw_vfs :: fopen ( $path . $file [ 'filename' ], 'wb' )) ||
! fwrite ( $fp , $attachment [ 'attachment' ]))
{
egw_framework :: message ( " Unable to zip { $file [ 'filename' ] } " , 'error' );
}
$file_list [] = $path . $file [ 'filename' ];
if ( $fp ) fclose ( $fp );
}
$this -> mail_bo -> closeConnection ();
2014-07-08 13:09:31 +02:00
2014-07-03 18:57:14 +02:00
// Zip it up
egw_vfs :: download_zip ( $file_list );
// Clean up
egw_vfs :: remove ( $temp_path );
2014-07-08 13:09:31 +02:00
2014-07-03 18:57:14 +02:00
common :: egw_exit ();
}
2014-03-03 15:56:12 +01:00
function get_load_email_data ( $uid , $partID , $mailbox , $htmlOptions = null )
2013-04-12 15:10:27 +02:00
{
// seems to be needed, as if we open a mail from notification popup that is
// located in a different folder, we experience: could not parse message
$this -> mail_bo -> reopen ( $mailbox );
2014-07-16 15:42:36 +02:00
$this -> mailbox = $mailbox ;
$this -> uid = $uid ;
$this -> partID = $partID ;
2013-07-20 09:23:55 +02:00
$bufferHtmlOptions = $this -> mail_bo -> htmlOptions ;
if ( empty ( $htmlOptions )) $htmlOptions = $this -> mail_bo -> htmlOptions ;
2013-11-10 21:53:51 +01:00
$bodyParts = $this -> mail_bo -> getMessageBody ( $uid , ( $htmlOptions ? $htmlOptions : '' ), $partID , null , false , $mailbox );
2013-04-12 15:10:27 +02:00
//error_log(__METHOD__.__LINE__.array2string($bodyParts));
$fetchEmbeddedImages = false ;
2013-07-20 09:23:55 +02:00
if ( $htmlOptions != 'always_display' ) $fetchEmbeddedImages = true ;
2014-07-16 18:34:15 +02:00
$attachments = ( array ) $this -> mail_bo -> getMessageAttachments ( $uid , $partID , null , $fetchEmbeddedImages , true , true , $mailbox );
2014-02-10 17:37:21 +01:00
//error_log(__METHOD__.__LINE__.array2string($attachments));
2014-07-16 18:34:15 +02:00
foreach ( $attachments as & $attach )
2013-04-12 15:10:27 +02:00
{
if ( strtolower ( $attach [ 'mimeType' ]) == 'text/calendar' &&
( strtolower ( $attach [ 'method' ]) == 'request' || strtolower ( $attach [ 'method' ]) == 'reply' ) &&
isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'calendar' ]) &&
2014-02-10 17:37:21 +01:00
( $attachment = $this -> mail_bo -> getAttachment ( $uid , $attach [ 'partID' ], 0 ,( strtolower ( $attach [ 'mimeType' ]) == 'text/calendar' ? false : true ))))
2013-04-12 15:10:27 +02:00
{
2013-06-03 11:58:27 +02:00
//error_log(__METHOD__.__LINE__.array2string($attachment));
2013-04-12 15:10:27 +02:00
egw_cache :: setSession ( 'calendar' , 'ical' , array (
'charset' => $attach [ 'charset' ] ? $attach [ 'charset' ] : 'utf-8' ,
'attachment' => $attachment [ 'attachment' ],
'method' => $attach [ 'method' ],
2014-07-16 18:34:15 +02:00
'sender' => $mailbox ,
2013-04-12 15:10:27 +02:00
));
2013-07-20 09:23:55 +02:00
$this -> mail_bo -> htmlOptions = $bufferHtmlOptions ;
2014-02-12 13:05:22 +01:00
translation :: add_app ( 'calendar' );
2013-06-03 11:58:27 +02:00
return ExecMethod ( 'calendar.calendar_uiforms.meeting' ,
array ( 'event' => null , 'msg' => '' , 'useSession' => true )
);
2013-04-12 15:10:27 +02:00
}
}
// Compose the content of the frame
$frameHtml =
2014-03-03 15:56:12 +01:00
$this -> get_email_header ( $this -> mail_bo -> getStyles ( $bodyParts )) .
$this -> showBody ( $this -> getdisplayableBody ( $bodyParts ), false );
2013-04-12 15:10:27 +02:00
//IE10 eats away linebreaks preceeded by a whitespace in PRE sections
$frameHtml = str_replace ( " \r \n " , " \r \n " , $frameHtml );
2013-07-20 09:23:55 +02:00
$this -> mail_bo -> htmlOptions = $bufferHtmlOptions ;
2013-04-12 15:10:27 +02:00
return $frameHtml ;
}
2014-03-03 15:56:12 +01:00
static function get_email_header ( $additionalStyle = '' )
2013-04-12 15:10:27 +02:00
{
2014-03-03 15:56:12 +01:00
// egw_info[flags][css] already include <style> tags
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'css' ] = preg_replace ( '|</?style[^>]*>|i' , '' , $additionalStyle );
2014-03-07 15:26:16 +01:00
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'nofooter' ] = true ;
$GLOBALS [ 'egw_info' ][ 'flags' ][ 'nonavbar' ] = true ;
2014-03-03 15:56:12 +01:00
// do NOT include any default CSS
egw_framework :: includeCSS ( 'mail' , 'preview' , true , true );
// load preview.js to activate mailto links
egw_framework :: validate_file ( '/mail/js/preview.js' );
// send CSP and content-type header
return $GLOBALS [ 'egw' ] -> framework -> header ();
2013-04-12 15:10:27 +02:00
}
2013-06-05 16:24:56 +02:00
function showBody ( & $body , $print = true , $fullPageTags = true )
2013-04-12 15:10:27 +02:00
{
2014-03-04 11:48:35 +01:00
$BeginBody = ' < div class = " mailDisplayBody " >
2014-07-16 15:42:36 +02:00
< table width = " 100% " style = " table-layout:fixed " >< tr >< td class = " td_display " > ' ;
2013-04-12 15:10:27 +02:00
$EndBody = '</td></tr></table></div>' ;
2013-06-05 16:24:56 +02:00
if ( $fullPageTags ) $EndBody .= " </body></html> " ;
2013-04-12 15:10:27 +02:00
if ( $print ) {
print $BeginBody . $body . $EndBody ;
} else {
return $BeginBody . $body . $EndBody ;
}
}
function & getdisplayableBody ( $_bodyParts , $modifyURI = true )
{
$bodyParts = $_bodyParts ;
$nonDisplayAbleCharacters = array ( '[\016]' , '[\017]' ,
'[\020]' , '[\021]' , '[\022]' , '[\023]' , '[\024]' , '[\025]' , '[\026]' , '[\027]' ,
'[\030]' , '[\031]' , '[\032]' , '[\033]' , '[\034]' , '[\035]' , '[\036]' , '[\037]' );
$body = '' ;
//error_log(__METHOD__.array2string($bodyParts)); //exit;
if ( empty ( $bodyParts )) return " " ;
foreach (( array ) $bodyParts as $singleBodyPart ) {
if ( ! isset ( $singleBodyPart [ 'body' ])) {
$singleBodyPart [ 'body' ] = $this -> getdisplayableBody ( $singleBodyPart , $modifyURI );
$body .= $singleBodyPart [ 'body' ];
continue ;
}
2013-09-10 15:39:44 +02:00
$bodyPartIsSet = strlen ( trim ( $singleBodyPart [ 'body' ]));
if ( ! $bodyPartIsSet )
{
$body .= '' ;
continue ;
}
2013-04-12 15:10:27 +02:00
if ( ! empty ( $body )) {
$body .= '<hr style="border:dotted 1px silver;">' ;
}
//error_log($singleBodyPart['body']);
//error_log(__METHOD__.__LINE__.' CharSet:'.$singleBodyPart['charSet'].' mimeType:'.$singleBodyPart['mimeType']);
// some characterreplacements, as they fail to translate
$sar = array (
'@(\x84|\x93|\x94)@' ,
'@(\x96|\x97|\x1a)@' ,
'@(\x82|\x91|\x92)@' ,
'@(\x85)@' ,
'@(\x86)@' ,
'@(\x99)@' ,
'@(\xae)@' ,
);
$rar = array (
'"' ,
'-' ,
'\'' ,
'...' ,
'&' ,
'(TM)' ,
'(R)' ,
);
if (( $singleBodyPart [ 'mimeType' ] == 'text/html' || $singleBodyPart [ 'mimeType' ] == 'text/plain' ) &&
strtoupper ( $singleBodyPart [ 'charSet' ]) != 'UTF-8' )
{
$singleBodyPart [ 'body' ] = preg_replace ( $sar , $rar , $singleBodyPart [ 'body' ]);
}
if ( $singleBodyPart [ 'charSet' ] === false ) $singleBodyPart [ 'charSet' ] = translation :: detect_encoding ( $singleBodyPart [ 'body' ]);
$singleBodyPart [ 'body' ] = $GLOBALS [ 'egw' ] -> translation -> convert (
$singleBodyPart [ 'body' ],
strtolower ( $singleBodyPart [ 'charSet' ])
);
// 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 ( mail_bo :: $displayCharset ) == 'UTF-8' )
{
$test = @ json_encode ( $singleBodyPart [ 'body' ]);
//error_log(__METHOD__.__LINE__.' ->'.strlen($singleBodyPart['body']).' Error:'.json_last_error().'<- BodyPart:#'.$test.'#');
if (( $test == " null " || $test === false || is_null ( $test )) && strlen ( $singleBodyPart [ 'body' ]) > 0 )
{
2013-07-15 14:31:02 +02:00
// try to fix broken utf8
$x = ( function_exists ( 'mb_convert_encoding' ) ? mb_convert_encoding ( $singleBodyPart [ 'body' ], 'UTF-8' , 'UTF-8' ) : ( function_exists ( 'iconv' ) ? @ iconv ( " UTF-8 " , " UTF-8//IGNORE " , $singleBodyPart [ 'body' ]) : $singleBodyPart [ 'body' ]));
$test = @ json_encode ( $x );
if (( $test == " null " || $test === false || is_null ( $test )) && strlen ( $singleBodyPart [ 'body' ]) > 0 )
{
// this should not be needed, unless something fails with charset detection/ wrong charset passed
error_log ( __METHOD__ . __LINE__ . ' Charset Reported:' . $singleBodyPart [ 'charSet' ] . ' Charset Detected:' . translation :: detect_encoding ( $singleBodyPart [ 'body' ]));
$singleBodyPart [ 'body' ] = utf8_encode ( $singleBodyPart [ 'body' ]);
}
else
{
$singleBodyPart [ 'body' ] = $x ;
}
2013-04-12 15:10:27 +02:00
}
}
2013-04-12 15:30:54 +02:00
//error_log(__METHOD__.__LINE__.array2string($singleBodyPart));
2013-04-12 15:10:27 +02:00
if ( $singleBodyPart [ 'mimeType' ] == 'text/plain' )
{
$newBody = @ htmlentities ( $singleBodyPart [ 'body' ], ENT_QUOTES , strtoupper ( mail_bo :: $displayCharset ));
// if empty and charset is utf8 try sanitizing the string in question
if ( empty ( $newBody ) && strtolower ( $singleBodyPart [ 'charSet' ]) == 'utf-8' ) $newBody = @ htmlentities ( iconv ( 'utf-8' , 'utf-8' , $singleBodyPart [ 'body' ]), ENT_QUOTES , strtoupper ( mail_bo :: $displayCharset ));
// if the conversion to htmlentities fails somehow, try without specifying the charset, which defaults to iso-
if ( empty ( $newBody )) $newBody = htmlentities ( $singleBodyPart [ 'body' ], ENT_QUOTES );
// search http[s] links and make them as links available again
// to understand what's going on here, have a look at
// http://www.php.net/manual/en/function.preg-replace.php
// create links for websites
if ( $modifyURI ) $newBody = html :: activate_links ( $newBody );
// redirect links for websites if you use no cookies
#if (!($GLOBALS['egw_info']['server']['usecookies']))
# $newBody = preg_replace("/href=(\"|\')((http(s?):\/\/)|(www\.))([\w,\-,\/,\?,\=,\.,&,!\n,\%,@,\(,\),\*,#,:,~,\+]+)(\"|\')/ie",
# "'href=\"$webserverURL/redirect.php?go='.@htmlentities(urlencode('http$4://$5$6'),ENT_QUOTES,\"mail_bo::$displayCharset\").'\"'", $newBody);
// create links for email addresses
//TODO:if ($modifyURI) $this->parseEmail($newBody);
// create links for inline images
if ( $modifyURI )
{
$newBody = preg_replace_callback ( " / \ [cid:(.*) \ ]/iU " , array ( $this , 'image_callback_plain' ), $newBody );
}
//TODO:$newBody = $this->highlightQuotes($newBody);
// to display a mailpart of mimetype plain/text, may be better taged as preformatted
#$newBody = nl2br($newBody);
// since we do not display the message as HTML anymore we may want to insert good linebreaking (for visibility).
//error_log($newBody);
// dont break lines that start with > (> as the text was processed with htmlentities before)
2013-04-12 15:30:54 +02:00
$newBody = " <pre> " . mail_bo :: wordwrap ( $newBody , 90 , " \n " , '>' ) . " </pre> " ;
2013-04-12 15:10:27 +02:00
}
else
{
$newBody = $singleBodyPart [ 'body' ];
//TODO:$newBody = $this->highlightQuotes($newBody);
#error_log(print_r($newBody,true));
// do the cleanup, set for the use of purifier
$usepurifier = true ;
$newBodyBuff = $newBody ;
mail_bo :: getCleanHTML ( $newBody , $usepurifier );
// 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 ( mail_bo :: $displayCharset ) == 'UTF-8' )
{
$test = @ json_encode ( $newBody );
//error_log(__METHOD__.__LINE__.' ->'.strlen($singleBodyPart['body']).' Error:'.json_last_error().'<- BodyPart:#'.$test.'#');
if (( $test == " null " || $test === false || is_null ( $test )) && strlen ( $newBody ) > 0 )
{
$newBody = $newBodyBuff ;
$tv = mail_bo :: $htmLawed_config [ 'tidy' ];
mail_bo :: $htmLawed_config [ 'tidy' ] = 0 ;
mail_bo :: getCleanHTML ( $newBody , $usepurifier );
mail_bo :: $htmLawed_config [ 'tidy' ] = $tv ;
}
}
// removes stuff between http and ?http
$Protocol = '(http:\/\/|(ftp:\/\/|https:\/\/))' ; // only http:// gets removed, other protocolls are shown
$newBody = preg_replace ( '~' . $Protocol . '[^>]*\?' . $Protocol . '~sim' , '$1' , $newBody ); // removes stuff between http:// and ?http://
// TRANSFORM MAILTO LINKS TO EMAILADDRESS ONLY, WILL BE SUBSTITUTED BY parseEmail TO CLICKABLE LINK
$newBody = preg_replace ( '/(?<!"|href=|href\s=\s|href=\s|href\s=)' . 'mailto:([a-z0-9._-]+)@([a-z0-9_-]+)\.([a-z0-9._-]+)/i' ,
" \\ 1@ \\ 2. \\ 3 " ,
$newBody );
// redirect links for websites if you use no cookies
#if (!($GLOBALS['egw_info']['server']['usecookies'])) { //do it all the time, since it does mask the mailadresses in urls
//TODO:if ($modifyURI) $this->parseHREF($newBody);
#}
// create links for inline images
if ( $modifyURI )
{
$newBody = preg_replace_callback ( " /src=( \" | \ ')cid:(.*)( \" | \ ')/iU " , array ( $this , 'image_callback' ), $newBody );
$newBody = preg_replace_callback ( " /url \ (cid:(.*) \ );/iU " , array ( $this , 'image_callback_url' ), $newBody );
$newBody = preg_replace_callback ( " /background=( \" | \ ')cid:(.*)( \" | \ ')/iU " , array ( $this , 'image_callback_background' ), $newBody );
}
2014-03-03 15:56:12 +01:00
// email addresses / mailto links get now activated on client-side
2013-04-12 15:10:27 +02:00
}
$body .= $newBody ;
}
// create links for windows shares
// \\\\\\\\ == '\\' in real life!! :)
$body = preg_replace ( " /( \\ \\ \\ \\ )([ \ w, \\ \\ ,-]+)/i " ,
" <a href= \" file: $ 1 $ 2 \" target= \" _blank \" ><font color= \" blue \" > $ 1 $ 2</font></a> " , $body );
$body = preg_replace ( $nonDisplayAbleCharacters , '' , $body );
return $body ;
}
/**
* preg_replace callback to replace image cid url ' s
*
* @ param array $matches matches from preg_replace ( " /src=( \" | \ ')cid:(.*)( \" | \ ')/iU " , ... )
* @ return string src attribute to replace
*/
function image_callback ( $matches )
{
static $cache = array (); // some caching, if mails containing the same image multiple times
2013-07-20 15:46:17 +02:00
2013-04-12 15:10:27 +02:00
$linkData = array (
2013-06-12 13:50:30 +02:00
'menuaction' => 'mail.mail_ui.displayImage' ,
2013-04-12 15:10:27 +02:00
'uid' => $this -> uid ,
'mailbox' => base64_encode ( $this -> mailbox ),
'cid' => base64_encode ( $matches [ 2 ]),
'partID' => $this -> partID ,
);
2014-02-04 12:31:13 +01:00
$imageURL = egw :: link ( '/index.php' , $linkData );
2013-04-12 15:10:27 +02:00
// to test without data uris, comment the if close incl. it's body
if ( html :: $user_agent != 'msie' || html :: $ua_version >= 8 )
{
if ( ! isset ( $cache [ $imageURL ]))
{
$attachment = $this -> mail_bo -> getAttachmentByCID ( $this -> uid , $matches [ 2 ], $this -> partID );
// only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
2014-01-18 13:47:46 +01:00
if (( $attachment instanceof Horde_Mime_Part ) && $attachment -> getBytes () < 8192 ) // msie=8 allows max 32k data uris
2013-04-12 15:10:27 +02:00
{
2013-11-10 21:53:51 +01:00
$this -> mail_bo -> fetchPartContents ( $this -> uid , $attachment );
$cache [ $imageURL ] = 'data:' . $attachment -> getType () . ';base64,' . base64_encode ( $attachment -> getContents ());
2013-04-12 15:10:27 +02:00
}
else
{
$cache [ $imageURL ] = $imageURL ;
}
}
$imageURL = $cache [ $imageURL ];
}
return 'src="' . $imageURL . '"' ;
}
/**
* preg_replace callback to replace image cid url ' s
*
* @ param array $matches matches from preg_replace ( " /src=( \" | \ ')cid:(.*)( \" | \ ')/iU " , ... )
* @ return string src attribute to replace
*/
function image_callback_plain ( $matches )
{
static $cache = array (); // some caching, if mails containing the same image multiple times
//error_log(__METHOD__.__LINE__.array2string($matches));
$linkData = array (
2013-06-12 13:50:30 +02:00
'menuaction' => 'mail.mail_ui.displayImage' ,
2013-04-12 15:10:27 +02:00
'uid' => $this -> uid ,
'mailbox' => base64_encode ( $this -> mailbox ),
'cid' => base64_encode ( $matches [ 1 ]),
'partID' => $this -> partID ,
);
2014-02-04 12:31:13 +01:00
$imageURL = egw :: link ( '/index.php' , $linkData );
2013-04-12 15:10:27 +02:00
// to test without data uris, comment the if close incl. it's body
if ( html :: $user_agent != 'msie' || html :: $ua_version >= 8 )
{
if ( ! isset ( $cache [ $imageURL ]))
{
$attachment = $this -> mail_bo -> getAttachmentByCID ( $this -> uid , $matches [ 1 ], $this -> partID );
// only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
2014-01-18 13:47:46 +01:00
if (( $attachment instanceof Horde_Mime_Part ) && bytes ( $attachment -> getBytes ()) < 8192 ) // msie=8 allows max 32k data uris
2013-04-12 15:10:27 +02:00
{
2013-11-10 21:53:51 +01:00
$this -> mail_bo -> fetchPartContents ( $this -> uid , $attachment );
$cache [ $imageURL ] = 'data:' . $attachment -> getType () . ';base64,' . base64_encode ( $attachment -> getContents ());
2013-04-12 15:10:27 +02:00
}
else
{
$cache [ $imageURL ] = $imageURL ;
}
}
$imageURL = $cache [ $imageURL ];
}
return '<img src="' . $imageURL . '" />' ;
}
/**
* preg_replace callback to replace image cid url ' s
*
* @ param array $matches matches from preg_replace ( " /src=( \" | \ ')cid:(.*)( \" | \ ')/iU " , ... )
* @ return string src attribute to replace
*/
function image_callback_url ( $matches )
{
static $cache = array (); // some caching, if mails containing the same image multiple times
//error_log(__METHOD__.__LINE__.array2string($matches));
$linkData = array (
2013-06-12 13:50:30 +02:00
'menuaction' => 'mail.mail_ui.displayImage' ,
2013-04-12 15:10:27 +02:00
'uid' => $this -> uid ,
'mailbox' => base64_encode ( $this -> mailbox ),
'cid' => base64_encode ( $matches [ 1 ]),
'partID' => $this -> partID ,
);
2014-02-04 12:31:13 +01:00
$imageURL = egw :: link ( '/index.php' , $linkData );
2013-04-12 15:10:27 +02:00
// to test without data uris, comment the if close incl. it's body
if ( html :: $user_agent != 'msie' || html :: $ua_version >= 8 )
{
if ( ! isset ( $cache [ $imageURL ]))
{
$attachment = $this -> mail_bo -> getAttachmentByCID ( $this -> uid , $matches [ 1 ], $this -> partID );
// only use data uri for "smaller" images, as otherwise the first display of the mail takes to long
2014-01-18 13:47:46 +01:00
if (( $attachment instanceof Horde_Mime_Part ) && $attachment -> getBytes () < 8192 ) // msie=8 allows max 32k data uris
2013-04-12 15:10:27 +02:00
{
2013-11-10 21:53:51 +01:00
$this -> mail_bo -> fetchPartContents ( $this -> uid , $attachment );
$cache [ $imageURL ] = 'data:' . $attachment -> getType () . ';base64,' . base64_encode ( $attachment -> getContents ());
2013-04-12 15:10:27 +02:00
}
else
{
$cache [ $imageURL ] = $imageURL ;
}
}
$imageURL = $cache [ $imageURL ];
}
return 'url(' . $imageURL . ');' ;
}
/**
* preg_replace callback to replace image cid url ' s
*
* @ param array $matches matches from preg_replace ( " /src=( \" | \ ')cid:(.*)( \" | \ ')/iU " , ... )
* @ return string src attribute to replace
*/
function image_callback_background ( $matches )
{
static $cache = array (); // some caching, if mails containing the same image multiple times
$linkData = array (
2013-06-12 13:50:30 +02:00
'menuaction' => 'mail.mail_ui.displayImage' ,
2013-04-12 15:10:27 +02:00
'uid' => $this -> uid ,
'mailbox' => base64_encode ( $this -> mailbox ),
'cid' => base64_encode ( $matches [ 2 ]),
'partID' => $this -> partID ,
);
2014-02-04 12:31:13 +01:00
$imageURL = egw :: link ( '/index.php' , $linkData );
2013-04-12 15:10:27 +02:00
// to test without data uris, comment the if close incl. it's body
if ( html :: $user_agent != 'msie' || html :: $ua_version >= 8 )
{
if ( ! isset ( $cache [ $imageURL ]))
{
$cache [ $imageURL ] = $imageURL ;
}
$imageURL = $cache [ $imageURL ];
}
return 'background="' . $imageURL . '"' ;
}
2013-04-12 11:22:23 +02:00
/**
* importMessage
2014-07-16 13:37:02 +02:00
* @ param array $content = null an array of content
2013-04-12 11:22:23 +02:00
*/
2013-09-05 16:52:11 +02:00
function importMessage ( $content = null )
2013-04-12 11:22:23 +02:00
{
2013-09-05 16:52:11 +02:00
//error_log(__METHOD__.__LINE__.$this->mail_bo->getDraftFolder());
2013-09-24 15:38:02 +02:00
2013-09-05 16:52:11 +02:00
if ( ! empty ( $content ))
{
2014-07-08 10:50:43 +02:00
//error_log(__METHOD__.__LINE__.array2string($content));
2014-07-16 13:37:02 +02:00
if ( $content [ 'vfsfile' ])
2013-10-16 13:25:46 +02:00
{
2014-07-16 13:37:02 +02:00
$file = $content [ 'vfsfile' ] = array (
'name' => egw_vfs :: basename ( $content [ 'vfsfile' ]),
'type' => egw_vfs :: mime_content_type ( $content [ 'vfsfile' ]),
'file' => egw_vfs :: PREFIX . $content [ 'vfsfile' ],
'size' => filesize ( egw_vfs :: PREFIX . $content [ 'vfsfile' ]),
2013-10-16 13:25:46 +02:00
);
}
else
{
2014-07-16 13:37:02 +02:00
$file = $content [ 'uploadForImport' ];
2013-10-16 13:25:46 +02:00
}
2014-07-16 13:37:02 +02:00
$destination = $content [ 'FOLDER' ][ 0 ];
2013-09-05 16:52:11 +02:00
$importID = mail_bo :: getRandomString ();
$importFailed = false ;
try
2013-04-12 11:22:23 +02:00
{
2013-10-16 13:25:46 +02:00
$messageUid = $this -> importMessageToFolder ( $file , $destination , $importID );
2013-09-05 16:52:11 +02:00
$linkData = array
(
2014-07-16 13:37:02 +02:00
'id' => $this -> createRowID ( $destination , $messageUid , true ),
2013-09-05 16:52:11 +02:00
);
2013-04-12 11:22:23 +02:00
}
2013-09-05 16:52:11 +02:00
catch ( egw_exception_wrong_userinput $e )
2013-04-12 11:22:23 +02:00
{
2013-09-05 16:52:11 +02:00
$importFailed = true ;
$content [ 'msg' ] = $e -> getMessage ();
2013-04-12 11:22:23 +02:00
}
2013-09-05 16:52:11 +02:00
if ( ! $importFailed )
2013-04-12 11:22:23 +02:00
{
2013-09-05 16:52:11 +02:00
ExecMethod2 ( 'mail.mail_ui.displayMessage' , $linkData );
2013-04-12 11:22:23 +02:00
exit ;
}
2013-09-05 16:52:11 +02:00
}
if ( ! is_array ( $content )) $content = array ();
2014-07-16 13:37:02 +02:00
if ( empty ( $content [ 'FOLDER' ])) $content [ 'FOLDER' ] = ( array ) $this -> mail_bo -> getDraftFolder ();
if ( ! empty ( $content [ 'FOLDER' ])) $sel_options [ 'FOLDER' ] = mail_compose :: ajax_searchFolder ( 0 , true );
2013-04-12 11:22:23 +02:00
2013-09-05 16:52:11 +02:00
$etpl = new etemplate_new ( 'mail.importMessage' );
$etpl -> setElementAttribute ( 'uploadForImport' , 'onFinish' , 'app.mail.uploadForImport' );
2014-07-16 18:34:15 +02:00
$etpl -> exec ( 'mail.mail_ui.importMessage' , $content , $sel_options , array (), array (), 2 );
2013-09-05 16:52:11 +02:00
}
/**
* importMessageToFolder
*
* @ param array $_formData Array with information of name , type , file and size
* @ param string $_folder ( passed by reference ) will set the folder used . must be set with a folder , but will hold modifications if
* folder is modified
* @ param string $importID ID for the imported message , used by attachments to identify them unambiguously
* @ return mixed $messageUID or exception
*/
function importMessageToFolder ( $_formData , & $_folder , $importID = '' )
{
$importfailed = false ;
//error_log(__METHOD__.__LINE__.array2string($_formData));
if ( empty ( $_formData [ 'file' ])) $_formData [ 'file' ] = $_formData [ 'tmp_name' ];
// check if formdata meets basic restrictions (in tmp dir, or vfs, mimetype, etc.)
try
{
$tmpFileName = mail_bo :: checkFileBasics ( $_formData , $importID );
}
catch ( egw_exception_wrong_userinput $e )
{
$importfailed = true ;
$alert_msg .= $e -> getMessage ();
}
// -----------------------------------------------------------------------
if ( $importfailed === false )
{
$mailObject = new egw_mailer ();
2014-07-16 18:34:15 +02:00
$Header = '' ;
$Body = '' ;
2013-09-05 16:52:11 +02:00
try
2013-04-12 11:22:23 +02:00
{
2013-09-05 16:52:11 +02:00
$this -> mail_bo -> parseFileIntoMailObject ( $mailObject , $tmpFileName , $Header , $Body );
2013-04-12 11:22:23 +02:00
}
2013-09-05 16:52:11 +02:00
catch ( egw_exception_assertion_failed $e )
2013-04-12 11:22:23 +02:00
{
2013-09-05 16:52:11 +02:00
$importfailed = true ;
$alert_msg .= $e -> getMessage ();
2013-04-12 11:22:23 +02:00
}
2013-09-05 16:52:11 +02:00
$this -> mail_bo -> openConnection ();
if ( empty ( $_folder ))
2013-04-12 11:22:23 +02:00
{
2013-09-05 16:52:11 +02:00
$importfailed = true ;
$alert_msg .= lang ( " Import of message %1 failed. Destination Folder not set. " , $_formData [ 'name' ]);
2013-04-12 11:22:23 +02:00
}
2013-09-05 16:52:11 +02:00
$delimiter = $this -> mail_bo -> getHierarchyDelimiter ();
if ( $_folder == 'INBOX' . $delimiter ) $_folder = 'INBOX' ;
if ( $importfailed === false )
{
if ( $this -> mail_bo -> folderExists ( $_folder , true )) {
try
{
$messageUid = $this -> mail_bo -> appendMessage ( $_folder ,
$Header . $mailObject -> LE . $mailObject -> LE ,
2014-07-24 14:00:17 +02:00
$Body , '\\Seen' );
2013-09-05 16:52:11 +02:00
}
catch ( egw_exception_wrong_userinput $e )
{
$importfailed = true ;
$alert_msg .= lang ( " Import of message %1 failed. Could not save message to folder %2 due to: %3 " , $_formData [ 'name' ], $_folder , $e -> getMessage ());
}
}
else
{
$importfailed = true ;
$alert_msg .= lang ( " Import of message %1 failed. Destination Folder %2 does not exist. " , $_formData [ 'name' ], $_folder );
}
}
}
// set the url to open when refreshing
if ( $importfailed == true )
{
throw new egw_exception_wrong_userinput ( $alert_msg );
}
else
{
return $messageUid ;
}
}
2013-04-12 11:22:23 +02:00
2013-09-05 16:52:11 +02:00
/**
* importMessageFromVFS2DraftAndEdit
*
* @ param array $formData Array with information of name , type , file and size ; file is required ,
* name , type and size may be set here to meet the requirements
* Example : $formData [ 'name' ] = 'a_email.eml' ;
* $formData [ 'type' ] = 'message/rfc822' ;
* $formData [ 'file' ] = 'vfs://default/home/leithoff/a_email.eml' ;
* $formData [ 'size' ] = 2136 ;
* @ return void
*/
function importMessageFromVFS2DraftAndEdit ( $formData = '' )
{
$this -> importMessageFromVFS2DraftAndDisplay ( $formData , 'edit' );
}
2013-04-12 11:22:23 +02:00
2013-09-05 16:52:11 +02:00
/**
* importMessageFromVFS2DraftAndDisplay
*
* @ param array $formData Array with information of name , type , file and size ; file is required ,
* name , type and size may be set here to meet the requirements
* Example : $formData [ 'name' ] = 'a_email.eml' ;
* $formData [ 'type' ] = 'message/rfc822' ;
* $formData [ 'file' ] = 'vfs://default/home/leithoff/a_email.eml' ;
* $formData [ 'size' ] = 2136 ;
* @ param string $mode mode to open ImportedMessage display and edit are supported
* @ return void
*/
function importMessageFromVFS2DraftAndDisplay ( $formData = '' , $mode = 'display' )
{
if ( empty ( $formData )) if ( isset ( $_REQUEST [ 'formData' ])) $formData = $_REQUEST [ 'formData' ];
2014-01-24 12:48:24 +01:00
//error_log(__METHOD__.__LINE__.':'.array2string($formData).' Mode:'.$mode.'->'.function_backtrace());
2013-09-05 16:52:11 +02:00
$draftFolder = $this -> mail_bo -> getDraftFolder ( false );
$importID = mail_bo :: getRandomString ();
// name should be set to meet the requirements of checkFileBasics
if ( parse_url ( $formData [ 'file' ], PHP_URL_SCHEME ) == 'vfs' && ( ! isset ( $formData [ 'name' ]) || empty ( $formData [ 'name' ])))
{
$buff = explode ( '/' , $formData [ 'file' ]);
$suffix = '' ;
if ( is_array ( $buff )) $formData [ 'name' ] = array_pop ( $buff ); // take the last part as name
}
// type should be set to meet the requirements of checkFileBasics
if ( parse_url ( $formData [ 'file' ], PHP_URL_SCHEME ) == 'vfs' && ( ! isset ( $formData [ 'type' ]) || empty ( $formData [ 'type' ])))
{
$buff = explode ( '.' , $formData [ 'file' ]);
$suffix = '' ;
if ( is_array ( $buff )) $suffix = array_pop ( $buff ); // take the last extension to check with ext2mime
if ( ! empty ( $suffix )) $formData [ 'type' ] = mime_magic :: ext2mime ( $suffix );
}
// size should be set to meet the requirements of checkFileBasics
if ( parse_url ( $formData [ 'file' ], PHP_URL_SCHEME ) == 'vfs' && ! isset ( $formData [ 'size' ]))
{
$formData [ 'size' ] = strlen ( $formData [ 'file' ]); // set some size, to meet requirements of checkFileBasics
}
try
{
$messageUid = $this -> importMessageToFolder ( $formData , $draftFolder , $importID );
2013-04-12 11:22:23 +02:00
$linkData = array
(
2013-09-05 16:52:11 +02:00
'menuaction' => ( $mode == 'display' ? 'mail.mail_ui.displayMessage' : 'mail.mail_compose.composeFromDraft' ),
'id' => $this -> createRowID ( $draftFolder , $messageUid , true ),
'deleteDraftOnClose' => 1 ,
2013-04-12 11:22:23 +02:00
);
2013-09-05 16:52:11 +02:00
if ( $mode != 'display' )
2013-04-12 11:22:23 +02:00
{
2013-09-05 16:52:11 +02:00
unset ( $linkData [ 'deleteDraftOnClose' ]);
$linkData [ 'method' ] = 'importMessageToMergeAndSend' ;
2013-04-12 11:22:23 +02:00
}
2014-01-24 12:48:24 +01:00
else
{
$linkData [ 'mode' ] = $mode ;
}
2013-09-05 16:52:11 +02:00
}
catch ( egw_exception_wrong_userinput $e )
{
$linkData = array
(
'menuaction' => 'mail.mail_ui.importMessage' ,
'msg' => htmlspecialchars ( $e -> getMessage ()),
);
}
egw :: redirect_link ( '/index.php' , $linkData );
exit ;
2013-03-05 15:09:35 +01:00
}
2013-04-12 15:10:27 +02:00
/**
* loadEmailBody
*
* @ param string _messageID UID
*
* @ return xajax response
*/
2014-03-03 15:56:12 +01:00
function loadEmailBody ( $_messageID = null , $_partID = null , $_htmloptions = null )
2013-04-12 15:10:27 +02:00
{
2014-02-04 13:31:11 +01:00
//error_log(__METHOD__.__LINE__.array2string($_GET));
2014-02-04 12:31:13 +01:00
if ( ! $_messageID && ! empty ( $_GET [ '_messageID' ])) $_messageID = $_GET [ '_messageID' ];
if ( ! $_partID && ! empty ( $_GET [ '_partID' ])) $_partID = $_GET [ '_partID' ];
if ( ! $_htmloptions && ! empty ( $_GET [ '_htmloptions' ])) $_htmloptions = $_GET [ '_htmloptions' ];
2014-07-16 18:34:15 +02:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . " -> " . print_r ( $_messageID , true ) . " , $_partID , $_htmloptions " );
2013-04-30 16:16:52 +02:00
if ( empty ( $_messageID )) return " " ;
2013-04-12 15:10:27 +02:00
$uidA = self :: splitRowID ( $_messageID );
$folder = $uidA [ 'folder' ]; // all messages in one set are supposed to be within the same folder
$messageID = $uidA [ 'msgUID' ];
2014-03-03 15:56:12 +01:00
$bodyResponse = $this -> get_load_email_data ( $messageID , $_partID , $folder , $_htmloptions );
2014-01-18 15:52:47 +01:00
egw_session :: cache_control ( true );
2013-04-12 15:10:27 +02:00
//error_log(array2string($bodyResponse));
echo $bodyResponse ;
}
2013-02-19 17:30:59 +01:00
/**
2013-04-12 11:22:23 +02:00
* ajax_setFolderStatus - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
2013-02-19 17:30:59 +01:00
* gets the counters and sets the text of a treenode if needed ( unread Messages found )
2013-04-12 11:22:23 +02:00
* @ param array $_folder folders to refresh its unseen message counters
2013-02-19 17:30:59 +01:00
* @ return nothing
*/
function ajax_setFolderStatus ( $_folder )
{
2014-01-27 13:18:16 +01:00
translation :: add_app ( 'mail' );
2013-04-09 18:00:12 +02:00
//error_log(__METHOD__.__LINE__.array2string($_folder));
2013-02-19 17:30:59 +01:00
if ( $_folder )
{
2014-07-16 18:34:15 +02:00
$this -> mail_bo -> getHierarchyDelimiter ( false );
2013-02-19 17:30:59 +01:00
$oA = array ();
foreach ( $_folder as $_folderName )
{
2013-02-20 17:27:10 +01:00
list ( $profileID , $folderName ) = explode ( self :: $delimiter , $_folderName , 2 );
if ( is_numeric ( $profileID ))
2013-02-19 17:30:59 +01:00
{
2013-02-20 17:27:10 +01:00
if ( $profileID != $this -> mail_bo -> profileID ) continue ; // only current connection
2013-02-19 17:30:59 +01:00
if ( $folderName )
{
2014-07-31 12:10:07 +02:00
$fS = $this -> mail_bo -> getFolderStatus ( $folderName , false , false , false );
2014-01-27 13:18:16 +01:00
if ( in_array ( $fS [ 'shortDisplayName' ], mail_bo :: $autoFolders )) $fS [ 'shortDisplayName' ] = lang ( $fS [ 'shortDisplayName' ]);
2013-02-19 17:30:59 +01:00
//error_log(__METHOD__.__LINE__.array2string($fS));
if ( $fS [ 'unseen' ])
{
2014-02-05 13:23:04 +01:00
$oA [ $_folderName ] = $fS [ 'shortDisplayName' ] . ' (' . $fS [ 'unseen' ] . ')' ;
2013-11-04 12:22:38 +01:00
}
2013-11-04 13:31:50 +01:00
if ( $fS [ 'unseen' ] == 0 && $fS [ 'shortDisplayName' ])
2013-11-04 12:22:38 +01:00
{
$oA [ $_folderName ] = $fS [ 'shortDisplayName' ];
2013-02-19 17:30:59 +01:00
}
}
}
}
2013-04-09 18:00:12 +02:00
//error_log(__METHOD__.__LINE__.array2string($oA));
2013-02-19 17:30:59 +01:00
if ( $oA )
{
$response = egw_json_response :: get ();
2014-01-11 15:16:36 +01:00
$response -> call ( 'app.mail.mail_setFolderStatus' , $oA );
2013-02-19 17:30:59 +01:00
}
}
}
2013-05-21 10:46:54 +02:00
/**
* ajax_addFolder - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
* @ param string $_parentFolderName folder to add a folder to
* @ param string $_newName new foldername
* @ return nothing
*/
function ajax_addFolder ( $_parentFolderName , $_newName )
{
2013-05-21 12:57:07 +02:00
//error_log(__METHOD__.__LINE__.' ParentFolderName:'.array2string($_parentFolderName).' NewName/Folder:'.array2string($_newName));
2013-05-21 10:46:54 +02:00
if ( $_parentFolderName )
{
$created = false ;
$decodedFolderName = $this -> mail_bo -> decodeEntityFolderName ( $_parentFolderName );
2013-12-12 14:34:35 +01:00
//the conversion is handeled by horde, frontend interaction is all utf-8
2014-07-16 15:42:36 +02:00
$_newName = $this -> mail_bo -> decodeEntityFolderName ( $_newName );
2013-05-21 10:46:54 +02:00
$del = $this -> mail_bo -> getHierarchyDelimiter ( false );
list ( $profileID , $parentFolderName ) = explode ( self :: $delimiter , $decodedFolderName , 2 );
if ( is_numeric ( $profileID ))
{
if ( $profileID != $this -> mail_bo -> profileID ) return ; // only current connection
2013-05-21 12:57:07 +02:00
$nA = explode ( $del , $_newName );
2013-05-21 10:46:54 +02:00
2014-07-16 15:42:36 +02:00
//error_log(__METHOD__.__LINE__."$folderName, $parentFolder, $_newName");
$oldFolderInfo = $this -> mail_bo -> getFolderStatus ( $parentFolderName , false );
//error_log(__METHOD__.__LINE__.array2string($oldFolderInfo));
$this -> mail_bo -> reopen ( 'INBOX' );
$parentName = $parentFolderName ;
// if newName has delimiter ($del) in it, we need to create the subtree
if ( ! empty ( $nA ))
{
$c = 0 ;
foreach ( $nA as $sTName )
2013-05-21 12:57:07 +02:00
{
2014-07-16 15:42:36 +02:00
if (( $parentFolderName = $this -> mail_bo -> createFolder ( $parentFolderName , $sTName , true )))
2013-05-21 12:57:07 +02:00
{
2014-07-16 15:42:36 +02:00
$c ++ ;
2013-05-21 12:57:07 +02:00
}
2013-05-21 10:46:54 +02:00
}
2014-07-16 15:42:36 +02:00
if ( $c == count ( $nA )) $created = true ;
2013-05-21 10:46:54 +02:00
}
2014-07-16 15:42:36 +02:00
$this -> mail_bo -> reopen ( $parentName );
2013-05-21 10:46:54 +02:00
}
//error_log(__METHOD__.__LINE__.array2string($oA));
if ( $created === true )
{
2013-05-21 12:57:07 +02:00
$this -> mail_bo -> resetFolderObjectCache ( $profileID );
2013-05-21 10:46:54 +02:00
$response = egw_json_response :: get ();
2014-01-13 14:06:29 +01:00
$response -> call ( 'app.mail.mail_reloadNode' , array ( $_parentFolderName => $oldFolderInfo [ 'shortDisplayName' ]));
2013-05-21 10:46:54 +02:00
}
}
}
2013-04-12 11:22:23 +02:00
/**
* ajax_renameFolder - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
* @ param string $_folderName folder to rename and refresh
* @ param string $_newName new foldername
* @ return nothing
*/
function ajax_renameFolder ( $_folderName , $_newName )
{
2013-12-12 16:44:47 +01:00
//error_log(__METHOD__.__LINE__.' OldFolderName:'.array2string($_folderName).' NewName:'.array2string($_newName));
2013-04-12 11:22:23 +02:00
if ( $_folderName )
{
2014-01-27 13:18:16 +01:00
translation :: add_app ( 'mail' );
2013-04-29 16:56:33 +02:00
$decodedFolderName = $this -> mail_bo -> decodeEntityFolderName ( $_folderName );
2013-12-12 16:10:25 +01:00
$_newName = $this -> mail_bo -> decodeEntityFolderName ( $_newName );
2013-04-12 11:22:23 +02:00
$del = $this -> mail_bo -> getHierarchyDelimiter ( false );
$oA = array ();
2013-04-29 16:56:33 +02:00
list ( $profileID , $folderName ) = explode ( self :: $delimiter , $decodedFolderName , 2 );
2013-05-10 09:24:27 +02:00
$hasChildren = false ;
2013-04-12 11:22:23 +02:00
if ( is_numeric ( $profileID ))
{
if ( $profileID != $this -> mail_bo -> profileID ) return ; // only current connection
$pA = explode ( $del , $folderName );
array_pop ( $pA );
$parentFolder = implode ( $del , $pA );
if ( strtoupper ( $folderName ) != 'INBOX' )
{
//error_log(__METHOD__.__LINE__."$folderName, $parentFolder, $_newName");
2013-05-07 10:26:17 +02:00
$oldFolderInfo = $this -> mail_bo -> getFolderStatus ( $folderName , false );
2013-05-10 09:24:27 +02:00
//error_log(__METHOD__.__LINE__.array2string($oldFolderInfo));
if ( ! empty ( $oldFolderInfo [ 'attributes' ]) && stripos ( array2string ( $oldFolderInfo [ 'attributes' ]), '\hasnochildren' ) === false )
{
$hasChildren = true ; // translates to: hasChildren -> dynamicLoading
$delimiter = $this -> mail_bo -> getHierarchyDelimiter ();
$nameSpace = $this -> mail_bo -> _getNameSpaces ();
$prefix = $this -> mail_bo -> getFolderPrefixFromNamespace ( $nameSpace , $folderName );
//error_log(__METHOD__.__LINE__.'->'."$_folderName, $delimiter, $prefix");
$fragments = array ();
$subFolders = $this -> mail_bo -> getMailBoxesRecursive ( $folderName , $delimiter , $prefix );
foreach ( $subFolders as $k => $folder )
{
// we do not monitor failure or success on subfolders
if ( $folder == $folderName )
{
unset ( $subFolders [ $k ]);
}
else
{
$rv = $this -> mail_bo -> subscribe ( $folder , false );
$fragments [ $profileID . self :: $delimiter . $folder ] = substr ( $folder , strlen ( $folderName ));
}
}
//error_log(__METHOD__.__LINE__.' Fetched Subfolders->'.array2string($fragments));
}
2013-04-29 16:56:33 +02:00
$this -> mail_bo -> reopen ( 'INBOX' );
2013-12-12 16:10:25 +01:00
$success = false ;
try
{
2014-05-22 09:47:49 +02:00
if (( $newFolderName = $this -> mail_bo -> renameFolder ( $folderName , $parentFolder , $_newName )))
{
2013-12-12 16:10:25 +01:00
$this -> mail_bo -> resetFolderObjectCache ( $profileID );
//enforce the subscription to the newly named server, as it seems to fail for names with umlauts
$rv = $this -> mail_bo -> subscribe ( $newFolderName , true );
$rv = $this -> mail_bo -> subscribe ( $folderName , false );
$success = true ;
}
}
catch ( Exception $e )
{
$newFolderName = $folderName ;
$msg = $e -> getMessage ();
2013-04-12 11:22:23 +02:00
}
2013-04-29 16:56:33 +02:00
$this -> mail_bo -> reopen ( $newFolderName );
2013-04-12 11:22:23 +02:00
$fS = $this -> mail_bo -> getFolderStatus ( $newFolderName , false );
//error_log(__METHOD__.__LINE__.array2string($fS));
2013-05-10 09:24:27 +02:00
if ( $hasChildren )
{
$subFolders = $this -> mail_bo -> getMailBoxesRecursive ( $newFolderName , $delimiter , $prefix );
foreach ( $subFolders as $k => $folder )
{
// we do not monitor failure or success on subfolders
if ( $folder == $folderName )
{
unset ( $subFolders [ $k ]);
}
else
{
$rv = $this -> mail_bo -> subscribe ( $folder , true );
}
}
//error_log(__METHOD__.__LINE__.' Fetched Subfolders->'.array2string($subFolders));
}
2013-04-29 16:56:33 +02:00
$oA [ $_folderName ][ 'id' ] = $profileID . self :: $delimiter . $newFolderName ;
2013-05-07 10:26:17 +02:00
$oA [ $_folderName ][ 'olddesc' ] = $oldFolderInfo [ 'shortDisplayName' ];
2013-04-12 11:22:23 +02:00
if ( $fS [ 'unseen' ])
{
2014-02-05 13:23:04 +01:00
$oA [ $_folderName ][ 'desc' ] = $fS [ 'shortDisplayName' ] . ' (' . $fS [ 'unseen' ] . ')' ;
2013-04-12 11:22:23 +02:00
}
2013-04-29 16:56:33 +02:00
else
{
$oA [ $_folderName ][ 'desc' ] = $fS [ 'shortDisplayName' ];
}
2013-05-10 09:24:27 +02:00
foreach ( $fragments as $oldFolderName => $fragment )
{
//error_log(__METHOD__.__LINE__.':'.$oldFolderName.'->'.$profileID.self::$delimiter.$newFolderName.$fragment);
$oA [ $oldFolderName ][ 'id' ] = $profileID . self :: $delimiter . $newFolderName . $fragment ;
$oA [ $oldFolderName ][ 'olddesc' ] = '#skip-user-interaction-message#' ;
$fS = $this -> mail_bo -> getFolderStatus ( $newFolderName . $fragment , false );
if ( $fS [ 'unseen' ])
{
2014-02-05 13:23:04 +01:00
$oA [ $oldFolderName ][ 'desc' ] = $fS [ 'shortDisplayName' ] . ' (' . $fS [ 'unseen' ] . ')' ;
2013-05-10 09:24:27 +02:00
}
else
{
$oA [ $oldFolderName ][ 'desc' ] = $fS [ 'shortDisplayName' ];
}
}
2013-04-12 11:22:23 +02:00
}
}
2013-12-03 15:38:50 +01:00
if ( $folderName == $this -> mail_bo -> sessionData [ 'mailbox' ])
{
$this -> mail_bo -> sessionData [ 'mailbox' ] = $newFolderName ;
$this -> mail_bo -> saveSessionData ();
}
2013-04-12 11:22:23 +02:00
//error_log(__METHOD__.__LINE__.array2string($oA));
2014-01-06 10:51:24 +01:00
$response = egw_json_response :: get ();
2013-12-12 16:10:25 +01:00
if ( $oA && $success )
2013-04-12 11:22:23 +02:00
{
2014-01-13 14:06:29 +01:00
$response -> call ( 'app.mail.mail_setLeaf' , $oA );
2013-04-12 11:22:23 +02:00
}
2013-12-12 16:10:25 +01:00
else
{
2014-05-27 15:31:37 +02:00
$response -> call ( 'egw.refresh' , lang ( 'failed to rename %1 ! Reason: %2' , $oldFolderName , $msg ), 'mail' );
2013-12-12 16:10:25 +01:00
}
2013-04-12 11:22:23 +02:00
}
}
2014-02-06 10:09:57 +01:00
/**
* reload node
*
* @ param string _folderName folder to reload
2014-07-16 15:42:36 +02:00
* @ param boolean $_subscribedOnly = true
2014-02-06 10:09:57 +01:00
* @ return void
*/
function ajax_reloadNode ( $_folderName , $_subscribedOnly = true )
{
translation :: add_app ( 'mail' );
2014-02-07 09:33:23 +01:00
$oldPrefForSubscribedOnly = ! $this -> mail_bo -> mailPreferences [ 'showAllFoldersInFolderPane' ];
2014-07-16 15:42:36 +02:00
2014-02-07 09:33:23 +01:00
// prefs are plain prefs; we discussed an approach to have user only prefs, and
// set them on rightclick action on foldertree
//error_log(__METHOD__.__LINE__.' showAllFoldersInFolderPane:'.$this->mail_bo->mailPreferences['showAllFoldersInFolderPane'].'/'.$GLOBALS['egw_info']['user']['preferences']['mail']['showAllFoldersInFolderPane']);
2014-02-06 10:09:57 +01:00
$decodedFolderName = $this -> mail_bo -> decodeEntityFolderName ( $_folderName );
2014-07-16 18:34:15 +02:00
$this -> mail_bo -> getHierarchyDelimiter ( false );
2014-02-06 10:09:57 +01:00
list ( $profileID , $folderName ) = explode ( self :: $delimiter , $decodedFolderName , 2 );
2014-02-07 09:33:23 +01:00
// if pref and required mode dont match -> reset the folderObject cache to ensure
// that we get what we request
if ( $_subscribedOnly != $oldPrefForSubscribedOnly ) $this -> mail_bo -> resetFolderObjectCache ( $profileID );
2014-02-06 10:09:57 +01:00
if ( $profileID != $this -> mail_bo -> profileID ) return ; // only current connection
2014-05-20 16:28:23 +02:00
if ( ! empty ( $folderName ))
2014-02-06 10:09:57 +01:00
{
2014-05-20 16:28:23 +02:00
$parentFolder = ( ! empty ( $folderName ) ? $folderName : 'INBOX' );
2014-07-31 12:10:07 +02:00
$folderInfo = $this -> mail_bo -> getFolderStatus ( $parentFolder , false , false , false );
2014-05-20 16:28:23 +02:00
if ( $folderInfo [ 'unseen' ])
{
$folderInfo [ 'shortDisplayName' ] = $folderInfo [ 'shortDisplayName' ] . ' (' . $folderInfo [ 'unseen' ] . ')' ;
}
if ( $folderInfo [ 'unseen' ] == 0 && $folderInfo [ 'shortDisplayName' ])
{
$folderInfo [ 'shortDisplayName' ] = $folderInfo [ 'shortDisplayName' ];
}
$refreshData = array (
$profileID . self :: $delimiter . $parentFolder => $folderInfo [ 'shortDisplayName' ]);
2014-02-06 10:09:57 +01:00
}
2014-05-20 16:28:23 +02:00
else
2014-02-06 10:09:57 +01:00
{
2014-05-20 16:28:23 +02:00
$refreshData = array (
$profileID => lang ( 'INBOX' ) //string with no meaning lateron
);
2014-02-06 10:09:57 +01:00
}
// Send full info back in the response
$response = egw_json_response :: get ();
foreach ( $refreshData as $folder => & $name )
{
$name = $this -> getFolderTree ( true , $folder , $_subscribedOnly );
}
$response -> call ( 'app.mail.mail_reloadNode' , $refreshData );
}
2014-01-06 13:57:53 +01:00
/**
* move folder
*
2014-01-11 12:58:31 +01:00
* @ param string _folderName folder to vove
* @ param string _target target folder
2014-01-06 13:57:53 +01:00
*
2014-01-11 12:58:31 +01:00
* @ return void
2014-01-06 13:57:53 +01:00
*/
function ajax_MoveFolder ( $_folderName , $_target )
{
2014-01-06 15:26:33 +01:00
//error_log(__METHOD__.__LINE__."Move Folder: $_folderName to Target: $_target");
2014-01-06 13:57:53 +01:00
if ( $_folderName )
{
$decodedFolderName = $this -> mail_bo -> decodeEntityFolderName ( $_folderName );
$_newLocation = $this -> mail_bo -> decodeEntityFolderName ( $_target );
$del = $this -> mail_bo -> getHierarchyDelimiter ( false );
list ( $profileID , $folderName ) = explode ( self :: $delimiter , $decodedFolderName , 2 );
2014-01-11 12:58:31 +01:00
list ( $newProfileID , $_newLocation ) = explode ( self :: $delimiter , $_newLocation , 2 );
2014-01-06 13:57:53 +01:00
$hasChildren = false ;
if ( is_numeric ( $profileID ))
{
2014-01-11 12:58:31 +01:00
if ( $profileID != $this -> mail_bo -> profileID || $profileID != $newProfileID ) return ; // only current connection
2014-01-06 13:57:53 +01:00
$pA = explode ( $del , $folderName );
$namePart = array_pop ( $pA );
$_newName = $namePart ;
2014-01-06 15:26:33 +01:00
$oldParentFolder = implode ( $del , $pA );
2014-01-06 13:57:53 +01:00
$parentFolder = $_newLocation ;
2014-07-16 15:42:36 +02:00
2014-01-10 14:07:01 +01:00
if ( strtoupper ( $folderName ) != 'INBOX' &&
(( $oldParentFolder === $parentFolder ) || //$oldParentFolder == $parentFolder means move on same level
(( $oldParentFolder != $parentFolder &&
strlen ( $parentFolder ) > 0 && strlen ( $folderName ) > 0 &&
strpos ( $parentFolder , $folderName ) === false )))) // indicates that we move the older up the tree within its own branch
2014-01-06 13:57:53 +01:00
{
//error_log(__METHOD__.__LINE__."$folderName, $parentFolder, $_newName");
2014-07-31 12:10:07 +02:00
$oldFolderInfo = $this -> mail_bo -> getFolderStatus ( $folderName , false , false , false );
2014-01-06 13:57:53 +01:00
//error_log(__METHOD__.__LINE__.array2string($oldFolderInfo));
if ( ! empty ( $oldFolderInfo [ 'attributes' ]) && stripos ( array2string ( $oldFolderInfo [ 'attributes' ]), '\hasnochildren' ) === false )
{
$hasChildren = true ; // translates to: hasChildren -> dynamicLoading
$delimiter = $this -> mail_bo -> getHierarchyDelimiter ();
$nameSpace = $this -> mail_bo -> _getNameSpaces ();
$prefix = $this -> mail_bo -> getFolderPrefixFromNamespace ( $nameSpace , $folderName );
//error_log(__METHOD__.__LINE__.'->'."$_folderName, $delimiter, $prefix");
2014-07-16 18:34:15 +02:00
2014-01-06 13:57:53 +01:00
$subFolders = $this -> mail_bo -> getMailBoxesRecursive ( $folderName , $delimiter , $prefix );
foreach ( $subFolders as $k => $folder )
{
// we do not monitor failure or success on subfolders
if ( $folder == $folderName )
{
unset ( $subFolders [ $k ]);
}
else
{
$rv = $this -> mail_bo -> subscribe ( $folder , false );
}
}
}
$this -> mail_bo -> reopen ( 'INBOX' );
$success = false ;
try
{
2014-05-22 09:47:49 +02:00
if (( $newFolderName = $this -> mail_bo -> renameFolder ( $folderName , $parentFolder , $_newName )))
{
2014-01-06 13:57:53 +01:00
$this -> mail_bo -> resetFolderObjectCache ( $profileID );
//enforce the subscription to the newly named server, as it seems to fail for names with umlauts
$rv = $this -> mail_bo -> subscribe ( $newFolderName , true );
$rv = $this -> mail_bo -> subscribe ( $folderName , false );
2014-01-06 16:47:19 +01:00
$this -> mail_bo -> resetFolderObjectCache ( $profileID );
2014-01-06 13:57:53 +01:00
$success = true ;
}
}
catch ( Exception $e )
{
$newFolderName = $folderName ;
$msg = $e -> getMessage ();
}
2014-01-06 15:26:33 +01:00
$this -> mail_bo -> reopen ( $parentFolder );
2014-07-31 12:10:07 +02:00
$this -> mail_bo -> getFolderStatus ( $parentFolder , false , false , false );
2014-01-06 13:57:53 +01:00
//error_log(__METHOD__.__LINE__.array2string($fS));
if ( $hasChildren )
{
2014-01-06 15:26:33 +01:00
$subFolders = $this -> mail_bo -> getMailBoxesRecursive ( $parentFolder , $delimiter , $prefix );
2014-01-06 13:57:53 +01:00
foreach ( $subFolders as $k => $folder )
{
// we do not monitor failure or success on subfolders
if ( $folder == $folderName )
{
unset ( $subFolders [ $k ]);
}
else
{
$rv = $this -> mail_bo -> subscribe ( $folder , true );
}
}
//error_log(__METHOD__.__LINE__.' Fetched Subfolders->'.array2string($subFolders));
}
}
}
if ( $folderName == $this -> mail_bo -> sessionData [ 'mailbox' ])
{
$this -> mail_bo -> sessionData [ 'mailbox' ] = $newFolderName ;
$this -> mail_bo -> saveSessionData ();
}
//error_log(__METHOD__.__LINE__.array2string($oA));
$response = egw_json_response :: get ();
2014-01-06 16:47:19 +01:00
if ( $success )
2014-01-06 13:57:53 +01:00
{
2014-01-27 13:18:16 +01:00
translation :: add_app ( 'mail' );
2014-07-31 12:10:07 +02:00
$oldFolderInfo = $this -> mail_bo -> getFolderStatus ( $oldParentFolder , false , false , false );
$folderInfo = $this -> mail_bo -> getFolderStatus ( $parentFolder , false , false , false );
2014-01-06 16:47:19 +01:00
$refreshData = array (
2014-01-06 15:26:33 +01:00
$profileID . self :: $delimiter . $oldParentFolder => $oldFolderInfo [ 'shortDisplayName' ],
2014-01-06 16:47:19 +01:00
$profileID . self :: $delimiter . $parentFolder => $folderInfo [ 'shortDisplayName' ]);
// if we move the folder within the same parent-branch of the tree, there is no need no refresh the upper part
2014-01-09 09:36:22 +01:00
if ( strlen ( $parentFolder ) > strlen ( $oldParentFolder ) && strpos ( $parentFolder , $oldParentFolder ) !== false ) unset ( $refreshData [ $profileID . self :: $delimiter . $parentFolder ]);
if ( count ( $refreshData ) > 1 && strlen ( $oldParentFolder ) > strlen ( $parentFolder ) && strpos ( $oldParentFolder , $parentFolder ) !== false ) unset ( $refreshData [ $profileID . self :: $delimiter . $oldParentFolder ]);
2014-01-18 15:52:47 +01:00
2014-01-11 12:58:31 +01:00
// Send full info back in the response
foreach ( $refreshData as $folder => & $name )
{
2014-02-07 09:33:23 +01:00
$name = $this -> getFolderTree ( true , $folder , ! $this -> mail_bo -> mailPreferences [ 'showAllFoldersInFolderPane' ]);
2014-01-11 12:58:31 +01:00
}
$response -> call ( 'app.mail.mail_reloadNode' , $refreshData );
2014-01-06 15:26:33 +01:00
2014-01-06 13:57:53 +01:00
}
else
{
2014-05-27 15:31:37 +02:00
$response -> call ( 'egw.refresh' , lang ( 'failed to move %1 ! Reason: %2' , $folderName , $msg ), 'mail' );
2014-01-06 13:57:53 +01:00
}
}
}
2013-05-13 16:42:42 +02:00
/**
* ajax_deleteFolder - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
* @ param string $_folderName folder to delete
* @ return nothing
*/
function ajax_deleteFolder ( $_folderName )
{
2013-05-21 10:46:54 +02:00
//error_log(__METHOD__.__LINE__.' OldFolderName:'.array2string($_folderName));
2013-05-13 16:42:42 +02:00
$success = false ;
if ( $_folderName )
{
$decodedFolderName = $this -> mail_bo -> decodeEntityFolderName ( $_folderName );
$del = $this -> mail_bo -> getHierarchyDelimiter ( false );
$oA = array ();
list ( $profileID , $folderName ) = explode ( self :: $delimiter , $decodedFolderName , 2 );
$hasChildren = false ;
if ( is_numeric ( $profileID ))
{
if ( $profileID != $this -> mail_bo -> profileID ) return ; // only current connection
$pA = explode ( $del , $folderName );
array_pop ( $pA );
if ( strtoupper ( $folderName ) != 'INBOX' )
{
2014-07-16 18:34:15 +02:00
//error_log(__METHOD__.__LINE__."$folderName, implode($del,$pA), $_newName");
2013-05-13 16:42:42 +02:00
$oA = array ();
2013-12-12 14:34:35 +01:00
$subFolders = array ();
2014-07-31 12:10:07 +02:00
$oldFolderInfo = $this -> mail_bo -> getFolderStatus ( $folderName , false , false , false );
2013-05-13 16:42:42 +02:00
//error_log(__METHOD__.__LINE__.array2string($oldFolderInfo));
if ( ! empty ( $oldFolderInfo [ 'attributes' ]) && stripos ( array2string ( $oldFolderInfo [ 'attributes' ]), '\hasnochildren' ) === false )
{
$hasChildren = true ; // translates to: hasChildren -> dynamicLoading
2014-07-16 18:34:15 +02:00
$ftD = array ();
2013-12-12 14:34:35 +01:00
$delimiter = $this -> mail_bo -> getHierarchyDelimiter ();
$nameSpace = $this -> mail_bo -> _getNameSpaces ();
$prefix = $this -> mail_bo -> getFolderPrefixFromNamespace ( $nameSpace , $folderName );
//error_log(__METHOD__.__LINE__.'->'."$_folderName, $delimiter, $prefix");
$subFolders = $this -> mail_bo -> getMailBoxesRecursive ( $folderName , $delimiter , $prefix );
//error_log(__METHOD__.__LINE__.'->'."$folderName, $delimiter, $prefix");
foreach ( $subFolders as $k => $f )
{
$ftD [ substr_count ( $f , $delimiter )][] = $f ;
}
krsort ( $ftD , SORT_NUMERIC ); //sort per level
//we iterate per level of depth of the subtree, deepest nesting is to be deleted first, and then up the tree
foreach ( $ftD as $k => $lc ) //collection per level
{
foreach ( $lc as $i => $f ) //folders contained in that level
{
try
{
//error_log(__METHOD__.__LINE__.array2string($f).'<->'.$folderName);
$this -> mail_bo -> deleteFolder ( $f );
$success = true ;
if ( $f == $folderName ) $oA [ $_folderName ] = $oldFolderInfo [ 'shortDisplayName' ];
}
catch ( Exception $e )
{
$msg .= ( $msg ? ' ' : '' ) . lang ( " Failed to delete %1. Server responded: " , $f ) . $e -> getMessage ();
$success = false ;
}
}
}
2013-05-13 16:42:42 +02:00
}
else
{
2013-12-12 14:34:35 +01:00
try
2013-05-13 16:42:42 +02:00
{
2013-12-12 14:34:35 +01:00
$this -> mail_bo -> deleteFolder ( $folderName );
$success = true ;
$oA [ $_folderName ] = $oldFolderInfo [ 'shortDisplayName' ];
2013-05-13 16:42:42 +02:00
}
2013-12-12 14:34:35 +01:00
catch ( Exception $e )
2013-05-13 16:42:42 +02:00
{
2013-12-12 14:34:35 +01:00
$msg = $e -> getMessage ();
$success = false ;
2013-05-13 16:42:42 +02:00
}
}
}
else
{
$msg = lang ( " refused to delete folder INBOX " );
}
}
$response = egw_json_response :: get ();
if ( $success )
{
2014-07-16 18:34:15 +02:00
$folders2return = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'folderObjects' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), $expiration = 60 * 60 * 1 );
2013-12-12 14:34:35 +01:00
if ( isset ( $folders2return [ $this -> mail_bo -> profileID ]))
{
//error_log(__METHOD__.__LINE__.array2string($folders2return[$this->mail_bo->profileID]));
if ( empty ( $subFolders )) $subFolders = array ( $folderName );
//error_log(__METHOD__.__LINE__.array2string($subFolders));
foreach ( $subFolders as $i => $f )
{
//error_log(__METHOD__.__LINE__.$f.'->'.array2string($folders2return[$this->mail_bo->profileID][$f]));
if ( isset ( $folders2return [ $this -> mail_bo -> profileID ][ $f ])) unset ( $folders2return [ $this -> mail_bo -> profileID ][ $f ]);
}
}
egw_cache :: setCache ( egw_cache :: INSTANCE , 'email' , 'folderObjects' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), $folders2return , $expiration = 60 * 60 * 1 );
2013-05-21 10:46:54 +02:00
//error_log(__METHOD__.__LINE__.array2string($oA));
2014-01-13 14:06:29 +01:00
$response -> call ( 'app.mail.mail_removeLeaf' , $oA );
2013-05-13 16:42:42 +02:00
}
else
{
2014-05-27 15:31:37 +02:00
$response -> call ( 'egw.refresh' , lang ( 'failed to delete %1 ! Reason: %2' , $oldFolderInfo [ 'shortDisplayName' ], $msg ), 'mail' );
2013-05-13 16:42:42 +02:00
}
}
}
2013-02-20 12:31:57 +01:00
/**
* empty changeProfile - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
*
2014-05-22 09:47:49 +02:00
* @ param int $icServerID New profile / server ID
2014-01-22 10:32:18 +01:00
* @ param bool $getFolders The client needs the folders for the profile
2013-02-20 12:31:57 +01:00
* @ return nothing
*/
2014-01-22 10:32:18 +01:00
function ajax_changeProfile ( $icServerID , $getFolders = true )
2013-02-20 12:31:57 +01:00
{
2014-06-30 17:48:49 +02:00
$response = egw_json_response :: get ();
2014-07-08 13:09:31 +02:00
2013-02-20 17:27:10 +01:00
if ( $icServerID && $icServerID != $this -> mail_bo -> profileID )
2013-10-18 11:58:25 +02:00
{
2014-06-30 17:48:49 +02:00
try
{
$this -> changeProfile ( $icServerID );
}
catch ( Exception $e ) {
self :: callWizard ( $e -> getMessage (), true );
}
2014-07-08 13:09:31 +02:00
2013-10-18 11:58:25 +02:00
}
2014-07-08 13:09:31 +02:00
2014-01-22 10:32:18 +01:00
// Send full info back in the response
if ( $getFolders )
{
2014-01-27 13:18:16 +01:00
translation :: add_app ( 'mail' );
2014-01-22 10:32:18 +01:00
$refreshData = array (
2014-07-16 18:34:15 +02:00
$icServerID => $this -> getFolderTree ( true , $icServerID , ! $this -> mail_bo -> mailPreferences [ 'showAllFoldersInFolderPane' ], true )
2014-01-22 10:32:18 +01:00
);
$response -> call ( 'app.mail.mail_reloadNode' , $refreshData );
}
2013-02-20 12:31:57 +01:00
}
2014-04-03 14:20:23 +02:00
/**
* ajax_refreshVacationNotice - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
* Note : only the activeProfile VacationNotice is refreshed
2014-05-22 09:47:49 +02:00
* @ param int $icServerID profileId / server ID to work on ; may be empty -> then activeProfile is used
2014-04-03 14:20:23 +02:00
* if other than active profile ; nothing is done !
* @ return nothing
*/
2014-05-22 09:47:49 +02:00
function ajax_refreshVacationNotice ( $icServerID = null )
2014-04-03 14:20:23 +02:00
{
//error_log(__METHOD__.__LINE__.array2string($icServerId));
if ( empty ( $icServerID )) $icServerID = $this -> mail_bo -> profileID ;
if ( $icServerID != $this -> mail_bo -> profileID ) return ;
$vacation = $this -> gatherVacation ();
//error_log(__METHOD__.__LINE__.array2string($vacation));
if ( $vacation ) {
if ( is_array ( $vacation ) && ( $vacation [ 'status' ] == 'on' || $vacation [ 'status' ] == 'by_date' ))
{
2014-07-16 15:42:36 +02:00
$dtfrmt = $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'common' ][ 'dateformat' ];
2014-04-03 14:20:23 +02:00
$refreshData [ 'vacationnotice' ] = lang ( 'Vacation notice is active' );
$refreshData [ 'vacationrange' ] = ( $vacation [ 'status' ] == 'by_date' ? common :: show_date ( $vacation [ 'start_date' ], $dtfrmt , true ) . ( $vacation [ 'end_date' ] > $vacation [ 'start_date' ] ? '->' . common :: show_date ( $vacation [ 'end_date' ] + 24 * 3600 - 1 , $dtfrmt , true ) : '' ) : '' );
}
}
if ( $vacation == false )
{
$refreshData [ 'vacationnotice' ] = '' ;
$refreshData [ 'vacationrange' ] = '' ;
}
$response = egw_json_response :: get ();
$response -> call ( 'app.mail.mail_refreshVacationNotice' , $refreshData );
}
2014-04-11 15:52:58 +02:00
/**
* ajax_refreshFilters - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
* Note : only the activeProfile Filters are refreshed
2014-05-22 09:47:49 +02:00
* @ param int $icServerID profileId / server ID to work on ; may be empty -> then activeProfile is used
2014-04-11 15:52:58 +02:00
* if other than active profile ; nothing is done !
* @ return nothing
*/
2014-05-22 09:47:49 +02:00
function ajax_refreshFilters ( $icServerID = null )
2014-04-11 15:52:58 +02:00
{
//error_log(__METHOD__.__LINE__.array2string($icServerId));
if ( empty ( $icServerID )) $icServerID = $this -> mail_bo -> profileID ;
if ( is_null ( emailadmin_imapbase :: $supportsORinQuery ) || ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ]))
{
2014-05-22 09:47:49 +02:00
emailadmin_imapbase :: $supportsORinQuery = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'supportsORinQuery' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), 60 * 60 * 10 );
2014-04-11 15:52:58 +02:00
if ( ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ])) emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] = true ;
}
if ( ! emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ])
{
unset ( $this -> searchTypes [ 'quick' ]);
}
if ( $this -> mail_bo -> icServer -> hasCapability ( 'SUPPORTS_KEYWORDS' ))
{
$this -> statusTypes = array_merge ( $this -> statusTypes , array (
'keyword1' => 'important' , //lang('important'),
'keyword2' => 'job' , //lang('job'),
'keyword3' => 'personal' , //lang('personal'),
'keyword4' => 'to do' , //lang('to do'),
'keyword5' => 'later' , //lang('later'),
));
}
else
{
2014-07-16 18:34:15 +02:00
$keywords = array ( 'keyword1' , 'keyword2' , 'keyword3' , 'keyword4' , 'keyword5' );
foreach ( $keywords as & $k )
2014-04-11 15:52:58 +02:00
{
if ( array_key_exists ( $k , $this -> statusTypes )) unset ( $this -> statusTypes [ $k ]);
}
}
$response = egw_json_response :: get ();
$response -> call ( 'app.mail.mail_refreshFilter2Options' , $this -> searchTypes );
$response -> call ( 'app.mail.mail_refreshFilterOptions' , $this -> statusTypes );
}
2013-10-18 11:58:25 +02:00
/**
* ajax_refreshQuotaDisplay - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
*
* @ return nothing
*/
function ajax_refreshQuotaDisplay ( $icServerID = null )
{
//error_log(__METHOD__.__LINE__.array2string($icServerID));
2014-01-27 13:18:16 +01:00
translation :: add_app ( 'mail' );
2013-10-18 11:58:25 +02:00
if ( is_null ( $icServerID )) $icServerID = $this -> mail_bo -> profileID ;
2014-01-17 10:59:25 +01:00
$rememberServerID = $this -> mail_bo -> profileID ;
2013-10-18 11:58:25 +02:00
if ( $icServerID && $icServerID != $this -> mail_bo -> profileID )
{
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
$this -> changeProfile ( $icServerID );
}
2014-07-31 12:42:56 +02:00
try
{
2013-10-18 11:58:25 +02:00
$quota = $this -> mail_bo -> getQuotaRoot ();
2014-07-31 12:42:56 +02:00
} catch ( Exception $e ) {
2013-10-18 11:58:25 +02:00
$quota [ 'limit' ] = 'NOT SET' ;
}
if ( $quota !== false && $quota [ 'limit' ] != 'NOT SET' ) {
$quotainfo = $this -> quotaDisplay ( $quota [ 'usage' ], $quota [ 'limit' ]);
$content [ 'quota' ] = $sel_options [ self :: $nm_index ][ 'quota' ] = $quotainfo [ 'text' ];
$content [ 'quotainpercent' ] = $sel_options [ self :: $nm_index ][ 'quotainpercent' ] = ( string ) $quotainfo [ 'percent' ];
$content [ 'quotaclass' ] = $sel_options [ self :: $nm_index ][ 'quotaclass' ] = $quotainfo [ 'class' ];
$content [ 'quotanotsupported' ] = $sel_options [ self :: $nm_index ][ 'quotanotsupported' ] = " " ;
} else {
$content [ 'quota' ] = $sel_options [ self :: $nm_index ][ 'quota' ] = lang ( " Quota not provided by server " );
$content [ 'quotaclass' ] = $sel_options [ self :: $nm_index ][ 'quotaclass' ] = " mail_DisplayNone " ;
$content [ 'quotanotsupported' ] = $sel_options [ self :: $nm_index ][ 'quotanotsupported' ] = " mail_DisplayNone " ;
}
2014-01-17 10:59:25 +01:00
if ( $rememberServerID != $this -> mail_bo -> profileID )
{
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$rememberServerID);
$this -> changeProfile ( $rememberServerID );
}
2013-10-18 11:58:25 +02:00
$response = egw_json_response :: get ();
2014-01-13 14:06:29 +01:00
$response -> call ( 'app.mail.mail_setQuotaDisplay' , array ( 'data' => $content ));
2013-10-18 11:58:25 +02:00
}
2013-02-12 18:48:04 +01:00
/**
* empty trash folder - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
*
2014-01-17 10:59:25 +01:00
* @ param string $icServerID id of the server to empty its trashFolder
2013-02-12 18:48:04 +01:00
* @ return nothing
*/
2014-01-17 10:59:25 +01:00
function ajax_emptyTrash ( $icServerID )
2013-02-12 18:48:04 +01:00
{
2014-01-27 13:18:16 +01:00
//error_log(__METHOD__.__LINE__.' '.$icServerID);
translation :: add_app ( 'mail' );
2014-01-17 10:59:25 +01:00
$rememberServerID = $this -> mail_bo -> profileID ;
if ( $icServerID && $icServerID != $this -> mail_bo -> profileID )
{
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
$this -> changeProfile ( $icServerID );
}
2013-02-12 18:48:04 +01:00
$trashFolder = $this -> mail_bo -> getTrashFolder ();
if ( ! empty ( $trashFolder )) {
$this -> mail_bo -> compressFolder ( $trashFolder );
}
2014-01-17 10:59:25 +01:00
if ( $rememberServerID != $this -> mail_bo -> profileID )
{
2014-07-31 12:10:07 +02:00
$oldFolderInfo = $this -> mail_bo -> getFolderStatus ( $trashFolder , false , false , false );
2014-01-17 10:59:25 +01:00
$response = egw_json_response :: get ();
2014-05-27 15:31:37 +02:00
$response -> call ( 'egw.message' , lang ( 'empty trash' ));
2014-01-17 10:59:25 +01:00
$response -> call ( 'app.mail.mail_reloadNode' , array ( $icServerID . self :: $delimiter . $trashFolder => $oldFolderInfo [ 'shortDisplayName' ]));
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$rememberServerID);
$this -> changeProfile ( $rememberServerID );
}
else
{
$response = egw_json_response :: get ();
2014-05-27 15:31:37 +02:00
$response -> call ( 'egw.refresh' , lang ( 'empty trash' ), 'mail' );
2014-01-17 10:59:25 +01:00
}
2013-02-12 18:48:04 +01:00
}
2013-02-13 16:35:12 +01:00
/**
* compress folder - its called via json , so the function must start with ajax ( or the class - name must contain ajax )
* fetches the current folder from session and compresses it
2014-01-17 10:59:25 +01:00
* @ param string $_folderName id of the folder to compress
2013-02-13 16:35:12 +01:00
* @ return nothing
*/
2014-01-17 10:59:25 +01:00
function ajax_compressFolder ( $_folderName )
2013-02-13 16:35:12 +01:00
{
2014-01-27 13:18:16 +01:00
//error_log(__METHOD__.__LINE__.' '.$_folderName);
translation :: add_app ( 'mail' );
2013-02-13 16:35:12 +01:00
$this -> mail_bo -> restoreSessionData ();
2014-01-17 10:59:25 +01:00
$decodedFolderName = $this -> mail_bo -> decodeEntityFolderName ( $_folderName );
list ( $icServerID , $folderName ) = explode ( self :: $delimiter , $decodedFolderName , 2 );
if ( empty ( $folderName )) $folderName = $this -> mail_bo -> sessionData [ 'mailbox' ];
if ( $this -> mail_bo -> folderExists ( $folderName ))
2013-02-13 16:35:12 +01:00
{
2014-01-17 10:59:25 +01:00
$rememberServerID = $this -> mail_bo -> profileID ;
if ( $icServerID && $icServerID != $this -> mail_bo -> profileID )
{
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$icServerID);
$this -> changeProfile ( $icServerID );
}
2013-02-13 16:35:12 +01:00
if ( ! empty ( $folder )) {
2014-01-17 10:59:25 +01:00
$this -> mail_bo -> compressFolder ( $folderName );
}
if ( $rememberServerID != $this -> mail_bo -> profileID )
{
//error_log(__METHOD__.__LINE__.' change Profile to ->'.$rememberServerID);
$this -> changeProfile ( $rememberServerID );
2013-02-13 16:35:12 +01:00
}
$response = egw_json_response :: get ();
2014-05-27 15:31:37 +02:00
$response -> call ( 'egw.refresh' , lang ( 'compress folder' ) . ': ' . $folderName , 'mail' );
2013-02-13 16:35:12 +01:00
}
}
2014-03-25 17:20:28 +01:00
/**
* sendMDN , ...
*
* @ param array _messageList list of UID ' s
*
* @ return nothing
*/
function ajax_sendMDN ( $_messageList )
{
2014-05-22 09:47:49 +02:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . " -> " . array2string ( $_messageList ));
2014-03-25 17:20:28 +01:00
$uidA = self :: splitRowID ( $_messageList [ 'msg' ][ 0 ]);
$folder = $uidA [ 'folder' ]; // all messages in one set are supposed to be within the same folder
$this -> mail_bo -> sendMDN ( $uidA [ 'msgUID' ], $folder );
}
2013-02-19 17:30:59 +01:00
/**
* flag messages as read , unread , flagged , ...
*
* @ param string _flag name of the flag
* @ param array _messageList list of UID ' s
2014-01-21 15:46:00 +01:00
* @ param bool _sendJsonResponse tell fuction to send the JsonResponse
2013-02-19 17:30:59 +01:00
*
* @ return xajax response
*/
2014-01-21 15:46:00 +01:00
function ajax_flagMessages ( $_flag , $_messageList , $_sendJsonResponse = true )
2013-02-19 17:30:59 +01:00
{
2014-01-21 16:00:22 +01:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . " -> " . $_flag . ':' . array2string ( $_messageList ));
2014-05-27 14:05:23 +02:00
$alreadyFlagged = false ;
2014-07-08 10:50:43 +02:00
$flag2check = '' ;
$filter2toggle = $query = array ();
2013-02-19 17:30:59 +01:00
if ( $_messageList == 'all' || ! empty ( $_messageList [ 'msg' ]))
{
2014-05-27 14:05:23 +02:00
if ( isset ( $_messageList [ 'all' ]) && $_messageList [ 'all' ])
2013-02-19 17:30:59 +01:00
{
2014-05-27 14:05:23 +02:00
// we have both messageIds AND allFlag folder information
$uidA = self :: splitRowID ( $_messageList [ 'msg' ][ 0 ]);
$folder = $uidA [ 'folder' ]; // all messages in one set are supposed to be within the same folder
if ( isset ( $_messageList [ 'activeFilters' ]) && $_messageList [ 'activeFilters' ])
{
$query = $_messageList [ 'activeFilters' ];
if ( ! empty ( $query [ 'search' ]) || ! empty ( $query [ 'filter' ]))
{
//([filterName] => Schnellsuche[type] => quick[string] => ebay[status] => any
if ( is_null ( emailadmin_imapbase :: $supportsORinQuery ) || ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ]))
{
emailadmin_imapbase :: $supportsORinQuery = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'supportsORinQuery' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), 60 * 60 * 10 );
if ( ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ])) emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] = true ;
}
$filter = $filter2toggle = array ( 'filterName' => ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] ? lang ( 'quicksearch' ) : lang ( 'subject' )), 'type' => ( $query [ 'filter2' ] ? $query [ 'filter2' ] : ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] ? 'quick' : 'subject' )), 'string' => $query [ 'search' ], 'status' => 'any' );
}
else
{
$filter = $filter2toggle = array ();
}
// flags read,flagged,label1,label2,label3,label4,label5 can be toggled: handle this when all mails in a folder
// should be affected serverside. here.
$messageList = $messageListForToggle = array ();
2014-07-08 10:50:43 +02:00
$flag2check = ( $_flag == 'read' ? 'seen' : $_flag );
if ( in_array ( $_flag , array ( 'read' , 'flagged' , 'label1' , 'label2' , 'label3' , 'label4' , 'label5' )) &&
! ( $flag2check == $query [ 'filter' ] || stripos ( $query [ 'filter' ], $flag2check ) !== false ))
2014-05-27 14:05:23 +02:00
{
$filter2toggle [ 'status' ] = array ( 'un' . $_flag );
2014-07-08 10:50:43 +02:00
if ( $query [ 'filter' ] && $query [ 'filter' ] != 'any' )
2014-05-27 14:05:23 +02:00
{
$filter2toggle [ 'status' ][] = $query [ 'filter' ];
}
2014-07-08 10:50:43 +02:00
$_sRt = $this -> mail_bo -> getSortedList (
2014-05-27 14:05:23 +02:00
$folder ,
$sort = 0 ,
$reverse = 1 ,
$filter2toggle ,
$rByUid = true ,
false
);
2014-07-08 10:50:43 +02:00
$messageListForToggle = $_sRt [ 'match' ] -> ids ;
2014-05-27 14:05:23 +02:00
$filter [ 'status' ] = array ( $_flag );
2014-07-08 10:50:43 +02:00
if ( $query [ 'filter' ] && $query [ 'filter' ] != 'any' )
2014-05-27 14:05:23 +02:00
{
$filter [ 'status' ][] = $query [ 'filter' ];
}
$_sR = $this -> mail_bo -> getSortedList (
$folder ,
$sort = 0 ,
$reverse = 1 ,
$filter ,
$rByUid = true ,
false
);
$messageList = $_sR [ 'match' ] -> ids ;
if ( count ( $messageListForToggle ) > 0 )
{
$flag2set = ( strtolower ( $_flag ));
//error_log(__METHOD__.__LINE__." toggle un$_flag -> $flag2set ".array2string($filter2toggle).array2string($messageListForToggle));
$this -> mail_bo -> flagMessages ( $flag2set , $messageListForToggle , $folder );
}
if ( count ( $messageList ) > 0 )
{
$flag2set = 'un' . $_flag ;
//error_log(__METHOD__.__LINE__." $_flag -> $flag2set ".array2string($filter).array2string($messageList));
$this -> mail_bo -> flagMessages ( $flag2set , $messageList , $folder );
}
$alreadyFlagged = true ;
}
2014-07-08 10:50:43 +02:00
elseif ( ! empty ( $filter ) &&
( ! in_array ( $_flag , array ( 'read' , 'flagged' , 'label1' , 'label2' , 'label3' , 'label4' , 'label5' )) ||
( in_array ( $_flag , array ( 'read' , 'flagged' , 'label1' , 'label2' , 'label3' , 'label4' , 'label5' )) &&
( $flag2check == $query [ 'filter' ] || stripos ( $query [ 'filter' ], $flag2check ) !== false ))))
2014-05-27 14:05:23 +02:00
{
$_sR = $this -> mail_bo -> getSortedList (
$folder ,
$sort = 0 ,
$reverse = 1 ,
$filter ,
$rByUid = true ,
false
);
$messageList = $_sR [ 'match' ] -> ids ;
unset ( $_messageList [ 'all' ]);
$_messageList [ 'msg' ] = array ();
}
else
{
2014-07-08 10:50:43 +02:00
//error_log(__METHOD__.__LINE__." $_flag all ".array2string($filter));
2014-05-27 14:05:23 +02:00
$alreadyFlagged = true ;
$uidA = self :: splitRowID ( $_messageList [ 'msg' ][ 0 ]);
$folder = $uidA [ 'folder' ]; // all messages in one set are supposed to be within the same folder
$this -> mail_bo -> flagMessages ( $_flag , 'all' , $folder );
2014-07-08 13:09:31 +02:00
}
2014-05-27 14:05:23 +02:00
}
2013-02-19 17:30:59 +01:00
}
else
{
2013-03-05 15:09:35 +01:00
$uidA = self :: splitRowID ( $_messageList [ 'msg' ][ 0 ]);
2013-02-19 17:30:59 +01:00
$folder = $uidA [ 'folder' ]; // all messages in one set are supposed to be within the same folder
}
2014-05-27 14:05:23 +02:00
if ( ! $alreadyFlagged )
2013-02-19 17:30:59 +01:00
{
2014-05-27 14:05:23 +02:00
foreach ( $_messageList [ 'msg' ] as $rowID )
{
$hA = self :: splitRowID ( $rowID );
$messageList [] = $hA [ 'msgUID' ];
}
2014-07-08 10:50:43 +02:00
//error_log(__METHOD__.__LINE__." $_flag in $folder:".array2string(((isset($_messageList['all']) && $_messageList['all']) ? 'all':$messageList)));
2014-05-27 14:05:23 +02:00
$this -> mail_bo -> flagMessages ( $_flag , (( isset ( $_messageList [ 'all' ]) && $_messageList [ 'all' ]) ? 'all' : $messageList ), $folder );
2013-02-19 17:30:59 +01:00
}
}
else
{
2013-02-28 10:28:08 +01:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . " -> No messages selected. " );
2013-02-19 17:30:59 +01:00
}
2014-01-21 15:46:00 +01:00
if ( $_sendJsonResponse )
{
$response = egw_json_response :: get ();
2014-07-08 10:50:43 +02:00
if ( $query [ 'filter' ] && ( $flag2check == $query [ 'filter' ] || stripos ( $query [ 'filter' ], $flag2check ) !== false ))
{
$response -> call ( 'egw.refresh' , lang ( 'flagged %1 messages as %2 in %3' ,( isset ( $_messageList [ 'all' ]) && $_messageList [ 'all' ] ? lang ( 'all' ) : count ( $_messageList [ 'msg' ])), lang ( $_flag ), $folder ), 'mail' );
}
else
{
$response -> call ( 'egw.message' , lang ( 'flagged %1 messages as %2 in %3' ,( isset ( $_messageList [ 'all' ]) && $_messageList [ 'all' ] ? lang ( 'all' ) : count ( $_messageList [ 'msg' ])), lang ( $_flag ), $folder ));
}
2014-01-21 15:46:00 +01:00
}
2013-02-19 17:30:59 +01:00
}
2013-02-28 10:28:08 +01:00
/**
* delete messages
*
* @ param array _messageList list of UID ' s
2013-05-27 15:48:55 +02:00
* @ param string _forceDeleteMethod - method of deletion to be enforced
2013-02-28 10:28:08 +01:00
* @ return xajax response
*/
2013-05-27 15:48:55 +02:00
function ajax_deleteMessages ( $_messageList , $_forceDeleteMethod = null )
2013-02-28 10:28:08 +01:00
{
2013-05-27 15:48:55 +02:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . " -> " . print_r ( $_messageList , true ) . ' Method:' . $_forceDeleteMethod );
$error = null ;
2014-07-17 11:59:14 +02:00
$filtered = false ;
2013-02-28 10:28:08 +01:00
if ( $_messageList == 'all' || ! empty ( $_messageList [ 'msg' ]))
{
2014-06-20 14:05:03 +02:00
if ( isset ( $_messageList [ 'all' ]) && $_messageList [ 'all' ])
2013-02-28 10:28:08 +01:00
{
2014-06-20 14:05:03 +02:00
// we have both messageIds AND allFlag folder information
$uidA = self :: splitRowID ( $_messageList [ 'msg' ][ 0 ]);
$folder = $uidA [ 'folder' ]; // all messages in one set are supposed to be within the same folder
if ( isset ( $_messageList [ 'activeFilters' ]) && $_messageList [ 'activeFilters' ])
{
$query = $_messageList [ 'activeFilters' ];
if ( ! empty ( $query [ 'search' ]) || ! empty ( $query [ 'filter' ]))
{
//([filterName] => Schnellsuche[type] => quick[string] => ebay[status] => any
if ( is_null ( emailadmin_imapbase :: $supportsORinQuery ) || ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ]))
{
emailadmin_imapbase :: $supportsORinQuery = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'supportsORinQuery' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), 60 * 60 * 10 );
if ( ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ])) emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] = true ;
}
2014-07-17 11:59:14 +02:00
$filtered = true ;
2014-07-08 10:50:43 +02:00
$filter = array ( 'filterName' => ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] ? lang ( 'quicksearch' ) : lang ( 'subject' )), 'type' => ( $query [ 'filter2' ] ? $query [ 'filter2' ] : ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] ? 'quick' : 'subject' )), 'string' => $query [ 'search' ], 'status' => ( ! empty ( $query [ 'filter' ]) ? $query [ 'filter' ] : 'any' ));
2014-06-20 14:05:03 +02:00
}
else
{
$filter = array ();
}
$messageList = array ();
2014-07-08 10:50:43 +02:00
//error_log(__METHOD__.__LINE__."->".print_r($filter,true).' folder:'.$folder.' Method:'.$_forceDeleteMethod);
2014-07-16 18:34:15 +02:00
$reverse = 1 ;
$rByUid = true ;
2014-06-20 14:05:03 +02:00
$_sR = $this -> mail_bo -> getSortedList (
$folder ,
$sort = 0 ,
2014-07-16 18:34:15 +02:00
$reverse ,
2014-06-20 14:05:03 +02:00
$filter ,
2014-07-16 18:34:15 +02:00
$rByUid ,
2014-06-20 14:05:03 +02:00
false
);
$messageList = $_sR [ 'match' ] -> ids ;
}
else
{
$messageList = 'all' ;
}
try
{
//error_log(__METHOD__.__LINE__."->".print_r($messageList,true).' folder:'.$folder.' Method:'.$_forceDeleteMethod);
$this -> mail_bo -> deleteMessages (( $messageList == 'all' ? 'all' : $messageList ), $folder ,( empty ( $_forceDeleteMethod ) ? 'no' : $_forceDeleteMethod ));
}
catch ( egw_exception $e )
{
$error = str_replace ( '"' , " ' " , $e -> getMessage ());
}
2013-02-28 10:28:08 +01:00
}
else
{
2013-03-05 15:09:35 +01:00
$uidA = self :: splitRowID ( $_messageList [ 'msg' ][ 0 ]);
2013-02-28 10:28:08 +01:00
$folder = $uidA [ 'folder' ]; // all messages in one set are supposed to be within the same folder
2014-06-20 14:05:03 +02:00
foreach ( $_messageList [ 'msg' ] as $rowID )
{
$hA = self :: splitRowID ( $rowID );
$messageList [] = $hA [ 'msgUID' ];
}
try
{
//error_log(__METHOD__.__LINE__."->".print_r($messageList,true).' folder:'.$folder.' Method:'.$_forceDeleteMethod);
$this -> mail_bo -> deleteMessages ( $messageList , $folder ,( empty ( $_forceDeleteMethod ) ? 'no' : $_forceDeleteMethod ));
}
catch ( egw_exception $e )
{
$error = str_replace ( '"' , " ' " , $e -> getMessage ());
}
2013-05-27 15:48:55 +02:00
}
$response = egw_json_response :: get ();
if ( empty ( $error ))
{
2014-07-17 11:59:14 +02:00
$response -> call ( 'app.mail.mail_deleteMessagesShowResult' , array ( 'egw_message' => lang ( 'deleted %1 messages in %2' ,( $messageList == 'all' || $_messageList [ 'all' ] ? ( $filtered ? lang ( 'all filtered' ) : lang ( 'all' )) : count ( $_messageList [ 'msg' ])), $folder ), 'msg' => $_messageList [ 'msg' ]));
2013-05-27 15:48:55 +02:00
}
else
{
$error = str_replace ( '\n' , " \n " , lang ( 'mailserver reported:\n%1 \ndo you want to proceed by deleting the selected messages immediately (click ok)?\nif not, please try to empty your trashfolder before continuing. (click cancel)' , $error ));
2014-01-13 14:06:29 +01:00
$response -> call ( 'app.mail.mail_retryForcedDelete' , array ( 'response' => $error , 'messageList' => $_messageList ));
2013-05-27 15:48:55 +02:00
}
2013-02-28 10:28:08 +01:00
}
else
{
if ( mail_bo :: $debug ) error_log ( __METHOD__ . " -> No messages selected. " );
}
}
2013-04-09 18:00:12 +02:00
/**
* copy messages
*
* @ param array _folderName target folder
* @ param array _messageList list of UID ' s
2013-12-18 11:27:27 +01:00
* @ param string _copyOrMove method to use copy or move allowed
2013-04-09 18:00:12 +02:00
*
* @ return xajax response
*/
2013-12-18 11:27:27 +01:00
function ajax_copyMessages ( $_folderName , $_messageList , $_copyOrMove = 'copy' )
2013-04-09 18:00:12 +02:00
{
2014-01-17 13:02:03 +01:00
if ( mail_bo :: $debug ) error_log ( __METHOD__ . " -> " . $_folderName . ':' . print_r ( $_messageList , true ) . ' Method:' . $_copyOrMove );
2013-04-29 16:56:33 +02:00
$_folderName = $this -> mail_bo -> decodeEntityFolderName ( $_folderName );
2013-12-18 11:27:27 +01:00
// only copy or move are supported as method
if ( ! ( $_copyOrMove == 'copy' || $_copyOrMove == 'move' )) $_copyOrMove = 'copy' ;
2013-12-18 13:14:18 +01:00
list ( $targetProfileID , $targetFolder ) = explode ( self :: $delimiter , $_folderName , 2 );
2014-05-20 12:02:21 +02:00
$lastFoldersUsedForMoveCont = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'lastFolderUsedForMove' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), $expiration = 60 * 60 * 1 );
$changeFolderActions = false ;
if ( ! isset ( $lastFoldersUsedForMoveCont [ $targetProfileID ][ $targetFolder ]))
{
if ( $lastFoldersUsedForMoveCont [ $targetProfileID ] && count ( $lastFoldersUsedForMoveCont [ $targetProfileID ]) > 3 )
{
$keys = array_keys ( $lastFoldersUsedForMoveCont [ $targetProfileID ]);
2014-07-16 18:34:15 +02:00
foreach ( $keys as & $f )
2014-05-20 12:02:21 +02:00
{
if ( count ( $lastFoldersUsedForMoveCont [ $targetProfileID ]) > 3 ) unset ( $lastFoldersUsedForMoveCont [ $targetProfileID ][ $f ]);
else break ;
}
//error_log(__METHOD__.__LINE__.array2string($lastFoldersUsedForMoveCont[$targetProfileID]));
}
$lastFoldersUsedForMoveCont [ $targetProfileID ][ $targetFolder ] = $_folderName ;
$changeFolderActions = true ;
}
2014-07-17 11:59:14 +02:00
$filtered = false ;
2013-04-29 16:56:33 +02:00
if ( $_messageList == 'all' || ! empty ( $_messageList [ 'msg' ]))
{
2014-06-20 15:37:20 +02:00
$error = false ;
if ( isset ( $_messageList [ 'all' ]) && $_messageList [ 'all' ])
2013-04-29 16:56:33 +02:00
{
2014-06-20 15:37:20 +02:00
// we have both messageIds AND allFlag folder information
$uidA = self :: splitRowID ( $_messageList [ 'msg' ][ 0 ]);
$folder = $uidA [ 'folder' ]; // all messages in one set are supposed to be within the same folder
$sourceProfileID = $uidA [ 'profileID' ];
if ( isset ( $_messageList [ 'activeFilters' ]) && $_messageList [ 'activeFilters' ])
{
$query = $_messageList [ 'activeFilters' ];
if ( ! empty ( $query [ 'search' ]) || ! empty ( $query [ 'filter' ]))
{
//([filterName] => Schnellsuche[type] => quick[string] => ebay[status] => any
if ( is_null ( emailadmin_imapbase :: $supportsORinQuery ) || ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ]))
{
emailadmin_imapbase :: $supportsORinQuery = egw_cache :: getCache ( egw_cache :: INSTANCE , 'email' , 'supportsORinQuery' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), null , array (), 60 * 60 * 10 );
if ( ! isset ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ])) emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] = true ;
}
2014-07-17 11:59:14 +02:00
$filtered = true ;
2014-07-08 10:50:43 +02:00
$filter = array ( 'filterName' => ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] ? lang ( 'quicksearch' ) : lang ( 'subject' )), 'type' => ( $query [ 'filter2' ] ? $query [ 'filter2' ] : ( emailadmin_imapbase :: $supportsORinQuery [ $this -> mail_bo -> profileID ] ? 'quick' : 'subject' )), 'string' => $query [ 'search' ], 'status' => ( ! empty ( $query [ 'filter' ]) ? $query [ 'filter' ] : 'any' ));
2014-06-20 15:37:20 +02:00
}
else
{
$filter = array ();
}
$messageList = array ();
2014-07-16 18:34:15 +02:00
$reverse = 1 ;
$rByUid = true ;
2014-06-20 15:37:20 +02:00
$_sR = $this -> mail_bo -> getSortedList (
$folder ,
$sort = 0 ,
2014-07-16 18:34:15 +02:00
$reverse ,
2014-06-20 15:37:20 +02:00
$filter ,
$rByUid = true ,
false
);
$messageList = $_sR [ 'match' ] -> ids ;
foreach ( $messageList as $uID )
{
//error_log(__METHOD__.__LINE__.$uID);
if ( $_copyOrMove == 'move' )
{
$messageListForRefresh [] = self :: generateRowID ( $sourceProfileID , $folderName , $uID , $_prependApp = false );
}
}
}
else
{
$messageList = 'all' ;
}
try
{
//error_log(__METHOD__.__LINE__."->".print_r($messageList,true).' folder:'.$folder.' Method:'.$_forceDeleteMethod);
$this -> mail_bo -> moveMessages ( $targetFolder , $messageList ,( $_copyOrMove == 'copy' ? false : true ), $folder , false ,( $targetProfileID != $sourceProfileID ? $targetProfileID : null ));
}
catch ( egw_exception $e )
{
$error = str_replace ( '"' , " ' " , $e -> getMessage ());
}
2013-04-29 16:56:33 +02:00
}
else
{
$uidA = self :: splitRowID ( $_messageList [ 'msg' ][ 0 ]);
$folder = $uidA [ 'folder' ]; // all messages in one set are supposed to be within the same folder
2013-12-18 13:14:18 +01:00
$sourceProfileID = $uidA [ 'profileID' ];
2014-06-20 15:37:20 +02:00
foreach ( $_messageList [ 'msg' ] as $rowID )
{
//error_log(__METHOD__.__LINE__.$rowID);
$hA = self :: splitRowID ( $rowID );
$messageList [] = $hA [ 'msgUID' ];
if ( $_copyOrMove == 'move' )
{
$helpvar = explode ( self :: $delimiter , $rowID );
array_shift ( $helpvar );
$messageListForRefresh [] = implode ( self :: $delimiter , $helpvar );
}
}
try
{
//error_log(__METHOD__.__LINE__."->".print_r($messageList,true).' folder:'.$folder.' Method:'.$_forceDeleteMethod);
$this -> mail_bo -> moveMessages ( $targetFolder , $messageList ,( $_copyOrMove == 'copy' ? false : true ), $folder , false ,( $targetProfileID != $sourceProfileID ? $targetProfileID : null ));
}
catch ( egw_exception $e )
{
$error = str_replace ( '"' , " ' " , $e -> getMessage ());
}
2013-04-29 16:56:33 +02:00
}
2014-06-20 15:37:20 +02:00
$response = egw_json_response :: get ();
if ( $error )
2013-04-29 16:56:33 +02:00
{
2014-06-20 15:37:20 +02:00
if ( $changeFolderActions == false )
2014-03-10 15:36:03 +01:00
{
2014-06-20 15:37:20 +02:00
unset ( $lastFoldersUsedForMoveCont [ $targetProfileID ][ $targetFolder ]);
$changeFolderActions = true ;
2014-03-10 15:36:03 +01:00
}
2014-06-20 15:37:20 +02:00
$response -> call ( 'egw.message' , $error , " error " );
2013-04-29 16:56:33 +02:00
}
2014-06-20 15:37:20 +02:00
else
2014-02-17 11:19:31 +01:00
{
2014-03-10 15:36:03 +01:00
if ( $_copyOrMove == 'copy' )
{
2014-07-17 11:59:14 +02:00
$response -> call ( 'egw.message' , lang ( 'copied %1 message(s) from %2 to %3' ,( $messageList == 'all' || $_messageList [ 'all' ] ? ( $filtered ? lang ( 'all filtered' ) : lang ( 'all' )) : count ( $messageList )), $folder , $targetFolder ));
2014-03-10 15:36:03 +01:00
}
else
{
2014-07-17 11:59:14 +02:00
$response -> call ( 'egw.refresh' , lang ( 'moved %1 message(s) from %2 to %3' ,( $messageList == 'all' || $_messageList [ 'all' ] ? ( $filtered ? lang ( 'all filtered' ) : lang ( 'all' )) : count ( $messageList )), $folder , $targetFolder ), 'mail' , $messageListForRefresh , 'delete' );
2014-03-10 15:36:03 +01:00
}
2014-02-17 11:19:31 +01:00
}
2014-05-20 12:02:21 +02:00
if ( $changeFolderActions == true )
{
egw_cache :: setCache ( egw_cache :: INSTANCE , 'email' , 'lastFolderUsedForMove' . trim ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ]), $lastFoldersUsedForMoveCont , $expiration = 60 * 60 * 1 );
2014-05-20 13:47:18 +02:00
$actionsnew = self :: get_actions ();
$actionsnew = etemplate_widget_nextmatch :: egw_actions ( $actionsnew );
2014-05-20 12:02:21 +02:00
$response -> call ( 'app.mail.mail_rebuildActionsOnList' , $actionsnew );
2014-02-17 11:19:31 +01:00
}
2013-04-29 16:56:33 +02:00
}
else
{
if ( mail_bo :: $debug ) error_log ( __METHOD__ . " -> No messages selected. " );
}
2013-04-09 18:00:12 +02:00
}
2013-02-08 20:11:44 +01:00
}