Mercurial > hg > Members > shoshi > webvirt
comparison cake/libs/controller/components/cookie.php @ 0:261e66bd5a0c
hg init
author | Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 24 Jul 2011 21:08:31 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:261e66bd5a0c |
---|---|
1 <?php | |
2 /** | |
3 * Cookie Component | |
4 * | |
5 * PHP versions 4 and 5 | |
6 * | |
7 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | |
8 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
9 * | |
10 * Licensed under The MIT License | |
11 * Redistributions of files must retain the above copyright notice. | |
12 * | |
13 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
14 * @link http://cakephp.org CakePHP(tm) Project | |
15 * @package cake | |
16 * @subpackage cake.cake.libs.controller.components | |
17 * @since CakePHP(tm) v 1.2.0.4213 | |
18 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
19 */ | |
20 | |
21 /** | |
22 * Load Security class | |
23 */ | |
24 App::import('Core', 'Security'); | |
25 | |
26 /** | |
27 * Cookie Component. | |
28 * | |
29 * Cookie handling for the controller. | |
30 * | |
31 * @package cake | |
32 * @subpackage cake.cake.libs.controller.components | |
33 * @link http://book.cakephp.org/view/1280/Cookies | |
34 * | |
35 */ | |
36 class CookieComponent extends Object { | |
37 | |
38 /** | |
39 * The name of the cookie. | |
40 * | |
41 * Overridden with the controller beforeFilter(); | |
42 * $this->Cookie->name = 'CookieName'; | |
43 * | |
44 * @var string | |
45 * @access public | |
46 */ | |
47 var $name = 'CakeCookie'; | |
48 | |
49 /** | |
50 * The time a cookie will remain valid. | |
51 * | |
52 * Can be either integer Unix timestamp or a date string. | |
53 * | |
54 * Overridden with the controller beforeFilter(); | |
55 * $this->Cookie->time = '5 Days'; | |
56 * | |
57 * @var mixed | |
58 * @access public | |
59 */ | |
60 var $time = null; | |
61 | |
62 /** | |
63 * Cookie path. | |
64 * | |
65 * Overridden with the controller beforeFilter(); | |
66 * $this->Cookie->path = '/'; | |
67 * | |
68 * The path on the server in which the cookie will be available on. | |
69 * If var $cookiePath is set to '/foo/', the cookie will only be available | |
70 * within the /foo/ directory and all sub-directories such as /foo/bar/ of domain. | |
71 * The default value is the entire domain. | |
72 * | |
73 * @var string | |
74 * @access public | |
75 */ | |
76 var $path = '/'; | |
77 | |
78 /** | |
79 * Domain path. | |
80 * | |
81 * The domain that the cookie is available. | |
82 * | |
83 * Overridden with the controller beforeFilter(); | |
84 * $this->Cookie->domain = '.example.com'; | |
85 * | |
86 * To make the cookie available on all subdomains of example.com. | |
87 * Set $this->Cookie->domain = '.example.com'; in your controller beforeFilter | |
88 * | |
89 * @var string | |
90 * @access public | |
91 */ | |
92 var $domain = ''; | |
93 | |
94 /** | |
95 * Secure HTTPS only cookie. | |
96 * | |
97 * Overridden with the controller beforeFilter(); | |
98 * $this->Cookie->secure = true; | |
99 * | |
100 * Indicates that the cookie should only be transmitted over a secure HTTPS connection. | |
101 * When set to true, the cookie will only be set if a secure connection exists. | |
102 * | |
103 * @var boolean | |
104 * @access public | |
105 */ | |
106 var $secure = false; | |
107 | |
108 /** | |
109 * Encryption key. | |
110 * | |
111 * Overridden with the controller beforeFilter(); | |
112 * $this->Cookie->key = 'SomeRandomString'; | |
113 * | |
114 * @var string | |
115 * @access protected | |
116 */ | |
117 var $key = null; | |
118 | |
119 /** | |
120 * Values stored in the cookie. | |
121 * | |
122 * Accessed in the controller using $this->Cookie->read('Name.key'); | |
123 * | |
124 * @see CookieComponent::read(); | |
125 * @var string | |
126 * @access private | |
127 */ | |
128 var $__values = array(); | |
129 | |
130 /** | |
131 * Type of encryption to use. | |
132 * | |
133 * Currently only one method is available | |
134 * Defaults to Security::cipher(); | |
135 * | |
136 * @var string | |
137 * @access private | |
138 * @todo add additional encryption methods | |
139 */ | |
140 var $__type = 'cipher'; | |
141 | |
142 /** | |
143 * Used to reset cookie time if $expire is passed to CookieComponent::write() | |
144 * | |
145 * @var string | |
146 * @access private | |
147 */ | |
148 var $__reset = null; | |
149 | |
150 /** | |
151 * Expire time of the cookie | |
152 * | |
153 * This is controlled by CookieComponent::time; | |
154 * | |
155 * @var string | |
156 * @access private | |
157 */ | |
158 var $__expires = 0; | |
159 | |
160 /** | |
161 * Main execution method. | |
162 * | |
163 * @param object $controller A reference to the instantiating controller object | |
164 * @access public | |
165 */ | |
166 function initialize(&$controller, $settings) { | |
167 $this->key = Configure::read('Security.salt'); | |
168 $this->_set($settings); | |
169 if (isset($this->time)) { | |
170 $this->__expire($this->time); | |
171 } | |
172 } | |
173 | |
174 /** | |
175 * Start CookieComponent for use in the controller | |
176 * | |
177 * @access public | |
178 */ | |
179 function startup() { | |
180 $this->__expire($this->time); | |
181 | |
182 if (isset($_COOKIE[$this->name])) { | |
183 $this->__values = $this->__decrypt($_COOKIE[$this->name]); | |
184 } | |
185 } | |
186 | |
187 /** | |
188 * Write a value to the $_COOKIE[$key]; | |
189 * | |
190 * Optional [Name.], required key, optional $value, optional $encrypt, optional $expires | |
191 * $this->Cookie->write('[Name.]key, $value); | |
192 * | |
193 * By default all values are encrypted. | |
194 * You must pass $encrypt false to store values in clear test | |
195 * | |
196 * You must use this method before any output is sent to the browser. | |
197 * Failure to do so will result in header already sent errors. | |
198 * | |
199 * @param mixed $key Key for the value | |
200 * @param mixed $value Value | |
201 * @param boolean $encrypt Set to true to encrypt value, false otherwise | |
202 * @param string $expires Can be either Unix timestamp, or date string | |
203 * @access public | |
204 */ | |
205 function write($key, $value = null, $encrypt = true, $expires = null) { | |
206 if (is_null($encrypt)) { | |
207 $encrypt = true; | |
208 } | |
209 $this->__encrypted = $encrypt; | |
210 $this->__expire($expires); | |
211 | |
212 if (!is_array($key)) { | |
213 $key = array($key => $value); | |
214 } | |
215 | |
216 foreach ($key as $name => $value) { | |
217 if (strpos($name, '.') === false) { | |
218 $this->__values[$name] = $value; | |
219 $this->__write("[$name]", $value); | |
220 | |
221 } else { | |
222 $names = explode('.', $name, 2); | |
223 if (!isset($this->__values[$names[0]])) { | |
224 $this->__values[$names[0]] = array(); | |
225 } | |
226 $this->__values[$names[0]] = Set::insert($this->__values[$names[0]], $names[1], $value); | |
227 $this->__write('[' . implode('][', $names) . ']', $value); | |
228 } | |
229 } | |
230 $this->__encrypted = true; | |
231 } | |
232 | |
233 /** | |
234 * Read the value of the $_COOKIE[$key]; | |
235 * | |
236 * Optional [Name.], required key | |
237 * $this->Cookie->read(Name.key); | |
238 * | |
239 * @param mixed $key Key of the value to be obtained. If none specified, obtain map key => values | |
240 * @return string or null, value for specified key | |
241 * @access public | |
242 */ | |
243 function read($key = null) { | |
244 if (empty($this->__values) && isset($_COOKIE[$this->name])) { | |
245 $this->__values = $this->__decrypt($_COOKIE[$this->name]); | |
246 } | |
247 | |
248 if (is_null($key)) { | |
249 return $this->__values; | |
250 } | |
251 | |
252 if (strpos($key, '.') !== false) { | |
253 $names = explode('.', $key, 2); | |
254 $key = $names[0]; | |
255 } | |
256 if (!isset($this->__values[$key])) { | |
257 return null; | |
258 } | |
259 | |
260 if (!empty($names[1])) { | |
261 return Set::extract($this->__values[$key], $names[1]); | |
262 } | |
263 return $this->__values[$key]; | |
264 } | |
265 | |
266 /** | |
267 * Delete a cookie value | |
268 * | |
269 * Optional [Name.], required key | |
270 * $this->Cookie->read('Name.key); | |
271 * | |
272 * You must use this method before any output is sent to the browser. | |
273 * Failure to do so will result in header already sent errors. | |
274 * | |
275 * @param string $key Key of the value to be deleted | |
276 * @return void | |
277 * @access public | |
278 */ | |
279 function delete($key) { | |
280 if (empty($this->__values)) { | |
281 $this->read(); | |
282 } | |
283 if (strpos($key, '.') === false) { | |
284 if (isset($this->__values[$key]) && is_array($this->__values[$key])) { | |
285 foreach ($this->__values[$key] as $idx => $val) { | |
286 $this->__delete("[$key][$idx]"); | |
287 } | |
288 } else { | |
289 $this->__delete("[$key]"); | |
290 } | |
291 unset($this->__values[$key]); | |
292 return; | |
293 } | |
294 $names = explode('.', $key, 2); | |
295 $this->__values[$names[0]] = Set::remove($this->__values[$names[0]], $names[1]); | |
296 $this->__delete('[' . implode('][', $names) . ']'); | |
297 } | |
298 | |
299 /** | |
300 * Destroy current cookie | |
301 * | |
302 * You must use this method before any output is sent to the browser. | |
303 * Failure to do so will result in header already sent errors. | |
304 * | |
305 * @return void | |
306 * @access public | |
307 */ | |
308 function destroy() { | |
309 if (isset($_COOKIE[$this->name])) { | |
310 $this->__values = $this->__decrypt($_COOKIE[$this->name]); | |
311 } | |
312 | |
313 foreach ($this->__values as $name => $value) { | |
314 if (is_array($value)) { | |
315 foreach ($value as $key => $val) { | |
316 unset($this->__values[$name][$key]); | |
317 $this->__delete("[$name][$key]"); | |
318 } | |
319 } | |
320 unset($this->__values[$name]); | |
321 $this->__delete("[$name]"); | |
322 } | |
323 } | |
324 | |
325 /** | |
326 * Will allow overriding default encryption method. | |
327 * | |
328 * @param string $type Encryption method | |
329 * @access public | |
330 * @todo NOT IMPLEMENTED | |
331 */ | |
332 function type($type = 'cipher') { | |
333 $this->__type = 'cipher'; | |
334 } | |
335 | |
336 /** | |
337 * Set the expire time for a session variable. | |
338 * | |
339 * Creates a new expire time for a session variable. | |
340 * $expire can be either integer Unix timestamp or a date string. | |
341 * | |
342 * Used by write() | |
343 * CookieComponent::write(string, string, boolean, 8400); | |
344 * CookieComponent::write(string, string, boolean, '5 Days'); | |
345 * | |
346 * @param mixed $expires Can be either Unix timestamp, or date string | |
347 * @return int Unix timestamp | |
348 * @access private | |
349 */ | |
350 function __expire($expires = null) { | |
351 $now = time(); | |
352 if (is_null($expires)) { | |
353 return $this->__expires; | |
354 } | |
355 $this->__reset = $this->__expires; | |
356 | |
357 if ($expires == 0) { | |
358 return $this->__expires = 0; | |
359 } | |
360 | |
361 if (is_integer($expires) || is_numeric($expires)) { | |
362 return $this->__expires = $now + intval($expires); | |
363 } | |
364 return $this->__expires = strtotime($expires, $now); | |
365 } | |
366 | |
367 /** | |
368 * Set cookie | |
369 * | |
370 * @param string $name Name for cookie | |
371 * @param string $value Value for cookie | |
372 * @access private | |
373 */ | |
374 function __write($name, $value) { | |
375 setcookie($this->name . $name, $this->__encrypt($value), $this->__expires, $this->path, $this->domain, $this->secure); | |
376 | |
377 if (!is_null($this->__reset)) { | |
378 $this->__expires = $this->__reset; | |
379 $this->__reset = null; | |
380 } | |
381 } | |
382 | |
383 /** | |
384 * Sets a cookie expire time to remove cookie value | |
385 * | |
386 * @param string $name Name of cookie | |
387 * @access private | |
388 */ | |
389 function __delete($name) { | |
390 setcookie($this->name . $name, '', time() - 42000, $this->path, $this->domain, $this->secure); | |
391 } | |
392 | |
393 /** | |
394 * Encrypts $value using var $type method in Security class | |
395 * | |
396 * @param string $value Value to encrypt | |
397 * @return string encrypted string | |
398 * @access private | |
399 */ | |
400 function __encrypt($value) { | |
401 if (is_array($value)) { | |
402 $value = $this->__implode($value); | |
403 } | |
404 | |
405 if ($this->__encrypted === true) { | |
406 $type = $this->__type; | |
407 $value = "Q2FrZQ==." .base64_encode(Security::$type($value, $this->key)); | |
408 } | |
409 return $value; | |
410 } | |
411 | |
412 /** | |
413 * Decrypts $value using var $type method in Security class | |
414 * | |
415 * @param array $values Values to decrypt | |
416 * @return string decrypted string | |
417 * @access private | |
418 */ | |
419 function __decrypt($values) { | |
420 $decrypted = array(); | |
421 $type = $this->__type; | |
422 | |
423 foreach ((array)$values as $name => $value) { | |
424 if (is_array($value)) { | |
425 foreach ($value as $key => $val) { | |
426 $pos = strpos($val, 'Q2FrZQ==.'); | |
427 $decrypted[$name][$key] = $this->__explode($val); | |
428 | |
429 if ($pos !== false) { | |
430 $val = substr($val, 8); | |
431 $decrypted[$name][$key] = $this->__explode(Security::$type(base64_decode($val), $this->key)); | |
432 } | |
433 } | |
434 } else { | |
435 $pos = strpos($value, 'Q2FrZQ==.'); | |
436 $decrypted[$name] = $this->__explode($value); | |
437 | |
438 if ($pos !== false) { | |
439 $value = substr($value, 8); | |
440 $decrypted[$name] = $this->__explode(Security::$type(base64_decode($value), $this->key)); | |
441 } | |
442 } | |
443 } | |
444 return $decrypted; | |
445 } | |
446 | |
447 /** | |
448 * Implode method to keep keys are multidimensional arrays | |
449 * | |
450 * @param array $array Map of key and values | |
451 * @return string String in the form key1|value1,key2|value2 | |
452 * @access private | |
453 */ | |
454 function __implode($array) { | |
455 $string = ''; | |
456 foreach ($array as $key => $value) { | |
457 $string .= ',' . $key . '|' . $value; | |
458 } | |
459 return substr($string, 1); | |
460 } | |
461 | |
462 /** | |
463 * Explode method to return array from string set in CookieComponent::__implode() | |
464 * | |
465 * @param string $string String in the form key1|value1,key2|value2 | |
466 * @return array Map of key and values | |
467 * @access private | |
468 */ | |
469 function __explode($string) { | |
470 $array = array(); | |
471 foreach (explode(',', $string) as $pair) { | |
472 $key = explode('|', $pair); | |
473 if (!isset($key[1])) { | |
474 return $key[0]; | |
475 } | |
476 $array[$key[0]] = $key[1]; | |
477 } | |
478 return $array; | |
479 } | |
480 } |