Completed
Pull Request — master (#552)
by Devin
03:45
created

Give_Session   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 286
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 0

Test Coverage

Coverage 51.19%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
wmc 37
c 4
b 0
f 0
lcom 2
cbo 0
dl 0
loc 286
ccs 43
cts 84
cp 0.5119
rs 8.6

10 Methods

Rating   Name   Duplication   Size   Complexity  
C __construct() 0 43 8
A init() 0 10 4
A get_id() 0 3 1
A get() 0 6 2
A set() 0 16 3
A set_expiration_variant_time() 0 4 2
A set_expiration_time() 0 4 2
D use_php_sessions() 0 39 9
A maybe_start_session() 0 11 3
A get_session_expiration() 0 13 3
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 24 and the first side effect is on line 16.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Give Session
4
 *
5
 * This is a wrapper class for WP_Session / PHP $_SESSION and handles the storage of Give sessions
6
 *
7
 * @package     Give
8
 * @subpackage  Classes/Session
9
 * @copyright   Copyright (c) 2016, WordImpress
10
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
11
 * @since       1.0
12
 */
13
14
// Exit if accessed directly
15
if ( ! defined( 'ABSPATH' ) ) {
16
	exit;
17
}
18
19
/**
20
 * Give_Session Class
21
 *
22
 * @since 1.0
23
 */
24
class Give_Session {
25
26
	/**
27
	 * Holds our session data
28
	 *
29
	 * @var array
30
	 * @access private
31
	 * @since  1.0
32
	 */
33
	private $session;
34
35
36
	/**
37
	 * Whether to use PHP $_SESSION or WP_Session
38
	 *
39
	 * @var bool
40
	 * @access private
41
	 * @since  1.0
42
	 */
43
	private $use_php_sessions = false;
44
45
	/**
46
	 * Expiration Time
47
	 *
48
	 * @var int
49
	 * @access private
50
	 * @since  1.0
51
	 */
52
	private $exp_option = false;
53
54
	/**
55
	 * Session index prefix
56
	 *
57
	 * @var string
58
	 * @access private
59
	 * @since  1.0
60
	 */
61
	private $prefix = '';
62
63
	/**
64
	 * Get things started
65
	 *
66
	 * Defines our WP_Session constants, includes the necessary libraries and
67
	 * retrieves the WP Session instance
68
	 *
69
	 * @since 1.0
70
	 */
71 2
	public function __construct() {
72
73 2
		$this->use_php_sessions = $this->use_php_sessions();
74 2
		$this->exp_option       = give_get_option( 'session_lifetime' );
75
76 2
		if ( $this->use_php_sessions ) {
77
78
			if ( is_multisite() ) {
79
80
				$this->prefix = '_' . get_current_blog_id();
81
82
			}
83
84
			add_action( 'give_pre_process_purchase', array( $this, 'maybe_start_session' ), - 2 );
85
86
		} else {
87
88
			// Use WP_Session (default)
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
89 2
			if ( ! defined( 'WP_SESSION_COOKIE' ) ) {
90 1
				define( 'WP_SESSION_COOKIE', 'give_wp_session' );
91 1
			}
92
93 2
			if ( ! class_exists( 'Recursive_ArrayAccess' ) ) {
94 1
				require_once GIVE_PLUGIN_DIR . 'includes/libraries/sessions/class-recursive-arrayaccess.php';
95 1
			}
96
97 2
			if ( ! class_exists( 'WP_Session' ) ) {
98 1
				require_once GIVE_PLUGIN_DIR . 'includes/libraries/sessions/class-wp-session.php';
99 1
				require_once GIVE_PLUGIN_DIR . 'includes/libraries/sessions/wp-session.php';
100 1
			}
101
102 2
			add_filter( 'wp_session_expiration_variant', array( $this, 'set_expiration_variant_time' ), 99999 );
103 2
			add_filter( 'wp_session_expiration', array( $this, 'set_expiration_time' ), 99999 );
104
105
		}
106
107 2
		if ( empty( $this->session ) && ! $this->use_php_sessions ) {
108 2
			add_action( 'plugins_loaded', array( $this, 'init' ), - 1 );
109 2
		} else {
110
			add_action( 'init', array( $this, 'init' ), - 1 );
111
		}
112
113 2
	}
114
115
	/**
116
	 * Setup the WP_Session instance
117
	 *
118
	 * @access public
119
	 * @since  1.0
120
	 * @return array $this->session
121
	 */
122
	public function init() {
123
124
		if ( $this->use_php_sessions ) {
125
			$this->session = isset( $_SESSION[ 'give' . $this->prefix ] ) && is_array( $_SESSION[ 'give' . $this->prefix ] ) ? $_SESSION[ 'give' . $this->prefix ] : array();
126
		} else {
127
			$this->session = WP_Session::get_instance();
128
		}
129
		
130
		return $this->session;
131
	}
132
133
134
	/**
135
	 * Retrieve session ID
136
	 *
137
	 * @access public
138
	 * @since  1.0
139
	 * @return string Session ID
140
	 */
141
	public function get_id() {
142
		return $this->session->session_id;
143
	}
144
145
146
	/**
147
	 * Retrieve a session variable
148
	 *
149
	 * @access public
150
	 * @since  1.0
151
	 *
152
	 * @param string $key Session key
153
	 *
154
	 * @return string Session variable
155
	 */
156 9
	public function get( $key ) {
157 9
		$key = sanitize_key( $key );
158
159 9
		return isset( $this->session[ $key ] ) ? maybe_unserialize( $this->session[ $key ] ) : false;
160
161
	}
162
163
	/**
164
	 * Set a session variable
165
	 *
166
	 * @since 1.0
167
	 *
168
	 * @param $key $_SESSION key
0 ignored issues
show
Documentation introduced by
The doc-type $key could not be parsed: Unknown type name "$key" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
Bug introduced by
There is no parameter named $_SESSION. 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...
169
	 * @param $value $_SESSION variable
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
Bug introduced by
There is no parameter named $_SESSION. 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...
170
	 *
171
	 * @return mixed Session variable
172
	 */
173 8
	public function set( $key, $value ) {
174
175 8
		$key = sanitize_key( $key );
176
177 8
		if ( is_array( $value ) ) {
178 6
			$this->session[ $key ] = serialize( $value );
179 6
		} else {
180 8
			$this->session[ $key ] = $value;
181
		}
182
183 8
		if ( $this->use_php_sessions ) {
184 8
			$_SESSION[ 'give' . $this->prefix ] = $this->session;
185 8
		}
186
187 8
		return $this->session[ $key ];
188
	}
189
190
	/**
191
	 * Set Cookie Variant Time
192
	 *
193
	 * @description Force the cookie expiration variant time to custom expiration option, less and hour; defaults to 23 hours (set_expiration_variant_time used in WP_Session)
194
	 *
195
	 * @access      public
196
	 * @since       1.0
197
	 *
198
	 * @return int
199
	 */
200
	public function set_expiration_variant_time() {
201
202
		return ( ! empty( $this->exp_option ) ? ( intval( $this->exp_option ) - 3600 ) : 30 * 60 * 23 );
203
	}
204
205
	/**
206
	 * Set the Cookie Expiration
207
	 *
208
	 * @description Force the cookie expiration time if set, default to 24 hours
209
	 *
210
	 * @access      public
211
	 * @since       1.0
212
	 *
213
	 * @return int
214
	 */
215
	public function set_expiration_time() {
216
217
		return ( ! empty( $this->exp_option ) ? intval( $this->exp_option ) : 30 * 60 * 24 );
218
	}
219
220
	/**
221
	 * Starts a new session if one hasn't started yet.
222
	 *
223
	 * @return null
224
	 * Checks to see if the server supports PHP sessions or if the GIVE_USE_PHP_SESSIONS constant is defined
225
	 *
226
	 * @access public
227
	 * @since  1.0
228
	 * @return bool $ret True if we are using PHP sessions, false otherwise
229
	 */
230 4
	public function use_php_sessions() {
231
232 4
		$ret = false;
233
234
		// If the database variable is already set, no need to run autodetection
235 4
		$give_use_php_sessions = (bool) get_option( 'give_use_php_sessions' );
236
237 4
		if ( ! $give_use_php_sessions ) {
238
239
			// Attempt to detect if the server supports PHP sessions
240
			if ( function_exists( 'session_start' ) && ! ini_get( 'safe_mode' ) ) {
241
242
				$this->set( 'give_use_php_sessions', 1 );
243
244
				if ( $this->get( 'give_use_php_sessions' ) ) {
245
246
					$ret = true;
247
248
					// Set the database option
249
					update_option( 'give_use_php_sessions', true );
250
251
				}
252
253
			}
254
255
		} else {
256
257 4
			$ret = $give_use_php_sessions;
258
		}
259
260
		// Enable or disable PHP Sessions based on the GIVE_USE_PHP_SESSIONS constant
261 4
		if ( defined( 'GIVE_USE_PHP_SESSIONS' ) && GIVE_USE_PHP_SESSIONS ) {
262
			$ret = true;
263 4
		} else if ( defined( 'GIVE_USE_PHP_SESSIONS' ) && ! GIVE_USE_PHP_SESSIONS ) {
264 4
			$ret = false;
265 4
		}
266
267 4
		return (bool) apply_filters( 'give_use_php_sessions', $ret );
268
	}
269
270
	/**
271
	 * Maybe Start Session
272
	 *
273
	 * @description Starts a new session if one hasn't started yet.
274
	 * @see         http://php.net/manual/en/function.session-set-cookie-params.php
275
	 */
276
	public function maybe_start_session() {
277
278
		//		session_destroy(); //Uncomment for testing ONLY
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
279
280
		if ( ! session_id() && ! headers_sent() ) {
281
			$lifetime = current_time( 'timestamp' ) + $this->set_expiration_time();
282
			session_start();
283
			setcookie( session_name(), session_id(), $lifetime ); //
284
			setcookie( session_name() . '_expiration', $lifetime, $lifetime );
285
		}
286
	}
287
288
289
	/**
290
	 * Get Session Expiration
291
	 *
292
	 * @description  Looks at the session cookies and returns the expiration date for this session if applicable
293
	 *
294
	 */
295
	public function get_session_expiration() {
296
297
		$expiration = false;
298
299
		if ( session_id() && isset( $_COOKIE[ session_name() . '_expiration' ] ) ) {
300
301
			$expiration = date( 'D, d M Y h:i:s', intval( $_COOKIE[ session_name() . '_expiration' ] ) );
302
303
		}
304
305
		return $expiration;
306
307
	}
308
309
}
310
311