2013-07-25 17:48:18 +02:00
< ? php
/**
* EGroupware - Mail - interface class
*
* @ link http :// www . egroupware . org
* @ package mail
2016-10-08 14:32:58 +02:00
* @ author Hadi Nategh [ hn @ egroupware . org ]
* @ copyright ( c ) 2013 - 16 by Hadi Nategh < hn - AT - egroupware . org >
2013-07-25 17:48:18 +02:00
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
2014-04-03 14:31:52 +02:00
* @ version $Id $
2013-07-25 17:48:18 +02:00
*/
2016-03-28 20:51:38 +02:00
use EGroupware\Api ;
2016-05-03 21:17:44 +02:00
use EGroupware\Api\Framework ;
use EGroupware\Api\Etemplate ;
2016-03-28 20:51:38 +02:00
use EGroupware\Api\Mail ;
2013-07-25 17:48:18 +02:00
class mail_sieve
{
2014-05-21 17:26:12 +02:00
var $public_functions = array (
'editVacation' => True ,
'index' => True ,
'edit' => True ,
'editEmailNotification' => True , // Added email notifications
);
2013-07-25 17:48:18 +02:00
var $errorStack ;
2014-05-14 18:23:11 +02:00
/**
* Current Identitiy
*
* @ var String
*/
2013-12-17 16:58:51 +01:00
var $currentIdentity ;
2014-05-20 12:14:27 +02:00
2014-05-20 10:48:50 +02:00
/**
* user has admin right to emailadmin
*
* @ var boolean
*/
var $mail_admin = false ;
2014-05-20 12:14:27 +02:00
2014-05-20 10:48:50 +02:00
/**
2014-05-20 17:39:20 +02:00
* account object
2014-05-20 10:48:50 +02:00
*
2016-03-28 20:51:38 +02:00
* @ var Mail\Account
2014-05-20 10:48:50 +02:00
*/
var $account ;
2014-05-20 12:14:27 +02:00
2014-05-20 10:48:50 +02:00
/**
* flag to check if vacation is called from admin
*
2014-05-20 17:39:20 +02:00
* @ var boolean
2014-05-20 10:48:50 +02:00
*/
var $is_admin_vac = false ;
2014-07-22 14:52:10 +02:00
2014-06-27 16:49:24 +02:00
/**
* siteConfigs
*
* @ var array
*/
var $mailConfig = array ();
2014-07-22 14:52:10 +02:00
2013-07-25 17:48:18 +02:00
/**
* Constructor
*/
function __construct ()
{
2016-03-28 20:51:38 +02:00
$this -> displayCharset = Api\Translation :: charset ();
2016-08-02 16:44:14 +02:00
$this -> mail_admin = isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ]);
2016-03-28 20:51:38 +02:00
$this -> mailConfig = Api\Config :: read ( 'mail' );
2014-07-22 14:52:10 +02:00
2016-03-28 20:51:38 +02:00
$acc_id = isset ( $_GET [ 'acc_id' ]) ? ( int ) $_GET [ 'acc_id' ] : Api\Cache :: getSession ( __CLASS__ , 'acc_id' );
2014-05-21 19:44:10 +02:00
if ( $acc_id > 0 )
2014-02-14 16:39:18 +01:00
{
2016-03-28 20:51:38 +02:00
$this -> account = Mail\Account :: read ( $acc_id );
$identity = Mail\Account :: read_identity ( $this -> account -> ident_id , true );
$this -> currentIdentity = Mail :: generateIdentityString ( $identity , false );
2014-02-14 16:39:18 +01:00
}
2014-07-22 14:52:10 +02:00
2013-07-25 17:48:18 +02:00
$this -> restoreSessionData ();
}
2014-05-21 20:16:39 +02:00
2013-07-25 17:48:18 +02:00
/**
* Sieve rules list
*
2014-05-20 15:06:33 +02:00
* @ param { array } $content
* @ param { string } $msg
2013-07-25 17:48:18 +02:00
*/
function index ( array $content = null , $msg = null )
{
2014-05-21 19:44:10 +02:00
if ( ! is_array ( $content ))
{
2016-03-28 20:51:38 +02:00
Api\Cache :: setSession ( __CLASS__ , 'acc_id' , $this -> account -> acc_id );
2014-05-21 19:44:10 +02:00
}
2016-05-03 21:17:44 +02:00
//Instantiate an eTemplate object
$tmpl = new Etemplate ( 'mail.sieve.index' );
2013-08-09 19:47:53 +02:00
2014-02-14 16:39:18 +01:00
if ( $msg )
{
$content [ 'msg' ] = $msg ;
}
2014-05-21 20:16:39 +02:00
2014-05-20 10:48:50 +02:00
if ( $this -> account -> acc_sieve_enabled )
2013-10-11 13:43:01 +02:00
{
//Initializes the Grid contents
2014-02-14 16:39:18 +01:00
$content [ 'rg' ] = $this -> get_rows ();
2013-07-25 17:48:18 +02:00
2013-10-11 13:43:01 +02:00
// Set content-menu actions
2016-03-28 20:51:38 +02:00
$tmpl -> setElementAttribute ( 'rg' , 'actions' , $this -> get_actions ());
2013-07-25 17:48:18 +02:00
2013-10-11 13:43:01 +02:00
$sel_options = array (
'status' => array (
'ENABLED' => lang ( 'Enabled' ),
'DISABLED' => lang ( 'Disabled' ),
)
);
}
else
{
2015-02-06 13:35:51 +01:00
$content [ 'msg' ] = lang ( 'error' ) . ':' . lang ( 'Serverside Filterrules (Sieve) are not activated' ) . '. ' . lang ( 'Please contact your Administrator to validate if your Server supports Serverside Filterrules, and how to enable them in EGroupware for your active Account (%1) with ID:%2.' , $this -> currentIdentity , $this -> account -> acc_id );
2013-10-11 13:43:01 +02:00
$content [ 'hideIfSieveDisabled' ] = 'mail_DisplayNone' ;
}
2024-03-20 10:14:30 +01:00
Api\Framework :: bodyClass ( 'scrollVertical' );
2014-02-14 16:39:18 +01:00
$tmpl -> exec ( 'mail.mail_sieve.index' , $content , $sel_options , array ());
2013-07-25 17:48:18 +02:00
}
2013-08-09 19:47:53 +02:00
/**
* Email Notification Edit
*
2014-02-14 16:39:18 +01:00
*
* @ param { array } $content
* @ param { string } $msg
2013-08-09 19:47:53 +02:00
*/
function editEmailNotification ( $content = null , $msg = '' )
{
2016-05-03 21:17:44 +02:00
//Instantiate an eTemplate object, representing sieve.emailNotification
$eNotitmpl = new Etemplate ( 'mail.sieve.emailNotification' );
2014-05-13 19:09:05 +02:00
2014-05-20 10:48:50 +02:00
if ( $this -> account -> acc_sieve_enabled )
2013-08-09 19:47:53 +02:00
{
2013-10-11 13:43:01 +02:00
$eNotification = $this -> getEmailNotification ();
2013-08-09 19:47:53 +02:00
2013-10-11 13:43:01 +02:00
if ( ! is_array ( $content ))
2013-08-09 19:47:53 +02:00
{
2013-10-11 13:43:01 +02:00
$content = $eNotification ;
2013-08-09 19:47:53 +02:00
2013-10-11 13:43:01 +02:00
if ( ! empty ( $eNotification [ 'externalEmail' ]))
{
$content [ 'externalEmail' ] = explode ( " , " , $eNotification [ 'externalEmail' ]);
}
}
else
2013-08-09 19:47:53 +02:00
{
2013-10-11 13:43:01 +02:00
$this -> restoreSessionData ();
2019-02-12 22:13:45 +01:00
$button = @ key ( $content [ 'button' ]);
2013-10-11 13:43:01 +02:00
unset ( $content [ 'button' ]);
switch ( $button )
{
case 'save' :
case 'apply' :
if ( isset ( $content [ 'status' ]))
2013-08-09 19:47:53 +02:00
{
2013-10-11 13:43:01 +02:00
$newEmailNotification = $content ;
2014-05-20 15:06:33 +02:00
if ( empty ( $this -> mailConfig [ 'prefpreventforwarding' ]) ||
$this -> mailConfig [ 'prefpreventforwarding' ] == 0 )
2013-08-09 19:47:53 +02:00
{
2013-10-11 13:43:01 +02:00
if ( is_array ( $content [ 'externalEmail' ]) && ! empty ( $content [ 'externalEmail' ]))
{
$newEmailNotification [ 'externalEmail' ] = implode ( " , " , $content [ 'externalEmail' ]);
}
2013-08-09 19:47:53 +02:00
}
}
2013-10-11 13:43:01 +02:00
if ( isset ( $content [ 'externalEmail' ]) && ! empty ( $content [ 'externalEmail' ]))
2013-08-09 19:47:53 +02:00
{
2014-05-21 17:26:12 +02:00
if ( ! $this -> account -> imapServer () -> setEmailNotification ( $newEmailNotification ))
2013-10-11 13:43:01 +02:00
{
$msg = lang ( " email notification update failed " ) . " <br /> " ;
break ;
}
else
{
$msg .= lang ( " email notification successfully updated! " );
}
2013-08-09 19:47:53 +02:00
}
else
{
2013-10-11 13:43:01 +02:00
$msg .= lang ( 'email notification update failed! You need to set an email address!' );
break ;
2013-08-09 19:47:53 +02:00
}
2016-05-03 21:17:44 +02:00
Framework :: refresh_opener ( $msg , 'mail' );
2014-05-13 09:54:42 +02:00
if ( $button === 'apply' )
{
break ;
2014-05-13 19:09:05 +02:00
}
2013-08-09 19:47:53 +02:00
2013-10-11 13:43:01 +02:00
case 'cancel' :
2016-05-03 21:17:44 +02:00
Framework :: window_close ();
2016-03-28 20:51:38 +02:00
exit ;
2013-10-11 13:43:01 +02:00
}
$this -> saveSessionData ();
2013-08-09 19:47:53 +02:00
}
2013-10-11 13:43:01 +02:00
$sel_options = array (
'status' => array (
'on' => lang ( 'Active' ),
'off' => lang ( 'Deactive' ),
),
'displaySubject' => array (
0 => lang ( 'No' ),
1 => lang ( 'Yes' ),
),
);
$content [ 'msg' ] = $msg ;
}
else
{
2015-02-06 13:35:51 +01:00
$content [ 'msg' ] = lang ( 'error' ) . ':' . lang ( 'Serverside Filterrules (Sieve) are not activated' ) . '. ' . lang ( 'Please contact your Administrator to validate if your Server supports Serverside Filterrules, and how to enable them in EGroupware for your active Account (%1) with ID:%2.' , $this -> currentIdentity , $this -> account -> acc_id );
2013-10-11 13:43:01 +02:00
$content [ 'hideIfSieveDisabled' ] = 'mail_DisplayNone' ;
}
2013-08-09 19:47:53 +02:00
$eNotitmpl -> exec ( 'mail.mail_sieve.editEmailNotification' , $content , $sel_options );
}
2013-07-25 17:48:18 +02:00
/**
* Sieve rules edit
*
2014-05-20 15:06:33 +02:00
* @ param { array } $content
2013-07-25 17:48:18 +02:00
*/
function edit ( $content = null )
{
2016-05-03 21:17:44 +02:00
//Instantiate an eTemplate object, representing sieve.edit template
$etmpl = new Etemplate ( 'mail.sieve.edit' );
2022-08-08 17:27:21 +02:00
$etmpl -> setElementAttribute ( 'action_folder_text' , 'searchOptions' , array ( 'noPrefixId' => true ));
2013-07-25 17:48:18 +02:00
if ( ! is_array ( $content ))
{
if ( $this -> getRules ( $_GET [ 'ruleID' ]) && isset ( $_GET [ 'ruleID' ]))
{
$rules = $this -> rulesByID ;
2013-08-09 19:47:53 +02:00
$content = $rules ;
2016-05-06 12:47:06 +02:00
$content [ 'ruleID' ] = $_GET [ 'ruleID' ];
2013-07-25 17:48:18 +02:00
switch ( $rules [ 'action' ])
{
case 'folder' :
2022-08-08 17:27:21 +02:00
$content [ 'action_folder_text' ] = $rules [ 'action_arg' ];
2013-08-09 19:47:53 +02:00
2013-07-25 17:48:18 +02:00
break ;
case 'address' :
2013-08-09 19:47:53 +02:00
2015-04-08 18:28:48 +02:00
$content [ 'action_address_text' ] = explode ( ',' , $rules [ 'action_arg' ]);
2013-07-25 17:48:18 +02:00
break ;
case 'reject' :
$content [ 'action_reject_text' ] = $rules [ 'action_arg' ];
2021-10-15 17:23:36 +02:00
break ;
case 'flags' :
$content [ 'action_flags_list' ] = explode ( ' ' , $rules [ 'action_arg' ]);
break ;
2013-07-25 17:48:18 +02:00
}
2021-01-29 11:19:35 +01:00
$content [ 'anyof' ] = $rules [ 'anyof' ] != 0 ? 1 : 0 ;
2013-07-25 17:48:18 +02:00
}
else // Adding new rule
{
2013-08-09 19:47:53 +02:00
$this -> getRules ( null );
2013-07-25 17:48:18 +02:00
$newRulePriority = count ( $this -> rules ) * 2 + 1 ;
$newRules [ 'priority' ] = $newRulePriority ;
$newRules [ 'status' ] = 'ENABLED' ;
2013-08-09 19:47:53 +02:00
$readonlys = array (
'button[delete]' => 'true' ,
);
2013-07-25 17:48:18 +02:00
$this -> rulesByID = $newRules ;
2013-08-09 19:47:53 +02:00
$content = $this -> rulesByID ;
2013-07-25 17:48:18 +02:00
}
$this -> saveSessionData ();
}
else
{
$this -> restoreSessionData ();
2019-02-12 22:13:45 +01:00
$button = @ key ( $content [ 'button' ]);
2014-02-14 16:39:18 +01:00
2013-08-09 19:47:53 +02:00
//$ruleID is calculated by priority from the selected rule and is an unique ID
2016-05-06 12:47:06 +02:00
$content [ 'ruleID' ] = $ruleID = ( $this -> rulesByID [ 'priority' ] - 1 ) / 2 ;
2014-02-14 17:56:48 +01:00
$error = 0 ;
2021-03-30 20:34:34 +02:00
$msg = '' ;
2013-07-25 17:48:18 +02:00
switch ( $button )
{
case 'save' :
2013-08-09 19:47:53 +02:00
case 'apply' :
2013-07-25 17:48:18 +02:00
if ( $content )
{
unset ( $content [ 'button' ]);
2013-08-09 19:47:53 +02:00
2013-07-25 17:48:18 +02:00
$newRule = $content ;
$newRule [ 'priority' ] = $this -> rulesByID [ 'priority' ];
$newRule [ 'status' ] = $this -> rulesByID [ 'status' ];
2013-10-09 19:17:24 +02:00
switch ( $content [ 'action' ])
2013-07-25 17:48:18 +02:00
{
case 'folder' :
2022-08-08 17:27:21 +02:00
$newRule [ 'action_arg' ] = $content [ 'action_folder_text' ];
2013-07-25 17:48:18 +02:00
break ;
case 'address' :
2015-07-20 15:00:48 +02:00
$content [ 'action_address_text' ] = self :: strip_rfc882_addresses ( $content [ 'action_address_text' ]);
$newRule [ 'action_arg' ] = implode ( ',' , $content [ 'action_address_text' ]);
2013-07-25 17:48:18 +02:00
break ;
case 'reject' :
$newRule [ 'action_arg' ] = $content [ 'action_reject_text' ];
2021-10-15 17:23:36 +02:00
break ;
case 'flags' :
$newRule [ 'action_arg' ] = implode ( ' ' , $content [ 'action_flags_list' ]);
break ;
2013-07-25 17:48:18 +02:00
}
unset ( $newRule [ 'action_folder_text' ]);
unset ( $newRule [ 'action_address_text' ]);
unset ( $newRule [ 'action_reject_text' ]);
2021-10-15 17:23:36 +02:00
unset ( $newRule [ 'action_flags_list' ]);
2013-07-25 17:48:18 +02:00
$newRule [ 'flg' ] = 0 ;
if ( $newRule [ 'continue' ] ) { $newRule [ 'flg' ] += 1 ; }
if ( $newRule [ 'gthan' ] ) { $newRule [ 'flg' ] += 2 ; }
if ( $newRule [ 'anyof' ] ) { $newRule [ 'flg' ] += 4 ; }
if ( $newRule [ 'keep' ] ) { $newRule [ 'flg' ] += 8 ; }
if ( $newRule [ 'regexp' ] ) { $newRule [ 'flg' ] += 128 ; }
2014-02-14 16:39:18 +01:00
2013-07-25 17:48:18 +02:00
if ( $newRule [ 'action' ] && $this -> rulesByID [ 'priority' ])
{
$this -> rules [ $ruleID ] = $newRule ;
2014-05-21 17:26:12 +02:00
$ret = $this -> account -> imapServer () -> setRules ( $this -> rules );
2014-05-20 10:48:50 +02:00
if ( ! $ret && ! empty ( $this -> account -> imapServer () -> error ))
2013-07-25 17:48:18 +02:00
{
2014-05-20 10:48:50 +02:00
$msg .= lang ( " Saving the rule failed: " ) . " <br /> " . $this -> account -> imapServer () -> error . " <br /> " ;
2013-07-25 17:48:18 +02:00
}
2013-08-09 19:47:53 +02:00
else
{
$msg .= lang ( " The rule with priority %1 successfully saved! " , $ruleID );
}
2013-07-25 17:48:18 +02:00
$this -> saveSessionData ();
}
else
{
$msg .= " \n " . lang ( " Error: Could not save rule " ) . ' ' . lang ( " No action defined! " );
$error ++ ;
}
}
else
{
$msg .= " \n " . lang ( " Error: Could not save rule " ) . ' ' . lang ( " No action defined! " );
$error ++ ;
}
2016-05-03 21:17:44 +02:00
Framework :: refresh_opener ( $msg , 'mail' , 'sieve' );
2014-05-13 09:54:42 +02:00
if ( $button == " apply " )
{
break ;
}
2013-08-09 19:47:53 +02:00
//fall through
2013-07-25 17:48:18 +02:00
case 'delete' :
2013-08-09 19:47:53 +02:00
if ( $button == " delete " )
2014-05-13 09:54:42 +02:00
{
2014-05-23 10:00:41 +02:00
if ( $ruleID === count ( $this -> rules ) - 1 )
{
$msg = lang ( 'rule with priority ' ) . $ruleID . lang ( ' deleted!' );
}
else
{
$msg = lang ( 'rule with priority ' ) . $ruleID . lang ( ' deleted!' ) . lang ( ' And the rule with priority %1, now got the priority %2' , $ruleID + 1 , $ruleID );
}
unset ( $this -> rules [ $ruleID ]);
$this -> rules = array_values ( $this -> rules );
2014-05-23 10:01:56 +02:00
$this -> updateScript ();
2014-05-13 09:54:42 +02:00
}
2016-05-03 21:17:44 +02:00
Framework :: refresh_opener ( $msg , 'mail' , 'sieve' );
2013-08-09 19:47:53 +02:00
case 'cancel' :
2016-05-03 21:17:44 +02:00
Framework :: window_close ();
2016-03-28 20:51:38 +02:00
exit ;
2013-07-25 17:48:18 +02:00
}
}
2013-08-09 19:47:53 +02:00
$sel_options = array ( //array_merge($sel_options,array(
2013-07-25 17:48:18 +02:00
'anyof' => array (
0 => lang ( 'all of' ),
1 => lang ( 'any of' ),
),
'gthan' => array (
0 => lang ( 'less than' ),
1 => lang ( 'greater than' ),
),
'bodytransform' => array (
0 => 'raw' ,
1 => 'text' ,
),
2016-03-28 20:51:38 +02:00
'ctype' => Mail\Script :: $btransform_ctype_array ,
2013-07-25 17:48:18 +02:00
);
2014-02-14 16:39:18 +01:00
2022-03-03 15:41:01 +01:00
// No forward should be applied regardless of content/rules
$content [ 'no_forward' ] = $this -> account -> acc_smtp_type !== Api\Mail\Smtp :: class && ! $this -> account -> acc_user_forward ;
2013-10-10 16:07:50 +02:00
//Set the preselect_options for mail/folders as we are not allow free entry for folder taglist
2022-08-08 17:27:21 +02:00
if ( ! empty ( $content [ 'action_folder_text' ]))
{
$sel_options [ 'action_folder_text' ] = [ $content [ 'action_folder_text' ] => $content [ 'action_folder_text' ]];
}
2014-02-14 17:56:48 +01:00
return $etmpl -> exec ( 'mail.mail_sieve.edit' , $content , $sel_options , $readonlys , array (), 2 );
2013-07-25 17:48:18 +02:00
}
2013-08-09 19:47:53 +02:00
/**
* Read email notification script from the sieve script from server
*
2014-02-14 16:39:18 +01:00
*
2013-08-09 19:47:53 +02:00
* @ return type , returns array of email notification data , and in case of failure returns false
2014-05-20 10:48:50 +02:00
* @ todo Need to be checked if it is still needed
2013-08-09 19:47:53 +02:00
*/
function getEmailNotification ()
2013-07-25 17:48:18 +02:00
{
2014-05-20 15:06:33 +02:00
if ( ! ( empty ( $this -> mailConfig [ 'prefpreventnotificationformailviaemail' ]) || $this -> mailConfig [ 'prefpreventnotificationformailviaemail' ] == 0 ))
2014-05-13 09:54:42 +02:00
{
2016-05-03 21:17:44 +02:00
throw new Api\Exception\NoPermission ();
2014-05-13 19:09:05 +02:00
}
2013-07-25 17:48:18 +02:00
2016-01-28 10:52:05 +01:00
try {
2014-05-20 19:22:52 +02:00
$emailNotification = $this -> account -> imapServer () -> getEmailNotification ();
2013-08-09 19:47:53 +02:00
}
2016-01-28 10:52:05 +01:00
catch ( Exception $e ) {
unset ( $e );
$emailNotification = array ();
}
2013-08-09 19:47:53 +02:00
return $emailNotification ;
}
/**
* Fetch Vacation rules and predefined Addresses from mailserver
*
2014-05-20 17:39:20 +02:00
* @ param string $accountID
2014-02-14 16:39:18 +01:00
*
2017-04-24 11:39:02 +02:00
* @ return array return multi - dimensional array of vacation and aliases
2013-08-09 19:47:53 +02:00
*/
2014-05-20 17:39:20 +02:00
function getVacation ( $accountID = null )
2013-08-09 19:47:53 +02:00
{
2014-05-20 15:06:33 +02:00
if ( ! ( empty ( $this -> mailConfig [ 'prefpreventabsentnotice' ]) || $this -> mailConfig [ 'prefpreventabsentnotice' ] == 0 ))
2013-07-25 17:48:18 +02:00
{
2016-05-03 21:17:44 +02:00
throw new Api\Exception\NoPermission ();
2013-07-25 17:48:18 +02:00
}
2014-05-20 17:39:20 +02:00
try {
if ( $this -> is_admin_vac )
2013-07-25 17:48:18 +02:00
{
2014-05-20 17:39:20 +02:00
$icServer = $this -> account -> imapServer ( $accountID );
$vacation = $icServer -> getVacationUser ( $accountID );
2013-07-25 17:48:18 +02:00
}
else
{
2014-05-20 17:39:20 +02:00
$icServer = $this -> account -> imapServer ();
2014-05-21 14:23:09 +02:00
$icServer -> retrieveRules ( null );
2014-05-20 17:39:20 +02:00
$vacation = $icServer -> getVacation ();
2013-07-25 17:48:18 +02:00
}
}
2014-05-20 17:39:20 +02:00
catch ( Exception $e )
2013-07-25 17:48:18 +02:00
{
2016-05-03 21:17:44 +02:00
Framework :: window_close ( lang ( $e -> getMessage ()));
2013-07-25 17:48:18 +02:00
}
2014-05-20 10:48:50 +02:00
if ( is_null ( $accountID )) $accountID = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
2014-05-20 12:14:27 +02:00
2017-04-24 11:39:02 +02:00
$account_email = Api\Accounts :: id2name ( $accountID , 'account_email' );
2016-05-03 21:17:44 +02:00
$accAllIdentities = $this -> account -> smtpServer () -> getAccountEmailAddress ( Api\Accounts :: id2name ( $accountID ));
2017-04-24 11:39:02 +02:00
$allAliases = $this -> account -> ident_email != '' ?
// Fix ident_email with no domain part set
array ( Mail :: fixInvalidAliasAddress ( $account_email , $this -> account -> ident_email ))
: array ();
2017-04-21 11:08:39 +02:00
foreach ( $accAllIdentities as & $val )
2014-05-14 18:23:11 +02:00
{
2017-04-21 11:08:39 +02:00
if ( $val [ 'type' ] != 'default' )
2014-05-14 18:23:11 +02:00
{
2017-04-21 11:08:39 +02:00
// if the alias has no domain part set try to add
// default domain extracted from ident_email address
2017-04-24 11:39:02 +02:00
$allAliases [] = Mail :: fixInvalidAliasAddress ( $account_email , $val [ 'address' ]);
2014-05-14 18:23:11 +02:00
}
}
2017-04-21 11:08:39 +02:00
// try to fix already stored aliases
foreach ( $vacation [ 'addresses' ] as & $address )
{
2017-04-24 11:39:02 +02:00
$address = Mail :: fixInvalidAliasAddress ( $account_email , $address );
2017-04-21 11:08:39 +02:00
}
2014-05-14 18:23:11 +02:00
asort ( $allAliases );
2013-08-09 19:47:53 +02:00
return array (
'vacation' => $vacation ,
2014-05-14 18:23:11 +02:00
'aliases' => array_values ( $allAliases ),
2014-05-13 19:09:05 +02:00
);
2013-08-09 19:47:53 +02:00
}
/**
* Vacation edit
*
2014-02-14 16:39:18 +01:00
* @ param { array } $content
* @ param { string } $msg
2013-08-09 19:47:53 +02:00
*/
function editVacation ( $content = null , $msg = '' )
{
2016-05-03 21:17:44 +02:00
//Instantiate an eTemplate object, representing the sieve.vacation template
$vtmpl = new Etemplate ( 'mail.sieve.vacation' );
2014-05-13 09:54:42 +02:00
$vacation = array ();
2014-05-20 12:14:27 +02:00
2014-05-20 10:48:50 +02:00
if ( isset ( $_GET [ 'account_id' ])) $account_id = $preserv [ 'account_id' ] = $_GET [ 'account_id' ];
2014-05-20 12:14:27 +02:00
2014-05-20 10:48:50 +02:00
if ( isset ( $content [ 'account_id' ]))
{
$account_id = $content [ 'account_id' ];
$preserv [ 'acc_id' ] = $content [ 'acc_id' ];
}
if ( isset ( $account_id ) && $this -> mail_admin )
{
2016-03-28 20:51:38 +02:00
foreach ( Mail\Account :: search ( $account_id , false , null , false , 0 , false ) as $account )
2014-05-20 12:14:27 +02:00
{
2014-09-24 19:25:18 +02:00
try {
// check if account is valid for multiple users, has admin credentials and sieve enabled
2016-03-28 20:51:38 +02:00
if ( Mail\Account :: is_multiple ( $account ) &&
2014-09-24 19:25:18 +02:00
( $icServer = $account -> imapServer ( true )) && // check on icServer object, so plugins can overwrite
$icServer -> acc_imap_admin_username && $icServer -> acc_sieve_enabled )
{
$allAccounts [ $account -> acc_id ] = $account -> acc_name ;
$accounts [ $account -> acc_id ] = $account ;
}
}
catch ( Exception $e ) {
unset ( $e );
// ignore broken accounts
2014-05-20 10:48:50 +02:00
}
}
2014-05-20 12:14:27 +02:00
2014-05-20 10:48:50 +02:00
$profileID = ! isset ( $content [ 'acc_id' ]) ? key ( $accounts ) : $content [ 'acc_id' ];
2014-09-24 19:25:18 +02:00
if ( isset ( $_GET [ 'acc_id' ]) && isset ( $allAccounts [ $_GET [ 'acc_id' ]]))
{
$profileID = $content [ 'acc_id' ] = ( int ) $_GET [ 'acc_id' ];
}
2014-05-20 12:14:27 +02:00
2014-05-20 10:48:50 +02:00
//Chooses the right account
$this -> account = $accounts [ $profileID ];
2014-05-20 12:14:27 +02:00
2014-05-20 10:48:50 +02:00
$this -> is_admin_vac = true ;
$preserv [ 'account_id' ] = $account_id ;
}
2014-05-21 17:26:12 +02:00
elseif ( ! is_array ( $content ) && isset ( $_GET [ 'acc_id' ]))
{
2016-03-28 20:51:38 +02:00
$this -> account = Mail\Account :: read ( $_GET [ 'acc_id' ]);
2014-05-21 17:26:12 +02:00
$preserv [ 'acc_id' ] = $this -> account -> acc_id ;
}
2014-05-21 19:44:10 +02:00
elseif ( $content [ 'acc_id' ])
{
2016-03-28 20:51:38 +02:00
$this -> account = Mail\Account :: read ( $content [ 'acc_id' ]);
2014-07-22 14:52:10 +02:00
$preserv [ 'acc_id' ] = $content [ 'acc_id' ];
2014-05-21 19:44:10 +02:00
}
2014-05-20 12:14:27 +02:00
2014-05-20 18:48:44 +02:00
$icServer = $this -> account -> imapServer ( $this -> is_admin_vac ? $account_id : false );
2014-05-20 12:14:27 +02:00
2014-05-20 18:48:44 +02:00
if ( $icServer -> acc_sieve_enabled )
2013-07-25 17:48:18 +02:00
{
2014-05-20 17:39:20 +02:00
$vacRules = $this -> getVacation ( $account_id );
2015-02-06 13:35:51 +01:00
if ( $vacRules [ 'vacation' ] === false )
2013-10-16 13:22:53 +02:00
{
2015-02-06 13:35:51 +01:00
$content [ 'msg' ] = lang ( 'error' ) . ':' . lang ( 'Serverside Vacationnotice (via Sieve) are not activated' ) . '. ' .
lang ( 'Please contact your Administrator to validate if your Server supports Serverside Vacationmessages, and how to enable them in EGroupware for your active Account (%1) with ID:%2.' , $this -> currentIdentity , $icServer -> ImapServerId );
$content [ 'hideIfSieveDisabled' ] = 'mail_DisplayNone' ;
2013-10-16 13:22:53 +02:00
}
2015-02-06 13:35:51 +01:00
else
2013-07-25 17:48:18 +02:00
{
2024-02-01 14:11:49 +01:00
if ( ! empty ( $icServer -> getExtensions ()) && in_array ( 'DATE' , $icServer -> getExtensions ()))
2014-05-13 09:54:42 +02:00
{
2015-02-06 13:35:51 +01:00
$ByDate = array ( 'by_date' => lang ( 'By date' ));
2014-05-13 09:54:42 +02:00
}
2015-04-21 13:17:49 +02:00
if ( ! is_array ( $content ) || ( $content [ 'acc_id' ] && ! isset ( $content [ 'button' ])) || ( strlen ( trim ( $content [ 'text' ])) == 0 && in_array ( $content [ 'status' ], array ( 'on' , 'by_date' ))))
2013-10-11 13:43:01 +02:00
{
2015-02-06 13:35:51 +01:00
$content = $vacation = $vacRules [ 'vacation' ];
if ( ! empty ( $profileID )) $content [ 'acc_id' ] = $profileID ;
if ( empty ( $vacation [ 'addresses' ]) || implode ( '' , $vacation [ 'addresses' ]) == '' )
{
$content [ 'addresses' ] = $vacRules [ 'aliases' ];
}
if ( ! empty ( $vacation [ 'forwards' ]))
{
$content [ 'forwards' ] = explode ( " , " , $vacation [ 'forwards' ]);
}
else
{
2024-01-15 13:16:51 +01:00
$content [ 'forwards' ] = [];
2015-02-06 13:35:51 +01:00
}
2015-04-21 13:17:49 +02:00
if ( strlen ( trim ( $vacation [ 'text' ])) == 0 && $this -> mailConfig [ 'default_vacation_text' ]) $content [ 'text' ] = $this -> mailConfig [ 'default_vacation_text' ];
if ( strlen ( trim ( $content [ 'text' ])) == 0 )
{
$content [ 'msg' ] = $msg = lang ( 'error' ) . ': ' . lang ( 'No vacation notice text provided. Please enter a message.' );
2016-05-03 21:17:44 +02:00
Framework :: refresh_opener ( $msg , 'mail' );
2015-04-21 13:17:49 +02:00
}
2015-02-06 13:35:51 +01:00
//Set default value for days new entry
2023-12-07 15:34:24 +01:00
if (( string ) $content [ 'days' ] === '' || $content [ 'days' ] < 0 ||
! $content [ 'days' ] && ! in_array ( 'VACATION-SECONDS' , $icServer -> getExtensions ()))
2015-02-06 13:35:51 +01:00
{
$content [ 'days' ] = '3' ;
}
$preserv [ 'is_admin_vac' ] = $content [ 'is_admin_vac' ] = $this -> is_admin_vac ;
2013-10-11 13:43:01 +02:00
}
else
{
2015-02-06 13:35:51 +01:00
$this -> restoreSessionData ();
2019-02-12 22:13:45 +01:00
$button = @ key ( $content [ 'button' ]);
2015-02-06 13:35:51 +01:00
unset ( $content [ 'button' ]);
2013-08-09 19:47:53 +02:00
2015-02-06 13:35:51 +01:00
switch ( $button )
{
case 'save' :
case 'apply' :
if ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ])
2013-10-11 13:43:01 +02:00
{
2015-02-06 13:35:51 +01:00
// store text as default
2015-04-21 13:17:49 +02:00
if ( $content [ 'set_as_default' ] == 1 && $content [ 'text' ])
2015-02-06 13:35:51 +01:00
{
2016-03-28 20:51:38 +02:00
Api\Config :: save_value ( 'default_vacation_text' , $content [ 'text' ], 'mail' );
2015-02-06 13:35:51 +01:00
}
2013-10-11 13:43:01 +02:00
}
2015-02-06 13:35:51 +01:00
if ( isset ( $content [ 'status' ]))
2013-08-09 19:47:53 +02:00
{
2015-02-06 13:35:51 +01:00
//error_log(__METHOD__. 'content:' . array2string($content));
$newVacation = $content ;
if ( empty ( $this -> mailConfig [ 'prefpreventforwarding' ]) ||
$this -> mailConfig [ 'prefpreventforwarding' ] == 0 )
2013-10-11 13:43:01 +02:00
{
2015-07-20 15:00:48 +02:00
$content [ 'forwards' ] = self :: strip_rfc882_addresses ( $content [ 'forwards' ]);
$newVacation [ 'forwards' ] = implode ( ',' , $content [ 'forwards' ]);
2013-10-11 13:43:01 +02:00
}
else
{
2015-02-06 13:35:51 +01:00
unset ( $newVacation [ 'forwards' ]);
2013-10-11 13:43:01 +02:00
}
2013-08-09 19:47:53 +02:00
2015-02-06 13:35:51 +01:00
if ( ! in_array ( $newVacation [ 'status' ], array ( 'on' , 'off' , 'by_date' )))
2014-05-20 10:48:50 +02:00
{
2015-02-06 13:35:51 +01:00
$newVacation [ 'status' ] = 'off' ;
2014-05-20 10:48:50 +02:00
}
2014-05-20 12:14:27 +02:00
2015-02-06 13:35:51 +01:00
$checkAddresses = isset ( $content [ 'check_mail_sent_to' ]) && $content [ 'check_mail_sent_to' ] != 0 ;
if ( $content [ 'addresses' ])
2013-10-11 13:43:01 +02:00
{
2015-07-20 15:00:48 +02:00
$newVacation [ 'addresses' ] = $content [ 'addresses' ] =
self :: strip_rfc882_addresses ( $content [ 'addresses' ]);
2013-10-11 13:43:01 +02:00
}
2015-02-06 13:35:51 +01:00
if ( $this -> checkRule ( $newVacation , $checkAddresses ))
2013-10-11 13:43:01 +02:00
{
2015-02-06 13:35:51 +01:00
if ( isset ( $account_id ) && $this -> mail_admin )
2014-05-21 17:26:12 +02:00
{
2015-02-06 13:35:51 +01:00
$resSetvac = $icServer -> setVacationUser ( $account_id , $newVacation , $this -> scriptName );
}
else
{
$resSetvac = $icServer -> setVacation ( $newVacation );
2014-05-21 17:26:12 +02:00
}
2014-09-24 19:25:18 +02:00
2015-02-06 13:35:51 +01:00
if ( ! $resSetvac )
{
2024-02-01 14:11:49 +01:00
$msg = lang ( 'Vacation notice update failed' ) . " : \n " . $this -> account -> imapServer () -> error ;
if ( ! $content [ 'days' ])
{
$msg .= " \n \n " . lang ( '%1 requires Sieve extension %2, maybe try %1 or higher number of days.' ,
lang ( 'Always respond / auto-responder' ), 'VACATION-SECONDS' , lang ( 'Once per day' ));
}
2015-02-06 13:35:51 +01:00
break ;
}
// schedule job to switch message on/off, if request and not already in past
else
{
if ( $newVacation [ 'status' ] == 'by_date' && $newVacation [ 'end_date' ] + 24 * 3600 > time () ||
$vacRules && $vacRules [ 'vacation' ][ 'status' ] == 'by_date' )
{
self :: setAsyncJob ( $newVacation );
}
//Reset vacationNotice cache which is used in mail_ui get_rows
2016-01-28 11:51:51 +01:00
if ( isset ( $account_id ) && $this -> mail_admin )
{
2016-05-03 21:17:44 +02:00
$account_lid = Api\Accounts :: id2name ( $account_id , 'account_lid' );
2016-03-28 20:51:38 +02:00
$cachedVacations = array ( $icServer -> acc_id => $newVacation ) + ( array ) Api\Cache :: getCache ( Api\Cache :: INSTANCE , 'email' , 'vacationNotice' . $account_lid );
2016-01-28 12:24:24 +01:00
//error_log(__METHOD__.__LINE__.' Setting Cache for '.$account_lid.':'.array2string($cachedVacations));
2016-03-28 20:51:38 +02:00
Api\Cache :: setCache ( Api\Cache :: INSTANCE , 'email' , 'vacationNotice' . $account_lid , $cachedVacations );
2016-01-28 11:51:51 +01:00
}
else
{
2016-03-28 20:51:38 +02:00
$cachedVacations = array ( $icServer -> acc_id => $newVacation ) + ( array ) Api\Cache :: getCache ( Api\Cache :: INSTANCE , 'email' , 'vacationNotice' . $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_lid' ]);
2016-01-28 12:24:24 +01:00
//error_log(__METHOD__.__LINE__.' Setting Cache for own ('.$GLOBALS['egw_info']['user']['account_lid'].'):'.array2string($cachedVacations));
2016-03-28 20:51:38 +02:00
Api\Cache :: setCache ( Api\Cache :: INSTANCE , 'email' , 'vacationNotice' . $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_lid' ], $cachedVacations );
2016-01-28 11:51:51 +01:00
}
2015-02-06 13:35:51 +01:00
$msg = lang ( 'Vacation notice sucessfully updated.' );
}
}
else
{
$msg .= implode ( " \n " , $this -> errorStack );
}
// refresh vacationNotice on index
2016-05-03 21:17:44 +02:00
$response = Api\Json\Response :: get ();
2015-02-06 13:35:51 +01:00
$response -> call ( 'app.mail.mail_callRefreshVacationNotice' , $icServer -> ImapServerId );
2016-05-03 21:17:44 +02:00
Framework :: refresh_opener ( $msg , 'mail' );
2015-02-06 13:35:51 +01:00
if ( $button === 'apply' || $icServer -> error !== " " )
{
break ;
2013-10-11 13:43:01 +02:00
}
2013-08-09 19:47:53 +02:00
}
2014-04-03 14:20:23 +02:00
2015-02-06 13:35:51 +01:00
case 'cancel' :
2016-05-03 21:17:44 +02:00
Framework :: window_close ();
2015-02-06 13:35:51 +01:00
}
2013-10-11 13:43:01 +02:00
}
2014-05-20 12:14:27 +02:00
2015-02-06 13:35:51 +01:00
$sel_options = array (
'status' => array (
'on' => lang ( 'Active' ),
'off' => lang ( 'Deactive' ),
),
'addresses' => array_combine ( $vacRules [ 'aliases' ], $vacRules [ 'aliases' ]),
);
2024-02-01 14:11:49 +01:00
if ( in_array ( 'VACATION-SECONDS' , $icServer -> getExtensions ()))
2023-12-07 15:34:24 +01:00
{
$sel_options [ 'days' ][ '0' ] = lang ( 'Always respond / auto-responder' );
}
for ( $d = 1 ; $d <= 31 ; ++ $d )
{
$sel_options [ 'days' ][( string ) $d ] = $d === 1 ? lang ( 'Once per day' ) : lang ( 'Every %1. day' , $d );
}
2015-02-06 13:35:51 +01:00
if ( ! isset ( $account_id ))
{
$readonlys [ 'acc_id' ] = true ;
}
else
{
$sel_options [ 'acc_id' ] = $allAccounts ;
}
if ( ! empty ( $ByDate ))
{
$sel_options [ 'status' ] += $ByDate ;
}
if ( ! isset ( $GLOBALS [ 'egw_info' ][ 'user' ][ 'apps' ][ 'admin' ]))
{
$content [ 'is_not_admin_user' ] = true ;
$readonlys [ 'set_as_default' ] = true ;
}
$content [ 'msg' ] = $msg ;
2014-06-30 14:03:09 +02:00
}
2013-10-11 13:43:01 +02:00
}
else
{
2015-02-06 13:35:51 +01:00
$content [ 'msg' ] = lang ( 'error' ) . ':' . lang ( 'Serverside Filterrules (Sieve) are not activated' ) . '. ' . lang ( 'Please contact your Administrator to validate if your Server supports Serverside Filterrules, and how to enable them in EGroupware for your active Account (%1) with ID:%2.' , $this -> currentIdentity , $icServer -> ImapServerId );
2013-10-11 13:43:01 +02:00
$content [ 'hideIfSieveDisabled' ] = 'mail_DisplayNone' ;
}
2014-05-20 10:48:50 +02:00
$vtmpl -> exec ( 'mail.mail_sieve.editVacation' , $content , $sel_options , $readonlys , $preserv , 2 );
2013-08-09 19:47:53 +02:00
}
2015-07-20 15:00:48 +02:00
/**
2016-10-08 14:32:58 +02:00
* Strip personal part from rfc822 addresses : " Ralf Becker <rb@egroupware.org> " --> rb @ egroupware . org
2015-07-20 15:00:48 +02:00
*
* Sieve only allows email - addresses , without angle brakets and personal parts .
*
* @ param array | string $_addresses
* @ return array of email - addresses without personal part
*/
static function strip_rfc882_addresses ( $_addresses )
{
$addresses = array ();
2016-03-28 20:51:38 +02:00
foreach ( Mail :: parseAddressList ( $_addresses ) as $addr )
2015-07-20 15:00:48 +02:00
{
if ( $addr -> valid )
{
$addresses [] = $addr -> mailbox . '@' . $addr -> host ;
}
}
return $addresses ;
}
2014-05-21 10:08:02 +02:00
/**
* set the asyncjob for a timed vacation
*
* @ param array $_vacation vacation to set / unset with values for 'account_id' , 'acc_id' and vacation stuff
* @ param boolean $_reschedule do nothing but reschedule the job by 3 minutes
* @ return void
*/
static function setAsyncJob ( array $_vacation , $_reschedule = false )
{
if ( ! ( $_vacation [ 'acc_id' ] > 0 ))
{
2016-05-03 21:17:44 +02:00
throw new Api\Exception\WrongParameter ( 'No acc_id given!' );
2014-05-21 10:08:02 +02:00
}
// setting up an async job to enable/disable the vacation message
2016-05-09 11:15:48 +02:00
$async = new Api\Asyncservice ();
2014-05-21 10:08:02 +02:00
if ( empty ( $_vacation [ 'account_id' ])) $_vacation [ 'account_id' ] = $GLOBALS [ 'egw_info' ][ 'user' ][ 'account_id' ];
$async_id = ! empty ( $_vacation [ 'id' ]) ? $_vacation [ 'id' ] : 'mail-vacation-' . $_vacation [ 'account_id' ];
$async -> delete ( $async_id );
$end_date = $_vacation [ 'end_date' ] + 24 * 3600 ; // end-date is inclusive, so we have to add 24h
2014-07-22 14:52:10 +02:00
if ( $_vacation [ 'status' ] == 'by_date' && time () < $end_date && ! $_reschedule )
2014-05-21 10:08:02 +02:00
{
$time = time () < $_vacation [ 'start_date' ] ? $_vacation [ 'start_date' ] : $end_date ;
$async -> set_timer ( $time , $async_id , 'mail_sieve::async_vacation' , $_vacation , $_vacation [ 'account_id' ]);
}
if ( $_reschedule )
{
2014-07-22 14:52:10 +02:00
$_vacation [ 'rescheduled' ] = $_vacation [ 'rescheduled' ] ? 2 * $_vacation [ 'rescheduled' ] : 5 ;
// only try to reschedule for 2 days max
if ( $_vacation [ 'rescheduled' ] <= 2 * 24 * 60 )
{
$time = time () + 60 * ( $_vacation [ 'rescheduled' ]);
unset ( $_vacation [ 'next' ]);
unset ( $_vacation [ 'times' ]);
$async -> set_timer ( $time , $async_id , 'mail_sieve::async_vacation' , $_vacation , $_vacation [ 'account_id' ]);
}
2014-05-21 10:08:02 +02:00
}
}
/**
* Callback for the async job to enable / disable the vacation message
*
* @ param array $_vacation
2016-05-03 21:17:44 +02:00
* @ throws Api\Exception\NotFound if mail account is not found
2014-05-21 10:08:02 +02:00
*/
static function async_vacation ( array $_vacation )
{
2014-05-21 14:23:09 +02:00
//error_log(__METHOD__.'('.array2string($_vacation).')');
2014-05-21 10:08:02 +02:00
2016-03-28 20:51:38 +02:00
$account = Mail\Account :: read ( $_vacation [ 'acc_id' ], $_vacation [ 'account_id' ]);
2014-05-21 10:08:02 +02:00
$icServer = $account -> imapServer ( $_vacation [ 'account_id' ]);
2014-05-21 14:23:09 +02:00
//error_log(__METHOD__.'() imap username='.$icServer->acc_imap_username);
2014-05-21 10:08:02 +02:00
try
{
2015-01-20 15:28:46 +01:00
$ret = $icServer -> setVacationUser ( $_vacation [ 'account_id' ], $_vacation );
2014-05-21 10:08:02 +02:00
self :: setAsyncJob ( $_vacation );
}
2014-07-22 14:52:10 +02:00
// if mail account no longer exists --> remove async job
2016-05-03 21:17:44 +02:00
catch ( Api\Exception\NotFound $e )
2014-07-22 14:52:10 +02:00
{
$_vacation [ 'status' ] = 'off' ;
self :: setAsyncJob ( $_vacation );
}
2014-05-21 10:08:02 +02:00
catch ( Exception $e ) {
error_log ( __METHOD__ . '(' . array2string ( $_vacation ) . ' failed ' . $e -> getMessage ());
self :: setAsyncJob ( $_vacation , true ); // reschedule
$ret = false ;
}
return $ret ;
}
2013-08-09 19:47:53 +02:00
/**
* Checking vaction validation
*
2014-02-14 16:39:18 +01:00
* @ param { array } $_vacation
* @ param { boolean } $_checkAddresses
*
2013-08-09 19:47:53 +02:00
* @ return boolean
*/
function checkRule ( $_vacation , $_checkAddresses = true )
{
$this -> errorStack = array ();
if ( ! $_vacation [ 'text' ])
2013-07-25 17:48:18 +02:00
{
2013-08-09 19:47:53 +02:00
$this -> errorStack [ 'text' ] = lang ( 'Please supply the message to send with auto-responses' ) . '! ' ;
2013-07-25 17:48:18 +02:00
}
2013-08-09 19:47:53 +02:00
2023-12-07 15:34:24 +01:00
if (( string ) $_vacation [ 'days' ] === '' || $_vacation [ 'days' ] < 0 )
2013-07-25 17:48:18 +02:00
{
2013-08-09 19:47:53 +02:00
$this -> errorStack [ 'days' ] = lang ( 'Please select the number of days to wait between responses' ) . '!' ;
2013-07-25 17:48:18 +02:00
}
2013-08-09 19:47:53 +02:00
2014-05-13 10:51:03 +02:00
if ( is_array ( $_vacation [ 'addresses' ]) && ! empty ( $_vacation [ 'addresses' ]))
2013-07-25 17:48:18 +02:00
{
2013-08-09 19:47:53 +02:00
$regexp = " /^[a-z0-9]+([_ \\ .-][a-z0-9]+)*@([a-z0-9]+([ \ .-][a-z0-9]+)*)+ \\ .[a-z] { 2,} $ /i " ;
foreach ( $_vacation [ 'addresses' ] as $addr )
{
if ( ! preg_match ( $regexp , $addr ) && $_checkAddresses )
{
$this -> errorStack [ 'addresses' ] = lang ( 'One address is not valid' ) . '!' ;
}
}
2013-07-25 17:48:18 +02:00
}
else
{
2013-08-09 19:47:53 +02:00
$this -> errorStack [ 'addresses' ] = lang ( 'Please select a address' ) . '!' ;
2013-07-25 17:48:18 +02:00
}
2013-08-09 19:47:53 +02:00
if ( $_vacation [ 'status' ] == 'by_date' )
2013-07-25 17:48:18 +02:00
{
2013-08-09 19:47:53 +02:00
if ( ! $_vacation [ 'start_date' ] || ! $_vacation [ 'end_date' ])
{
$this -> errorStack [ 'status' ] = lang ( 'Activating by date requires a start- AND end-date!' );
}
elseif ( $_vacation [ 'start_date' ] > $_vacation [ 'end_date' ])
{
$this -> errorStack [ 'status' ] = lang ( 'Vacation start-date must be BEFORE the end-date!' );
}
2013-07-25 17:48:18 +02:00
}
2013-08-09 19:47:53 +02:00
if ( $_vacation [ 'forwards' ])
2013-07-25 17:48:18 +02:00
{
2013-08-09 19:47:53 +02:00
foreach ( preg_split ( '/, ?/' , $_vacation [ 'forwards' ]) as $addr )
{
if ( ! preg_match ( $regexp , $addr ) && $_checkAddresses )
{
$this -> errorStack [ 'forwards' ] = lang ( 'One address is not valid' . '!' );
}
}
2013-07-25 17:48:18 +02:00
}
2014-02-14 16:39:18 +01:00
//error_log(__METHOD__. array2string($this->errorStack));
2013-08-09 19:47:53 +02:00
if ( count ( $this -> errorStack ) == 0 )
2013-07-25 17:48:18 +02:00
{
2013-08-09 19:47:53 +02:00
return true ;
2013-07-25 17:48:18 +02:00
}
else
{
2013-08-09 19:47:53 +02:00
$this -> errorStack [ 'message' ] = lang ( 'Vacation notice is not saved yet! (But we filled in some defaults to cover some of the above errors. Please correct and check your settings and save again.)' );
return false ;
2013-07-25 17:48:18 +02:00
}
}
/**
* Move rule to an other position in list
*
2014-02-14 16:39:18 +01:00
* @ param { array } $orders
2013-07-25 17:48:18 +02:00
*/
2020-11-04 23:15:31 +01:00
function ajax_moveRule ( $exec_id , $orders )
2013-07-25 17:48:18 +02:00
{
2013-08-09 19:47:53 +02:00
2014-05-13 09:54:42 +02:00
foreach ( $orders as $keys => $val )
{
2014-05-14 10:32:11 +02:00
$orders [ $keys ] = $val - 1 ;
2014-05-13 09:54:42 +02:00
}
2014-05-20 12:14:27 +02:00
2013-07-25 17:48:18 +02:00
$this -> getRules ( null );
$newrules = $this -> rules ;
2014-05-13 09:54:42 +02:00
2013-07-25 17:48:18 +02:00
foreach ( $orders as $keys => $ruleID )
{
$newrules [ $keys ] = $this -> rules [ $ruleID ];
}
2013-08-09 19:47:53 +02:00
$this -> rules = $newrules ;
2013-07-25 17:48:18 +02:00
$this -> updateScript ();
$this -> saveSessionData ();
2013-08-09 19:47:53 +02:00
//Calling to referesh after move action
2016-05-03 21:17:44 +02:00
$response = Api\Json\Response :: get ();
2014-05-13 09:54:42 +02:00
$response -> call ( 'app.mail.sieve_refresh' );
2013-08-09 19:47:53 +02:00
}
/**
* Ajax function to handle actions over sieve rules list on gd
2013-07-25 17:48:18 +02:00
*
2014-05-22 16:46:50 +02:00
* @ param string $action name of action
* @ param string $checked the selected rule id
* @ param string $msg containing the message comming from the client - side
2014-02-14 16:39:18 +01:00
*
2013-07-25 17:48:18 +02:00
*/
2014-05-22 16:46:50 +02:00
function ajax_action ( $action , $checked , $msg )
2013-07-25 17:48:18 +02:00
{
2013-08-09 19:47:53 +02:00
$this -> getRules ( null );
2013-07-25 17:48:18 +02:00
switch ( $action )
{
case 'delete' :
2013-08-09 19:47:53 +02:00
if ( $checked === count ( $this -> rules ) - 1 )
{
$msg = lang ( 'rule with priority ' ) . $checked . lang ( ' deleted!' );
2014-05-21 17:26:12 +02:00
}
else
2013-08-09 19:47:53 +02:00
{
$msg = lang ( 'rule with priority ' ) . $checked . lang ( ' deleted!' ) . lang ( ' And the rule with priority %1, now got the priority %2' , $checked + 1 , $checked );
}
2013-07-25 17:48:18 +02:00
unset ( $this -> rules [ $checked ]);
$this -> rules = array_values ( $this -> rules );
break ;
case 'enable' :
2013-08-09 19:47:53 +02:00
$msg = lang ( 'rule with priority ' ) . $checked . lang ( ' enabled!' );
2021-10-14 15:37:52 +02:00
$this -> rules [ $checked ][ 'status' ] = 'ENABLED' ;
2013-07-25 17:48:18 +02:00
break ;
case 'disable' :
2013-08-09 19:47:53 +02:00
$msg = lang ( 'rule with priority ' ) . $checked . lang ( ' disabled!' );
2021-10-14 15:37:52 +02:00
$this -> rules [ $checked ][ 'status' ] = 'DISABLED' ;
2013-07-25 17:48:18 +02:00
break ;
2013-08-09 19:47:53 +02:00
case 'move' :
break ;
2013-07-25 17:48:18 +02:00
}
2013-08-09 19:47:53 +02:00
2014-02-13 20:00:11 +01:00
ob_start ();
$result = $this -> updateScript ();
2014-05-23 11:21:59 +02:00
2016-05-03 21:17:44 +02:00
$response = Api\Json\Response :: get ();
2014-05-23 11:21:59 +02:00
2014-02-13 20:00:11 +01:00
if ( $result )
{
2018-06-15 15:49:34 +02:00
$response -> message ( $result );
2014-02-13 20:00:11 +01:00
return ;
}
2013-07-25 17:48:18 +02:00
$this -> saveSessionData ();
2014-05-22 16:46:50 +02:00
$response -> call ( 'app.mail.sieve_refresh' );
2013-08-09 19:47:53 +02:00
}
2013-07-25 17:48:18 +02:00
/**
2013-08-09 19:47:53 +02:00
* Convert an script seive format rule to human readable format
2013-07-25 17:48:18 +02:00
*
2014-02-14 16:39:18 +01:00
* @ param { array } $rule Array of rules
* @ return { string } return the rule as a string .
2013-07-25 17:48:18 +02:00
*/
function buildRule ( $rule )
{
$andor = ' ' . lang ( 'and' ) . ' ' ;
$started = 0 ;
2014-05-13 09:54:42 +02:00
if ( $rule [ 'anyof' ])
{
$andor = ' ' . lang ( 'or' ) . ' ' ;
}
2013-07-25 17:48:18 +02:00
$complete = lang ( 'IF' ) . ' ' ;
2014-05-13 09:54:42 +02:00
if ( $rule [ 'unconditional' ])
{
$complete = " [Unconditional] " ;
}
2013-07-25 17:48:18 +02:00
if ( $rule [ 'from' ])
{
$match = $this -> setMatchType ( $rule [ 'from' ], $rule [ 'regexp' ]);
$complete .= " 'From:' " . $match . " ' " . $rule [ 'from' ] . " ' " ;
$started = 1 ;
}
if ( $rule [ 'to' ])
{
2014-05-13 09:54:42 +02:00
if ( $started )
{
$complete .= $andor ;
}
2013-07-25 17:48:18 +02:00
$match = $this -> setMatchType ( $rule [ 'to' ], $rule [ 'regexp' ]);
$complete .= " 'To:' " . $match . " ' " . $rule [ 'to' ] . " ' " ;
$started = 1 ;
}
if ( $rule [ 'subject' ])
{
2014-05-13 09:54:42 +02:00
if ( $started )
{
$complete .= $andor ;
}
2013-07-25 17:48:18 +02:00
$match = $this -> setMatchType ( $rule [ 'subject' ], $rule [ 'regexp' ]);
$complete .= " 'Subject:' " . $match . " ' " . $rule [ 'subject' ] . " ' " ;
$started = 1 ;
}
if ( $rule [ 'field' ] && $rule [ 'field_val' ])
{
2014-05-13 09:54:42 +02:00
if ( $started )
{
$complete .= $andor ;
}
2013-07-25 17:48:18 +02:00
$match = $this -> setMatchType ( $rule [ 'field_val' ], $rule [ 'regexp' ]);
$complete .= " ' " . $rule [ 'field' ] . " ' " . $match . " ' " . $rule [ 'field_val' ] . " ' " ;
$started = 1 ;
}
if ( $rule [ 'size' ])
{
$xthan = " less than ' " ;
2014-05-13 09:54:42 +02:00
if ( $rule [ 'gthan' ])
{
$xthan = " greater than ' " ;
}
if ( $started )
{
$complete .= $andor ;
}
2013-07-25 17:48:18 +02:00
$complete .= " message " . $xthan . $rule [ 'size' ] . " KB' " ;
}
2013-10-11 09:58:37 +02:00
if ( ! empty ( $rule [ 'field_bodytransform' ]))
2013-08-09 19:47:53 +02:00
{
$btransform = " :raw " ;
$match = ' :contains' ;
2014-05-13 09:54:42 +02:00
if ( $rule [ 'bodytransform' ])
{
$btransform = " :text " ;
}
if ( preg_match ( " / \ *| \ ?/ " , $rule [ 'field_bodytransform' ]))
{
$match = ':matches' ;
}
if ( $rule [ 'regexp' ])
{
$match = ':regex' ;
}
2013-08-09 19:47:53 +02:00
$complete .= " body " . $btransform . $match . " \" " . $rule [ 'field_bodytransform' ] . " \" " ;
}
2013-10-11 09:58:37 +02:00
if ( $rule [ 'ctype' ] != '0' && ! empty ( $rule [ 'ctype' ]))
2013-08-09 19:47:53 +02:00
{
2016-03-28 20:51:38 +02:00
$btransform_ctype = Mail\Script :: $btransform_ctype_array [ $rule [ 'ctype' ]];
2013-08-09 19:47:53 +02:00
$ctype_subtype = " " ;
2014-05-13 09:54:42 +02:00
if ( $rule [ 'field_ctype_val' ])
{
$ctype_subtype = " / " ;
}
2013-08-09 19:47:53 +02:00
$complete .= " body :content " . " \" " . $btransform_ctype . $ctype_subtype . $rule [ 'field_ctype_val' ] . " \" " . " :contains \" \" " ;
2016-03-28 20:51:38 +02:00
//error_log(__CLASS__."::".__METHOD__.array2string(Mail\Script::$btransform_ctype_array));
2013-08-09 19:47:53 +02:00
}
2014-05-13 09:54:42 +02:00
if ( ! $rule [ 'unconditional' ])
{
$complete .= ' ' . lang ( 'THEN' ) . ' ' ;
}
2013-07-25 17:48:18 +02:00
if ( preg_match ( " /folder/i " , $rule [ 'action' ]))
2014-05-13 09:54:42 +02:00
{
2013-07-25 17:48:18 +02:00
$complete .= lang ( 'file into' ) . " ' " . $rule [ 'action_arg' ] . " '; " ;
2014-05-13 09:54:42 +02:00
}
2013-07-25 17:48:18 +02:00
if ( preg_match ( " /reject/i " , $rule [ 'action' ]))
2014-05-13 09:54:42 +02:00
{
2013-07-25 17:48:18 +02:00
$complete .= lang ( 'reject with' ) . " ' " . $rule [ 'action_arg' ] . " '. " ;
2014-05-13 09:54:42 +02:00
}
2013-07-25 17:48:18 +02:00
if ( preg_match ( " /address/i " , $rule [ 'action' ]))
2014-05-13 09:54:42 +02:00
{
2013-07-25 17:48:18 +02:00
$complete .= lang ( 'forward to' ) . ' ' . $rule [ 'action_arg' ] . '.' ;
2014-05-13 09:54:42 +02:00
}
2013-07-25 17:48:18 +02:00
if ( preg_match ( " /discard/i " , $rule [ 'action' ]))
2014-05-13 09:54:42 +02:00
{
2013-07-25 17:48:18 +02:00
$complete .= lang ( 'discard' ) . '.' ;
2014-05-13 09:54:42 +02:00
}
if ( $rule [ 'continue' ])
{
$complete .= " [Continue] " ;
}
if ( $rule [ 'keep' ])
{
$complete .= " [Keep a copy] " ;
}
2013-07-25 17:48:18 +02:00
return $complete ;
}
/**
2014-02-14 16:39:18 +01:00
* Helper function to find the type of content
2013-07-25 17:48:18 +02:00
*
2014-02-14 16:39:18 +01:00
* @ param { string } $matchstr string that should be compared
* @ param { string } $regex regular expresion as pattern to be matched
* @ return { string } return the type
2013-07-25 17:48:18 +02:00
*/
function setMatchType ( & $matchstr , $regex = false )
{
$match = lang ( 'contains' );
2014-03-13 14:16:09 +01:00
if ( preg_match ( " /^ \ s*!/ " , $matchstr ))
2014-05-13 09:54:42 +02:00
{
$match = lang ( 'does not contain' );
}
if ( preg_match ( " / \ *| \ ?/ " , $matchstr ))
{
$match = lang ( 'matches' );
if ( preg_match ( " /^ \ s*!/ " , $matchstr ))
2014-03-13 14:16:09 +01:00
{
2014-05-13 09:54:42 +02:00
$match = lang ( 'does not match' );
2014-03-13 14:16:09 +01:00
}
2014-05-13 09:54:42 +02:00
}
if ( $regex )
2013-07-25 17:48:18 +02:00
{
2014-05-13 09:54:42 +02:00
$match = lang ( 'matches regexp' );
if ( preg_match ( " /^ \ s*!/ " , $matchstr ))
2013-07-25 17:48:18 +02:00
{
2014-05-13 09:54:42 +02:00
$match = lang ( 'does not match regexp' );
2013-07-25 17:48:18 +02:00
}
}
2014-05-13 09:54:42 +02:00
if ( $regex && preg_match ( " /^ \ s* \\ \\ !/ " , $matchstr ))
{
$matchstr = preg_replace ( " /^ \ s* \\ \\ !/ " , " ! " , $matchstr );
}
else
{
$matchstr = preg_replace ( " /^ \ s*!/ " , " " , $matchstr );
}
return $match ;
2013-07-25 17:48:18 +02:00
}
/**
2013-08-09 19:47:53 +02:00
* Save session data
2013-07-25 17:48:18 +02:00
*/
function saveSessionData ()
{
$sessionData [ 'sieve_rules' ] = $this -> rules ;
$sessionData [ 'sieve_rulesByID' ] = $this -> rulesByID ;
$sessionData [ 'sieve_scriptToEdit' ] = $this -> scriptToEdit ;
2016-07-07 10:21:37 +02:00
Api\Cache :: setSession ( __CLASS__ , 'sieve_session_data' , $sessionData );
2013-07-25 17:48:18 +02:00
}
/**
2013-08-09 19:47:53 +02:00
* Update the sieve script on mail server
2013-07-25 17:48:18 +02:00
*/
function updateScript ()
{
2014-05-21 17:26:12 +02:00
if ( ! $this -> account -> imapServer () -> setRules ( $this -> rules ))
2013-07-25 17:48:18 +02:00
{
2018-06-15 15:49:34 +02:00
return $this -> account -> imapServer () -> error ;
2013-07-25 17:48:18 +02:00
}
}
/**
* Fetched rules save on array () rules .
*
2014-02-14 16:39:18 +01:00
* @ param { string } $ruleID Numeric Id of the rule if specify return the specitic rule | otherwise ruleByID would be null
*
* @ return { boolean } returns false in case of failure and true in case of success .
2013-07-25 17:48:18 +02:00
*/
2014-02-14 16:39:18 +01:00
function getRules ( $ruleID = null )
2013-07-25 17:48:18 +02:00
{
2016-01-28 10:52:05 +01:00
try {
$this -> account -> imapServer () -> retrieveRules ();
2014-05-20 19:22:52 +02:00
$this -> rules = $this -> account -> imapServer () -> getRules ();
$this -> rulesByID = $this -> rules [ $ruleID ];
$this -> vacation = $this -> account -> imapServer () -> getVacation ();
2013-07-25 17:48:18 +02:00
}
2016-01-28 10:52:05 +01:00
catch ( Exception $e ) {
error_log ( __METHOD__ . __LINE__ . $e -> getMessage () . ': ' . $e -> details );
$this -> rules = array ();
$this -> rulesByID = array ();
$this -> vacation = array ();
return false ;
}
2014-05-20 19:22:52 +02:00
return true ;
2013-07-25 17:48:18 +02:00
}
/**
2013-08-09 19:47:53 +02:00
* Restore session data
2013-07-25 17:48:18 +02:00
*/
function restoreSessionData ()
{
2016-07-07 10:21:37 +02:00
$sessionData = Api\Cache :: getSession ( __CLASS__ , 'sieve_session_data' );
2013-07-25 17:48:18 +02:00
$this -> rules = $sessionData [ 'sieve_rules' ];
$this -> rulesByID = $sessionData [ 'sieve_rulesByID' ];
$this -> scriptToEdit = $sessionData [ 'sieve_scriptToEdit' ];
}
/**
2014-02-14 16:39:18 +01:00
*
2013-08-09 19:47:53 +02:00
* Get the data for iterating the rows on rules list grid
2014-05-14 14:04:02 +02:00
*
2014-02-14 16:39:18 +01:00
* @ return { boolean | array } Array of rows | false if failed
2013-07-25 17:48:18 +02:00
*/
2014-05-14 14:04:02 +02:00
function get_rows ()
2013-07-25 17:48:18 +02:00
{
$rows = array ();
2014-05-14 14:04:02 +02:00
$this -> getRules ( null );
2013-07-25 17:48:18 +02:00
if ( is_array ( $this -> rules ) && ! empty ( $this -> rules ) )
{
$rows = $this -> rules ;
foreach ( $rows as & $row )
{
$row [ 'rules' ] = $this -> buildRule ( $row );
$row [ 'ruleID' ] = ( string )(( $row [ 'priority' ] - 1 ) / 2 );
2014-02-14 17:56:48 +01:00
if ( $row [ 'status' ] === 'DISABLED' )
2013-07-25 17:48:18 +02:00
{
2014-02-14 17:56:48 +01:00
$row [ 'class' ] = 'mail_sieve_DISABLED' ;
2013-07-25 17:48:18 +02:00
}
2014-02-14 17:56:48 +01:00
}
2014-05-21 17:26:12 +02:00
}
else
2013-07-25 17:48:18 +02:00
{
//error_log(__METHOD__.'There are no rules or something is went wrong at getRules()!');
2014-02-14 16:39:18 +01:00
return false ;
2013-07-25 17:48:18 +02:00
}
2014-02-14 16:39:18 +01:00
// Shift one down, because in grid the first row is reserved for header
2013-07-25 17:48:18 +02:00
array_unshift ( $rows , array ( '' => '' ));
return $rows ;
}
/**
* Get actions / context menu for index
*
2014-02-14 16:39:18 +01:00
* @ return { array } returns defined actions as an array
2013-07-25 17:48:18 +02:00
*/
2014-02-14 17:56:48 +01:00
private function get_actions ()
2013-07-25 17:48:18 +02:00
{
$actions = array (
'edit' => array (
'caption' => 'Edit' ,
'default' => true ,
2014-02-14 17:56:48 +01:00
'onExecute' => 'javaScript:app.mail.action' ,
'disableClass' => 'th'
2013-07-25 17:48:18 +02:00
),
'add' => array (
'caption' => 'Add' ,
'onExecute' => 'javaScript:app.mail.action'
),
'enable' => array (
'caption' => 'Enable' ,
'onExecute' => 'javaScript:app.mail.action' ,
2014-02-14 17:56:48 +01:00
'enableClass' => 'mail_sieve_DISABLED' ,
'hideOnDisabled' => true
2013-07-25 17:48:18 +02:00
),
'disable' => array (
'caption' => 'Disable' ,
'onExecute' => 'javaScript:app.mail.action' ,
2014-02-14 17:56:48 +01:00
'disableClass' => 'mail_sieve_DISABLED' ,
'hideOnDisabled' => true
2013-07-25 17:48:18 +02:00
),
'delete' => array (
'caption' => 'Delete' ,
'onExecute' => 'javaScript:app.mail.action'
),
);
return $actions ;
}
2015-01-19 13:12:18 +01:00
/**
* Callback function to get mail folders
* int $_searchStringLength
* @ param boolean $_returnList
* @ param int $_mailaccountToSearch
* @ param boolean $_noPrefixID = false , if set to true folders name does not get prefixed by account id
*/
function ajax_getFolders ( $_searchStringLength = 2 , $_returnList = false , $_mailaccountToSearch = null , $_noPrefixId = false )
{
$mailCompose = new mail_compose ();
2015-07-20 15:00:48 +02:00
if ( $_REQUEST [ 'noPrefixId' ]) $_noPrefixId = $_REQUEST [ 'noPrefixId' ];
$mailCompose -> ajax_searchFolder ( $_searchStringLength , $_returnList , $_mailaccountToSearch , $_noPrefixId );
2015-01-19 13:12:18 +01:00
}
2022-08-08 17:27:21 +02:00
}