PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 8.5.74
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v8.5.74
9.1.3 9.1.2 9.1.1 9.1.0 9.0.3 9.0.2 9.0.1 9.0.0 8.5.79 8.5.78 8.5.77 8.5.76 8.5.75 8.5.74 8.5.73 8.5.72 8.5.71 8.5.70 8.5.69 8.5.68 8.5.35 8.5.36 8.5.37 8.5.38 8.5.39 All 222 releases
wpvr / vendor / linno / telemetry / README.md

README.md in WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress 8.5.74, at vendor/linno/telemetry/README.md

374 lines 12.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 # Linno Telemetry SDK
2
3 Privacy-first telemetry SDK for Linno WordPress plugins.
4
5 ## Overview
6
7 The Linno Telemetry SDK is a Composer package that provides privacy-first telemetry tracking for WordPress plugins. It enforces user consent, standardizes event payloads, and supports both the PostHog and OpenPanel analytics platforms.
8
9 ## Compliance and Development Guidelines (MUST READ)
10
11 The SDK's core purpose is to handle data transmission securely and ethically. Developers using this SDK **must** adhere to strict consent and disclosure requirements.
12
13 * **Internal Compliance Mandates:** For a complete list of requirements regarding PII collection, opt-in placement, and WordPress.org submission rules, please see our detailed **[](PRIVACY_GUIDELINE.mdPrivacy Implementation Guideline](PRIVACY_GUIDELINE.md](PRIVACY_GUIDELINE.md)**.
14 *(This document details mandatory steps for GDPR/WP.org compliance when implementing the SDK.)*
15
16
17 ## Features
18
19 - **Privacy-First**: Enforces user consent before sending most data (lifecycle events do not require consent).
20 - **Easy Integration**: Simple config-array constructor — only `pluginFile` and `slug` are required.
21 - **Canonical Event Taxonomy**: Library-owned events are emitted under a stable `activation/*` namespace.
22 - **Lifecycle Events**: Tracks plugin activation and deactivation via the standard WordPress hook system.
23 - **Optional PLG Triggers**: Define `setup` / `onboarding`, and `aha` / `kui` triggers only when needed — omitting them leaves those modules disabled by default.
24 - **Custom Events**: Send arbitrary events with any name and optional properties through a PHP API _or_ a WordPress action hook.
25 - **Non-Fatal Telemetry**: Missing drivers and send failures are logged and silently dropped — they never interrupt plugin execution.
26 - **Multi-Driver Support**: Works with PostHog and OpenPanel; falls back to a safe NullDriver when no driver is configured.
27 - **Asynchronous Sending**: Consented custom events are queued and sent via WP-Cron to prevent performance impact.
28 - **WordPress Native**: Uses WordPress APIs and follows WordPress coding standards.
29 - **Secure**: HTTPS-only transmission, nonce verification, input sanitization.
30 - **Internationalized**: All user-facing strings are translatable.
31
32 ## Requirements
33
34 - PHP 7.4 or higher
35 - WordPress 5.0 or higher
36
37 ## Installation
38
39 ### Step 1: Configure Composer
40
41 Add the VCS repository to your `composer.json`:
42
43 ```json
44 "repositories": [
45 {
46 "type": "vcs",
47 "url": "git@github.com:CODEREXLTD/linno-telemetry.git"
48 }
49 ]
50 ```
51
52 ### Step 2: Install via Composer
53
54 In your WordPress plugin directory, run:
55
56 ```bash
57 composer require linno/telemetry:dev-master
58 ```
59
60 ### Step 3: Require Autoloader
61
62 In your main plugin file, require the Composer autoloader:
63
64 ```php
65 require_once __DIR__ . '/vendor/autoload.php';
66 ```
67
68 That's it! You're ready to use the SDK.
69
70 ## Quick Start
71
72 Here's a complete example of integrating the SDK into your WordPress plugin:
73
74 ```php
75 <?php
76 /**
77 * Plugin Name: My Awesome Plugin
78 * Description: An awesome WordPress plugin with telemetry
79 * Version: 1.0.0
80 * Author: Your Name
81 * Text Domain: my-awesome-plugin
82 */
83
84 if (!defined('ABSPATH')) { exit; }
85
86 require_once __DIR__ . '/vendor/autoload.php';
87
88 use LinnoSDK\Telemetry\Client;
89
90 // Optional display customizations
91 Client::set_text_domain( 'my-awesome-plugin' );
92 Client::set_privacy_url( 'https://your-site.com/privacy-policy/' );
93 Client::set_consent_service_name( 'My Analytics' );
94
95 // Initialize the client — only 'pluginFile' and 'slug' are required.
96 $telemetry_client = new Client([
97 'pluginFile' => __FILE__,
98 'slug' => 'my-awesome-plugin',
99 'pluginName' => 'My Awesome Plugin',
100 'version' => '1.0.0',
101
102 // Choose a driver. Omit to run with no driver (events silently dropped).
103 'driver' => 'open_panel', // or 'posthog'
104 'apiKey' => 'op_YOUR_CLIENT_ID',
105 'apiSecret' => 'sec_YOUR_API_SECRET',
106 ]);
107
108 // Optional: define automatic triggers for onboarding and AHA milestones.
109 // Every key is optional — omitting a key disables that module.
110 $telemetry_client->define_triggers([
111
112 // Fires activation/onboarding_completed once — use 'setup' or 'onboarding'
113 'setup' => 'my_plugin_setup_complete',
114
115 // Fires retention/feature_used for each defined feature
116 'feature_used' => [
117 'funnel_created' => [
118 'hook' => 'my_plugin_funnel_created',
119 ],
120 ],
121
122 // Fires activation/aha_reached — use 'aha' (canonical) or 'kui' (legacy alias)
123 'aha' => [
124 'order_received' => [
125 'hook' => 'woocommerce_order_created',
126 'threshold' => ['count' => 2, 'period' => 'week'],
127 'callback' => function( $order_id ) {
128 return ['order_id' => $order_id];
129 },
130 ],
131 'funnel_published' => [
132 'hook' => 'my_plugin_funnel_published',
133 ],
134 ],
135 ]);
136 // Initialization, activation/deactivation hooks, and the custom-event action
137 // hook are all registered inside the constructor — no extra init() call needed.
138 ```
139
140 ### What Happens Next?
141
142 1. **Plugin Activation**: The SDK internally registers the activation hook. When the plugin activates, it emits `activation/plugin_activated`.
143 2. **Global Consent Notice (One Time)**: On the first Linno plugin installation, an admin notice asks for telemetry consent.
144 3. **Shared Consent Across Linno Plugins**: Once allowed (or declined), the choice is reused for all other Linno plugins on that same site.
145 4. **Table Creation After Consent**: The telemetry queue table is created only after consent is allowed, and only once per site.
146 5. **Deactivation Feedback**: Upon deactivation, a modal will prompt the user for a reason, which triggers `activation/plugin_deactivated`. Handled automatically.
147 6. **Asynchronous Sending**: Consented custom events are added to a local queue and sent via a daily WP-Cron job.
148
149 ### Onboarding Consent Flow (Important)
150
151 If your plugin asks for consent inside a custom onboarding wizard (instead of using the default admin notice), activation happens first, so `plugin_activated` is initially marked as pending.
152
153 When the user allows tracking in onboarding, call:
154
155 ```php
156 $telemetry_client->set_optin_state( 'yes' );
157 ```
158
159 This now automatically:
160
161 - creates the queue table (if needed), and
162 - flushes pending `plugin_activated` tracking exactly once.
163
164 If your onboarding stores consent in your own option first, call this right after saving to keep telemetry state in sync:
165
166 ```php
167 $telemetry_client->sync_consent_state();
168 ```
169
170 Or use the global helper (no direct client call needed):
171
172 ```php
173 linno_telemetry_sync_consent_state( __FILE__ );
174 ```
175
176 No manual `plugin_activated` tracking is needed in your plugin. The SDK now also recovers this event when telemetry is initialized after activation (common in setup-wizard-driven bootstraps).
177
178 If your wizard writes the consent option directly (without calling SDK methods), the SDK will still detect consent on `init()` and flush pending `plugin_activated` on the next request.
179
180 ## Canonical Event Names
181
182 The SDK emits all library-owned events under the `activation/*` namespace for a stable analytics taxonomy:
183
184 | Trigger | Emitted Event Name |
185 |---|---|
186 | Plugin activation | `activation/plugin_activated` |
187 | Plugin deactivation | `activation/plugin_deactivated` |
188 | Onboarding / setup | `activation/onboarding_completed` |
189 | Feature Used | `retention/feature_used` |
190 | AHA / KUI milestone | `activation/aha_reached` |
191
192 Custom events submitted via `Client::track()` or the `<slug>_telemetry_track` WordPress action are passed through **unchanged** — the SDK never alters caller-supplied event names.
193
194 ## Custom Events
195
196 ### PHP API
197
198 ```php
199 // Any event name; optional associative properties array; optional consent override.
200 $telemetry_client->track( 'post_published', [ 'post_id' => 42 ] );
201 ```
202
203 ### WordPress Action Hook
204
205 The SDK registers `<slug>_telemetry_track` during initialization. Fire it from anywhere:
206
207 ```php
208 do_action( 'my-awesome-plugin_telemetry_track', 'post_published', [ 'post_id' => 42 ] );
209 ```
210
211 Both paths accept any event name and an optional associative properties array, and route through the same consent-gated queue path.
212
213 ## Trigger System
214
215 ### Setup / Onboarding (fires `activation/onboarding_completed` once)
216
217 ```php
218 $telemetry_client->define_triggers([
219 'setup' => 'my_plugin_setup_complete', // legacy key
220 // 'onboarding' => 'my_plugin_setup_complete', // canonical alias — same behavior
221 ]);
222 ```
223
224 ### Feature Used (fires `retention/feature_used`)
225
226 ```php
227 $telemetry_client->define_triggers([
228 'feature_used' => [
229 'funnel_created' => [
230 'hook' => 'my_plugin_funnel_created',
231 'callback' => function( $funnel_id ) {
232 return ['funnel_id' => $funnel_id];
233 },
234 ],
235 ],
236 ]);
237 ```
238
239 Alternatively, use the static convenience method to register a feature-used event from anywhere in your codebase after the client is initialized:
240
241 ```php
242 use LinnoSDK\Telemetry\Client;
243
244 // Fires retention/feature_used with feature='Export Settings' when the hook is triggered.
245 Client::add_feature_used_event( 'my_plugin_settings_exported', 'Export Settings' );
246
247 // With optional extra parameters.
248 Client::add_feature_used_event( 'my_plugin_settings_imported', 'Import Settings', [ 'source' => 'file' ] );
249 ```
250
251 Then trigger the corresponding WordPress action in your plugin code:
252
253 ```php
254 function my_plugin_export_settings() {
255 // ... export logic ...
256 do_action( 'my_plugin_settings_exported' );
257 }
258 ```
259
260 ### AHA / KUI Milestones (fires `activation/aha_reached`)
261
262 ```php
263 $telemetry_client->define_triggers([
264 // 'aha' is the canonical key; 'kui' is the legacy alias — both work.
265 'aha' => [
266 'order_received' => [
267 'hook' => 'woocommerce_order_created',
268 'threshold' => ['count' => 2, 'period' => 'week'],
269 ],
270 'funnel_published' => [
271 'hook' => 'my_plugin_funnel_published', // fires every time
272 ],
273 ],
274 ]);
275 ```
276
277 `activation/aha_reached` events include an `indicator` property with the milestone name for downstream filtering.
278
279 ### Custom Trigger (pass-through event name)
280
281 Register a trigger that fires a developer-supplied event name on any hook:
282
283 ```php
284 $telemetry_client->triggers()
285 ->on( 'page_created', 'my_plugin_page_created', function( $page_id ) {
286 return ['page_id' => $page_id];
287 });
288 ```
289
290 ## Events Not Requiring Consent
291
292 The SDK automatically tracks these events **without requiring user consent**:
293
294 - **`activation/plugin_activated`**: When the plugin is activated.
295 - Includes: `site_url`, `unique_id`.
296 - **`activation/plugin_deactivated`**: When the plugin is deactivated.
297 - Includes: `site_url`, `unique_id`, `reason`.
298
299 **Why no opt-in required?** These lifecycle events contain no personal data (no email, name, or user profile fields).
300
301 ## Non-Fatal Driver Behavior
302
303 The SDK is designed to never interrupt plugin execution:
304
305 - **No driver configured** → a warning is written to `error_log` and events are silently dropped.
306 - **Unrecognized driver name** → same as above.
307 - **Driver `send()` fails** → the failure is logged to `error_log` and the event is dropped.
308
309 No exceptions are thrown during normal event submission.
310
311 ## Data Collected (with User Consent)
312
313 With user consent, the SDK collects:
314
315 - Site URL
316 - Plugin name and version
317 - Event timestamps
318 - Unique site profile ID (anonymous)
319 - Custom event properties (as defined by developer)
320
321 **No sensitive personal data** is collected beyond what is strictly necessary for anonymous usage analytics and product improvement, and only with explicit user consent.
322
323 ## Appsero Consent Compatibility
324
325 The SDK supports migration from Appsero consent keys so existing users are not prompted again.
326
327 - Primary key: `linno_telemetry_allow_tracking`
328 - Legacy pattern: `{plugin_slug}_allow_tracking`
329 - Also checks known legacy keys:
330 - `best-woocommerce-feed_allow_tracking`
331 - `wpvr_allow_tracking`
332 - `wpfunnels_allow_tracking`
333 - `cart-lift_allow_tracking`
334 - `creatorlms_allow_tracking`
335 - `mail-mint_allow_tracking`
336
337 If a legacy key exists with `yes` or `no` and `linno_telemetry_allow_tracking` is not set, the value is automatically reused and migrated to the Linno key.
338
339 ## Using the PostHog Driver
340
341 ```bash
342 composer require posthog/posthog-php
343 ```
344
345 ```php
346 $client = new Client([
347 'pluginFile' => __FILE__,
348 'slug' => 'my-awesome-plugin',
349 'driver' => 'posthog',
350 'driver_config' => [
351 'host' => 'https://app.posthog.com',
352 'api_key' => 'phc_YOUR_POSTHOG_API_KEY',
353 ],
354 ]);
355 ```
356
357 ## Using the OpenPanel Driver
358
359 ```php
360 $client = new Client([
361 'pluginFile' => __FILE__,
362 'slug' => 'my-awesome-plugin',
363 'driver' => 'open_panel',
364 'apiKey' => 'op_YOUR_CLIENT_ID',
365 'apiSecret' => 'sec_YOUR_API_SECRET',
366 ]);
367 ```
368
369 ## License
370 GPL-2.0-or-later
371
372 ## Support
373 For support, please contact support@linno.co
374