Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
6.02% |
10 / 166 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
PlayerColors | |
6.02% |
10 / 166 |
|
0.00% |
0 / 9 |
318.61 | |
0.00% |
0 / 1 |
init | |
55.56% |
10 / 18 |
|
0.00% |
0 / 1 |
1.09 | |||
addPlayerThemeSetting | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
2 | |||
addPlayerColorsSetting | |
0.00% |
0 / 45 |
|
0.00% |
0 / 1 |
2 | |||
renderPlayerThemeSetting | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
6 | |||
sanitizeColorsArray | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
42 | |||
sanitizeColor | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
getPlayerThemeOptions | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
2 | |||
renderPlayerColorsSetting | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
2 | |||
playerColorsTable | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | /** |
6 | * Setting: Player colors |
7 | * |
8 | * @package Beyondwords\Wordpress |
9 | * @author Stuart McAlpine <stu@beyondwords.io> |
10 | * @since 5.0.0 |
11 | */ |
12 | |
13 | namespace Beyondwords\Wordpress\Component\Settings\Fields\PlayerColors; |
14 | |
15 | use Beyondwords\Wordpress\Component\Settings\SettingsUtils; |
16 | use Beyondwords\Wordpress\Component\Settings\Sync; |
17 | |
18 | /** |
19 | * PlayerColors |
20 | * |
21 | * @since 5.0.0 |
22 | */ |
23 | class PlayerColors |
24 | { |
25 | /** |
26 | * Option name. |
27 | */ |
28 | public const OPTION_NAME_THEME = 'beyondwords_player_theme'; |
29 | |
30 | /** |
31 | * Option name. |
32 | */ |
33 | public const OPTION_NAME_LIGHT_THEME = 'beyondwords_player_theme_light'; |
34 | |
35 | /** |
36 | * Option name. |
37 | */ |
38 | public const OPTION_NAME_DARK_THEME = 'beyondwords_player_theme_dark'; |
39 | |
40 | /** |
41 | * Option name. |
42 | */ |
43 | public const OPTION_NAME_VIDEO_THEME = 'beyondwords_player_theme_video'; |
44 | |
45 | /** |
46 | * Init. |
47 | * |
48 | * @since 5.0.0 |
49 | */ |
50 | public function init() |
51 | { |
52 | add_action('admin_init', array($this, 'addPlayerThemeSetting')); |
53 | add_action('admin_init', array($this, 'addPlayerColorsSetting')); |
54 | add_action('pre_update_option_' . self::OPTION_NAME_THEME, function ($value) { |
55 | Sync::syncOptionToDashboard(self::OPTION_NAME_THEME); |
56 | return $value; |
57 | }); |
58 | add_action('pre_update_option_' . self::OPTION_NAME_LIGHT_THEME, function ($value) { |
59 | Sync::syncOptionToDashboard(self::OPTION_NAME_LIGHT_THEME); |
60 | return $value; |
61 | }); |
62 | add_action('pre_update_option_' . self::OPTION_NAME_DARK_THEME, function ($value) { |
63 | Sync::syncOptionToDashboard(self::OPTION_NAME_DARK_THEME); |
64 | return $value; |
65 | }); |
66 | add_action('pre_update_option_' . self::OPTION_NAME_VIDEO_THEME, function ($value) { |
67 | Sync::syncOptionToDashboard(self::OPTION_NAME_VIDEO_THEME); |
68 | return $value; |
69 | }); |
70 | } |
71 | |
72 | /** |
73 | * Init "Player color" setting. |
74 | * |
75 | * @since 5.0.0 |
76 | * |
77 | * @return void |
78 | */ |
79 | public function addPlayerThemeSetting() |
80 | { |
81 | register_setting( |
82 | 'beyondwords_player_settings', |
83 | self::OPTION_NAME_THEME, |
84 | [ |
85 | 'default' => '', |
86 | ] |
87 | ); |
88 | |
89 | add_settings_field( |
90 | 'beyondwords-player-theme', |
91 | __('Player theme', 'speechkit'), |
92 | array($this, 'renderPlayerThemeSetting'), |
93 | 'beyondwords_player', |
94 | 'styling' |
95 | ); |
96 | } |
97 | |
98 | /** |
99 | * Init "Player colors" setting. |
100 | * |
101 | * @since 5.0.0 |
102 | * |
103 | * @return void |
104 | */ |
105 | public function addPlayerColorsSetting() |
106 | { |
107 | register_setting( |
108 | 'beyondwords_player_settings', |
109 | self::OPTION_NAME_LIGHT_THEME, |
110 | [ |
111 | 'default' => [ |
112 | 'background_color' => '#f5f5f5', |
113 | 'icon_color' => '#000', |
114 | 'text_color' => '#111', |
115 | 'highlight_color' => '#eee', |
116 | ], |
117 | 'sanitize_callback' => array($this, 'sanitizeColorsArray'), |
118 | ] |
119 | ); |
120 | |
121 | register_setting( |
122 | 'beyondwords_player_settings', |
123 | self::OPTION_NAME_DARK_THEME, |
124 | [ |
125 | 'default' => [ |
126 | 'background_color' => '#f5f5f5', |
127 | 'icon_color' => '#000', |
128 | 'text_color' => '#111', |
129 | 'highlight_color' => '#eee', |
130 | ], |
131 | 'sanitize_callback' => array($this, 'sanitizeColorsArray'), |
132 | ] |
133 | ); |
134 | |
135 | register_setting( |
136 | 'beyondwords_player_settings', |
137 | self::OPTION_NAME_VIDEO_THEME, |
138 | [ |
139 | 'default' => [ |
140 | 'background_color' => '#000', |
141 | 'icon_color' => '#fff', |
142 | 'text_color' => '#fff', |
143 | ], |
144 | 'sanitize_callback' => array($this, 'sanitizeColorsArray'), |
145 | ] |
146 | ); |
147 | |
148 | add_settings_field( |
149 | 'beyondwords-player-colors', |
150 | __('Player colors', 'speechkit'), |
151 | array($this, 'renderPlayerColorsSetting'), |
152 | 'beyondwords_player', |
153 | 'styling' |
154 | ); |
155 | } |
156 | |
157 | /** |
158 | * Render setting field. |
159 | * |
160 | * @since 5.0.0 |
161 | * |
162 | * @return string |
163 | **/ |
164 | public function renderPlayerThemeSetting() |
165 | { |
166 | $current = get_option(self::OPTION_NAME_THEME); |
167 | $themeOptions = $this->getPlayerThemeOptions(); |
168 | ?> |
169 | <div class="beyondwords-setting__player beyondwords-setting__player--player-colors"> |
170 | <select name="<?php echo esc_attr(self::OPTION_NAME_THEME) ?>"> |
171 | <?php |
172 | foreach ($themeOptions as $option) { |
173 | printf( |
174 | '<option value="%s" %s>%s</option>', |
175 | esc_attr($option['value']), |
176 | selected($option['value'], $current), |
177 | esc_html($option['label']) |
178 | ); |
179 | } |
180 | ?> |
181 | </select> |
182 | </div> |
183 | <?php |
184 | } |
185 | |
186 | /** |
187 | * Sanitise the colors array setting value. |
188 | * |
189 | * @since 5.0.0 |
190 | * |
191 | * @param array $value The submitted value. |
192 | * |
193 | * @return array The sanitized value. |
194 | **/ |
195 | public function sanitizeColorsArray($value) |
196 | { |
197 | if (!is_array($value)) { |
198 | return []; |
199 | } |
200 | |
201 | $value['background_color'] = $this->sanitizeColor($value['background_color'] ?: ''); |
202 | $value['text_color'] = $this->sanitizeColor($value['text_color'] ?: ''); |
203 | $value['icon_color'] = $this->sanitizeColor($value['icon_color'] ?: ''); |
204 | |
205 | // Highlight doesn't exist for video player |
206 | if (!empty($value['highlight_color'])) { |
207 | $value['highlight_color'] = $this->sanitizeColor($value['highlight_color']); |
208 | } |
209 | |
210 | return $value; |
211 | } |
212 | |
213 | /** |
214 | * Sanitize an individual color value. |
215 | * |
216 | * @since 5.0.0 |
217 | * |
218 | * @param string $value The submitted individual color value. |
219 | * |
220 | * @return array The sanitized value. |
221 | **/ |
222 | public function sanitizeColor($value) |
223 | { |
224 | $value = strtolower(trim((string)$value)); |
225 | |
226 | // Prepend hash to hexidecimal values, if missing |
227 | if (preg_match("/^[0-9a-f]+$/", $value)) { |
228 | $value = '#' . $value; |
229 | } |
230 | |
231 | return $value; |
232 | } |
233 | |
234 | /** |
235 | * Get all options for the current component. |
236 | * |
237 | * @since 5.0.0 |
238 | * |
239 | * @return string[] Associative array of player theme options. |
240 | **/ |
241 | public function getPlayerThemeOptions() |
242 | { |
243 | $themeOptions = [ |
244 | [ |
245 | 'value' => 'light', |
246 | 'label' => 'Light (default)', |
247 | ], |
248 | [ |
249 | 'value' => 'dark', |
250 | 'label' => 'Dark', |
251 | ], |
252 | [ |
253 | 'value' => 'auto', |
254 | 'label' => 'Auto', |
255 | ], |
256 | ]; |
257 | |
258 | return $themeOptions; |
259 | } |
260 | |
261 | /** |
262 | * Render setting field. |
263 | * |
264 | * @since 5.0.0 |
265 | * |
266 | * @return string |
267 | **/ |
268 | public function renderPlayerColorsSetting() |
269 | { |
270 | $lightTheme = get_option(self::OPTION_NAME_LIGHT_THEME); |
271 | $darkTheme = get_option(self::OPTION_NAME_DARK_THEME); |
272 | $videoTheme = get_option(self::OPTION_NAME_VIDEO_THEME); |
273 | |
274 | $this->playerColorsTable( |
275 | __('Light theme settings', 'speechkit'), |
276 | self::OPTION_NAME_LIGHT_THEME, |
277 | $lightTheme, |
278 | ); |
279 | |
280 | $this->playerColorsTable( |
281 | __('Dark theme settings', 'speechkit'), |
282 | self::OPTION_NAME_DARK_THEME, |
283 | $darkTheme, |
284 | ); |
285 | |
286 | $this->playerColorsTable( |
287 | __('Video theme settings', 'speechkit'), |
288 | self::OPTION_NAME_VIDEO_THEME, |
289 | $videoTheme, |
290 | ); |
291 | } |
292 | |
293 | /** |
294 | * A player colors table. |
295 | * |
296 | * @since 5.0.0 |
297 | * |
298 | * @return string |
299 | **/ |
300 | public function playerColorsTable($title, $name, $value) |
301 | { |
302 | ?> |
303 | <h3 class="subheading"> |
304 | <?php echo esc_html($title); ?> |
305 | </h3> |
306 | <div class="color-pickers"> |
307 | <div class="row"> |
308 | <?php |
309 | SettingsUtils::colorInput( |
310 | __('Background', 'speechkit'), |
311 | sprintf('%s[background_color]', $name), |
312 | $value['background_color'] ?: '' |
313 | ); |
314 | ?> |
315 | </div> |
316 | <div class="row"> |
317 | <?php |
318 | SettingsUtils::colorInput( |
319 | __('Icons', 'speechkit'), |
320 | sprintf('%s[icon_color]', $name), |
321 | $value['icon_color'] ?: '' |
322 | ); |
323 | ?> |
324 | </div> |
325 | <div class="row"> |
326 | <?php |
327 | SettingsUtils::colorInput( |
328 | __('Text color', 'speechkit'), |
329 | sprintf('%s[text_color]', $name), |
330 | $value['text_color'] ?: '' |
331 | ); |
332 | ?> |
333 | </div> |
334 | </div> |
335 | <?php |
336 | } |
337 | } |