PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / 3.2.13
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar v3.2.13
3.3.1 3.3.0 3.2.14 3.2.13 3.2.12 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 trunk 0.2.5.5 0.2.5.6 0.2.5.7 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 All 156 releases
notificationx / includes / Core / UsageTracker.php

UsageTracker.php in NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar 3.2.13, at includes/Core/UsageTracker.php

158 lines 5.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Usage Tracker Class File.
4 *
5 * Collects anonymous NotificationX usage statistics — which notification
6 * types and which data sources customers are using — and merges them into the
7 * WP Insights tracking payload that is sent (once per day, after user opt-in)
8 * to send.wpinsight.com via {@see \NotificationX\Admin\PluginInsights}.
9 *
10 * The data is attached to the payload's `optional_data` key. The wpinsights
11 * app renders `optional_data` as a flat `key => value` table (nested arrays
12 * show up as "[object Object]"), so every value here is a scalar count and the
13 * type/source grouping is expressed through key prefixes:
14 *
15 * created_notifications => total notifications
16 * notificationx-total-active => total enabled notifications
17 * notificationx-total-inactive => total disabled notifications
18 * notificationx-type-<slug> => count of notifications of that type
19 * notificationx-source-<slug> => count of notifications using that source
20 * notificationx-active-type-<slug> => count of *enabled* notifications of that type
21 * notificationx-active-source-<slug> => count of *enabled* notifications using that source
22 *
23 * No additional cron is required: PluginInsights already schedules a daily
24 * `put_do_weekly_action` event whose payload we enrich here through the
25 * `nx_plugin_usage_tracker_data` filter.
26 *
27 * @package NotificationX\Core
28 * @since 3.3.0
29 */
30
31 namespace NotificationX\Core;
32
33 use NotificationX\GetInstance;
34
35 /**
36 * UsageTracker Class.
37 *
38 * @method static UsageTracker get_instance($args = null)
39 */
40 class UsageTracker {
41
42 use GetInstance;
43
44 /**
45 * Prefix applied to every key inside optional_data so NotificationX rows
46 * are easy to identify in the wpinsights app.
47 */
48 const KEY_PREFIX = 'notificationx-';
49
50 /**
51 * Bootstrap the tracker by hooking into the insights payload.
52 */
53 public function __construct() {
54 add_filter( 'nx_plugin_usage_tracker_data', [ $this, 'add_usage_data' ], 10, 1 );
55 }
56
57 /**
58 * Merge NotificationX usage counts into the insights payload's
59 * `optional_data` (the mapping WP Insights renders in the app).
60 *
61 * @param array $body The tracking data collected by PluginInsights.
62 * @return array
63 */
64 public function add_usage_data( $body ) {
65 $optional = ( isset( $body['optional_data'] ) && is_array( $body['optional_data'] ) )
66 ? $body['optional_data']
67 : [];
68
69 $body['optional_data'] = array_merge( $optional, $this->get_optional_data() );
70
71 return $body;
72 }
73
74 /**
75 * Build the grouped `optional_data`: totals plus per-type and per-source
76 * counts, split into "created" (all) and "active" (enabled-only) groups.
77 *
78 * @return array
79 */
80 public function get_optional_data() {
81 $db = Database::get_instance();
82
83 // Grouped counts, e.g. [ 'woocommerce_sales' => 5, ... ].
84 $by_type = $this->normalize_counts( $db->get_source_count( Database::$table_posts, 'type' ) );
85 $by_source = $this->normalize_counts( $db->get_source_count( Database::$table_posts, 'source' ) );
86 $by_type_active = $this->normalize_counts( $db->get_source_count( Database::$table_posts, 'type', [ 'enabled' => true ] ) );
87 $by_src_active = $this->normalize_counts( $db->get_source_count( Database::$table_posts, 'source', [ 'enabled' => true ] ) );
88
89 $total = array_sum( $by_type );
90 $total_active = array_sum( $by_type_active );
91
92 // The wpinsights app renders optional_data as a flat key => value
93 // table; nested arrays display as "[object Object]". So everything is
94 // flattened to top-level scalar keys, with descriptive prefixes that
95 // keep the type/source grouping readable by name.
96 $data = [
97 'created_notifications' => $total,
98 self::KEY_PREFIX . 'total-active' => $total_active,
99 self::KEY_PREFIX . 'total-inactive' => max( 0, $total - $total_active ),
100 ];
101
102 $data = array_merge(
103 $data,
104 $this->prefix_keys( self::KEY_PREFIX . 'type-', $by_type ),
105 $this->prefix_keys( self::KEY_PREFIX . 'source-', $by_source ),
106 $this->prefix_keys( self::KEY_PREFIX . 'active-type-', $by_type_active ),
107 $this->prefix_keys( self::KEY_PREFIX . 'active-source-', $by_src_active )
108 );
109
110 /**
111 * Filter the final NotificationX optional_data before it is attached
112 * to the tracking payload.
113 *
114 * @since 3.3.0
115 * @param array<string,int> $data Flat usage count map.
116 */
117 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context.
118 return apply_filters( 'nx_usage_tracker_data', $data );
119 }
120
121 /**
122 * Re-key a grouped-count set with a prefixed slug key.
123 *
124 * @param string $prefix Key prefix, e.g. 'notificationx-type-'.
125 * @param array $counts Counts keyed by slug.
126 * @return array<string,int>
127 */
128 protected function prefix_keys( $prefix, $counts ) {
129 $result = [];
130 foreach ( $counts as $slug => $count ) {
131 $result[ $prefix . $slug ] = $count;
132 }
133 return $result;
134 }
135
136 /**
137 * Normalize a grouped-count result: drop empty keys, cast counts to int
138 * and sort descending so the most-used entry comes first.
139 *
140 * @param array $counts Raw counts keyed by slug.
141 * @return array<string,int>
142 */
143 protected function normalize_counts( $counts ) {
144 $result = [];
145 if ( ! is_array( $counts ) ) {
146 return $result;
147 }
148 foreach ( $counts as $key => $value ) {
149 if ( '' === $key || null === $key ) {
150 continue;
151 }
152 $result[ $key ] = (int) $value;
153 }
154 arsort( $result );
155 return $result;
156 }
157 }
158