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.3 API

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