PluginProbe
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress / 9.1.3
WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress v9.1.3
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 / examples / test-plugin / test-telemetry-plugin.php

test-telemetry-plugin.php in WPVR – 360 Panorama viewer and Virtual Tour Builder for WordPress 9.1.3, at vendor/linno/telemetry/examples/test-plugin/test-telemetry-plugin.php

429 lines 17.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: Test Telemetry Plugin
4 * Plugin URI: https://linno.co
5 * Description: A test plugin to demonstrate and validate Linno Telemetry SDK functionality
6 * Version: 1.0.0
7 * Author: Linno
8 * Author URI: https://linno.co
9 * License: GPL-2.0-or-later
10 * Text Domain: test-telemetry-plugin
11 * Requires at least: 5.0
12 * Requires PHP: 7.4
13 */
14
15 // Exit if accessed directly
16 if (!defined('ABSPATH')) {
17 exit;
18 }
19
20 // Load Composer autoloader
21 // Try plugin's own vendor directory first (if installed via Composer in plugin dir)
22 if (file_exists(__DIR__ . '/vendor/autoload.php')) {
23 require_once __DIR__ . '/vendor/autoload.php';
24 }
25 // Fall back to SDK's vendor directory (when testing from SDK repository)
26 elseif (file_exists(__DIR__ . '/../../vendor/autoload.php')) {
27 require_once __DIR__ . '/../../vendor/autoload.php';
28 }
29 // If neither exists, show error
30 else {
31 add_action('admin_notices', function() {
32 echo '<div class="notice notice-error"><p>';
33 echo '<strong>Test Telemetry Plugin Error:</strong> Composer autoloader not found. ';
34 echo 'Please run <code>composer install</code> from the plugin directory or the SDK root directory.';
35 echo '</p></div>';
36 });
37 return;
38 }
39
40 use LinnoSDK\Telemetry\Client;
41
42 /**
43 * Global telemetry client instance.
44 *
45 * @var Client|null
46 */
47 $test_telemetry_client = null;
48
49 $text_domain = 'test-telemetry-plugin';
50
51 try {
52 // Optional: Set text domain for i18n (defaults to plugin slug if not set)
53 Client::set_text_domain( $text_domain );
54
55 // Initialize the telemetry client using a config array.
56 // Only 'pluginFile' and 'slug' are required.
57 // Set 'driver' to 'posthog' or 'open_panel'. Omit it to run with no driver (events are silently dropped).
58 $test_telemetry_client = new Client([
59 'pluginFile' => __FILE__,
60 'slug' => 'test-telemetry-plugin',
61 'pluginName' => 'Test Telemetry Plugin',
62 'version' => '1.0.0',
63
64 // --- PostHog driver example ---
65 // 'driver' => 'posthog',
66 // 'driver_config' => [
67 // 'host' => 'https://app.posthog.com',
68 // 'api_key' => 'phc_YOUR_POSTHOG_API_KEY',
69 // ],
70
71 // --- OpenPanel driver example ---
72 'driver' => 'open_panel',
73 'apiKey' => 'op_YOUR_CLIENT_ID',
74 'apiSecret' => 'sec_YOUR_API_SECRET',
75 ]);
76
77 // Define optional automatic triggers.
78 // Each key is optional — omitting a key simply disables that module.
79 $test_telemetry_client->define_triggers([
80
81 // Onboarding completion: fires activation/onboarding_completed once.
82 // Both 'setup' (legacy) and 'onboarding' (canonical) are accepted.
83 'setup' => 'my_plugin_setup_complete',
84 // 'onboarding' => 'my_plugin_onboarding_finished', // canonical alias
85
86 // Feature Used: fires retention/feature_used.
87 'feature_used' => [
88 'funnel_created' => [
89 'hook' => 'my_plugin_funnel_created',
90 ],
91 ],
92
93 // AHA-milestone indicators (fire activation/aha_reached).
94 // Both 'kui' (legacy) and 'aha' (canonical) are accepted.
95 'aha' => [
96 'order_received' => [
97 'hook' => 'woocommerce_order_created',
98 'threshold' => ['count' => 2, 'period' => 'week'],
99 'callback' => function( $order_id ) {
100 return ['order_id' => $order_id];
101 },
102 ],
103 'student_enrolled' => [
104 'hook' => 'lms_student_enrolled',
105 'threshold' => ['count' => 2, 'period' => 'week'],
106 'callback' => function( $course_id, $student_id ) {
107 return ['course_id' => $course_id, 'student_id' => $student_id];
108 },
109 ],
110 ],
111 ]);
112
113 } catch (Exception $e) {
114 error_log('Test Telemetry Plugin: Failed to initialize - ' . $e->getMessage());
115 }
116
117 /**
118 * Track a custom event when a post is published.
119 *
120 * Option A — direct PHP API call:
121 *
122 * @param int $post_id Post ID
123 * @since 1.0.0
124 */
125 function test_telemetry_track_post_published($post_id) {
126 global $test_telemetry_client;
127 if ($test_telemetry_client instanceof Client) {
128 $test_telemetry_client->track('post_published', [
129 'post_id' => $post_id,
130 'post_type' => get_post_type($post_id),
131 ]);
132 }
133 }
134 add_action('publish_post', 'test_telemetry_track_post_published');
135
136 /**
137 * Option B — WordPress action hook:
138 * Any code in the plugin can fire this action to send a custom telemetry event:
139 *
140 * do_action( 'test-telemetry-plugin_telemetry_track', 'post_published', ['post_id' => 42] );
141 *
142 * The client registers this handler automatically during initialization.
143 * No extra setup is required.
144 */
145
146 // --- Examples of optional trigger-module tracking (commented out) ---
147
148 // Example: Track onboarding completion (once, requires consent)
149 // function test_telemetry_track_setup_complete() {
150 // global $test_telemetry_client;
151 // if ($test_telemetry_client instanceof Client) {
152 // $test_telemetry_client->track_setup(['setup_method' => 'quick_install']);
153 // // Emits: activation/onboarding_completed
154 // }
155 // }
156 // add_action('my_plugin_setup_complete', 'test_telemetry_track_setup_complete');
157
158 // Example: Track feature usage via static convenience method (requires consent)
159 // Call this after the client is initialized to register the event for a specific hook.
160 Client::add_feature_used_event( 'my_plugin_settings_exported', 'Export Settings' );
161 // When 'my_plugin_settings_exported' action fires, a retention/feature_used event
162 // is sent with feature='Export Settings'.
163
164 // With optional extra parameters:
165 // Client::add_feature_used_event( 'my_plugin_settings_imported', 'Import Settings', [ 'source' => 'file' ] );
166
167 // Example: Track AHA milestone (multiple times, requires consent)
168 // function test_telemetry_track_order_received($order_id, $amount) {
169 // global $test_telemetry_client;
170 // if ($test_telemetry_client instanceof Client) {
171 // $test_telemetry_client->track_kui('order_received', ['order_id' => $order_id, 'amount' => $amount]);
172 // // Emits: activation/aha_reached with indicator=order_received
173 // }
174 // }
175 // add_action('woocommerce_new_order', 'test_telemetry_track_order_received', 10, 2);
176
177
178 /**
179 * Add admin menu for testing
180 *
181 * @since 1.0.0
182 */
183 function test_telemetry_admin_menu() {
184 add_menu_page(
185 'Telemetry Test',
186 'Telemetry Test',
187 'manage_options',
188 'test-telemetry',
189 'test_telemetry_admin_page',
190 'dashicons-chart-line',
191 100
192 );
193 }
194 add_action('admin_menu', 'test_telemetry_admin_menu');
195
196 /**
197 * Render admin test page
198 *
199 * @since 1.0.0
200 */
201 function test_telemetry_admin_page() {
202 if (!current_user_can('manage_options')) {
203 return;
204 }
205
206 global $test_telemetry_client;
207
208 // Handle test event submission
209 if (isset($_POST['test_event']) && check_admin_referer('test_telemetry_event')) {
210 error_log('=== TEST PLUGIN FORM HANDLER EXECUTING - ' . time() . ' ===');
211
212 // Remove WordPress magic quotes from entire POST array
213 $_POST = array_map('stripslashes_deep', $_POST);
214
215 $event_name = sanitize_text_field($_POST['event_name']);
216 $event_data = isset($_POST['event_data']) ? trim($_POST['event_data']) : '';
217
218 error_log('Test Plugin [' . time() . '] - Raw event_data: ' . $event_data);
219
220 $properties = [];
221 if (!empty($event_data)) {
222 // Try to decode JSON
223 $decoded = json_decode($event_data, true);
224
225 error_log('Test Plugin [' . time() . '] - JSON decode result: ' . print_r($decoded, true));
226 error_log('Test Plugin [' . time() . '] - JSON error: ' . json_last_error_msg());
227
228 if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
229 // JSON is valid - use decoded array
230 $properties = $decoded;
231 error_log('Test Plugin [' . time() . '] - SUCCESS: Using decoded properties');
232 } else {
233 // JSON is invalid - store as raw_data with error info
234 $properties = [
235 'raw_data' => $event_data,
236 'json_error' => json_last_error_msg()
237 ];
238 error_log('Test Plugin [' . time() . '] - FAILED: JSON decode failed, using raw_data');
239 }
240 }
241
242 if ($test_telemetry_client instanceof Client) {
243 $test_telemetry_client->track($event_name, $properties);
244 $message = 'Event added to queue! It will be sent during the next cron run.';
245 echo '<div class="notice notice-success"><p>' . esc_html($message) . '</p></div>';
246 } else {
247 $message = 'Telemetry Client not initialized.';
248 echo '<div class="notice notice-error"><p>' . esc_html($message) . '</p></div>';
249 }
250 }
251
252 // Handle manual cron trigger
253 if (isset($_POST['trigger_cron']) && check_admin_referer('test_telemetry_cron')) {
254 global $test_telemetry_client;
255 if ($test_telemetry_client instanceof Client) {
256 $test_telemetry_client->process_queue();
257 echo '<div class="notice notice-success"><p>Telemetry queue processed manually!</p></div>';
258 } else {
259 echo '<div class="notice notice-error"><p>Telemetry Client not initialized for cron processing.</p></div>';
260 }
261 }
262
263 ?>
264 <div class="wrap">
265 <h1>Telemetry SDK Test Page</h1>
266
267 <p class="description" style="background: #fff; padding: 15px; border-left: 4px solid #00a0d2;">
268 <strong>Note:</strong> This test plugin demonstrates integration with the Linno Telemetry SDK.
269 Consent notices and deactivation modals will appear as expected. Events are added to a queue and sent via WP-Cron.
270 </p>
271
272 <div class="card">
273 <h2>Test Custom Event</h2>
274 <form method="post">
275 <?php wp_nonce_field('test_telemetry_event'); ?>
276 <table class="form-table">
277 <tr>
278 <th scope="row"><label for="event_name">Event Name</label></th>
279 <td>
280 <input type="text" id="event_name" name="event_name" value="test_custom_event" class="regular-text" required>
281 <p class="description">Use alphanumeric characters and underscores only</p>
282 </td>
283 </tr>
284 <tr>
285 <th scope="row"><label for="event_data">Event Properties (JSON)</label></th>
286 <td>
287 <textarea id="event_data" name="event_data" rows="5" class="large-text" placeholder='{"test_key": "test_value", "user_action": "button_click"}'></textarea>
288 <p class="description">Optional: Enter JSON object with custom properties.</p>
289 </td>
290 </tr>
291 </table>
292 <p class="submit">
293 <button type="submit" name="test_event" class="button button-primary">Send Test Event</button>
294 </p>
295 </form>
296 </div>
297
298 <div class="card">
299 <h2>Test Telemetry Queue Processing</h2>
300 <p>Manually trigger the telemetry queue processing:</p>
301 <form method="post">
302 <?php wp_nonce_field('test_telemetry_cron'); ?>
303 <p class="submit">
304 <button type="submit" name="trigger_cron" class="button button-secondary">Process Telemetry Queue</button>
305 </p>
306 </form>
307 <?php
308 $next_scheduled_cron_hook = $test_telemetry_client ? $test_telemetry_client->get_slug() . '_telemetry_queue_process' : '';
309 $next_scheduled = $next_scheduled_cron_hook ? wp_next_scheduled($next_scheduled_cron_hook) : false;
310
311 if ($next_scheduled) {
312 echo '<p>Next scheduled queue processing: <strong>' . esc_html(date('Y-m-d H:i:s', $next_scheduled)) . '</strong></p>';
313 } else {
314 echo '<p style="color: orange;">No cron job scheduled. This may be normal if consent is not granted or if the client is not initialized.</p>';
315 }
316 ?>
317 </div>
318
319 <div class="card">
320 <h2>System Information</h2>
321 <table class="widefat">
322 <tbody>
323 <tr>
324 <td><strong>PHP Version:</strong></td>
325 <td><?php echo esc_html(PHP_VERSION); ?></td>
326 </tr>
327 <tr>
328 <td><strong>WordPress Version:</strong></td>
329 <td><?php echo esc_html(get_bloginfo('version')); ?></td>
330 </tr>
331 <tr>
332 <td><strong>MySQL Version:</strong></td>
333 <td><?php global $wpdb; echo esc_html($wpdb->db_version()); ?></td>
334 </tr>
335 <tr>
336 <td><strong>Server Software:</strong></td>
337 <td><?php echo esc_html($_SERVER['SERVER_SOFTWARE'] ?? 'Unknown'); ?></td>
338 </tr>
339 <tr>
340 <td><strong>Site URL:</strong></td>
341 <td><?php echo esc_html(get_site_url()); ?></td>
342 </tr>
343 </tbody>
344 </table>
345 </div>
346
347 <div class="card">
348 <h2>Testing Checklist</h2>
349 <ul style="list-style: disc; margin-left: 20px;">
350 <li>✓ Activate plugin and verify consent notice appears.</li>
351 <li>✓ Click "Allow" and verify `plugin_activated` event is queued.</li>
352 <li>✓ Use form above to send custom test events and verify they are queued.</li>
353 <li>✓ Trigger queue processing manually and verify events are dispatched.</li>
354 <li>✓ Deactivate plugin and verify reason modal appears.</li>
355 <li>✓ Submit deactivation reason and verify `plugin_deactivated` event is queued.</li>
356 <li>✓ Reactivate, click "Do not allow" on consent notice and verify custom events are not queued.</li>
357 <li>✓ Check browser console and PHP error logs for issues.</li>
358 </ul>
359 </div>
360
361 <div class="card">
362 <h2>Debug Information</h2>
363 <p><strong>Plugin File:</strong> <?php echo esc_html(__FILE__); ?></p>
364 <p><strong>Plugin Folder:</strong> test-telemetry-plugin</p>
365 <p><strong>Plugin Version:</strong> 1.0.0</p>
366 <p><strong>SDK Loaded:</strong> <?php echo class_exists('LinnoSDK\Telemetry\Client') ? ' Yes' : ' No'; ?></p>
367 <?php
368 if ($test_telemetry_client instanceof Client): ?>
369 <p style="color: green;"><strong>✓ Telemetry Client Initialized</strong></p>
370 <p><strong>Plugin Slug:</strong> <?php echo esc_html($test_telemetry_client->get_slug()); ?></p>
371 <p><strong>Text Domain:</strong> <?php echo esc_html($test_telemetry_client->get_text_domain()); ?></p>
372 <p><strong>Opt-in Option Key:</strong> <code><?php echo esc_html($test_telemetry_client->get_optin_key()); ?></code></p>
373 <p><strong>Opt-in Status:</strong> <?php
374 $opt_in_key = $test_telemetry_client->get_optin_key();
375 $opt_in = get_option($opt_in_key, 'no');
376 echo $opt_in === 'yes' ? '<span style="color: green;"> Enabled</span>' : '<span style="color: red;"> Disabled</span>';
377 ?></p>
378 <p><strong>Next Queue Processing Cron:</strong> <code><?php echo esc_html($test_telemetry_client->get_cron_hook()); ?></code></p>
379 <?php else: ?>
380 <p style="color: red;"><strong>✗ Telemetry Client Not Initialized</strong></p>
381 <?php endif; ?>
382 </div>
383 </div>
384
385 <style>
386 .card {
387 background: #fff;
388 border: 1px solid #ccd0d4;
389 border-radius: 4px;
390 padding: 20px;
391 margin: 20px 0;
392 box-shadow: 0 1px 1px rgba(0,0,0,.04);
393 }
394 .card h2 {
395 margin-top: 0;
396 border-bottom: 1px solid #eee;
397 padding-bottom: 10px;
398 }
399 </style>
400 <?php
401 }
402
403 /**
404 * Customize the telemetry report interval for testing
405 *
406 * @param string $interval Default interval
407 * @return string Modified interval
408 * @since 1.0.0
409 */
410 function test_telemetry_custom_interval($interval) {
411 // Change to 'hourly' for faster testing, or keep 'weekly' for production
412 return 'weekly';
413 }
414 add_filter('test-telemetry-plugin_telemetry_report_interval', 'test_telemetry_custom_interval');
415
416 /**
417 * Add custom system info for testing
418 *
419 * @param array $info System information array
420 * @return array Modified system information
421 * @since 1.0.0
422 */
423 function test_telemetry_custom_system_info($info) {
424 $info['test_plugin_active'] = true;
425 $info['active_theme'] = wp_get_theme()->get('Name');
426 return $info;
427 }
428 add_filter($test_telemetry_client->get_slug() . '_telemetry_system_info', 'test_telemetry_custom_system_info');
429