public function as_text()
{
$script = '';
$variables = '';
$exts = array();
// rules
$activeRules = 0;
foreach ($this->content as $rule) {
$tests = array();
$i = 0;
if ($rule['disabled'] == 1) {
$script .= '# rule:[' . $rule['name'] . "]" . RCUBE_SIEVE_NEWLINE;
$script .= '# disabledRule:[' . $this->_safe_serial(serialize($rule)) . "]" . RCUBE_SIEVE_NEWLINE;
} else {
// header
$script .= '# rule:[' . $rule['name'] . "]" . RCUBE_SIEVE_NEWLINE;
// constraints expressions
foreach ($rule['tests'] as $test) {
$tests[$i] = '';
switch ($test['type']) {
case 'size':
$tests[$i] .= $test['not'] ? 'not ' : '';
$tests[$i] .= 'size :' . ($test['operator'] == 'under' ? 'under ' : 'over ') . $test['target'];
break;
case 'virustest':
case 'spamtest':
array_push($exts, $test['type']);
array_push($exts, 'relational');
array_push($exts, 'comparator-i;ascii-numeric');
$tests[$i] .= $test['not'] ? 'not ' : '';
$tests[$i] .= $test['type'] . ' :value ' . ($test['operator'] == 'eq' ? '"eq" ' : ($test['operator'] == 'le' ? '"le" ' : '"ge" ')) . ':comparator "i;ascii-numeric" "' . $test['target'] . '"';
break;
case 'true':
$tests[$i] .= $test['not'] ? 'not true' : 'true';
break;
case 'exists':
$tests[$i] .= $test['not'] ? 'not ' : '';
if (is_array($test['header'])) {
$tests[$i] .= 'exists ["' . implode('", "', $this->_escape_string($test['header'])) . '"]';
} else {
$tests[$i] .= 'exists "' . $this->_escape_string($test['header']) . '"';
}
break;
case 'envelope':
array_push($exts, 'envelope');
case 'header':
case 'address':
if ($test['operator'] == 'regex') {
array_push($exts, 'regex');
} elseif (substr($test['operator'], 0, 5) == 'count' || substr($test['operator'], 0, 5) == 'value') {
array_push($exts, 'relational');
} elseif ($test['operator'] == 'user' || $test['operator'] == 'detail' || $test['operator'] == 'domain') {
array_push($exts, 'subaddress');
}
$tests[$i] .= $test['not'] ? 'not ' : '';
$tests[$i] .= $test['type'] . ' :' . $test['operator'];
if ($test['comparator'] != '') {
if ($test['comparator'] != 'i;ascii-casemap' && $test['comparator'] != 'i;octet') {
array_push($exts, 'comparator-' . $test['comparator']);
}
$tests[$i] .= ' :comparator "' . $test['comparator'] . '"';
}
if (is_array($test['header'])) {
$tests[$i] .= ' ["' . implode('", "', $this->_escape_string($test['header'])) . '"]';
} else {
$tests[$i] .= ' "' . $this->_escape_string($test['header']) . '"';
}
if (is_array($test['target'])) {
$tests[$i] .= ' ["' . implode('", "', $this->_escape_string($test['target'])) . '"]';
} else {
$tests[$i] .= ' "' . $this->_escape_string($test['target']) . '"';
}
break;
case 'body':
array_push($exts, 'body');
if ($test['operator'] == 'regex') {
array_push($exts, 'regex');
} elseif (substr($test['operator'], 0, 5) == 'count' || substr($test['operator'], 0, 5) == 'value') {
array_push($exts, 'relational');
}
$tests[$i] .= $test['not'] ? 'not ' : '';
$tests[$i] .= $test['type'];
if ($test['bodypart'] != '') {
$tests[$i] .= ' :' . $test['bodypart'];
}
if ($test['contentpart'] != '') {
$tests[$i] .= ' "' . $test['contentpart'] . '"';
}
$tests[$i] .= ' :' . $test['operator'];
if ($test['comparator'] != '') {
if ($test['comparator'] != 'i;ascii-casemap' && $test['comparator'] != 'i;octet') {
array_push($exts, 'comparator-' . $test['comparator']);
}
$tests[$i] .= ' :comparator "' . $test['comparator'] . '"';
}
if (is_array($test['target'])) {
$tests[$i] .= ' ["' . implode('", "', $this->_escape_string($test['target'])) . '"]';
} else {
$tests[$i] .= ' "' . $this->_escape_string($test['target']) . '"';
}
break;
case 'date':
array_push($exts, 'date');
if ($test['operator'] == 'regex') {
array_push($exts, 'regex');
} elseif (substr($test['operator'], 0, 5) == 'count' || substr($test['operator'], 0, 5) == 'value') {
array_push($exts, 'relational');
}
$tests[$i] .= $test['not'] ? 'not ' : '';
$tests[$i] .= $test['header'];
$timezone = rcube::get_instance()->config->get('timezone', 'auto');
if ($timezone != 'auto') {
$tz = new DateTimeZone($timezone);
$date = new DateTime('now', $tz);
$tests[$i] .= ' :zone ' . '"' . $date->format('O') . '"';
}
$tests[$i] .= ' :' . $test['operator'];
if ($test['comparator'] != '') {
if ($test['comparator'] != 'i;ascii-casemap' && $test['comparator'] != 'i;octet') {
array_push($exts, 'comparator-' . $test['comparator']);
}
$tests[$i] .= ' :comparator "' . $test['comparator'] . '"';
}
$tests[$i] .= ' "' . $this->_escape_string($test['datepart']) . '"';
$tests[$i] .= ' "' . $this->_escape_string($test['target']) . '"';
break;
}
$i++;
}
$script .= ($activeRules > 0 && $this->elsif ? 'els' : '') . ($rule['join'] ? 'if allof (' : 'if anyof (');
$activeRules++;
if (sizeof($tests) > 1) {
$script .= implode("," . RCUBE_SIEVE_NEWLINE . RCUBE_SIEVE_INDENT, $tests);
} elseif (sizeof($tests)) {
$script .= $tests[0];
} else {
$script .= 'true';
}
$script .= ")" . RCUBE_SIEVE_NEWLINE . "{" . RCUBE_SIEVE_NEWLINE;
// action(s)
$actions = '';
foreach ($rule['actions'] as $action) {
switch ($action['type']) {
case 'fileinto':
case 'fileinto_copy':
array_push($exts, 'fileinto');
$args = '';
if ($action['type'] == 'fileinto_copy') {
array_push($exts, 'copy');
$args .= ' :copy';
}
if ($action['create']) {
array_push($exts, 'mailbox');
$args .= ' :create';
}
// variables support in fileinto by David Warden
if (preg_match('/\\$\\{\\d+\\}/', $action['target'])) {
array_push($exts, 'variables');
}
$actions .= RCUBE_SIEVE_INDENT . "fileinto" . $args . " \"" . $this->_escape_string($action['target']) . "\";" . RCUBE_SIEVE_NEWLINE;
break;
case 'redirect':
case 'redirect_copy':
$args = '';
if ($action['type'] == 'redirect_copy') {
array_push($exts, 'copy');
$args .= ' :copy';
}
$tokens = preg_split('/[,;\\s]/', $action['target']);
foreach ($tokens as $email) {
$actions .= RCUBE_SIEVE_INDENT . "redirect" . $args . " \"" . $this->_escape_string($email) . "\";" . RCUBE_SIEVE_NEWLINE;
}
break;
case 'reject':
case 'ereject':
array_push($exts, $action['type']);
if (strpos($action['target'], "\n") !== false) {
$actions .= RCUBE_SIEVE_INDENT . $action['type'] . " text:" . RCUBE_SIEVE_NEWLINE . $action['target'] . RCUBE_SIEVE_NEWLINE . "." . RCUBE_SIEVE_NEWLINE . ";" . RCUBE_SIEVE_NEWLINE;
} else {
$actions .= RCUBE_SIEVE_INDENT . $action['type'] . " \"" . $this->_escape_string($action['target']) . "\";" . RCUBE_SIEVE_NEWLINE;
}
break;
case 'vacation':
array_push($exts, 'vacation');
$action['subject'] = $this->_escape_string($action['subject']);
// // encoding subject header with mb_encode provides better results with asian characters
// if (function_exists("mb_encode_mimeheader"))
// {
// mb_internal_encoding($action['charset']);
// $action['subject'] = mb_encode_mimeheader($action['subject'], $action['charset'], 'Q');
// mb_internal_encoding(RCUBE_CHARSET);
// }
// detect original recipient
if ($action['from'] == 'auto') {
if (strpos($variables, 'set "from"') === false) {
array_push($exts, 'variables');
$variables .= 'set "from" "";' . RCUBE_SIEVE_NEWLINE;
$variables .= 'if header :matches "to" "*" {' . RCUBE_SIEVE_NEWLINE;
$variables .= RCUBE_SIEVE_INDENT . 'set "from" "${1}";' . RCUBE_SIEVE_NEWLINE;
$variables .= '}' . RCUBE_SIEVE_NEWLINE;
}
$action['from'] = "\${from}";
} elseif ($action['from'] == 'auto') {
$action['from'] = "\${from}";
}
// append original subject
if ($action['origsubject'] == '1') {
if (strpos($variables, 'set "subject"') === false) {
array_push($exts, 'variables');
$variables .= 'set "subject" "";' . RCUBE_SIEVE_NEWLINE;
$variables .= 'if header :matches "subject" "*" {' . RCUBE_SIEVE_NEWLINE;
$variables .= RCUBE_SIEVE_INDENT . 'set "subject" "${1}";' . RCUBE_SIEVE_NEWLINE;
$variables .= '}' . RCUBE_SIEVE_NEWLINE;
}
$action['subject'] = trim($action['subject']);
if (substr($action['subject'], -1, 1) != ":") {
$action['subject'] .= ":";
}
$action['subject'] .= " \${subject}";
}
$actions .= RCUBE_SIEVE_INDENT . "vacation" . RCUBE_SIEVE_NEWLINE;
if (!empty($action['seconds'])) {
array_push($exts, 'vacation-seconds');
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":seconds " . $action['seconds'] . RCUBE_SIEVE_NEWLINE;
} elseif (!empty($action['days'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":days " . $action['days'] . RCUBE_SIEVE_NEWLINE;
}
if (!empty($action['addresses'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":addresses [\"" . str_replace(",", "\",\"", $this->_escape_string($action['addresses'])) . "\"]" . RCUBE_SIEVE_NEWLINE;
}
if (!empty($action['subject'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":subject \"" . $action['subject'] . "\"" . RCUBE_SIEVE_NEWLINE;
}
if (!empty($action['handle'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":handle \"" . $this->_escape_string($action['handle']) . "\"" . RCUBE_SIEVE_NEWLINE;
}
if (!empty($action['from'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":from \"" . $this->_escape_string($action['from']) . "\"" . RCUBE_SIEVE_NEWLINE;
}
if ($action['htmlmsg']) {
$MAIL_MIME = new Mail_mime("\r\n");
$action['msg'] = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">' . "\r\n<html><body>\r\n" . $action['msg'] . "\r\n</body></html>\r\n";
$MAIL_MIME->setHTMLBody($action['msg']);
// add a plain text version of the e-mail as an alternative part.
$h2t = new rcube_html2text($action['msg'], false, true, 0);
$plainTextPart = $h2t->get_text();
if (!$plainTextPart) {
// empty message body breaks attachment handling in drafts
$plainTextPart = "\r\n";
} else {
// make sure all line endings are CRLF (#1486712)
$plainTextPart = preg_replace('/\\r?\\n/', "\r\n", $plainTextPart);
}
$MAIL_MIME->setTXTBody($plainTextPart);
$MAIL_MIME->setParam('html_charset', $action['charset']);
$MAIL_MIME->setParam('text_charset', $action['charset']);
$action['msg'] = $MAIL_MIME->getMessage();
}
// escape lines which start is a .
$action['msg'] = preg_replace('/(^|\\r?\\n)\\./', "\$1..", $action['msg']);
if ($action['htmlmsg']) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":mime text:" . RCUBE_SIEVE_NEWLINE . $action['msg'] . RCUBE_SIEVE_NEWLINE . "." . RCUBE_SIEVE_NEWLINE . ";" . RCUBE_SIEVE_NEWLINE;
} elseif ($action['charset'] != "UTF-8") {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":mime text:" . RCUBE_SIEVE_NEWLINE . "Content-Type: text/plain; charset=" . $action['charset'] . RCUBE_SIEVE_NEWLINE . RCUBE_SIEVE_NEWLINE . $action['msg'] . RCUBE_SIEVE_NEWLINE . "." . RCUBE_SIEVE_NEWLINE . ";" . RCUBE_SIEVE_NEWLINE;
} elseif (strpos($action['msg'], "\n") !== false) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . "text:" . RCUBE_SIEVE_NEWLINE . $action['msg'] . RCUBE_SIEVE_NEWLINE . "." . RCUBE_SIEVE_NEWLINE . ";" . RCUBE_SIEVE_NEWLINE;
} else {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . "\"" . $this->_escape_string($action['msg']) . "\";" . RCUBE_SIEVE_NEWLINE;
}
break;
case 'imapflags':
case 'imap4flags':
array_push($exts, $action['type']);
if (strpos($actions, "setflag") !== false) {
$actions .= RCUBE_SIEVE_INDENT . "addflag \"" . $this->_escape_string($action['target']) . "\";" . RCUBE_SIEVE_NEWLINE;
} else {
$actions .= RCUBE_SIEVE_INDENT . "setflag \"" . $this->_escape_string($action['target']) . "\";" . RCUBE_SIEVE_NEWLINE;
}
break;
case 'notify':
array_push($exts, 'notify');
$actions .= RCUBE_SIEVE_INDENT . "notify" . RCUBE_SIEVE_NEWLINE;
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":method \"" . $this->_escape_string($action['method']) . "\"" . RCUBE_SIEVE_NEWLINE;
if (!empty($action['options'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":options [\"" . str_replace(",", "\",\"", $this->_escape_string($action['options'])) . "\"]" . RCUBE_SIEVE_NEWLINE;
}
if (!empty($action['from'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":from \"" . $this->_escape_string($action['from']) . "\"" . RCUBE_SIEVE_NEWLINE;
}
if (!empty($action['importance'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":importance \"" . $this->_escape_string($action['importance']) . "\"" . RCUBE_SIEVE_NEWLINE;
}
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":message \"" . $this->_escape_string($action['msg']) . "\";" . RCUBE_SIEVE_NEWLINE;
break;
case 'enotify':
array_push($exts, 'enotify');
$actions .= RCUBE_SIEVE_INDENT . "notify" . RCUBE_SIEVE_NEWLINE;
if (!empty($action['options'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":options [\"" . str_replace(",", "\",\"", $this->_escape_string($action['options'])) . "\"]" . RCUBE_SIEVE_NEWLINE;
}
if (!empty($action['from'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":from \"" . $this->_escape_string($action['from']) . "\"" . RCUBE_SIEVE_NEWLINE;
}
if (!empty($action['importance'])) {
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":importance \"" . $this->_escape_string($action['importance']) . "\"" . RCUBE_SIEVE_NEWLINE;
}
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . ":message \"" . $this->_escape_string($action['msg']) . "\"" . RCUBE_SIEVE_NEWLINE;
$actions .= RCUBE_SIEVE_INDENT . RCUBE_SIEVE_INDENT . "\"" . $this->_escape_string($action['method']) . "\";" . RCUBE_SIEVE_NEWLINE;
break;
case 'editheaderadd':
array_push($exts, 'editheader');
$actions .= RCUBE_SIEVE_INDENT . "addheader";
if ($action['index'] == 'last') {
$actions .= " :last";
}
$actions .= " \"" . $this->_escape_string($action['name']) . "\" \"" . $this->_escape_string($action['value']) . "\";" . RCUBE_SIEVE_NEWLINE;
break;
case 'editheaderrem':
array_push($exts, 'editheader');
$actions .= RCUBE_SIEVE_INDENT . "deleteheader";
if (is_numeric($action['index'])) {
$actions .= " :index " . $action['index'];
} elseif ($action['index'] == 'last') {
$actions .= " :last";
}
if (strlen($action['operator']) > 0) {
$actions .= " :" . $action['operator'];
}
$actions .= " \"" . $this->_escape_string($action['name']) . "\"";
if (strlen($action['value']) > 0) {
$actions .= " \"" . $this->_escape_string($action['value']) . "\"";
}
$actions .= ";" . RCUBE_SIEVE_NEWLINE;
break;
case 'variables':
array_push($exts, 'variables');
$actions .= RCUBE_SIEVE_INDENT . "set \"" . $this->_escape_string($action['name']) . "\" \"" . $this->_escape_string($action['value']) . "\";" . RCUBE_SIEVE_NEWLINE;
break;
case 'keep':
case 'discard':
case 'stop':
$actions .= RCUBE_SIEVE_INDENT . $action['type'] . ";" . RCUBE_SIEVE_NEWLINE;
break;
}
}
$script .= $actions . "}" . RCUBE_SIEVE_NEWLINE;
}
}
if ($variables) {
$variables .= RCUBE_SIEVE_NEWLINE;
}
// requires
$exts = array_unique($exts);
if (sizeof($exts)) {
$script = 'require ["' . implode('","', $exts) . "\"];" . RCUBE_SIEVE_NEWLINE . RCUBE_SIEVE_NEWLINE . $variables . $script;
}
// author
if ($script && RCUBE_SIEVE_HEADER) {
$script = RCUBE_SIEVE_HEADER . RCUBE_SIEVE_NEWLINE . $script;
}
return $script;
}