Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
94.92% |
187 / 197 |
|
81.82% |
9 / 11 |
CRAP | |
0.00% |
0 / 1 |
SiteHealth | |
94.92% |
187 / 197 |
|
81.82% |
9 / 11 |
34.15 | |
0.00% |
0 / 1 |
init | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
debugInformation | |
100.00% |
28 / 28 |
|
100.00% |
1 / 1 |
1 | |||
addContentSettings | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
7 | |||
addProjectSettings | |
100.00% |
24 / 24 |
|
100.00% |
1 / 1 |
1 | |||
addPlayerSettings | |
100.00% |
50 / 50 |
|
100.00% |
1 / 1 |
5 | |||
addPluginVersion | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
4 | |||
addRestApiConnection | |
64.00% |
16 / 25 |
|
0.00% |
0 / 1 |
2.19 | |||
addFilters | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
5 | |||
addNoticeSettings | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
addConstant | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
4.02 | |||
maskString | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | declare(strict_types=1); |
4 | |
5 | /** |
6 | * BeyondWords SiteHealth. |
7 | * |
8 | * @package Beyondwords\Wordpress |
9 | * @author Stuart McAlpine <stu@beyondwords.io> |
10 | * @since 3.7.0 |
11 | */ |
12 | |
13 | namespace Beyondwords\Wordpress\Component\SiteHealth; |
14 | |
15 | use Beyondwords\Wordpress\Component\Settings\SettingsUtils; |
16 | use Beyondwords\Wordpress\Core\Environment; |
17 | |
18 | /** |
19 | * BeyondWords SiteHealth. |
20 | * |
21 | * @since 3.7.0 |
22 | */ |
23 | class SiteHealth |
24 | { |
25 | /** |
26 | * @var string[] List of current filters to check. |
27 | * |
28 | * @since 3.7.0 Introduced. |
29 | * @since 4.3.0 Filters refactoring - many were removed and renamed. |
30 | */ |
31 | public const FILTERS = [ |
32 | 'beyondwords_content_params', |
33 | 'beyondwords_player_script_onload', |
34 | 'beyondwords_player_html', |
35 | 'beyondwords_player_sdk_params', |
36 | 'beyondwords_settings_player_styles', |
37 | 'beyondwords_settings_post_types', |
38 | 'beyondwords_settings_post_statuses', |
39 | ]; |
40 | |
41 | /** |
42 | * @var string[] List of deprecated filters to check. |
43 | * |
44 | * @since 3.7.0 Introduced. |
45 | * @since 4.3.0 Filters refactoring - many were removed and renamed. |
46 | */ |
47 | public const DEPRECATED_FILTERS = [ |
48 | 'beyondwords_amp_player_html', |
49 | 'beyondwords_body_params', |
50 | 'beyondwords_content', |
51 | 'beyondwords_content_id', |
52 | 'beyondwords_js_player_html', |
53 | 'beyondwords_js_player_params', |
54 | 'beyondwords_player_styles', |
55 | 'beyondwords_post_audio_enabled_blocks', |
56 | 'beyondwords_post_metadata', |
57 | 'beyondwords_post_player_enabled', |
58 | 'beyondwords_post_statuses', |
59 | 'beyondwords_post_types', |
60 | 'beyondwords_project_id', |
61 | 'sk_player_after', |
62 | 'sk_player_before', |
63 | 'sk_the_content', |
64 | 'speechkit_amp_player_html', |
65 | 'speechkit_content', |
66 | 'speechkit_js_player_html', |
67 | 'speechkit_js_player_params', |
68 | 'speechkit_post_player_enabled', |
69 | 'speechkit_post_statuses', |
70 | 'speechkit_post_types', |
71 | ]; |
72 | |
73 | /** |
74 | * Init |
75 | * |
76 | * @since 4.0.0 |
77 | */ |
78 | public function init() |
79 | { |
80 | add_filter('debug_information', array($this, 'debugInformation')); |
81 | } |
82 | |
83 | /** |
84 | * Add "Site Health" navigation tab. |
85 | * |
86 | * @since 3.7.0 |
87 | * |
88 | * @param array $info |
89 | * |
90 | * @return array |
91 | */ |
92 | public function debugInformation($info) |
93 | { |
94 | $info['beyondwords']['label'] = __('BeyondWords - Text-to-Speech', 'speechkit'); |
95 | |
96 | $this->addPluginVersion($info); |
97 | $this->addRestApiConnection($info); |
98 | |
99 | $info['beyondwords']['fields']['compatible-post-types'] = [ |
100 | 'label' => __('Compatible post types', 'speechkit'), |
101 | 'value' => implode(', ', SettingsUtils::getCompatiblePostTypes()), |
102 | ]; |
103 | |
104 | $info['beyondwords']['fields']['incompatible-post-types'] = [ |
105 | 'label' => __('Incompatible post types', 'speechkit'), |
106 | 'value' => implode(', ', SettingsUtils::getIncompatiblePostTypes()), |
107 | ]; |
108 | |
109 | $info['beyondwords']['fields']['beyondwords_api_key'] = [ |
110 | 'label' => __('API Key', 'speechkit'), |
111 | 'value' => SiteHealth::maskString(get_option('beyondwords_api_key')), |
112 | ]; |
113 | |
114 | $info['beyondwords']['fields']['beyondwords_project_id'] = [ |
115 | 'label' => __('Project ID', 'speechkit'), |
116 | 'value' => get_option('beyondwords_project_id'), |
117 | ]; |
118 | |
119 | $this->addContentSettings($info); |
120 | $this->addProjectSettings($info); |
121 | $this->addPlayerSettings($info); |
122 | $this->addFilters($info); |
123 | $this->addNoticeSettings($info); |
124 | |
125 | $this->addConstant($info, 'BEYONDWORDS_AUTO_SYNC_SETTINGS'); |
126 | $this->addConstant($info, 'BEYONDWORDS_AUTOREGENERATE'); |
127 | $this->addConstant($info, 'BEYONDWORDS_PLAYER_INLINE_SCRIPT_TAG'); |
128 | |
129 | return $info; |
130 | } |
131 | |
132 | /** |
133 | * Add content settings to the info debugging array. |
134 | * |
135 | * @since 5.0.0 |
136 | * |
137 | * @param array $info Debugging info array |
138 | * |
139 | * @return array |
140 | */ |
141 | public function addContentSettings(&$info) |
142 | { |
143 | $info['beyondwords']['fields']['beyondwords_project_title_enabled'] = [ |
144 | 'label' => __('Include title in audio', 'speechkit'), |
145 | 'value' => get_option('beyondwords_project_title_enabled') ? __('Yes', 'speechkit') : __('No', 'speechkit'), // phpcs:ignore Generic.Files.LineLength.TooLong |
146 | 'debug' => get_option('beyondwords_project_title_enabled') ? 'yes' : 'no', |
147 | ]; |
148 | |
149 | $info['beyondwords']['fields']['beyondwords_project_auto_publish_enabled'] = [ |
150 | 'label' => __('Auto-publish audio', 'speechkit'), |
151 | 'value' => get_option('beyondwords_project_auto_publish_enabled') ? __('Yes', 'speechkit') : __('No', 'speechkit'), // phpcs:ignore Generic.Files.LineLength.TooLong |
152 | 'debug' => get_option('beyondwords_project_auto_publish_enabled') ? 'yes' : 'no', |
153 | ]; |
154 | |
155 | $info['beyondwords']['fields']['beyondwords_prepend_excerpt'] = [ |
156 | 'label' => __('Include excerpts in audio', 'speechkit'), |
157 | 'value' => get_option('beyondwords_prepend_excerpt') ? __('Yes', 'speechkit') : __('No', 'speechkit'), // phpcs:ignore Generic.Files.LineLength.TooLong |
158 | 'debug' => get_option('beyondwords_prepend_excerpt') ? 'yes' : 'no', |
159 | ]; |
160 | |
161 | $info['beyondwords']['fields']['beyondwords_preselect'] = [ |
162 | 'label' => __('Preselect ‘Generate audio’', 'speechkit'), |
163 | 'value' => (string) wp_json_encode(get_option('beyondwords_preselect'), JSON_PRETTY_PRINT), |
164 | ]; |
165 | } |
166 | |
167 | /** |
168 | * Add project settings to the info debugging array. |
169 | * |
170 | * @since 5.0.0 |
171 | * |
172 | * @param array $info Debugging info array |
173 | * |
174 | * @return array |
175 | */ |
176 | public function addProjectSettings(&$info) |
177 | { |
178 | $info['beyondwords']['fields']['beyondwords_project_language_code'] = [ |
179 | 'label' => __('Default language code', 'speechkit'), |
180 | 'value' => get_option('beyondwords_project_language_code'), |
181 | ]; |
182 | |
183 | $info['beyondwords']['fields']['beyondwords_project_language_id'] = [ |
184 | 'label' => __('Default language ID', 'speechkit'), |
185 | 'value' => get_option('beyondwords_project_language_id'), |
186 | ]; |
187 | |
188 | $info['beyondwords']['fields']['beyondwords_project_title_voice_id'] = [ |
189 | 'label' => __('Title voice ID', 'speechkit'), |
190 | 'value' => get_option('beyondwords_project_title_voice_id'), |
191 | ]; |
192 | |
193 | $info['beyondwords']['fields']['beyondwords_project_title_voice_speaking_rate'] = [ |
194 | 'label' => __('Title voice speaking rate', 'speechkit'), |
195 | 'value' => get_option('beyondwords_project_title_voice_speaking_rate'), |
196 | ]; |
197 | |
198 | $info['beyondwords']['fields']['beyondwords_project_body_voice_id'] = [ |
199 | 'label' => __('Body voice ID', 'speechkit'), |
200 | 'value' => get_option('beyondwords_project_body_voice_id'), |
201 | ]; |
202 | |
203 | $info['beyondwords']['fields']['beyondwords_project_body_voice_speaking_rate'] = [ |
204 | 'label' => __('Body voice speaking rate', 'speechkit'), |
205 | 'value' => get_option('beyondwords_project_body_voice_speaking_rate'), |
206 | ]; |
207 | } |
208 | |
209 | /** |
210 | * Add player settings to the info debugging array. |
211 | * |
212 | * @since 5.0.0 |
213 | * |
214 | * @param array $info Debugging info array |
215 | * |
216 | * @return array |
217 | */ |
218 | public function addPlayerSettings(&$info) |
219 | { |
220 | $info['beyondwords']['fields']['beyondwords_player_ui'] = [ |
221 | 'label' => __('Player UI', 'speechkit'), |
222 | 'value' => get_option('beyondwords_player_ui'), |
223 | ]; |
224 | |
225 | $info['beyondwords']['fields']['beyondwords_player_style'] = [ |
226 | 'label' => __('Player style', 'speechkit'), |
227 | 'value' => get_option('beyondwords_player_style'), |
228 | ]; |
229 | |
230 | $info['beyondwords']['fields']['beyondwords_player_theme'] = [ |
231 | 'label' => __('Player theme', 'speechkit'), |
232 | 'value' => get_option('beyondwords_player_theme'), |
233 | ]; |
234 | |
235 | $info['beyondwords']['fields']['beyondwords_player_theme_light'] = [ |
236 | 'label' => __('Light theme', 'speechkit'), |
237 | 'value' => (string) wp_json_encode(get_option('beyondwords_player_theme_light'), JSON_PRETTY_PRINT), |
238 | ]; |
239 | |
240 | $info['beyondwords']['fields']['beyondwords_player_theme_dark'] = [ |
241 | 'label' => __('Dark theme', 'speechkit'), |
242 | 'value' => (string) wp_json_encode(get_option('beyondwords_player_theme_dark'), JSON_PRETTY_PRINT), |
243 | ]; |
244 | |
245 | $info['beyondwords']['fields']['beyondwords_player_theme_video'] = [ |
246 | 'label' => __('Video theme', 'speechkit'), |
247 | 'value' => (string) wp_json_encode(get_option('beyondwords_player_theme_video'), JSON_PRETTY_PRINT), |
248 | ]; |
249 | |
250 | $info['beyondwords']['fields']['beyondwords_player_call_to_action'] = [ |
251 | 'label' => __('Call-to-action', 'speechkit'), |
252 | 'value' => get_option('beyondwords_player_call_to_action'), |
253 | ]; |
254 | |
255 | $info['beyondwords']['fields']['beyondwords_player_highlight_sections'] = [ |
256 | 'label' => __('Text highlighting', 'speechkit'), |
257 | 'value' => get_option('beyondwords_player_highlight_sections') ? __('Yes', 'speechkit') : __('No', 'speechkit'), // phpcs:ignore Generic.Files.LineLength.TooLong |
258 | 'debug' => get_option('beyondwords_player_highlight_sections') ? 'yes' : 'no', |
259 | ]; |
260 | |
261 | $info['beyondwords']['fields']['beyondwords_player_clickable_sections'] = [ |
262 | 'label' => __('Playback from segments', 'speechkit'), |
263 | 'value' => get_option('beyondwords_player_clickable_sections') ? __('Yes', 'speechkit') : __('No', 'speechkit'), // phpcs:ignore Generic.Files.LineLength.TooLong |
264 | 'debug' => get_option('beyondwords_player_clickable_sections') ? 'yes' : 'no', |
265 | ]; |
266 | |
267 | $info['beyondwords']['fields']['beyondwords_player_widget_style'] = [ |
268 | 'label' => __('Widget style', 'speechkit'), |
269 | 'value' => get_option('beyondwords_player_widget_style'), |
270 | ]; |
271 | |
272 | $info['beyondwords']['fields']['beyondwords_player_widget_position'] = [ |
273 | 'label' => __('Widget position', 'speechkit'), |
274 | 'value' => get_option('beyondwords_player_widget_position'), |
275 | ]; |
276 | |
277 | $info['beyondwords']['fields']['beyondwords_player_skip_button_style'] = [ |
278 | 'label' => __('Skip button style', 'speechkit'), |
279 | 'value' => get_option('beyondwords_player_skip_button_style'), |
280 | ]; |
281 | } |
282 | |
283 | /** |
284 | * Add plugin version to the info debugging array. |
285 | * |
286 | * @since 3.7.0 |
287 | * |
288 | * @param array $info Debugging info array |
289 | * |
290 | * @return array |
291 | */ |
292 | public function addPluginVersion(&$info) |
293 | { |
294 | $constVersion = defined('BEYONDWORDS__PLUGIN_VERSION') ? BEYONDWORDS__PLUGIN_VERSION : ''; |
295 | $dbVersion = get_option('beyondwords_version'); |
296 | |
297 | if ($constVersion && $constVersion === $dbVersion) { |
298 | $info['beyondwords']['fields']['plugin-version'] = [ |
299 | 'label' => __('Plugin version', 'speechkit'), |
300 | 'value' => BEYONDWORDS__PLUGIN_VERSION, |
301 | ]; |
302 | } else { |
303 | $info['beyondwords']['fields']['plugin-version'] = [ |
304 | 'label' => __('Plugin version', 'speechkit'), |
305 | 'value' => sprintf( |
306 | /* translators: 1: Current plugin version, 2: Database plugin version */ |
307 | __('Version mismatch: file: %1$s / db: %2$s', 'speechkit'), |
308 | $constVersion, |
309 | $dbVersion |
310 | ), |
311 | ]; |
312 | } |
313 | } |
314 | |
315 | /** |
316 | * Adds debugging data for the BeyondWords REST API connection. |
317 | * |
318 | * @since 3.7.0 |
319 | * @since 5.2.2 Remove sslverify param for REST API calls. |
320 | * |
321 | * @param array $info Debugging info array |
322 | * |
323 | * @return array |
324 | */ |
325 | public function addRestApiConnection(&$info) |
326 | { |
327 | // translators: Tab heading for Site Health navigation. |
328 | $apiUrl = Environment::getApiUrl(); |
329 | |
330 | $info['beyondwords']['fields']['api-url'] = [ |
331 | 'label' => __('REST API URL', 'speechkit'), |
332 | 'value' => $apiUrl, |
333 | ]; |
334 | |
335 | $response = wp_remote_request(Environment::getApiUrl(), [ |
336 | 'blocking' => true, |
337 | 'body' => '', |
338 | 'method' => 'GET', |
339 | ]); |
340 | |
341 | if (! is_wp_error($response)) { |
342 | $info['beyondwords']['fields']['api-communication'] = array( |
343 | 'label' => __('Communication with REST API', 'speechkit'), |
344 | 'value' => __('BeyondWords API is reachable', 'speechkit'), |
345 | 'debug' => 'true', |
346 | ); |
347 | } else { |
348 | $info['beyondwords']['fields']['api-communication'] = array( |
349 | 'label' => __('Communication with REST API', 'speechkit'), |
350 | 'value' => sprintf( |
351 | /* translators: 1: The IP address the REST API resolves to. 2: The error returned by the lookup. */ |
352 | __('Unable to reach BeyondWords API at %1$s: %2$s', 'speechkit'), |
353 | gethostbyname(Environment::getApiUrl()), |
354 | $response->get_error_message() |
355 | ), |
356 | 'debug' => $response->get_error_message(), |
357 | ); |
358 | } |
359 | } |
360 | |
361 | /** |
362 | * Adds filters. |
363 | * |
364 | * @since 5.0.0 |
365 | * |
366 | * @param array $info Debugging info array |
367 | * |
368 | * @return array |
369 | */ |
370 | public function addFilters(&$info) |
371 | { |
372 | $registered = array_values(array_filter(SiteHealth::FILTERS, 'has_filter')); |
373 | |
374 | $info['beyondwords']['fields']['registered-filters'] = [ |
375 | 'label' => __('Registered filters', 'speechkit'), |
376 | 'value' => empty($registered) ? __('None', 'speechkit') : implode(', ', $registered), |
377 | 'debug' => empty($registered) ? 'none' : implode(', ', $registered), |
378 | ]; |
379 | |
380 | $registered = array_values(array_filter(SiteHealth::DEPRECATED_FILTERS, 'has_filter')); |
381 | |
382 | $info['beyondwords']['fields']['registered-deprecated-filters'] = [ |
383 | 'label' => __('Registered deprecated filters', 'speechkit'), |
384 | 'value' => empty($registered) ? __('None', 'speechkit') : implode(', ', $registered), |
385 | 'debug' => empty($registered) ? 'none' : implode(', ', $registered), |
386 | ]; |
387 | } |
388 | |
389 | /** |
390 | * Add notice settings to the info debugging array. |
391 | * |
392 | * @since 5.4.0 |
393 | * |
394 | * @param array $info Debugging info array |
395 | * |
396 | * @return array |
397 | */ |
398 | public function addNoticeSettings(&$info) |
399 | { |
400 | $info['beyondwords']['fields']['beyondwords_date_activated'] = [ |
401 | 'label' => __('Date Activated', 'speechkit'), |
402 | 'value' => get_option('beyondwords_date_activated', ''), |
403 | ]; |
404 | |
405 | $info['beyondwords']['fields']['beyondwords_notice_review_dismissed'] = [ |
406 | 'label' => __('Review Notice Dismissed', 'speechkit'), |
407 | 'value' => get_option('beyondwords_notice_review_dismissed', ''), |
408 | ]; |
409 | } |
410 | |
411 | /** |
412 | * Add a single constant to the debugging info array. |
413 | * |
414 | * @since 3.7.0 |
415 | * @since 5.0.0 Handle boolean values. |
416 | * |
417 | * @param array $info Debugging info array |
418 | * @param string $name Constant name |
419 | * |
420 | * @return array |
421 | */ |
422 | public function addConstant(&$info, $name) |
423 | { |
424 | $value = __('Undefined', 'speechkit'); |
425 | |
426 | if (defined($name)) { |
427 | $value = constant($name); |
428 | |
429 | if (is_bool($value)) { |
430 | // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_var_export |
431 | $value = (true === $value) ? 'True' : 'False'; |
432 | } |
433 | } |
434 | |
435 | $info['beyondwords']['fields'][$name] = [ |
436 | 'label' => $name, |
437 | 'value' => $value, |
438 | 'debug' => $value, |
439 | ]; |
440 | } |
441 | |
442 | /** |
443 | * Mask a sensitive string for display in Site Health. |
444 | * |
445 | * @since 3.7.0 |
446 | * @static |
447 | * |
448 | * @param string $string |
449 | * @param int $count |
450 | * @param string $char |
451 | * |
452 | * @return string |
453 | */ |
454 | public static function maskString($string, $count = 4, $char = 'X') |
455 | { |
456 | if (! is_string($string)) { |
457 | return ''; |
458 | } |
459 | |
460 | if (strlen($string) < 8) { |
461 | return str_repeat($char, strlen($string)); |
462 | } else { |
463 | return str_repeat($char, strlen($string) - $count) . substr($string, (0 - $count)); |
464 | } |
465 | } |
466 | } |