PluginProbe
404 Solution / 4.2.0
404 Solution v4.2.0
4.3.5 4.3.4 4.3.3 4.3.2 4.3.1 4.3.0 4.2.0 4.1.19 4.1.18 4.1.17 4.1.16 4.1.15 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.1.7 4.1.6 4.1.5 4.1.4 4.1.3 trunk 2.30.0 All 109 releases
404-solution / includes / AdminThemeManager.php

AdminThemeManager.php in 404 Solution 4.2.0, at includes/AdminThemeManager.php

199 lines 7.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 /**
8 * Admin theme detection and critical CSS output.
9 *
10 * Detects dark mode from WordPress color schemes, dark mode plugins,
11 * and browser preferences. Outputs critical theme CSS inline in the
12 * <head> to prevent flash of unstyled content.
13 */
14 class ABJ_404_Solution_AdminThemeManager {
15
16 /** Detect if dark mode is enabled from various sources.
17 *
18 * @return bool True if dark mode is detected
19 */
20 static function isDarkModeDetected() {
21 $current_user_id = get_current_user_id();
22 if ($current_user_id) {
23 $admin_color = get_user_meta($current_user_id, 'admin_color', true);
24 $dark_schemes = array('midnight', 'ectoplasm', 'coffee');
25 if (in_array($admin_color, $dark_schemes)) {
26 return true;
27 }
28 }
29
30 if (get_option('wp_dark_mode_enabled')) {
31 return true;
32 }
33
34 if (get_option('dark_mode_for_wp_dashboard_enabled')) {
35 return true;
36 }
37
38 if (class_exists('WP_Dark_Mode') || class_exists('Dark_Mode_For_WP_Dashboard')) {
39 return true;
40 }
41
42 return false;
43 }
44
45 /**
46 * @return string The theme to use ('obsidian' for dark mode, 'default' otherwise)
47 */
48 static function getAutoSelectedTheme() {
49 if (self::isDarkModeDetected()) {
50 return 'obsidian';
51 }
52 return 'default';
53 }
54
55 /**
56 * Output critical theme CSS inline to prevent FOUC.
57 *
58 * @return void
59 */
60 static function outputCriticalThemeCSS() {
61 try {
62 if (!array_key_exists('abj404_settingsPageName', $GLOBALS) ||
63 !array_key_exists('page', $_GET) ||
64 $_GET['page'] != ABJ404_PP) {
65 return;
66 }
67
68 $logic = abj_service('plugin_logic');
69 $options = $logic->getOptions();
70 $theme = (isset($options['admin_theme']) && is_string($options['admin_theme'])) ? $options['admin_theme'] : 'default';
71
72 $auto_dark_mode = !isset($options['disable_auto_dark_mode']) || $options['disable_auto_dark_mode'] != '1';
73
74 if ($theme === 'default' && $auto_dark_mode) {
75 $theme = self::getAutoSelectedTheme();
76 }
77
78 $allowed_themes = array('default', 'calm', 'mono', 'neon', 'obsidian');
79 if (!in_array($theme, $allowed_themes)) {
80 $theme = 'default';
81 }
82
83 if ($theme === 'default') {
84 $html = ABJ_404_Solution_Functions::readFileContents(__DIR__ . "/html/themeRemoverScript.html");
85 echo $html;
86 return;
87 }
88
89 $html = ABJ_404_Solution_Functions::readFileContents(__DIR__ . "/html/themeSetterScript.html");
90 $f = abj_service('functions');
91 $html = $f->str_replace('{theme}', esc_js($theme), $html);
92 echo $html;
93
94 $themeVariables = array(
95 'mono' => array(
96 '--abj404-bg' => '#F8FAFC',
97 '--abj404-bg-muted' => '#F5F7FA',
98 '--abj404-surface' => '#ffffff',
99 '--abj404-surface-muted' => '#F1F5F9',
100 '--abj404-text' => '#111827',
101 '--abj404-text-muted' => '#6B7280',
102 '--abj404-border' => '#E5E7EB',
103 '--abj404-primary' => '#374151',
104 '--abj404-accent' => '#2563EB',
105 '--abj404-info' => '#3B82F6',
106 '--abj404-success' => '#10B981',
107 '--abj404-warning' => '#F59E0B',
108 '--abj404-danger' => '#EF4444',
109 '--abj404-focus' => '#93C5FD',
110 '--abj404-table-header' => '#F1F5F9',
111 '--abj404-row-hover' => '#F5F7FA',
112 '--abj404-row-selected' => '#DBEAFE',
113 '--abj404-badge-bg' => '#EFF1F5',
114 '--abj404-badge-text' => '#374151',
115 ),
116 'calm' => array(
117 '--abj404-bg' => '#F7FAFD',
118 '--abj404-bg-muted' => '#F1F6FE',
119 '--abj404-surface' => '#ffffff',
120 '--abj404-surface-muted' => '#E9F0FB',
121 '--abj404-text' => '#17223B',
122 '--abj404-text-muted' => '#5A6B86',
123 '--abj404-border' => '#E1E8F5',
124 '--abj404-primary' => '#1E6BD6',
125 '--abj404-accent' => '#00A27A',
126 '--abj404-info' => '#2B8AE2',
127 '--abj404-success' => '#20B67A',
128 '--abj404-warning' => '#F6A700',
129 '--abj404-danger' => '#D53F3F',
130 '--abj404-focus' => '#5AA2FF',
131 '--abj404-table-header' => '#E9F0FB',
132 '--abj404-row-hover' => '#F1F6FE',
133 '--abj404-row-selected' => '#D7E8FF',
134 '--abj404-badge-bg' => '#EEF2F8',
135 '--abj404-badge-text' => '#3E546E',
136 ),
137 'neon' => array(
138 '--abj404-bg' => '#0C0F13',
139 '--abj404-bg-muted' => '#11151A',
140 '--abj404-surface' => '#151A21',
141 '--abj404-surface-muted' => '#1B222B',
142 '--abj404-text' => '#E5EAF2',
143 '--abj404-text-muted' => '#A6B0C3',
144 '--abj404-border' => '#273141',
145 '--abj404-primary' => '#7C3AED',
146 '--abj404-accent' => '#22D3EE',
147 '--abj404-info' => '#60A5FA',
148 '--abj404-success' => '#34D399',
149 '--abj404-warning' => '#F59E0B',
150 '--abj404-danger' => '#F87171',
151 '--abj404-focus' => '#38BDF8',
152 '--abj404-table-header' => '#1F2732',
153 '--abj404-row-hover' => '#192028',
154 '--abj404-row-selected' => '#0E2936',
155 '--abj404-badge-bg' => '#202734',
156 '--abj404-badge-text' => '#CFD8E6',
157 ),
158 'obsidian' => array(
159 '--abj404-bg' => '#0A0F1A',
160 '--abj404-bg-muted' => '#0E1522',
161 '--abj404-surface' => '#121826',
162 '--abj404-surface-muted' => '#172032',
163 '--abj404-text' => '#E6ECF7',
164 '--abj404-text-muted' => '#A9B7CC',
165 '--abj404-border' => '#223149',
166 '--abj404-primary' => '#1D4ED8',
167 '--abj404-accent' => '#A78BFA',
168 '--abj404-info' => '#60A5FA',
169 '--abj404-success' => '#22C55E',
170 '--abj404-warning' => '#F59E0B',
171 '--abj404-danger' => '#EF4444',
172 '--abj404-focus' => '#93C5FD',
173 '--abj404-table-header' => '#1B253A',
174 '--abj404-row-hover' => '#141C2C',
175 '--abj404-row-selected' => '#1A2A46',
176 '--abj404-badge-bg' => '#1A2438',
177 '--abj404-badge-text' => '#DCE6F7',
178 ),
179 );
180
181 /** @var string $themeKey */
182 $themeKey = $theme;
183 if (isset($themeVariables[$themeKey])) {
184 $cssVars = '';
185 foreach ($themeVariables[$themeKey] as $var => $value) {
186 $cssVars .= esc_html($var) . ':' . esc_html($value) . ';';
187 }
188
189 $html = ABJ_404_Solution_Functions::readFileContents(__DIR__ . "/html/criticalThemeCSS.html");
190 $f = abj_service('functions');
191 $html = $f->str_replace('{css_variables}', $cssVars, $html);
192 echo $html;
193 }
194 } catch (Throwable $e) {
195 ABJ_404_Solution_WordPress_Connector::reportAdminRuntimeError('admin_head', $e);
196 }
197 }
198 }
199