CakePHP
  • Documentation
    • Book
    • API
    • Videos
    • Reporting Security Issues
    • Privacy Policy
    • Logos & Trademarks
  • Business Solutions
  • Swag
  • Road Trip
  • Team
  • Community
    • Community
    • Get Involved
    • Issues (GitHub)
    • Bakery
    • Featured Resources
    • Training
    • Meetups
    • My CakePHP
    • CakeFest
    • Newsletter
    • Linkedin
    • YouTube
    • Facebook
    • Twitter
    • Mastodon
    • Help & Support
    • Forum
    • Stack Overflow
    • Slack
    • Paid Support
CakePHP

C CakePHP 2.1 API

  • Overview
  • Tree
  • Deprecated
  • Version:
    • 2.1
      • 4.2
      • 4.1
      • 4.0
      • 3.9
      • 3.8
      • 3.7
      • 3.6
      • 3.5
      • 3.4
      • 3.3
      • 3.2
      • 3.1
      • 3.0
      • 2.10
      • 2.9
      • 2.8
      • 2.7
      • 2.6
      • 2.5
      • 2.4
      • 2.3
      • 2.2
      • 2.1
      • 2.0
      • 1.3
      • 1.2

Packages

  • Cake
    • Cache
      • Engine
    • Configure
    • Console
      • Command
        • Task
    • Controller
      • Component
        • Acl
        • Auth
    • Core
    • Error
    • Event
    • I18n
    • Log
      • Engine
    • Model
      • Behavior
      • Datasource
        • Database
        • Session
    • Network
      • Email
      • Http
    • Routing
      • Route
    • TestSuite
      • Coverage
      • Fixture
      • Reporter
    • Utility
    • View
      • Helper

Classes

  • CakeSession
  • DataSource
  • DboSource
  1: <?php
  2: /**
  3:  * Session class for Cake.
  4:  *
  5:  * Cake abstracts the handling of sessions.
  6:  * There are several convenient methods to access session information.
  7:  * This class is the implementation of those methods.
  8:  * They are mostly used by the Session Component.
  9:  *
 10:  * PHP 5
 11:  *
 12:  * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 13:  * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 14:  *
 15:  * Licensed under The MIT License
 16:  * Redistributions of files must retain the above copyright notice.
 17:  *
 18:  * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 19:  * @link          http://cakephp.org CakePHP(tm) Project
 20:  * @package       Cake.Model.Datasource
 21:  * @since         CakePHP(tm) v .0.10.0.1222
 22:  * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 23:  */
 24: 
 25: App::uses('Set', 'Utility');
 26: App::uses('Security', 'Utility');
 27: 
 28: /**
 29:  * Session class for Cake.
 30:  *
 31:  * Cake abstracts the handling of sessions. There are several convenient methods to access session information.
 32:  * This class is the implementation of those methods. They are mostly used by the Session Component.
 33:  *
 34:  * @package       Cake.Model.Datasource
 35:  */
 36: class CakeSession {
 37: 
 38: /**
 39:  * True if the Session is still valid
 40:  *
 41:  * @var boolean
 42:  */
 43:     public static $valid = false;
 44: 
 45: /**
 46:  * Error messages for this session
 47:  *
 48:  * @var array
 49:  */
 50:     public static $error = false;
 51: 
 52: /**
 53:  * User agent string
 54:  *
 55:  * @var string
 56:  */
 57:     protected static $_userAgent = '';
 58: 
 59: /**
 60:  * Path to where the session is active.
 61:  *
 62:  * @var string
 63:  */
 64:     public static $path = '/';
 65: 
 66: /**
 67:  * Error number of last occurred error
 68:  *
 69:  * @var integer
 70:  */
 71:     public static $lastError = null;
 72: 
 73: /**
 74:  * Start time for this session.
 75:  *
 76:  * @var integer
 77:  */
 78:     public static $time = false;
 79: 
 80: /**
 81:  * Cookie lifetime
 82:  *
 83:  * @var integer
 84:  */
 85:     public static $cookieLifeTime;
 86: 
 87: /**
 88:  * Time when this session becomes invalid.
 89:  *
 90:  * @var integer
 91:  */
 92:     public static $sessionTime = false;
 93: 
 94: /**
 95:  * Current Session id
 96:  *
 97:  * @var string
 98:  */
 99:     public static $id = null;
100: 
101: /**
102:  * Hostname
103:  *
104:  * @var string
105:  */
106:     public static $host = null;
107: 
108: /**
109:  * Session timeout multiplier factor
110:  *
111:  * @var integer
112:  */
113:     public static $timeout = null;
114: 
115: /**
116:  * Number of requests that can occur during a session time without the session being renewed.
117:  * This feature is only used when config value `Session.autoRegenerate` is set to true.
118:  *
119:  * @var integer
120:  * @see CakeSession::_checkValid()
121:  */
122:     public static $requestCountdown = 10;
123: 
124: /**
125:  * Constructor.
126:  *
127:  * @param string $base The base path for the Session
128:  * @return void
129:  */
130:     public static function init($base = null) {
131:         self::$time = time();
132: 
133:         $checkAgent = Configure::read('Session.checkAgent');
134:         if (($checkAgent === true || $checkAgent === null) && env('HTTP_USER_AGENT') != null) {
135:             self::$_userAgent = md5(env('HTTP_USER_AGENT') . Configure::read('Security.salt'));
136:         }
137:         self::_setPath($base);
138:         self::_setHost(env('HTTP_HOST'));
139:     }
140: 
141: /**
142:  * Setup the Path variable
143:  *
144:  * @param string $base base path
145:  * @return void
146:  */
147:     protected static function _setPath($base = null) {
148:         if (empty($base)) {
149:             self::$path = '/';
150:             return;
151:         }
152:         if (strpos($base, 'index.php') !== false) {
153:              $base = str_replace('index.php', '', $base);
154:         }
155:         if (strpos($base, '?') !== false) {
156:              $base = str_replace('?', '', $base);
157:         }
158:         self::$path = $base;
159:     }
160: 
161: /**
162:  * Set the host name
163:  *
164:  * @param string $host Hostname
165:  * @return void
166:  */
167:     protected static function _setHost($host) {
168:         self::$host = $host;
169:         if (strpos(self::$host, ':') !== false) {
170:             self::$host = substr(self::$host, 0, strpos(self::$host, ':'));
171:         }
172:     }
173: 
174: /**
175:  * Starts the Session.
176:  *
177:  * @return boolean True if session was started
178:  */
179:     public static function start() {
180:         if (self::started()) {
181:             return true;
182:         }
183:         CakeSession::init();
184:         $id = self::id();
185:         session_write_close();
186:         self::_configureSession();
187:         self::_startSession();
188: 
189:         if (!$id && self::started()) {
190:             self::_checkValid();
191:         }
192: 
193:         self::$error = false;
194:         return self::started();
195:     }
196: 
197: /**
198:  * Determine if Session has been started.
199:  *
200:  * @return boolean True if session has been started.
201:  */
202:     public static function started() {
203:         return isset($_SESSION) && session_id();
204:     }
205: 
206: /**
207:  * Returns true if given variable is set in session.
208:  *
209:  * @param string $name Variable name to check for
210:  * @return boolean True if variable is there
211:  */
212:     public static function check($name = null) {
213:         if (!self::started() && !self::start()) {
214:             return false;
215:         }
216:         if (empty($name)) {
217:             return false;
218:         }
219:         $result = Set::classicExtract($_SESSION, $name);
220:         return isset($result);
221:     }
222: 
223: /**
224:  * Returns the Session id
225:  *
226:  * @param string $id
227:  * @return string Session id
228:  */
229:     public static function id($id = null) {
230:         if ($id) {
231:             self::$id = $id;
232:             session_id(self::$id);
233:         }
234:         if (self::started()) {
235:             return session_id();
236:         }
237:         return self::$id;
238:     }
239: 
240: /**
241:  * Removes a variable from session.
242:  *
243:  * @param string $name Session variable to remove
244:  * @return boolean Success
245:  */
246:     public static function delete($name) {
247:         if (self::check($name)) {
248:             self::_overwrite($_SESSION, Set::remove($_SESSION, $name));
249:             return (self::check($name) == false);
250:         }
251:         self::_setError(2, __d('cake_dev', "%s doesn't exist", $name));
252:         return false;
253:     }
254: 
255: /**
256:  * Used to write new data to _SESSION, since PHP doesn't like us setting the _SESSION var itself
257:  *
258:  * @param array $old Set of old variables => values
259:  * @param array $new New set of variable => value
260:  * @return void
261:  */
262:     protected static function _overwrite(&$old, $new) {
263:         if (!empty($old)) {
264:             foreach ($old as $key => $var) {
265:                 if (!isset($new[$key])) {
266:                     unset($old[$key]);
267:                 }
268:             }
269:         }
270:         foreach ($new as $key => $var) {
271:             $old[$key] = $var;
272:         }
273:     }
274: 
275: /**
276:  * Return error description for given error number.
277:  *
278:  * @param integer $errorNumber Error to set
279:  * @return string Error as string
280:  */
281:     protected static function _error($errorNumber) {
282:         if (!is_array(self::$error) || !array_key_exists($errorNumber, self::$error)) {
283:             return false;
284:         } else {
285:             return self::$error[$errorNumber];
286:         }
287:     }
288: 
289: /**
290:  * Returns last occurred error as a string, if any.
291:  *
292:  * @return mixed Error description as a string, or false.
293:  */
294:     public static function error() {
295:         if (self::$lastError) {
296:             return self::_error(self::$lastError);
297:         }
298:         return false;
299:     }
300: 
301: /**
302:  * Returns true if session is valid.
303:  *
304:  * @return boolean Success
305:  */
306:     public static function valid() {
307:         if (self::read('Config')) {
308:             if (self::_validAgentAndTime() && self::$error === false) {
309:                 self::$valid = true;
310:             } else {
311:                 self::$valid = false;
312:                 self::_setError(1, 'Session Highjacking Attempted !!!');
313:             }
314:         }
315:         return self::$valid;
316:     }
317: 
318: /**
319:  * Tests that the user agent is valid and that the session hasn't 'timed out'.
320:  * Since timeouts are implemented in CakeSession it checks the current self::$time
321:  * against the time the session is set to expire.  The User agent is only checked
322:  * if Session.checkAgent == true.
323:  *
324:  * @return boolean
325:  */
326:     protected static function _validAgentAndTime() {
327:         $config = self::read('Config');
328:         $validAgent = (
329:             Configure::read('Session.checkAgent') === false ||
330:             self::$_userAgent == $config['userAgent']
331:         );
332:         return ($validAgent && self::$time <= $config['time']);
333:     }
334: 
335: /**
336:  * Get / Set the userAgent
337:  *
338:  * @param string $userAgent Set the userAgent
339:  * @return void
340:  */
341:     public static function userAgent($userAgent = null) {
342:         if ($userAgent) {
343:             self::$_userAgent = $userAgent;
344:         }
345:         if (empty(self::$_userAgent)) {
346:             CakeSession::init(self::$path);
347:         }
348:         return self::$_userAgent;
349:     }
350: 
351: /**
352:  * Returns given session variable, or all of them, if no parameters given.
353:  *
354:  * @param mixed $name The name of the session variable (or a path as sent to Set.extract)
355:  * @return mixed The value of the session variable
356:  */
357:     public static function read($name = null) {
358:         if (!self::started() && !self::start()) {
359:             return false;
360:         }
361:         if (is_null($name)) {
362:             return self::_returnSessionVars();
363:         }
364:         if (empty($name)) {
365:             return false;
366:         }
367:         $result = Set::classicExtract($_SESSION, $name);
368: 
369:         if (!is_null($result)) {
370:             return $result;
371:         }
372:         self::_setError(2, "$name doesn't exist");
373:         return null;
374:     }
375: 
376: /**
377:  * Returns all session variables.
378:  *
379:  * @return mixed Full $_SESSION array, or false on error.
380:  */
381:     protected static function _returnSessionVars() {
382:         if (!empty($_SESSION)) {
383:             return $_SESSION;
384:         }
385:         self::_setError(2, 'No Session vars set');
386:         return false;
387:     }
388: 
389: /**
390:  * Writes value to given session variable name.
391:  *
392:  * @param mixed $name Name of variable
393:  * @param string $value Value to write
394:  * @return boolean True if the write was successful, false if the write failed
395:  */
396:     public static function write($name, $value = null) {
397:         if (!self::started() && !self::start()) {
398:             return false;
399:         }
400:         if (empty($name)) {
401:             return false;
402:         }
403:         $write = $name;
404:         if (!is_array($name)) {
405:             $write = array($name => $value);
406:         }
407:         foreach ($write as $key => $val) {
408:             self::_overwrite($_SESSION, Set::insert($_SESSION, $key, $val));
409:             if (Set::classicExtract($_SESSION, $key) !== $val) {
410:                 return false;
411:             }
412:         }
413:         return true;
414:     }
415: 
416: /**
417:  * Helper method to destroy invalid sessions.
418:  *
419:  * @return void
420:  */
421:     public static function destroy() {
422:         if (self::started()) {
423:             session_destroy();
424:         }
425:         self::clear();
426:     }
427: 
428: /**
429:  * Clears the session, the session id, and renew's the session.
430:  *
431:  * @return void
432:  */
433:     public static function clear() {
434:         $_SESSION = null;
435:         self::$id = null;
436:         self::start();
437:         self::renew();
438:     }
439: 
440: /**
441:  * Helper method to initialize a session, based on Cake core settings.
442:  *
443:  * Sessions can be configured with a few shortcut names as well as have any number of ini settings declared.
444:  *
445:  * @return void
446:  * @throws CakeSessionException Throws exceptions when ini_set() fails.
447:  */
448:     protected static function _configureSession() {
449:         $sessionConfig = Configure::read('Session');
450:         $iniSet = function_exists('ini_set');
451: 
452:         if (isset($sessionConfig['defaults'])) {
453:             $defaults = self::_defaultConfig($sessionConfig['defaults']);
454:             if ($defaults) {
455:                 $sessionConfig = Set::merge($defaults, $sessionConfig);
456:             }
457:         }
458:         if (!isset($sessionConfig['ini']['session.cookie_secure']) && env('HTTPS')) {
459:             $sessionConfig['ini']['session.cookie_secure'] = 1;
460:         }
461:         if (isset($sessionConfig['timeout']) && !isset($sessionConfig['cookieTimeout'])) {
462:             $sessionConfig['cookieTimeout'] = $sessionConfig['timeout'];
463:         }
464:         if (!isset($sessionConfig['ini']['session.cookie_lifetime'])) {
465:             $sessionConfig['ini']['session.cookie_lifetime'] = $sessionConfig['cookieTimeout'] * 60;
466:         }
467:         if (!isset($sessionConfig['ini']['session.name'])) {
468:             $sessionConfig['ini']['session.name'] = $sessionConfig['cookie'];
469:         }
470:         if (!empty($sessionConfig['handler'])) {
471:             $sessionConfig['ini']['session.save_handler'] = 'user';
472:         }
473:         if (!isset($sessionConfig['ini']['session.gc_maxlifetime'])) {
474:             $sessionConfig['ini']['session.gc_maxlifetime'] = $sessionConfig['timeout'] * 60;
475:         }
476: 
477:         if (empty($_SESSION)) {
478:             if (!empty($sessionConfig['ini']) && is_array($sessionConfig['ini'])) {
479:                 foreach ($sessionConfig['ini'] as $setting => $value) {
480:                     if (ini_set($setting, $value) === false) {
481:                         throw new CakeSessionException(sprintf(
482:                             __d('cake_dev', 'Unable to configure the session, setting %s failed.'),
483:                             $setting
484:                         ));
485:                     }
486:                 }
487:             }
488:         }
489:         if (!empty($sessionConfig['handler']) && !isset($sessionConfig['handler']['engine'])) {
490:             call_user_func_array('session_set_save_handler', $sessionConfig['handler']);
491:         }
492:         if (!empty($sessionConfig['handler']['engine'])) {
493:             $handler = self::_getHandler($sessionConfig['handler']['engine']);
494:             session_set_save_handler(
495:                 array($handler, 'open'),
496:                 array($handler, 'close'),
497:                 array($handler, 'read'),
498:                 array($handler, 'write'),
499:                 array($handler, 'destroy'),
500:                 array($handler, 'gc')
501:             );
502:         }
503:         Configure::write('Session', $sessionConfig);
504:         self::$sessionTime = self::$time + ($sessionConfig['timeout'] * 60);
505:     }
506: 
507: /**
508:  * Find the handler class and make sure it implements the correct interface.
509:  *
510:  * @param string $handler
511:  * @return void
512:  * @throws CakeSessionException
513:  */
514:     protected static function _getHandler($handler) {
515:         list($plugin, $class) = pluginSplit($handler, true);
516:         App::uses($class, $plugin . 'Model/Datasource/Session');
517:         if (!class_exists($class)) {
518:             throw new CakeSessionException(__d('cake_dev', 'Could not load %s to handle the session.', $class));
519:         }
520:         $handler = new $class();
521:         if ($handler instanceof CakeSessionHandlerInterface) {
522:             return $handler;
523:         }
524:         throw new CakeSessionException(__d('cake_dev', 'Chosen SessionHandler does not implement CakeSessionHandlerInterface it cannot be used with an engine key.'));
525:     }
526: 
527: /**
528:  * Get one of the prebaked default session configurations.
529:  *
530:  * @param string $name
531:  * @return boolean|array
532:  */
533:     protected static function _defaultConfig($name) {
534:         $defaults = array(
535:             'php' => array(
536:                 'cookie' => 'CAKEPHP',
537:                 'timeout' => 240,
538:                 'ini' => array(
539:                     'session.use_trans_sid' => 0,
540:                     'session.cookie_path' => self::$path
541:                 )
542:             ),
543:             'cake' => array(
544:                 'cookie' => 'CAKEPHP',
545:                 'timeout' => 240,
546:                 'ini' => array(
547:                     'session.use_trans_sid' => 0,
548:                     'url_rewriter.tags' => '',
549:                     'session.serialize_handler' => 'php',
550:                     'session.use_cookies' => 1,
551:                     'session.cookie_path' => self::$path,
552:                     'session.auto_start' => 0,
553:                     'session.save_path' => TMP . 'sessions',
554:                     'session.save_handler' => 'files'
555:                 )
556:             ),
557:             'cache' => array(
558:                 'cookie' => 'CAKEPHP',
559:                 'timeout' => 240,
560:                 'ini' => array(
561:                     'session.use_trans_sid' => 0,
562:                     'url_rewriter.tags' => '',
563:                     'session.auto_start' => 0,
564:                     'session.use_cookies' => 1,
565:                     'session.cookie_path' => self::$path,
566:                     'session.save_handler' => 'user',
567:                 ),
568:                 'handler' => array(
569:                     'engine' => 'CacheSession',
570:                     'config' => 'default'
571:                 )
572:             ),
573:             'database' => array(
574:                 'cookie' => 'CAKEPHP',
575:                 'timeout' => 240,
576:                 'ini' => array(
577:                     'session.use_trans_sid' => 0,
578:                     'url_rewriter.tags' => '',
579:                     'session.auto_start' => 0,
580:                     'session.use_cookies' => 1,
581:                     'session.cookie_path' => self::$path,
582:                     'session.save_handler' => 'user',
583:                     'session.serialize_handler' => 'php',
584:                 ),
585:                 'handler' => array(
586:                     'engine' => 'DatabaseSession',
587:                     'model' => 'Session'
588:                 )
589:             )
590:         );
591:         if (isset($defaults[$name])) {
592:             return $defaults[$name];
593:         }
594:         return false;
595:     }
596: 
597: /**
598:  * Helper method to start a session
599:  *
600:  * @return boolean Success
601:  */
602:     protected static function _startSession() {
603:         if (headers_sent()) {
604:             if (empty($_SESSION)) {
605:                 $_SESSION = array();
606:             }
607:         } else {
608:             // For IE<=8
609:             session_cache_limiter("must-revalidate");
610:             session_start();
611:         }
612:         return true;
613:     }
614: 
615: /**
616:  * Helper method to create a new session.
617:  *
618:  * @return void
619:  */
620:     protected static function _checkValid() {
621:         if (!self::started() && !self::start()) {
622:             self::$valid = false;
623:             return false;
624:         }
625:         if ($config = self::read('Config')) {
626:             $sessionConfig = Configure::read('Session');
627: 
628:             if (self::_validAgentAndTime()) {
629:                 self::write('Config.time', self::$sessionTime);
630:                 if (isset($sessionConfig['autoRegenerate']) && $sessionConfig['autoRegenerate'] === true) {
631:                     $check = $config['countdown'];
632:                     $check -= 1;
633:                     self::write('Config.countdown', $check);
634: 
635:                     if ($check < 1) {
636:                         self::renew();
637:                         self::write('Config.countdown', self::$requestCountdown);
638:                     }
639:                 }
640:                 self::$valid = true;
641:             } else {
642:                 self::destroy();
643:                 self::$valid = false;
644:                 self::_setError(1, 'Session Highjacking Attempted !!!');
645:             }
646:         } else {
647:             self::write('Config.userAgent', self::$_userAgent);
648:             self::write('Config.time', self::$sessionTime);
649:             self::write('Config.countdown', self::$requestCountdown);
650:             self::$valid = true;
651:         }
652:     }
653: 
654: /**
655:  * Restarts this session.
656:  *
657:  * @return void
658:  */
659:     public static function renew() {
660:         if (session_id()) {
661:             if (session_id() != '' || isset($_COOKIE[session_name()])) {
662:                 setcookie(Configure::read('Session.cookie'), '', time() - 42000, self::$path);
663:             }
664:             session_regenerate_id(true);
665:         }
666:     }
667: 
668: /**
669:  * Helper method to set an internal error message.
670:  *
671:  * @param integer $errorNumber Number of the error
672:  * @param string $errorMessage Description of the error
673:  * @return void
674:  */
675:     protected static function _setError($errorNumber, $errorMessage) {
676:         if (self::$error === false) {
677:             self::$error = array();
678:         }
679:         self::$error[$errorNumber] = $errorMessage;
680:         self::$lastError = $errorNumber;
681:     }
682: 
683: }
684: 
OpenHub
Rackspace
Rackspace
  • Business Solutions
  • Showcase
  • Documentation
  • Book
  • API
  • Videos
  • Reporting Security Issues
  • Privacy Policy
  • Logos & Trademarks
  • Community
  • Get Involved
  • Issues (GitHub)
  • Bakery
  • Featured Resources
  • Training
  • Meetups
  • My CakePHP
  • CakeFest
  • Newsletter
  • Linkedin
  • YouTube
  • Facebook
  • Twitter
  • Mastodon
  • Help & Support
  • Forum
  • Stack Overflow
  • Slack
  • Paid Support

Generated using CakePHP API Docs