PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.6
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.6
1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 All 49 releases
fluent-cart / app / Services / Theme / Readers / DiviSettingsReader.php

DiviSettingsReader.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.6, at app/Services/Theme/Readers/DiviSettingsReader.php

196 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Services\Theme\Readers;
4
5 use FluentCart\App\Services\Theme\ColorMath;
6 use FluentCart\App\Services\Theme\ThemePalette;
7
8 /**
9 * Divi's Customizer colours, read from its settings.
10 *
11 * Divi publishes no palette to theme.json, so without a reader inheritance has
12 * nothing to follow. Its Customizer keeps the colours as flat values in the
13 * `et_divi` option row, read through `et_get_option()` — the call Divi's own
14 * `et_divi_add_customizer_css()` prints them from: Theme Accent Color
15 * (`accent_color`), Body Text Color (`font_color`), and the Buttons section
16 * (`all_buttons_bg_color`, `all_buttons_text_color` and their `_hover` pair).
17 * The content area is painted from the core `background_color` theme mod
18 * (`et_divi_add_main_content_background_css()`).
19 *
20 * Accent and body text are Divi 5's Customizer global colours, printed as
21 * `--gcid-primary-color` and `--gcid-body-color` from these same options
22 * (GlobalData::get_customizer_colors()), so they are stated live with the
23 * option's hex as the fallback: `var(--gcid-primary-color, #hex)`. The button
24 * and background settings have no property, so they are stated as hex.
25 *
26 * Divi's default button is an outline: a transparent background
27 * (`rgba(0,0,0,0)`), the accent as its text and border. Only a background the
28 * owner set to a solid hex is a filled button; anything else states no button
29 * and FluentCart falls back as it did before.
30 *
31 * An empty value is what Divi's own CSS treats as unset — its static
32 * stylesheet paints the default — so it takes Divi's default here too. A
33 * value FluentCart cannot write (rgb(), rgba(), Divi 5's `hsl(from var(--gcid…))`
34 * or a `$variable(…)$` reference) is not stated.
35 *
36 * Verified against Divi 5.0.1.
37 */
38 class DiviSettingsReader implements ThemeSettingsReader
39 {
40 /**
41 * Divi's defaults (GlobalData::$customizer_colors, the Customizer settings
42 * and the static stylesheet).
43 *
44 * @var array
45 */
46 protected static $defaults = [
47 'accent_color' => '#2ea3f2',
48 'font_color' => '#666666',
49 // `#main-content { background-color: #fff }` in Divi's stylesheet.
50 'content' => '#ffffff',
51 ];
52
53 /**
54 * Detected by Divi's own option API and customizer printer, and by the
55 * `$shortname` Divi's `et_setup_theme()` sets: `et_get_option()` is shared
56 * by every Elegant Themes product and reads the row named after that
57 * global, so only 'divi' means the `et_divi` row these settings live in.
58 * Theme name is not used, so a child theme keeps working.
59 *
60 * @return bool
61 */
62 public static function applies(): bool
63 {
64 return function_exists('et_get_option')
65 && function_exists('et_divi_add_customizer_css')
66 && isset($GLOBALS['shortname'])
67 && $GLOBALS['shortname'] === 'divi';
68 }
69
70 /**
71 * @return array Role => hex or `var(--gcid-…, #hex)`.
72 */
73 public static function roles(): array
74 {
75 if (!self::applies()) {
76 return [];
77 }
78
79 $accentHex = self::hex(et_get_option('accent_color', self::$defaults['accent_color']), self::$defaults['accent_color']);
80 $textHex = self::hex(et_get_option('font_color', self::$defaults['font_color']), self::$defaults['font_color']);
81
82 $roles = [
83 'accent' => $accentHex !== '' ? 'var(--gcid-primary-color, ' . $accentHex . ')' : '',
84 'text' => $textHex !== '' ? 'var(--gcid-body-color, ' . $textHex . ')' : '',
85 'surface' => self::surface(),
86 ];
87
88 $button = self::button($roles['accent']);
89
90 if ($button) {
91 $roles = array_merge($roles, $button);
92 }
93
94 return array_filter($roles, function ($value) {
95 return $value !== '';
96 });
97 }
98
99 /**
100 * The filled button and its hover, when Divi paints one.
101 *
102 * A background that is not a solid hex — Divi's transparent default, an
103 * rgba() — is an outline or a tint, not a fill, so no button is stated and
104 * its hover goes with it.
105 *
106 * An empty text keeps what Divi paints on a button, the accent, while that
107 * reads on the background (WCAG 4.5:1); otherwise the colour that does.
108 * Divi prints no hover text when it is empty, so the resting text carries
109 * over — which resolve() already does when no hover text is stated. A
110 * hover background that is not a solid hex (Divi's default white tint)
111 * states no hover, and FluentCart derives it from the button as before.
112 *
113 * @param string $accent The stated accent, or ''.
114 * @return array
115 */
116 protected static function button(string $accent): array
117 {
118 $background = self::hex(et_get_option('all_buttons_bg_color', 'rgba(0,0,0,0)'));
119
120 if ($background === '') {
121 return [];
122 }
123
124 $text = self::hex(et_get_option('all_buttons_text_color', ''));
125
126 if ($text === '') {
127 $accentHex = ThemePalette::measurable($accent);
128
129 $text = $accentHex !== '' && ColorMath::contrast($background, $accentHex) >= 4.5
130 ? $accent
131 : ColorMath::readableText($background);
132 }
133
134 $roles = [
135 'button_bg' => $background,
136 'button_text' => $text,
137 ];
138
139 $hoverBg = self::hex(et_get_option('all_buttons_bg_color_hover', 'rgba(255,255,255,0.2)'));
140
141 if ($hoverBg !== '') {
142 $roles['button_hover_bg'] = $hoverBg;
143 $roles['button_hover_text'] = self::hex(et_get_option('all_buttons_text_color_hover', ''));
144 }
145
146 return $roles;
147 }
148
149 /**
150 * The content background.
151 *
152 * Outside the Divi Builder, Divi paints `#main-content` with the core
153 * Background Color and turns it transparent over a Background Image
154 * (`et_divi_add_main_content_background_css()`); with neither, its
155 * stylesheet paints it white. An image paints no colour, so it states no
156 * surface. The theme mod is saved without its `#`.
157 *
158 * @return string
159 */
160 protected static function surface(): string
161 {
162 if ((string)get_theme_mod('background_image', '') !== '') {
163 return '';
164 }
165
166 $color = trim((string)get_theme_mod('background_color', ''));
167
168 if ($color === '') {
169 return self::$defaults['content'];
170 }
171
172 return self::hex('#' . ltrim($color, '#'));
173 }
174
175 /**
176 * A Divi colour value as a hex FluentCart can write.
177 *
178 * Empty or missing takes `$default` — what Divi's own stylesheet paints
179 * when the setting prints nothing. Anything but a hex is not stated.
180 *
181 * @param mixed $raw
182 * @param string $default
183 * @return string Lowercase hex, or ''.
184 */
185 protected static function hex($raw, string $default = ''): string
186 {
187 if (!is_string($raw) || trim($raw) === '') {
188 $raw = $default;
189 }
190
191 $raw = trim($raw);
192
193 return preg_match('/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/', $raw) ? strtolower(ColorMath::hex($raw)) : '';
194 }
195 }
196