PluginProbe
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment / 2.1.39
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment v2.1.39
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
← All changes | Inc/Core/FB/Box.php +335 -532 1.0.102.1.39 View file →
@@ -1,12 +1,12 @@
1 1 <?php
2 2 /**
3 3 * @package FireBox
4 - * @version 1.0.10 Free
4 + * @version 2.1.39 Free
5 5 *
6 6 * @author FirePlugins <info@fireplugins.com>
7 7 * @link https://www.fireplugins.com
8 - * @copyright Copyright © 2022 FirePlugins All Rights Reserved
8 + * @copyright Copyright © 2025 FirePlugins All Rights Reserved
9 9 * @license GNU GPLv3 <http://www.gnu.org/licenses/gpl.html> or later
10 10 */
11 11
12 12 namespace FireBox\Core\FB;
@@ -18,8 +18,9 @@
18 18
19 19 use FireBox\Core\Helpers\BoxHelper;
20 20 use FPFramework\Libs\Registry;
21 21 use FPFramework\Helpers\Fields\DimensionsHelper;
22 +use FPFramework\Helpers\CSS;
22 23
23 24 class Box
24 25 {
25 26 /**
@@ -29,48 +30,95 @@
29 30 */
30 31 static $loadedLocalizedScript = false;
31 32
32 33 /**
33 - * The box settings
34 + * The box.
35 + *
36 + * @param object
34 37 */
35 - private $boxSettings;
38 + private $box = null;
36 39
37 40 /**
38 - * The factory
41 + * Factory
39 42 *
40 43 * @var Factory
41 44 */
42 - protected $factory;
45 + private $factory = null;
43 46
44 - public function __construct($boxSettings = null, $factory = null)
47 + /**
48 + * FireBox settings.
49 + *
50 + * @var object
51 + */
52 + private $params = null;
53 +
54 + /**
55 + * Popup CSS.
56 + *
57 + * @var CSS
58 + */
59 + public $css = null;
60 +
61 + /**
62 + * Constructor.
63 + *
64 + * @param object $box
65 + * @param object $factory
66 + *
67 + * @return void
68 + */
69 + public function __construct($box = null, $factory = null)
45 70 {
46 - $this->init($boxSettings, $factory);
71 + if ($box)
72 + {
73 + $this->box = $this->prepareConstructorBox($box);
74 + }
75 +
76 + if (!$factory)
77 + {
78 + $factory = new \FPFramework\Base\Factory();
79 + }
80 + $this->factory = $factory;
81 +
82 + $this->params = new Registry(BoxHelper::getParams());
47 83 }
48 84
49 - public function init($boxSettings = null, $factory = null)
85 + /**
86 + * Allow to set either a box ID or box object
87 + * and we then set the box object.
88 + *
89 + * @param mixed $box
90 + *
91 + * @return object
92 + */
93 + private function prepareConstructorBox($box)
50 94 {
51 - if (!$factory)
95 + if (!is_object($box))
52 96 {
53 - $factory = new \FPFramework\Base\Factory();
97 + $box = $this->get($box);
54 98 }
55 99
56 - $this->boxSettings = $boxSettings;
57 - $this->factory = $factory;
100 + return $box;
58 101 }
59 102
60 103 /**
61 - * Gets published box.
104 + * Get a box.
62 105 *
63 - * @param integer $id
64 - * @param string $status
106 + * @param int $id
107 + * @param string $status
65 108 *
66 - * @return array
109 + * @return object
67 110 */
68 - public function get($id, $status = null)
111 + public function get($id = null, $status = null)
69 112 {
113 + if (!$id)
114 + {
115 + return;
116 + }
117 +
70 118 $payload = [
71 119 'where' => [
72 - 'ID' => ' = ' . esc_sql($id),
120 + 'ID' => ' = ' . esc_sql(intval($id)),
73 121 'post_type' => " = 'firebox'"
74 122 ]
75 123 ];
76 124
@@ -89,155 +137,135 @@
89 137 {
90 138 return [];
91 139 }
92 140
93 - $box = $box[0];
141 + $this->box = $box[0];
94 142
95 143 // get meta options for box
96 - $meta = self::getMeta($id);
97 - $box->params = new Registry($meta);
144 + $meta = \FireBox\Core\Helpers\BoxHelper::getMeta($id);
145 + $this->box->params = new Registry($meta);
98 146
99 - return $box;
147 + return $this->box;
100 148 }
101 149
102 150 /**
103 - * Get box meta
151 + * Renders the box.
104 152 *
105 - * @param int $id
106 - *
107 - * @return array
153 + * @return void
108 154 */
109 - public static function getMeta($id)
155 + public function render()
110 156 {
111 - return get_post_meta($id, 'fpframework_meta_settings', true);
157 + // Check Publishing Assignments
158 + if (!$this->pass())
159 + {
160 + return false;
161 + }
162 +
163 + $fbox = $this->box;
164 +
165 + /**
166 + * Runs before rendering the box.
167 + */
168 + do_action('firebox/box/before_render', $this->box);
169 +
170 + $this->prepare();
171 +
172 + $css = $this->getCustomCSS();
173 +
174 + add_action('wp_enqueue_scripts', function() use ($fbox, $css) {
175 + // Loads all media files.
176 + $this->loadBoxMedia($fbox);
177 +
178 + // Load CSS
179 + if ($css)
180 + {
181 + wp_add_inline_style('firebox', $css);
182 + }
183 +
184 +
185 + });
186 +
187 + // Allow to manipulate the box before rendering
188 + $this->box = apply_filters('firebox/box/edit', $this->box);
189 +
190 + // payload
191 + $payload = [
192 + 'box' => $this->box,
193 + 'params' => $this->params,
194 + ];
195 +
196 + // print campaign HTML
197 + add_action('wp_footer', function() use ($payload) {
198 + echo $this->getFinalCampaignHTML($payload); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
199 + });
200 +
201 + return true;
112 202 }
113 203
114 - /**
115 - * Render box
116 - *
117 - * @return string
118 - */
119 - public function render($box = null)
204 + public function renderEmbed()
120 205 {
121 - // we do not have a passed box or box settings from constructor, abort
122 - // as we cannot render a box without any box parameters
123 - if (!$box && !$this->boxSettings)
124 - {
125 - return;
206 + // Check Publishing Assignments
207 + if (!$this->pass())
208 + {
209 + return false;
126 210 }
127 211
128 - // if a box was given to the function, use these settings instead
129 - if ($box)
130 - {
131 - $this->boxSettings = $box;
132 - }
212 + /**
213 + * Runs before rendering the box.
214 + */
215 + do_action('firebox/box/before_render', $this->box);
133 216
134 - // if we have box settings, then set up our box with these settings
135 - if ($this->boxSettings)
136 - {
137 - $box = $this->boxSettings;
138 - }
217 + $this->prepare();
218 +
219 + // Loads all media files.
220 + $this->loadBoxMedia($this->box);
139 221
140 - // Check Publishing Assignments
141 - if (!$this->pass($box))
142 - {
143 - return;
144 - }
222 + $css = $this->getCustomCSS();
145 223
146 - // get settings params
147 - $params = BoxHelper::getParams();
224 + wp_register_style('fireboxStyle', false);
225 + wp_enqueue_style('fireboxStyle');
148 226
149 - if (!did_action('wp_enqueue_scripts'))
227 + // Load CSS
228 + if ($css)
150 229 {
151 - /**
152 - * Loads all media files.
153 - */
154 - add_action('wp_enqueue_scripts', function() use ($box, $params) {
155 - // load box media
156 - $this->loadBoxMedia($box, $params);
157 - });
230 + wp_add_inline_style('fireboxStyle', $css);
158 231 }
159 - else
160 - {
161 - // load box media
162 - $this->loadBoxMedia($box, $params);
163 - }
164 232
165 - self::prepare($box);
166 -
167 - if (!did_action('wp_head'))
168 - {
169 - /**
170 - * Custom CSS
171 - */
172 - add_action('wp_head', function() use ($box) {
173 - if ($css = $this->getCustomCSS($box))
174 - {
175 - echo '<style type="text/css" class="fb-' . esc_attr($box->ID) . '-style fb-responsive-style">' . $css . '</style>';
176 - }
177 - });
178 - }
179 - else
180 - {
181 - if ($css = $this->getCustomCSS($box))
182 - {
183 - echo '<style type="text/css" class="fb-' . esc_attr($box->ID) . '-style fb-responsive-style">' . $css . '</style>';
184 - }
185 - }
186 233
187 - /**
188 - * Runs before rendering the box.
189 - */
190 - do_action('firebox/box/before_render', $box);
234 +
235 + // Allow to manipulate the box before rendering
236 + $this->box = apply_filters('firebox/box/edit', $this->box);
191 237
192 - // after we prepare it, update box settings
193 - $this->boxSettings = $box;
194 -
195 238 // payload
196 239 $payload = [
197 - 'box' => $box,
198 - 'params' => $params,
240 + 'box' => $this->box,
241 + 'params' => $this->params,
199 242 ];
200 -
243 +
201 244 // return box template
202 - add_action('wp_footer', function() use ($box, $payload) {
203 - echo firebox()->renderer->public->render('box', $payload, true);
204 - });
245 + return $this->getFinalCampaignHTML($payload);
205 246 }
206 247
248 + public function getFinalCampaignHTML($payload)
249 + {
250 + $html = firebox()->renderer->public->render('box', $payload, true);
251 +
252 + /**
253 + * Runs after rendering the box.
254 + */
255 + return apply_filters('firebox/box/after_render', $html, $payload['box']);
256 + }
257 +
207 258 /**
208 259 * Gets the Custom CSS of the popup.
209 260 *
210 - * @param object $box
211 - *
212 261 * @return string
213 262 */
214 - private function getCustomCSS($box)
263 + public function getCustomCSS()
215 264 {
216 - $css = is_string($box->params->get('customcss')) ? $box->params->get('customcss') : '';
265 + return $this->box->params->get('customcss', '');
266 + }
217 267
218 - // add responsive CSS
219 - if ($responsive_css = (array) $box->params->get('responsive_css', []))
220 - {
221 - if (isset($responsive_css['tablet']) && !empty($responsive_css['tablet']))
222 - {
223 - $css .= '
224 -@media only screen and (max-width: 768px) {
225 - .fb-' . esc_attr($box->ID) . ' .fb-dialog { ' . esc_html($responsive_css['tablet']) . ' }
226 -}';
227 - }
228 - if (isset($responsive_css['mobile']) && !empty($responsive_css['mobile']))
229 - {
230 - $css .= '
231 -@media only screen and (max-width: 468px) {
232 - .fb-' . esc_attr($box->ID) . ' .fb-dialog { ' . esc_html($responsive_css['mobile']) . ' }
233 -}';
234 - }
235 - }
236 -
237 - return $css;
238 - }
239 -
240 268 /**
241 269 * Send a helpful object to JavaScript files
242 270 *
243 271 * @return void
@@ -249,57 +277,31 @@
249 277 return;
250 278 }
251 279 self::$loadedLocalizedScript = true;
252 280
253 - $data = array(
254 - 'ajax_url' => admin_url('admin-ajax.php'),
255 - 'nonce' => wp_create_nonce('fbox_js_nonce'),
256 - 'site_url' => site_url('/'),
257 - 'referrer' => wp_get_referer()
258 - );
281 + $data = [
282 + 'ajax_url' => admin_url('admin-ajax.php'),
283 + 'nonce' => wp_create_nonce('fbox_js_nonce'),
284 + 'site_url' => site_url('/'),
285 + 'referrer' => isset($_SERVER['HTTP_REFERER']) ? sanitize_url(wp_unslash($_SERVER['HTTP_REFERER'])) : ''
286 + ];
259 287
260 - wp_localize_script('firebox', 'fbox_js_object', $data);
288 + wp_add_inline_script('firebox-main', 'const fbox_js_object = ' . wp_json_encode($data), 'before');
261 289 }
262 290
263 291 /**
264 292 * Load Box Media
265 293 *
266 - * @param array $box
267 - * @param array $params
268 - *
269 294 * @return void
270 295 */
271 - public function loadBoxMedia($box, $params)
296 + public function loadBoxMedia($box)
272 297 {
273 298 $box = new Registry($box);
274 - $params = new Registry($params);
275 299
276 300 /**
277 - * We require a CSS handle to register inline styles.
278 - *
279 - * For this case, we use this dummy style to add inline CSS for our popups
280 - * even though the FireBox CSS file may not appear in the page.
281 - */
282 - wp_register_style('firebox-custom-styles', false);
283 - wp_enqueue_style('firebox-custom-styles');
284 -
285 - // Add polyfills for Internet Explorer
286 - $browser = $this->factory->getBrowser();
287 - if ($browser && is_array($browser) && array_key_exists('name', $browser) && $browser['name'] == 'ie')
288 - {
289 - wp_enqueue_script(
290 - 'firebox-ie11-polyfill',
291 - 'https://polyfill.io/v3/polyfill.min.js?features=NodeList.prototype.forEach%2CElement.prototype.closest%2CArray.prototype.forEach%2CArray.prototype.find%2CIntersectionObserver%2CIntersectionObserverEntry',
292 - [],
293 - FBOX_VERSION,
294 - false
295 - );
296 - }
297 -
298 - /**
299 301 * Velocity
300 302 */
301 - if ($params->get('loadVelocity', true))
303 + if ($this->params->get('loadVelocity', true))
302 304 {
303 305 wp_enqueue_script(
304 306 'firebox-velocity',
305 307 FBOX_MEDIA_PUBLIC_URL . 'js/vendor/velocity.js',
@@ -304,16 +306,16 @@
304 306 'firebox-velocity',
305 307 FBOX_MEDIA_PUBLIC_URL . 'js/vendor/velocity.js',
306 308 [],
307 309 FBOX_VERSION,
308 - false
310 + true
309 311 );
310 312 wp_enqueue_script(
311 313 'firebox-velocity-ui',
312 314 FBOX_MEDIA_PUBLIC_URL . 'js/vendor/velocity.ui.js',
313 - [],
315 + ['firebox-velocity'],
314 316 FBOX_VERSION,
315 - false
317 + true
316 318 );
317 319
318 320 /**
319 321 * Animations
@@ -322,11 +324,11 @@
322 324 {
323 325 wp_enqueue_script(
324 326 'firebox-animations',
325 327 FBOX_MEDIA_PUBLIC_URL . 'js/animations.js',
326 - [],
328 + ['firebox-velocity-ui'],
327 329 FBOX_VERSION,
328 - false
330 + true
329 331 );
330 332 }
331 333 }
332 334
@@ -333,15 +335,23 @@
333 335 /**
334 336 * FireBox JS
335 337 */
336 338 wp_enqueue_script(
337 - 'firebox',
339 + 'firebox-main',
338 340 FBOX_MEDIA_PUBLIC_URL . 'js/firebox.js',
339 341 [],
340 342 FBOX_VERSION,
341 - false
343 + true
342 344 );
343 345
346 + // Add Custom Javascript
347 + $custom_code = $box->get('params.data.customcode', '');
348 + if (is_string($custom_code) && !empty($custom_code))
349 + {
350 + $custom_code = html_entity_decode(stripslashes($custom_code));
351 + wp_add_inline_script('firebox-main', $custom_code, 'after');
352 + }
353 +
344 354 // run above the main JS script to run only once
345 355 self::setJSObject();
346 356
347 357 /**
@@ -346,16 +356,15 @@
346 356
347 357 /**
348 358 * FireBox CSS
349 359 */
350 - if ($params->get('loadCSS', true))
360 + if ($this->params->get('loadCSS', true))
351 361 {
352 362 wp_enqueue_style(
353 363 'firebox',
354 364 FBOX_MEDIA_PUBLIC_URL . 'css/firebox.css',
355 365 [],
356 - FBOX_VERSION,
357 - false
366 + FBOX_VERSION
358 367 );
359 368 }
360 369
361 370 /**
@@ -365,76 +374,47 @@
365 374 {
366 375 wp_enqueue_script(
367 376 'firebox-pageslide-mode',
368 377 FBOX_MEDIA_PUBLIC_URL . 'js/pageslide_mode.js',
369 - [],
378 + ['firebox-main'],
370 379 FBOX_VERSION,
371 - false
380 + true
372 381 );
373 382 }
374 383
375 384
376 -
377 - $this->loadThemeCSSOverrides();
378 385 }
379 386
380 387 /**
381 - * Some themes require overrides to preserve as much as we can the styling of the popups.
388 + * Prepares the box before rendering
382 389 *
383 390 * @return void
384 391 */
385 - private function loadThemeCSSOverrides()
392 + public function prepare()
386 393 {
387 - $active_theme = wp_get_theme();
388 - $theme = $active_theme->template;
394 + $this->css = new Styling\CSS($this->box);
389 395
390 - /**
391 - * This is the listed of the themes that we have created overrides
392 - */
393 - $themes = [
394 - 'twentytwentyone'
395 - ];
396 -
397 - if (!in_array($theme, $themes))
398 - {
399 - return;
400 - }
401 -
402 - wp_enqueue_style(
403 - 'firebox-theme-' . $theme . '-override',
404 - FBOX_MEDIA_PUBLIC_URL . 'css/themes/' . $theme . '.css',
405 - [],
406 - FBOX_VERSION,
407 - false
408 - );
409 - }
410 -
411 - /**
412 - * Prepares the box before rendering
413 - *
414 - * @param array $box
415 - *
416 - * @return void
417 - */
418 - public static function prepare(&$box)
419 - {
420 396 $cParam = BoxHelper::getParams();
421 397 $cParam = new Registry($cParam);
422 398
423 - $box->post_content = apply_filters('the_content', $box->post_content);
424 -
425 - $css_class_prefix = 'fb-';
399 + $this->box->post_content = apply_filters('the_content', $this->box->post_content);
426 400
427 - $position = $box->params->get('position', '');
428 - $position = !is_string($position) ? '' : $position;
429 -
430 401 /* Classes */
431 402 $css_class = [
432 - $box->ID,
433 - $position
403 + $this->box->ID
434 404 ];
405 +
406 + if ($this->box->params->get('mode') === 'popup')
407 + {
408 + $position = $this->box->params->get('position', '');
409 + $position = !is_string($position) ? '' : $position;
410 + if ($position)
411 + {
412 + $css_class[] = $position;
413 + }
414 + }
435 415
436 - $rtl = $box->params->get('rtl', '0');
416 + $rtl = $this->box->params->get('rtl', '0');
437 417 if ($rtl == '1')
438 418 {
439 419 $css_class[] = 'rtl';
440 420 }
@@ -440,18 +420,18 @@
440 420 }
441 421
442 422 self::prefixCSSClasses($css_class);
443 423
444 - // class suffix
445 - $classSuffix = $box->params->get('classsuffix', '');
424 + // Class suffix
425 + $classSuffix = $this->box->params->get('classsuffix', '');
446 426 $classSuffix = is_string($classSuffix) ? $classSuffix : '';
447 427
448 428 $css_class[] = $classSuffix;
449 429
450 - $box->classes = $css_class;
430 + $this->box->classes = $css_class;
451 431
452 - // box shadow
453 - $boxshadow = (is_string($box->params->get('boxshadow', '1')) || is_int($box->params->get('boxshadow', '1'))) ? $box->params->get('boxshadow', '1') : '0';
432 + // Box shadow
433 + $boxshadow = (is_string($this->box->params->get('boxshadow', '1')) || is_int($this->box->params->get('boxshadow', '1'))) ? $this->box->params->get('boxshadow', '1') : '0';
454 434
455 435 $dialog_css_classes = [
456 436 $boxshadow != '0' ? 'shd' . $boxshadow : null
457 437 ];
@@ -456,315 +436,140 @@
456 436 $boxshadow != '0' ? 'shd' . $boxshadow : null
457 437 ];
458 438
459 439 // Align Content
460 - $aligncontent = is_string($box->params->get('aligncontent')) ? explode(' ', $box->params->get('aligncontent')) : [];
440 + $aligncontent = is_string($this->box->params->get('aligncontent')) ? explode(' ', $this->box->params->get('aligncontent')) : [];
461 441 $dialog_css_classes = array_merge($dialog_css_classes, $aligncontent);
462 442
463 443 self::prefixCSSClasses($dialog_css_classes);
464 - $box->dialog_classes = $dialog_css_classes;
444 + $this->box->dialog_classes = $dialog_css_classes;
465 445
466 - /* CSS */
467 - // border
468 - $border = is_string($box->params->get('bordertype', 'none')) ? $box->params->get('bordertype', 'none') : 'none';
469 - $border_width = $box->params->get('borderwidth.value', 0) ? $box->params->get('borderwidth.value', 0) : 0;
470 - $border_unit = is_string($box->params->get('borderwidth.unit', 'px')) ? $box->params->get('borderwidth.unit', 'px') : 0;
471 - $border_color = is_string($box->params->get('bordercolor')) ? $box->params->get('bordercolor') : '';
472 -
473 - $style = [
474 - 'background' => $box->params->get('backgroundcolor'),
475 - 'color' => $box->params->get('textcolor'),
476 - 'border' => $border == 'none' ? null : $border . ' ' . $border_width . $border_unit . ' ' . $border_color,
477 - ];
478 -
479 - // add shared properties
480 - $shared_properties = [
481 - 'width' => [
482 - 'prefix_only' => true
483 - ],
484 - 'height' => [
485 - 'prefix_only' => true
486 - ],
487 - 'padding' => [],
488 - 'margin' => []
489 - ];
490 - foreach ($shared_properties as $prop => $prop_data)
491 - {
492 - // add dekstop property
493 - $value = (array) $box->params->get($prop . '_control.' . $prop, []);
494 - if (isset($value['desktop']))
495 - {
496 - $prefix_only = isset($prop_data['prefix_only']) ? (bool) $prop_data['prefix_only'] : false;
497 -
498 - $desktop_value = DimensionsHelper::parseDimensionsData($value['desktop'], $prop, false, $prefix_only);
499 - $style = array_merge($style, $desktop_value);
500 - }
501 - }
502 -
503 - // add dekstop border_radius
504 - $border_radius = (array) $box->params->get('borderradius_control.borderradius', []);
505 - if (isset($border_radius['desktop']))
506 - {
507 - $desktop_border_radius = DimensionsHelper::parseDimensionsBorderRadiusData($border_radius['desktop']);
508 - $style = array_merge($style, $desktop_border_radius);
509 - }
510 -
511 - // Background Image
512 - if ($box->params->get('bgimage', false))
513 - {
514 - $bgrepeat = is_string($box->params->get('bgrepeat')) ? $box->params->get('bgrepeat') : '';
515 - $bgsize = is_string($box->params->get('bgsize')) ? $box->params->get('bgsize') : '';
516 - $bgposition = is_string($box->params->get('bgposition')) ? $box->params->get('bgposition') : '';
517 -
518 - $style['background-image'] = 'url(\'' . esc_url($box->params->get('bgimagefile')) . '\')';
519 - $style['background-repeat'] = strtolower($bgrepeat);
520 - $style['background-size'] = strtolower($bgsize);
521 - $style['background-position'] = strtolower($bgposition);
522 - }
523 -
524 - $box->style = BoxHelper::arrayToCSSS($style);
525 -
526 446 $trigger_point_methods = [
527 - 'pageheight' => 'onScrollDepth',
528 - 'element' => 'onElementVisibility',
529 - 'pageready' => 'onPageReady',
447 + 'pageready' => 'onPageReady',
530 448 'pageload' => 'onPageLoad',
531 - 'userleave' => 'onExit',
532 449 'onclick' => 'onClick',
533 450 'elementHover' => 'onHover',
534 - 'ondemand' => 'onDemand'
451 + 'ondemand' => 'onDemand',
452 +
535 453 ];
536 454
537 455 /* Other Settings */
538 - $scroll_depth = $box->params->get('scroll_depth', 'percentage');
539 - $scroll_depth = is_string($scroll_depth) ? $scroll_depth : '';
456 + $animation_duration = $this->box->params->get('duration') ? (float) $this->box->params->get('duration') : 0;
540 457
541 - $animation_duration = $box->params->get('duration') ? (float) $box->params->get('duration') : 0;
542 -
458 + $delay = in_array($this->box->params->get('triggermethod'), ['floatingbutton', 'onexternallink']) ? 0 : (int) $this->box->params->get('triggerdelay') * 1000;
459 +
460 + $trigger_method = (is_string($this->box->params->get('triggermethod'))) && array_key_exists($this->box->params->get('triggermethod'), $trigger_point_methods) ? $trigger_point_methods[$this->box->params->get('triggermethod')] : $this->box->params->get('triggermethod');
461 +
462 + $trigger_element = is_scalar($this->box->params->get('triggerelement', '')) ? $this->box->params->get('triggerelement', '') : '';
463 +
543 464 // Use Namespaced classes for each trigger point and let them manipulate the settings dynamicaly.
544 - $box->settings = [
545 - 'trigger' => (is_string($box->params->get('triggermethod'))) && array_key_exists($box->params->get('triggermethod'), $trigger_point_methods) ? $trigger_point_methods[$box->params->get('triggermethod')] : $box->params->get('triggermethod'),
546 - 'trigger_selector' => $box->params->get('triggerelement'),
547 - 'delay' => (int) $box->params->get('triggerdelay') * 1000,
548 - 'scroll_depth' => $scroll_depth,
549 - 'scroll_depth_value' => $scroll_depth == 'percentage' ? (int) $box->params->get('triggerpercentage') : (int) $box->params->get('scroll_pixel'),
550 - 'firing_frequency' => (int) $box->params->get('firing_frequency', 1),
551 - 'reverse_scroll_close' => (bool) $box->params->get('autohide'),
552 - 'threshold' => (float) $box->params->get('threshold', 0) / 100,
553 - 'close_out_viewport' => (bool) $box->params->get('close_out_viewport', false),
554 - 'exit_timer' => (int) $box->params->get('exittimer') * 1000,
555 - 'idle_time' => (int) $box->params->get('idle_time') * 1000,
556 - 'animation_open' => $box->params->get('animationin'),
557 - 'animation_close' => $box->params->get('animationout'),
465 + $this->box->settings = [
466 + 'name' => $this->box->post_title,
467 + 'trigger' => $trigger_method,
468 + 'trigger_selector' => $trigger_method === 'onExternalLink' ? '' : rtrim($trigger_element, ','),
469 + 'delay' => $delay,
470 +
471 + 'animation_open' => $this->box->params->get('animationin'),
472 + 'animation_close' => $this->box->params->get('animationout'),
558 473 'animation_duration' => (float) $animation_duration * 1000,
559 - 'prevent_default' => (bool) $box->params->get('preventdefault', true),
560 - 'backdrop' => (bool) $box->params->get('overlay'),
561 - 'backdrop_color' => $box->params->get('overlay_color'),
562 - 'backdrop_click' => (bool) $box->params->get('overlayclick'),
563 - 'disable_page_scroll' => (bool) $box->params->get('preventpagescroll'),
564 - 'test_mode' => (bool) $box->params->get('testmode'),
474 + 'prevent_default' => (bool) $this->box->params->get('preventdefault', true),
475 + 'backdrop' => (bool) $this->box->params->get('overlay'),
476 + 'backdrop_color' => $this->box->params->get('overlay_color'),
477 + 'backdrop_click' => (bool) $this->box->params->get('overlayclick'),
478 + 'disable_page_scroll' => (bool) $this->box->params->get('preventpagescroll'),
479 + 'test_mode' => (bool) $this->box->params->get('testmode'),
565 480 'debug' => (bool) $cParam->get('debug', false),
566 - 'ga_tracking' => (bool) $cParam->get('gaTrack', 0),
567 - 'ga_tracking_id' => $cParam->get('gaID', 0),
568 - 'ga_tracking_label' => $cParam->get('gaCategory'),
569 - 'auto_focus' => (bool) $box->params->get('autofocus', false)
481 + 'auto_focus' => (bool) $this->box->params->get('autofocus', false),
482 + 'mode' => $this->box->params->get('mode')
570 483 ];
571 484
572 - $box->styles_container = BoxHelper::arrayToCSSS([
573 - 'z-index' => $box->params->get('zindex', 99999) != 99999 ? $box->params->get('zindex') : null
574 - ]);
485 + // Apply Popup CSS
486 + $this->box->params->set('customcss', $this->box->params->get('customcss') . $this->css->getCSS());
575 487
576 - // Let's start using CSS vars for each box settings.
577 - $cssVars = [
578 - 'animation_duration' => (float) $animation_duration . 's'
579 - ];
580 -
581 - // Enqueue firebox custom inline CSS
582 - $cssVarsForm = self::cssVarsToString($cssVars, '.fb-' . $box->ID);
583 - if (!did_action('wp_enqueue_scripts'))
584 - {
585 - add_action('wp_enqueue_scripts', function() use ($cssVarsForm) {
586 - wp_add_inline_style('firebox-custom-styles', $cssVarsForm);
587 - });
588 - }
589 - else
590 - {
591 - wp_add_inline_style('firebox-custom-styles', $cssVarsForm);
592 - }
593 -
594 - // set padding and margin for other devices as well
595 - self::setResponsiveCSS($box);
596 -
597 - self::replaceBoxSmartTags($box);
488 + $this->replaceBoxSmartTags();
598 489 }
599 490
600 491 /**
601 - * Converts an array of CSS variables to its corresponding strings.
602 - *
603 - * @param array $cssVars
604 - * @param string $namespace
605 - *
606 - * @return string
607 - */
608 - private static function cssVarsToString($cssVars, $namespace)
609 - {
610 - $output = '';
611 -
612 - foreach ($cssVars as $key => $value)
613 - {
614 - $output .= '--' . $key . ': ' . $value . ';' . "\n";
615 - }
616 -
617 - return $namespace . ' {
618 - ' . $output . '
619 - }
620 - ';
621 - }
622 -
623 - /**
624 - * Sets all responsive CSS to use in box view
625 - *
626 - * @param object $box
627 - *
628 - * @return void
629 - */
630 - private static function setResponsiveCSS(&$box)
631 - {
632 - $tablet = '';
633 - $mobile = '';
634 -
635 - /**
636 - * Handle width, height, padding, margin the same way.
637 - */
638 - $shared_properties = [
639 - 'width' => [
640 - 'prefix_only' => true
641 - ],
642 - 'height' => [
643 - 'prefix_only' => true
644 - ],
645 - 'padding' => [],
646 - 'margin' => []
647 - ];
648 -
649 - foreach ($shared_properties as $prop => $prop_settings)
650 - {
651 - $prop_data = (array) $box->params->get($prop . '_control.' . $prop, []);
652 -
653 - $prefix_only = isset($prop_settings['prefix_only']) ? $prop_settings['prefix_only'] : false;
654 -
655 - // assign each device CSS
656 - if (isset($prop_data['tablet']))
657 - {
658 - $tablet .= BoxHelper::arrayToCSSS(DimensionsHelper::parseDimensionsData($prop_data['tablet'], $prop, true, $prefix_only));
659 - }
660 - if (isset($prop_data['mobile']))
661 - {
662 - $mobile .= BoxHelper::arrayToCSSS(DimensionsHelper::parseDimensionsData($prop_data['mobile'], $prop, true, $prefix_only));
663 - }
664 - }
665 -
666 - // border radius requires a special method
667 - $border_radius = (array) $box->params->get('borderradius_control.borderradius', []);
668 - if (isset($border_radius['tablet']))
669 - {
670 - $tablet .= BoxHelper::arrayToCSSS(DimensionsHelper::parseDimensionsBorderRadiusData($border_radius['tablet'], true));
671 - }
672 - if (isset($border_radius['mobile']))
673 - {
674 - $mobile .= BoxHelper::arrayToCSSS(DimensionsHelper::parseDimensionsBorderRadiusData($border_radius['mobile'], true));
675 - }
676 -
677 - $responsive_css = [
678 - 'tablet' => $tablet,
679 - 'mobile' => $mobile
680 - ];
681 - $box->params->set('responsive_css', $responsive_css);
682 - }
683 -
684 - /**
685 492 * Replaces all box smart tags
686 493 *
687 - * @param object $box
688 - *
689 494 * @return object
690 495 */
691 - public static function replaceBoxSmartTags(&$box)
496 + public function replaceBoxSmartTags()
692 497 {
693 498 $tags = new \FPFramework\Base\SmartTags\SmartTags();
694 499
695 500 // register FB Smart Tags
696 - $tags->register('\FireBox\Core\SmartTags', FBOX_BASE_FOLDER . '/Inc/Core/SmartTags', $box);
501 + $tags->register('\FireBox\Core\SmartTags', FBOX_BASE_FOLDER . '/Inc/Core/SmartTags', $this->box);
697 502
698 - $box = $tags->replace($box);
503 + $this->box = $tags->replace($this->box);
699 504 }
700 505
701 506 /**
702 507 * Checks if a box passes assignments
703 508 *
704 - * @param object $box
705 - *
706 509 * @return boolean
707 510 */
708 - public function pass($box)
511 + public function pass()
709 512 {
710 - if (!$box || !is_object($box))
513 + if (!$this->box || !is_object($this->box))
711 514 {
712 515 return false;
713 516 }
714 517
715 - // set box settings if empty
716 - if (empty($this->boxSettings))
717 - {
718 - $this->boxSettings = $box;
719 - }
518 + // Check first local assignments
519 + if (!$this->passLocalAssignments())
520 + {
521 + return false;
522 + }
720 523
721 - // Prepare boxes that mirror other boxes assignments
722 - if ($box->params->get('mirror', false) && $mirror_box_id = $box->params->get('mirror_box'))
524 + $displayConditionsType = $this->box->params->get('display_conditions_type', '');
525 +
526 + // If empty, display popup sitewide
527 + if (empty($displayConditionsType) || $displayConditionsType === 'all')
723 528 {
724 - $box->params->merge(self::getAssignmentsForMirroring($mirror_box_id));
529 + return true;
725 530 }
531 +
532 + // Mirror Display Conditions of another popup.
533 + if ($displayConditionsType == 'mirror' && $mirror_box_id = $this->box->params->get('mirror_box'))
534 + {
535 + $this->box->params->merge(self::getAssignmentsForMirroring($mirror_box_id));
536 + }
726 537
727 - // Check first local assignments
728 - if (!$this->passLocalAssignments($box))
538 + // Get a recursive array of all rules
539 + $rules = $this->box->params->get('rules', []);
540 + $rules = is_string($rules) ? json_decode($rules, true) : json_decode(wp_json_encode($rules), true);
541 +
542 + // If testmode is enabled disable the User Groups condition
543 + if ($this->box->params->get('testmode'))
729 544 {
730 - return false;
545 + foreach ($rules as $key => &$group)
546 + {
547 + foreach ($group['rules'] as $_key => &$rule)
548 + {
549 + if (!isset($rule['name']) || empty($rule['name']))
550 + {
551 + continue;
552 + }
553 +
554 + if ($rule['name'] === 'WP\UserGroup')
555 + {
556 + unset($group['rules'][$_key]);
557 + }
558 + }
559 + }
731 560 }
732 561
733 - // If testmode is enabled disable the User Groups assignment
734 - if ($box->params->get('testmode'))
735 - {
736 - $box->params->set('assignments.assign_grouplevel.selection', '0');
737 - }
738 -
739 - $globalAssignments = $this->passGlobalAssignments($box);
740 -
741 - // Check framework based assignments
742 - return $globalAssignments;
562 + // Check framework based conditions
563 + return \FPFramework\Base\Conditions\ConditionBuilder::pass($rules, $this->factory);
743 564 }
744 565
745 - /**
746 - * Passes framework based global assignments
747 - *
748 - * @param object $box
749 - *
750 - * @return boolean
751 - */
752 - private function passGlobalAssignments($box)
753 - {
754 - $assignments = new \FPFramework\Base\Assignments($this->factory);
755 - $pass = $assignments->passAll($box, $box->params->get('assignmentMatchingMethod', 'and'));
756 - return $pass;
757 - }
758 -
759 566 /**
760 - * Check if a box passes local assignments
567 + * Check if a box passes local conditions
761 568 *
762 - * @param object $box
763 - *
764 569 * @return boolean
765 570 */
766 - private function passLocalAssignments($box)
571 + private function passLocalAssignments()
767 572 {
768 573 $localAssignments = new \FireBox\Core\FB\Assignments($this, $this->factory);
769 574 return $localAssignments->passAll();
770 575 }
@@ -775,9 +580,9 @@
775 580 * @param int $box_id
776 581 *
777 582 * @return object
778 583 */
779 - private static function getAssignmentsForMirroring($box_id)
584 + private function getAssignmentsForMirroring($box_id)
780 585 {
781 586 $payload = [
782 587 'where' => [
783 588 'ID' => ' = ' . intval($box_id),
@@ -795,29 +600,11 @@
795 600 $box = $box[0];
796 601
797 602 // get meta options for box
798 603 $meta = get_post_meta($box_id, 'fpframework_meta_settings', true);
799 - $box->params = $meta;
604 + $box->params = new Registry($meta);
800 605
801 - // To prevent user frustration, we ignore the following assignments because they are not displayed in the Publishing Assignments.
802 - $params_to_ignore = [
803 - 'assign_impressions'
804 - ];
805 -
806 - $assignments = [];
807 -
808 - // Gather params to merge
809 - foreach ($box->params as $param_key => $param_value)
810 - {
811 - if (strpos($param_key, 'assign') === false || in_array($param_key, $params_to_ignore))
812 - {
813 - continue;
814 - }
815 -
816 - $assignments[$param_key] = $param_value;
817 - }
818 -
819 - return new Registry($assignments);
606 + return new Registry(['rules' => $box->params->get('rules')]);
820 607 }
821 608
822 609 /**
823 610 * Prefixes the CSS classes
@@ -885,69 +672,85 @@
885 672 }
886 673
887 674 firebox()->log->track($box_id, 2, $box_log_id);
888 675 }
889 -
676 +
890 677 /**
891 - * Get box impressions
678 + * Get total box impressions
892 679 *
893 680 * @param array $payload
894 681 *
895 682 * @return array
896 683 */
897 - public function getImpressions($payload)
684 + public function getTotalImpressions($payload)
898 685 {
899 - return firebox()->tables->boxlog->getResults($payload);
686 + $impressions = firebox()->tables->boxlog->getResults($payload);
687 +
688 + return count($impressions);
900 689 }
901 -
690 +
902 691 /**
903 - * Get total box impressions
692 + * Returns the cookie instance.
904 693 *
905 - * @param array $payload
906 - *
907 - * @return array
694 + * @return mixed
908 695 */
909 - public function getTotalImpressions($payload)
696 + public function getCookie()
910 697 {
911 - return count($this->getImpressions($payload));
698 + if (!$this->box)
699 + {
700 + return;
701 + }
702 +
703 + return new Cookie($this->box);
912 704 }
913 705
914 706 /**
915 - * Return the box settings
707 + * Returns the box.
916 708 *
917 709 * @return object
918 710 */
919 - public function getBoxSettings()
711 + public function getBox()
920 712 {
921 - return $this->boxSettings;
713 + return $this->box;
922 714 }
923 715
924 716 /**
925 - * Sets the box settings
717 + * Sets the box.
926 718 *
927 - * @param object $settings
719 + * @param object $box
928 720 *
929 - * @return object
721 + * @return Box
930 722 */
931 - public function setBoxSettings($settings)
723 + public function setBox($box)
932 724 {
933 - $this->boxSettings = $settings;
725 + $this->box = $box;
726 +
727 + return $this;
934 728 }
935 729
936 - /**
937 - * Returns the box cookie
938 - *
939 - * @param string $cookie
940 - *
941 - * @return mixed
942 - */
943 - public function getCookie($cookie = null)
730 + public function getParams()
944 731 {
945 - $cookie = $cookie ? $cookie : (isset($this->boxSettings->ID) ? $this->boxSettings->ID : null);
946 - if (!isset($cookie))
732 + return $this->params;
733 + }
734 +
735 + public function setParams($params)
736 + {
737 + $this->params = $params;
738 +
739 + return $this;
740 + }
741 +
742 + public function getCampaignParams()
743 + {
744 + return isset($this->box->params) ? $this->box->params : null;
745 + }
746 +
747 + public function setCampaignParams($params)
748 + {
749 + if (isset($this->box->params))
947 750 {
948 - return;
751 + $this->box->params = $params;
949 752 }
950 -
951 - return new Cookie($cookie);
753 +
754 + return $this;
952 755 }
953 756 }