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

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