PluginProbe
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF / 2.3.3
Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF v2.3.3
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
imagify / classes / Tracking / BaseTracking.php

BaseTracking.php in Imagify Image Optimization: Optimize Images | Compress & Convert to WebP/AVIF 2.3.3, at classes/Tracking/BaseTracking.php

144 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 declare(strict_types=1);
3
4 namespace Imagify\Tracking;
5
6 use Imagify\Dependencies\WPMedia\Mixpanel\Optin;
7 use Imagify\Dependencies\WPMedia\Mixpanel\TrackingPlugin;
8
9 /**
10 * Abstract base class for Imagify tracking.
11 *
12 * @since 2.3.0
13 */
14 abstract class BaseTracking {
15
16 /**
17 * The Mixpanel opt-in service.
18 *
19 * @var Optin
20 */
21 protected $optin;
22
23 /**
24 * The Mixpanel tracking plugin service.
25 *
26 * @var TrackingPlugin
27 */
28 protected $mixpanel;
29
30 /**
31 * Whether the Mixpanel user has already been identified during this request.
32 *
33 * @var bool
34 */
35 private $identified = false;
36
37 /**
38 * Constructor.
39 *
40 * @param Optin $optin The Mixpanel opt-in service.
41 * @param TrackingPlugin $mixpanel The Mixpanel tracking plugin service.
42 */
43 public function __construct( Optin $optin, TrackingPlugin $mixpanel ) {
44 $this->optin = $optin;
45 $this->mixpanel = $mixpanel;
46 }
47
48 /**
49 * Check if tracking is allowed.
50 *
51 * @return bool True if tracking is allowed, false otherwise.
52 */
53 public function can_track(): bool {
54 return $this->optin->can_track();
55 }
56
57 /**
58 * Returns the default event properties shared by every tracked event.
59 *
60 * IMPORTANT: do NOT add `domain`, `wp_version`, `php_version`, `plugin`,
61 * `brand`, or `application` here. `TrackingPlugin::track_direct()` injects
62 * those automatically and any value set here is silently overwritten.
63 *
64 * @return array<string, mixed>
65 */
66 protected function get_default_event_properties(): array {
67 $email = $this->get_license_owner_email();
68 $license_owner = '' !== $email ? hash( 'sha256', $email ) : '';
69
70 $this->identify_user( $email );
71
72 return [
73 'context' => 'wp_plugin',
74 'license_owner' => $license_owner,
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 : '';
142 }
143 }
144