Allow filtering of cookie flags, which enables setting of samesite (#33219)

Allow filtering of cookie flags, which enables setting of `samesite`.

* Break out filter so the same filter can be used for any version of PHP.
* Add docblocks and other linting fixes; add changelog.

Props: David Anderson <DavidAnderson684@users.noreply.github.com>
This commit is contained in:
Matt Harrison 2022-05-26 19:40:16 -04:00 committed by GitHub
parent 8edc32c7fb
commit 3ac62945c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 2 deletions

View File

@ -0,0 +1,4 @@
Significance: patch
Type: tweak
Introduce new hook `woocommerce_set_cookie_options` to exercise more control over cookie options.

View File

@ -1048,12 +1048,63 @@ function wc_print_js() {
* @param bool $httponly Whether the cookie is only accessible over HTTP, not scripting languages like JavaScript. @since 3.6.0.
*/
function wc_setcookie( $name, $value, $expire = 0, $secure = false, $httponly = false ) {
if ( ! apply_filters( 'woocommerce_set_cookie_enabled', true, $name ,$value, $expire, $secure ) ) {
/**
* Controls whether the cookie should be set via wc_setcookie().
*
* @since 6.3.0
*
* @param bool $set_cookie_enabled If wc_setcookie() should set the cookie.
* @param string $name Cookie name.
* @param string $value Cookie value.
* @param integer $expire When the cookie should expire.
* @param bool $secure If the cookie should only be served over HTTPS.
*/
if ( ! apply_filters( 'woocommerce_set_cookie_enabled', true, $name, $value, $expire, $secure ) ) {
return;
}
if ( ! headers_sent() ) {
setcookie( $name, $value, $expire, COOKIEPATH ? COOKIEPATH : '/', COOKIE_DOMAIN, $secure, apply_filters( 'woocommerce_cookie_httponly', $httponly, $name, $value, $expire, $secure ) );
/**
* Controls the options to be specified when setting the cookie.
*
* @see https://www.php.net/manual/en/function.setcookie.php
* @since 6.7.0
*
* @param array $cookie_options Cookie options.
* @param string $name Cookie name.
* @param string $value Cookie value.
*/
$options = apply_filters(
'woocommerce_set_cookie_options',
array(
'expires' => $expire,
'secure' => $secure,
'path' => COOKIEPATH ? COOKIEPATH : '/',
'domain' => COOKIE_DOMAIN,
/**
* Controls whether the cookie should only be accessible via the HTTP protocol, or if it should also be
* accessible to Javascript.
*
* @see https://www.php.net/manual/en/function.setcookie.php
* @since 3.3.0
*
* @param bool $httponly If the cookie should only be accessible via the HTTP protocol.
* @param string $name Cookie name.
* @param string $value Cookie value.
* @param int $expire When the cookie should expire.
* @param bool $secure If the cookie should only be served over HTTPS.
*/
'httponly' => apply_filters( 'woocommerce_cookie_httponly', $httponly, $name, $value, $expire, $secure ),
),
$name,
$value
);
if ( version_compare( PHP_VERSION, '7.3.0', '>=' ) ) {
setcookie( $name, $value, $options );
} else {
setcookie( $name, $value, $options['expires'], $options['path'], $options['domain'], $options['secure'], $options['httponly'] );
}
} elseif ( Constants::is_true( 'WP_DEBUG' ) ) {
headers_sent( $file, $line );
trigger_error( "{$name} cookie cannot be set - headers already sent by {$file} on line {$line}", E_USER_NOTICE ); // @codingStandardsIgnoreLine