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_If class represents a Sieve If Statement.
17 *
18 * @author   Mike Cochrane <mike@graftonhall.co.nz>
19 * @author   Jan Schneider <jan@horde.org>
20 * @category Horde
21 * @license  http://www.horde.org/licenses/apache ASL
22 * @package  Ingo
23 */
24class Ingo_Script_Sieve_If implements Ingo_Script_Item
25{
26    /**
27     * The Ingo_Script_Sieve_Test object for the if test.
28     *
29     * @var Ingo_Script_Sieve_Test
30     */
31    protected $_test;
32
33    /**
34     * A list of Ingo_Script_Sieve_Action objects that go into the if clause.
35     *
36     * @var array
37     */
38    protected $_actions = array();
39
40    /**
41     * A list of Ingo_Script_Sieve_Elseif objects that create optional elsif
42     * clauses.
43     *
44     * @var array
45     */
46    protected $_elsifs = array();
47
48    /**
49     * A Ingo_Script_Sieve_Else object that creates an optional else clause.
50     *
51     * @var Ingo_Script_Sieve_Else
52     */
53    protected $_else;
54
55    /**
56     * Constructor.
57     *
58     * @param Ingo_Script_Sieve_Test $test  A Ingo_Script_Sieve_Test object.
59     */
60    public function __construct($test = null)
61    {
62        $this->_test = is_null($test)
63            ? new Ingo_Script_Sieve_Test_False()
64            : $test;
65
66        $this->_actions[] = new Ingo_Script_Sieve_Action_Keep();
67        $this->_else = new Ingo_Script_Sieve_Else();
68    }
69
70    /**
71     */
72    public function getTest()
73    {
74        return $this->_test;
75    }
76
77    /**
78     */
79    public function setTest($test)
80    {
81        $this->_test = $test;
82    }
83
84    /**
85     */
86    public function getActions()
87    {
88        return $this->_actions;
89    }
90
91    /**
92     */
93    public function setActions($actions)
94    {
95        $this->_actions = $actions;
96    }
97
98    /**
99     */
100    public function getElsifs()
101    {
102        return $this->_elsifs;
103    }
104
105    /**
106     */
107    public function setElsifs($elsifs)
108    {
109        $this->_elsifs = $elsifs;
110    }
111
112    /**
113     */
114    public function addElsif($elsif)
115    {
116        $this->_elsifs[] = $elsif;
117    }
118
119    /**
120     */
121    public function getElse()
122    {
123        return $this->_else;
124    }
125
126    /**
127     */
128    public function setElse($else)
129    {
130        $this->_else = $else;
131    }
132
133    /**
134     * Returns a script snippet representing this rule and any sub-rules.
135     *
136     * @return string  A Sieve script snippet.
137     */
138    public function generate()
139    {
140        $code = 'if ' . $this->_test->generate() . " {\n";
141        foreach ($this->_actions as $action) {
142            $code .= '    ' . $action->generate() . "\n";
143        }
144        $code .= '}';
145
146        foreach ($this->_elsifs as $elsif) {
147            $code .= $elsif->generate();
148        }
149
150        $code .= $this->_else->generate();
151
152        return $code;
153    }
154
155    /**
156     * Checks if all sub-rules are valid.
157     *
158     * @return boolean|string  True if all rules are valid, an error message
159     *                         otherwise.
160     */
161    public function check()
162    {
163        $res = $this->_test->check();
164        if ($res !== true) {
165            return $res;
166        }
167
168        foreach ($this->_elsifs as $elsif) {
169            $res = $elsif->check();
170            if ($res !== true) {
171                return $res;
172            }
173        }
174
175        $res = $this->_else->check();
176        if ($res !== true) {
177            return $res;
178        }
179
180        foreach ($this->_actions as $action) {
181            $res = $action->check();
182            if ($res !== true) {
183                return $res;
184            }
185        }
186
187        return true;
188    }
189
190    /**
191     * Returns a list of sieve extensions required for this rule and any
192     * sub-rules.
193     *
194     * @return array  A Sieve extension list.
195     */
196    public function requires()
197    {
198        $requires = array();
199
200        foreach ($this->_actions as $action) {
201            $requires = array_merge($requires, $action->requires());
202        }
203
204        foreach ($this->_elsifs as $elsif) {
205            $requires = array_merge($requires, $elsif->requires());
206        }
207
208        return array_merge($requires, $this->_test->requires(), $this->_else->requires());
209    }
210}
211