PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.1
1.7.1 1.7.0 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 All 51 releases
fluent-cart / app / Services / Theme / Readers / AstraSettingsReader.php

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

206 lines 6.8 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 use FluentCart\Framework\Support\Arr;
8
9 /**
10 * Astra's Customizer colours, read from its settings rather than its slots.
11 *
12 * Astra keeps its Theme Colors as settings that point at a palette swatch
13 * (`var(--ast-global-color-N)`) or hold a custom colour, and its primary
14 * button colours as four settings that are empty until the owner sets them.
15 * `astra_get_option()` merges what the owner saved over Astra's defaults, so
16 * an untouched install reads its defaults and a customised one reads the
17 * customisation — the same values Astra's own dynamic CSS prints from.
18 *
19 * Empty button settings follow Astra's own chain, not a FluentCart default:
20 * background → Accent (`theme-color`), hover background → Link Hover
21 * (`link-h-color`), and each text partner → the colour that reads on its
22 * background.
23 *
24 * Its Buttons → Border Radius (`button-radius-fields`) is the button radius
25 * (see radii()). Astra has no form-field or product-card radius setting.
26 *
27 * Verified against Astra 4.13.11.
28 */
29 class AstraSettingsReader implements ThemeSettingsReader, ThemeRadiusReader
30 {
31 /**
32 * Astra's outline button presets: a transparent background with a border.
33 *
34 * @var array
35 */
36 protected static $outlinePresets = ['button_04', 'button_05', 'button_06'];
37
38 /**
39 * @return bool
40 */
41 public static function applies(): bool
42 {
43 return function_exists('astra_get_option');
44 }
45
46 /**
47 * @return array Role => hex or `var(--ast-global-color-N, #hex)`.
48 */
49 public static function roles(): array
50 {
51 if (!self::applies()) {
52 return [];
53 }
54
55 $roles = [];
56
57 $accent = self::read('theme-color');
58 $roles['accent'] = $accent;
59 $roles['text'] = self::read('text-color');
60 $roles['border'] = self::read('border-color');
61
62 // Astra paints the content area with the content background and falls
63 // back to the site background outside it. Tablet and mobile inherit
64 // desktop when empty, so desktop is the value that speaks for all.
65 $surface = self::readResponsive('content-bg-obj-responsive');
66
67 if ($surface === '') {
68 $surface = self::readResponsive('site-layout-outside-bg-obj-responsive');
69 }
70
71 $roles['surface'] = $surface;
72
73 // An outline preset turns the primary button transparent: there is no
74 // filled button to report, so the button roles are left to the
75 // palette-slot fallback.
76 $preset = (string)astra_get_option('button-preset-style');
77
78 if (!in_array($preset, self::$outlinePresets, true)) {
79 $roles = array_merge($roles, self::buttonPair(
80 astra_get_option('button-bg-color'),
81 $accent,
82 astra_get_option('button-color'),
83 'button_bg',
84 'button_text'
85 ));
86
87 $roles = array_merge($roles, self::buttonPair(
88 astra_get_option('button-bg-h-color'),
89 self::read('link-h-color'),
90 astra_get_option('button-h-color'),
91 'button_hover_bg',
92 'button_hover_text'
93 ));
94 }
95
96 return array_filter($roles, function ($value) {
97 return $value !== '';
98 });
99 }
100
101 /**
102 * One background + text pair, following Astra's fallback chain.
103 *
104 * A stated background wins; an empty one follows `$fallbackBg`. A value
105 * that is set but unreadable is not replaced by the fallback — Astra is
106 * painting it, just not in a form FluentCart can write, so the pair is
107 * omitted rather than reported as a colour Astra is not showing.
108 *
109 * @param mixed $rawBg The background setting as saved.
110 * @param string $fallbackBg Already-normalised fallback background.
111 * @param mixed $rawText The text setting as saved.
112 * @param string $bgRole
113 * @param string $textRole
114 * @return array
115 */
116 protected static function buttonPair($rawBg, string $fallbackBg, $rawText, string $bgRole, string $textRole): array
117 {
118 $isSet = is_string($rawBg) && trim($rawBg) !== '';
119 $background = $isSet ? ThemePalette::settingValue($rawBg) : $fallbackBg;
120
121 if ($background === '') {
122 return [];
123 }
124
125 $text = ThemePalette::settingValue($rawText);
126
127 if ($text === '') {
128 // Astra's own rule for an empty text: the foreground that reads on
129 // the background.
130 $bgHex = ThemePalette::measurable($background);
131 $text = $bgHex !== '' ? ColorMath::readableText($bgHex) : '';
132 }
133
134 return [
135 $bgRole => $background,
136 $textRole => $text,
137 ];
138 }
139
140 /**
141 * @param string $key
142 * @return string
143 */
144 protected static function read(string $key): string
145 {
146 return ThemePalette::settingValue(astra_get_option($key));
147 }
148
149 /**
150 * @param string $key
151 * @return string
152 */
153 protected static function readResponsive(string $key): string
154 {
155 $value = astra_get_option($key);
156
157 if (!is_array($value)) {
158 return '';
159 }
160
161 return ThemePalette::settingValue(Arr::get($value, 'desktop.background-color', ''));
162 }
163
164 /**
165 * The primary button's Border Radius.
166 *
167 * `button-radius-fields` is a responsive four-corner control; Astra prints
168 * each desktop corner as `<value><desktop-unit>` (astra_responsive_spacing()
169 * in inc/class-astra-dynamic-css.php) and tablet/mobile only override it,
170 * so desktop speaks for all. Only four equal corners are one length. An
171 * empty corner prints nothing — Astra's stylesheet then paints `button`
172 * 2px but `.button` 0, no single answer — so an empty radius states none.
173 *
174 * @return array Role => length, as Astra prints it.
175 */
176 public static function radii(): array
177 {
178 if (!self::applies()) {
179 return [];
180 }
181
182 $fields = astra_get_option('button-radius-fields');
183
184 if (!is_array($fields) || !isset($fields['desktop']) || !is_array($fields['desktop'])) {
185 return [];
186 }
187
188 $unit = isset($fields['desktop-unit']) && is_string($fields['desktop-unit']) && $fields['desktop-unit'] !== ''
189 ? $fields['desktop-unit']
190 : 'px';
191 $corners = [];
192
193 foreach (['top', 'right', 'bottom', 'left'] as $side) {
194 $value = isset($fields['desktop'][$side]) ? $fields['desktop'][$side] : '';
195
196 if (!is_numeric($value)) {
197 return [];
198 }
199
200 $corners[] = $value . $unit;
201 }
202
203 return count(array_unique($corners)) === 1 ? ['btn' => $corners[0]] : [];
204 }
205 }
206