PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / trunk
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF vtrunk
2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.9 2.2.8 trunk 1.10 1.3.3 1.3.4 1.3.5 1.3.5.1 1.3.5.2 1.3.6 1.3.6.1 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.5 All 103 releases
← All changes | classes/Tracking/BaseTracking.php +76 -6 2.3.0 → trunk View file →
@@ -27,8 +27,15 @@
27 27 */
28 28 protected $mixpanel;
29 29
30 30 /**
31 + * Whether the Mixpanel user has already been identified during this request.
32 + *
33 + * @var bool
34 + */
35 + private $identified = false;
36 +
37 + /**
31 38 * Constructor.
32 39 *
33 40 * @param Optin $optin The Mixpanel opt-in service.
34 41 * @param TrackingPlugin $mixpanel The Mixpanel tracking plugin service.
@@ -56,18 +63,81 @@
56 63 *
57 64 * @return array<string, mixed>
58 65 */
59 66 protected function get_default_event_properties(): array {
60 - $user = get_imagify_user();
61 - $license_owner = '';
67 + $email = $this->get_license_owner_email();
68 + $license_owner = '' !== $email ? hash( 'sha256', $email ) : '';
62 69
63 - if ( ! is_wp_error( $user ) && ! empty( $user->email ) ) {
64 - $license_owner = hash( 'sha256', $user->email );
65 - }
70 + $this->identify_user( $email );
66 71
67 72 return [
68 73 'context' => 'wp_plugin',
69 74 'license_owner' => $license_owner,
70 - 'user_id' => (int) get_current_user_id(),
71 75 ];
76 + }
77 +
78 + /**
79 + * Registers a stable `distinct_id` super property on the Mixpanel instance.
80 + *
81 + * Mixpanel needs `distinct_id` on every event to compute user-level metrics
82 + * (MAU/DAU, retention, cohorts, funnels). `TrackingPlugin::identify()` hashes
83 + * the identifier with sha224 before it is registered, so no raw email or
84 + * domain ever leaves the site.
85 + *
86 + * The identifier is the Imagify license owner email — the same strategy as
87 + * WP Rocket, so one license maps to one Mixpanel user across all its sites.
88 + * When no license email is available (unlicensed or unreachable API), the
89 + * site host is used instead so events are still attributed to a stable,
90 + * anonymized identity rather than none at all.
91 + *
92 + * Called from `get_default_event_properties()` — the single choke point every
93 + * tracked event goes through — so the license user is fetched only once and
94 + * never on plugin bootstrap. Runs at most once per instance per request; the
95 + * underlying Mixpanel instance is shared, so the property applies to every
96 + * subsequent event.
97 + *
98 + * @param string $email The license owner email, or an empty string when unknown.
99 + *
100 + * @return void
101 + */
102 + protected function identify_user( string $email ): void {
103 + if ( $this->identified ) {
104 + return;
105 + }
106 +
107 + $identifier = '' !== $email ? $email : $this->get_site_identifier();
108 +
109 + if ( '' === $identifier ) {
110 + return;
111 + }
112 +
113 + $this->mixpanel->identify( $identifier );
114 +
115 + $this->identified = true;
116 + }
117 +
118 + /**
119 + * Returns the Imagify license owner email.
120 + *
121 + * @return string The email, or an empty string when the account is unknown.
122 + */
123 + private function get_license_owner_email(): string {
124 + $user = get_imagify_user();
125 +
126 + if ( is_wp_error( $user ) || empty( $user->email ) ) {
127 + return '';
128 + }
129 +
130 + return (string) $user->email;
131 + }
132 +
133 + /**
134 + * Returns the site host, used as a fallback identifier when no license email exists.
135 + *
136 + * @return string The host, or an empty string when it cannot be resolved.
137 + */
138 + private function get_site_identifier(): string {
139 + $host = wp_parse_url( get_home_url(), PHP_URL_HOST );
140 +
141 + return is_string( $host ) ? $host : '';
72 142 }
73 143 }