← All changes
|
app/Services/Theme/Readers/BlocksySettingsReader.php
+172
-1
1.6.6
→
1.7.1
View file →
| @@ -26,11 +26,16 @@ | ||
| 26 | 26 | * always kept live: Blocksy Companion's dark mode redefines the palette |
| 27 | 27 | * properties under `:root[data-color-mode*="dark"]`, which a bare hex would |
| 28 | 28 | * never follow. |
| 29 | 29 | * |
| 30 | + * Radii (see radii()): Buttons → Border Radius (`buttonRadius`) and Form | |
| 31 | + * Elements → Border Radius (`formFieldBorderRadius`). The product card radius | |
| 32 | + * (`cardProductRadius`) is a WooCommerce setting Blocksy only prints with | |
| 33 | + * WooCommerce, so it is not read. | |
| 34 | + * | |
| 30 | 35 | * Verified against Blocksy 2.1.57. |
| 31 | 36 | */ |
| 32 | -class BlocksySettingsReader implements ThemeSettingsReader | |
| 37 | +class BlocksySettingsReader implements ThemeSettingsReader, ThemeRadiusReader | |
| 33 | 38 | { |
| 34 | 39 | /** |
| 35 | 40 | * Blocksy's defaults per mod and sub-key (inc/dynamic-styles/global/all.php |
| 36 | 41 | * and background.php). |
| @@ -218,6 +223,172 @@ | ||
| 218 | 223 | $raw = $default; |
| 219 | 224 | } |
| 220 | 225 | |
| 221 | 226 | return ThemePalette::settingValue($raw); |
| 227 | + } | |
| 228 | + | |
| 229 | + /** | |
| 230 | + * Blocksy's stylesheet fallback for both radii | |
| 231 | + * (`var(--theme-button-border-radius, 3px)`, | |
| 232 | + * `var(--theme-form-field-border-radius, 3px)`, static/bundle/main.min.css), | |
| 233 | + * and the `empty_value` its dynamic CSS skips printing at. | |
| 234 | + * | |
| 235 | + * @var int | |
| 236 | + */ | |
| 237 | + protected static $defaultRadius = 3; | |
| 238 | + | |
| 239 | + /** | |
| 240 | + * The button and form-field radii. | |
| 241 | + * | |
| 242 | + * Button: `buttonRadius`, a ct-spacing value printed as | |
| 243 | + * `--theme-button-border-radius` (inc/dynamic-styles/global/all.php). Its | |
| 244 | + * desktop value speaks for all; an empty one is Blocksy's 3px. | |
| 245 | + * | |
| 246 | + * Form field: `formFieldBorderRadius`, a number of px (default 3) printed | |
| 247 | + * as `--theme-form-field-border-radius` (global/forms.php). It is only | |
| 248 | + * worn by classic forms: modern forms paint | |
| 249 | + * `var(--has-classic-forms, …)` with `--false`, which leaves the field | |
| 250 | + * square, so they state 0. | |
| 251 | + * | |
| 252 | + * @return array Role => length, as Blocksy prints it. | |
| 253 | + */ | |
| 254 | + public static function radii(): array | |
| 255 | + { | |
| 256 | + if (!self::applies()) { | |
| 257 | + return []; | |
| 258 | + } | |
| 259 | + | |
| 260 | + $radii = []; | |
| 261 | + | |
| 262 | + $button = blocksy_get_theme_mod('buttonRadius', null); | |
| 263 | + | |
| 264 | + if (is_array($button) && isset($button['desktop'])) { | |
| 265 | + $button = $button['desktop']; | |
| 266 | + } | |
| 267 | + | |
| 268 | + $buttonRadius = self::spacingLength($button); | |
| 269 | + | |
| 270 | + if ($buttonRadius !== '') { | |
| 271 | + $radii['btn'] = $buttonRadius; | |
| 272 | + } | |
| 273 | + | |
| 274 | + if (blocksy_get_theme_mod('forms_type', 'classic-forms') !== 'classic-forms') { | |
| 275 | + $radii['input'] = '0'; | |
| 276 | + } else { | |
| 277 | + $field = blocksy_get_theme_mod('formFieldBorderRadius', self::$defaultRadius); | |
| 278 | + | |
| 279 | + if (is_numeric($field)) { | |
| 280 | + $radii['input'] = $field . 'px'; | |
| 281 | + } | |
| 282 | + } | |
| 283 | + | |
| 284 | + return $radii; | |
| 285 | + } | |
| 286 | + | |
| 287 | + /** | |
| 288 | + * A ct-spacing value as the one length Blocksy prints, the way | |
| 289 | + * blocksy_spacing_prepare_for_device() writes it (inc/css/spacing.php): | |
| 290 | + * | |
| 291 | + * - unset, or every side empty: Blocksy prints nothing and its | |
| 292 | + * stylesheet's 3px applies; | |
| 293 | + * - custom (state 3): the custom string as typed; | |
| 294 | + * - otherwise each side's value and unit, an empty side taking 3 when | |
| 295 | + * the sides are linked (0 when not), a side without a unit taking the | |
| 296 | + * others'. Only four equal sides are one length. | |
| 297 | + * | |
| 298 | + * The pre-`values` format (`top`/`right`/`bottom`/`left` strings) is read | |
| 299 | + * the same way. | |
| 300 | + * | |
| 301 | + * @param mixed $value | |
| 302 | + * @return string | |
| 303 | + */ | |
| 304 | + protected static function spacingLength($value): string | |
| 305 | + { | |
| 306 | + $fallback = self::$defaultRadius . 'px'; | |
| 307 | + | |
| 308 | + if (!is_array($value)) { | |
| 309 | + return $fallback; | |
| 310 | + } | |
| 311 | + | |
| 312 | + if (!isset($value['values'])) { | |
| 313 | + return self::legacySpacingLength($value); | |
| 314 | + } | |
| 315 | + | |
| 316 | + $state = (int)Arr::get($value, 'state', 1); | |
| 317 | + | |
| 318 | + if ($state === 3) { | |
| 319 | + $custom = trim((string)Arr::get($value, 'custom', '')); | |
| 320 | + | |
| 321 | + return $custom === '' ? $fallback : $custom; | |
| 322 | + } | |
| 323 | + | |
| 324 | + $sides = []; | |
| 325 | + $unit = ''; | |
| 326 | + $allEmpty = true; | |
| 327 | + | |
| 328 | + foreach (array_slice(array_values((array)$value['values']), 0, 4) as $side) { | |
| 329 | + $number = is_array($side) ? Arr::get($side, 'value', '') : ''; | |
| 330 | + $sideUnit = is_array($side) ? (string)Arr::get($side, 'unit', '') : ''; | |
| 331 | + | |
| 332 | + if ($number === '' || $number === 'auto' || $number === null) { | |
| 333 | + $number = $state === 1 ? self::$defaultRadius : 0; | |
| 334 | + } else { | |
| 335 | + $allEmpty = false; | |
| 336 | + } | |
| 337 | + | |
| 338 | + if ($sideUnit !== '') { | |
| 339 | + $unit = $sideUnit; | |
| 340 | + } | |
| 341 | + | |
| 342 | + $sides[] = ['value' => (string)$number, 'unit' => $sideUnit]; | |
| 343 | + } | |
| 344 | + | |
| 345 | + if (count($sides) !== 4 || $allEmpty) { | |
| 346 | + return $fallback; | |
| 347 | + } | |
| 348 | + | |
| 349 | + $lengths = []; | |
| 350 | + | |
| 351 | + foreach ($sides as $side) { | |
| 352 | + $lengths[] = $side['value'] . ($side['unit'] !== '' ? $side['unit'] : $unit); | |
| 353 | + } | |
| 354 | + | |
| 355 | + return count(array_unique($lengths)) === 1 ? $lengths[0] : ''; | |
| 356 | + } | |
| 357 | + | |
| 358 | + /** | |
| 359 | + * The pre-`values` spacing format: four strings carrying their unit. | |
| 360 | + * Blocksy writes an empty, `auto` or `0` side as its empty value. | |
| 361 | + * | |
| 362 | + * @param array $value | |
| 363 | + * @return string | |
| 364 | + */ | |
| 365 | + protected static function legacySpacingLength(array $value): string | |
| 366 | + { | |
| 367 | + $sides = []; | |
| 368 | + | |
| 369 | + foreach (['top', 'right', 'bottom', 'left'] as $key) { | |
| 370 | + $side = trim((string)Arr::get($value, $key, '')); | |
| 371 | + $sides[] = ($side === '' || $side === 'auto' || $side === '0') ? '' : $side; | |
| 372 | + } | |
| 373 | + | |
| 374 | + if (implode('', $sides) === '') { | |
| 375 | + return self::$defaultRadius . 'px'; | |
| 376 | + } | |
| 377 | + | |
| 378 | + $unit = 'px'; | |
| 379 | + | |
| 380 | + foreach ($sides as $side) { | |
| 381 | + if ($side !== '' && preg_match('/^[\d.]+([a-z%]+)$/i', $side, $matches)) { | |
| 382 | + $unit = $matches[1]; | |
| 383 | + } | |
| 384 | + } | |
| 385 | + | |
| 386 | + foreach ($sides as $index => $side) { | |
| 387 | + if ($side === '') { | |
| 388 | + $sides[$index] = self::$defaultRadius . $unit; | |
| 389 | + } | |
| 390 | + } | |
| 391 | + | |
| 392 | + return count(array_unique($sides)) === 1 ? $sides[0] : ''; | |
| 222 | 393 | } |
| 223 | 394 | } |