is_configured()) {
return;
}
add_action('admin_enqueue_scripts', array($this, 'enqueue_ga4_script'));
add_action('admin_head', array($this, 'track_admin_page_view'));
}
private function get_measurement_id() {
return defined('METASYNC_GA4_MEASUREMENT_ID') && !empty(METASYNC_GA4_MEASUREMENT_ID)
? METASYNC_GA4_MEASUREMENT_ID
: null;
}
private function is_configured() {
return $this->get_measurement_id() !== null;
}
public function is_opted_in() {
return get_option(self::OPT_IN_OPTION, 'no') === 'yes';
}
private function get_anonymized_user_id() {
$current_user = wp_get_current_user();
if (!$current_user || !$current_user->ID) {
return 'guest';
}
$site_identifier = get_option('siteurl');
return 'user_' . wp_hash($current_user->ID . '|' . $site_identifier);
}
private function get_plugin_version() {
return defined('METASYNC_VERSION') ? METASYNC_VERSION : 'unknown';
}
private function is_plugin_admin_page() {
if (!isset($_GET['page'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page and tab check for GA4 assets
return false;
}
$page = sanitize_text_field(wp_unslash($_GET['page'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page and tab check for GA4 assets
$plugin_slug = 'searchatlas';
if (class_exists('Metasync_Admin') && isset(Metasync_Admin::$page_slug)) {
$plugin_slug = Metasync_Admin::$page_slug;
}
return $page === $plugin_slug || strpos($page, $plugin_slug . '-') === 0;
}
private function get_admin_screen_name() {
if (!isset($_GET['page'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page and tab check for GA4 assets
return 'Unknown';
}
$page = sanitize_text_field(wp_unslash($_GET['page'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page and tab check for GA4 assets
$plugin_slug = 'searchatlas';
if (class_exists('Metasync_Admin') && isset(Metasync_Admin::$page_slug)) {
$plugin_slug = Metasync_Admin::$page_slug;
}
$screen_map = array(
$plugin_slug => 'Settings',
$plugin_slug . '-dashboard' => 'Dashboard',
$plugin_slug . '-compatibility' => 'Compatibility',
$plugin_slug . '-sync-log' => 'Changes Log',
$plugin_slug . '-seo-controls' => 'Indexation Control',
$plugin_slug . '-redirections' => 'Redirections',
$plugin_slug . '-xml-sitemap' => 'XML Sitemap',
$plugin_slug . '-robots-txt' => 'Robots.txt',
$plugin_slug . '-404-monitor' => '404 Monitor',
'ottodebug' => 'OTTO Debug',
);
if ($page === $plugin_slug && isset($_GET['tab'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page and tab check for GA4 assets
$tab = sanitize_text_field(wp_unslash($_GET['tab'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only page and tab check for GA4 assets
return 'Settings - ' . ucfirst(str_replace('_', ' ', $tab));
}
return $screen_map[$page] ?? 'Unknown Page';
}
public function enqueue_ga4_script() {
if (!$this->is_configured() || !$this->is_plugin_admin_page() || !$this->is_opted_in()) {
return;
}
$measurement_id = esc_js($this->get_measurement_id());
$user_id = esc_js($this->get_anonymized_user_id());
$plugin_version = esc_js($this->get_plugin_version());
$wp_version = esc_js(get_bloginfo('version'));
$php_version = esc_js(PHP_VERSION);
$inline_script = "
var gtagScript = document.createElement('script');
gtagScript.async = true;
gtagScript.src = 'https://www.googletagmanager.com/gtag/js?id={$measurement_id}';
document.head.appendChild(gtagScript);
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{$measurement_id}', {
'user_id': '{$user_id}',
'send_page_view': false
});
gtag('set', {
'plugin_version': '{$plugin_version}',
'wp_version': '{$wp_version}',
'php_version': '{$php_version}'
});
window.metasyncGA4Track = function(eventName, params) {
if (typeof gtag !== 'undefined') {
gtag('event', eventName, params || {});
}
};";
wp_register_script('metasync-ga4-init', '', array(), $this->get_plugin_version(), false);
wp_enqueue_script('metasync-ga4-init');
wp_add_inline_script('metasync-ga4-init', $inline_script, 'before');
}
public function track_admin_page_view() {
if (!$this->is_configured() || !$this->is_plugin_admin_page() || !$this->is_opted_in()) {
return;
}
$screen_name = $this->get_admin_screen_name();
$params = wp_json_encode(
array('screen_name' => $screen_name),
JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT
);
$inline_tracking = "";
echo $inline_tracking; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $params is wp_json_encode() output with JSON_HEX_TAG/AMP/APOS/QUOT, safe inside an inline