PluginProbe
BeyondWords – AI audio for publishers / 6.3.0
BeyondWords – AI audio for publishers v6.3.0
7.1.0 trunk 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.1.0 4.1.1 4.1.2 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.3.0 4.4.0 4.5.0 4.5.1 4.6.0 4.6.1 4.6.2 4.7.0 All 43 releases
speechkit / src / Component / Settings / SettingsUtils.php

SettingsUtils.php in BeyondWords – AI audio for publishers 6.3.0, at src/Component/Settings/SettingsUtils.php

285 lines 8.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // phpcs:disable Generic.Files.LineLength.TooLong
3
4 declare(strict_types=1);
5
6 namespace Beyondwords\Wordpress\Component\Settings;
7
8 use Beyondwords\Wordpress\Core\ApiClient;
9 use Beyondwords\Wordpress\Core\Environment;
10 use Beyondwords\Wordpress\Core\Request;
11
12 /**
13 * BeyondWords Settings Utilities.
14 *
15 * @package Beyondwords
16 * @subpackage Beyondwords/includes
17 * @author Stuart McAlpine <stu@beyondwords.io>
18 * @since 3.5.0
19 */
20 defined('ABSPATH') || exit;
21
22 class SettingsUtils
23 {
24 /**
25 * Get the post types BeyondWords will consider for compatibility.
26 *
27 * We don't consider many of the core built-in post types for compatibity
28 * because they don't support the features we need such as titles, body,
29 * custom fields, etc.
30 *
31 * @since 3.7.0
32 * @since 4.5.0 Renamed from getAllowedPostTypes to getConsideredPostTypes.
33 * @since 4.6.2 Exclude wp_font_face and wp_font_family from considered post types.
34 *
35 * @static
36 *
37 * @return string[] Array of post type names.
38 **/
39 public static function getConsideredPostTypes(): array
40 {
41 $postTypes = get_post_types();
42
43 $skip = [
44 'attachment',
45 'custom_css',
46 'customize_changeset',
47 'nav_menu_item',
48 'oembed_cache',
49 'revision',
50 'user_request',
51 'wp_block',
52 'wp_font_face',
53 'wp_font_family',
54 'wp_template',
55 'wp_template_part',
56 'wp_global_styles',
57 'wp_navigation',
58 ];
59
60 // Remove the skipped post types
61 $postTypes = array_diff($postTypes, $skip);
62
63 return array_values($postTypes);
64 }
65
66 /**
67 * Get the post types that are compatible with BeyondWords.
68 *
69 * - Start with the considered post types
70 * - Allow publishers to filter the list
71 * - Filter again, removing any that are incompatible
72 *
73 * @since 3.0.0
74 * @since 3.2.0 Removed $output parameter to always output names, never objects.
75 * @since 3.2.0 Added `beyondwords_post_types` filter.
76 * @since 3.5.0 Moved from Core\Utils to Component\Settings\SettingsUtils.
77 * @since 3.7.0 Refactored forbidden/allowed/supported post type methods to improve site health debugging info.
78 * @since 4.5.0 Renamed from getSupportedPostTypes to getCompatiblePostTypes.
79 * @since 5.0.0 Remove beyondwords_post_types filter.
80 *
81 * @static
82 *
83 * @return string[] Array of post type names.
84 **/
85 public static function getCompatiblePostTypes(): array
86 {
87 $postTypes = SettingsUtils::getConsideredPostTypes();
88
89 /**
90 * Filters the post types supported by BeyondWords.
91 *
92 * This defaults to all registered post types with 'custom-fields' in their 'supports' array.
93 *
94 * If any of the supplied post types do not support custom fields then they will be removed
95 * from the array.
96 *
97 * @since 3.3.3 Introduced as beyondwords_post_types
98 * @since 4.3.0 Renamed from beyondwords_post_types to beyondwords_settings_post_types.
99 *
100 * @param string[] The post types supported by BeyondWords.
101 */
102 $postTypes = apply_filters('beyondwords_settings_post_types', $postTypes);
103
104 // Remove incompatible post types
105 $postTypes = array_diff($postTypes, SettingsUtils::getIncompatiblePostTypes());
106
107 return array_values($postTypes);
108 }
109
110 /**
111 * Get the post types that are incompatible with BeyondWords.
112 *
113 * The requirements are:
114 * - Must support Custom Fields.
115 *
116 * @since 4.5.0
117 *
118 * @static
119 *
120 * @return string[] Array of post type names.
121 **/
122 public static function getIncompatiblePostTypes(): array
123 {
124 $postTypes = SettingsUtils::getConsideredPostTypes();
125
126 // Filter the array, removing unsupported post types
127 $postTypes = array_filter($postTypes, function ($postType) {
128 if (post_type_supports($postType, 'custom-fields')) {
129 return false;
130 }
131
132 return true;
133 });
134
135 return array_values($postTypes);
136 }
137
138 /**
139 * Do we have both an API Key and Project ID?
140 *
141 * @since 5.2.0
142 * @static
143 */
144 public static function hasApiCreds(): bool
145 {
146 $projectId = trim(strval(get_option('beyondwords_project_id')));
147 $apiKey = trim(strval(get_option('beyondwords_api_key')));
148
149 return strlen($projectId) && strlen($apiKey);
150 }
151
152 /**
153 * Do we have a valid REST API connection for the BeyondWords REST API?
154 *
155 * Note that this only whether a valid REST API connection was made when
156 * the API Key was supplied. The API connection may be invalidated at a later
157 * date e.g. if the API Key is revoked.
158 *
159 * @since 5.2.0
160 * @static
161 */
162 public static function hasValidApiConnection(): bool
163 {
164 return boolval(get_option('beyondwords_valid_api_connection'));
165 }
166
167 /**
168 * Validate the BeyondWords REST API connection.
169 *
170 * @since 5.0.0
171 * @since 5.2.0 Moved from Sync class into SettingsUtils class.
172 * @static
173 **/
174 public static function validateApiConnection(): bool
175 {
176 // This may have been left over from previous versions
177 delete_transient('beyondwords_validate_api_connection');
178
179 // Assume invalid connection
180 delete_option('beyondwords_valid_api_connection');
181
182 $projectId = get_option('beyondwords_project_id');
183 $apiKey = get_option('beyondwords_api_key');
184
185 if (! $projectId || ! $apiKey) {
186 return false;
187 }
188
189 $url = sprintf('%s/projects/%d', Environment::getApiUrl(), $projectId);
190
191 $response = ApiClient::callApi(
192 new Request('GET', $url)
193 );
194
195 $statusCode = wp_remote_retrieve_response_code($response);
196
197 if ($statusCode === 200) {
198 update_option('beyondwords_valid_api_connection', gmdate(\DateTime::ATOM), false);
199 wp_cache_set('beyondwords_sync_to_wordpress', ['all'], 'beyondwords', 60);
200 return true;
201 }
202
203 // Cancel any syncs
204 wp_cache_delete('beyondwords_sync_to_wordpress', 'beyondwords');
205
206 $debug = sprintf(
207 '<code>%s</code>: <code>%s</code>',
208 wp_remote_retrieve_response_code($response),
209 wp_remote_retrieve_body($response)
210 );
211
212 self::addSettingsErrorMessage(
213 sprintf(
214 /* translators: %s is replaced with the BeyondWords REST API response debug data */
215 __(
216 'We were unable to validate your BeyondWords REST API connection.<br />Please check your project ID and API key, save changes, and contact us for support if this message remains.<br /><br />BeyondWords REST API Response:<br />%s', // phpcs:ignore Generic.Files.LineLength.TooLong
217 'speechkit'
218 ),
219 $debug,
220 ),
221 'Settings/ValidApiConnection'
222 );
223
224 return false;
225 }
226
227 /**
228 * A color input.
229 *
230 * @since 5.0.0
231 * @static
232 *
233 * @param string $label Content for the `<label>`
234 * @param string $name `name` attribute for the `<input />`
235 * @param string $value `value` attribute for the `<input />`
236 */
237 public static function colorInput(string $label, string $name, string $value): void
238 {
239 ?>
240 <div class="color-input">
241 <label>
242 <?php echo esc_attr($label); ?>
243 </label>
244 <output
245 for="<?php echo esc_attr($name); ?>"
246 style="background: <?php echo esc_attr($value); ?>; margin-right: 0.25rem;"
247 ></output>
248 <input
249 name="<?php echo esc_attr($name); ?>"
250 type="text"
251 value="<?php echo esc_attr($value); ?>"
252 class="small-text"
253 oninput="this.previousElementSibling.style.background = 'transparent'; this.previousElementSibling.style.background = `${this.value}`"
254 />
255 </div>
256 <?php
257 }
258
259 /**
260 * Add settings error message.
261 *
262 * @since 5.2.0
263 * @static
264 *
265 * @param string $message The error message.
266 * @param string $errorId The error ID.
267 **/
268 public static function addSettingsErrorMessage(string $message, string $errorId = ''): void
269 {
270 $errors = wp_cache_get('beyondwords_settings_errors', 'beyondwords');
271
272 if (empty($errors)) {
273 $errors = [];
274 }
275
276 if (empty($errorId)) {
277 $errorId = bin2hex(random_bytes(8));
278 }
279
280 $errors[$errorId] = $message;
281
282 wp_cache_set('beyondwords_settings_errors', $errors, 'beyondwords');
283 }
284 }
285