Test Failed
Pull Request — master (#391)
by Kiran
15:55
created

WP_Session::key()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * WordPress session managment.
4
 *
5
 * Standardizes WordPress session data using database-backed options for storage.
6
 * for storing user session information.
7
 *
8
 * @package WordPress
9
 * @subpackage Session
10
 * @since   3.7.0
11
 */
12
13
/**
14
 * WordPress Session class for managing user session data.
15
 *
16
 * @package WordPress
17
 * @since   3.7.0
18
 */
19
final class WP_Session extends Recursive_ArrayAccess {
20
	/**
21
	 * ID of the current session.
22
	 *
23
	 * @var string
24
	 */
25
	public $session_id;
26
27
	/**
28
	 * Unix timestamp when session expires.
29
	 *
30
	 * @var int
31
	 */
32
	protected $expires;
33
34
	/**
35
	 * Unix timestamp indicating when the expiration time needs to be reset.
36
	 *
37
	 * @var int
38
	 */
39
	protected $exp_variant;
40
41
	/**
42
	 * Singleton instance.
43
	 *
44
	 * @var bool|WP_Session
45
	 */
46
	private static $instance = false;
47
48
	/**
49
	 * Retrieve the current session instance.
50
	 *
51
	 * @param bool $session_id Session ID from which to populate data.
0 ignored issues
show
Bug introduced by
There is no parameter named $session_id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
52
	 *
53
	 * @return bool|WP_Session
54
	 */
55
	public static function get_instance() {
56
		if ( ! self::$instance ) {
57
			self::$instance = new self();
58
		}
59
60
		return self::$instance;
61
	}
62
63
	/**
64
	 * Default constructor.
65
	 * Will rebuild the session collection from the given session ID if it exists. Otherwise, will
66
	 * create a new session with that ID.
67
	 *
68
	 * @param $session_id
69
	 * @uses apply_filters Calls `wp_session_expiration` to determine how long until sessions expire.
70
	 */
71
	protected function __construct() {
72
		if ( isset( $_COOKIE[WP_SESSION_COOKIE] ) ) {
73
			$cookie = stripslashes( $_COOKIE[WP_SESSION_COOKIE] );
74
			$cookie_crumbs = explode( '||', $cookie );
75
76
            $this->session_id = preg_replace("/[^A-Za-z0-9_]/", '', $cookie_crumbs[0] );
77
            $this->expires = absint( $cookie_crumbs[1] );
78
            $this->exp_variant = absint( $cookie_crumbs[2] );
79
80
			// Update the session expiration if we're past the variant time
81
			if ( time() > $this->exp_variant ) {
82
				$this->set_expiration();
83
				delete_option( "_wp_session_expires_{$this->session_id}" );
84
				add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' );
85
			}
86
		} else {
87
			$this->session_id = WP_Session_Utils::generate_id();
88
			$this->set_expiration();
89
		}
90
91
		$this->read_data();
92
93
		$this->set_cookie();
94
95
	}
96
97
	/**
98
	 * Set both the expiration time and the expiration variant.
99
	 *
100
	 * If the current time is below the variant, we don't update the session's expiration time. If it's
101
	 * greater than the variant, then we update the expiration time in the database.  This prevents
102
	 * writing to the database on every page load for active sessions and only updates the expiration
103
	 * time if we're nearing when the session actually expires.
104
	 *
105
	 * By default, the expiration time is set to 30 minutes.
106
	 * By default, the expiration variant is set to 24 minutes.
107
	 *
108
	 * As a result, the session expiration time - at a maximum - will only be written to the database once
109
	 * every 24 minutes.  After 30 minutes, the session will have been expired. No cookie will be sent by
110
	 * the browser, and the old session will be queued for deletion by the garbage collector.
111
	 *
112
	 * @uses apply_filters Calls `wp_session_expiration_variant` to get the max update window for session data.
113
	 * @uses apply_filters Calls `wp_session_expiration` to get the standard expiration time for sessions.
114
	 */
115
	protected function set_expiration() {
116
		$this->exp_variant = time() + (int) apply_filters( 'wp_session_expiration_variant', 24 * 60 );
117
		$this->expires = time() + (int) apply_filters( 'wp_session_expiration', 30 * 60 );
118
	}
119
120
	/**
121
	* Set the session cookie
122
	* @uses apply_filters Calls `wp_session_cookie_secure` to set the $secure parameter of setcookie()
123
	* @uses apply_filters Calls `wp_session_cookie_httponly` to set the $httponly parameter of setcookie()
124
	*/
125
	protected function set_cookie() {
126
		if ( !defined( 'GD_TESTING_MODE' ) ) {
127
			try {
128
				$secure = apply_filters('wp_session_cookie_secure', false);
129
				$httponly = apply_filters('wp_session_cookie_httponly', false);
130
				setcookie( WP_SESSION_COOKIE, $this->session_id . '||' . $this->expires . '||' . $this->exp_variant , $this->expires, COOKIEPATH, COOKIE_DOMAIN, $secure, $httponly );
131
			} catch(Exception $e) {
132
				error_log( 'Set Cookie Error: ' . $e->getMessage() );
133
			}
134
		}
135
	}
136
137
	/**
138
	 * Read data from a transient for the current session.
139
	 *
140
	 * Automatically resets the expiration time for the session transient to some time in the future.
141
	 *
142
	 * @return array
143
	 */
144
	protected function read_data() {
145
		$this->container = get_option( "_wp_session_{$this->session_id}", array() );
146
147
		return $this->container;
148
	}
149
150
	/**
151
	 * Write the data from the current session to the data storage system.
152
	 */
153
	public function write_data() {
154
		$option_key = "_wp_session_{$this->session_id}";
155
		
156
		if ( false === get_option( $option_key ) ) {
157
			add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' );
158
			add_option( "_wp_session_expires_{$this->session_id}", $this->expires, '', 'no' );
159
		} else {
160
			delete_option( "_wp_session_{$this->session_id}" );
161
			add_option( "_wp_session_{$this->session_id}", $this->container, '', 'no' );
162
		}
163
	}
164
165
	/**
166
	 * Output the current container contents as a JSON-encoded string.
167
	 *
168
	 * @return string
169
	 */
170
	public function json_out() {
171
		return json_encode( $this->container );
172
	}
173
174
	/**
175
	 * Decodes a JSON string and, if the object is an array, overwrites the session container with its contents.
176
	 *
177
	 * @param string $data
178
	 *
179
	 * @return bool
180
	 */
181
	public function json_in( $data ) {
182
		$array = json_decode( $data );
183
184
		if ( is_array( $array ) ) {
185
			$this->container = $array;
186
			return true;
187
		}
188
189
		return false;
190
	}
191
192
	/**
193
	 * Regenerate the current session's ID.
194
	 *
195
	 * @param bool $delete_old Flag whether or not to delete the old session data from the server.
196
	 */
197
	public function regenerate_id( $delete_old = false ) {
198
		if ( $delete_old ) {
199
			delete_option( "_wp_session_{$this->session_id}" );
200
		}
201
202
		$this->session_id = WP_Session_Utils::generate_id();
203
204
		$this->set_cookie();
205
	}
206
207
	/**
208
	 * Check if a session has been initialized.
209
	 *
210
	 * @return bool
211
	 */
212
	public function session_started() {
213
		return !!self::$instance;
214
	}
215
216
	/**
217
	 * Return the read-only cache expiration value.
218
	 *
219
	 * @return int
220
	 */
221
	public function cache_expiration() {
222
		return $this->expires;
223
	}
224
225
	/**
226
	 * Flushes all session variables.
227
	 */
228
	public function reset() {
229
		$this->container = array();
230
	}
231
}
232