config = $config; $this->validator = new Validator($config); $this->output_manager = new Output_Manager($config); $this->init_hooks(); } private function current_user_can_manage_codes() { return current_user_can('manage_options') || current_user_can('wptag_manage_codes'); } private function current_user_can_manage_services() { return current_user_can('manage_options') || current_user_can('wptag_manage_services'); } private function init_hooks() { add_filter('wptag_should_output_codes', '__return_false', 999); add_action('admin_menu', array($this, 'add_admin_menu')); add_action('admin_init', array($this, 'admin_init')); add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets')); add_action('wp_ajax_wptag_validate_code', array($this, 'ajax_validate_code')); add_action('wp_ajax_wptag_preview_code', array($this, 'ajax_preview_code')); add_action('wp_ajax_wptag_export_settings', array($this, 'ajax_export_settings')); add_action('wp_ajax_wptag_import_settings', array($this, 'ajax_import_settings')); add_action('wp_ajax_wptag_reset_settings', array($this, 'ajax_reset_settings')); add_filter('plugin_action_links_' . plugin_basename(WPTAG_PLUGIN_FILE), array($this, 'add_action_links')); add_filter('plugin_row_meta', array($this, 'add_row_meta'), 10, 2); add_action('init', array($this, 'add_custom_capabilities')); } public function add_custom_capabilities() { $role = get_role('administrator'); if ($role) { $role->add_cap('wptag_manage_codes'); $role->add_cap('wptag_manage_services'); } $role = get_role('editor'); if ($role) { $role->add_cap('wptag_manage_codes'); } } public function add_admin_menu() { $main_hook = add_options_page( 'WPTag Settings', 'WPTag', 'manage_options', 'wptag-settings', array($this, 'display_admin_page') ); add_action('load-' . $main_hook, array($this, 'handle_form_submission')); } public function admin_init() { register_setting( 'wptag_settings_group', 'wptag_settings', array( 'sanitize_callback' => array($this, 'sanitize_settings'), 'default' => array() ) ); register_setting( 'wptag_services_group', 'wptag_services', array( 'sanitize_callback' => array($this, 'sanitize_services'), 'default' => array() ) ); } public function enqueue_admin_assets($hook) { if ($hook !== 'settings_page_wptag-settings') { return; } wp_enqueue_style( 'wptag-admin', WPTAG_PLUGIN_URL . 'assets/admin.css', array(), WPTAG_VERSION ); wp_enqueue_script( 'wptag-admin', WPTAG_PLUGIN_URL . 'assets/admin.js', array('jquery', 'wp-util'), WPTAG_VERSION, true ); wp_localize_script('wptag-admin', 'wptagAdmin', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('wptag_admin_nonce'), 'strings' => array( 'validating' => 'Validating...', 'valid' => 'Valid', 'invalid' => 'Invalid', 'preview' => 'Preview', 'close' => 'Close', 'export_success' => 'Settings exported successfully', 'import_success' => 'Settings imported successfully', 'reset_success' => 'Settings reset successfully', 'confirm_reset' => 'Are you sure you want to reset all settings? This cannot be undone.', 'confirm_import' => 'This will overwrite your current settings. Continue?', 'loading' => 'Loading...', 'fill_required' => 'Please fill in required fields for enabled services.', 'advanced_settings' => 'Advanced Settings', 'hide_advanced' => 'Hide Advanced Settings' ) )); } public function display_admin_page() { if (!$this->current_user_can_manage_codes() && !$this->current_user_can_manage_services()) { wp_die(__('You do not have sufficient permissions to access this page.')); } add_filter('wptag_should_output_codes', '__return_false', 999); remove_action('wp_head', array($this->frontend ?? null, 'output_head_codes'), 1); remove_action('wp_body_open', array($this->frontend ?? null, 'output_body_codes'), 1); remove_action('wp_footer', array($this->frontend ?? null, 'output_footer_codes'), 1); $active_tab = isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'analytics'; $categories = $this->get_categories_with_services(); ?>
Manage your tracking codes and analytics services with ease. Enable services in the Services Management tab, then configure them in their respective category tabs.
Debug Mode: Check your website's source code for WPTag debug comments if codes are not appearing.
You do not have permission to manage services.
'; echo 'Enable or disable tracking services. Only enabled services will appear in the category tabs.
Custom Code Support: When using custom code, JavaScript will be preserved without filtering - perfect for gtag(), fbq(), and other tracking functions.
No services are enabled for this category. Enable some services to get started.
'; echo '%s
', esc_attr($notice['type']), esc_html($notice['message']) ); } delete_transient('wptag_admin_notices_' . get_current_user_id()); } private function add_admin_notice($type, $message) { $notices = get_transient('wptag_admin_notices_' . get_current_user_id()) ?: array(); $notices[] = array('type' => $type, 'message' => $message); set_transient('wptag_admin_notices_' . get_current_user_id(), $notices, 30); } public function handle_form_submission() { if (!isset($_POST['wptag_nonce']) && !isset($_POST['wptag_services_nonce'])) { return; } if (isset($_POST['wptag_services_nonce']) && wp_verify_nonce($_POST['wptag_services_nonce'], 'wptag_save_services')) { $this->handle_services_form_submission(); return; } if (isset($_POST['wptag_nonce']) && wp_verify_nonce($_POST['wptag_nonce'], 'wptag_save_settings')) { $this->handle_settings_form_submission(); return; } } private function handle_settings_form_submission() { if (!$this->current_user_can_manage_codes()) { $this->add_admin_notice('error', 'You do not have permission to manage tracking codes.'); return; } $settings = $_POST['wptag_settings'] ?? array(); if ($this->validator->validate_settings($settings)) { $result = $this->config->update_settings($settings); if ($result) { do_action('wptag_settings_saved', $settings); $has_custom_code = false; foreach ($settings as $service_settings) { if (!empty($service_settings['enabled']) && empty($service_settings['use_template']) && !empty($service_settings['custom_code'])) { $has_custom_code = true; break; } } if ($has_custom_code) { $this->add_admin_notice('success', 'Settings saved successfully. Custom JavaScript codes have been preserved correctly.'); } else { $this->add_admin_notice('success', 'Settings saved successfully.'); } } else { $this->add_admin_notice('error', 'Failed to save settings.'); } } else { $errors = $this->validator->get_error_messages(); $this->add_admin_notice('error', 'Validation failed: ' . implode(', ', $errors)); } $redirect_url = add_query_arg( array( 'page' => 'wptag-settings', 'tab' => isset($_GET['tab']) ? sanitize_text_field($_GET['tab']) : 'analytics' ), admin_url('options-general.php') ); wp_redirect($redirect_url); exit; } private function handle_services_form_submission() { if (!$this->current_user_can_manage_services()) { $this->add_admin_notice('error', 'You do not have permission to manage services.'); return; } $enabled_services = isset($_POST['enabled_services']) ? array_map('sanitize_text_field', $_POST['enabled_services']) : array(); $result = $this->config->update_enabled_services($enabled_services); if ($result) { do_action('wptag_services_updated', $enabled_services); $this->add_admin_notice('success', 'Services updated successfully.'); } else { $this->add_admin_notice('error', 'Failed to update services.'); } wp_redirect(add_query_arg(array('page' => 'wptag-settings', 'tab' => 'services'), admin_url('options-general.php'))); exit; } public function sanitize_settings($settings) { return $this->config->sanitize_settings($settings); } public function sanitize_services($services) { return is_array($services) ? array_map('sanitize_text_field', $services) : array(); } public function ajax_validate_code() { check_ajax_referer('wptag_admin_nonce', 'nonce'); if (!$this->current_user_can_manage_codes()) { wp_send_json_error(array('message' => 'You do not have permission to validate codes.')); return; } $service_key = sanitize_text_field($_POST['service'] ?? ''); $use_template = ($_POST['use_template'] ?? '0') === '1'; if (empty($service_key)) { wp_send_json_error(array('message' => 'Service key is required.')); return; } $settings = array( 'enabled' => true, 'use_template' => $use_template ); if ($use_template) { $service_config = $this->config->get_service_config($service_key); if ($service_config) { $field_key = $service_config['field']; $settings[$field_key] = sanitize_text_field($_POST['id_value'] ?? ''); } } else { $raw_custom_code = $_POST['custom_code'] ?? ''; $settings['custom_code'] = $this->sanitize_custom_code_for_validation($raw_custom_code); } $is_valid = $this->validator->validate_service_code($service_key, $settings); if ($is_valid) { wp_send_json_success(array('message' => 'Code is valid and ready to use.')); } else { $errors = $this->validator->get_error_messages(); wp_send_json_error(array('message' => implode(', ', $errors))); } } private function sanitize_custom_code_for_validation($custom_code) { if (empty($custom_code)) { return ''; } $custom_code = stripslashes($custom_code); $custom_code = wp_check_invalid_utf8($custom_code); return trim($custom_code); } public function ajax_preview_code() { check_ajax_referer('wptag_admin_nonce', 'nonce'); if (!$this->current_user_can_manage_codes()) { wp_send_json_error(array('message' => 'You do not have permission to preview codes.')); return; } $service_key = sanitize_text_field($_POST['service'] ?? ''); $id_value = sanitize_text_field($_POST['id_value'] ?? ''); if (empty($service_key)) { wp_send_json_error(array('message' => 'Service key is required.')); return; } if (empty($id_value)) { wp_send_json_error(array('message' => 'ID value is required for preview.')); return; } $preview = $this->output_manager->get_template_preview($service_key, $id_value); if (!empty($preview)) { $safe_preview = $this->sanitize_preview_output($preview); wp_send_json_success(array('preview' => $safe_preview)); } else { wp_send_json_error(array('message' => 'Unable to generate preview. Please check your ID format.')); } } private function sanitize_preview_output($preview) { $preview = htmlspecialchars($preview, ENT_QUOTES, 'UTF-8'); $preview = str_replace(array('<script>', '</script>'), array(''), $preview); $preview = str_replace(array('<noscript>', '</noscript>'), array(''), $preview); return $preview; } public function ajax_export_settings() { check_ajax_referer('wptag_admin_nonce', 'nonce'); if (!$this->current_user_can_manage_codes()) { wp_send_json_error(array('message' => 'You do not have permission to export settings.')); return; } try { $export_data = $this->config->export_settings(); wp_send_json_success(array( 'data' => $export_data, 'filename' => 'wptag-settings-' . date('Y-m-d-H-i-s') . '.json' )); } catch (Exception $e) { wp_send_json_error(array('message' => 'Export failed: ' . $e->getMessage())); } } public function ajax_import_settings() { check_ajax_referer('wptag_admin_nonce', 'nonce'); if (!$this->current_user_can_manage_codes()) { wp_send_json_error(array('message' => 'You do not have permission to import settings.')); return; } $import_data = wp_unslash($_POST['import_data'] ?? ''); if (empty($import_data)) { wp_send_json_error(array('message' => 'Import data is required.')); return; } if ($this->validator->validate_import_data($import_data)) { $result = $this->config->import_settings($import_data); if (!is_wp_error($result)) { do_action('wptag_settings_imported'); wp_send_json_success(array('message' => 'Settings imported successfully')); } else { wp_send_json_error(array('message' => $result->get_error_message())); } } else { $errors = $this->validator->get_error_messages(); wp_send_json_error(array('message' => 'Import validation failed: ' . implode(', ', $errors))); } } public function ajax_reset_settings() { check_ajax_referer('wptag_admin_nonce', 'nonce'); if (!$this->current_user_can_manage_codes()) { wp_send_json_error(array('message' => 'You do not have permission to reset settings.')); return; } try { $this->config->reset_to_defaults(); do_action('wptag_settings_reset'); wp_send_json_success(array('message' => 'Settings reset successfully')); } catch (Exception $e) { wp_send_json_error(array('message' => 'Reset failed: ' . $e->getMessage())); } } public function add_action_links($links) { $settings_link = 'Settings'; array_unshift($links, $settings_link); return $links; } public function add_row_meta($links, $file) { if ($file === plugin_basename(WPTAG_PLUGIN_FILE)) { $links[] = 'Documentation'; $links[] = 'Support'; } return $links; } private function get_template_help_text($service_key, $service_config) { return ''; } private function get_service_help_text($service_key, $service_config) { return ''; } private function get_service_docs_url($service_key) { $service_docs_mapping = array( 'google_analytics' => 'google-analytics', 'google_tag_manager' => 'google-tag-manager', 'facebook_pixel' => 'facebook-pixel', 'google_ads' => 'google-ads', 'microsoft_clarity' => 'microsoft-clarity', 'hotjar' => 'hotjar', 'tiktok_pixel' => 'tiktok-pixel', 'linkedin_insight' => 'linkedin-insight', 'twitter_pixel' => 'twitter-pixel', 'pinterest_pixel' => 'pinterest-pixel', 'snapchat_pixel' => 'snapchat-pixel', 'google_optimize' => 'google-optimize', 'crazyegg' => 'crazy-egg', 'mixpanel' => 'mixpanel', 'amplitude' => 'amplitude', 'matomo' => 'matomo' ); $docs_slug = isset($service_docs_mapping[$service_key]) ? $service_docs_mapping[$service_key] : $service_key; return 'https://wptag.com/document/' . $docs_slug . '/'; } }