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

416 lines 9.4 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 2.0.19 Free
5 *
6 * @author FirePlugins <info@fireplugins.com>
7 * @link https://www.fireplugins.com
8 * @copyright Copyright © 2023 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 }
62
63 /**
64 * Returns all popup CSS.
65 *
66 * @return string
67 */
68 public function getCSS()
69 {
70 $css = '';
71
72 foreach ($this->breakpoints as $breakpoint)
73 {
74 $finalcss = $this->getBreakpointCSS($breakpoint);
75
76 // Update $responsive_css with final CSS
77 $this->responsive_css[$breakpoint] = $finalcss;
78
79 $css .= $finalcss;
80 }
81
82 return $css;
83 }
84
85 /**
86 * Sets the instance CSS.
87 *
88 * @return void
89 */
90 private function setInstanceCSS()
91 {
92 $animation_duration = $this->box->params->get('duration') ? (float) $this->box->params->get('duration') : 0;
93
94 $style = [
95 'animation-duration' => (float) $animation_duration . 's'
96 ];
97
98 // Z-index
99 $zindex = $this->box->params->get('zindex', 99999) != 99999 ? $this->box->params->get('zindex') : null;
100 if (intval($zindex))
101 {
102 $style['z-index'] = $zindex;
103 }
104
105 // Overlay blur
106 $overlay_enabled = (bool) $this->box->params->get('overlay');
107 if ($overlay_enabled && $radius = $this->box->params->get('overlayblurradius', 0))
108 {
109 $radius = intval($radius) * 0.25;
110 // Limit blur
111 if ($radius > 60)
112 {
113 $radius = 60;
114 }
115
116 $style['backdrop-filter'] = 'blur(' . $radius . 'px)';
117 }
118
119 // Add CSS (non-responsive) to desktop breakpoint
120 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', '.fb-inst');
121 }
122
123 /**
124 * Sets the dialog CSS.
125 *
126 * @return void
127 */
128 private function setDialogCSS()
129 {
130 // Dialog CSS
131 $style = [
132 'color' => $this->box->params->get('textcolor'),
133 ];
134
135 // Border
136 $border = is_string($this->box->params->get('bordertype', 'none')) ? trim($this->box->params->get('bordertype', 'none')) : 'none';
137 $border_width = $this->box->params->get('borderwidth.value', 0) ? trim($this->box->params->get('borderwidth.value', 0)) : 0;
138 $border_unit = is_string($this->box->params->get('borderwidth.unit', 'px')) ? trim($this->box->params->get('borderwidth.unit', 'px')) : '';
139 $border_color = is_string($this->box->params->get('bordercolor')) ? trim($this->box->params->get('bordercolor')) : '';
140
141 if (!($border === 'none' || empty($border_width) || empty($border_unit) || empty($border_color)))
142 {
143 $style['border'] = $border . ' ' . $border_width . $border_unit . ' ' . $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 /**
170 * Calculate Responsive CSS
171 * and add them to each breakpoint.
172 */
173 $css_properties = [
174 'fontsize' => [
175 'prefix' => 'font-size'
176 ],
177 'width' => [],
178 'height' => [],
179 'padding' => [],
180 'margin' => [],
181 'borderradius' => [
182 'prefix' => 'border-radius',
183 'parser' => 'parseDimensionsBorderRadiusData'
184 ]
185 ];
186 $this->parseCSSProperties($css_properties, ' .fb-dialog');
187 }
188
189 /**
190 * Set close button CSS.
191 *
192 * @return void
193 */
194 private function setCloseButtonCSS()
195 {
196 // Delay the display of the close button using CSS animation
197 $delay = (float) $this->box->params->get('closebutton.delay', 0);
198 if ($delay > 0)
199 {
200 $style = [
201 'visibility' => 'hidden'
202 ];
203 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-close');
204
205 $style = [
206 'animation' => $delay . 's ebFadeIn',
207 'animation-fill-mode' => 'forwards'
208 ];
209 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', '.fb-visible .fb-close');
210 }
211
212 // Close Button Initial color
213 $btnSource = is_string($this->box->params->get('closebutton.source', 'icon')) ? $this->box->params->get('closebutton.source', 'icon') : 'icon';
214 $color = is_string($this->box->params->get('closebutton.color', null)) ? $this->box->params->get('closebutton.color', null) : null;
215 if ($btnSource == 'icon' && !empty($color))
216 {
217 $style = [
218 'color' => $color
219 ];
220 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-close');
221 }
222
223 // Add the hover color
224 if ($hoverColor = $this->box->params->get('closebutton.hover', null))
225 {
226 $style = [
227 'color' => esc_attr($hoverColor) . ' !important'
228 ];
229 $this->addCSS(CSSHelper::arrayToCSS($style), 'desktop', ' .fb-close:hover');
230 }
231 }
232
233 /**
234 * Parses the given CSS properties and adds the CSS to the list.
235 *
236 * @param array $props
237 * @param string $selector
238 *
239 * @return void
240 */
241 private function parseCSSProperties($props = [], $selector = '')
242 {
243 foreach ($props as $prop => $prop_data)
244 {
245 $value = (array) $this->box->params->get($prop . '_control.' . $prop, []);
246
247 foreach ($this->breakpoints as $breakpoint)
248 {
249 if (!isset($value[$breakpoint]))
250 {
251 continue;
252 }
253
254 $prefix = isset($prop_data['prefix']) ? $prop_data['prefix'] : $prop;
255
256 $parserMethod = isset($prop_data['parser']) ? $prop_data['parser'] : 'parseDimensionsData';
257
258 $test = DimensionsHelper::$parserMethod($value[$breakpoint], $prefix);
259
260 if (empty($test))
261 {
262 continue;
263 }
264
265 $breakpoint_value = CSSHelper::arrayToCSS($test);
266
267 $this->addCSS($breakpoint_value, $breakpoint, $selector);
268 }
269 }
270 }
271
272 /**
273 * Add CSS to given breakpoint and selector.
274 *
275 * @param string $css
276 * @param string $breakpoint
277 * @param string $selector
278 *
279 * @return void
280 */
281 public function addCSS($css = '', $breakpoint = 'desktop', $selector = '')
282 {
283 if (empty($css))
284 {
285 return;
286 }
287
288 // No selector, append to breakpoint as new item
289 if (empty($selector))
290 {
291 $this->responsive_css[$breakpoint][] = $css;
292 return;
293 }
294
295 // With selector, if first breakpoint item, set it
296 if (empty($this->responsive_css[$breakpoint][$selector]))
297 {
298 $this->responsive_css[$breakpoint][$selector] = $css;
299 }
300 // Otherwise, append to existing CSS
301 else
302 {
303 $this->responsive_css[$breakpoint][$selector] .= ' ' . $css;
304 }
305 }
306
307 /**
308 * Returns the CSS for a given breakpoint.
309 *
310 * @param string $breakpoint
311 *
312 * @return string
313 */
314 private function getBreakpointCSS($breakpoint = 'desktop')
315 {
316 if (!isset($this->responsive_css[$breakpoint]))
317 {
318 return;
319 }
320
321 $skeletonFunctionName = 'get' . ucfirst($breakpoint) . 'Skeleton';
322 if (!method_exists($this, $skeletonFunctionName))
323 {
324 return;
325 }
326
327 $skeleton = $this->$skeletonFunctionName();
328
329 /**
330 * This array holds all CSS grouped by selector.
331 *
332 * The empty key,value pair indicates that the CSS does not have a custom selector
333 */
334 $data = [
335 // Global CSS
336 '' => ''
337 ];
338
339 // Group CSS by selector
340 foreach ($this->responsive_css[$breakpoint] as $selector => $value)
341 {
342 $selector = is_string($selector) && $selector !== '' ? $selector : '';
343
344 if (empty($selector))
345 {
346 $data[''] .= $value;
347 }
348 else
349 {
350 $data[$selector] = $value;
351 }
352 }
353
354 // Get final CSS for the breakpoint
355 $cssvalue = '';
356 foreach ($data as $selector => $value)
357 {
358 if (empty($value))
359 {
360 continue;
361 }
362
363 $selectorSkeleton = $this->getSelector($selector);
364
365 $cssvalue .= sprintf($selectorSkeleton, $value);
366 }
367
368 // Return breakpoint with final CSS
369 return sprintf($skeleton, $cssvalue);
370 }
371
372 /**
373 * Returns the CSS Selector.
374 *
375 * @return string
376 */
377 private function getSelector($selector = ' .fb-dialog')
378 {
379 return '.fb-' . esc_attr($this->box->ID . $selector) . ' { %s }';
380 }
381
382 /**
383 * Desktop CSS Skeleton.
384 *
385 * @return string
386 */
387 private function getDesktopSkeleton()
388 {
389 return '%s';
390 }
391
392 /**
393 * Tablet CSS Skeleton.
394 *
395 * @return string
396 */
397 private function getTabletSkeleton()
398 {
399 return '@media only screen and (max-width: 991px) { %s }';
400 }
401
402 /**
403 * Mobile CSS Skeleton.
404 *
405 * @return string
406 */
407 private function getMobileSkeleton()
408 {
409 return '@media only screen and (max-width: 575px) { %s }';
410 }
411
412 public function getResponsiveCSS()
413 {
414 return $this->responsive_css;
415 }
416 }