# speechkit/4.0.0/src/Component/Settings/Settings.php

BeyondWords – AI audio for publishers, version 4.0.0. 522 lines.

- Page: https://pluginprobe.com/plugins/speechkit/4.0.0/code/src/Component/Settings/Settings.php
- Raw: https://pluginprobe.com/plugins/speechkit/4.0.0/raw/src/Component/Settings/Settings.php
- Modified: 2023-07-26T14:25:00+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/speechkit/4.0.0/code/src/Component/Settings/Settings.php#L10-L20`.

```php
<?php

declare(strict_types=1);

/**
 * BeyondWords settings.
 *
 * @package Beyondwords\Wordpress
 * @author  Stuart McAlpine <stu@beyondwords.io>
 * @since   3.0.0
 */

namespace Beyondwords\Wordpress\Component\Settings;

use Beyondwords\Wordpress\Component\Settings\Languages\Languages;
use Beyondwords\Wordpress\Component\Settings\Preselect\Preselect;
use Beyondwords\Wordpress\Component\Settings\SettingsUtils;
use Beyondwords\Wordpress\Core\Core;
use Beyondwords\Wordpress\Core\Environment;

/**
 * Settings setup
 *
 * @since 3.0.0
 */
class Settings
{
    private $apiClient;

    /**
     * Constructor
     */
    public function __construct($apiClient)
    {
        $this->apiClient = $apiClient;

        add_action('admin_menu', array($this, 'addOptionsPage'));
        add_action('admin_init', array($this, 'init'));
        add_action('admin_notices', array($this, 'printPluginAdminNotices'));
        add_action('rest_api_init', array($this, 'restApiInit'));

        add_filter('plugin_action_links_speechkit/speechkit.php', array($this, 'addSettingsLinkToPluginPage'));

        add_action('updated_option', array($this, 'updatedOption'), 99, 3);
        add_action('added_option', array($this, 'addedOption'), 99, 2);
    }

    /**
     * Add items to the WordPress admin menu.
     *
     * @since  3.0.0
     *
     * @return void
     */
    public function addOptionsPage()
    {
        // Settings > BeyondWords
        add_options_page(
            __('BeyondWords', 'speechkit'),
            __('BeyondWords', 'speechkit'),
            'manage_options',
            'beyondwords',
            array($this, 'createAdminInterface')
        );
    }

    /**
     * Init Settings.
     *
     * =====
     * Basic
     * =====
     * 'api_key'    => '',
     * 'project_id' => '',
     *
     * ==============
     * Player
     * ==============
     * 'version' => '0',
     *
     * ==============
     * Generate audio
     * ==============
     * 'preselect' => array('post' => '1', 'page' => '1'),
     *
     * ========
     * Advanced
     * ========
     * 'merge_excerpt' => false,
     *
     * @since  3.0.0
     */
    public function init()
    {
        // Add Settings Section: Basic
        add_settings_section(
            'basic',
            __('Basic settings', 'speechkit'),
            array($this, 'basicSectionCallback'),
            'beyondwords'
        );

        if (SettingsUtils::hasApiSettings()) {
            // Add Settings Section: Player
            add_settings_section(
                'player',
                __('Player settings', 'speechkit'),
                array($this, 'playerSectionCallback'),
                'beyondwords'
            );

            // Add Settings Section: Content
            add_settings_section(
                'content',
                __('Content settings', 'speechkit'),
                array($this, 'contentSectionCallback'),
                'beyondwords'
            );

            // Add Settings Section: Generate audio
            add_settings_section(
                'generate-audio',
                __('‘Generate audio’ settings', 'speechkit'),
                array($this, 'generateAudioSectionCallback'),
                'beyondwords'
            );
        }
    }

    /**
     * "Basic section" callback
     *
     * @since 3.0.0
     *
     * @return void
     **/
    public function basicSectionCallback()
    {
        delete_transient('beyondwords_settings_errors');
        ?>
        <p class="description">
            <?php
            _e(
                'The details we need to authenticate your BeyondWords account. For more options, head to your BeyondWords dashboard.', // phpcs:ignore
                'speechkit'
            );
            ?>
        </p>
        <?php
    }

    /**
     * "Player section" callback
     *
     * @since 4.0.0
     *
     * @return void
     **/
    public function playerSectionCallback()
    {
        ?>
        <p class="description">
            <?php
            _e(
                'Upgrade to the latest player version for the newest features.', // phpcs:ignore
                'speechkit'
            );
            ?>
        </p>
        <?php
    }

    /**
     * "Content" section callback
     *
     * @since 3.0.0
     *
     * @return void
     **/
    public function contentSectionCallback()
    {
        ?>
        <p class="description">
            <?php
            _e(
                'By default, BeyondWords will process your titles and body content into audio.', // phpcs:ignore
                'speechkit'
            );
            ?>
        </p>
        <?php
    }

    /**
     * ‘Generate audio’ section callback.
     *
     * @since 3.0.0
     *
     * @return void
     **/
    public function generateAudioSectionCallback()
    {
        ?>
        <p class="description">
            <?php
            _e(
                '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
                'speechkit'
            );
            ?>
        </p>
        <p class="description">
            <?php
            _e(
                '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
                'speechkit'
            );
            ?>
        </p>
        <p class="description">
            <em>
                <?php
                _e(
                    'The default WordPress ‘Categories’ taxonomy is currently the only taxonomy supported.',
                    'speechkit'
                );
                ?>
            </em>
        </p>
        <?php
    }

    public function addSettingsLinkToPluginPage($links)
    {
        $links[] = '<a href="' .
            esc_url(admin_url('options-general.php?page=beyondwords')) .
            '">' . __('Settings', 'speechkit') . '</a>';
        return $links;
    }



    public function createAdminInterface()
    {
        ?>
        <div class="wrap">

            <form
                id="beyondwords-plugin-settings"
                action="<?php echo esc_url(admin_url('options.php')); ?>"
                method="post"
            >

                <h1><?php _e('BeyondWords settings', 'speechkit'); ?></h1>

                <?php
                $projectId      = get_option('beyondwords_project_id');
                $playerReverted = get_transient('beyondwords_player_reverted');

                if ($projectId) :
                    ?>
                    <p>
                        <a
                            class="button button-secondary"
                            href="<?php echo esc_url(Environment::getDashboardUrl()); ?>"
                            target="_blank"
                        >
                            <?php _e('BeyondWords dashboard', 'speechkit'); ?>
                        </a>
                    </p>
                    <?php
                endif;

                if ($playerReverted) :
                    ?>
                    <div id="beyondwords-player-reverted-notice" class="notice notice-error">
                        <p>
                            <span class="dashicons dashicons-editor-help"></span>
                            <?php
                            printf(
                                /* translators: %s is replaced with a "let us know" link */
                                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
                                sprintf(
                                    '<a href="mailto:support@beyondwords.io?subject=%s">%s</a>',
                                    esc_attr__('WordPress support: Latest player', 'speechkit'),
                                    esc_html__('let us know', 'speechkit')
                                )
                            );
                            ?>
                        </p>
                    </div>
                    <?php
                endif;
                if (SettingsUtils::hasApiSettings()) :
                    ?>
                    <div id="beyondwords-player-location-notice" class="notice notice-info">
                        <p>
                            <span class="dashicons dashicons-info"></span>
                            <?php _e(
                                '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
                                'speechkit'
                            );
                            ?>
                        </p>
                    </div>
                    <?php
                endif;

                settings_fields('beyondwords');
                do_settings_sections('beyondwords');

                if (SettingsUtils::hasApiSettings()) {
                    submit_button('Save Settings');
                } else {
                    submit_button('Continue setup');
                }
                ?>
            </form>
        </div>
        <?php
    }

    /**
     * Print Admin Notices.
     *
     * @since 3.0.0
     *
     * @return void
     */
    public function printPluginAdminNotices()
    {
        $hasApiSettings = SettingsUtils::hasApiSettings();
        $settingsErrors = get_transient('beyondwords_settings_errors');

        if (is_array($settingsErrors) && count($settingsErrors)) :
            ?>
            <div class="notice notice-error">
                <p>
                    <strong>
                        <?php
                        printf(
                            /* translators: %s is replaced with a "plugin settings" link */
                            esc_html__('To use BeyondWords, please update the %s.', 'speechkit'),
                            sprintf(
                                '<a href="%s">%s</a>',
                                esc_url(admin_url('options-general.php?page=beyondwords')),
                                esc_html__('plugin settings', 'speechkit')
                            )
                        );
                        ?>
                    </strong>
                </p>
                <ul class="ul-disc">
                    <?php
                    foreach ($settingsErrors as $error) {
                        printf(
                            '<li>%s</li>',
                            // Only allow links with href and target attributes
                            wp_kses(
                                $error,
                                array(
                                    'a' => array(
                                        'href'   => array(),
                                        'target' => array(),
                                    ),
                                    'b' => array(),
                                    'strong' => array(),
                                    'i' => array(),
                                    'em' => array(),
                                )
                            )
                        );
                    }
                    ?>
                </ul>
            </div>

            <?php
        elseif (false === $hasApiSettings) :
            ?>
            <div class="notice notice-info">
                <p>
                    <strong>
                        <?php
                        printf(
                            esc_html__('To use BeyondWords, please update the %s.', 'speechkit'),
                            sprintf(
                                '<a href="%s">%s</a>',
                                esc_url(admin_url('options-general.php?page=beyondwords')),
                                esc_html__('plugin settings', 'speechkit')
                            )
                        );
                        ?>
                    </strong>
                </p>
                <p>
                    <?php _e('Don’t have a BeyondWords account yet?', 'speechkit'); ?>
                </p>
                <p>
                    <a
                        class="button button-secondary"
                        href="<?php echo esc_url(sprintf('%s/auth/signup', Environment::getDashboardUrl())); ?>"
                        target="_blank"
                    >
                        <?php _e('Sign up free', 'speechkit'); ?>
                    </a>
                </p>
            </div>
            <?php
        endif;
    }

    /**
     * Register WP REST API route
     *
     * @return void
     */
    public function restApiInit()
    {
        // settings endpoint
        register_rest_route('beyondwords/v1', '/settings', array(
            'methods'  => \WP_REST_Server::READABLE,
            'callback' => array($this, 'restApiResponse'),
            'permission_callback' => function () {
                return current_user_can('edit_posts');
            },
        ));
    }

    /**
     * WP REST API response (required for the Gutenberg editor).
     *
     * DO NOT expose ALL settings e.g. be sure to never expose the API key.
     *
     * @return \WP_REST_Response
     */
    public function restApiResponse()
    {
        return new \WP_REST_Response([
            'apiKey'        => get_option('beyondwords_api_key', ''),
            'preselect'     => get_option('beyondwords_preselect', Preselect::DEFAULT_PRESELECT),
            'languages'     => get_option('beyondwords_languages', Languages::DEFAULT_LANGUAGES),
            'debug'         => defined('BEYONDWORDS_DEBUG') ? boolval(BEYONDWORDS_DEBUG) : false,
        ]);
    }

    /**
     * Check API creds are valid whenever any setting is added.
     *
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     *
     * @since 4.0.0
     *
     * @return void
     */
    public function addedOption($optionName, $value)
    {
        if ($optionName === 'beyondwords_settings_updated') {
            $this->checkApiCreds();
        }
    }

    /**
     * Check API creds are valid whenever the settings are updated.
     *
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     *
     * @since 4.0.0
     *
     * @return void
     */
    public function updatedOption($optionName, $oldValue, $value)
    {
        if ($optionName === 'beyondwords_settings_updated') {
            $this->checkApiCreds();
        }
    }

    /**
     * Check to see if user has valid BeyondWords API credentials by performing
     * a GET request using the API Key and Project ID.
     *
     * @since 4.0.0
     *
     * @return void
     */
    public function checkApiCreds()
    {
        // Assume invalid connection
        delete_option('beyondwords_valid_api_connection');

        $apiKey    = get_option('beyondwords_api_key');
        $projectId = get_option('beyondwords_project_id');

        if (empty($apiKey) || empty($projectId)) {
            return;
        }

        $project = $this->apiClient->getProject();

        $validConnection = (
            is_array($project)
            && array_key_exists('id', $project)
            && strval($project['id']) === $projectId
        );

        if ($validConnection) {
            // Store date of last check
            update_option('beyondwords_valid_api_connection', gmdate(DATE_ISO8601));
        } else {
            $errors = get_transient('beyondwords_settings_errors', []);

            $errors['Settings/ValidApiConnection'] = __(
                'Please check and re-enter your BeyondWords API key and project ID. They appear to be invalid.',
                'speechkit'
            );

            set_transient('beyondwords_settings_errors', $errors);
        }
    }
}

```
