PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / 3.2.11
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar v3.2.11
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.11, at includes/Core/UsageTracker.php

157 lines 5.8 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 return apply_filters( 'nx_usage_tracker_data', $data );
118 }
119
120 /**
121 * Re-key a grouped-count set with a prefixed slug key.
122 *
123 * @param string $prefix Key prefix, e.g. 'notificationx-type-'.
124 * @param array $counts Counts keyed by slug.
125 * @return array<string,int>
126 */
127 protected function prefix_keys( $prefix, $counts ) {
128 $result = [];
129 foreach ( $counts as $slug => $count ) {
130 $result[ $prefix . $slug ] = $count;
131 }
132 return $result;
133 }
134
135 /**
136 * Normalize a grouped-count result: drop empty keys, cast counts to int
137 * and sort descending so the most-used entry comes first.
138 *
139 * @param array $counts Raw counts keyed by slug.
140 * @return array<string,int>
141 */
142 protected function normalize_counts( $counts ) {
143 $result = [];
144 if ( ! is_array( $counts ) ) {
145 return $result;
146 }
147 foreach ( $counts as $key => $value ) {
148 if ( '' === $key || null === $key ) {
149 continue;
150 }
151 $result[ $key ] = (int) $value;
152 }
153 arsort( $result );
154 return $result;
155 }
156 }
157