1 | <?php namespace Comodojo\Cookies; |
||
2 | |||
3 | use \Comodojo\Exception\CookieException; |
||
4 | |||
5 | /** |
||
6 | * Base class, to be estended implementing a CookieInterface |
||
7 | * |
||
8 | * @package Comodojo Spare Parts |
||
9 | * @author Marco Giovinazzi <[email protected]> |
||
10 | * @license MIT |
||
11 | * |
||
12 | * LICENSE: |
||
13 | * |
||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
||
20 | * THE SOFTWARE. |
||
21 | */ |
||
22 | |||
23 | abstract class AbstractCookie implements CookieInterface { |
||
24 | |||
25 | /** |
||
26 | * The cookie name |
||
27 | * |
||
28 | * @var string |
||
29 | */ |
||
30 | protected $name; |
||
31 | |||
32 | /** |
||
33 | * Cookie value (native string or serialized one) |
||
34 | * |
||
35 | * @var string |
||
36 | */ |
||
37 | protected $value; |
||
38 | |||
39 | /** |
||
40 | * Expiration time |
||
41 | * |
||
42 | * @var integer |
||
43 | */ |
||
44 | protected $expire; |
||
45 | |||
46 | /** |
||
47 | * Path of cookie |
||
48 | * |
||
49 | * @var string |
||
50 | */ |
||
51 | protected $path; |
||
52 | |||
53 | /** |
||
54 | * Domain of cookie |
||
55 | * |
||
56 | * @var string |
||
57 | */ |
||
58 | protected $domain; |
||
59 | |||
60 | /** |
||
61 | * Secure flag |
||
62 | * |
||
63 | * @var bool |
||
64 | */ |
||
65 | protected $secure = false; |
||
66 | |||
67 | /** |
||
68 | * Httponly flag |
||
69 | * |
||
70 | * @var bool |
||
71 | */ |
||
72 | protected $httponly = false; |
||
73 | |||
74 | /* |
||
75 | * Max cookie size |
||
76 | * |
||
77 | * Should be 4096 max |
||
78 | * |
||
79 | * @var int |
||
80 | */ |
||
81 | protected $max_cookie_size; |
||
82 | |||
83 | /** |
||
84 | * Default cookie's constructor |
||
85 | * |
||
86 | * @param string $name |
||
87 | * @param int $max_cookie_size |
||
88 | * |
||
89 | * @throws CookieException |
||
90 | */ |
||
91 | 99 | public function __construct($name, $max_cookie_size = null) { |
|
92 | |||
93 | try { |
||
94 | |||
95 | 99 | $this->setName($name); |
|
96 | |||
97 | 99 | } catch (CookieException $ce) { |
|
98 | |||
99 | throw $ce; |
||
100 | |||
101 | } |
||
102 | |||
103 | 99 | $this->max_cookie_size = filter_var($max_cookie_size, FILTER_VALIDATE_INT, [ |
|
104 | 'options' => [ |
||
105 | 'default' => CookieInterface::COOKIE_MAX_SIZE |
||
106 | ] |
||
107 | ]); |
||
108 | |||
109 | } |
||
110 | |||
111 | /** |
||
112 | * {@inheritdoc} |
||
113 | 99 | */ |
|
114 | public function setName($name) { |
||
115 | |||
116 | if ( empty($name) || !is_scalar($name) ) throw new CookieException("Invalid cookie name"); |
||
117 | |||
118 | 99 | $this->name = $name; |
|
119 | |||
120 | 99 | return $this; |
|
121 | |||
122 | 99 | } |
|
123 | |||
124 | 99 | /** |
|
125 | * {@inheritdoc} |
||
126 | */ |
||
127 | public function getName() { |
||
128 | |||
129 | return $this->name; |
||
130 | |||
131 | 9 | } |
|
132 | |||
133 | 9 | /** |
|
134 | * {@inheritdoc} |
||
135 | */ |
||
136 | abstract function setValue($value, $serialize); |
||
0 ignored issues
–
show
|
|||
137 | |||
138 | /** |
||
139 | * {@inheritdoc} |
||
140 | */ |
||
141 | abstract function getValue($unserialize); |
||
0 ignored issues
–
show
|
|||
142 | |||
143 | /** |
||
144 | * {@inheritdoc} |
||
145 | */ |
||
146 | public function setExpire($timestamp) { |
||
147 | |||
148 | if ( !is_int($timestamp) ) throw new CookieException("Invalud cookie's expiration time"); |
||
149 | |||
150 | 3 | $this->expire = $timestamp; |
|
151 | |||
152 | 3 | return $this; |
|
153 | |||
154 | 3 | } |
|
155 | |||
156 | 3 | /** |
|
157 | * {@inheritdoc} |
||
158 | */ |
||
159 | public function setPath($location) { |
||
160 | |||
161 | if ( !is_string($location) ) throw new CookieException("Invalid path attribute"); |
||
162 | |||
163 | 3 | $this->path = $location; |
|
164 | |||
165 | 3 | return $this; |
|
166 | |||
167 | 3 | } |
|
168 | |||
169 | 3 | /** |
|
170 | * {@inheritdoc} |
||
171 | */ |
||
172 | public function setDomain($domain) { |
||
173 | |||
174 | if ( !is_scalar($domain) || !CookieTools::checkDomain($domain) ) throw new CookieException("Invalid domain attribute"); |
||
175 | |||
176 | 3 | $this->domain = $domain; |
|
177 | |||
178 | 3 | return $this; |
|
179 | |||
180 | 3 | } |
|
181 | |||
182 | 3 | /** |
|
183 | * {@inheritdoc} |
||
184 | */ |
||
185 | public function setSecure($mode = true) { |
||
186 | |||
187 | $this->secure = filter_var($mode, FILTER_VALIDATE_BOOLEAN); |
||
188 | |||
189 | 3 | return $this; |
|
190 | |||
191 | 3 | } |
|
192 | |||
193 | 3 | /** |
|
194 | * {@inheritdoc} |
||
195 | */ |
||
196 | public function setHttponly($mode = true) { |
||
197 | |||
198 | $this->httponly = filter_var($mode, FILTER_VALIDATE_BOOLEAN); |
||
199 | |||
200 | 3 | return $this; |
|
201 | |||
202 | 3 | } |
|
203 | |||
204 | 3 | /** |
|
205 | * {@inheritdoc} |
||
206 | */ |
||
207 | public function save() { |
||
208 | |||
209 | if ( setcookie( |
||
210 | $this->name, |
||
211 | $this->value, |
||
212 | $this->expire, |
||
213 | $this->path, |
||
214 | $this->domain, |
||
215 | $this->secure, |
||
216 | $this->httponly |
||
217 | ) === false ) throw new CookieException("Cannot set cookie: ".$this->name); |
||
218 | |||
219 | return true; |
||
220 | |||
221 | } |
||
222 | |||
223 | /** |
||
224 | * {@inheritdoc} |
||
225 | */ |
||
226 | public function load() { |
||
227 | |||
228 | if ( !$this->exists() ) throw new CookieException("Cookie does not exists"); |
||
229 | |||
230 | 12 | $this->value = $_COOKIE[$this->name]; |
|
231 | |||
232 | 12 | return $this; |
|
233 | |||
234 | } |
||
235 | |||
236 | /** |
||
237 | * {@inheritdoc} |
||
238 | */ |
||
239 | public function delete() { |
||
240 | |||
241 | if ( !$this->exists() ) return true; |
||
242 | |||
243 | 6 | if ( setcookie( |
|
244 | $this->name, |
||
245 | 6 | null, |
|
246 | time() - 86400, |
||
247 | null, |
||
248 | null, |
||
249 | $this->secure, |
||
250 | $this->httponly |
||
251 | ) === false ) throw new CookieException("Cannot delete cookie"); |
||
252 | |||
253 | return true; |
||
254 | |||
255 | } |
||
256 | |||
257 | /** |
||
258 | * {@inheritdoc} |
||
259 | */ |
||
260 | public function exists() { |
||
261 | |||
262 | return isset($_COOKIE[$this->name]); |
||
263 | |||
264 | 21 | } |
|
265 | |||
266 | 21 | /** |
|
267 | * Static method to quickly delete a cookie |
||
268 | * |
||
269 | * @param string $name |
||
270 | * The cookie name |
||
271 | * |
||
272 | * @return boolean |
||
273 | * @throws CookieException |
||
274 | */ |
||
275 | public static function erase($name) { |
||
276 | |||
277 | try { |
||
278 | |||
279 | 3 | $class = get_called_class(); |
|
280 | |||
281 | $cookie = new $class($name); |
||
282 | |||
283 | 3 | return $cookie->delete(); |
|
284 | |||
285 | 3 | } catch (CookieException $ce) { |
|
286 | |||
287 | 3 | throw $ce; |
|
288 | |||
289 | } |
||
290 | |||
291 | } |
||
292 | |||
293 | } |
||
294 |
Adding explicit visibility (
private
,protected
, orpublic
) is generally recommend to communicate to other developers how, and from where this method is intended to be used.