This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Session |
||
4 | * |
||
5 | * @package Give |
||
6 | * @subpackage Classes/Give_Session |
||
7 | * @copyright Copyright (c) 2016, WordImpress |
||
8 | * @license https://opensource.org/licenses/gpl-license GNU Public License |
||
9 | * @since 1.0 |
||
10 | */ |
||
11 | |||
12 | // Exit if accessed directly. |
||
13 | if ( ! defined( 'ABSPATH' ) ) { |
||
14 | exit; |
||
15 | } |
||
16 | |||
17 | /** |
||
18 | * Class Give_Session |
||
19 | */ |
||
20 | class Give_Session { |
||
0 ignored issues
–
show
Coding Style
introduced
by
![]() |
|||
21 | /** |
||
22 | * Instance. |
||
23 | * |
||
24 | * @since 2.2.0 |
||
25 | * @access private |
||
26 | * @var Give_Session |
||
27 | */ |
||
28 | static private $instance; |
||
29 | |||
30 | /** |
||
31 | * Holds our session data |
||
32 | * |
||
33 | * @since 1.0 |
||
34 | * @access private |
||
35 | * |
||
36 | * @var array |
||
37 | */ |
||
38 | private $session = array(); |
||
39 | |||
40 | /** |
||
41 | * Holds our session data |
||
42 | * |
||
43 | * @since 1.0 |
||
44 | * @access private |
||
45 | * |
||
46 | * @var string |
||
47 | */ |
||
48 | private $session_data_changed = false; |
||
49 | |||
50 | /** |
||
51 | * Cookie Name |
||
52 | * |
||
53 | * @since 1.0 |
||
54 | * @access private |
||
55 | * |
||
56 | * @var string |
||
57 | */ |
||
58 | private $cookie_name = ''; |
||
59 | |||
60 | /** |
||
61 | * Donor Unique ID |
||
62 | * |
||
63 | * @since 1.0 |
||
64 | * @access private |
||
65 | * |
||
66 | * @var string |
||
67 | */ |
||
68 | private $donor_id = ''; |
||
69 | |||
70 | 2 | /** |
|
71 | * Session expiring time |
||
72 | 2 | * |
|
73 | 2 | * @since 2.2.0 |
|
74 | * @access private |
||
75 | * |
||
76 | 2 | * @var string |
|
77 | */ |
||
78 | private $session_expiring = false; |
||
79 | |||
80 | /** |
||
81 | * Session expiration time |
||
82 | * |
||
83 | * @since 2.2.0 |
||
84 | * @access private |
||
85 | * |
||
86 | * @var string |
||
87 | */ |
||
88 | 2 | private $session_expiration = false; |
|
89 | 2 | ||
90 | /** |
||
91 | * Flag to check if donor has cookie or not |
||
92 | * |
||
93 | * @since 2.2.0 |
||
94 | * @access private |
||
95 | * |
||
96 | * @var bool |
||
97 | */ |
||
98 | private $has_cookie = false; |
||
99 | |||
100 | /** |
||
101 | * Expiration Time |
||
102 | * |
||
103 | * @since 1.0 |
||
104 | * @access private |
||
105 | * |
||
106 | * @var int |
||
107 | */ |
||
108 | private $exp_option = false; |
||
109 | |||
110 | /** |
||
111 | * Expiration Time |
||
112 | * |
||
113 | * @since 2.2.0 |
||
114 | * @access private |
||
115 | * |
||
116 | * @var string |
||
117 | */ |
||
118 | private $nonce_cookie_name = ''; |
||
119 | |||
120 | /** |
||
121 | * Singleton pattern. |
||
122 | * |
||
123 | * @since 2.2.0 |
||
124 | * @access private |
||
125 | */ |
||
126 | private function __construct() { |
||
127 | } |
||
128 | |||
129 | |||
130 | /** |
||
131 | * Get instance. |
||
132 | * |
||
133 | * @since 2.2.0 |
||
134 | * @access public |
||
135 | * @return Give_Session |
||
136 | */ |
||
137 | View Code Duplication | public static function get_instance() { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
138 | if ( null === static::$instance ) { |
||
139 | self::$instance = new static(); |
||
140 | self::$instance->__setup(); |
||
141 | } |
||
142 | |||
143 | return self::$instance; |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * Setup |
||
148 | * |
||
149 | * @since 2.2.0 |
||
150 | * @access public |
||
151 | */ |
||
152 | private function __setup() { // @codingStandardsIgnoreLine |
||
153 | $this->exp_option = give_get_option( 'session_lifetime' ); |
||
154 | $this->exp_option = ! empty( $this->exp_option ) |
||
155 | ? $this->exp_option |
||
156 | : 30 * 60 * 24; // Default expiration time is 12 hours |
||
157 | |||
158 | $this->set_cookie_name(); |
||
159 | $this->cookie_name = $this->get_cookie_name( 'session' ); |
||
160 | $cookie = $this->get_session_cookie(); |
||
161 | |||
162 | if ( ! empty( $cookie ) ) { |
||
163 | $this->donor_id = $cookie[0]; |
||
164 | $this->session_expiration = $cookie[1]; |
||
165 | 12 | $this->session_expiring = $cookie[2]; |
|
166 | 12 | $this->has_cookie = true; |
|
167 | |||
168 | 12 | // Update session if its close to expiring. |
|
169 | if ( time() > $this->session_expiring ) { |
||
170 | $this->set_expiration_time(); |
||
171 | Give()->session_db->update_session_timestamp( $this->donor_id, $this->session_expiration ); |
||
172 | } |
||
173 | |||
174 | // Load session. |
||
175 | $this->session = $this->get_session_data(); |
||
176 | |||
177 | } else { |
||
178 | $this->generate_donor_id(); |
||
179 | } |
||
180 | |||
181 | add_action( 'give_process_donation_after_validation', array( $this, 'maybe_start_session' ) ); |
||
182 | 11 | ||
183 | add_action( 'shutdown', array( $this, 'save_data' ), 20 ); |
||
184 | 11 | add_action( 'wp_logout', array( $this, 'destroy_session' ) ); |
|
185 | |||
186 | 11 | if ( ! is_user_logged_in() ) { |
|
187 | 9 | add_filter( 'nonce_user_logged_out', array( $this, '__nonce_user_logged_out' ) ); |
|
188 | 9 | } |
|
189 | 9 | ||
190 | // Remove old sessions. |
||
191 | Give_Cron::add_daily_event( array( $this, '__cleanup_sessions' ) ); |
||
192 | 11 | } |
|
193 | 11 | ||
194 | 11 | /** |
|
195 | * Get session data |
||
196 | 11 | * |
|
197 | * @since 2.2.0 |
||
198 | * @access public |
||
199 | * |
||
200 | * @return array |
||
201 | */ |
||
202 | public function get_session_data() { |
||
203 | return $this->has_session() ? (array) Give()->session_db->get_session( $this->donor_id, array() ) : array(); |
||
204 | } |
||
205 | |||
206 | |||
207 | /** |
||
208 | * Get session by session id |
||
209 | * |
||
210 | * @since 2.2.0 |
||
211 | * @access public |
||
212 | * |
||
213 | * @return array |
||
214 | */ |
||
215 | public function get_session_cookie() { |
||
216 | $session = array(); |
||
217 | $cookie_value = isset( $_COOKIE[ $this->cookie_name ] ) ? give_clean( $_COOKIE[ $this->cookie_name ] ) : false; // @codingStandardsIgnoreLine. |
||
218 | |||
219 | if ( empty( $cookie_value ) || ! is_string( $cookie_value ) ) { |
||
220 | return $session; |
||
221 | } |
||
222 | |||
223 | list( $donor_id, $session_expiration, $session_expiring, $cookie_hash ) = explode( '||', $cookie_value ); |
||
224 | |||
225 | if ( empty( $donor_id ) ) { |
||
226 | return $session; |
||
227 | } |
||
228 | |||
229 | // Validate hash. |
||
230 | $to_hash = $donor_id . '|' . $session_expiration; |
||
231 | $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) ); |
||
232 | |||
233 | if ( empty( $cookie_hash ) || ! hash_equals( $hash, $cookie_hash ) ) { |
||
234 | return $session; |
||
235 | } |
||
236 | |||
237 | return array( $donor_id, $session_expiration, $session_expiring, $cookie_hash ); |
||
238 | } |
||
239 | |||
240 | |||
241 | /** |
||
242 | * Check if session exist for specific session id |
||
243 | * |
||
244 | * @since 2.2.0 |
||
245 | * @access public |
||
246 | * |
||
247 | * @return bool |
||
248 | */ |
||
249 | public function has_session() { |
||
250 | return $this->has_cookie; |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * Set cookie name |
||
255 | * |
||
256 | * @since 2.2.0 |
||
257 | 4 | * @access private |
|
258 | * |
||
259 | 4 | * @return string Cookie name. |
|
260 | */ |
||
261 | private function set_cookie_name() { |
||
262 | 4 | $this->cookie_name = apply_filters( 'give_session_cookie', 'wp_give_session_' . COOKIEHASH ); |
|
263 | $this->nonce_cookie_name = 'wp_give_session_reset_nonce_' . COOKIEHASH; |
||
264 | 4 | } |
|
265 | |||
266 | /** |
||
267 | * Get Session |
||
268 | * |
||
269 | * Retrieve session variable for a given session key. |
||
270 | * |
||
271 | * @since 1.0 |
||
272 | * @access public |
||
273 | * |
||
274 | * @param string $key Session key. |
||
275 | * @param mixed $default default value. |
||
276 | * |
||
277 | * @return string|array Session variable. |
||
278 | */ |
||
279 | public function get( $key, $default = false ) { |
||
280 | $key = sanitize_key( $key ); |
||
281 | |||
282 | return isset( $this->session[ $key ] ) ? maybe_unserialize( $this->session[ $key ] ) : $default; |
||
283 | } |
||
284 | 4 | ||
285 | /** |
||
286 | * Set Session |
||
287 | * |
||
288 | 4 | * @since 1.0 |
|
289 | * @access public |
||
290 | 4 | * |
|
291 | 4 | * @param string $key Session key. |
|
292 | 4 | * @param mixed $value Session variable. |
|
293 | * |
||
294 | 4 | * @return string Session variable. |
|
295 | */ |
||
296 | public function set( $key, $value ) { |
||
297 | if ( $value !== $this->get( $key ) ) { |
||
298 | $this->session[ sanitize_key( $key ) ] = maybe_serialize( $value ); |
||
299 | $this->session_data_changed = true; |
||
0 ignored issues
–
show
The property
$session_data_changed was declared of type string , but true is of type boolean . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
300 | } |
||
301 | |||
302 | return $this->session[ $key ]; |
||
303 | 2 | } |
|
304 | |||
305 | 2 | /** |
|
306 | * Set Session Cookies |
||
307 | 2 | * |
|
308 | * Cookies are used to increase the session lifetime using the give setting. This is helpful for when a user closes |
||
309 | 2 | * their browser after making a donation and comes back to the site. |
|
310 | 2 | * |
|
311 | 2 | * @since 1.4 |
|
312 | 2 | * @access public |
|
313 | 2 | * |
|
314 | 2 | * @param bool $set Flag to check if set cookie or not. |
|
315 | 2 | */ |
|
316 | public function set_session_cookies( $set ) { |
||
317 | 2 | if ( $set ) { |
|
318 | 2 | $this->set_expiration_time(); |
|
319 | 2 | ||
320 | 2 | $to_hash = $this->donor_id . '|' . $this->session_expiration; |
|
321 | $cookie_hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) ); |
||
322 | $cookie_value = $this->donor_id . '||' . $this->session_expiration . '||' . $this->session_expiring . '||' . $cookie_hash; |
||
323 | 2 | $this->has_cookie = true; |
|
324 | |||
325 | give_setcookie( $this->cookie_name, $cookie_value, $this->session_expiration, apply_filters( 'give_session_use_secure_cookie', false ) ); |
||
326 | 2 | give_setcookie( $this->nonce_cookie_name, '1', $this->session_expiration, apply_filters( 'give_session_use_secure_cookie', false ) ); |
|
327 | 2 | } |
|
328 | 2 | } |
|
329 | 2 | ||
330 | /** |
||
331 | 2 | * Set Cookie Expiration |
|
332 | * |
||
333 | * Force the cookie expiration time if set, default to 24 hours. |
||
334 | * |
||
335 | * @since 1.0 |
||
336 | * @access public |
||
337 | * |
||
338 | * @return int |
||
339 | */ |
||
340 | public function set_expiration_time() { |
||
341 | $this->session_expiring = time() + intval( apply_filters( 'give_session_expiring', ( $this->exp_option - 3600 ) ) ); // Default 11 Hours. |
||
0 ignored issues
–
show
The property
$session_expiring was declared of type string , but time() + intval(apply_fi...is->exp_option - 3600)) is of type integer . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
342 | $this->session_expiration = time() + intval( apply_filters( 'give_session_expiration', $this->exp_option ) ); // Default 12 Hours. |
||
0 ignored issues
–
show
The property
$session_expiration was declared of type string , but time() + intval(apply_fi...n', $this->exp_option)) is of type integer . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
343 | |||
344 | return $this->session_expiration; |
||
345 | } |
||
346 | |||
347 | /** |
||
348 | * Get Session Expiration |
||
349 | * |
||
350 | * Looks at the session cookies and returns the expiration date for this session if applicable |
||
351 | * |
||
352 | * @since 2.2.0 |
||
353 | * @access public |
||
354 | * |
||
355 | * @return string Formatted expiration date string. |
||
356 | */ |
||
357 | public function get_session_expiration() { |
||
358 | return $this->session_expiration; |
||
359 | } |
||
360 | |||
361 | /** |
||
362 | * Maybe Start Session |
||
363 | * |
||
364 | * Starts a new session if one hasn't started yet. |
||
365 | * |
||
366 | * @since 2.2.0 |
||
367 | * @access public |
||
368 | * |
||
369 | * @return void |
||
370 | */ |
||
371 | public function maybe_start_session() { |
||
372 | if ( |
||
373 | ! headers_sent() |
||
374 | && empty( $this->session ) |
||
375 | && ! $this->has_cookie |
||
376 | ) { |
||
377 | $this->set_session_cookies( true ); |
||
378 | } |
||
379 | } |
||
380 | |||
381 | /** |
||
382 | * Generate a unique donor ID. |
||
383 | * |
||
384 | * Uses Portable PHP password hashing framework to generate a unique cryptographically strong ID. |
||
385 | * |
||
386 | * @since 2.2.0 |
||
387 | * @access public |
||
388 | */ |
||
389 | public function generate_donor_id() { |
||
390 | require_once ABSPATH . 'wp-includes/class-phpass.php'; |
||
391 | |||
392 | $hasher = new PasswordHash( 8, false ); |
||
393 | $this->donor_id = md5( $hasher->get_random_bytes( 32 ) ); |
||
394 | } |
||
395 | |||
396 | /** |
||
397 | * Save donor session data |
||
398 | * |
||
399 | * @since 2.2.0 |
||
400 | * @access public |
||
401 | */ |
||
402 | public function save_data() { |
||
403 | // Dirty if something changed - prevents saving nothing new. |
||
404 | if ( $this->session_data_changed && $this->has_session() ) { |
||
405 | global $wpdb; |
||
406 | |||
407 | Give()->session_db->__replace( |
||
408 | Give()->session_db->table_name, |
||
409 | array( |
||
410 | 'session_key' => $this->donor_id, |
||
411 | 'session_value' => maybe_serialize( $this->session ), |
||
412 | 'session_expiry' => $this->session_expiration, |
||
413 | ), |
||
414 | array( |
||
415 | '%s', |
||
416 | '%s', |
||
417 | '%d', |
||
418 | ) |
||
419 | ); |
||
420 | |||
421 | $this->session_data_changed = false; |
||
0 ignored issues
–
show
The property
$session_data_changed was declared of type string , but false is of type false . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
422 | } |
||
423 | } |
||
424 | |||
425 | /** |
||
426 | * Destroy all session data. |
||
427 | * |
||
428 | * @since 2.2.0 |
||
429 | * @access public |
||
430 | */ |
||
431 | public function destroy_session() { |
||
432 | give_setcookie( $this->cookie_name, '', time() - YEAR_IN_SECONDS, apply_filters( 'give_session_use_secure_cookie', false ) ); |
||
433 | give_setcookie( $this->nonce_cookie_name, '', time() - YEAR_IN_SECONDS, apply_filters( 'give_session_use_secure_cookie', false ) ); |
||
434 | |||
435 | Give()->session_db->delete_session( $this->donor_id ); |
||
436 | |||
437 | $this->session = array(); |
||
438 | $this->session_data_changed = false; |
||
0 ignored issues
–
show
The property
$session_data_changed was declared of type string , but false is of type false . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
439 | |||
440 | $this->generate_donor_id(); |
||
441 | } |
||
442 | |||
443 | /** |
||
444 | * Delete nonce cookie if generating fresh form html. |
||
445 | * |
||
446 | * @since 2.2.0 |
||
447 | * @access public |
||
448 | * |
||
449 | * @return bool |
||
450 | */ |
||
451 | public function is_delete_nonce_cookie(){ |
||
452 | $value = false; |
||
453 | |||
454 | if ( Give()->session->has_session() ) { |
||
455 | $value = true; |
||
456 | } |
||
457 | |||
458 | return $value; |
||
459 | } |
||
460 | |||
461 | /** |
||
462 | * Get cookie names |
||
463 | * |
||
464 | * @since 2.2.0 |
||
465 | * @access public |
||
466 | * |
||
467 | * @param string $type Nonce type. |
||
468 | * |
||
469 | * @return string Cookie name |
||
470 | */ |
||
471 | public function get_cookie_name( $type = '' ) { |
||
472 | $name = ''; |
||
473 | |||
474 | switch ( $type ) { |
||
475 | case 'nonce': |
||
476 | $name = $this->nonce_cookie_name; |
||
477 | break; |
||
478 | |||
479 | case 'session': |
||
480 | $name = $this->cookie_name; |
||
481 | break; |
||
482 | } |
||
483 | |||
484 | return $name; |
||
485 | } |
||
486 | |||
487 | /** |
||
488 | * When a user is logged out, ensure they have a unique nonce by using the donor/session ID. |
||
489 | * Note: for internal logic only. |
||
490 | * |
||
491 | * @since 2.2.0 |
||
492 | * @access public |
||
493 | * |
||
494 | * @param int $uid User ID. |
||
495 | * |
||
496 | * @return string |
||
497 | */ |
||
498 | public function __nonce_user_logged_out( $uid ) { |
||
0 ignored issues
–
show
|
|||
499 | return $this->has_session() && $this->donor_id ? $this->donor_id : $uid; |
||
500 | } |
||
501 | |||
502 | |||
503 | /** |
||
504 | * Cleanup session data from the database and clear caches. |
||
505 | * Note: for internal logic only. |
||
506 | * |
||
507 | * @since 2.2.0 |
||
508 | * @access public |
||
509 | */ |
||
510 | public function __cleanup_sessions() { // @codingStandardsIgnoreLine |
||
511 | Give()->session_db->delete_expired_sessions(); |
||
512 | } |
||
513 | |||
514 | |||
515 | /** |
||
516 | * Get Session ID |
||
517 | * |
||
518 | * Retrieve session ID. |
||
519 | * |
||
520 | * @since 1.0 |
||
521 | * @deprecated 2.2.0 |
||
522 | * @access public |
||
523 | * |
||
524 | * @return string Session ID. |
||
525 | */ |
||
526 | public function get_id() { |
||
527 | return $this->get_cookie_name('session'); |
||
0 ignored issues
–
show
|
|||
528 | } |
||
529 | |||
530 | /** |
||
531 | * Set Cookie Variant Time |
||
532 | * |
||
533 | * Force the cookie expiration variant time to custom expiration option, less and hour. defaults to 23 hours |
||
534 | * (set_expiration_variant_time used in WP_Session). |
||
535 | * |
||
536 | * @since 1.0 |
||
537 | * @deprecated 2.2.0 |
||
538 | * @access public |
||
539 | * |
||
540 | * @return int |
||
541 | */ |
||
542 | public function set_expiration_variant_time() { |
||
543 | |||
544 | return ( ! empty( $this->exp_option ) ? ( intval( $this->exp_option ) - 3600 ) : 30 * 60 * 23 ); |
||
545 | } |
||
546 | |||
547 | /** |
||
548 | * Starts a new session if one has not started yet. |
||
549 | * |
||
550 | * Checks to see if the server supports PHP sessions or if the GIVE_USE_PHP_SESSIONS constant is defined. |
||
551 | * |
||
552 | * @since 1.0 |
||
553 | * @access public |
||
554 | * @deprecated 2.2.0 |
||
555 | * |
||
556 | * @return bool $ret True if we are using PHP sessions, false otherwise. |
||
557 | */ |
||
558 | public function use_php_sessions() { |
||
559 | $ret = false; |
||
560 | |||
561 | give_doing_it_wrong( __FUNCTION__, __( 'We are using database session logic instead of PHP session', 'give' ), '2.2.0' ); |
||
562 | |||
563 | return (bool) apply_filters( 'give_use_php_sessions', $ret ); |
||
564 | } |
||
565 | |||
566 | /** |
||
567 | * Should Start Session |
||
568 | * |
||
569 | * Determines if we should start sessions. |
||
570 | * |
||
571 | * @since 1.4 |
||
572 | * @access public |
||
573 | * @deprecated 2.2.0 |
||
574 | * |
||
575 | * @return bool |
||
576 | */ |
||
577 | public function should_start_session() { |
||
578 | |||
579 | $start_session = true; |
||
580 | |||
581 | give_doing_it_wrong( __FUNCTION__, __( 'We are using database session logic instead of PHP session', 'give' ), '2.2.0' ); |
||
582 | |||
0 ignored issues
–
show
|
|||
583 | |||
584 | if ( ! empty( $_SERVER['REQUEST_URI'] ) ) { // @codingStandardsIgnoreLine |
||
585 | |||
586 | $blacklist = apply_filters( |
||
587 | 'give_session_start_uri_blacklist', array( |
||
588 | 'feed', |
||
589 | 'feed', |
||
590 | 'feed/rss', |
||
591 | 'feed/rss2', |
||
592 | 'feed/rdf', |
||
593 | 'feed/atom', |
||
594 | 'comments/feed/', |
||
595 | ) |
||
596 | ); |
||
597 | $uri = ltrim( $_SERVER['REQUEST_URI'], '/' ); // // @codingStandardsIgnoreLine |
||
598 | $uri = untrailingslashit( $uri ); |
||
599 | if ( in_array( $uri, $blacklist, true ) ) { |
||
600 | $start_session = false; |
||
601 | } |
||
602 | if ( false !== strpos( $uri, 'feed=' ) ) { |
||
603 | $start_session = false; |
||
604 | } |
||
605 | if ( is_admin() ) { |
||
606 | $start_session = false; |
||
607 | } |
||
608 | } |
||
609 | |||
610 | return apply_filters( 'give_start_session', $start_session ); |
||
611 | } |
||
612 | } |
||
613 |