1<?php
2/* Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */
3
4namespace Icinga\Web;
5
6use Icinga\Application\Config;
7use Icinga\Application\Icinga;
8use InvalidArgumentException;
9
10/**
11 * A HTTP cookie
12 */
13class Cookie
14{
15    /**
16     * Domain of the cookie
17     *
18     * @var string
19     */
20    protected $domain;
21
22    /**
23     * The timestamp at which the cookie expires
24     *
25     * @var int
26     */
27    protected $expire;
28
29    /**
30     * Whether to protect the cookie against client side script code attempts to read the cookie
31     *
32     * Defaults to true.
33     *
34     * @var bool
35     */
36    protected $httpOnly = true;
37
38    /**
39     * Name of the cookie
40     *
41     * @var string
42     */
43    protected $name;
44
45    /**
46     * The path on the web server where the cookie is available
47     *
48     * Defaults to the base URL.
49     *
50     * @var string
51     */
52    protected $path;
53
54    /**
55     * Whether to send the cookie only over a secure connection
56     *
57     * Defaults to auto-detection so that if the current request was sent over a secure connection the secure flag will
58     * be set to true.
59     *
60     * @var bool
61     */
62    protected $secure;
63
64    /**
65     * Value of the cookie
66     *
67     * @var string
68     */
69    protected $value;
70
71    /**
72     * Create a new cookie
73     *
74     * @param   string  $name
75     * @param   string  $value
76     */
77    public function __construct($name, $value = null)
78    {
79        if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
80            throw new InvalidArgumentException(sprintf(
81                'Cookie name can\'t contain these characters: =,; \t\r\n\013\014 (%s)',
82                $name
83            ));
84        }
85        if (empty($name)) {
86            throw new InvalidArgumentException('The cookie name can\'t be empty');
87        }
88        $this->name = $name;
89        $this->value = $value;
90    }
91
92    /**
93     * Get the domain of the cookie
94     *
95     * @return  string
96     */
97    public function getDomain()
98    {
99        if ($this->domain === null) {
100            $this->domain = Config::app()->get('cookie', 'domain');
101        }
102        return $this->domain;
103    }
104
105    /**
106     * Set the domain of the cookie
107     *
108     * @param   string  $domain
109     *
110     * @return  $this
111     */
112    public function setDomain($domain)
113    {
114        $this->domain = $domain;
115        return $this;
116    }
117
118    /**
119     * Get the timestamp at which the cookie expires
120     *
121     * @return  int
122     */
123    public function getExpire()
124    {
125        return $this->expire;
126    }
127
128    /**
129     * Set the timestamp at which the cookie expires
130     *
131     * @param   int $expire
132     *
133     * @return  $this
134     */
135    public function setExpire($expire)
136    {
137        $this->expire = $expire;
138        return $this;
139    }
140
141    /**
142     * Get whether to protect the cookie against client side script code attempts to read the cookie
143     *
144     * @return  bool
145     */
146    public function isHttpOnly()
147    {
148        return $this->httpOnly;
149    }
150
151    /**
152     * Set whether to protect the cookie against client side script code attempts to read the cookie
153     *
154     * @param   bool    $httpOnly
155     *
156     * @return  $this
157     */
158    public function setHttpOnly($httpOnly)
159    {
160        $this->httpOnly = $httpOnly;
161        return $this;
162    }
163
164    /**
165     * Get the name of the cookie
166     *
167     * @return string
168     */
169    public function getName()
170    {
171        return $this->name;
172    }
173
174    /**
175     * Get the path on the web server where the cookie is available
176     *
177     * If the path has not been set either via {@link setPath()} or via config, the base URL will be returned.
178     *
179     * @return  string
180     */
181    public function getPath()
182    {
183        if ($this->path === null) {
184            $path = Config::app()->get('cookie', 'path');
185            if ($path === null) {
186                // The following call could be used as default for ConfigObject::get(), but we prevent unnecessary
187                // function calls here, if the path is set in the config
188                $path = Icinga::app()->getRequest()->getBaseUrl() . '/'; // Zend has rtrim($baseUrl, '/')
189            }
190            $this->path = $path;
191        }
192        return $this->path;
193    }
194
195    /**
196     * Set the path on the web server where the cookie is available
197     *
198     * @param   string  $path
199     *
200     * @return  $this
201     */
202    public function setPath($path)
203    {
204        $this->path = $path;
205        return $this;
206    }
207
208    /**
209     * Get whether to send the cookie only over a secure connection
210     *
211     * If the secure flag has not been set either via {@link setSecure()} or via config and if the current request was
212     * sent over a secure connection, true will be returned.
213     *
214     * @return bool
215     */
216    public function isSecure()
217    {
218        if ($this->secure === null) {
219            $secure = Config::app()->get('cookie', 'secure');
220            if ($secure === null) {
221                // The following call could be used as default for ConfigObject::get(), but we prevent unnecessary
222                // function calls here, if the secure flag is set in the config
223                $secure = Icinga::app()->getRequest()->isSecure();
224            }
225            $this->secure = $secure;
226        }
227        return $this->secure;
228    }
229
230    /**
231     * Set whether to send the cookie only over a secure connection
232     *
233     * @param   bool    $secure
234     *
235     * @return  $this
236     */
237    public function setSecure($secure)
238    {
239        $this->secure = $secure;
240        return $this;
241    }
242
243    /**
244     * Get the value of the cookie
245     *
246     * @return  string
247     */
248    public function getValue()
249    {
250        return $this->value;
251    }
252
253    /**
254     * Set the value of the cookie
255     *
256     * @param   string  $value
257     *
258     * @return  $this
259     */
260    public function setValue($value)
261    {
262        $this->value = $value;
263        return $this;
264    }
265}
266