Skip to content

Commit b7d8aa9

Browse files
Tsvetan StoychevTsvetan Stoychev
authored andcommitted
Improve consent integration and local setup
1 parent 007932a commit b7d8aa9

37 files changed

Lines changed: 1601 additions & 464 deletions

‎.env.example‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Local Docker development defaults. Copy to .env to override them.
2-
WORDPRESS_PORT=8080
2+
WORDPRESS_PORT=9080
33
WORDPRESS_DB_HOST=db:3306
44
WORDPRESS_DB_NAME=wordpress
55
WORDPRESS_DB_USER=wordpress
66
WORDPRESS_DB_PASSWORD=wordpress
77
WORDPRESS_DB_ROOT_PASSWORD=root
88

9-
WP_URL=http://localhost:8080
9+
WP_URL=http://localhost:9080
1010
WP_TITLE=Basicrum Local
1111
WP_ADMIN_USER=admin
1212
WP_ADMIN_PASSWORD=basicrum-dev-password

‎AGENTS.md‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@ namespace, PSR-4 Composer autoloading, PHP 7.4+, and WordPress 6.0+.
77

88
- `basicrum.php` is the bootstrap; `src/Plugin.php` registers services.
99
- `src/Assets.php` injects Boomerang and config; `PageTypeDetector.php` sets
10-
`p_type`; `Compatibility.php` handles cache-plugin exclusions.
11-
- The standard loader is used without consent mode; consent mode uses the
12-
consent loader and exposes `OPT_IN_BASIC_RUM()` / `OPT_OUT_BASIC_RUM()` for
13-
integration with a site's consent banner.
10+
`p_type`; `Compatibility.php` handles cache-plugin exclusions; `Admin/Privacy.php`
11+
contributes editable WordPress privacy-policy text.
12+
- Immediate loading uses the standard loader. Consent-controlled loading uses
13+
the consent loader and exposes `OPT_IN_BASICRUM_LOADER_WRAPPER()` /
14+
`OPT_OUT_BASICRUM_LOADER_WRAPPER()` for integration with a site's external
15+
consent tool. Load the adapter after the consent loader and call one callback
16+
on every page. Basicrum does not persist consent across page loads.
1417
- Settings use the `basicrum_settings` option. Keep defaults, UI, and
1518
sanitization in sync in `Helpers`, `Admin\Settings\Page`, and
1619
`Admin\Settings\Validate`.

‎README.md‎

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ make package-smoke
3535

3636
`make up` installs Composer dependencies, starts the stack, provisions
3737
WordPress on a new database, and activates Basicrum. The development site is at
38-
`http://localhost:8080/wp-admin/`.
38+
`http://localhost:9080/wp-admin/`.
3939

4040
Default local administrator credentials are `admin` /
4141
`basicrum-dev-password`. Copy `.env.example` to `.env` to override the
@@ -46,6 +46,46 @@ To use an HTTP beacon URL during local testing, enable **HTTP Strictness**
4646
under **Basicrum > Developer Settings**. Keep it disabled on production sites
4747
so HTTP beacon URLs are automatically upgraded to HTTPS.
4848

49+
### Visitor Privacy
50+
51+
Basicrum supports two observable loading policies under **Basicrum > Visitor
52+
Privacy**:
53+
54+
- **Load immediately** loads Boomerang on every eligible page without waiting
55+
for a consent signal.
56+
- **Wait for visitor consent** blocks Boomerang until the site's external
57+
consent tool calls `window.OPT_IN_BASICRUM_LOADER_WRAPPER()` on the current
58+
page. The tool must call `window.OPT_OUT_BASICRUM_LOADER_WRAPPER()` when
59+
consent is rejected, expires, or is withdrawn.
60+
61+
The callbacks are registered when the consent loader reaches its configured
62+
Script Position. The consent integration must run after those callbacks are
63+
available and call one of them on every page. Basicrum does not persist a
64+
separate consent choice across page loads; the external tool is authoritative
65+
on every page. If consent is withdrawn after Boomerang loading starts, reload
66+
the page before granting it again.
67+
68+
Load the adapter after the Basicrum consent loader and use this shape:
69+
70+
```js
71+
function reportBasicrumConsent(allowed) {
72+
const callbackName = allowed
73+
? 'OPT_IN_BASICRUM_LOADER_WRAPPER'
74+
: 'OPT_OUT_BASICRUM_LOADER_WRAPPER';
75+
76+
if (typeof window[callbackName] === 'function') {
77+
window[callbackName]();
78+
}
79+
}
80+
```
81+
82+
A tested Borlabs Cookie v3 adapter is available under
83+
[`examples/integrations/`](examples/integrations/).
84+
85+
Basicrum does not display a consent popup, select a legal basis, or make a site
86+
compliant by itself. The WordPress Privacy Policy Guide includes editable
87+
suggested disclosure text for the configured collector and loading policy.
88+
4989
## Plugin Source
5090

5191
The WordPress plugin itself lives in `plugins/basicrum/`.

‎checklist.md‎

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,33 @@ Acceptance criteria:
1919

2020
## 2. Resolve the unused consent mode setting
2121

22-
- [ ] Define the intended behavior for `explicit`, `implicit`, and `cookie_popup`
22+
- [x] Define the intended behavior for `explicit`, `implicit`, and `cookie_popup`
2323
modes.
24-
- [ ] Decide whether each mode has distinct runtime behavior.
25-
- [ ] Implement the defined behavior, or remove modes that do not represent real
24+
- [x] Decide whether each mode has distinct runtime behavior.
25+
- [x] Implement the defined behavior, or remove modes that do not represent real
2626
behavior and keep a single consent-enabled switch.
27-
- [ ] Keep defaults, settings UI, validation, migrations, documentation, and
27+
- [x] Keep defaults, settings UI, validation, migrations, documentation, and
2828
translations synchronized.
29-
- [ ] Add PHP tests for every supported setting and loader selection path.
29+
- [x] Add PHP tests for every supported setting and loader selection path.
30+
31+
Decision:
32+
33+
- Immediate loading and consent-controlled loading are the only observable
34+
policies. The retired `explicit`, `implicit`, and `cookie_popup` values all
35+
selected the same loader and have been removed without changing existing
36+
sites' consent gate.
37+
- Basicrum supplies an integration gate, not a consent popup, legal-basis
38+
decision, or compliance guarantee.
39+
- In consent-controlled loading, the site's external consent tool is the source
40+
of truth on every page. Its adapter loads after the consent loader and calls
41+
exactly one of the two public callbacks. Basicrum does not persist consent
42+
across page loads.
3043

3144
Acceptance criteria:
3245

33-
- [ ] Every consent option shown to an administrator has observable and documented
46+
- [x] Every consent option shown to an administrator has observable and documented
3447
runtime behavior.
35-
- [ ] No unused consent settings remain in stored options or the UI.
48+
- [x] No unused consent settings remain in stored options or the UI.
3649

3750
## 3. Add JavaScript consent and loader tests
3851

@@ -41,10 +54,8 @@ Acceptance criteria:
4154
- [x] Test that opt-in loads Boomerang exactly once.
4255
- [x] Test that repeated opt-in calls do not load duplicate scripts.
4356
- [x] Test that opt-out disables Boomerang when it is already loaded.
44-
- [x] Test removal of Boomerang cookies during opt-out.
45-
- [x] Test consent cookie behavior on HTTP and HTTPS.
46-
- [x] Test consent cookie behavior for normal hostnames, localhost, and relevant
47-
subdomain cases.
57+
- [x] Test removal of Boomerang RT and BA cookies during opt-out.
58+
- [x] Test measurement-cookie cleanup for the current host and parent domains.
4859
- [x] Run the same behavioral assertions against minified and unminified loaders.
4960
- [x] Add JavaScript tests to CI.
5061

‎docker-compose.yml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ services:
3030
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER:-wordpress}
3131
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD:-wordpress}
3232
ports:
33-
- "${WORDPRESS_PORT:-8080}:80"
33+
- "${WORDPRESS_PORT:-9080}:80"
3434
volumes:
3535
- wordpress_data:/var/www/html
3636
- ./plugins/basicrum:/var/www/html/wp-content/plugins/basicrum
@@ -46,7 +46,7 @@ services:
4646
WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME:-wordpress}
4747
WORDPRESS_DB_USER: ${WORDPRESS_DB_USER:-wordpress}
4848
WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD:-wordpress}
49-
WP_URL: ${WP_URL:-http://localhost:8080}
49+
WP_URL: ${WP_URL:-http://localhost:9080}
5050
WP_TITLE: ${WP_TITLE:-Basicrum Local}
5151
WP_ADMIN_USER: ${WP_ADMIN_USER:-admin}
5252
WP_ADMIN_PASSWORD: ${WP_ADMIN_PASSWORD:-basicrum-dev-password}

‎examples/integrations/README.md‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Consent Tool Integration Examples
2+
3+
These examples are copy-and-paste adapters for webmasters. They are development
4+
and documentation files outside the installable Basicrum plugin.
5+
6+
## Borlabs Cookie v3
7+
8+
The [`borlabs-cookie-v3.js`](borlabs-cookie-v3.js) adapter follows the public
9+
Borlabs Cookie v3 JavaScript contract:
10+
11+
- It reads `BorlabsCookie.Consents.hasConsent('basicrum')`.
12+
- It synchronizes after `borlabs-cookie-after-init`.
13+
- It synchronizes again after `borlabs-cookie-consent-saved`.
14+
- It calls exactly one of Basicrum's opt-in or opt-out callbacks.
15+
16+
In Borlabs Cookie, create and enable a custom service with the service ID
17+
`basicrum`, normally in the Statistics service group. Configure Basicrum to
18+
**Wait for visitor consent**.
19+
20+
Load the Basicrum consent loader before this adapter. Then load the adapter as
21+
unblocked site code on every frontend page. Do not place the adapter itself
22+
behind the Basicrum service consent because it must also report rejection and
23+
withdrawal. Borlabs remains the consent source of truth.
24+
25+
If consent is withdrawn after Boomerang has loaded, Basicrum disables
26+
collection and removes its known measurement cookies. Reload the page before
27+
granting consent again; an already disabled Boomerang instance is not restarted
28+
on the same page.
29+
30+
The Playwright suite runs this exact adapter against
31+
`tests/javascript/fixtures/borlabs-cookie-v3-test-double.js`. The test double
32+
models the documented API and events; it is not the proprietary Borlabs Cookie
33+
plugin.
34+
35+
Official reference:
36+
[Borlabs Cookie JavaScript API v3](https://borlabs.io/kb/javascript-api-v3/).
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
( function( window ) {
2+
'use strict';
3+
4+
var serviceId = 'basicrum';
5+
6+
/**
7+
* Report the current decision to the Basicrum consent loader.
8+
*
9+
* @param {boolean} allowed Whether Borlabs allows the Basicrum service.
10+
* @return {void}
11+
*/
12+
function reportDecision( allowed ) {
13+
var callbackName = allowed
14+
? 'OPT_IN_BASICRUM_LOADER_WRAPPER'
15+
: 'OPT_OUT_BASICRUM_LOADER_WRAPPER';
16+
17+
if ( 'function' === typeof window[ callbackName ] ) {
18+
window[ callbackName ]();
19+
}
20+
}
21+
22+
/**
23+
* Read the authoritative decision from the Borlabs Cookie v3 API.
24+
*
25+
* @return {void}
26+
*/
27+
function synchronizeConsent() {
28+
var consents = window.BorlabsCookie && window.BorlabsCookie.Consents;
29+
30+
if ( ! consents || 'function' !== typeof consents.hasConsent ) {
31+
reportDecision( false );
32+
return;
33+
}
34+
35+
try {
36+
reportDecision( true === consents.hasConsent( serviceId ) );
37+
} catch ( error ) {
38+
// Fail closed until Borlabs can report an authoritative decision.
39+
reportDecision( false );
40+
}
41+
}
42+
43+
window.addEventListener( 'borlabs-cookie-after-init', synchronizeConsent );
44+
window.addEventListener( 'borlabs-cookie-consent-saved', synchronizeConsent );
45+
46+
// Also support snippets added after Borlabs has already initialized.
47+
synchronizeConsent();
48+
}( window ) );

‎plugins/basicrum/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Plugin Name: Basic Rum Wordpress Plugin
33
Plugin URI: https://www.basicrum.com/
44
Description: Budget - Open Source - Real User Monitoring system.
5-
Version: 1.0.1
5+
Version: 1.0.2
66
Author: Tsvetan Stoychev
77
Author URI: https://www.basicrum.com/contact/
88
License: MIT
@@ -114,4 +114,4 @@ Titles are optional, naturally.
114114
Markdown uses email style notation for blockquotes and I've been told:
115115
> Asterisks for *emphasis*. Double it up for **strong**.
116116
117-
`<?php code(); // goes in backticks ?>`
117+
`<?php code(); // goes in backticks ?>`

‎plugins/basicrum/assets/css/admin/settings.css‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,23 @@
2222
color: #d63638;
2323
font-weight: 600;
2424
}
25+
26+
.basicrum-radio-option {
27+
margin-bottom: 12px;
28+
max-width: 760px;
29+
}
30+
31+
.basicrum-radio-option p.description {
32+
margin: 4px 0 0 24px;
33+
}
34+
35+
.basicrum-consent-info {
36+
max-width: 760px;
37+
}
38+
39+
.basicrum-consent-info pre {
40+
background: #fff;
41+
border: 1px solid #ddd;
42+
overflow-x: auto;
43+
padding: 8px;
44+
}

0 commit comments

Comments
 (0)