* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @version $Id$ */ class mail_sieve { var $public_functions = array( 'editVacation' => True, 'index' => True, 'edit' => True, 'editEmailNotification'=> True, // Added email notifications ); var $errorStack; /** * Current Identitiy * * @var String */ var $currentIdentity; /** * user has admin right to emailadmin * * @var boolean */ var $mail_admin = false; /** * account object * * @var emailadmin_account */ var $account; /** * flag to check if vacation is called from admin * * @var boolean */ var $is_admin_vac = false; /** * siteConfigs * * @var array */ var $mailConfig = array(); /** * Constructor */ function __construct() { $this->displayCharset = translation::charset(); $this->mail_admin = isset($GLOBALS['egw_info']['user']['apps']['emailadmin']); $this->mailConfig = config::read('mail'); $acc_id = isset($_GET['acc_id']) ? (int)$_GET['acc_id'] : egw_cache::getSession(__CLASS__, 'acc_id'); if ($acc_id > 0) { $this->account = emailadmin_account::read($acc_id); } $this->restoreSessionData(); } /** * Sieve rules list * * @param {array} $content * @param {string} $msg */ function index(array $content=null,$msg=null) { if (!is_array($content)) { egw_cache::setSession(__CLASS__, 'acc_id', $this->account->acc_id); } //Instantiate an etemplate_new object $tmpl = new etemplate_new('mail.sieve.index'); if ($msg) { $content['msg'] = $msg; } if ($this->account->acc_sieve_enabled) { //Initializes the Grid contents $content['rg']= $this->get_rows(); // Set content-menu actions $tmpl->set_cell_attribute('rg', 'actions',$this->get_actions()); $sel_options = array( 'status' => array( 'ENABLED' => lang('Enabled'), 'DISABLED' => lang('Disabled'), ) ); } else { $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['identity_string'],$this->mailbo->profileID); $content['hideIfSieveDisabled']='mail_DisplayNone'; } $tmpl->exec('mail.mail_sieve.index',$content,$sel_options,array()); } /** * Email Notification Edit * * * @param {array} $content * @param {string} $msg */ function editEmailNotification($content=null, $msg='') { //Instantiate an etemplate_new object, representing sieve.emailNotification $eNotitmpl = new etemplate_new('mail.sieve.emailNotification'); if ($this->account->acc_sieve_enabled) { $eNotification = $this->getEmailNotification(); if (!is_array($content)) { $content = $eNotification; if (!empty($eNotification['externalEmail'])) { $content['externalEmail'] = explode(",",$eNotification['externalEmail']); } } else { $this->restoreSessionData(); list($button) = @each($content['button']); unset ($content['button']); switch($button) { case 'save': case 'apply': if (isset($content['status'])) { $newEmailNotification = $content; if (empty($this->mailConfig['prefpreventforwarding']) || $this->mailConfig['prefpreventforwarding'] == 0 ) { if (is_array($content['externalEmail']) && !empty($content['externalEmail'])) { $newEmailNotification['externalEmail'] = implode(",",$content['externalEmail']); } } } if (isset($content['externalEmail']) && !empty($content['externalEmail'])) { if (!$this->account->imapServer()->setEmailNotification($newEmailNotification)) { $msg = lang("email notification update failed")."
"; break; } else { $msg .= lang("email notification successfully updated!"); } } else { $msg .= lang('email notification update failed! You need to set an email address!'); break; } egw_framework::refresh_opener($msg, 'mail'); if ($button === 'apply') { break; } case 'cancel': egw_framework::window_close(); common::egw_exit(); } $this->saveSessionData(); } $sel_options = array( 'status' => array( 'on' => lang('Active'), 'off' => lang('Deactive'), ), 'displaySubject' => array( 0 => lang('No'), 1 => lang('Yes'), ), ); $content['msg'] = $msg; } else { $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['identity_string'],$this->mailbo->profileID); $content['hideIfSieveDisabled']='mail_DisplayNone'; } $eNotitmpl->exec('mail.mail_sieve.editEmailNotification', $content,$sel_options); } /** * Sieve rules edit * * @param {array} $content */ function edit ($content=null) { //Instantiate an etemplate_new object, representing sieve.edit template $etmpl = new etemplate_new('mail.sieve.edit'); if (!is_array($content)) { if ( $this->getRules($_GET['ruleID']) && isset($_GET['ruleID'])) { $rules = $this->rulesByID; $content= $rules; switch ($rules['action']) { case 'folder': $content['action_folder_text'][] = translation::convert($rules['action_arg'],'utf-8','utf7-imap'); break; case 'address': $content['action_address_text'][] = $rules['action_arg']; break; case 'reject': $content['action_reject_text'] = $rules['action_arg']; } } else // Adding new rule { $this->getRules(null); $newRulePriority = count($this->rules)*2+1; $newRules ['priority'] = $newRulePriority; $newRules ['status'] = 'ENABLED'; $readonlys = array( 'button[delete]' => 'true', ); $this->rulesByID = $newRules; $content = $this->rulesByID; } $this->saveSessionData(); } else { $this->restoreSessionData(); list($button) = @each($content['button']); //$ruleID is calculated by priority from the selected rule and is an unique ID $ruleID = ($this->rulesByID['priority'] -1) / 2; $error = 0; switch ($button) { case 'save': case 'apply': if($content) { unset($content['button']); $newRule = $content; $newRule['priority'] = $this->rulesByID['priority']; $newRule['status'] = $this->rulesByID['status']; switch ($content['action']) { case 'folder': $newRule['action_arg'] = translation::convert(implode($content['action_folder_text']), 'utf7-imap', 'utf-8'); break; case 'address': $newRule['action_arg'] = implode($content['action_address_text']); //error_log(__METHOD__. '() newRules_address '. array2string($newRule['action_arg'])); break; case 'reject': $newRule['action_arg'] = $content['action_reject_text']; } unset($newRule['action_folder_text']); unset($newRule['action_address_text']); unset($newRule['action_reject_text']); $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; } if($newRule['action'] && $this->rulesByID['priority']) { $this->rules[$ruleID] = $newRule; $ret = $this->account->imapServer()->setRules($this->rules); if (!$ret && !empty($this->account->imapServer()->error)) { $msg .= lang("Saving the rule failed:")."
".$this->account->imapServer()->error."
"; } else { $msg .= lang("The rule with priority %1 successfully saved!",$ruleID); } $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++; } egw_framework::refresh_opener($msg, 'mail', 'sieve'); if ($button == "apply") { break; } //fall through case 'delete': if ($button == "delete") { 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); $this->updateScript(); } egw_framework::refresh_opener($msg, 'mail', 'sieve'); case 'cancel': egw_framework::window_close(); common::egw_exit(); } } $sel_options = array(//array_merge($sel_options,array( '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', ), 'ctype' => emailadmin_script::$btransform_ctype_array, ); //Set the preselect_options for mail/folders as we are not allow free entry for folder taglist $mailCompose = new mail_compose(); $sel_options['action_folder_text'] = $mailCompose->ajax_searchFolder(0,true); return $etmpl->exec('mail.mail_sieve.edit',$content,$sel_options,$readonlys,array(),2); } /** * Read email notification script from the sieve script from server * * * @return type, returns array of email notification data, and in case of failure returns false * @todo Need to be checked if it is still needed */ function getEmailNotification() { if(!(empty($this->mailConfig['prefpreventnotificationformailviaemail']) || $this->mailConfig['prefpreventnotificationformailviaemail'] == 0)) { throw new egw_exception_no_permission(); } if(PEAR::isError($error = $this->account->imapServer()->retrieveRules()) ) { $rules = array(); $emailNotification = array(); } else { $rules = $this->account->imapServer()->getRules(); $emailNotification = $this->account->imapServer()->getEmailNotification(); } return $emailNotification; } /** * Fetch Vacation rules and predefined Addresses from mailserver * * @param string $accountID * * @return array return multi-dimentional array of vacation and aliases */ function getVacation($accountID = null) { if(!(empty($this->mailConfig['prefpreventabsentnotice']) || $this->mailConfig['prefpreventabsentnotice'] == 0)) { throw new egw_exception_no_permission(); } try { if ($this->is_admin_vac) { $icServer = $this->account->imapServer($accountID); $vacation = $icServer->getVacationUser($accountID); } else { $icServer = $this->account->imapServer(); $icServer->retrieveRules(null); $vacation = $icServer->getVacation(); } } catch(Exception $e) { egw_framework::window_close(lang($e->getMessage())); } if (is_null($accountID)) $accountID = $GLOBALS['egw_info']['user']['account_id']; $accAllIdentities = $this->account->smtpServer()->getAccountEmailAddress(accounts::id2name($accountID)); $allAliases = array($this->account->ident_email); foreach ($accAllIdentities as &$arrVal) { if ($arrVal['type'] !='default') { $allAliases[] = $arrVal['address']; } } asort($allAliases); return array( 'vacation' =>$vacation, 'aliases' => array_values($allAliases), ); } /** * Vacation edit * * @param {array} $content * @param {string} $msg */ function editVacation($content=null, $msg='') { //Instantiate an etemplate_new object, representing the sieve.vacation template $vtmpl = new etemplate_new('mail.sieve.vacation'); $vacation = array(); if (isset($_GET['account_id'])) $account_id = $preserv['account_id'] = $_GET['account_id']; if (isset($content['account_id'])) { $account_id = $content['account_id']; $preserv['acc_id'] = $content['acc_id']; } if(isset($account_id) && $this->mail_admin) { foreach(emailadmin_account::search($account_id, false, null, false, 0, false) as $account) { try { // check if account is valid for multiple users, has admin credentials and sieve enabled if (emailadmin_account::is_multiple($account) && ($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 } } $profileID = !isset($content['acc_id']) ? key($accounts):$content['acc_id']; if (isset($_GET['acc_id']) && isset($allAccounts[$_GET['acc_id']])) { $profileID = $content['acc_id'] = (int)$_GET['acc_id']; } //Chooses the right account $this->account = $accounts[$profileID]; $this->is_admin_vac = true; $preserv['account_id'] = $account_id; } elseif(!is_array($content) && isset($_GET['acc_id'])) { $this->account = emailadmin_account::read($_GET['acc_id']); $preserv['acc_id'] = $this->account->acc_id; } elseif ($content['acc_id']) { $this->account = emailadmin_account::read($content['acc_id']); $preserv['acc_id'] = $content['acc_id']; } $icServer = $this->account->imapServer($this->is_admin_vac ? $account_id : false); if ($icServer->acc_sieve_enabled) { $vacRules = $this->getVacation($account_id); if ($icServer->acc_imap_administration) { $ByDate = array('by_date' => lang('By date')); } if (!is_array($content) || ($content['acc_id'] && !isset($content['button']))) { $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 { $content['forwards'] = ''; } if (empty($vacation['text']) && $this->mailConfig['default_vacation_text']) $content['text'] = $this->mailConfig['default_vacation_text']; //Set default value for days new entry if (empty($content['days'])) { $content['days'] = '3'; } $preserv['is_admin_vac'] = $content['is_admin_vac'] = $this->is_admin_vac; } else { $this->restoreSessionData(); list($button) = @each($content['button']); unset ($content['button']); switch($button) { case 'save': case 'apply': if ($GLOBALS['egw_info']['user']['apps']['admin']) { // store text as default if ($content['set_as_default'] == 1) { config::save_value('default_vacation_text', $content['text'], 'mail'); } } if (isset($content['status'])) { //error_log(__METHOD__. 'content:' . array2string($content)); $newVacation = $content; if (empty($this->mailConfig['prefpreventforwarding']) || $this->mailConfig['prefpreventforwarding'] == 0 ) { if (is_array($content['forwards']) && !empty($content['forwards'])) { $newVacation['forwards'] = implode(",",$content['forwards']); } else { $newVacation ['forwards'] = ''; } } else { unset($newVacation ['forwards']); } if (!in_array($newVacation['status'],array('on','off','by_date'))) { $newVacation['status'] = 'off'; } $checkAddresses = isset($content['check_mail_sent_to']) && $content['check_mail_sent_to'] != 0; if ($content['addresses']) { $newVacation ['addresses'] = $content['addresses']; } if($this->checkRule($newVacation,$checkAddresses)) { if (isset($account_id) && $this->mail_admin) { $resSetvac = $icServer->setVacationUser($account_id, $newVacation, $this->scriptName); } else { $resSetvac = $icServer->setVacation($newVacation); } if (!$resSetvac) { $msg = lang('vacation update failed') . "\n" . lang('Vacation notice update failed') . ":" . $this->account->imapServer()->error; 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 $cachedVacations = egw_cache::getCache(egw_cache::INSTANCE, 'email', 'vacationNotice'.$GLOBALS['egw_info']['user']['account_lid']); $cachedVacations = array($icServer->acc_id => $newVacation) + (array)$cachedVacations; egw_cache::setCache(egw_cache::INSTANCE,'email', 'vacationNotice'.$GLOBALS['egw_info']['user']['account_lid'], $cachedVacations); $msg = lang('Vacation notice sucessfully updated.'); } } else { $msg .= implode("\n",$this->errorStack); } // refresh vacationNotice on index $response = egw_json_response::get(); $response->call('app.mail.mail_callRefreshVacationNotice',$this->mailbo->profileID); egw_framework::refresh_opener($msg, 'mail'); if ($button === 'apply' || $icServer->error !=="") { break; } } case 'cancel': egw_framework::window_close(); } } $sel_options = array( 'status' => array( 'on' => lang('Active'), 'off' => lang('Deactive'), ), 'addresses' => array_combine($vacRules['aliases'],$vacRules['aliases']), ); 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; } else { $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['identity_string'],$this->mailbo->profileID); $content['hideIfSieveDisabled']='mail_DisplayNone'; } $vtmpl->exec('mail.mail_sieve.editVacation',$content,$sel_options,$readonlys,$preserv,2); } /** * 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)) { throw new egw_exception_wrong_parameter('No acc_id given!'); } // setting up an async job to enable/disable the vacation message $async = new asyncservice(); 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 if ($_vacation['status'] == 'by_date' && time() < $end_date && !$_reschedule) { $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) { $_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']); } } } /** * Callback for the async job to enable/disable the vacation message * * @param array $_vacation * @throws egw_exception_not_found if mail account is not found */ static function async_vacation(array $_vacation) { //error_log(__METHOD__.'('.array2string($_vacation).')'); $account = emailadmin_account::read($_vacation['acc_id'], $_vacation['account_id']); $icServer = $account->imapServer($_vacation['account_id']); //error_log(__METHOD__.'() imap username='.$icServer->acc_imap_username); try { $ret = $icServer->setVacationUser($_vacation['account_id'], null, $_vacation); self::setAsyncJob($_vacation); } // if mail account no longer exists --> remove async job catch (egw_exception_not_found $e) { $_vacation['status'] = 'off'; self::setAsyncJob($_vacation); } catch (Exception $e) { error_log(__METHOD__.'('.array2string($_vacation).' failed '.$e->getMessage()); self::setAsyncJob($_vacation, true); // reschedule $ret = false; } return $ret; } /** * Checking vaction validation * * @param {array} $_vacation * @param {boolean} $_checkAddresses * * @return boolean */ function checkRule($_vacation,$_checkAddresses=true) { $this->errorStack = array(); if (!$_vacation['text']) { $this->errorStack['text'] = lang('Please supply the message to send with auto-responses').'! '; } if (!$_vacation['days']) { $this->errorStack['days'] = lang('Please select the number of days to wait between responses').'!'; } if(is_array($_vacation['addresses']) && !empty($_vacation['addresses'])) { $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').'!'; } } } else { $this->errorStack['addresses'] = lang('Please select a address').'!'; } if ($_vacation['status'] == 'by_date') { 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!'); } } if ($_vacation['forwards']) { foreach(preg_split('/, ?/',$_vacation['forwards']) as $addr) { if (!preg_match($regexp,$addr) && $_checkAddresses) { $this->errorStack['forwards'] = lang('One address is not valid'.'!'); } } } //error_log(__METHOD__. array2string($this->errorStack)); if(count($this->errorStack) == 0) { return true; } else { $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; } } /** * Move rule to an other position in list * * @param {array} $orders */ function ajax_moveRule($orders) { foreach ($orders as $keys => $val) { $orders[$keys] = $val -1; } $this->getRules(null); $newrules = $this->rules; foreach($orders as $keys => $ruleID) { $newrules[$keys] = $this->rules[$ruleID]; } $this->rules = $newrules; $this->updateScript(); $this->saveSessionData(); //Calling to referesh after move action $response = egw_json_response::get(); $response->call('app.mail.sieve_refresh'); } /** * Ajax function to handle actions over sieve rules list on gd * * @param string $action name of action * @param string $checked the selected rule id * @param string $msg containing the message comming from the client-side * */ function ajax_action($action, $checked, $msg) { $this->getRules(null); switch ($action) { case 'delete': if ($checked === count($this->rules)-1) { $msg = lang('rule with priority ') . $checked . lang(' deleted!'); } else { $msg = lang('rule with priority ') . $checked . lang(' deleted!') . lang(' And the rule with priority %1, now got the priority %2',$checked+1,$checked); } unset($this->rules[$checked]); $this->rules = array_values($this->rules); break; case 'enable': $msg = lang('rule with priority ') . $checked . lang(' enabled!'); $this->rules[$checked][status] = 'ENABLED'; break; case 'disable': $msg = lang('rule with priority ') . $checked . lang(' disabled!'); $this->rules[$checked][status] = 'DISABLED'; break; case 'move': break; } ob_start(); $result = $this->updateScript(); $response = egw_json_response::get(); if($result) { $response->error($result); return; } $this->saveSessionData(); $response->call('app.mail.sieve_refresh'); } /** * Convert an script seive format rule to human readable format * * @param {array} $rule Array of rules * @return {string} return the rule as a string. */ function buildRule($rule) { $andor = ' '. lang('and') .' '; $started = 0; if ($rule['anyof']) { $andor = ' '. lang('or') .' '; } $complete = lang('IF').' '; if ($rule['unconditional']) { $complete = "[Unconditional] "; } if ($rule['from']) { $match = $this->setMatchType($rule['from'],$rule['regexp']); $complete .= "'From:' " . $match . " '" . $rule['from'] . "'"; $started = 1; } if ($rule['to']) { if ($started) { $complete .= $andor; } $match = $this->setMatchType($rule['to'],$rule['regexp']); $complete .= "'To:' " . $match . " '" . $rule['to'] . "'"; $started = 1; } if ($rule['subject']) { if ($started) { $complete .= $andor; } $match = $this->setMatchType($rule['subject'],$rule['regexp']); $complete .= "'Subject:' " . $match . " '" . $rule['subject'] . "'"; $started = 1; } if ($rule['field'] && $rule['field_val']) { if ($started) { $complete .= $andor; } $match = $this->setMatchType($rule['field_val'],$rule['regexp']); $complete .= "'" . $rule['field'] . "' " . $match . " '" . $rule['field_val'] . "'"; $started = 1; } if ($rule['size']) { $xthan = " less than '"; if ($rule['gthan']) { $xthan = " greater than '"; } if ($started) { $complete .= $andor; } $complete .= "message " . $xthan . $rule['size'] . "KB'"; $started = 1; } if (!empty($rule['field_bodytransform'])) { if ($started) { $newruletext .= ", "; } $btransform = " :raw "; $match = ' :contains'; if ($rule['bodytransform']) { $btransform = " :text "; } if (preg_match("/\*|\?/", $rule['field_bodytransform'])) { $match = ':matches'; } if ($rule['regexp']) { $match = ':regex'; } $complete .= " body " . $btransform . $match . " \"" . $rule['field_bodytransform'] . "\""; $started = 1; } if ($rule['ctype']!= '0' && !empty($rule['ctype'])) { if ($started) { $newruletext .= ", "; } $btransform_ctype = emailadmin_script::$btransform_ctype_array[$rule['ctype']]; $ctype_subtype = ""; if ($rule['field_ctype_val']) { $ctype_subtype = "/"; } $complete .= " body :content " . " \"" . $btransform_ctype . $ctype_subtype . $rule['field_ctype_val'] . "\"" . " :contains \"\""; $started = 1; //error_log(__CLASS__."::".__METHOD__.array2string(emailadmin_script::$btransform_ctype_array)); } if (!$rule['unconditional']) { $complete .= ' '.lang('THEN').' '; } if (preg_match("/folder/i",$rule['action'])) { $complete .= lang('file into')." '" . $rule['action_arg'] . "';"; } if (preg_match("/reject/i",$rule['action'])) { $complete .= lang('reject with')." '" . $rule['action_arg'] . "'."; } if (preg_match("/address/i",$rule['action'])) { $complete .= lang('forward to').' ' . $rule['action_arg'] .'.'; } if (preg_match("/discard/i",$rule['action'])) { $complete .= lang('discard').'.'; } if ($rule['continue']) { $complete .= " [Continue]"; } if ($rule['keep']) { $complete .= " [Keep a copy]"; } return $complete; } /** * Helper function to find the type of content * * @param {string} $matchstr string that should be compared * @param {string} $regex regular expresion as pattern to be matched * @return {string} return the type */ function setMatchType (&$matchstr, $regex = false) { $match = lang('contains'); if (preg_match("/^\s*!/", $matchstr)) { $match = lang('does not contain'); } if (preg_match("/\*|\?/", $matchstr)) { $match = lang('matches'); if (preg_match("/^\s*!/", $matchstr)) { $match = lang('does not match'); } } if ($regex) { $match = lang('matches regexp'); if (preg_match("/^\s*!/", $matchstr)) { $match = lang('does not match regexp'); } } if ($regex && preg_match("/^\s*\\\\!/", $matchstr)) { $matchstr = preg_replace("/^\s*\\\\!/","!",$matchstr); } else { $matchstr = preg_replace("/^\s*!/","",$matchstr); } return $match; } /** * Save session data */ function saveSessionData() { $sessionData['sieve_rules'] = $this->rules; $sessionData['sieve_rulesByID'] = $this->rulesByID; $sessionData['sieve_scriptToEdit'] = $this->scriptToEdit; $GLOBALS['egw']->session->appsession('sieve_session_data','',$sessionData); } /** * Update the sieve script on mail server */ function updateScript() { if (!$this->account->imapServer()->setRules($this->rules)) { return "update failed"; } } /** * Fetched rules save on array()rules. * * @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. */ function getRules($ruleID = null) { if(PEAR::isError($error = $this->account->imapServer()->retrieveRules()) ) { error_log(__METHOD__.__LINE__.$error->message); $this->rules = array(); $this->rulesByID = array(); $this->vacation = array(); } else { $this->rules = $this->account->imapServer()->getRules(); $this->rulesByID = $this->rules[$ruleID]; $this->vacation = $this->account->imapServer()->getVacation(); } return true; } /** * Restore session data */ function restoreSessionData() { $sessionData = $GLOBALS['egw']->session->appsession('sieve_session_data'); $this->rules = $sessionData['sieve_rules']; $this->rulesByID = $sessionData['sieve_rulesByID']; $this->scriptToEdit = $sessionData['sieve_scriptToEdit']; } /** * * Get the data for iterating the rows on rules list grid * * @return {boolean|array} Array of rows | false if failed */ function get_rows() { $rows = array(); $this->getRules(null); 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 ); if ($row ['status'] === 'DISABLED') { $row['class'] = 'mail_sieve_DISABLED'; } } } else { //error_log(__METHOD__.'There are no rules or something is went wrong at getRules()!'); return false; } // Shift one down, because in grid the first row is reserved for header array_unshift($rows,array(''=> '')); return $rows; } /** * Get actions / context menu for index * * @return {array} returns defined actions as an array */ private function get_actions() { $actions =array( 'edit' => array( 'caption' => 'Edit', 'default' => true, 'onExecute' => 'javaScript:app.mail.action', 'disableClass' => 'th' ), 'add' => array( 'caption' => 'Add', 'onExecute' => 'javaScript:app.mail.action' ), 'enable' => array( 'caption' => 'Enable', 'onExecute' => 'javaScript:app.mail.action', 'enableClass' => 'mail_sieve_DISABLED', 'hideOnDisabled' => true ), 'disable' => array( 'caption' => 'Disable', 'onExecute' => 'javaScript:app.mail.action', 'disableClass' => 'mail_sieve_DISABLED', 'hideOnDisabled' => true ), 'delete' => array( 'caption' => 'Delete', 'onExecute' => 'javaScript:app.mail.action' ), ); return $actions; } }