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 / Helpers / BoxHelper.php

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

533 lines 10.9 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\Helpers;
13
14 if (!defined('ABSPATH'))
15 {
16 exit; // Exit if accessed directly.
17 }
18
19 use FPFramework\Libs\Registry;
20
21 class BoxHelper
22 {
23 /**
24 * Get box meta
25 *
26 * @param int $id
27 *
28 * @return array
29 */
30 public static function getMeta($id)
31 {
32 $meta = get_post_meta($id, 'firebox_meta', false);
33 $meta = isset($meta[0]) && is_array($meta[0]) ? $meta[0] : [];
34
35 return $meta;
36 }
37
38 /**
39 * Whether any of the given campaigns uses session-dependent behavior:
40 * the Pageviews/Time on Site display conditions, or an impressions
41 * limit scoped to the visitor's session (fpfsid).
42 *
43 * These are stamped and evaluated against JS-set session cookies, so
44 * when in use the frontend runtime must be enqueued on every page.
45 * Skipped entirely when no campaign needs them, so other sites load no
46 * extra JS or cookies.
47 *
48 * @param \WP_Query $boxes
49 *
50 * @return bool
51 */
52 public static function sessionConditionsInUse($boxes)
53 {
54 if (!$boxes || empty($boxes->posts))
55 {
56 return false;
57 }
58
59 foreach ($boxes->posts as $box)
60 {
61 $meta = self::getMeta($box->ID);
62
63 if (!$meta)
64 {
65 continue;
66 }
67
68 // Impressions limit scoped to the browser session
69 $impressionsPeriod = isset($meta['assign_impressions_param_type']) ? $meta['assign_impressions_param_type'] : '';
70
71 if ($impressionsPeriod === 'custom')
72 {
73 $impressionsPeriod = isset($meta['assign_impressions_param_custom_period']) ? $meta['assign_impressions_param_custom_period'] : '';
74 }
75
76 if ($impressionsPeriod === 'session')
77 {
78 return true;
79 }
80
81 // Session-dependent display conditions
82 $metaJson = wp_json_encode($meta);
83
84 if (strpos($metaJson, 'Pageviews') !== false || strpos($metaJson, 'TimeOnSite') !== false)
85 {
86 return true;
87 }
88 }
89
90 return false;
91 }
92
93 /**
94 * Gets all Boxes.
95 *
96 * @param array $status
97 * @param int $limit
98 *
99 * @return array
100 */
101 public static function getAllBoxes($status = ['publish'], $limit = -1)
102 {
103 // cache key
104 $hash = md5('firebox_getAllBoxes_' . implode(',', $status) . '_' . (int) $limit);
105
106 // check cache
107 if ($data = wp_cache_get($hash, 'firebox'))
108 {
109 return $data;
110 }
111
112 $args = [
113 'post_status' => $status,
114 'post_type' => 'firebox',
115 'posts_per_page' => $limit,
116 'no_found_rows' => true,
117 'update_post_term_cache' => false,
118 'cache_results' => true
119 ];
120
121 // Get the query.
122 $query = new \WP_Query($args);
123
124 wp_reset_postdata();
125
126 // set cache (short TTL: box publish state changes should reflect reasonably promptly)
127 wp_cache_set($hash, $query, 'firebox', 5 * MINUTE_IN_SECONDS);
128
129 return $query;
130 }
131
132 /**
133 * Retrieves all boxes in a key => value array of ID => title
134 *
135 * @return array
136 */
137 public static function getAllBoxesParsedByKeyValue()
138 {
139 if (!$boxes = self::getAllBoxes())
140 {
141 return [];
142 }
143
144 return self::produceKeyValueBoxes($boxes->posts);
145 }
146
147 /**
148 * Produce a key,value pair of boxes containg their ID,title
149 *
150 * @return array
151 */
152 public static function produceKeyValueBoxes($boxes)
153 {
154 if (!$boxes)
155 {
156 return [];
157 }
158
159 $data = [];
160
161 foreach ($boxes as $key => $box)
162 {
163 $data[$box->ID] = $box->post_title;
164 }
165
166 return $data;
167 }
168
169 /**
170 * Gets all published Boxes except the given id.
171 * The array structure is [ID, title] to properly appear in a Dropdown field.
172 *
173 * @param integer $id
174 *
175 * @return array
176 */
177 public static function getAllMirrorBoxesExceptID($id)
178 {
179 if (!$id)
180 {
181 return [];
182 }
183
184 $boxes = firebox()->tables->box->getResults([
185 'where' => [
186 'ID' => ' NOT IN (' . absint($id) . ')',
187 'post_status' => " = 'publish'",
188 'post_type' => " = 'firebox'"
189 ]
190 ]);
191
192 $boxes_parsed = [];
193
194 foreach ($boxes as $key => $p)
195 {
196 $boxes_parsed[$p->ID] = $p->post_title . ' (' . $p->ID . ')';
197 }
198
199 return $boxes_parsed;
200 }
201
202 /**
203 * Get box data
204 *
205 * @param int $box
206 *
207 * @return array
208 */
209 public static function getBoxData($box)
210 {
211 if (!$box)
212 {
213 return false;
214 }
215
216 $box = (int) $box;
217
218 $box = firebox()->tables->box->getResults([
219 'where' => [
220 'ID' => " = '" . absint($box) . "'"
221 ]
222 ]);
223
224 return isset($box[0]) ? $box[0] : [];
225 }
226
227 /**
228 * Checks whether the box exist
229 *
230 * @param int $box
231 *
232 * @return boolean
233 */
234 public static function boxExist($box)
235 {
236 if (!$box)
237 {
238 return false;
239 }
240
241 $box = (int) $box;
242
243 $box = firebox()->tables->box->getResults([
244 'where' => [
245 'ID' => " = '" . absint($box) . "'"
246 ]
247 ]);
248
249 if (!$box)
250 {
251 return false;
252 }
253
254 return true;
255 }
256
257 /**
258 * Gets boxes in a [id, title] pair from a list of Box IDs
259 *
260 * @param array $items
261 *
262 * @return array
263 */
264 public static function getSelectedSearchItems($items)
265 {
266 $boxes = firebox()->tables->box->getResults([
267 'where' => [
268 'ID' => ' IN(' . implode(',', array_map('intval', $items)) . ')',
269 'post_status' => " = 'publish'",
270 'post_type' => " = 'firebox'"
271 ]
272 ]);
273
274 $boxes_parsed = [];
275
276 foreach ($boxes as $key => $p)
277 {
278 $boxes_parsed[] = [
279 'id' => $p->ID,
280 'title' => $p->post_title
281 ];
282 }
283
284 return $boxes_parsed;
285 }
286
287 /**
288 * Gets Settings Data
289 *
290 * @return array
291 */
292 public static function getParams()
293 {
294 // cache key
295 $cache_key = md5('fboxSettings');
296
297 // check cache
298 if ($params = wp_cache_get($cache_key, 'firebox'))
299 {
300 return $params;
301 }
302
303 // get params
304 $params = get_option('firebox_settings');
305
306 // set cache
307 wp_cache_set($cache_key, $params, 'firebox', 5 * MINUTE_IN_SECONDS);
308
309 return $params;
310 }
311
312 /**
313 * Duplicates a box
314 *
315 * @param integer $box_id
316 *
317 * @return bool
318 */
319 public static function duplicateBox($box_id)
320 {
321 // get box
322 $box = firebox()->tables->box->getResults([
323 'where' => [
324 'ID' => " = '" . absint($box_id) . "'",
325 'post_status' => " = '" . sanitize_key(get_post_status($box_id)) . "'",
326 'post_type' => " = 'firebox'"
327 ],
328 'limit' => 1
329 ]);
330
331 if (empty($box))
332 {
333 return false;
334 }
335
336 // reset box ID and make it a draft
337 $box = $box[0];
338 $box->ID = '';
339 $box->post_title = 'Copy of ' . $box->post_title;
340 $box->post_status = 'draft';
341
342 $factory = new \FPFramework\Base\Factory();
343
344 $tz = wp_timezone();
345 $date_without_tz = $factory->getDate();
346 $date_with_tz = $factory->getDate()->setTimezone($tz);
347
348 $box->post_date = $date_with_tz->format('Y-m-d H:i:s');
349 $box->post_date_gmt = $date_without_tz->format('Y-m-d H:i:s');
350
351 Form\Form::ensureUniqueFormIDs($box->post_content);
352
353 // get meta options
354 $meta = self::getMeta($box_id);
355
356 // insert new box
357 $new_box_id = firebox()->tables->box->insert($box);
358
359 // add meta options for new box
360 // TODO: In the future, use "firebox_meta". This is a temporary fix for backwards compatibility.
361 $checkMeta = (array) $meta;
362 $meta_key = isset($checkMeta['width']) ? 'firebox_meta' : 'fpframework_meta_settings';
363 update_post_meta($new_box_id, $meta_key, wp_slash($meta));
364
365 return $new_box_id;
366 }
367
368 /**
369 * Reset Box Stats
370 *
371 * @param array $box_ids
372 *
373 * @return void
374 */
375 public static function resetBoxStats($box_ids)
376 {
377 $logs_table = firebox()->tables->boxlog->getFullTableName();
378 $logs_details_table = firebox()->tables->boxlogdetails->getFullTableName();
379
380 // delete box logs details
381 firebox()->tables->boxlogdetails->executeRaw("DELETE FROM `$logs_details_table` WHERE log_id IN (SELECT id FROM `$logs_table` WHERE box IN (" . implode(",", $box_ids) . "))");
382
383 // delete box logs
384 firebox()->tables->boxlog->deleteRaw('WHERE box IN (' . implode(',', $box_ids) . ')');
385 }
386
387 /**
388 * Builds the export payload (boxes + meta) and a suggested filename for the given box ids,
389 * without emitting any headers or output. Shared by exportBoxes() (legacy file-download
390 * action) and the Campaigns REST export endpoint.
391 *
392 * @param array $box_ids
393 *
394 * @return array|null ['filename' => string, 'exported' => array] or null if no boxes matched
395 */
396 public static function getExportPayload($box_ids)
397 {
398 // get boxes
399 $boxes = firebox()->tables->box->getResults([
400 'where' => [
401 'ID' => ' IN (' . implode(',', array_map('intval', $box_ids)) . ')',
402 'post_type' => " = 'firebox'"
403 ]
404 ]);
405
406 $boxes = (array) $boxes;
407
408 if (!count($boxes))
409 {
410 return null;
411 }
412
413 $exported = [];
414
415 $filename = firebox()->_('FB_PLUGIN_NAME') . ' Items';
416
417 // name for 1 box
418 if (count($boxes) == 1)
419 {
420 $name = mb_strtolower(html_entity_decode($boxes['0']->post_title));
421 $name = preg_replace('#[^a-z0-9_-]#', '_', $name);
422 $name = trim(preg_replace('#__+#', '_', $name), '_-');
423
424 $filename = firebox()->_('FB_PLUGIN_NAME') . ' Item (' . $name . ')';
425 }
426
427 foreach ($boxes as $box)
428 {
429 $meta = self::getMeta($box->ID);
430
431 $exported[] = [
432 'box' => $box,
433 'meta' => $meta
434 ];
435 }
436
437 return [
438 'filename' => $filename,
439 'exported' => $exported,
440 ];
441 }
442
443 /**
444 * Exports boxes
445 *
446 * @param array $box_ids
447 *
448 * @return string
449 */
450 public static function exportBoxes($box_ids)
451 {
452 if (!$payload = self::getExportPayload($box_ids))
453 {
454 return;
455 }
456
457 $filename = $payload['filename'];
458 $exported = $payload['exported'];
459
460 // SET DOCUMENT HEADER
461 $userAgent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
462 if (preg_match('#Opera(/| )([0-9].[0-9]{1,2})#', $userAgent))
463 {
464 $UserBrowser = "Opera";
465 }
466 elseif (preg_match('#MSIE ([0-9].[0-9]{1,2})#', $userAgent))
467 {
468 $UserBrowser = "IE";
469 }
470 else
471 {
472 $UserBrowser = '';
473 }
474 $mime_type = ($UserBrowser == 'IE' || $UserBrowser == 'Opera') ? 'application/octetstream' : 'application/octet-stream';
475 @ob_end_clean();
476 ob_start();
477
478 header('Content-Type: ' . $mime_type);
479 header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
480
481 if ($UserBrowser == 'IE')
482 {
483 header('Content-Disposition: inline; filename="' . $filename . '.fbox"');
484 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
485 header('Pragma: public');
486 }
487 else
488 {
489 header('Content-Disposition: attachment; filename="' . $filename . '.fbox"');
490 header('Pragma: no-cache');
491 }
492
493 // PRINT STRING
494 echo wp_json_encode($exported);
495
496 if (ob_get_level())
497 {
498 @ob_end_flush();
499 }
500 die();
501 }
502
503 /**
504 * Returns the last date viewed of a campaign.
505 *
506 * @param int $id
507 *
508 * @return string
509 */
510 public static function getCampaignLastDateViewed($id = null)
511 {
512 if (!$id)
513 {
514 return;
515 }
516
517 $last_date_viewed = firebox()->tables->boxlog->getResults([
518 'select' => [
519 'date as last_date_viewed'
520 ],
521 'where' => [
522 'box' => ' = ' . absint($id),
523 ],
524 'orderby' => ' date desc',
525 'limit' => 1
526 ]);
527
528 return isset($last_date_viewed[0]->last_date_viewed) ? get_date_from_gmt($last_date_viewed[0]->last_date_viewed) : null;
529 }
530
531
532 }
533