PageRenderTime 58ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/html/cakephp/test/cake/libs/controller/components/cookie.php

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