Overview

Namespaces

  • None
  • PHP

Classes

  • Breadcrumb
  • Breadcrumbs
  • CacheFile
  • Comment
  • CommentArray
  • CommentFilter
  • CommentForm
  • CommentList
  • Config
  • Database
  • DatabaseQuery
  • DatabaseQuerySelect
  • DatabaseQuerySelectFulltext
  • DatabaseStopwords
  • Debug
  • Field
  • Fieldgroup
  • Fieldgroups
  • FieldgroupsArray
  • Fields
  • FieldsArray
  • Fieldtype
  • FieldtypeMulti
  • Fieldtypes
  • FileLog
  • FilenameArray
  • Fuel
  • HookEvent
  • ImageSizer
  • Inputfield
  • InputfieldsArray
  • InputfieldWrapper
  • Language
  • LanguageParser
  • Languages
  • LanguagesPageFieldValue
  • LanguageSupportInstall
  • LanguageTranslator
  • Markdown_Parser
  • MarkdownExtra_Parser
  • ModuleJS
  • ModulePlaceholder
  • Modules
  • Notice
  • NoticeError
  • NoticeMessage
  • Notices
  • NullPage
  • Page
  • PageArray
  • Pagefile
  • Pagefiles
  • PagefilesManager
  • PageFinder
  • Pageimage
  • Pageimages
  • PagerNav
  • PagerNavItem
  • Pages
  • PagesAccess
  • PagesSortfields
  • PagesType
  • Paths
  • Permission
  • Permissions
  • Process
  • ProcessController
  • ProcessWire
  • Role
  • Roles
  • Sanitizer
  • Selector
  • SelectorBitwiseAnd
  • SelectorContains
  • SelectorContainsLike
  • SelectorContainsWords
  • SelectorEnds
  • SelectorEqual
  • SelectorGreaterThan
  • SelectorGreaterThanEqual
  • SelectorLessThan
  • SelectorLessThanEqual
  • SelectorNotEqual
  • Selectors
  • SelectorStarts
  • Session
  • SessionCSRF
  • SmartyPants_Parser
  • SmartyPantsTypographer_Parser
  • SystemUpdate1
  • Template
  • TemplateFile
  • Templates
  • TemplatesArray
  • Textformatter
  • Textile
  • User
  • Users
  • Wire
  • WireArray
  • WireData
  • WireInput
  • WireInputData
  • WireSaveableItems
  • WireSaveableItemsLookup
  • WireUpload

Interfaces

  • CommentFormInterface
  • CommentListInterface
  • ConfigurableModule
  • FieldtypeLanguageInterface
  • FieldtypePageTitleCompatible
  • HasLookupItems
  • HasRoles
  • InputfieldHasArrayValue
  • Module
  • Saveable
  • TrackChanges

Exceptions

  • ProcessController404Exception
  • ProcessControllerPermissionException
  • Wire404Exception
  • WireDatabaseException
  • WireException
  • WirePermissionException

Functions

  • __
  • _n
  • _x
  • fuel
  • identify_modifier_markdown
  • Markdown
  • mdwp_add_p
  • mdwp_hide_tags
  • mdwp_show_tags
  • mdwp_strip_p
  • ProcessWireClassLoader
  • ProcessWireHostSiteConfig
  • ProcessWireShutdown
  • removeNewlines
  • SmartDashes
  • SmartEllipsis
  • SmartQuotes
  • smarty_modifier_markdown
  • smarty_modifier_smartypants
  • SmartyPants
  • tabIndent
  • unregisterGLOBALS
  • wire
  • wireDecodeJSON
  • wireEncodeJSON
  • wireMkdir
  • Overview
  • Namespace
  • Class
  • Tree
  • Download
  1: <?php
  2: 
  3: /**
  4:  * ProcessWire Session
  5:  *
  6:  * Start a session with login/logout capability 
  7:  *
  8:  * This should be used instead of the $_SESSION superglobal, though the $_SESSION superglobal can still be 
  9:  * used, but it's in a different namespace than this. A value set in $_SESSION won't appear in $session
 10:  * and likewise a value set in $session won't appear in $_SESSION.  It's also good to use this class
 11:  * over the $_SESSION superglobal just in case we ever need to replace PHP's session handling in the future.
 12:  * 
 13:  * ProcessWire 2.x 
 14:  * Copyright (C) 2010 by Ryan Cramer 
 15:  * Licensed under GNU/GPL v2, see LICENSE.TXT
 16:  * 
 17:  * http://www.processwire.com
 18:  * http://www.ryancramer.com
 19:  *
 20:  */
 21: 
 22: class Session extends Wire implements IteratorAggregate {
 23: 
 24:     /**
 25:      * Reference to ProcessWire $config object
 26:      *
 27:      * For convenience, since our __get() does not reference the Fuel, unlike other Wire derived classes.
 28:      *
 29:      */
 30:     protected $config; 
 31: 
 32:     /**
 33:      * Instance of the SessionCSRF protection class, instantiated when requested from $session->CSRF.
 34:      *
 35:      */
 36:     protected $CSRF = null; 
 37: 
 38:     /**
 39:      * Start the session and set the current User if a session is active
 40:      *
 41:      * Assumes that you have already performed all session-specific ini_set() and session_name() calls 
 42:      *
 43:      */
 44:     public function __construct() {
 45: 
 46:         $this->config = $this->fuel('config'); 
 47:         @session_start();
 48:         unregisterGLOBALS();
 49:         $className = $this->className();
 50:         $user = null;
 51: 
 52:         if(empty($_SESSION[$className])) $_SESSION[$className] = array();
 53: 
 54:         if($userID = $this->get('_user_id')) {
 55:             if($this->isValidSession()) {
 56:                 $user = $this->fuel('users')->get($userID); 
 57:             } else {
 58:                 $this->logout();
 59:             }
 60:         }
 61: 
 62:         if(!$user || !$user->id) $user = $this->fuel('users')->getGuestUser();
 63:         $this->fuel('users')->setCurrentUser($user);    
 64: 
 65:         foreach(array('message', 'error') as $type) {
 66:             if($items = $this->get($type)) foreach($items as $item) {
 67:                 list($text, $flags) = $item;
 68:                 parent::$type($text, $flags); 
 69:             }
 70:             $this->remove($type);
 71:         }
 72: 
 73:         $this->setTrackChanges(true);
 74:     }
 75: 
 76: 
 77:     /**
 78:      * Checks if the session is valid based on a challenge cookie and fingerprint
 79:      *
 80:      * These items may be disabled at the config level, in which case this method always returns true
 81:      *
 82:      * @return bool
 83:      *
 84:      */
 85:     protected function ___isValidSession() {
 86: 
 87:         $valid = true; 
 88:         $sessionName = session_name();
 89: 
 90:         if($this->config->sessionChallenge) {
 91:             if(empty($_COOKIE[$sessionName . "_challenge"]) || ($this->get('_user_challenge') != $_COOKIE[$sessionName . "_challenge"])) {
 92:                 $valid = false; 
 93:             }
 94:         }   
 95: 
 96:         if($this->config->sessionFingerprint) {
 97:             if(($_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']) != $this->get("_user_fingerprint")) {
 98:                 $valid = false; 
 99:             }
100:         }
101: 
102:         return $valid; 
103:     }
104: 
105: 
106:     /**
107:      * Get a session variable
108:      *
109:      * @param string $key
110:      * @return mixed
111:      *
112:      */
113:     public function get($key) {
114:         if($key == 'CSRF') {
115:             if(is_null($this->CSRF)) $this->CSRF = new SessionCSRF();
116:             return $this->CSRF; 
117:         }
118:         $className = $this->className();
119:         return isset($_SESSION[$className][$key]) ? $_SESSION[$className][$key] : null; 
120:     }
121: 
122:     /**
123:      * Get all session variables
124:      *
125:      * @return array
126:      *
127:      */
128:     public function getAll() {
129:         return $_SESSION[$this->className()]; 
130:     }
131: 
132:     /**
133:      * Set a session variable
134:      *
135:      * @param string $key
136:      * @param mixed $value
137:      * @return this
138:      *
139:      */
140:     public function set($key, $value) {
141:         $className = $this->className();
142:         $oldValue = $this->get($key); 
143:         if($value !== $oldValue) $this->trackChange($key); 
144:         $_SESSION[$className][$key] = $value; 
145:         return $this; 
146:     }
147: 
148:     /**
149:      * Unsets a session variable
150:      *
151:      * @param string $value
152:      * @return this
153:      *
154:      */
155:     public function remove($key) {
156:         unset($_SESSION[$this->className()][$key]); 
157:         return $this; 
158:     }
159: 
160:     /**
161:      * Provide $session->variable get access
162:      *
163:      */
164:     public function __get($key) {
165:         return $this->get($key); 
166:     }
167: 
168:     /**
169:      * Provide $session->variable = variable set access
170:      *
171:      */
172:     public function __set($key, $value) {
173:         return $this->set($key, $value); 
174:     }
175: 
176:     /**
177:      * Allow iteration of session variables, i.e. foreach($session as $key => $var) {} 
178:      *
179:      */
180:     public function getIterator() {
181:         return new ArrayObject($_SESSION[$this->className()]); 
182:     }
183: 
184:     /**
185:      * Login a user with the given name and password
186:      *
187:      * Also sets them to the current user
188:      *
189:      * @param string $name
190:      * @param string $pass Raw, non-hashed password
191:      * @return User Return the $user if the login was successful or null if not. 
192:      *
193:      */
194:     public function ___login($name, $pass) {
195: 
196:         $name = $this->fuel('sanitizer')->username($name); 
197:         $user = $this->fuel('users')->get("name=$name"); 
198: 
199:         if($user->id && $this->authenticate($user, $pass)) { 
200: 
201:             $this->trackChange('login'); 
202:             session_regenerate_id();
203:             $this->set('_user_id', $user->id); 
204: 
205:             if($this->config->sessionChallenge) {
206:                 $challenge = md5(mt_rand() . $user->id . microtime()); 
207:                 $expireSeconds = $this->config->sessionExpireSeconds ? time() + $this->config->sessionExpireSeconds : 0; 
208:                 setcookie(session_name() . "_challenge", $challenge, $expireSeconds, '/', null, false, true); 
209:                 $this->set('_user_challenge', $challenge); 
210:             }
211: 
212:             if($this->config->sessionFingerprint) {
213:                 $this->set('_user_fingerprint', $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']); 
214:             }
215: 
216:             $this->setFuel('user', $user); 
217:             $this->get('CSRF')->resetToken();
218: 
219:             return $user; 
220:         }
221: 
222:         return null; 
223:     }
224: 
225:     /**
226:      * Return true or false whether the user authenticated with the supplied password
227:      *
228:      * @param User $user 
229:      * @param string $pass
230:      * @return bool
231:      *
232:      */
233:     public function ___authenticate(User $user, $pass) {
234:         return $user->pass->matches($pass);
235:     }
236: 
237:     /**
238:      * Logout the current user, and clear all session variables
239:      *
240:      * @return this
241:      *
242:      */
243:     public function ___logout() {
244:         $sessionName = session_name();
245:         $_SESSION = array();
246:         if(isset($_COOKIE[$sessionName])) setcookie($sessionName, '', time()-42000, '/'); 
247:         if(isset($_COOKIE[$sessionName . "_challenge"])) setcookie($sessionName . "_challenge", '', time()-42000, '/'); 
248:         session_destroy();
249:         session_name($sessionName); 
250:         session_start(); 
251:         session_regenerate_id();
252:         $_SESSION[$this->className()] = array();
253:         $guest = $this->fuel('users')->getGuestUser();
254:         $this->fuel('users')->setCurrentUser($guest); 
255:         $this->trackChange('logout'); 
256:         return $this; 
257:     }
258: 
259:     /**
260:      * Redirect this session to another URL
261:      *
262:      */
263:     public function ___redirect($url, $http301 = true) {
264: 
265:         // if there are notices, then queue them so that they aren't lost
266:         $notices = $this->fuel('notices'); 
267:         if(count($notices)) foreach($notices as $notice) {
268:             $this->queueNotice($notice->text, $notice instanceof NoticeError ? 'error' : 'message', $notice->flags); 
269:         }
270: 
271:         // perform the redirect
272:         if($http301) header("HTTP/1.1 301 Moved Permanently");
273:         header("Location: $url");
274:         header("Connection: close"); 
275:         exit(0);
276:     }
277: 
278:     /**
279:      * Queue a notice (message/error) to be shown the next time this ession class is instantiated
280:      *
281:      */
282:     protected function queueNotice($text, $type, $flags) {
283:         $items = $this->get($type);
284:         if(is_null($items)) $items = array();
285:         $item = array($text, $flags); 
286:         $items[] = $item;
287:         $this->set($type, $items); 
288:     }
289: 
290: 
291:     /**
292:      * Queue a message to appear the next time session is instantiated
293:      *
294:      */
295:     public function message($text, $flags = 0) {
296:         $this->queueNotice($text, 'message', $flags); 
297:         return $this;
298:     }
299: 
300:     /**
301:      * Queue an error to appear the next time session is instantiated
302:      *
303:      */
304:     public function error($text, $flags = 0) {
305:         $this->queueNotice($text, 'error', $flags); 
306:         return $this; 
307:     }
308: 
309: 
310: }
311: 
ProcessWire API documentation generated by ApiGen 2.6.0