Merge pull request #22666 from woocommerce/update/21101

Prevent multiple cookie sets per request
This commit is contained in:
Gerhard Potgieter 2019-02-06 15:40:04 +02:00 committed by GitHub
commit 4e311b944f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 10 deletions

View File

@ -47,13 +47,19 @@ final class WC_Cart_Session {
public function init() { public function init() {
add_action( 'wp_loaded', array( $this, 'get_cart_from_session' ) ); add_action( 'wp_loaded', array( $this, 'get_cart_from_session' ) );
add_action( 'woocommerce_cart_emptied', array( $this, 'destroy_cart_session' ) ); add_action( 'woocommerce_cart_emptied', array( $this, 'destroy_cart_session' ) );
add_action( 'wp', array( $this, 'maybe_set_cart_cookies' ), 99 );
add_action( 'woocommerce_add_to_cart', array( $this, 'maybe_set_cart_cookies' ) );
add_action( 'woocommerce_after_calculate_totals', array( $this, 'set_session' ) ); add_action( 'woocommerce_after_calculate_totals', array( $this, 'set_session' ) );
add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'set_session' ) ); add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'set_session' ) );
add_action( 'woocommerce_removed_coupon', array( $this, 'set_session' ) ); add_action( 'woocommerce_removed_coupon', array( $this, 'set_session' ) );
add_action( 'shutdown', array( $this, 'maybe_set_cart_cookies' ), 0 );
add_action( 'woocommerce_cart_updated', array( $this, 'persistent_cart_update' ) ); add_action( 'woocommerce_cart_updated', array( $this, 'persistent_cart_update' ) );
// Cookie events - cart cookies need to be set before headers are sent.
if ( function_exists( 'header_register_callback' ) ) {
header_register_callback( array( $this, 'maybe_set_cart_cookies' ) ); // phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.header_register_callbackFound
} else {
add_action( 'woocommerce_add_to_cart', array( $this, 'maybe_set_cart_cookies' ) );
add_action( 'wp', array( $this, 'maybe_set_cart_cookies' ), 99 );
add_action( 'shutdown', array( $this, 'maybe_set_cart_cookies' ), 0 );
}
} }
/** /**
@ -253,18 +259,34 @@ final class WC_Cart_Session {
} }
/** /**
* Set cart hash cookie and items in cart. * Set cart hash cookie and items in cart if not already set.
* *
* @param bool $set Should cookies be set (true) or unset. * @param bool $set Should cookies be set (true) or unset.
*/ */
private function set_cart_cookies( $set = true ) { private function set_cart_cookies( $set = true ) {
if ( $set ) { if ( $set ) {
wc_setcookie( 'woocommerce_items_in_cart', 1 ); $setcookies = array(
wc_setcookie( 'woocommerce_cart_hash', WC()->cart->get_cart_hash() ); 'woocommerce_items_in_cart' => '1',
} elseif ( isset( $_COOKIE['woocommerce_items_in_cart'] ) ) { // WPCS: input var ok. 'woocommerce_cart_hash' => WC()->cart->get_cart_hash(),
wc_setcookie( 'woocommerce_items_in_cart', 0, time() - HOUR_IN_SECONDS ); );
wc_setcookie( 'woocommerce_cart_hash', '', time() - HOUR_IN_SECONDS ); foreach ( $setcookies as $name => $value ) {
if ( ! isset( $_COOKIE[ $name ] ) || $_COOKIE[ $name ] !== $value ) {
wc_setcookie( $name, $value );
}
}
} else {
$unsetcookies = array(
'woocommerce_items_in_cart',
'woocommerce_cart_hash',
);
foreach ( $unsetcookies as $name ) {
if ( isset( $_COOKIE[ $name ] ) ) {
wc_setcookie( $name, 0, time() - HOUR_IN_SECONDS );
unset( $_COOKIE[ $name ] );
}
}
} }
do_action( 'woocommerce_set_cart_cookies', $set ); do_action( 'woocommerce_set_cart_cookies', $set );
} }

View File

@ -111,7 +111,9 @@ class WC_Session_Handler extends WC_Session {
$cookie_value = $this->_customer_id . '||' . $this->_session_expiration . '||' . $this->_session_expiring . '||' . $cookie_hash; $cookie_value = $this->_customer_id . '||' . $this->_session_expiration . '||' . $this->_session_expiring . '||' . $cookie_hash;
$this->_has_cookie = true; $this->_has_cookie = true;
wc_setcookie( $this->_cookie, $cookie_value, $this->_session_expiration, apply_filters( 'wc_session_use_secure_cookie', false ) ); if ( ! isset( $_COOKIE[ $this->_cookie ] ) || $_COOKIE[ $this->_cookie ] !== $cookie_value ) {
wc_setcookie( $this->_cookie, $cookie_value, $this->_session_expiration, apply_filters( 'wc_session_use_secure_cookie', false ) );
}
} }
} }