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>
305 lines
9.0 KiB
PHP
305 lines
9.0 KiB
PHP
<?php
|
|
/**
|
|
* Admin settings handler.
|
|
*
|
|
* @package ATT_Consent
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class ATT_Consent_Admin {
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function __construct() {
|
|
add_action( 'admin_menu', array( $this, 'add_menu_page' ) );
|
|
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
|
|
add_action( 'admin_post_att_cc_save_settings', array( $this, 'save_settings' ) );
|
|
add_action( 'wp_ajax_att_cc_save_script', array( $this, 'ajax_save_script' ) );
|
|
add_action( 'wp_ajax_att_cc_delete_script', array( $this, 'ajax_delete_script' ) );
|
|
add_action( 'wp_ajax_att_cc_get_script', array( $this, 'ajax_get_script' ) );
|
|
add_filter( 'plugin_action_links_' . ATT_CC_PLUGIN_BASENAME, array( $this, 'add_settings_link' ) );
|
|
}
|
|
|
|
/**
|
|
* Add settings link to plugins page.
|
|
*
|
|
* @param array $links Existing links.
|
|
* @return array
|
|
*/
|
|
public function add_settings_link( $links ) {
|
|
$settings_link = sprintf(
|
|
'<a href="%s">%s</a>',
|
|
esc_url( admin_url( 'admin.php?page=att-consent' ) ),
|
|
esc_html__( 'Settings', 'att-consent' )
|
|
);
|
|
array_unshift( $links, $settings_link );
|
|
return $links;
|
|
}
|
|
|
|
/**
|
|
* Register the admin menu page.
|
|
*/
|
|
public function add_menu_page() {
|
|
add_menu_page(
|
|
__( 'ATT Consent', 'att-consent' ),
|
|
__( 'Cookie Consent', 'att-consent' ),
|
|
'manage_options',
|
|
'att-consent',
|
|
array( $this, 'render_settings_page' ),
|
|
'dashicons-shield',
|
|
81
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Enqueue admin assets.
|
|
*
|
|
* @param string $hook_suffix The current admin page hook.
|
|
*/
|
|
public function enqueue_assets( $hook_suffix ) {
|
|
if ( 'toplevel_page_att-consent' !== $hook_suffix ) {
|
|
return;
|
|
}
|
|
|
|
wp_enqueue_style( 'wp-color-picker' );
|
|
wp_enqueue_style(
|
|
'att-consent-admin',
|
|
ATT_CC_PLUGIN_URL . 'admin/css/admin.css',
|
|
array(),
|
|
ATT_CC_VERSION
|
|
);
|
|
|
|
wp_enqueue_script( 'wp-color-picker' );
|
|
wp_enqueue_script(
|
|
'att-consent-admin',
|
|
ATT_CC_PLUGIN_URL . 'admin/js/admin.js',
|
|
array( 'jquery', 'wp-color-picker' ),
|
|
ATT_CC_VERSION,
|
|
true
|
|
);
|
|
|
|
wp_localize_script( 'att-consent-admin', 'attCCAdmin', array(
|
|
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
|
'nonce' => wp_create_nonce( 'att_cc_admin' ),
|
|
'strings' => array(
|
|
'confirmDelete' => __( 'Are you sure you want to delete this script?', 'att-consent' ),
|
|
'saved' => __( 'Script saved.', 'att-consent' ),
|
|
'deleted' => __( 'Script deleted.', 'att-consent' ),
|
|
'error' => __( 'An error occurred. Please try again.', 'att-consent' ),
|
|
),
|
|
) );
|
|
}
|
|
|
|
/**
|
|
* Render the settings page.
|
|
*/
|
|
public function render_settings_page() {
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
return;
|
|
}
|
|
|
|
$active_tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'general'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
$tabs = array(
|
|
'general' => __( 'General', 'att-consent' ),
|
|
'appearance' => __( 'Appearance', 'att-consent' ),
|
|
'categories' => __( 'Categories', 'att-consent' ),
|
|
'scripts' => __( 'Custom Scripts', 'att-consent' ),
|
|
'advanced' => __( 'Advanced', 'att-consent' ),
|
|
);
|
|
|
|
$settings = ATT_Consent::get_settings();
|
|
?>
|
|
<div class="wrap att-cc-admin-wrap">
|
|
<h1><?php esc_html_e( 'ATT Consent Settings', 'att-consent' ); ?></h1>
|
|
|
|
<?php
|
|
if ( isset( $_GET['saved'] ) && '1' === $_GET['saved'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Settings saved.', 'att-consent' ) . '</p></div>';
|
|
}
|
|
?>
|
|
|
|
<nav class="nav-tab-wrapper">
|
|
<?php foreach ( $tabs as $tab_key => $tab_label ) : ?>
|
|
<a href="<?php echo esc_url( admin_url( 'admin.php?page=att-consent&tab=' . $tab_key ) ); ?>"
|
|
class="nav-tab <?php echo $active_tab === $tab_key ? 'nav-tab-active' : ''; ?>">
|
|
<?php echo esc_html( $tab_label ); ?>
|
|
</a>
|
|
<?php endforeach; ?>
|
|
</nav>
|
|
|
|
<div class="att-cc-tab-content">
|
|
<?php
|
|
$view_file = ATT_CC_PLUGIN_DIR . 'admin/views/settings-' . $active_tab . '.php';
|
|
if ( file_exists( $view_file ) ) {
|
|
include $view_file;
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Save settings from any tab.
|
|
*/
|
|
public function save_settings() {
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
wp_die( esc_html__( 'Unauthorized.', 'att-consent' ) );
|
|
}
|
|
|
|
check_admin_referer( 'att_cc_save_settings' );
|
|
|
|
$tab = sanitize_key( $_POST['att_cc_tab'] ?? 'general' );
|
|
$settings = ATT_Consent::get_settings();
|
|
|
|
switch ( $tab ) {
|
|
case 'general':
|
|
$settings['tracking_mode'] = in_array( $_POST['tracking_mode'] ?? '', array( 'gtag', 'gtm' ), true ) ? $_POST['tracking_mode'] : 'gtag';
|
|
$settings['ga4_measurement_id'] = sanitize_text_field( $_POST['ga4_measurement_id'] ?? '' );
|
|
$settings['gtm_container_id'] = sanitize_text_field( $_POST['gtm_container_id'] ?? '' );
|
|
$settings['consent_mode'] = in_array( $_POST['consent_mode'] ?? '', array( 'advanced', 'basic' ), true ) ? $_POST['consent_mode'] : 'advanced';
|
|
$settings['banner_position'] = in_array( $_POST['banner_position'] ?? '', array( 'bottom', 'top', 'center' ), true ) ? $_POST['banner_position'] : 'bottom';
|
|
$settings['consent_expiry'] = absint( $_POST['consent_expiry'] ?? 365 );
|
|
break;
|
|
|
|
case 'appearance':
|
|
$color_fields = array(
|
|
'banner_bg_color', 'banner_text_color',
|
|
'btn_accept_bg', 'btn_accept_text',
|
|
'btn_reject_bg', 'btn_reject_text',
|
|
'btn_preferences_bg', 'btn_preferences_text',
|
|
);
|
|
foreach ( $color_fields as $field ) {
|
|
$value = $_POST[ $field ] ?? '';
|
|
if ( 'transparent' === $value ) {
|
|
$settings[ $field ] = 'transparent';
|
|
} else {
|
|
$settings[ $field ] = sanitize_hex_color( $value ) ?: $settings[ $field ];
|
|
}
|
|
}
|
|
|
|
$text_fields = array(
|
|
'banner_heading', 'banner_message',
|
|
'btn_accept_label', 'btn_reject_label',
|
|
'btn_preferences_label', 'btn_save_label',
|
|
);
|
|
foreach ( $text_fields as $field ) {
|
|
if ( 'banner_message' === $field ) {
|
|
$settings[ $field ] = wp_kses_post( $_POST[ $field ] ?? '' );
|
|
} else {
|
|
$settings[ $field ] = sanitize_text_field( $_POST[ $field ] ?? '' );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 'categories':
|
|
$cat_fields = array(
|
|
'cat_necessary_desc', 'cat_functional_desc',
|
|
'cat_analytics_desc', 'cat_marketing_desc',
|
|
);
|
|
foreach ( $cat_fields as $field ) {
|
|
$settings[ $field ] = wp_kses_post( $_POST[ $field ] ?? '' );
|
|
}
|
|
break;
|
|
|
|
case 'advanced':
|
|
$settings['url_passthrough'] = ! empty( $_POST['url_passthrough'] );
|
|
$settings['ads_data_redaction'] = ! empty( $_POST['ads_data_redaction'] );
|
|
$settings['wait_for_update'] = absint( $_POST['wait_for_update'] ?? 500 );
|
|
if ( $settings['wait_for_update'] < 100 ) {
|
|
$settings['wait_for_update'] = 100;
|
|
}
|
|
if ( $settings['wait_for_update'] > 10000 ) {
|
|
$settings['wait_for_update'] = 10000;
|
|
}
|
|
break;
|
|
}
|
|
|
|
$settings = apply_filters( 'att_consent_settings_save', $settings, $tab );
|
|
update_option( 'att_consent_settings', $settings );
|
|
|
|
wp_safe_redirect( admin_url( 'admin.php?page=att-consent&tab=' . $tab . '&saved=1' ) );
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* AJAX: Save a custom script.
|
|
*/
|
|
public function ajax_save_script() {
|
|
check_ajax_referer( 'att_cc_admin', 'nonce' );
|
|
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
wp_send_json_error( 'Unauthorized' );
|
|
}
|
|
|
|
$data = array(
|
|
'id' => absint( $_POST['script_id'] ?? 0 ) ?: null,
|
|
'name' => $_POST['name'] ?? '',
|
|
'snippet' => $_POST['snippet'] ?? '',
|
|
'category' => $_POST['category'] ?? 'analytics',
|
|
'placement' => $_POST['placement'] ?? 'head',
|
|
'status' => $_POST['status'] ?? 'active',
|
|
'priority' => $_POST['priority'] ?? 10,
|
|
);
|
|
|
|
$result = ATT_Consent_Scripts_Manager::save_script( $data );
|
|
|
|
if ( false !== $result ) {
|
|
wp_send_json_success( array(
|
|
'id' => $result,
|
|
'scripts' => ATT_Consent_Scripts_Manager::get_all_scripts(),
|
|
) );
|
|
} else {
|
|
wp_send_json_error( 'Failed to save script.' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AJAX: Delete a custom script.
|
|
*/
|
|
public function ajax_delete_script() {
|
|
check_ajax_referer( 'att_cc_admin', 'nonce' );
|
|
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
wp_send_json_error( 'Unauthorized' );
|
|
}
|
|
|
|
$id = absint( $_POST['script_id'] ?? 0 );
|
|
if ( ! $id ) {
|
|
wp_send_json_error( 'Invalid ID.' );
|
|
}
|
|
|
|
if ( ATT_Consent_Scripts_Manager::delete_script( $id ) ) {
|
|
wp_send_json_success( array(
|
|
'scripts' => ATT_Consent_Scripts_Manager::get_all_scripts(),
|
|
) );
|
|
} else {
|
|
wp_send_json_error( 'Failed to delete script.' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* AJAX: Get a single script for editing.
|
|
*/
|
|
public function ajax_get_script() {
|
|
check_ajax_referer( 'att_cc_admin', 'nonce' );
|
|
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
wp_send_json_error( 'Unauthorized' );
|
|
}
|
|
|
|
$id = absint( $_POST['script_id'] ?? 0 );
|
|
$script = ATT_Consent_Scripts_Manager::get_script( $id );
|
|
|
|
if ( $script ) {
|
|
wp_send_json_success( $script );
|
|
} else {
|
|
wp_send_json_error( 'Script not found.' );
|
|
}
|
|
}
|
|
}
|