PluginProbe
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment / 3.1.5
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment v3.1.5
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.5, at Inc/Core/UsageTracking/PluginData.php

387 lines 11.3 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.5 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 * Get total view-through revenue across all campaigns
57 * View-through revenue is when someone views a campaign and purchases later without converting
58 *
59 * @return float
60 */
61 public function getViewThroughRevenue()
62 {
63 return $this->getRevenueBySource('impression');
64 }
65
66 /**
67 * Get total click-through (conversion-through) revenue across all campaigns
68 * Click-through revenue is when someone views a campaign, converts through it, and then purchases
69 *
70 * @return float
71 */
72 public function getClickThroughRevenue()
73 {
74 return $this->getRevenueBySource('conversion');
75 }
76
77 /**
78 * Get cached revenue totals by attribution source
79 * Uses a single optimized query and caches results
80 *
81 * @param string $source Attribution source ('impression' or 'conversion')
82 * @return float
83 */
84 private function getRevenueBySource($source)
85 {
86 // Check cache first
87 $cache_key = "firebox_revenue_totals_{$source}";
88 $cached_result = wp_cache_get($cache_key, 'firebox_revenue');
89
90 if ($cached_result !== false)
91 {
92 return (float) $cached_result;
93 }
94
95 // Get revenue data with single query
96 $revenue_data = $this->getCachedRevenueData();
97
98 $total_revenue = 0.0;
99
100 foreach ($revenue_data as $row)
101 {
102 if ($row->event_source !== $source || !$row->order_id || !$row->order_type)
103 {
104 continue;
105 }
106
107 $total_revenue += $this->getOrderTotalCached($row->order_id, $row->order_type);
108 }
109
110 // Cache result for 1 hour
111 wp_cache_set($cache_key, $total_revenue, 'firebox_revenue', HOUR_IN_SECONDS);
112
113 return $total_revenue;
114 }
115
116 /**
117 * Get all revenue data with a single optimized query and cache it
118 *
119 * @return array
120 */
121 private function getCachedRevenueData()
122 {
123 $cache_key = 'firebox_all_revenue_data';
124 $cached_results = wp_cache_get($cache_key, 'firebox_revenue');
125
126 if ($cached_results === false)
127 {
128 global $wpdb;
129 $table_name = $wpdb->prefix . 'firebox_logs_details';
130
131 $query = "
132 SELECT
133 event_source,
134 JSON_UNQUOTE(JSON_EXTRACT(event_label, '$.order_id')) AS order_id,
135 JSON_UNQUOTE(JSON_EXTRACT(event_label, '$.order_type')) AS order_type
136 FROM {$table_name}
137 WHERE event = 'revenue'
138 AND event_source IN ('impression', 'conversion')
139 AND JSON_VALID(event_label)
140 AND JSON_EXTRACT(event_label, '$.order_id') IS NOT NULL
141 ";
142
143 $cached_results = $wpdb->get_results($query);
144 if (!is_array($cached_results))
145 {
146 $cached_results = [];
147 }
148
149 // Cache for 1 hour
150 wp_cache_set($cache_key, $cached_results, 'firebox_revenue', HOUR_IN_SECONDS);
151 }
152
153 return $cached_results;
154 }
155
156 /**
157 * Get order total with caching to avoid duplicate queries
158 *
159 * @param string $order_id
160 * @param string $order_type
161 * @return float
162 */
163 private function getOrderTotalCached($order_id, $order_type)
164 {
165 if (!$order_id || !$order_type)
166 {
167 return 0.0;
168 }
169
170 $cache_key = "firebox_order_total_{$order_type}_{$order_id}";
171 $cached_total = wp_cache_get($cache_key, 'firebox_orders');
172
173 if ($cached_total !== false)
174 {
175 return (float) $cached_total;
176 }
177
178 $total = 0.0;
179 if (class_exists('\FireBox\Core\RevenueAttribution\OrderHelper'))
180 {
181 $total = \FireBox\Core\RevenueAttribution\OrderHelper::getOrderTotal($order_id, $order_type);
182 }
183
184 // Cache for 6 hours (orders don't change frequently)
185 wp_cache_set($cache_key, $total, 'firebox_orders', 6 * HOUR_IN_SECONDS);
186
187 return (float) $total;
188 }
189
190 public function getTotalsBySetting($setting_name = '', $setting_value = '')
191 {
192 if (!$setting_name || !$setting_value)
193 {
194 return;
195 }
196
197 $posts = $this->getCachedCampaigns();
198
199 $count = 0;
200 foreach ($posts as $post)
201 {
202 $tmp_setting_name = $setting_name;
203 $tmp_setting_value = $setting_value;
204
205 $meta = maybe_unserialize($post->meta_value);
206
207 if (strpos($setting_name, '.') !== false)
208 {
209 $keys = explode('.', $setting_name);
210
211 $meta = isset($meta[$keys[0]]) && is_array($meta[$keys[0]]) ? $meta[$keys[0]] : false;
212
213 if (!$meta)
214 {
215 continue;
216 }
217
218 $tmp_setting_name = $keys[1];
219 }
220
221 if (isset($meta[$tmp_setting_name]))
222 {
223 if (strpos($tmp_setting_value, 'cond:') === 0)
224 {
225 $condition = substr($tmp_setting_value, 5);
226 switch ($condition)
227 {
228 case 'not:none':
229 if ($meta[$tmp_setting_name] !== 'none')
230 {
231 $count++;
232 }
233 break;
234 case 'not:empty':
235 if (!empty($meta[$tmp_setting_name]) && !is_null($meta[$tmp_setting_name]))
236 {
237 $count++;
238 }
239 break;
240 case 'not:emptyArray':
241 if (is_array($meta[$tmp_setting_name]) && count($meta[$tmp_setting_name]))
242 {
243 $count++;
244 }
245 break;
246 }
247 }
248 else if ($tmp_setting_value === 'boolean')
249 {
250 // Check if the value is a boolean
251 if ((is_bool($meta[$tmp_setting_name]) && $meta[$tmp_setting_name]) || $meta[$tmp_setting_name] === '1')
252 {
253 $count++;
254 }
255 }
256
257 // Equal comparison
258 if ($meta[$tmp_setting_name] === $tmp_setting_value)
259 {
260 $count++;
261 }
262 // In array comparison
263 else if (is_array($meta[$tmp_setting_name]) && in_array($tmp_setting_value, $meta[$tmp_setting_name]))
264 {
265 $count++;
266 }
267 }
268 }
269
270 return $count;
271 }
272
273 public function getTotalsByCondition($condition = '')
274 {
275 if (!$condition)
276 {
277 return;
278 }
279
280 $posts = $this->getCachedCampaigns();
281
282 $count = 0;
283 foreach ($posts as $post)
284 {
285 $meta = maybe_unserialize($post->meta_value);
286
287 if (!isset($meta['rules']))
288 {
289 continue;
290 }
291
292 if (!$rules = $meta['rules'])
293 {
294 continue;
295 }
296
297 if (is_string($rules))
298 {
299 $rules = json_decode($rules, true);
300 }
301
302 if (!is_array($rules))
303 {
304 continue;
305 }
306
307 foreach ($rules as $key => $group)
308 {
309 if (!isset($group['rules']) || !is_array($group['rules']))
310 {
311 continue;
312 }
313
314 foreach ($group['rules'] as $groupRule)
315 {
316 if (!isset($groupRule['name']))
317 {
318 continue;
319 }
320
321 $groupName = str_replace('\\\\', '\\', $groupRule['name']);
322
323 if ($groupName === $condition)
324 {
325 $count++;
326 }
327 }
328 }
329 }
330
331 return $count;
332 }
333
334 public function getDimensionsData()
335 {
336 $posts = $this->getCachedCampaigns();
337 $dimensions = [];
338
339 foreach ($posts as $post)
340 {
341 $meta = maybe_unserialize($post->meta_value);
342
343 $width = isset($meta['width_control']['width']['desktop']['value']) ? $meta['width_control']['width']['desktop']['value'] : '';
344 $height = isset($meta['height_control']['height']['desktop']['value']) && $meta['height_control']['height']['desktop']['value'] ? $meta['height_control']['height']['desktop']['value'] : 'auto';
345
346 if (!$width || !$height)
347 {
348 continue;
349 }
350
351 // Format: "400xauto" or "500x300"
352 $dimension_key = $width . 'x' . $height;
353
354 if (!isset($dimensions[$dimension_key]))
355 {
356 $dimensions[$dimension_key] = 0;
357 }
358
359 $dimensions[$dimension_key]++;
360 }
361
362 return $dimensions;
363 }
364
365 private function getCachedCampaigns()
366 {
367 global $wpdb;
368 $cache_key = 'firebox_campaigns_for_search';
369 $cached_results = wp_cache_get($cache_key);
370
371 if ($cached_results === false)
372 {
373 $query = "
374 SELECT p.ID, pm.meta_value
375 FROM {$wpdb->posts} p
376 LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
377 WHERE p.post_type = 'firebox'
378 AND p.post_status IN ('draft', 'trash', 'publish')
379 AND (pm.meta_key = 'fpframework_meta_settings' OR pm.meta_key = 'firebox_meta')
380 ";
381 $cached_results = $wpdb->get_results($query);
382 wp_cache_set($cache_key, $cached_results, 'firebox', 6 * DAY_IN_SECONDS + 12 * HOUR_IN_SECONDS);
383 }
384
385 return $cached_results;
386 }
387 }