????
| Current Path : /proc/self/root/home/arabianr/www/wp-content/plugins/simplybook/app/Services/ |
| Current File : //proc/self/root/home/arabianr/www/wp-content/plugins/simplybook/app/Services/ThemeColorService.php |
<?php
namespace SimplyBook\Services;
use SimplyBook\Support\Utility\ColorUtility;
class ThemeColorService
{
private ColorUtility $colorUtility;
public function __construct(ColorUtility $colorUtility)
{
$this->colorUtility = $colorUtility;
}
/**
* Maps WordPress theme color names to standardized keys.
* For widget: primary=background, secondary=text, active=button
*/
private array $wpColorMappings = [
'primary' => ['background', 'base'],
'secondary' => ['contrast', 'foreground'],
'active' => ['accent-1', 'accent', 'tertiary'],
'background' => ['background', 'base'],
'foreground' => ['foreground', 'text'],
'text' => ['contrast', 'foreground'],
];
/**
* Fallback chain: Global Styles → Theme JSON → CSS Variables → config defaults
*/
public function getThemeColors(): array
{
$colors = $this->getColorsFromGlobalStyles();
if (empty($colors)) {
$colors = $this->getColorsFromThemeJson();
}
if (empty($colors)) {
$colors = $this->getColorsFromCssVariables();
}
if (empty($colors)) {
return $this->getFallbackColors();
}
return $this->ensureCompleteColors($colors);
}
/**
* WordPress 5.9+ Global Styles API - includes user customizations
*/
public function getColorsFromGlobalStyles(): array
{
if (!function_exists('wp_get_global_styles')) {
return [];
}
$globalStyles = wp_get_global_styles();
if (isset($globalStyles['color']['palette'])) {
$palette = $globalStyles['color']['palette'];
return $this->mapPaletteToStandardColors($palette);
}
return $this->getButtonColorsFromGlobalStyles($globalStyles);
}
/**
* Theme JSON resolver - theme defaults before user customizations
*/
public function getColorsFromThemeJson(): array
{
if (
!class_exists('WP_Theme_JSON_Resolver')
|| !function_exists('wp_get_theme')
) {
return [];
}
try {
$theme = wp_get_theme()->get_stylesheet();
$settings = \WP_Theme_JSON_Resolver::get_merged_data($theme)->get_settings();
$themeColors = ($settings['color']['palette']['theme'] ?? []);
} catch (\Exception $e) {
return [];
}
return $this->mapPaletteToStandardColors($themeColors);
}
/**
* Maps various theme color names (accent, main, etc.) to standard keys
*/
private function mapPaletteToStandardColors(array $palette): array
{
$colors = [];
foreach ($palette as $color) {
if (!isset($color['slug']) || !isset($color['color'])) {
continue;
}
$slug = $color['slug'];
$colorValue = $color['color'];
foreach ($this->wpColorMappings as $ourType => $wpSlugs) {
if (in_array($slug, $wpSlugs, true)) {
$colors[$ourType] = $colorValue;
break;
}
}
}
return $colors;
}
/**
* Extracts button and link colors from Global Styles elements
* For widget: primary=background, secondary=text, active=accent-1
*/
private function getButtonColorsFromGlobalStyles(array $globalStyles): array
{
$colors = [];
// Extract theme background for primary
if (isset($globalStyles['color']['background'])) {
$colors['primary'] = $this->colorUtility->resolveColorToHex($globalStyles['color']['background']);
}
// Extract theme text for secondary
if (isset($globalStyles['color']['text'])) {
$colors['secondary'] = $this->colorUtility->resolveColorToHex($globalStyles['color']['text']);
}
// For active color, prioritize accent-1 over button background
// This ensures we get the theme's primary accent color
$colors['active'] = $this->colorUtility->resolveColorToHex('var(--wp--preset--color--accent-1)');
// Extract button text color if available
if (isset($globalStyles['elements']['button']['color']['text'])) {
$colors['text'] = $this->colorUtility->resolveColorToHex($globalStyles['elements']['button']['color']['text']);
}
// If accent-1 couldn't be resolved, fall back to a button background
if ($colors['active'] === 'var(--wp--preset--color--accent-1)') {
if (isset($globalStyles['elements']['button']['color']['background'])) {
$colors['active'] = $this->colorUtility->resolveColorToHex($globalStyles['elements']['button']['color']['background']);
} elseif (isset($globalStyles['elements']['link']['color']['text'])) {
$colors['active'] = $this->colorUtility->resolveColorToHex($globalStyles['elements']['link']['color']['text']);
}
}
return $colors;
}
/**
* Fills missing colors with fallbacks and resolves CSS variables
*/
private function ensureCompleteColors(array $colors): array
{
$normalized = [];
$fallbackColors = $this->getFallbackColors();
if (empty($fallbackColors)) {
return [];
}
foreach ($fallbackColors as $type => $fallback) {
$colorValue = $colors[$type] ?? $fallback;
$normalized[$type] = $this->colorUtility->resolveColorToHex($colorValue);
}
return $normalized;
}
/**
* Standard WordPress CSS variables - works with any modern block theme
* For widget: primary=background, secondary=text, active=button
*/
public function getColorsFromCssVariables(): array
{
$rawColors = [
'primary' => 'var(--wp--preset--color--background)',
'secondary' => 'var(--wp--preset--color--contrast)',
'active' => 'var(--wp--preset--color--accent-1)',
'background' => 'var(--wp--preset--color--background)',
'foreground' => 'var(--wp--preset--color--foreground)',
'text' => 'var(--wp--preset--color--contrast)',
];
$colors = [];
foreach ($rawColors as $type => $cssVar) {
$colors[$type] = $this->colorUtility->resolveColorToHex($cssVar);
}
return $colors;
}
public function getFallbackColors(): array
{
return [
'primary' => '#FF3259',
'secondary' => '#000000',
'active' => '#055B78',
'background' => '#f7f7f7',
'foreground' => '#494949',
'text' => '#ffffff',
];
}
}