Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

All notable changes to Warder Cookie Consent are documented here.

## [2.1.0] - 2026-05-30

### Added
- `warder_block_script_until_consent()` — a `script_loader_tag` filter that rewrites known analytics/marketing script tags to `type="text/plain" data-category="<category>"` before consent is given. vanilla-cookieconsent holds these scripts and re-executes them once the user accepts the matching category. Built-in handles: `sourcebuster-js`, `wc-order-attribution`, `wp_slimstat`. Site owners can extend or replace the list via the `warder_blocked_scripts` filter.
- Expanded the `necessary` category cookie defaults to cover the full WordPress and WooCommerce session surface: `cc_cookie` (consent record), `wordpress_logged_in_*`, `wordpress_sec_*`, `wordpress_test_cookie`, `wp-settings-*`, `wp_woocommerce_session_*`, `woocommerce_cart_hash`, `woocommerce_items_in_cart`, `woocommerce_recently_viewed`, `PHPSESSID`.

### Changed
- `sbjs_*` (SourceBuster.js attribution cookies) moved from the `necessary` category to `analytics`, where they belong — they are set by an optional tracking script, not by WordPress core.

## [2.0.2] - 2026-05-30

### Security
Expand Down
47 changes: 46 additions & 1 deletion inc/defaults.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,51 @@ function warder_get_default_options() {
'enabled' => true,
'readonly' => true,
'cookies' => array(
// Consent record — must always be kept.
array(
'name' => '/^sbjs_/',
'name' => 'cc_cookie',
'is_regex' => false,
),
// WordPress login & security.
array(
'name' => '/^wordpress_logged_in_/',
'is_regex' => true,
),
array(
'name' => '/^wordpress_sec_/',
'is_regex' => true,
),
array(
'name' => 'wordpress_test_cookie',
'is_regex' => false,
),
// WordPress admin bar / customizer.
array(
'name' => '/^wp-settings-/',
'is_regex' => true,
),
// WooCommerce session & cart.
array(
'name' => '/^wp_woocommerce_session_/',
'is_regex' => true,
),
array(
'name' => 'woocommerce_cart_hash',
'is_regex' => false,
),
array(
'name' => 'woocommerce_items_in_cart',
'is_regex' => false,
),
array(
'name' => 'woocommerce_recently_viewed',
'is_regex' => false,
),
// PHP session.
array(
'name' => 'PHPSESSID',
'is_regex' => false,
),
),
),
'analytics' => array(
Expand Down Expand Up @@ -66,6 +107,10 @@ function warder_get_default_options() {
'name' => '/^mtm_/',
'is_regex' => true,
),
array(
'name' => '/^sbjs_/',
'is_regex' => true,
),
),
),
),
Expand Down
57 changes: 57 additions & 0 deletions inc/frontend.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,60 @@ function warder_add_preferences_button() {
echo '</button>';
}
add_action( 'wp_footer', 'warder_add_preferences_button' );

/**
* Blocks known analytics/marketing scripts until the matching consent category
* is accepted by rewriting their type to "text/plain" and adding data-category.
*
* Vanilla-cookieconsent holds type="text/plain" scripts and re-executes them
* (as type="text/javascript") once the user accepts the named category. This
* prevents scripts like WooCommerce's SourceBuster (which sets sbjs_* cookies)
* and Slimstat from firing before consent.
*
* Site owners can extend or override the list via the warder_blocked_scripts filter.
*
* @param string $tag The full <script> HTML tag.
* @param string $handle The registered script handle.
* @return string
*/
function warder_block_script_until_consent( $tag, $handle ) {
$options = warder_get_merged_options();
if ( empty( $options['enabled'] ) ) {
return $tag;
}

/**
* Map of WordPress script handles to the consent category that must be
* accepted before the script is allowed to run.
*
* @param array<string,string> $scripts handle => category slug.
*/
$blocked = apply_filters(
'warder_blocked_scripts',
array(
'sourcebuster-js' => 'analytics',
'wc-order-attribution' => 'analytics',
'wp_slimstat' => 'analytics',
)
);

if ( ! isset( $blocked[ $handle ] ) ) {
return $tag;
}

$category = esc_attr( $blocked[ $handle ] );

// Replace an explicit type="text/javascript" if present, otherwise inject.
if ( preg_match( '/\btype=["\']text\/javascript["\']/i', $tag ) ) {
$tag = preg_replace(
'/\btype=["\']text\/javascript["\']/i',
'type="text/plain" data-category="' . $category . '"',
$tag
);
} else {
$tag = str_replace( '<script ', '<script type="text/plain" data-category="' . $category . '" ', $tag );
}

return $tag;
}
add_filter( 'script_loader_tag', 'warder_block_script_until_consent', 10, 2 );
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "imwz-cookie-consent",
"version": "2.0.2",
"version": "2.1.0",
"main": "webpack.config.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
Expand Down
12 changes: 11 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Donate link: https://imagewize.com
Tags: cookie, consent, gdpr, privacy, compliance
Requires at least: 5.0
Tested up to: 7.0
Stable tag: 2.0.2
Stable tag: 2.1.0
Requires PHP: 8.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Expand Down Expand Up @@ -66,6 +66,13 @@ https://github.com/imagewize/warder-cookie-consent

== Changelog ==

= 2.1.0 =
*2026-05-30*

* Added: `warder_block_script_until_consent()` — rewrites known analytics/marketing script tags to `type="text/plain" data-category="<category>"` so they are held by vanilla-cookieconsent until the user accepts the matching category. Covers `sourcebuster-js` (SourceBuster.js), `wc-order-attribution` (WooCommerce order attribution), and `wp_slimstat` (Slimstat Analytics) out of the box. Extend or replace the list with the `warder_blocked_scripts` filter.
* Added: expanded `necessary` category cookie defaults to cover the full WordPress and WooCommerce session surface: `cc_cookie`, `wordpress_logged_in_*`, `wordpress_sec_*`, `wordpress_test_cookie`, `wp-settings-*`, `wp_woocommerce_session_*`, `woocommerce_cart_hash`, `woocommerce_items_in_cart`, `woocommerce_recently_viewed`, `PHPSESSID`. Existing installs are unaffected (defaults only apply to new installs or when the necessary category has no cookies configured).
* Changed: `sbjs_*` (SourceBuster.js attribution cookies) moved from the `necessary` category to `analytics` in the default configuration — they are set by an optional tracking script, not by WordPress core.

= 2.0.2 =
*2026-05-30*

Expand Down Expand Up @@ -194,6 +201,9 @@ https://github.com/imagewize/warder-cookie-consent

== Upgrade Notice ==

= 2.1.0 =
Adds automatic script blocking for SourceBuster.js, WooCommerce order attribution, and Slimstat before consent is given. Necessary cookie defaults now include the full WordPress and WooCommerce session cookie set. The `sbjs_*` pattern moves to analytics — if you manually placed it under necessary, you can remove the duplicate.

= 2.0.2 =
Security and code-quality hardening: stronger input sanitization on settings save, nonce verification before delete actions, isset-guarded validation, and clearer source-code documentation. Recommended for all users.

Expand Down
4 changes: 2 additions & 2 deletions warder-cookie-consent.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/**
* Plugin Name: Warder Cookie Consent
* Description: GDPR-compliant cookie consent banner with category management and floating preferences toggle.
* Version: 2.0.2
* Version: 2.1.0
* Author: Jasper Frumau
* Author URI: https://imagewize.com
* Requires at least: 5.0
Expand All @@ -16,7 +16,7 @@

defined( 'ABSPATH' ) || exit;

define( 'WARDER_VERSION', '2.0.2' );
define( 'WARDER_VERSION', '2.1.0' );
define( 'WARDER_PLUGIN_FILE', __FILE__ );

require_once plugin_dir_path( __FILE__ ) . 'inc/defaults.php';
Expand Down
Loading