1<?php
2/**
3 * Copyright 2012-2017 Horde LLC (http://www.horde.org/)
4 *
5 * See the enclosed file LICENSE for license information (ASL).  If you
6 * did not receive this file, see http://www.horde.org/licenses/apache.
7 *
8 * @author   Mike Cochrane <mike@graftonhall.co.nz>
9 * @author   Jan Schneider <jan@horde.org>
10 * @category Horde
11 * @license  http://www.horde.org/licenses/apache ASL
12 * @package  Ingo
13 */
14
15/**
16 * The Ingo_Script_Sieve_Test_Address class represents a test on parts or all
17 * of the addresses in the given fields.
18 *
19 * @author   Mike Cochrane <mike@graftonhall.co.nz>
20 * @author   Jan Schneider <jan@horde.org>
21 * @category Horde
22 * @license  http://www.horde.org/licenses/apache ASL
23 * @package  Ingo
24 */
25class Ingo_Script_Sieve_Test_Address extends Ingo_Script_Sieve_Test
26{
27    /**
28     * Constructor.
29     *
30     * @param array $vars  Any required parameters.
31     */
32    public function __construct($vars)
33    {
34        $this->_vars['headers'] = isset($vars['headers'])
35            ? $vars['headers']
36            : '';
37        $this->_vars['comparator'] = isset($vars['comparator'])
38            ? $vars['comparator']
39            : 'i;ascii-casemap';
40        $this->_vars['match-type'] = isset($vars['match-type'])
41            ? $vars['match-type']
42            : ':is';
43        $this->_vars['address-part'] = isset($vars['address-part'])
44            ? $vars['address-part']
45            : ':all';
46        $this->_vars['addresses'] = isset($vars['addresses'])
47            ? $vars['addresses']
48            : '';
49    }
50
51    /**
52     * Checks if the rule parameters are valid.
53     *
54     * @return boolean|string  True if this rule is valid, an error message
55     *                         otherwise.
56     */
57    public function check()
58    {
59        return preg_split('(\r\n|\n|\r)', $this->_vars['headers']) &&
60               preg_split('(\r\n|\n|\r)', $this->_vars['addresses']);
61    }
62
63    /**
64     * Returns a script snippet representing this rule and any sub-rules.
65     *
66     * @return string  A Sieve script snippet.
67     */
68    public function generate()
69    {
70        $code = 'address ' .
71            $this->_vars['address-part'] . ' ' .
72            ':comparator "' . $this->_vars['comparator'] . '" ' .
73            $this->_vars['match-type'] . ' ';
74
75        $headers = preg_split('(\r\n|\n|\r|,)', $this->_vars['headers']);
76        $headers = array_filter($headers);
77        if (count($headers) > 1) {
78            $code .= "[";
79            $headerstr = '';
80            foreach ($headers as $header) {
81                $header = trim($header);
82                if (!empty($header)) {
83                    $headerstr .= empty($headerstr) ? '"' : ', "';
84                    $headerstr .= Ingo_Script_Sieve::escapeString($header, $this->_vars['match-type'] == ':regex') . '"';
85                }
86            }
87            $code .= $headerstr . "] ";
88        } elseif (count($headers) == 1) {
89            $code .= '"' . Ingo_Script_Sieve::escapeString($headers[0], $this->_vars['match-type'] == ':regex') . '" ';
90        } else {
91            return "No Headers Specified";
92        }
93
94        $addresses = preg_split('(\r\n|\n|\r)', $this->_vars['addresses']);
95        $addresses = array_filter($addresses);
96        if (count($addresses) > 1) {
97            $code .= "[";
98            $addressstr = '';
99            foreach ($addresses as $addr) {
100                $addr = trim($addr);
101                if (!empty($addr)) {
102                    $addressstr .= empty($addressstr) ? '"' : ', "';
103                    $addressstr .= Ingo_Script_Sieve::escapeString($addr, $this->_vars['match-type'] == ':regex') . '"';
104                }
105            }
106            $code .= $addressstr . "] ";
107        } elseif (count($addresses) == 1) {
108            $code .= '"' . Ingo_Script_Sieve::escapeString($addresses[0], $this->_vars['match-type'] == ':regex') . '" ';
109        } else {
110            return "No Addresses Specified";
111        }
112
113        return $code;
114    }
115
116    /**
117     * Returns a list of sieve extensions required for this rule and any
118     * sub-rules.
119     *
120     * @return array  A Sieve extension list.
121     */
122    public function requires()
123    {
124        return ($this->_vars['match-type'] == ':regex')
125            ? array('regex')
126            : array();
127    }
128}
129