PluginProbe
BeyondWords – AI audio for publishers / 4.0.6
BeyondWords – AI audio for publishers v4.0.6
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 / Settings.php

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

522 lines 15.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 /**
6 * BeyondWords settings.
7 *
8 * @package Beyondwords\Wordpress
9 * @author Stuart McAlpine <stu@beyondwords.io>
10 * @since 3.0.0
11 */
12
13 namespace Beyondwords\Wordpress\Component\Settings;
14
15 use Beyondwords\Wordpress\Component\Settings\Languages\Languages;
16 use Beyondwords\Wordpress\Component\Settings\Preselect\Preselect;
17 use Beyondwords\Wordpress\Component\Settings\SettingsUtils;
18 use Beyondwords\Wordpress\Core\Core;
19 use Beyondwords\Wordpress\Core\Environment;
20
21 /**
22 * Settings setup
23 *
24 * @since 3.0.0
25 */
26 class Settings
27 {
28 private $apiClient;
29
30 /**
31 * Constructor
32 */
33 public function __construct($apiClient)
34 {
35 $this->apiClient = $apiClient;
36
37 add_action('admin_menu', array($this, 'addOptionsPage'));
38 add_action('admin_init', array($this, 'init'));
39 add_action('admin_notices', array($this, 'printPluginAdminNotices'));
40 add_action('rest_api_init', array($this, 'restApiInit'));
41
42 add_filter('plugin_action_links_speechkit/speechkit.php', array($this, 'addSettingsLinkToPluginPage'));
43
44 add_action('updated_option', array($this, 'updatedOption'), 99, 3);
45 add_action('added_option', array($this, 'addedOption'), 99, 2);
46 }
47
48 /**
49 * Add items to the WordPress admin menu.
50 *
51 * @since 3.0.0
52 *
53 * @return void
54 */
55 public function addOptionsPage()
56 {
57 // Settings > BeyondWords
58 add_options_page(
59 __('BeyondWords', 'speechkit'),
60 __('BeyondWords', 'speechkit'),
61 'manage_options',
62 'beyondwords',
63 array($this, 'createAdminInterface')
64 );
65 }
66
67 /**
68 * Init Settings.
69 *
70 * =====
71 * Basic
72 * =====
73 * 'api_key' => '',
74 * 'project_id' => '',
75 *
76 * ==============
77 * Player
78 * ==============
79 * 'version' => '0',
80 *
81 * ==============
82 * Generate audio
83 * ==============
84 * 'preselect' => array('post' => '1', 'page' => '1'),
85 *
86 * ========
87 * Advanced
88 * ========
89 * 'merge_excerpt' => false,
90 *
91 * @since 3.0.0
92 */
93 public function init()
94 {
95 // Add Settings Section: Basic
96 add_settings_section(
97 'basic',
98 __('Basic settings', 'speechkit'),
99 array($this, 'basicSectionCallback'),
100 'beyondwords'
101 );
102
103 if (SettingsUtils::hasApiSettings()) {
104 // Add Settings Section: Player
105 add_settings_section(
106 'player',
107 __('Player settings', 'speechkit'),
108 array($this, 'playerSectionCallback'),
109 'beyondwords'
110 );
111
112 // Add Settings Section: Content
113 add_settings_section(
114 'content',
115 __('Content settings', 'speechkit'),
116 array($this, 'contentSectionCallback'),
117 'beyondwords'
118 );
119
120 // Add Settings Section: Generate audio
121 add_settings_section(
122 'generate-audio',
123 __('‘Generate audio’ settings', 'speechkit'),
124 array($this, 'generateAudioSectionCallback'),
125 'beyondwords'
126 );
127 }
128 }
129
130 /**
131 * "Basic section" callback
132 *
133 * @since 3.0.0
134 *
135 * @return void
136 **/
137 public function basicSectionCallback()
138 {
139 delete_transient('beyondwords_settings_errors');
140 ?>
141 <p class="description">
142 <?php
143 _e(
144 'The details we need to authenticate your BeyondWords account. For more options, head to your BeyondWords dashboard.', // phpcs:ignore
145 'speechkit'
146 );
147 ?>
148 </p>
149 <?php
150 }
151
152 /**
153 * "Player section" callback
154 *
155 * @since 4.0.0
156 *
157 * @return void
158 **/
159 public function playerSectionCallback()
160 {
161 ?>
162 <p class="description">
163 <?php
164 _e(
165 'Upgrade to the latest player version for the newest features.', // phpcs:ignore
166 'speechkit'
167 );
168 ?>
169 </p>
170 <?php
171 }
172
173 /**
174 * "Content" section callback
175 *
176 * @since 3.0.0
177 *
178 * @return void
179 **/
180 public function contentSectionCallback()
181 {
182 ?>
183 <p class="description">
184 <?php
185 _e(
186 'By default, BeyondWords will process your titles and body content into audio.', // phpcs:ignore
187 'speechkit'
188 );
189 ?>
190 </p>
191 <?php
192 }
193
194 /**
195 * ‘Generate audio’ section callback.
196 *
197 * @since 3.0.0
198 *
199 * @return void
200 **/
201 public function generateAudioSectionCallback()
202 {
203 ?>
204 <p class="description">
205 <?php
206 _e(
207 'The ‘Generate audio’ checkbox in the BeyondWords sidebar will be automatically checked for selected post types. The default setting can be manually overridden.', // phpcs:ignore
208 'speechkit'
209 );
210 ?>
211 </p>
212 <p class="description">
213 <?php
214 _e(
215 'Uncheck a post type to view its Categories. You can then set defaults at a category level. Make sure to check all relevant boxes.', // phpcs:ignore
216 'speechkit'
217 );
218 ?>
219 </p>
220 <p class="description">
221 <em>
222 <?php
223 _e(
224 'The default WordPress ‘Categories’ taxonomy is currently the only taxonomy supported.',
225 'speechkit'
226 );
227 ?>
228 </em>
229 </p>
230 <?php
231 }
232
233 public function addSettingsLinkToPluginPage($links)
234 {
235 $links[] = '<a href="' .
236 esc_url(admin_url('options-general.php?page=beyondwords')) .
237 '">' . __('Settings', 'speechkit') . '</a>';
238 return $links;
239 }
240
241
242
243 public function createAdminInterface()
244 {
245 ?>
246 <div class="wrap">
247
248 <form
249 id="beyondwords-plugin-settings"
250 action="<?php echo esc_url(admin_url('options.php')); ?>"
251 method="post"
252 >
253
254 <h1><?php _e('BeyondWords settings', 'speechkit'); ?></h1>
255
256 <?php
257 $projectId = get_option('beyondwords_project_id');
258 $playerReverted = get_transient('beyondwords_player_reverted');
259
260 if ($projectId) :
261 ?>
262 <p>
263 <a
264 class="button button-secondary"
265 href="<?php echo esc_url(Environment::getDashboardUrl()); ?>"
266 target="_blank"
267 >
268 <?php _e('BeyondWords dashboard', 'speechkit'); ?>
269 </a>
270 </p>
271 <?php
272 endif;
273
274 if ($playerReverted) :
275 ?>
276 <div id="beyondwords-player-reverted-notice" class="notice notice-error">
277 <p>
278 <span class="dashicons dashicons-editor-help"></span>
279 <?php
280 printf(
281 /* translators: %s is replaced with a "let us know" link */
282 esc_html__('It looks like you tried the "Latest" player and switched back to the "Legacy" player. If you experienced any issues switching player please %s so we can help.', 'speechkit'), // phpcs:ignore
283 sprintf(
284 '<a href="mailto:support@beyondwords.io?subject=%s">%s</a>',
285 esc_attr__('WordPress support: Latest player', 'speechkit'),
286 esc_html__('let us know', 'speechkit')
287 )
288 );
289 ?>
290 </p>
291 </div>
292 <?php
293 endif;
294 if (SettingsUtils::hasApiSettings()) :
295 ?>
296 <div id="beyondwords-player-location-notice" class="notice notice-info">
297 <p>
298 <span class="dashicons dashicons-info"></span>
299 <?php _e(
300 'The player will appear before the first part of <code>the_content()</code> by default. You can change the location via the WordPress Editor.', // phpcs:ignore
301 'speechkit'
302 );
303 ?>
304 </p>
305 </div>
306 <?php
307 endif;
308
309 settings_fields('beyondwords');
310 do_settings_sections('beyondwords');
311
312 if (SettingsUtils::hasApiSettings()) {
313 submit_button('Save Settings');
314 } else {
315 submit_button('Continue setup');
316 }
317 ?>
318 </form>
319 </div>
320 <?php
321 }
322
323 /**
324 * Print Admin Notices.
325 *
326 * @since 3.0.0
327 *
328 * @return void
329 */
330 public function printPluginAdminNotices()
331 {
332 $hasApiSettings = SettingsUtils::hasApiSettings();
333 $settingsErrors = get_transient('beyondwords_settings_errors');
334
335 if (is_array($settingsErrors) && count($settingsErrors)) :
336 ?>
337 <div class="notice notice-error">
338 <p>
339 <strong>
340 <?php
341 printf(
342 /* translators: %s is replaced with a "plugin settings" link */
343 esc_html__('To use BeyondWords, please update the %s.', 'speechkit'),
344 sprintf(
345 '<a href="%s">%s</a>',
346 esc_url(admin_url('options-general.php?page=beyondwords')),
347 esc_html__('plugin settings', 'speechkit')
348 )
349 );
350 ?>
351 </strong>
352 </p>
353 <ul class="ul-disc">
354 <?php
355 foreach ($settingsErrors as $error) {
356 printf(
357 '<li>%s</li>',
358 // Only allow links with href and target attributes
359 wp_kses(
360 $error,
361 array(
362 'a' => array(
363 'href' => array(),
364 'target' => array(),
365 ),
366 'b' => array(),
367 'strong' => array(),
368 'i' => array(),
369 'em' => array(),
370 )
371 )
372 );
373 }
374 ?>
375 </ul>
376 </div>
377
378 <?php
379 elseif (false === $hasApiSettings) :
380 ?>
381 <div class="notice notice-info">
382 <p>
383 <strong>
384 <?php
385 printf(
386 esc_html__('To use BeyondWords, please update the %s.', 'speechkit'),
387 sprintf(
388 '<a href="%s">%s</a>',
389 esc_url(admin_url('options-general.php?page=beyondwords')),
390 esc_html__('plugin settings', 'speechkit')
391 )
392 );
393 ?>
394 </strong>
395 </p>
396 <p>
397 <?php _e('Don’t have a BeyondWords account yet?', 'speechkit'); ?>
398 </p>
399 <p>
400 <a
401 class="button button-secondary"
402 href="<?php echo esc_url(sprintf('%s/auth/signup', Environment::getDashboardUrl())); ?>"
403 target="_blank"
404 >
405 <?php _e('Sign up free', 'speechkit'); ?>
406 </a>
407 </p>
408 </div>
409 <?php
410 endif;
411 }
412
413 /**
414 * Register WP REST API route
415 *
416 * @return void
417 */
418 public function restApiInit()
419 {
420 // settings endpoint
421 register_rest_route('beyondwords/v1', '/settings', array(
422 'methods' => \WP_REST_Server::READABLE,
423 'callback' => array($this, 'restApiResponse'),
424 'permission_callback' => function () {
425 return current_user_can('edit_posts');
426 },
427 ));
428 }
429
430 /**
431 * WP REST API response (required for the Gutenberg editor).
432 *
433 * DO NOT expose ALL settings e.g. be sure to never expose the API key.
434 *
435 * @return \WP_REST_Response
436 */
437 public function restApiResponse()
438 {
439 return new \WP_REST_Response([
440 'apiKey' => get_option('beyondwords_api_key', ''),
441 'preselect' => get_option('beyondwords_preselect', Preselect::DEFAULT_PRESELECT),
442 'languages' => get_option('beyondwords_languages', Languages::DEFAULT_LANGUAGES),
443 'debug' => defined('BEYONDWORDS_DEBUG') ? boolval(BEYONDWORDS_DEBUG) : false,
444 ]);
445 }
446
447 /**
448 * Check API creds are valid whenever any setting is added.
449 *
450 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
451 *
452 * @since 4.0.0
453 *
454 * @return void
455 */
456 public function addedOption($optionName, $value)
457 {
458 if ($optionName === 'beyondwords_settings_updated') {
459 $this->checkApiCreds();
460 }
461 }
462
463 /**
464 * Check API creds are valid whenever the settings are updated.
465 *
466 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
467 *
468 * @since 4.0.0
469 *
470 * @return void
471 */
472 public function updatedOption($optionName, $oldValue, $value)
473 {
474 if ($optionName === 'beyondwords_settings_updated') {
475 $this->checkApiCreds();
476 }
477 }
478
479 /**
480 * Check to see if user has valid BeyondWords API credentials by performing
481 * a GET request using the API Key and Project ID.
482 *
483 * @since 4.0.0
484 *
485 * @return void
486 */
487 public function checkApiCreds()
488 {
489 // Assume invalid connection
490 delete_option('beyondwords_valid_api_connection');
491
492 $apiKey = get_option('beyondwords_api_key');
493 $projectId = get_option('beyondwords_project_id');
494
495 if (empty($apiKey) || empty($projectId)) {
496 return;
497 }
498
499 $project = $this->apiClient->getProject();
500
501 $validConnection = (
502 is_array($project)
503 && array_key_exists('id', $project)
504 && strval($project['id']) === $projectId
505 );
506
507 if ($validConnection) {
508 // Store date of last check
509 update_option('beyondwords_valid_api_connection', gmdate(DATE_ISO8601));
510 } else {
511 $errors = get_transient('beyondwords_settings_errors', []);
512
513 $errors['Settings/ValidApiConnection'] = __(
514 'Please check and re-enter your BeyondWords API key and project ID. They appear to be invalid.',
515 'speechkit'
516 );
517
518 set_transient('beyondwords_settings_errors', $errors);
519 }
520 }
521 }
522