WP_Session

WordPress Session class for managing user session data.

Defined (2)

The class is defined in the following location(s).

/deprecated/includes/libraries/class-wp-session.php  
  1. final class WP_Session extends Recursive_ArrayAccess implements Iterator, Countable { 
  2. /** 
  3. * ID of the current session. 
  4. * @var string 
  5. */ 
  6. public $session_id; 
  7.  
  8. /** 
  9. * Unix timestamp when session expires. 
  10. * @var int 
  11. */ 
  12. protected $expires; 
  13.  
  14. /** 
  15. * Unix timestamp indicating when the expiration time needs to be reset. 
  16. * @var int 
  17. */ 
  18. protected $exp_variant; 
  19.  
  20. /** 
  21. * Singleton instance. 
  22. * @var bool|WP_Session 
  23. */ 
  24. private static $instance = false; 
  25.  
  26. /** 
  27. * Retrieve the current session instance. 
  28. * @param bool $session_id Session ID from which to populate data. 
  29. * @return bool|WP_Session 
  30. */ 
  31. public static function get_instance() { 
  32. if ( ! self::$instance ) { 
  33. self::$instance = new self(); 
  34.  
  35. return self::$instance; 
  36.  
  37. /** 
  38. * Default constructor. 
  39. * Will rebuild the session collection from the given session ID if it exists. Otherwise, will 
  40. * create a new session with that ID. 
  41. * @param $session_id 
  42. * @uses apply_filters Calls `wp_session_expiration` to determine how long until sessions expire. 
  43. */ 
  44. protected function __construct() { 
  45. if ( isset( $_COOKIE[WP_SESSION_COOKIE] ) ) { 
  46. $cookie = stripslashes( $_COOKIE[WP_SESSION_COOKIE] ); 
  47. $cookie_crumbs = explode( '||', $cookie ); 
  48.  
  49. if( $this->is_valid_md5( $cookie_crumbs[0] ) ) { 
  50. $this->session_id = $cookie_crumbs[0]; 
  51. } else { 
  52. $this->session_id = $this->regenerate_id(); 
  53.  
  54. $this->expires = $cookie_crumbs[1]; 
  55. $this->exp_variant = $cookie_crumbs[2]; 
  56.  
  57. // Update the session expiration if we're past the variant time 
  58. if ( time() > $this->exp_variant ) { 
  59. $this->set_expiration(); 
  60. delete_option( "_wp_session_expires_{$this->session_id}" ); 
  61. add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' ); 
  62. } else { 
  63. $this->session_id = $this->generate_id(); 
  64. $this->set_expiration(); 
  65.  
  66. $this->read_data(); 
  67.  
  68. /** 
  69. * Only set the cookie manually, on form submission. 
  70. */ 
  71. //$this->set_cookie(); 
  72.  
  73.  
  74. /** 
  75. * Set both the expiration time and the expiration variant. 
  76. * If the current time is below the variant, we don't update the session's expiration time. If it's 
  77. * greater than the variant, then we update the expiration time in the database. This prevents 
  78. * writing to the database on every page load for active sessions and only updates the expiration 
  79. * time if we're nearing when the session actually expires. 
  80. * By default, the expiration time is set to 30 minutes. 
  81. * By default, the expiration variant is set to 24 minutes. 
  82. * As a result, the session expiration time - at a maximum - will only be written to the database once 
  83. * every 24 minutes. After 30 minutes, the session will have been expired. No cookie will be sent by 
  84. * the browser, and the old session will be queued for deletion by the garbage collector. 
  85. * @uses apply_filters Calls `wp_session_expiration_variant` to get the max update window for session data. 
  86. * @uses apply_filters Calls `wp_session_expiration` to get the standard expiration time for sessions. 
  87. */ 
  88. protected function set_expiration() { 
  89. $this->exp_variant = time() + (int) apply_filters( 'wp_session_expiration_variant', 24 * 60 ); 
  90. $this->expires = time() + (int) apply_filters( 'wp_session_expiration', 30 * 60 ); 
  91.  
  92. /** 
  93. * Set the session cookie 
  94. * IMPORTANT: Made public 
  95. */ 
  96. public function set_cookie() { 
  97. @setcookie( WP_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant , $this->expires, COOKIEPATH, COOKIE_DOMAIN ); 
  98.  
  99. /** 
  100. * Generate a cryptographically strong unique ID for the session token. 
  101. * @return string 
  102. */ 
  103. protected function generate_id() { 
  104. require_once( ABSPATH . 'wp-includes/class-phpass.php'); 
  105. $hasher = new PasswordHash( 8, false ); 
  106.  
  107. return md5( $hasher->get_random_bytes( 32 ) ); 
  108.  
  109. /** 
  110. * Read data from a transient for the current session. 
  111. * Automatically resets the expiration time for the session transient to some time in the future. 
  112. * @return array 
  113. */ 
  114. protected function read_data() { 
  115. $this->container = get_option( "_wp_session_{$this->session_id}", array() ); 
  116.  
  117. return $this->container; 
  118.  
  119. /** 
  120. * Write the data from the current session to the data storage system. 
  121. */ 
  122. public function write_data() { 
  123. $option_key = "_wp_session_{$this->session_id}"; 
  124.  
  125. // Only write the collection to the DB if it's changed. 
  126. if ( $this->dirty ) { 
  127. if ( false === get_option( $option_key ) ) { 
  128. add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' ); 
  129. add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' ); 
  130. } else { 
  131. delete_option( "_wp_session_{$this->session_id}" ); 
  132. add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' ); 
  133.  
  134. /** 
  135. * Output the current container contents as a JSON-encoded string. 
  136. * @return string 
  137. */ 
  138. public function json_out() { 
  139. return json_encode( $this->container ); 
  140.  
  141. /** 
  142. * Decodes a JSON string and, if the object is an array, overwrites the session container with its contents. 
  143. * @param string $data 
  144. * @return bool 
  145. */ 
  146. public function json_in( $data ) { 
  147. $array = json_decode( $data ); 
  148.  
  149. if ( is_array( $array ) ) { 
  150. $this->container = $array; 
  151. return true; 
  152.  
  153. return false; 
  154.  
  155. /** 
  156. * Regenerate the current session's ID. 
  157. * @param bool $delete_old Flag whether or not to delete the old session data from the server. 
  158. */ 
  159. public function regenerate_id( $delete_old = false ) { 
  160. if ( $delete_old ) { 
  161. delete_option( "_wp_session_{$this->session_id}" ); 
  162.  
  163. $this->session_id = $this->generate_id(); 
  164.  
  165. $this->set_cookie(); 
  166.  
  167. /** 
  168. * Check if a session has been initialized. 
  169. * @return bool 
  170. */ 
  171. public function session_started() { 
  172. return !!self::$instance; 
  173.  
  174. /** 
  175. * Return the read-only cache expiration value. 
  176. * @return int 
  177. */ 
  178. public function cache_expiration() { 
  179. return $this->expires; 
  180.  
  181. /** 
  182. * Flushes all session variables. 
  183. */ 
  184. public function reset() { 
  185. $this->container = array(); 
  186.  
  187. /** 
  188. * Checks if is valid md5 string 
  189. * @param string $md5 
  190. * @return int 
  191. */ 
  192. protected function is_valid_md5( $md5 = '' ) { 
  193. return preg_match( '/^[a-f0-9]{32}$/', $md5 ); 
  194.  
  195. /*****************************************************************/ 
  196. /** Iterator Implementation */ 
  197. /*****************************************************************/ 
  198.  
  199. /** 
  200. * Current position of the array. 
  201. * @link http://php.net/manual/en/iterator.current.php 
  202. * @return mixed 
  203. */ 
  204. public function current() { 
  205. return current( $this->container ); 
  206.  
  207. /** 
  208. * Key of the current element. 
  209. * @link http://php.net/manual/en/iterator.key.php 
  210. * @return mixed 
  211. */ 
  212. public function key() { 
  213. return key( $this->container ); 
  214.  
  215. /** 
  216. * Move the internal point of the container array to the next item 
  217. * @link http://php.net/manual/en/iterator.next.php 
  218. * @return void 
  219. */ 
  220. public function next() { 
  221. next( $this->container ); 
  222.  
  223. /** 
  224. * Rewind the internal point of the container array. 
  225. * @link http://php.net/manual/en/iterator.rewind.php 
  226. * @return void 
  227. */ 
  228. public function rewind() { 
  229. reset( $this->container ); 
  230.  
  231. /** 
  232. * Is the current key valid? 
  233. * @link http://php.net/manual/en/iterator.rewind.php 
  234. * @return bool 
  235. */ 
  236. public function valid() { 
  237. return $this->offsetExists( $this->key() ); 
  238.  
  239. /*****************************************************************/ 
  240. /** Countable Implementation */ 
  241. /*****************************************************************/ 
  242.  
  243. /** 
  244. * Get the count of elements in the container array. 
  245. * @link http://php.net/manual/en/countable.count.php 
  246. * @return int 
  247. */ 
  248. public function count() { 
  249. return count( $this->container ); 
/includes/Libraries/Session/class-wp-session.php  
  1. final class WP_Session extends Recursive_ArrayAccess implements Iterator, Countable { 
  2. /** 
  3. * ID of the current session. 
  4. * @var string 
  5. */ 
  6. public $session_id; 
  7.  
  8. /** 
  9. * Unix timestamp when session expires. 
  10. * @var int 
  11. */ 
  12. protected $expires; 
  13.  
  14. /** 
  15. * Unix timestamp indicating when the expiration time needs to be reset. 
  16. * @var int 
  17. */ 
  18. protected $exp_variant; 
  19.  
  20. /** 
  21. * Singleton instance. 
  22. * @var bool|WP_Session 
  23. */ 
  24. private static $instance = false; 
  25.  
  26. /** 
  27. * Retrieve the current session instance. 
  28. * @param bool $session_id Session ID from which to populate data. 
  29. * @return bool|WP_Session 
  30. */ 
  31. public static function get_instance() { 
  32. if ( ! self::$instance ) { 
  33. self::$instance = new self(); 
  34.  
  35. return self::$instance; 
  36.  
  37. /** 
  38. * Default constructor. 
  39. * Will rebuild the session collection from the given session ID if it exists. Otherwise, will 
  40. * create a new session with that ID. 
  41. * @param $session_id 
  42. * @uses apply_filters Calls `wp_session_expiration` to determine how long until sessions expire. 
  43. */ 
  44. protected function __construct() { 
  45. if ( isset( $_COOKIE[WP_SESSION_COOKIE] ) ) { 
  46. $cookie = stripslashes( $_COOKIE[WP_SESSION_COOKIE] ); 
  47. $cookie_crumbs = explode( '||', $cookie ); 
  48.  
  49. if( $this->is_valid_md5( $cookie_crumbs[0] ) ) { 
  50.  
  51. $this->session_id = $cookie_crumbs[0]; 
  52.  
  53. } else { 
  54.  
  55. $this->regenerate_id( true ); 
  56.  
  57.  
  58. $this->expires = $cookie_crumbs[1]; 
  59. $this->exp_variant = $cookie_crumbs[2]; 
  60.  
  61. // Update the session expiration if we're past the variant time 
  62. if ( time() > $this->exp_variant ) { 
  63. $this->set_expiration(); 
  64. delete_option( "_wp_session_expires_{$this->session_id}" ); 
  65. add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' ); 
  66. } else { 
  67. $this->session_id = $this->generate_id(); 
  68. $this->set_expiration(); 
  69.  
  70. $this->read_data(); 
  71.  
  72. /** 
  73. * MODIFICATION: Only set the cookie manually. 
  74. */ 
  75. //$this->set_cookie(); 
  76.  
  77. /** 
  78. * Set both the expiration time and the expiration variant. 
  79. * If the current time is below the variant, we don't update the session's expiration time. If it's 
  80. * greater than the variant, then we update the expiration time in the database. This prevents 
  81. * writing to the database on every page load for active sessions and only updates the expiration 
  82. * time if we're nearing when the session actually expires. 
  83. * By default, the expiration time is set to 30 minutes. 
  84. * By default, the expiration variant is set to 24 minutes. 
  85. * As a result, the session expiration time - at a maximum - will only be written to the database once 
  86. * every 24 minutes. After 30 minutes, the session will have been expired. No cookie will be sent by 
  87. * the browser, and the old session will be queued for deletion by the garbage collector. 
  88. * @uses apply_filters Calls `wp_session_expiration_variant` to get the max update window for session data. 
  89. * @uses apply_filters Calls `wp_session_expiration` to get the standard expiration time for sessions. 
  90. */ 
  91. protected function set_expiration() { 
  92. $this->exp_variant = time() + (int) apply_filters( 'wp_session_expiration_variant', 24 * 60 ); 
  93. $this->expires = time() + (int) apply_filters( 'wp_session_expiration', 30 * 60 ); 
  94.  
  95. /** 
  96. * Set the session cookie 
  97. */ 
  98. /** 
  99. * MODIFICATION: Change access to public for manually setting cookie. 
  100. */ 
  101. public function set_cookie() { 
  102. @setcookie( WP_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant , $this->expires, COOKIEPATH, COOKIE_DOMAIN ); 
  103.  
  104. /** 
  105. * Generate a cryptographically strong unique ID for the session token. 
  106. * @return string 
  107. */ 
  108. protected function generate_id() { 
  109. require_once( ABSPATH . 'wp-includes/class-phpass.php'); 
  110. $hasher = new PasswordHash( 8, false ); 
  111.  
  112. return md5( $hasher->get_random_bytes( 32 ) ); 
  113.  
  114. /** 
  115. * Checks if is valid md5 string 
  116. * @param string $md5 
  117. * @return int 
  118. */ 
  119. protected function is_valid_md5( $md5 = '' ) { 
  120. return preg_match( '/^[a-f0-9]{32}$/', $md5 ); 
  121.  
  122. /** 
  123. * Read data from a transient for the current session. 
  124. * Automatically resets the expiration time for the session transient to some time in the future. 
  125. * @return array 
  126. */ 
  127. protected function read_data() { 
  128. $this->container = get_option( "_wp_session_{$this->session_id}", array() ); 
  129.  
  130. return $this->container; 
  131.  
  132. /** 
  133. * Write the data from the current session to the data storage system. 
  134. */ 
  135. public function write_data() { 
  136. $option_key = "_wp_session_{$this->session_id}"; 
  137.  
  138. // Only write the collection to the DB if it's changed. 
  139. if ( $this->dirty ) { 
  140. if ( false === get_option( $option_key ) ) { 
  141. add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' ); 
  142. add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' ); 
  143. } else { 
  144. delete_option( "_wp_session_{$this->session_id}" ); 
  145. add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' ); 
  146.  
  147. /** 
  148. * Output the current container contents as a JSON-encoded string. 
  149. * @return string 
  150. */ 
  151. public function json_out() { 
  152. return json_encode( $this->container ); 
  153.  
  154. /** 
  155. * Decodes a JSON string and, if the object is an array, overwrites the session container with its contents. 
  156. * @param string $data 
  157. * @return bool 
  158. */ 
  159. public function json_in( $data ) { 
  160. $array = json_decode( $data ); 
  161.  
  162. if ( is_array( $array ) ) { 
  163. $this->container = $array; 
  164. return true; 
  165.  
  166. return false; 
  167.  
  168. /** 
  169. * Regenerate the current session's ID. 
  170. * @param bool $delete_old Flag whether or not to delete the old session data from the server. 
  171. */ 
  172. public function regenerate_id( $delete_old = false ) { 
  173. if ( $delete_old ) { 
  174. delete_option( "_wp_session_{$this->session_id}" ); 
  175.  
  176. $this->session_id = $this->generate_id(); 
  177.  
  178. $this->set_cookie(); 
  179.  
  180. /** 
  181. * Check if a session has been initialized. 
  182. * @return bool 
  183. */ 
  184. public function session_started() { 
  185. return !!self::$instance; 
  186.  
  187. /** 
  188. * Return the read-only cache expiration value. 
  189. * @return int 
  190. */ 
  191. public function cache_expiration() { 
  192. return $this->expires; 
  193.  
  194. /** 
  195. * Flushes all session variables. 
  196. */ 
  197. public function reset() { 
  198. $this->container = array(); 
  199.  
  200. /*****************************************************************/ 
  201. /** Iterator Implementation */ 
  202. /*****************************************************************/ 
  203.  
  204. /** 
  205. * Current position of the array. 
  206. * @link http://php.net/manual/en/iterator.current.php 
  207. * @return mixed 
  208. */ 
  209. public function current() { 
  210. return current( $this->container ); 
  211.  
  212. /** 
  213. * Key of the current element. 
  214. * @link http://php.net/manual/en/iterator.key.php 
  215. * @return mixed 
  216. */ 
  217. public function key() { 
  218. return key( $this->container ); 
  219.  
  220. /** 
  221. * Move the internal point of the container array to the next item 
  222. * @link http://php.net/manual/en/iterator.next.php 
  223. * @return void 
  224. */ 
  225. public function next() { 
  226. next( $this->container ); 
  227.  
  228. /** 
  229. * Rewind the internal point of the container array. 
  230. * @link http://php.net/manual/en/iterator.rewind.php 
  231. * @return void 
  232. */ 
  233. public function rewind() { 
  234. reset( $this->container ); 
  235.  
  236. /** 
  237. * Is the current key valid? 
  238. * @link http://php.net/manual/en/iterator.rewind.php 
  239. * @return bool 
  240. */ 
  241. public function valid() { 
  242. return $this->offsetExists( $this->key() ); 
  243.  
  244. /*****************************************************************/ 
  245. /** Countable Implementation */ 
  246. /*****************************************************************/ 
  247.  
  248. /** 
  249. * Get the count of elements in the container array. 
  250. * @link http://php.net/manual/en/countable.count.php 
  251. * @return int 
  252. */ 
  253. public function count() { 
  254. return count( $this->container );