Initial commit: ATT Consent plugin v1.0.0

Google Consent Mode v2 cookie consent plugin with session attribution
preservation, custom script management, and gtag.js/GTM support.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 05:45:42 +00:00
commit 6bf9f553de
19 changed files with 2726 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
<?php
/**
* Advanced settings tab.
*
* @package ATT_Consent
* @var array $settings Current settings.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
<?php wp_nonce_field( 'att_cc_save_settings' ); ?>
<input type="hidden" name="action" value="att_cc_save_settings">
<input type="hidden" name="att_cc_tab" value="advanced">
<table class="form-table">
<tr>
<th scope="row"><?php esc_html_e( 'URL Passthrough', 'att-consent' ); ?></th>
<td>
<label>
<input type="checkbox" name="url_passthrough" value="1" <?php checked( $settings['url_passthrough'] ); ?>>
<?php esc_html_e( 'Enable URL passthrough', 'att-consent' ); ?>
</label>
<p class="description">
<?php esc_html_e( 'Passes ad click information (gclid, dclid) through URL parameters when navigating between pages, even before consent is granted. Recommended for better conversion attribution.', 'att-consent' ); ?>
</p>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e( 'Ads Data Redaction', 'att-consent' ); ?></th>
<td>
<label>
<input type="checkbox" name="ads_data_redaction" value="1" <?php checked( $settings['ads_data_redaction'] ); ?>>
<?php esc_html_e( 'Enable ads data redaction', 'att-consent' ); ?>
</label>
<p class="description">
<?php esc_html_e( 'When ad_storage is denied, redacts ad click identifiers sent in network requests. Provides additional privacy protection.', 'att-consent' ); ?>
</p>
</td>
</tr>
<tr>
<th scope="row">
<label for="wait_for_update"><?php esc_html_e( 'Wait for Update (ms)', 'att-consent' ); ?></label>
</th>
<td>
<input type="number" name="wait_for_update" id="wait_for_update"
value="<?php echo esc_attr( $settings['wait_for_update'] ); ?>"
class="small-text" min="100" max="10000" step="100">
<p class="description">
<?php esc_html_e( 'How long Google tags wait for a consent update before firing with default (denied) state. 500ms is the recommended default. Only applies on first visit.', 'att-consent' ); ?>
</p>
</td>
</tr>
</table>
<h2><?php esc_html_e( 'Google Consent Mode v2 Signal Reference', 'att-consent' ); ?></h2>
<table class="widefat fixed" style="max-width: 700px;">
<thead>
<tr>
<th><?php esc_html_e( 'Consent Category', 'att-consent' ); ?></th>
<th><?php esc_html_e( 'Google Consent Signals', 'att-consent' ); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><?php esc_html_e( 'Necessary', 'att-consent' ); ?></strong></td>
<td><code>security_storage</code> <?php esc_html_e( '(always granted)', 'att-consent' ); ?></td>
</tr>
<tr>
<td><strong><?php esc_html_e( 'Functional', 'att-consent' ); ?></strong></td>
<td><code>functionality_storage</code>, <code>personalization_storage</code></td>
</tr>
<tr>
<td><strong><?php esc_html_e( 'Analytics', 'att-consent' ); ?></strong></td>
<td><code>analytics_storage</code></td>
</tr>
<tr>
<td><strong><?php esc_html_e( 'Marketing', 'att-consent' ); ?></strong></td>
<td><code>ad_storage</code>, <code>ad_user_data</code>, <code>ad_personalization</code></td>
</tr>
</tbody>
</table>
<?php submit_button(); ?>
</form>

View File

@@ -0,0 +1,118 @@
<?php
/**
* Appearance settings tab.
*
* @package ATT_Consent
* @var array $settings Current settings.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
<?php wp_nonce_field( 'att_cc_save_settings' ); ?>
<input type="hidden" name="action" value="att_cc_save_settings">
<input type="hidden" name="att_cc_tab" value="appearance">
<h2><?php esc_html_e( 'Banner Text', 'att-consent' ); ?></h2>
<table class="form-table">
<tr>
<th scope="row">
<label for="banner_heading"><?php esc_html_e( 'Heading', 'att-consent' ); ?></label>
</th>
<td>
<input type="text" name="banner_heading" id="banner_heading"
value="<?php echo esc_attr( $settings['banner_heading'] ); ?>"
class="large-text">
</td>
</tr>
<tr>
<th scope="row">
<label for="banner_message"><?php esc_html_e( 'Message', 'att-consent' ); ?></label>
</th>
<td>
<textarea name="banner_message" id="banner_message" rows="4"
class="large-text"><?php echo esc_textarea( $settings['banner_message'] ); ?></textarea>
<p class="description"><?php esc_html_e( 'Basic HTML is allowed (links, bold, italic).', 'att-consent' ); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="btn_accept_label"><?php esc_html_e( 'Accept Button Label', 'att-consent' ); ?></label>
</th>
<td>
<input type="text" name="btn_accept_label" id="btn_accept_label"
value="<?php echo esc_attr( $settings['btn_accept_label'] ); ?>" class="regular-text">
</td>
</tr>
<tr>
<th scope="row">
<label for="btn_reject_label"><?php esc_html_e( 'Reject Button Label', 'att-consent' ); ?></label>
</th>
<td>
<input type="text" name="btn_reject_label" id="btn_reject_label"
value="<?php echo esc_attr( $settings['btn_reject_label'] ); ?>" class="regular-text">
</td>
</tr>
<tr>
<th scope="row">
<label for="btn_preferences_label"><?php esc_html_e( 'Preferences Button Label', 'att-consent' ); ?></label>
</th>
<td>
<input type="text" name="btn_preferences_label" id="btn_preferences_label"
value="<?php echo esc_attr( $settings['btn_preferences_label'] ); ?>" class="regular-text">
</td>
</tr>
<tr>
<th scope="row">
<label for="btn_save_label"><?php esc_html_e( 'Save Preferences Label', 'att-consent' ); ?></label>
</th>
<td>
<input type="text" name="btn_save_label" id="btn_save_label"
value="<?php echo esc_attr( $settings['btn_save_label'] ); ?>" class="regular-text">
</td>
</tr>
</table>
<h2><?php esc_html_e( 'Colours', 'att-consent' ); ?></h2>
<table class="form-table">
<tr>
<th scope="row"><?php esc_html_e( 'Banner Background', 'att-consent' ); ?></th>
<td><input type="text" name="banner_bg_color" value="<?php echo esc_attr( $settings['banner_bg_color'] ); ?>" class="att-cc-color-picker"></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e( 'Banner Text', 'att-consent' ); ?></th>
<td><input type="text" name="banner_text_color" value="<?php echo esc_attr( $settings['banner_text_color'] ); ?>" class="att-cc-color-picker"></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e( 'Accept Button Background', 'att-consent' ); ?></th>
<td><input type="text" name="btn_accept_bg" value="<?php echo esc_attr( $settings['btn_accept_bg'] ); ?>" class="att-cc-color-picker"></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e( 'Accept Button Text', 'att-consent' ); ?></th>
<td><input type="text" name="btn_accept_text" value="<?php echo esc_attr( $settings['btn_accept_text'] ); ?>" class="att-cc-color-picker"></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e( 'Reject Button Background', 'att-consent' ); ?></th>
<td><input type="text" name="btn_reject_bg" value="<?php echo esc_attr( $settings['btn_reject_bg'] ); ?>" class="att-cc-color-picker"></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e( 'Reject Button Text', 'att-consent' ); ?></th>
<td><input type="text" name="btn_reject_text" value="<?php echo esc_attr( $settings['btn_reject_text'] ); ?>" class="att-cc-color-picker"></td>
</tr>
<tr>
<th scope="row"><?php esc_html_e( 'Preferences Button Background', 'att-consent' ); ?></th>
<td>
<input type="text" name="btn_preferences_bg" value="<?php echo esc_attr( $settings['btn_preferences_bg'] ); ?>" class="att-cc-color-picker">
<p class="description"><?php esc_html_e( 'Use "transparent" for an outline-style button.', 'att-consent' ); ?></p>
</td>
</tr>
<tr>
<th scope="row"><?php esc_html_e( 'Preferences Button Text', 'att-consent' ); ?></th>
<td><input type="text" name="btn_preferences_text" value="<?php echo esc_attr( $settings['btn_preferences_text'] ); ?>" class="att-cc-color-picker"></td>
</tr>
</table>
<?php submit_button(); ?>
</form>

View File

@@ -0,0 +1,64 @@
<?php
/**
* Categories settings tab.
*
* @package ATT_Consent
* @var array $settings Current settings.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
<?php wp_nonce_field( 'att_cc_save_settings' ); ?>
<input type="hidden" name="action" value="att_cc_save_settings">
<input type="hidden" name="att_cc_tab" value="categories">
<p><?php esc_html_e( 'Customise the descriptions shown to visitors for each cookie category in the preferences modal.', 'att-consent' ); ?></p>
<table class="form-table">
<tr>
<th scope="row">
<label for="cat_necessary_desc"><?php esc_html_e( 'Necessary', 'att-consent' ); ?></label>
</th>
<td>
<textarea name="cat_necessary_desc" id="cat_necessary_desc" rows="3"
class="large-text"><?php echo esc_textarea( $settings['cat_necessary_desc'] ); ?></textarea>
<p class="description"><?php esc_html_e( 'Always enabled. Maps to: security_storage.', 'att-consent' ); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="cat_functional_desc"><?php esc_html_e( 'Functional', 'att-consent' ); ?></label>
</th>
<td>
<textarea name="cat_functional_desc" id="cat_functional_desc" rows="3"
class="large-text"><?php echo esc_textarea( $settings['cat_functional_desc'] ); ?></textarea>
<p class="description"><?php esc_html_e( 'Maps to: functionality_storage, personalization_storage.', 'att-consent' ); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="cat_analytics_desc"><?php esc_html_e( 'Analytics', 'att-consent' ); ?></label>
</th>
<td>
<textarea name="cat_analytics_desc" id="cat_analytics_desc" rows="3"
class="large-text"><?php echo esc_textarea( $settings['cat_analytics_desc'] ); ?></textarea>
<p class="description"><?php esc_html_e( 'Maps to: analytics_storage.', 'att-consent' ); ?></p>
</td>
</tr>
<tr>
<th scope="row">
<label for="cat_marketing_desc"><?php esc_html_e( 'Marketing', 'att-consent' ); ?></label>
</th>
<td>
<textarea name="cat_marketing_desc" id="cat_marketing_desc" rows="3"
class="large-text"><?php echo esc_textarea( $settings['cat_marketing_desc'] ); ?></textarea>
<p class="description"><?php esc_html_e( 'Maps to: ad_storage, ad_user_data, ad_personalization.', 'att-consent' ); ?></p>
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>

View File

@@ -0,0 +1,120 @@
<?php
/**
* General settings tab.
*
* @package ATT_Consent
* @var array $settings Current settings.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
?>
<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
<?php wp_nonce_field( 'att_cc_save_settings' ); ?>
<input type="hidden" name="action" value="att_cc_save_settings">
<input type="hidden" name="att_cc_tab" value="general">
<table class="form-table">
<tr>
<th scope="row">
<label for="tracking_mode"><?php esc_html_e( 'Tracking Mode', 'att-consent' ); ?></label>
</th>
<td>
<select name="tracking_mode" id="tracking_mode">
<option value="gtag" <?php selected( $settings['tracking_mode'], 'gtag' ); ?>>
<?php esc_html_e( 'Google Analytics (gtag.js)', 'att-consent' ); ?>
</option>
<option value="gtm" <?php selected( $settings['tracking_mode'], 'gtm' ); ?>>
<?php esc_html_e( 'Google Tag Manager', 'att-consent' ); ?>
</option>
</select>
<p class="description">
<?php esc_html_e( 'Choose whether to inject gtag.js directly or use a GTM container.', 'att-consent' ); ?>
</p>
</td>
</tr>
<tr class="att-cc-gtag-row">
<th scope="row">
<label for="ga4_measurement_id"><?php esc_html_e( 'GA4 Measurement ID', 'att-consent' ); ?></label>
</th>
<td>
<input type="text" name="ga4_measurement_id" id="ga4_measurement_id"
value="<?php echo esc_attr( $settings['ga4_measurement_id'] ); ?>"
class="regular-text" placeholder="G-XXXXXXXXXX">
<p class="description">
<?php esc_html_e( 'Your GA4 Measurement ID (starts with G-).', 'att-consent' ); ?>
</p>
</td>
</tr>
<tr class="att-cc-gtm-row">
<th scope="row">
<label for="gtm_container_id"><?php esc_html_e( 'GTM Container ID', 'att-consent' ); ?></label>
</th>
<td>
<input type="text" name="gtm_container_id" id="gtm_container_id"
value="<?php echo esc_attr( $settings['gtm_container_id'] ); ?>"
class="regular-text" placeholder="GTM-XXXXXXX">
<p class="description">
<?php esc_html_e( 'Your Google Tag Manager Container ID (starts with GTM-).', 'att-consent' ); ?>
</p>
</td>
</tr>
<tr>
<th scope="row">
<label for="consent_mode"><?php esc_html_e( 'Consent Mode', 'att-consent' ); ?></label>
</th>
<td>
<select name="consent_mode" id="consent_mode">
<option value="advanced" <?php selected( $settings['consent_mode'], 'advanced' ); ?>>
<?php esc_html_e( 'Advanced (recommended)', 'att-consent' ); ?>
</option>
<option value="basic" <?php selected( $settings['consent_mode'], 'basic' ); ?>>
<?php esc_html_e( 'Basic', 'att-consent' ); ?>
</option>
</select>
<p class="description">
<?php esc_html_e( 'Advanced: Tags load before consent, sending cookieless pings for better modelling. Basic: No tags load until consent is given.', 'att-consent' ); ?>
</p>
</td>
</tr>
<tr>
<th scope="row">
<label for="banner_position"><?php esc_html_e( 'Banner Position', 'att-consent' ); ?></label>
</th>
<td>
<select name="banner_position" id="banner_position">
<option value="bottom" <?php selected( $settings['banner_position'], 'bottom' ); ?>>
<?php esc_html_e( 'Bottom Bar', 'att-consent' ); ?>
</option>
<option value="top" <?php selected( $settings['banner_position'], 'top' ); ?>>
<?php esc_html_e( 'Top Bar', 'att-consent' ); ?>
</option>
<option value="center" <?php selected( $settings['banner_position'], 'center' ); ?>>
<?php esc_html_e( 'Centre Modal', 'att-consent' ); ?>
</option>
</select>
</td>
</tr>
<tr>
<th scope="row">
<label for="consent_expiry"><?php esc_html_e( 'Consent Expiry (days)', 'att-consent' ); ?></label>
</th>
<td>
<input type="number" name="consent_expiry" id="consent_expiry"
value="<?php echo esc_attr( $settings['consent_expiry'] ); ?>"
class="small-text" min="1" max="730">
<p class="description">
<?php esc_html_e( 'How long the consent cookie lasts before the user is asked again.', 'att-consent' ); ?>
</p>
</td>
</tr>
</table>
<?php submit_button(); ?>
</form>

View File

@@ -0,0 +1,133 @@
<?php
/**
* Custom Scripts tab.
*
* @package ATT_Consent
* @var array $settings Current settings.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$scripts = ATT_Consent_Scripts_Manager::get_all_scripts();
?>
<div class="att-cc-scripts-wrap">
<h2>
<?php esc_html_e( 'Custom Scripts', 'att-consent' ); ?>
<button type="button" class="page-title-action" id="att-cc-add-script">
<?php esc_html_e( 'Add New Script', 'att-consent' ); ?>
</button>
</h2>
<p><?php esc_html_e( 'Add custom JavaScript snippets that will only execute after the visitor consents to the relevant category. This is useful for conversion pixels, chat widgets, and other third-party scripts.', 'att-consent' ); ?></p>
<!-- Scripts list -->
<table class="wp-list-table widefat fixed striped" id="att-cc-scripts-table">
<thead>
<tr>
<th class="column-name"><?php esc_html_e( 'Name', 'att-consent' ); ?></th>
<th class="column-category"><?php esc_html_e( 'Category', 'att-consent' ); ?></th>
<th class="column-placement"><?php esc_html_e( 'Placement', 'att-consent' ); ?></th>
<th class="column-priority"><?php esc_html_e( 'Priority', 'att-consent' ); ?></th>
<th class="column-status"><?php esc_html_e( 'Status', 'att-consent' ); ?></th>
<th class="column-actions"><?php esc_html_e( 'Actions', 'att-consent' ); ?></th>
</tr>
</thead>
<tbody id="att-cc-scripts-list">
<?php if ( empty( $scripts ) ) : ?>
<tr class="att-cc-no-scripts">
<td colspan="6"><?php esc_html_e( 'No custom scripts added yet.', 'att-consent' ); ?></td>
</tr>
<?php else : ?>
<?php foreach ( $scripts as $script ) : ?>
<tr data-id="<?php echo esc_attr( $script['id'] ); ?>">
<td class="column-name"><?php echo esc_html( $script['name'] ); ?></td>
<td class="column-category"><span class="att-cc-badge att-cc-badge--<?php echo esc_attr( $script['category'] ); ?>"><?php echo esc_html( ucfirst( $script['category'] ) ); ?></span></td>
<td class="column-placement"><?php echo esc_html( ucfirst( $script['placement'] ) ); ?></td>
<td class="column-priority"><?php echo esc_html( $script['priority'] ); ?></td>
<td class="column-status">
<span class="att-cc-status att-cc-status--<?php echo esc_attr( $script['status'] ); ?>">
<?php echo esc_html( ucfirst( $script['status'] ) ); ?>
</span>
</td>
<td class="column-actions">
<button type="button" class="button button-small att-cc-edit-script" data-id="<?php echo esc_attr( $script['id'] ); ?>">
<?php esc_html_e( 'Edit', 'att-consent' ); ?>
</button>
<button type="button" class="button button-small button-link-delete att-cc-delete-script" data-id="<?php echo esc_attr( $script['id'] ); ?>">
<?php esc_html_e( 'Delete', 'att-consent' ); ?>
</button>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
<!-- Add/Edit modal -->
<div id="att-cc-script-modal" class="att-cc-modal" style="display:none;">
<div class="att-cc-modal__overlay"></div>
<div class="att-cc-modal__content">
<h2 id="att-cc-script-modal-title"><?php esc_html_e( 'Add Script', 'att-consent' ); ?></h2>
<form id="att-cc-script-form">
<input type="hidden" name="script_id" id="att-cc-script-id" value="">
<table class="form-table">
<tr>
<th><label for="att-cc-script-name"><?php esc_html_e( 'Name', 'att-consent' ); ?></label></th>
<td><input type="text" id="att-cc-script-name" name="name" class="regular-text" required></td>
</tr>
<tr>
<th><label for="att-cc-script-category"><?php esc_html_e( 'Category', 'att-consent' ); ?></label></th>
<td>
<select id="att-cc-script-category" name="category">
<option value="functional"><?php esc_html_e( 'Functional', 'att-consent' ); ?></option>
<option value="analytics" selected><?php esc_html_e( 'Analytics', 'att-consent' ); ?></option>
<option value="marketing"><?php esc_html_e( 'Marketing', 'att-consent' ); ?></option>
</select>
<p class="description"><?php esc_html_e( 'The script will only execute after the visitor consents to this category.', 'att-consent' ); ?></p>
</td>
</tr>
<tr>
<th><label for="att-cc-script-placement"><?php esc_html_e( 'Placement', 'att-consent' ); ?></label></th>
<td>
<select id="att-cc-script-placement" name="placement">
<option value="head"><?php esc_html_e( 'Head', 'att-consent' ); ?></option>
<option value="footer"><?php esc_html_e( 'Footer', 'att-consent' ); ?></option>
</select>
</td>
</tr>
<tr>
<th><label for="att-cc-script-priority"><?php esc_html_e( 'Priority', 'att-consent' ); ?></label></th>
<td>
<input type="number" id="att-cc-script-priority" name="priority" value="10" min="1" max="100" class="small-text">
<p class="description"><?php esc_html_e( 'Lower numbers execute first.', 'att-consent' ); ?></p>
</td>
</tr>
<tr>
<th><label for="att-cc-script-status"><?php esc_html_e( 'Status', 'att-consent' ); ?></label></th>
<td>
<select id="att-cc-script-status" name="status">
<option value="active"><?php esc_html_e( 'Active', 'att-consent' ); ?></option>
<option value="inactive"><?php esc_html_e( 'Inactive', 'att-consent' ); ?></option>
</select>
</td>
</tr>
<tr>
<th><label for="att-cc-script-snippet"><?php esc_html_e( 'Script Code', 'att-consent' ); ?></label></th>
<td>
<textarea id="att-cc-script-snippet" name="snippet" rows="10" class="large-text code" placeholder="<script>&#10;// Your code here&#10;</script>"></textarea>
<p class="description"><?php esc_html_e( 'Include the full script tag(s). This code will be injected into the page after consent is given for the selected category.', 'att-consent' ); ?></p>
</td>
</tr>
</table>
<div class="att-cc-modal__actions">
<button type="submit" class="button button-primary"><?php esc_html_e( 'Save Script', 'att-consent' ); ?></button>
<button type="button" class="button att-cc-close-modal"><?php esc_html_e( 'Cancel', 'att-consent' ); ?></button>
</div>
</form>
</div>
</div>
</div>