cookie.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: cookie.php 8260 2009-07-28 20:01:42Z DarkAngelBGE $ */
00003 /**
00004  * Short description for file.
00005  *
00006  * Long description for file
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.libs.controller.components
00021  * @since         CakePHP(tm) v 1.2.0.4213
00022  * @version       $Revision: 8260 $
00023  * @modifiedby    $LastChangedBy: DarkAngelBGE $
00024  * @lastmodified  $Date: 2009-07-28 16:01:42 -0400 (Tue, 28 Jul 2009) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 /**
00028  * Load Security class
00029  */
00030 App::import('Core', 'Security');
00031 /**
00032  * Cookie Component.
00033  *
00034  * Cookie handling for the controller.
00035  *
00036  * @package       cake
00037  * @subpackage    cake.cake.libs.controller.components
00038  *
00039  */
00040 class CookieComponent extends Object {
00041 /**
00042  * The name of the cookie.
00043  *
00044  * Overridden with the controller beforeFilter();
00045  * $this->Cookie->name = 'CookieName';
00046  *
00047  * @var string
00048  * @access public
00049  */
00050     var $name = 'CakeCookie';
00051 /**
00052  * The time a cookie will remain valid.
00053  *
00054  * Can be either integer Unix timestamp or a date string.
00055  *
00056  * Overridden with the controller beforeFilter();
00057  * $this->Cookie->time = '5 Days';
00058  *
00059  * @var mixed
00060  * @access public
00061  */
00062     var $time = null;
00063 /**
00064  * Cookie path.
00065  *
00066  * Overridden with the controller beforeFilter();
00067  * $this->Cookie->path = '/';
00068  *
00069  * The path on the server in which the cookie will be available on.
00070  * If  var $cookiePath is set to '/foo/', the cookie will only be available
00071  * within the /foo/ directory and all sub-directories such as /foo/bar/ of domain.
00072  * The default value is the entire domain.
00073  *
00074  * @var string
00075  * @access public
00076  */
00077     var $path = '/';
00078 /**
00079  * Domain path.
00080  *
00081  * The domain that the cookie is available.
00082  *
00083  * Overridden with the controller beforeFilter();
00084  * $this->Cookie->domain = '.example.com';
00085  *
00086  * To make the cookie available on all subdomains of example.com.
00087  * Set $this->Cookie->domain = '.example.com'; in your controller beforeFilter
00088  *
00089  * @var string
00090  * @access public
00091  */
00092     var $domain = '';
00093 /**
00094  * Secure HTTPS only cookie.
00095  *
00096  * Overridden with the controller beforeFilter();
00097  * $this->Cookie->secure = true;
00098  *
00099  * Indicates that the cookie should only be transmitted over a secure HTTPS connection.
00100  * When set to true, the cookie will only be set if a secure connection exists.
00101  *
00102  * @var boolean
00103  * @access public
00104  */
00105     var $secure = false;
00106 /**
00107  * Encryption key.
00108  *
00109  * Overridden with the controller beforeFilter();
00110  * $this->Cookie->key = 'SomeRandomString';
00111  *
00112  * @var string
00113  * @access protected
00114  */
00115     var $key = null;
00116 /**
00117  * Values stored in the cookie.
00118  *
00119  * Accessed in the controller using $this->Cookie->read('Name.key');
00120  *
00121  * @see CookieComponent::read();
00122  * @var string
00123  * @access private
00124  */
00125     var $__values = array();
00126 /**
00127  * Type of encryption to use.
00128  *
00129  * Currently only one method is available
00130  * Defaults to Security::cipher();
00131  *
00132  * @var string
00133  * @access private
00134  * @todo add additional encryption methods
00135  */
00136     var $__type = 'cipher';
00137 /**
00138  * Used to reset cookie time if $expire is passed to CookieComponent::write()
00139  *
00140  * @var string
00141  * @access private
00142  */
00143     var $__reset = null;
00144 /**
00145  * Expire time of the cookie
00146  *
00147  * This is controlled by CookieComponent::time;
00148  *
00149  * @var string
00150  * @access private
00151  */
00152     var $__expires = 0;
00153 /**
00154  * Main execution method.
00155  *
00156  * @param object $controller A reference to the instantiating controller object
00157  * @access public
00158  */
00159     function initialize(&$controller, $settings) {
00160         $this->key = Configure::read('Security.salt');
00161         $this->_set($settings);
00162     }
00163 /**
00164  * Start CookieComponent for use in the controller
00165  *
00166  * @access public
00167  */
00168     function startup() {
00169         $this->__expire($this->time);
00170 
00171         if (isset($_COOKIE[$this->name])) {
00172             $this->__values = $this->__decrypt($_COOKIE[$this->name]);
00173         }
00174     }
00175 /**
00176  * Write a value to the $_COOKIE[$key];
00177  *
00178  * Optional [Name.], reguired key, optional $value, optional $encrypt, optional $expires
00179  * $this->Cookie->write('[Name.]key, $value);
00180  *
00181  * By default all values are encrypted.
00182  * You must pass $encrypt false to store values in clear test
00183  *
00184  * You must use this method before any output is sent to the browser.
00185  * Failure to do so will result in header already sent errors.
00186  *
00187  * @param mixed $key Key for the value
00188  * @param mixed $value Value
00189  * @param boolean $encrypt Set to true to encrypt value, false otherwise
00190  * @param string $expires Can be either Unix timestamp, or date string
00191  * @access public
00192  */
00193     function write($key, $value = null, $encrypt = true, $expires = null) {
00194         if (is_null($encrypt)) {
00195             $encrypt = true;
00196         }
00197 
00198         $this->__encrypted = $encrypt;
00199         $this->__expire($expires);
00200 
00201         if (!is_array($key) && $value !== null) {
00202             $name = $this->__cookieVarNames($key);
00203 
00204             if (count($name) > 1) {
00205                 $this->__values[$name[0]][$name[1]] = $value;
00206                 $this->__write("[" . $name[0] . "][" . $name[1] . "]", $value);
00207             } else {
00208                 $this->__values[$name[0]] = $value;
00209                 $this->__write("[" . $name[0] . "]", $value);
00210             }
00211         } else {
00212             foreach ($key as $names => $value) {
00213                 $name = $this->__cookieVarNames($names);
00214 
00215                 if (count($name) > 1) {
00216                     $this->__values[$name[0]][$name[1]] = $value;
00217                     $this->__write("[" . $name[0] . "][" . $name[1] . "]", $value);
00218                 } else {
00219                     $this->__values[$name[0]] = $value;
00220                     $this->__write("[" . $name[0] . "]", $value);
00221                 }
00222             }
00223         }
00224         $this->__encrypted = true;
00225     }
00226 /**
00227  * Read the value of the $_COOKIE[$key];
00228  *
00229  * Optional [Name.], reguired key
00230  * $this->Cookie->read(Name.key);
00231  *
00232  * @param mixed $key Key of the value to be obtained. If none specified, obtain map key => values
00233  * @return string or null, value for specified key
00234  * @access public
00235  */
00236     function read($key = null) {
00237         if (empty($this->__values) && isset($_COOKIE[$this->name])) {
00238             $this->__values = $this->__decrypt($_COOKIE[$this->name]);
00239         }
00240 
00241         if (is_null($key)) {
00242             return $this->__values;
00243         }
00244         $name = $this->__cookieVarNames($key);
00245 
00246         if (count($name) > 1) {
00247             if (isset($this->__values[$name[0]])) {
00248                 if (isset($this->__values[$name[0]][$name[1]])) {
00249                     return $this->__values[$name[0]][$name[1]];
00250                 }
00251             }
00252             return null;
00253         } else {
00254             if (isset($this->__values[$name[0]])) {
00255                 $value = $this->__values[$name[0]];
00256                 return $value;
00257             }
00258             return null;
00259         }
00260     }
00261 /**
00262  * Delete a cookie value
00263  *
00264  * Optional [Name.], reguired key
00265  * $this->Cookie->read('Name.key);
00266  *
00267  * You must use this method before any output is sent to the browser.
00268  * Failure to do so will result in header already sent errors.
00269  *
00270  * @param string $key Key of the value to be deleted
00271  * @return void
00272  * @access public
00273  */
00274     function del($key) {
00275         if (empty($this->__values)) {
00276             $this->read();
00277         }
00278         $name = $this->__cookieVarNames($key);
00279         if (count($name) > 1) {
00280             if (isset($this->__values[$name[0]])) {
00281                 $this->__delete("[" . $name[0] . "][" . $name[1] . "]");
00282                 unset($this->__values[$name[0]][$name[1]]);
00283             }
00284         } else {
00285             if (isset($this->__values[$name[0]])) {
00286                 if (is_array($this->__values[$name[0]])) {
00287                     foreach ($this->__values[$name[0]] as $key => $value) {
00288                         $this->__delete("[" . $name[0] . "][" . $key . "]");
00289                     }
00290                 }
00291                 $this->__delete("[" . $name[0] . "]");
00292                 unset($this->__values[$name[0]]);
00293             }
00294         }
00295     }
00296 /**
00297  * Destroy current cookie
00298  *
00299  * You must use this method before any output is sent to the browser.
00300  * Failure to do so will result in header already sent errors.
00301  *
00302  * @return void
00303  * @access public
00304  */
00305     function destroy() {
00306         if (isset($_COOKIE[$this->name])) {
00307             $this->__values = $this->__decrypt($_COOKIE[$this->name]);
00308         }
00309 
00310         foreach ($this->__values as $name => $value) {
00311             if (is_array($value)) {
00312                 foreach ($value as $key => $val) {
00313                     unset($this->__values[$name][$key]);
00314                     $this->__delete("[$name][$key]");
00315                 }
00316             }
00317             unset($this->__values[$name]);
00318             $this->__delete("[$name]");
00319         }
00320     }
00321 /**
00322  * Will allow overriding default encryption method.
00323  *
00324  * @param string $type Encryption method
00325  * @access public
00326  * @todo NOT IMPLEMENTED
00327  */
00328     function type($type = 'cipher') {
00329         $this->__type = 'cipher';
00330     }
00331 /**
00332  * Set the expire time for a session variable.
00333  *
00334  * Creates a new expire time for a session variable.
00335  * $expire can be either integer Unix timestamp or a date string.
00336  *
00337  * Used by write()
00338  * CookieComponent::write(string, string, boolean, 8400);
00339  * CookieComponent::write(string, string, boolean, '5 Days');
00340  *
00341  * @param mixed $expires Can be either Unix timestamp, or date string
00342  * @return int Unix timestamp
00343  * @access private
00344  */
00345     function __expire($expires = null) {
00346         $now = time();
00347         if (is_null($expires)) {
00348             return $this->__expires;
00349         }
00350         $this->__reset = $this->__expires;
00351         if (is_integer($expires) || is_numeric($expires)) {
00352             return $this->__expires = $now + intval($expires);
00353         }
00354         return $this->__expires = strtotime($expires, $now);
00355     }
00356 /**
00357  * Set cookie
00358  *
00359  * @param string $name Name for cookie
00360  * @param string $value Value for cookie
00361  * @access private
00362  */
00363     function __write($name, $value) {
00364         setcookie($this->name . "$name", $this->__encrypt($value), $this->__expires, $this->path, $this->domain, $this->secure);
00365 
00366         if (!is_null($this->__reset)) {
00367             $this->__expires = $this->__reset;
00368             $this->__reset = null;
00369         }
00370     }
00371 /**
00372  * Sets a cookie expire time to remove cookie value
00373  *
00374  * @param string $name Name of cookie
00375  * @access private
00376  */
00377     function __delete($name) {
00378         setcookie($this->name . $name, '', time() - 42000, $this->path, $this->domain, $this->secure);
00379     }
00380 /**
00381  * Encrypts $value using var $type method in Security class
00382  *
00383  * @param string $value Value to encrypt
00384  * @return string encrypted string
00385  * @access private
00386  */
00387     function __encrypt($value) {
00388         if (is_array($value)) {
00389             $value = $this->__implode($value);
00390         }
00391 
00392         if ($this->__encrypted === true) {
00393             $type = $this->__type;
00394             $value = "Q2FrZQ==." .base64_encode(Security::$type($value, $this->key));
00395         }
00396         return($value);
00397     }
00398 /**
00399  * Decrypts $value using var $type method in Security class
00400  *
00401  * @param array $values Values to decrypt
00402  * @return string decrypted string
00403  * @access private
00404  */
00405     function __decrypt($values) {
00406         $decrypted = array();
00407         $type = $this->__type;
00408 
00409         foreach ($values as $name => $value) {
00410             if (is_array($value)) {
00411                 foreach ($value as $key => $val) {
00412                     $pos = strpos($val, 'Q2FrZQ==.');
00413                     $decrypted[$name][$key] = $this->__explode($val);
00414 
00415                     if ($pos !== false) {
00416                         $val = substr($val, 8);
00417                         $decrypted[$name][$key] = $this->__explode(Security::$type(base64_decode($val), $this->key));
00418                     }
00419                 }
00420             } else {
00421                 $pos = strpos($value, 'Q2FrZQ==.');
00422                 $decrypted[$name] = $this->__explode($value);
00423 
00424                 if ($pos !== false) {
00425                     $value = substr($value, 8);
00426                     $decrypted[$name] = $this->__explode(Security::$type(base64_decode($value), $this->key));
00427                 }
00428             }
00429         }
00430 
00431         return($decrypted);
00432     }
00433 
00434 /**
00435  * Creates an array from the $name parameter which allows the dot notation
00436  * similar to one used by Session and Configure classes
00437  *
00438  * @param string $name Name with or without dot notation
00439  * @return array Extracted names
00440  * @access private
00441  */
00442     function __cookieVarNames($name) {
00443         if (is_string($name)) {
00444             if (strpos($name, ".")) {
00445                 $name = explode(".", $name);
00446             } else {
00447                 $name = array($name);
00448             }
00449         }
00450         return $name;
00451     }
00452 /**
00453  * Implode method to keep keys are multidimensional arrays
00454  *
00455  * @param array $array Map of key and values
00456  * @return string String in the form key1|value1,key2|value2
00457  * @access private
00458  */
00459     function __implode($array) {
00460         $string = '';
00461         foreach ($array as $key => $value) {
00462             $string .= ',' . $key . '|' . $value;
00463         }
00464         return substr($string, 1);
00465     }
00466 /**
00467  * Explode method to return array from string set in CookieComponent::__implode()
00468  *
00469  * @param string $string String in the form key1|value1,key2|value2
00470  * @return array Map of key and values
00471  * @access private
00472  */
00473     function __explode($string) {
00474         $array = array();
00475         foreach (explode(',', $string) as $pair) {
00476             $key = explode('|', $pair);
00477             if (!isset($key[1])) {
00478                 return $key[0];
00479             }
00480             $array[$key[0]] = $key[1];
00481         }
00482         return $array;
00483     }
00484 }
00485 ?>

Generated on Sun Nov 22 00:30:52 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7