optin = $optin; $this->mixpanel = $mixpanel; } /** * Check if tracking is allowed. * * @return bool True if tracking is allowed, false otherwise. */ public function can_track(): bool { return $this->optin->can_track(); } /** * Returns the default event properties shared by every tracked event. * * IMPORTANT: do NOT add `domain`, `wp_version`, `php_version`, `plugin`, * `brand`, or `application` here. `TrackingPlugin::track_direct()` injects * those automatically and any value set here is silently overwritten. * * @return array */ protected function get_default_event_properties(): array { $email = $this->get_license_owner_email(); $license_owner = '' !== $email ? hash( 'sha256', $email ) : ''; $this->identify_user( $email ); return [ 'context' => 'wp_plugin', 'license_owner' => $license_owner, 'user_id' => (int) get_current_user_id(), ]; } /** * Registers a stable `distinct_id` super property on the Mixpanel instance. * * Mixpanel needs `distinct_id` on every event to compute user-level metrics * (MAU/DAU, retention, cohorts, funnels). `TrackingPlugin::identify()` hashes * the identifier with sha224 before it is registered, so no raw email or * domain ever leaves the site. * * The identifier is the Imagify license owner email — the same strategy as * WP Rocket, so one license maps to one Mixpanel user across all its sites. * When no license email is available (unlicensed or unreachable API), the * site host is used instead so events are still attributed to a stable, * anonymized identity rather than none at all. * * Called from `get_default_event_properties()` — the single choke point every * tracked event goes through — so the license user is fetched only once and * never on plugin bootstrap. Runs at most once per instance per request; the * underlying Mixpanel instance is shared, so the property applies to every * subsequent event. * * @param string $email The license owner email, or an empty string when unknown. * * @return void */ protected function identify_user( string $email ): void { if ( $this->identified ) { return; } $identifier = '' !== $email ? $email : $this->get_site_identifier(); if ( '' === $identifier ) { return; } $this->mixpanel->identify( $identifier ); $this->identified = true; } /** * Returns the Imagify license owner email. * * @return string The email, or an empty string when the account is unknown. */ private function get_license_owner_email(): string { $user = get_imagify_user(); if ( is_wp_error( $user ) || empty( $user->email ) ) { return ''; } return (string) $user->email; } /** * Returns the site host, used as a fallback identifier when no license email exists. * * @return string The host, or an empty string when it cannot be resolved. */ private function get_site_identifier(): string { $host = wp_parse_url( get_home_url(), PHP_URL_HOST ); return is_string( $host ) ? $host : ''; } }