PluginProbe
BeyondWords – AI audio for publishers / 6.0.3
BeyondWords – AI audio for publishers v6.0.3
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.0.3, at src/Component/Settings/SettingsUtils.php

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