PluginProbe
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment / 3.0.1
FireBox – WooCommerce Popup Builder, Exit Intent Popup, Email Optin & Cart Abandonment v3.0.1
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 3.0.1, at Inc/Core/FB/Styling/CSS.php

423 lines 9.5 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.0.1 Free
5 *
6 * @author FirePlugins <info@fireplugins.com>
7 * @link https://www.fireplugins.com
8 * @copyright Copyright © 2025 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 $border_width = $this->box->params->get('border.width', 0) ? trim($this->box->params->get('border.width', 0)) : 0;
138 $border_style = is_string($this->box->params->get('border.style', 0)) ? trim($this->box->params->get('border.style', 0)) : '';
139 $border_color = is_string($this->box->params->get('border.color')) ? trim($this->box->params->get('border.color')) : '';
140
141 if (!empty($border_width) && !empty($border_style) && !empty($border_color))
142 {
143 $style['border'] = implode(' ' , [$border_width, $border_style, $border_color]);
144 }
145
146 // Background
147 $background = $this->box->params->get('backgroundcolor');
148 if (!empty($background))
149 {
150 $style['background'] = $background;
151 }
152
153 // Background Image
154 if ($this->box->params->get('bgimage', false))
155 {
156 $bgrepeat = is_string($this->box->params->get('bgrepeat')) ? $this->box->params->get('bgrepeat') : '';
157 $bgsize = is_string($this->box->params->get('bgsize')) ? $this->box->params->get('bgsize') : '';
158 $bgposition = is_string($this->box->params->get('bgposition')) ? $this->box->params->get('bgposition') : '';
159
160 $style['background-image'] = 'url(\'' . esc_url($this->box->params->get('bgimagefile', '')) . '\')';
161 $style['background-repeat'] = strtolower($bgrepeat);
162 $style['background-size'] = strtolower($bgsize);
163 $style['background-position'] = strtolower($bgposition);
164 }
165
166 // Add CSS (non-responsive) to desktop breakpoint
167 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-dialog');
168
169 $css_properties = [
170 'width' => [],
171 'height' => [],
172 'padding' => [],
173 'borderradius' => [
174 'prefix' => 'border-radius',
175 'parser' => 'parseDimensionsBorderRadiusData'
176 ],
177
178 // Deprecated
179 'fontsize' => [
180 'prefix' => 'font-size'
181 ],
182 ];
183 $this->parseCSSProperties($css_properties, ' .fb-dialog');
184 }
185
186 /**
187 * Set close button CSS.
188 *
189 * @return void
190 */
191 private function setCloseButtonCSS()
192 {
193 // Delay the display of the close button using CSS animation
194 $delay = (float) $this->box->params->get('closebutton.delay', 0);
195 if ($delay > 0)
196 {
197 $style = [
198 'visibility' => 'hidden'
199 ];
200 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-close');
201
202 $style = [
203 'animation' => $delay . 's ebFadeIn',
204 'animation-fill-mode' => 'forwards'
205 ];
206 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', '.fb-visible .fb-close');
207 }
208
209 // Close Button Initial color
210 $btnSource = is_string($this->box->params->get('closebutton.source', 'icon')) ? $this->box->params->get('closebutton.source', 'icon') : 'icon';
211 $color = is_string($this->box->params->get('closebutton.color', null)) ? $this->box->params->get('closebutton.color', null) : null;
212 if ($btnSource == 'icon' && !empty($color))
213 {
214 $style = [
215 'color' => $color
216 ];
217 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-close');
218 }
219
220 // Add the hover color
221 if ($hoverColor = $this->box->params->get('closebutton.hover', null))
222 {
223 $style = [
224 'color' => esc_attr($hoverColor) . ' !important'
225 ];
226 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-close:hover');
227 }
228 }
229
230 private function setFloatingButtonCSS()
231 {
232 $css_properties = [
233 'margin' => [
234 'prefix' => 'padding'
235 ],
236 ];
237 $this->parseCSSProperties($css_properties, '.fb-floating-button');
238 }
239
240 /**
241 * Parses the given CSS properties and adds the CSS to the list.
242 *
243 * @param array $props
244 * @param string $selector
245 *
246 * @return void
247 */
248 private function parseCSSProperties($props = [], $selector = '')
249 {
250 foreach ($props as $prop => $prop_data)
251 {
252 $value = (array) $this->box->params->get($prop, []);
253
254 foreach ($this->breakpoints as $breakpoint)
255 {
256 if (!isset($value[$breakpoint]))
257 {
258 continue;
259 }
260
261 $prefix = isset($prop_data['prefix']) ? $prop_data['prefix'] : $prop;
262
263 $parserMethod = isset($prop_data['parser']) ? $prop_data['parser'] : 'parseDimensionsData';
264
265 $_value = DimensionsHelper::$parserMethod($value[$breakpoint], $prefix);
266
267 if (empty($_value))
268 {
269 continue;
270 }
271
272 $breakpoint_value = CSSHelper::arrayToCSS($_value);
273
274 $this->addCSS($breakpoint_value, $breakpoint, $selector);
275 }
276 }
277 }
278
279 /**
280 * Add CSS to given breakpoint and selector.
281 *
282 * @param string $css
283 * @param string $breakpoint
284 * @param string $selector
285 *
286 * @return void
287 */
288 public function addCSS($css = '', $breakpoint = 'desktop', $selector = '')
289 {
290 if (empty($css))
291 {
292 return;
293 }
294
295 // No selector, append to breakpoint as new item
296 if (empty($selector))
297 {
298 $this->responsive_css[$breakpoint][] = $css;
299 return;
300 }
301
302 // With selector, if first breakpoint item, set it
303 if (empty($this->responsive_css[$breakpoint][$selector]))
304 {
305 $this->responsive_css[$breakpoint][$selector] = $css;
306 }
307 // Otherwise, append to existing CSS
308 else
309 {
310 $this->responsive_css[$breakpoint][$selector] .= ' ' . $css;
311 }
312 }
313
314 /**
315 * Returns the CSS for a given breakpoint.
316 *
317 * @param string $breakpoint
318 *
319 * @return string
320 */
321 private function getBreakpointCSS($breakpoint = 'desktop')
322 {
323 if (!isset($this->responsive_css[$breakpoint]))
324 {
325 return;
326 }
327
328 $skeletonFunctionName = 'get' . ucfirst($breakpoint) . 'Skeleton';
329 if (!method_exists($this, $skeletonFunctionName))
330 {
331 return;
332 }
333
334 $skeleton = $this->$skeletonFunctionName();
335
336 /**
337 * This array holds all CSS grouped by selector.
338 *
339 * The empty key,value pair indicates that the CSS does not have a custom selector
340 */
341 $data = [
342 // Global CSS
343 '' => ''
344 ];
345
346 // Group CSS by selector
347 foreach ($this->responsive_css[$breakpoint] as $selector => $value)
348 {
349 $selector = is_string($selector) && $selector !== '' ? $selector : '';
350
351 if (empty($selector))
352 {
353 $data[''] .= $value;
354 }
355 else
356 {
357 $data[$selector] = $value;
358 }
359 }
360
361 // Get final CSS for the breakpoint
362 $cssvalue = '';
363 foreach ($data as $selector => $value)
364 {
365 if (empty($value))
366 {
367 continue;
368 }
369
370 $selectorSkeleton = $this->getSelector($selector);
371
372 $cssvalue .= sprintf($selectorSkeleton, $value);
373 }
374
375 // Return breakpoint with final CSS
376 return sprintf($skeleton, $cssvalue);
377 }
378
379 /**
380 * Returns the CSS Selector.
381 *
382 * @return string
383 */
384 private function getSelector($selector = ' .fb-dialog')
385 {
386 return '.fb-' . esc_attr($this->box->ID . $selector) . ' { %s }';
387 }
388
389 /**
390 * Desktop CSS Skeleton.
391 *
392 * @return string
393 */
394 private function getDesktopSkeleton()
395 {
396 return '%s';
397 }
398
399 /**
400 * Tablet CSS Skeleton.
401 *
402 * @return string
403 */
404 private function getTabletSkeleton()
405 {
406 return '@media only screen and (max-width: 991px) { %s }';
407 }
408
409 /**
410 * Mobile CSS Skeleton.
411 *
412 * @return string
413 */
414 private function getMobileSkeleton()
415 {
416 return '@media only screen and (max-width: 575px) { %s }';
417 }
418
419 public function getResponsiveCSS()
420 {
421 return $this->responsive_css;
422 }
423 }