PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 2.5.13
GiveWP – Donation Plugin and Fundraising Platform v2.5.13
4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / includes / class-give-session.php
give / includes Last commit date
admin 6 years ago api 6 years ago database 6 years ago deprecated 6 years ago donors 6 years ago emails 6 years ago forms 6 years ago frontend 7 years ago gateways 6 years ago libraries 7 years ago payments 6 years ago actions.php 6 years ago ajax-functions.php 6 years ago class-give-async-process.php 7 years ago class-give-background-updater.php 6 years ago class-give-cache-setting.php 6 years ago class-give-cache.php 6 years ago class-give-cli-commands.php 6 years ago class-give-comment.php 7 years ago class-give-cron.php 6 years ago class-give-donate-form.php 6 years ago class-give-donor-wall-widget.php 6 years ago class-give-donor.php 6 years ago class-give-email-access.php 7 years ago class-give-license-handler.php 6 years ago class-give-logging.php 7 years ago class-give-readme-parser.php 7 years ago class-give-roles.php 6 years ago class-give-scripts.php 6 years ago class-give-session.php 6 years ago class-give-stats.php 7 years ago class-give-template-loader.php 8 years ago class-give-tooltips.php 7 years ago class-give-translation.php 8 years ago class-notices.php 6 years ago country-functions.php 6 years ago currencies-list.php 6 years ago currency-functions.php 6 years ago error-tracking.php 7 years ago filters.php 7 years ago formatting.php 6 years ago install.php 6 years ago login-register.php 7 years ago misc-functions.php 6 years ago plugin-compatibility.php 6 years ago post-types.php 6 years ago price-functions.php 7 years ago process-donation.php 6 years ago setting-functions.php 6 years ago shortcodes.php 6 years ago template-functions.php 6 years ago user-functions.php 6 years ago
class-give-session.php
664 lines
1 <?php
2 /**
3 * Session
4 *
5 * @package Give
6 * @subpackage Classes/Give_Session
7 * @copyright Copyright (c) 2016, GiveWP
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 {
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 /**
71 * Session expiring time
72 *
73 * @since 2.2.0
74 * @access private
75 *
76 * @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 private $session_expiration = false;
89
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 public static function get_instance() {
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 $cookie = $this->get_session_cookie();
160
161 if ( ! empty( $cookie ) ) {
162 $this->donor_id = $cookie[0];
163 $this->session_expiration = $cookie[1];
164 $this->session_expiring = $cookie[2];
165 $this->has_cookie = true;
166
167 // Update session if its close to expiring.
168 if ( time() > $this->session_expiring ) {
169 $this->set_expiration_time();
170 Give()->session_db->update_session_timestamp( $this->donor_id, $this->session_expiration );
171 }
172
173 // Load session.
174 $this->session = $this->get_session_data();
175
176 } else {
177 $this->generate_donor_id();
178 }
179
180 add_action( 'give_process_donation_after_validation', array( $this, 'maybe_start_session' ) );
181
182 add_action( 'shutdown', array( $this, 'save_data' ), 20 );
183 add_action( 'wp_logout', array( $this, 'destroy_session' ) );
184
185 if ( ! is_user_logged_in() ) {
186 add_filter( 'nonce_user_logged_out', array( $this, '__nonce_user_logged_out' ) );
187 }
188
189 // Remove old sessions.
190 Give_Cron::add_daily_event( array( $this, '__cleanup_sessions' ) );
191 }
192
193 /**
194 * Get session data
195 *
196 * @since 2.2.0
197 * @access public
198 *
199 * @return array
200 */
201 public function get_session_data() {
202 return $this->has_session() ? (array) Give()->session_db->get_session( $this->donor_id, array() ) : array();
203 }
204
205
206 /**
207 * Get session by session id
208 *
209 * @since 2.2.0
210 * @access public
211 *
212 * @return array
213 */
214 public function get_session_cookie() {
215 $session = array();
216 $cookie_value = isset( $_COOKIE[ $this->cookie_name ] ) ? give_clean( $_COOKIE[ $this->cookie_name ] ) : $this->__handle_ajax_cookie(); // @codingStandardsIgnoreLine.
217
218 if ( empty( $cookie_value ) || ! is_string( $cookie_value ) ) {
219 return $session;
220 }
221
222 list( $donor_id, $session_expiration, $session_expiring, $cookie_hash ) = explode( '||', $cookie_value );
223
224 if ( empty( $donor_id ) ) {
225 return $session;
226 }
227
228 // Validate hash.
229 $to_hash = $donor_id . '|' . $session_expiration;
230 $hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
231
232 if ( empty( $cookie_hash ) || ! hash_equals( $hash, $cookie_hash ) ) {
233 return $session;
234 }
235
236 /**
237 * Filter the session cookie data
238 *
239 * @since 2.2.6
240 */
241 $cookie_data = apply_filters(
242 'give_get_session_cookie',
243 array( $donor_id, $session_expiration, $session_expiring, $cookie_hash )
244 );
245
246 return $cookie_data;
247 }
248
249
250 /**
251 * Load session cookie by ajax
252 *
253 * @since 2.2.6
254 * @access private
255 *
256 * @return array|bool|string
257 */
258 private function __handle_ajax_cookie(){
259 $cookie = false;
260
261 // @see https://github.com/impress-org/give/issues/3705
262 if (
263 empty( $cookie )
264 && wp_doing_ajax()
265 && isset( $_GET['action'] )
266 && 'get_receipt' === $_GET['action']
267 ) {
268 $cookie = isset( $_GET[$this->cookie_name] ) ? give_clean( $_GET[$this->cookie_name] ) : false;
269 }
270
271 return $cookie;
272 }
273
274
275 /**
276 * Check if session exist for specific session id
277 *
278 * @since 2.2.0
279 * @access public
280 *
281 * @return bool
282 */
283 public function has_session() {
284 return $this->has_cookie;
285 }
286
287 /**
288 * Set cookie name
289 *
290 * @since 2.2.0
291 * @access private
292 *
293 * @return void
294 */
295 private function set_cookie_name() {
296 /**
297 * Filter the cookie name
298 *
299 * @since 2.2.0
300 *
301 * @param string $cookie_name Cookie name.
302 * @param string $cookie_type Cookie type session or nonce.
303 */
304 $this->cookie_name = apply_filters(
305 'give_session_cookie',
306 'wp-give_session_' . COOKIEHASH, // Cookie name.
307 'session' // Cookie type.
308 );
309
310 $this->nonce_cookie_name = apply_filters(
311 'give_session_cookie',
312 'wp-give_session_reset_nonce_' . COOKIEHASH, // Cookie name.
313 'nonce' // Cookie type.
314 );
315 }
316
317 /**
318 * Get Session
319 *
320 * Retrieve session variable for a given session key.
321 *
322 * @since 1.0
323 * @access public
324 *
325 * @param string $key Session key.
326 * @param mixed $default default value.
327 *
328 * @return string|array Session variable.
329 */
330 public function get( $key, $default = false ) {
331 $key = sanitize_key( $key );
332
333 return isset( $this->session[ $key ] ) ? maybe_unserialize( $this->session[ $key ] ) : $default;
334 }
335
336 /**
337 * Set Session
338 *
339 * @since 1.0
340 * @access public
341 *
342 * @param string $key Session key.
343 * @param mixed $value Session variable.
344 *
345 * @return string Session variable.
346 */
347 public function set( $key, $value ) {
348 if ( $value !== $this->get( $key ) ) {
349 $this->session[ sanitize_key( $key ) ] = maybe_serialize( $value );
350 $this->session_data_changed = true;
351 }
352
353 return $this->session[ $key ];
354 }
355
356 /**
357 * Set Session Cookies
358 *
359 * Cookies are used to increase the session lifetime using the give setting. This is helpful for when a user closes
360 * their browser after making a donation and comes back to the site.
361 *
362 * @since 1.4
363 * @access public
364 *
365 * @param bool $set Flag to check if set cookie or not.
366 */
367 public function set_session_cookies( $set ) {
368 if ( $set ) {
369 $this->set_expiration_time();
370
371 $to_hash = $this->donor_id . '|' . $this->session_expiration;
372 $cookie_hash = hash_hmac( 'md5', $to_hash, wp_hash( $to_hash ) );
373 $cookie_value = $this->donor_id . '||' . $this->session_expiration . '||' . $this->session_expiring . '||' . $cookie_hash;
374 $this->has_cookie = true;
375
376 give_setcookie( $this->cookie_name, $cookie_value, $this->session_expiration, apply_filters( 'give_session_use_secure_cookie', false ) );
377 give_setcookie( $this->nonce_cookie_name, '1', $this->session_expiration, apply_filters( 'give_session_use_secure_cookie', false ) );
378 }
379 }
380
381 /**
382 * Set Cookie Expiration
383 *
384 * Force the cookie expiration time if set, default to 24 hours.
385 *
386 * @since 1.0
387 * @access public
388 *
389 * @return int
390 */
391 public function set_expiration_time() {
392 $this->session_expiring = time() + intval( apply_filters( 'give_session_expiring', ( $this->exp_option - 3600 ) ) ); // Default 11 Hours.
393 $this->session_expiration = time() + intval( apply_filters( 'give_session_expiration', $this->exp_option ) ); // Default 12 Hours.
394
395 return $this->session_expiration;
396 }
397
398 /**
399 * Get Session Expiration
400 *
401 * Looks at the session cookies and returns the expiration date for this session if applicable
402 *
403 * @since 2.2.0
404 * @access public
405 *
406 * @return string|bool Formatted expiration date string.
407 */
408 public function get_session_expiration() {
409 return $this->has_session() ? $this->session_expiration :false;
410 }
411
412 /**
413 * Maybe Start Session
414 *
415 * Starts a new session if one hasn't started yet.
416 *
417 * @since 2.2.0
418 * @access public
419 *
420 * @return void
421 */
422 public function maybe_start_session() {
423 if (
424 ! headers_sent()
425 && empty( $this->session )
426 && ! $this->has_cookie
427 ) {
428 $this->set_session_cookies( true );
429 }
430 }
431
432 /**
433 * Generate a unique donor ID.
434 *
435 * Uses Portable PHP password hashing framework to generate a unique cryptographically strong ID.
436 *
437 * @since 2.2.0
438 * @access public
439 */
440 public function generate_donor_id() {
441 require_once ABSPATH . 'wp-includes/class-phpass.php';
442
443 $hasher = new PasswordHash( 8, false );
444 $this->donor_id = md5( $hasher->get_random_bytes( 32 ) );
445 }
446
447 /**
448 * Save donor session data
449 *
450 * @since 2.2.0
451 * @access public
452 */
453 public function save_data() {
454 // Dirty if something changed - prevents saving nothing new.
455 if ( $this->session_data_changed && $this->has_session() ) {
456 global $wpdb;
457
458 Give()->session_db->__replace(
459 Give()->session_db->table_name,
460 array(
461 'session_key' => $this->donor_id,
462 'session_value' => maybe_serialize( $this->session ),
463 'session_expiry' => $this->session_expiration,
464 ),
465 array(
466 '%s',
467 '%s',
468 '%d',
469 )
470 );
471
472 $this->session_data_changed = false;
473 }
474 }
475
476 /**
477 * Destroy all session data.
478 *
479 * @since 2.2.0
480 * @access public
481 */
482 public function destroy_session() {
483 give_setcookie( $this->cookie_name, '', time() - YEAR_IN_SECONDS, apply_filters( 'give_session_use_secure_cookie', false ) );
484 give_setcookie( $this->nonce_cookie_name, '', time() - YEAR_IN_SECONDS, apply_filters( 'give_session_use_secure_cookie', false ) );
485
486 Give()->session_db->delete_session( $this->donor_id );
487
488 $this->session = array();
489 $this->session_data_changed = false;
490
491 $this->generate_donor_id();
492 }
493
494 /**
495 * Delete nonce cookie if generating fresh form html.
496 *
497 * @since 2.2.0
498 * @access public
499 *
500 * @return bool
501 */
502 public function is_delete_nonce_cookie(){
503 $value = false;
504
505 if ( Give()->session->has_session() ) {
506 $value = true;
507 }
508
509 return $value;
510 }
511
512 /**
513 * Get cookie names
514 *
515 * @since 2.2.0
516 * @access public
517 *
518 * @param string $type Nonce type.
519 *
520 * @return string Cookie name
521 */
522 public function get_cookie_name( $type = '' ) {
523 $name = '';
524
525 switch ( $type ) {
526 case 'nonce':
527 $name = $this->nonce_cookie_name;
528 break;
529
530 case 'session':
531 $name = $this->cookie_name;
532 break;
533 }
534
535 return $name;
536 }
537
538 /**
539 * When a user is logged out, ensure they have a unique nonce by using the donor/session ID.
540 * Note: for internal logic only.
541 *
542 * @since 2.2.0
543 * @access public
544 *
545 * @param int $uid User ID.
546 *
547 * @return string
548 */
549 public function __nonce_user_logged_out( $uid ) {
550 return $this->has_session() && $this->donor_id ? $this->donor_id : $uid;
551 }
552
553
554 /**
555 * Cleanup session data from the database and clear caches.
556 * Note: for internal logic only.
557 *
558 * @since 2.2.0
559 * @access public
560 */
561 public function __cleanup_sessions() { // @codingStandardsIgnoreLine
562 Give()->session_db->delete_expired_sessions();
563 }
564
565
566 /**
567 * Get Session ID
568 *
569 * Retrieve session ID.
570 *
571 * @since 1.0
572 * @deprecated 2.2.0
573 * @access public
574 *
575 * @return string Session ID.
576 */
577 public function get_id() {
578 return $this->get_cookie_name( 'session' );
579 }
580
581 /**
582 * Set Cookie Variant Time
583 *
584 * Force the cookie expiration variant time to custom expiration option, less and hour. defaults to 23 hours
585 * (set_expiration_variant_time used in WP_Session).
586 *
587 * @since 1.0
588 * @deprecated 2.2.0
589 * @access public
590 *
591 * @return int
592 */
593 public function set_expiration_variant_time() {
594
595 return ( ! empty( $this->exp_option ) ? ( intval( $this->exp_option ) - 3600 ) : 30 * 60 * 23 );
596 }
597
598 /**
599 * Starts a new session if one has not started yet.
600 *
601 * Checks to see if the server supports PHP sessions or if the GIVE_USE_PHP_SESSIONS constant is defined.
602 *
603 * @since 1.0
604 * @access public
605 * @deprecated 2.2.0
606 *
607 * @return bool $ret True if we are using PHP sessions, false otherwise.
608 */
609 public function use_php_sessions() {
610 $ret = false;
611
612 give_doing_it_wrong( __FUNCTION__, __( 'We are using database session logic instead of PHP session since GiveWP 2.2.0', 'give' ) );
613
614 return (bool) apply_filters( 'give_use_php_sessions', $ret );
615 }
616
617 /**
618 * Should Start Session
619 *
620 * Determines if we should start sessions.
621 *
622 * @since 1.4
623 * @access public
624 * @deprecated 2.2.0
625 *
626 * @return bool
627 */
628 public function should_start_session() {
629
630 $start_session = true;
631
632 give_doing_it_wrong( __FUNCTION__, __( 'We are using database session logic instead of PHP session since GiveWP 2.2.0', 'give' ) );
633
634
635 if ( ! empty( $_SERVER['REQUEST_URI'] ) ) { // @codingStandardsIgnoreLine
636
637 $blacklist = apply_filters(
638 'give_session_start_uri_blacklist', array(
639 'feed',
640 'feed',
641 'feed/rss',
642 'feed/rss2',
643 'feed/rdf',
644 'feed/atom',
645 'comments/feed/',
646 )
647 );
648 $uri = ltrim( $_SERVER['REQUEST_URI'], '/' ); // // @codingStandardsIgnoreLine
649 $uri = untrailingslashit( $uri );
650 if ( in_array( $uri, $blacklist, true ) ) {
651 $start_session = false;
652 }
653 if ( false !== strpos( $uri, 'feed=' ) ) {
654 $start_session = false;
655 }
656 if ( is_admin() ) {
657 $start_session = false;
658 }
659 }
660
661 return apply_filters( 'give_start_session', $start_session );
662 }
663 }
664