File: /wordpress/plugins/wp-cloud-client/1.0.0/src/Analytics/GoogleAnalytics4.php
<?php
declare(strict_types=1);
namespace VPlugins\WPCloudClient\Analytics;
use VPlugins\WPCloudClient\Settings\SettingsRepository;
/**
* Injects Google Analytics 4 tracking script into the site's <head>.
*
* Supports two tracking IDs:
* 1. A platform-connected ID supplied via the GA4_TRACKING_ID server variable.
* 2. A user-supplied custom ID saved in the plugin settings.
*
* The production default ID (G-3KT4C16M4V) is reserved and cannot be set
* by the user as a custom ID.
*/
class GoogleAnalytics4 {
private const TRACKING_ID_PROD = 'G-3KT4C16M4V';
private string $connectedTrackingId;
/**
* Constructor.
*
* @param SettingsRepository $settings Plugin settings repository.
*/
public function __construct(
private readonly SettingsRepository $settings,
) {
$this->connectedTrackingId = isset( $_SERVER['GA4_TRACKING_ID'] )
? sanitize_text_field( (string) $_SERVER['GA4_TRACKING_ID'] )
: '';
}
/**
* Register the analytics script hook.
*
* @return void
*/
public function register(): void {
add_action( 'wp_head', [ $this, 'injectScript' ] );
}
/**
* Sanitizes and validates a user-submitted GA4 tracking ID.
*
* Called via register_setting sanitize_callback.
*
* @param string $input The raw tracking ID input.
* @return string The sanitized tracking ID.
*/
public function sanitizeTrackingId( string $input ): string {
$input = strtoupper( trim( $input ) );
if ( '' === $input ) {
return '';
}
if ( self::TRACKING_ID_PROD === $input ) {
add_settings_error(
'wpcc_settings',
'wpcc_ga4_reserved',
sprintf( '%s %s', $input, __( 'is already in use', 'wp-cloud-client' ) ),
'error',
);
return $this->settings->getGa4TrackingId() ?? '';
}
if ( ! preg_match( '/^G-[A-Z0-9]{10}$/', $input ) ) {
add_settings_error(
'wpcc_settings',
'wpcc_ga4_invalid',
sprintf( '%s: %s', __( 'Invalid Google Analytics 4 Tracking ID', 'wp-cloud-client' ), $input ),
'error',
);
return $this->settings->getGa4TrackingId() ?? '';
}
return $input;
}
/**
* Outputs the gtag script tags into wp_head.
*/
public function injectScript(): void {
$trackingIds = $this->getTrackingIds();
if ( empty( $trackingIds ) ) {
return;
}
$siteId = (string) ( $this->settings->getSiteId() ?? '' );
$idsJson = wp_json_encode( $trackingIds );
?>
<script async src="https://www.googletagmanager.com/gtag/js?id=<?php echo esc_attr( $trackingIds[0] ); ?>"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
var tracking_ids = <?php echo wp_json_encode( $trackingIds ); ?>;
var site_id = '<?php echo esc_js( $siteId ); ?>';
gtag('js', new Date());
for (var i = 0; i < tracking_ids.length; i++) {
gtag('config', tracking_ids[i], { 'dimension1': site_id });
gtag('event', 'page_view', { 'send_to': tracking_ids[i], 'dimension1': site_id });
gtag('event', 'first_visit', { 'send_to': tracking_ids[i], 'dimension1': site_id });
gtag('event', 'engaged_sessions', { 'send_to': tracking_ids[i], 'dimension1': site_id });
gtag('set', { 'siteSpeedSampleRate': 50 });
}
</script>
<?php
}
/**
* Returns the active tracking ID list.
* Index 0 is always the platform/default ID; index 1 (if present) is the user-supplied custom ID.
*/
private function getTrackingIds(): array {
$primary = '' !== $this->connectedTrackingId ? $this->connectedTrackingId : self::TRACKING_ID_PROD;
$ids = [ $primary ];
$userTracking = $this->settings->getGa4TrackingId();
if ( null !== $userTracking && $userTracking !== $primary ) {
$ids[] = $userTracking;
}
return $ids;
}
}