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 / FB / Styling / CSS.php

CSS.php in FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment trunk, at Inc/Core/FB/Styling/CSS.php

427 lines 9.8 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\FB\Styling;
13
14 if (!defined('ABSPATH'))
15 {
16 exit; // Exit if accessed directly.
17 }
18
19 use FPFramework\Libs\Registry;
20 use FPFramework\Helpers\Fields\DimensionsHelper;
21 use FPFramework\Helpers\CSS as CSSHelper;
22
23 class CSS
24 {
25 /**
26 * Breakpoints.
27 *
28 * @var array
29 */
30 private $breakpoints = [
31 'desktop',
32 'tablet',
33 'mobile'
34 ];
35
36 /**
37 * CSS per breakpoint.
38 *
39 * @var array
40 */
41 private $responsive_css = [
42 'desktop' => [],
43 'tablet' => [],
44 'mobile' => []
45 ];
46
47 /**
48 * The box we are generating CSS for.
49 *
50 * @var Object
51 */
52 private $box;
53
54 public function __construct($box)
55 {
56 $this->box = $box;
57
58 $this->setInstanceCSS();
59 $this->setDialogCSS();
60 $this->setCloseButtonCSS();
61 $this->setFloatingButtonCSS();
62 }
63
64 /**
65 * Returns all popup CSS.
66 *
67 * @return string
68 */
69 public function getCSS()
70 {
71 $css = '';
72
73 foreach ($this->breakpoints as $breakpoint)
74 {
75 $finalcss = $this->getBreakpointCSS($breakpoint);
76
77 // Update $responsive_css with final CSS
78 $this->responsive_css[$breakpoint] = $finalcss;
79
80 $css .= $finalcss;
81 }
82
83 return $css;
84 }
85
86 /**
87 * Sets the instance CSS.
88 *
89 * @return void
90 */
91 private function setInstanceCSS()
92 {
93 $style = [];
94
95 // Z-index
96 $zindex = $this->box->params->get('zindex', 99999) != 99999 ? $this->box->params->get('zindex') : null;
97 if (intval($zindex))
98 {
99 $style['z-index'] = $zindex;
100 }
101
102 // Overlay blur
103 $overlay_enabled = (bool) $this->box->params->get('overlay');
104 if ($overlay_enabled && $radius = $this->box->params->get('overlayblurradius', 0))
105 {
106 $style['backdrop-filter'] = 'blur(' . $radius . 'px)';
107 $style['-webkit-backdrop-filter'] = 'blur(' . $radius . 'px)';
108 }
109
110 // Add CSS (non-responsive) to desktop breakpoint
111 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', '.fb-inst');
112
113 $css_properties = [
114 'margin' => [
115 'prefix' => 'padding'
116 ],
117 ];
118 $this->parseCSSProperties($css_properties, '.fb-inst');
119 }
120
121 /**
122 * Sets the dialog CSS.
123 *
124 * @return void
125 */
126 private function setDialogCSS()
127 {
128 // Dialog CSS
129 $style = [
130 'color' => $this->box->params->get('textcolor'),
131 ];
132
133 $animation_duration = $this->box->params->get('animation_duration') ? (float) $this->box->params->get('animation_duration') : 0;
134 $style['animation-duration'] = (float) $animation_duration . 's';
135
136 // Border
137 // A truthy but non-scalar width (a Dimensions/ResponsiveControl value is an array)
138 // would reach trim(), which is a TypeError since PHP 8.0. Numeric widths must keep
139 // working, so this checks for scalars rather than only for strings.
140 $border_width_raw = $this->box->params->get('border.width', 0);
141 $border_width = is_scalar($border_width_raw) && $border_width_raw ? trim((string) $border_width_raw) : 0;
142 $border_style = is_string($this->box->params->get('border.style', 0)) ? trim($this->box->params->get('border.style', 0)) : '';
143 $border_color = is_string($this->box->params->get('border.color')) ? trim($this->box->params->get('border.color')) : '';
144
145 if (!empty($border_width) && !empty($border_style) && !empty($border_color))
146 {
147 $style['border'] = implode(' ' , [$border_width, $border_style, $border_color]);
148 }
149
150 // Background
151 $background = $this->box->params->get('backgroundcolor');
152 if (!empty($background))
153 {
154 $style['background'] = $background;
155 }
156
157 // Background Image
158 if ($this->box->params->get('bgimage', false))
159 {
160 $bgrepeat = is_string($this->box->params->get('bgrepeat')) ? $this->box->params->get('bgrepeat') : '';
161 $bgsize = is_string($this->box->params->get('bgsize')) ? $this->box->params->get('bgsize') : '';
162 $bgposition = is_string($this->box->params->get('bgposition')) ? $this->box->params->get('bgposition') : '';
163
164 $style['background-image'] = 'url(\'' . esc_url($this->box->params->get('bgimagefile', '')) . '\')';
165 $style['background-repeat'] = strtolower($bgrepeat);
166 $style['background-size'] = strtolower($bgsize);
167 $style['background-position'] = strtolower($bgposition);
168 }
169
170 // Add CSS (non-responsive) to desktop breakpoint
171 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-dialog');
172
173 $css_properties = [
174 'width' => [],
175 'height' => [],
176 'padding' => [],
177 'borderradius' => [
178 'prefix' => 'border-radius',
179 'parser' => 'parseDimensionsBorderRadiusData'
180 ],
181
182 // Deprecated
183 'fontsize' => [
184 'prefix' => 'font-size'
185 ],
186 ];
187 $this->parseCSSProperties($css_properties, ' .fb-dialog');
188 }
189
190 /**
191 * Set close button CSS.
192 *
193 * @return void
194 */
195 private function setCloseButtonCSS()
196 {
197 // Delay the display of the close button using CSS animation
198 $delay = (float) $this->box->params->get('closebutton.delay', 0);
199 if ($delay > 0)
200 {
201 $style = [
202 'visibility' => 'hidden'
203 ];
204 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-close');
205
206 $style = [
207 'animation' => $delay . 's ebFadeIn',
208 'animation-fill-mode' => 'forwards'
209 ];
210 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', '.fb-visible .fb-close');
211 }
212
213 // Close Button Initial color
214 $btnSource = is_string($this->box->params->get('closebutton.source', 'icon')) ? $this->box->params->get('closebutton.source', 'icon') : 'icon';
215 $color = is_string($this->box->params->get('closebutton.color', null)) ? $this->box->params->get('closebutton.color', null) : null;
216 if ($btnSource == 'icon' && !empty($color))
217 {
218 $style = [
219 'color' => $color
220 ];
221 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-close');
222 }
223
224 // Add the hover color
225 if ($hoverColor = $this->box->params->get('closebutton.hover', null))
226 {
227 $style = [
228 'color' => esc_attr($hoverColor) . ' !important'
229 ];
230 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-close:hover');
231 }
232 }
233
234 private function setFloatingButtonCSS()
235 {
236 $css_properties = [
237 'margin' => [
238 'prefix' => 'padding'
239 ],
240 ];
241 $this->parseCSSProperties($css_properties, '.fb-floating-button');
242 }
243
244 /**
245 * Parses the given CSS properties and adds the CSS to the list.
246 *
247 * @param array $props
248 * @param string $selector
249 *
250 * @return void
251 */
252 private function parseCSSProperties($props = [], $selector = '')
253 {
254 foreach ($props as $prop => $prop_data)
255 {
256 $value = (array) $this->box->params->get($prop, []);
257
258 foreach ($this->breakpoints as $breakpoint)
259 {
260 if (!isset($value[$breakpoint]))
261 {
262 continue;
263 }
264
265 $prefix = isset($prop_data['prefix']) ? $prop_data['prefix'] : $prop;
266
267 $parserMethod = isset($prop_data['parser']) ? $prop_data['parser'] : 'parseDimensionsData';
268
269 $_value = DimensionsHelper::$parserMethod($value[$breakpoint], $prefix);
270
271 if (empty($_value))
272 {
273 continue;
274 }
275
276 $breakpoint_value = CSSHelper::arrayToCSS($_value);
277
278 $this->addCSS($breakpoint_value, $breakpoint, $selector);
279 }
280 }
281 }
282
283 /**
284 * Add CSS to given breakpoint and selector.
285 *
286 * @param string $css
287 * @param string $breakpoint
288 * @param string $selector
289 *
290 * @return void
291 */
292 public function addCSS($css = '', $breakpoint = 'desktop', $selector = '')
293 {
294 if (empty($css))
295 {
296 return;
297 }
298
299 // No selector, append to breakpoint as new item
300 if (empty($selector))
301 {
302 $this->responsive_css[$breakpoint][] = $css;
303 return;
304 }
305
306 // With selector, if first breakpoint item, set it
307 if (empty($this->responsive_css[$breakpoint][$selector]))
308 {
309 $this->responsive_css[$breakpoint][$selector] = $css;
310 }
311 // Otherwise, append to existing CSS
312 else
313 {
314 $this->responsive_css[$breakpoint][$selector] .= ' ' . $css;
315 }
316 }
317
318 /**
319 * Returns the CSS for a given breakpoint.
320 *
321 * @param string $breakpoint
322 *
323 * @return string
324 */
325 private function getBreakpointCSS($breakpoint = 'desktop')
326 {
327 if (!isset($this->responsive_css[$breakpoint]))
328 {
329 return;
330 }
331
332 $skeletonFunctionName = 'get' . ucfirst($breakpoint) . 'Skeleton';
333 if (!method_exists($this, $skeletonFunctionName))
334 {
335 return;
336 }
337
338 $skeleton = $this->$skeletonFunctionName();
339
340 /**
341 * This array holds all CSS grouped by selector.
342 *
343 * The empty key,value pair indicates that the CSS does not have a custom selector
344 */
345 $data = [
346 // Global CSS
347 '' => ''
348 ];
349
350 // Group CSS by selector
351 foreach ($this->responsive_css[$breakpoint] as $selector => $value)
352 {
353 $selector = is_string($selector) && $selector !== '' ? $selector : '';
354
355 if (empty($selector))
356 {
357 $data[''] .= $value;
358 }
359 else
360 {
361 $data[$selector] = $value;
362 }
363 }
364
365 // Get final CSS for the breakpoint
366 $cssvalue = '';
367 foreach ($data as $selector => $value)
368 {
369 if (empty($value))
370 {
371 continue;
372 }
373
374 $selectorSkeleton = $this->getSelector($selector);
375
376 $cssvalue .= sprintf($selectorSkeleton, $value);
377 }
378
379 // Return breakpoint with final CSS
380 return sprintf($skeleton, $cssvalue);
381 }
382
383 /**
384 * Returns the CSS Selector.
385 *
386 * @return string
387 */
388 private function getSelector($selector = ' .fb-dialog')
389 {
390 return '.fb-' . esc_attr($this->box->ID . $selector) . ' { %s }';
391 }
392
393 /**
394 * Desktop CSS Skeleton.
395 *
396 * @return string
397 */
398 private function getDesktopSkeleton()
399 {
400 return '%s';
401 }
402
403 /**
404 * Tablet CSS Skeleton.
405 *
406 * @return string
407 */
408 private function getTabletSkeleton()
409 {
410 return '@media only screen and (max-width: 991px) { %s }';
411 }
412
413 /**
414 * Mobile CSS Skeleton.
415 *
416 * @return string
417 */
418 private function getMobileSkeleton()
419 {
420 return '@media only screen and (max-width: 575px) { %s }';
421 }
422
423 public function getResponsiveCSS()
424 {
425 return $this->responsive_css;
426 }
427 }