PluginProbe
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment / 3.1.9
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment v3.1.9
3.1.13 3.1.12 3.1.11 3.1.10 3.1.9 3.1.8 3.1.7 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 All 122 releases
firebox / Inc / Core / UsageTracking / PluginData.php

PluginData.php in FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment 3.1.9, at Inc/Core/UsageTracking/PluginData.php

422 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package FireBox
4 * @version 3.1.9 Free
5 *
6 * @author FirePlugins <info@fireplugins.com>
7 * @link https://www.fireplugins.com
8 * @copyright Copyright © 2026 FirePlugins All Rights Reserved
9 * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
10 */
11
12 namespace FireBox\Core\UsageTracking;
13
14 if (!defined('ABSPATH'))
15 {
16 exit; // Exit if accessed directly.
17 }
18
19 class PluginData
20 {
21 public function getViews()
22 {
23 global $wpdb;
24 $table_name = $wpdb->prefix . 'firebox_logs';
25 $total_views = $wpdb->get_var("SELECT COUNT(id) FROM $table_name");
26 return $total_views;
27 }
28
29 public function getCampaigns($status = '')
30 {
31 if (!$status)
32 {
33 return;
34 }
35
36 global $wpdb;
37 $query = "
38 SELECT COUNT(id) as total
39 FROM {$wpdb->posts}
40 WHERE post_type = 'firebox'
41 AND post_status IN ('" . $status . "')
42 ";
43 $results = $wpdb->get_var($query);
44 return $results;
45 }
46
47 public function getSubmissions()
48 {
49 global $wpdb;
50 $table_name = $wpdb->prefix . 'firebox_submissions';
51 $total_submissions = $wpdb->get_var("SELECT COUNT(id) FROM $table_name");
52 return $total_submissions;
53 }
54
55 /**
56 * Returns one-time duration (in seconds) from tracking start to first campaign draft.
57 *
58 * @return int|null
59 */
60 public function getTimeToFirstCampaignDraft()
61 {
62 $duration = get_option('firebox_time_to_first_campaign_draft_seconds', null);
63
64 if ($duration === null || $duration === '')
65 {
66 return null;
67 }
68
69 return (int) $duration;
70 }
71
72 /**
73 * Returns one-time duration (in seconds) from tracking start to first campaign publish.
74 *
75 * @return int|null
76 */
77 public function getTimeToFirstCampaignPublish()
78 {
79 $duration = get_option('firebox_time_to_first_campaign_publish_seconds', null);
80
81 if ($duration === null || $duration === '')
82 {
83 return null;
84 }
85
86 return (int) $duration;
87 }
88
89 /**
90 * Get total view-through revenue across all campaigns
91 * View-through revenue is when someone views a campaign and purchases later without converting
92 *
93 * @return float
94 */
95 public function getViewThroughRevenue()
96 {
97 return $this->getRevenueBySource('impression');
98 }
99
100 /**
101 * Get total click-through (conversion-through) revenue across all campaigns
102 * Click-through revenue is when someone views a campaign, converts through it, and then purchases
103 *
104 * @return float
105 */
106 public function getClickThroughRevenue()
107 {
108 return $this->getRevenueBySource('conversion');
109 }
110
111 /**
112 * Get cached revenue totals by attribution source
113 * Uses a single optimized query and caches results
114 *
115 * @param string $source Attribution source ('impression' or 'conversion')
116 * @return float
117 */
118 private function getRevenueBySource($source)
119 {
120 // Check cache first
121 $cache_key = "firebox_revenue_totals_{$source}";
122 $cached_result = wp_cache_get($cache_key, 'firebox_revenue');
123
124 if ($cached_result !== false)
125 {
126 return (float) $cached_result;
127 }
128
129 // Get revenue data with single query
130 $revenue_data = $this->getCachedRevenueData();
131
132 $total_revenue = 0.0;
133
134 foreach ($revenue_data as $row)
135 {
136 if ($row->event_source !== $source || !$row->order_id || !$row->order_type)
137 {
138 continue;
139 }
140
141 $total_revenue += $this->getOrderTotalCached($row->order_id, $row->order_type);
142 }
143
144 // Cache result for 1 hour
145 wp_cache_set($cache_key, $total_revenue, 'firebox_revenue', HOUR_IN_SECONDS);
146
147 return $total_revenue;
148 }
149
150 /**
151 * Get all revenue data with a single optimized query and cache it
152 *
153 * @return array
154 */
155 private function getCachedRevenueData()
156 {
157 $cache_key = 'firebox_all_revenue_data';
158 $cached_results = wp_cache_get($cache_key, 'firebox_revenue');
159
160 if ($cached_results === false)
161 {
162 global $wpdb;
163 $table_name = $wpdb->prefix . 'firebox_logs_details';
164
165 $query = "
166 SELECT
167 event_source,
168 JSON_UNQUOTE(JSON_EXTRACT(event_label, '$.order_id')) AS order_id,
169 JSON_UNQUOTE(JSON_EXTRACT(event_label, '$.order_type')) AS order_type
170 FROM {$table_name}
171 WHERE event = 'revenue'
172 AND event_source IN ('impression', 'conversion')
173 AND JSON_VALID(event_label)
174 AND JSON_EXTRACT(event_label, '$.order_id') IS NOT NULL
175 ";
176
177 $cached_results = $wpdb->get_results($query);
178 if (!is_array($cached_results))
179 {
180 $cached_results = [];
181 }
182
183 // Cache for 1 hour
184 wp_cache_set($cache_key, $cached_results, 'firebox_revenue', HOUR_IN_SECONDS);
185 }
186
187 return $cached_results;
188 }
189
190 /**
191 * Get order total with caching to avoid duplicate queries
192 *
193 * @param string $order_id
194 * @param string $order_type
195 * @return float
196 */
197 private function getOrderTotalCached($order_id, $order_type)
198 {
199 if (!$order_id || !$order_type)
200 {
201 return 0.0;
202 }
203
204 $cache_key = "firebox_order_total_{$order_type}_{$order_id}";
205 $cached_total = wp_cache_get($cache_key, 'firebox_orders');
206
207 if ($cached_total !== false)
208 {
209 return (float) $cached_total;
210 }
211
212 $total = 0.0;
213 if (class_exists('\FireBox\Core\RevenueAttribution\OrderHelper'))
214 {
215 $total = \FireBox\Core\RevenueAttribution\OrderHelper::getOrderTotal($order_id, $order_type);
216 }
217
218 // Cache for 6 hours (orders don't change frequently)
219 wp_cache_set($cache_key, $total, 'firebox_orders', 6 * HOUR_IN_SECONDS);
220
221 return (float) $total;
222 }
223
224 public function getTotalsBySetting($setting_name = '', $setting_value = '')
225 {
226 if (!$setting_name || !$setting_value)
227 {
228 return;
229 }
230
231 $posts = $this->getCachedCampaigns();
232
233 $count = 0;
234 foreach ($posts as $post)
235 {
236 $tmp_setting_name = $setting_name;
237 $tmp_setting_value = $setting_value;
238
239 $meta = maybe_unserialize($post->meta_value);
240
241 if (strpos($setting_name, '.') !== false)
242 {
243 $keys = explode('.', $setting_name);
244
245 $meta = isset($meta[$keys[0]]) && is_array($meta[$keys[0]]) ? $meta[$keys[0]] : false;
246
247 if (!$meta)
248 {
249 continue;
250 }
251
252 $tmp_setting_name = $keys[1];
253 }
254
255 if (isset($meta[$tmp_setting_name]))
256 {
257 if (strpos($tmp_setting_value, 'cond:') === 0)
258 {
259 $condition = substr($tmp_setting_value, 5);
260 switch ($condition)
261 {
262 case 'not:none':
263 if ($meta[$tmp_setting_name] !== 'none')
264 {
265 $count++;
266 }
267 break;
268 case 'not:empty':
269 if (!empty($meta[$tmp_setting_name]) && !is_null($meta[$tmp_setting_name]))
270 {
271 $count++;
272 }
273 break;
274 case 'not:emptyArray':
275 if (is_array($meta[$tmp_setting_name]) && count($meta[$tmp_setting_name]))
276 {
277 $count++;
278 }
279 break;
280 }
281 }
282 else if ($tmp_setting_value === 'boolean')
283 {
284 // Check if the value is a boolean
285 if ((is_bool($meta[$tmp_setting_name]) && $meta[$tmp_setting_name]) || $meta[$tmp_setting_name] === '1')
286 {
287 $count++;
288 }
289 }
290
291 // Equal comparison
292 if ($meta[$tmp_setting_name] === $tmp_setting_value)
293 {
294 $count++;
295 }
296 // In array comparison
297 else if (is_array($meta[$tmp_setting_name]) && in_array($tmp_setting_value, $meta[$tmp_setting_name]))
298 {
299 $count++;
300 }
301 }
302 }
303
304 return $count;
305 }
306
307 public function getTotalsByCondition($condition = '')
308 {
309 if (!$condition)
310 {
311 return;
312 }
313
314 $posts = $this->getCachedCampaigns();
315
316 $count = 0;
317 foreach ($posts as $post)
318 {
319 $meta = maybe_unserialize($post->meta_value);
320
321 if (!isset($meta['rules']))
322 {
323 continue;
324 }
325
326 if (!$rules = $meta['rules'])
327 {
328 continue;
329 }
330
331 if (is_string($rules))
332 {
333 $rules = json_decode($rules, true);
334 }
335
336 if (!is_array($rules))
337 {
338 continue;
339 }
340
341 foreach ($rules as $key => $group)
342 {
343 if (!isset($group['rules']) || !is_array($group['rules']))
344 {
345 continue;
346 }
347
348 foreach ($group['rules'] as $groupRule)
349 {
350 if (!isset($groupRule['name']))
351 {
352 continue;
353 }
354
355 $groupName = str_replace('\\\\', '\\', $groupRule['name']);
356
357 if ($groupName === $condition)
358 {
359 $count++;
360 }
361 }
362 }
363 }
364
365 return $count;
366 }
367
368 public function getDimensionsData()
369 {
370 $posts = $this->getCachedCampaigns();
371 $dimensions = [];
372
373 foreach ($posts as $post)
374 {
375 $meta = maybe_unserialize($post->meta_value);
376
377 $width = isset($meta['width_control']['width']['desktop']['value']) ? $meta['width_control']['width']['desktop']['value'] : '';
378 $height = isset($meta['height_control']['height']['desktop']['value']) && $meta['height_control']['height']['desktop']['value'] ? $meta['height_control']['height']['desktop']['value'] : 'auto';
379
380 if (!$width || !$height)
381 {
382 continue;
383 }
384
385 // Format: "400xauto" or "500x300"
386 $dimension_key = $width . 'x' . $height;
387
388 if (!isset($dimensions[$dimension_key]))
389 {
390 $dimensions[$dimension_key] = 0;
391 }
392
393 $dimensions[$dimension_key]++;
394 }
395
396 return $dimensions;
397 }
398
399 private function getCachedCampaigns()
400 {
401 global $wpdb;
402 $cache_key = 'firebox_campaigns_for_search';
403 $cached_results = wp_cache_get($cache_key);
404
405 if ($cached_results === false)
406 {
407 $query = "
408 SELECT p.ID, pm.meta_value
409 FROM {$wpdb->posts} p
410 LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
411 WHERE p.post_type = 'firebox'
412 AND p.post_status IN ('draft', 'trash', 'publish')
413 AND (pm.meta_key = 'fpframework_meta_settings' OR pm.meta_key = 'firebox_meta')
414 ";
415 $cached_results = $wpdb->get_results($query);
416 wp_cache_set($cache_key, $cached_results, 'firebox', 6 * DAY_IN_SECONDS + 12 * HOUR_IN_SECONDS);
417 }
418
419 return $cached_results;
420 }
421 }
422