Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.83% covered (success)
93.83%
76 / 81
25.00% covered (danger)
25.00%
1 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
PlayerStyle
93.75% covered (success)
93.75%
75 / 80
25.00% covered (danger)
25.00%
1 / 4
13.04
0.00% covered (danger)
0.00%
0 / 1
 init
60.00% covered (danger)
60.00%
3 / 5
0.00% covered (danger)
0.00%
0 / 1
1.06
 addSetting
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
 render
96.67% covered (success)
96.67%
29 / 30
0.00% covered (danger)
0.00%
0 / 1
4
 getOptions
93.55% covered (success)
93.55%
29 / 31
0.00% covered (danger)
0.00%
0 / 1
7.01
1<?php
2
3declare(strict_types=1);
4
5/**
6 * Setting: Player style
7 *
8 * @package Beyondwords\Wordpress
9 * @author  Stuart McAlpine <stu@beyondwords.io>
10 * @since   4.1.0
11 */
12
13namespace Beyondwords\Wordpress\Component\Settings\Fields\PlayerStyle;
14
15use Beyondwords\Wordpress\Component\Settings\Sync;
16
17/**
18 * PlayerStyle
19 *
20 * @since 4.1.0
21 */
22defined('ABSPATH') || exit;
23
24class PlayerStyle
25{
26    /**
27     * Option name.
28     */
29    public const OPTION_NAME = 'beyondwords_player_style';
30
31    public const STANDARD = 'standard';
32
33    public const SMALL = 'small';
34
35    public const LARGE = 'large';
36
37    public const VIDEO = 'video';
38
39    /**
40     * Constructor
41     *
42     * @since 6.0.0 Make static.
43     */
44    public static function init()
45    {
46        add_action('admin_init', [self::class, 'addSetting']);
47        add_action('pre_update_option_' . self::OPTION_NAME, function ($value) {
48            Sync::syncOptionToDashboard(self::OPTION_NAME);
49            return $value;
50        });
51    }
52
53    /**
54     * Add setting.
55     *
56     * @since 4.5.0
57     * @since 6.0.0 Make static.
58     *
59     * @return void
60     */
61    public static function addSetting()
62    {
63        register_setting(
64            'beyondwords_player_settings',
65            self::OPTION_NAME,
66            [
67                'default' => PlayerStyle::STANDARD,
68            ]
69        );
70
71        add_settings_field(
72            'beyondwords-player-style',
73            __('Player style', 'speechkit'),
74            [self::class, 'render'],
75            'beyondwords_player',
76            'styling'
77        );
78    }
79
80    /**
81     * Render setting field.
82     *
83     * @since 4.1.0
84     * @since 6.0.0 Make static.
85     *
86     * @return void
87     **/
88    public static function render()
89    {
90        $value    = get_option(self::OPTION_NAME);
91        $selected = PlayerStyle::STANDARD;
92        $options  = self::getOptions();
93
94        foreach ($options as $option) {
95            if ($option['value'] === $value) {
96                $selected = $option['value'];
97            }
98        }
99        ?>
100        <div class="beyondwords-setting__player beyondwords-setting__player--player-style">
101            <select name="<?php echo esc_attr(self::OPTION_NAME) ?>">
102                <?php
103                foreach ($options as $option) {
104                    $disabled = $option['disabled'] ?? false;
105
106                    printf(
107                        '<option value="%s" %s %s>%s</option>',
108                        esc_attr($option['value']),
109                        selected($option['value'], $selected),
110                        disabled($disabled, true),
111                        esc_html($option['label'])
112                    );
113                }
114                ?>
115            </select>
116        </div>
117        <p class="description">
118            <?php
119            printf(
120                /* translators: %s is replaced with the "playerStyle setting" link */
121                esc_html__('The default player style (%s) for the audio player. This can be overridden for each post.', 'speechkit'), // phpcs:ignore Generic.Files.LineLength.TooLong
122                sprintf(
123                    '<a href="https://github.com/beyondwords-io/player/blob/main/doc/player-settings.md" target="_blank" rel="nofollow">%s</a>', // phpcs:ignore Generic.Files.LineLength.TooLong
124                    esc_html__('playerStyle setting', 'speechkit')
125                )
126            );
127            ?>
128        </p>
129        <?php
130    }
131
132    /**
133     * Get all Player styles for the current project.
134     *
135     * @since 4.1.0
136     * @since 5.0.0 Rename beyondwords_player_styles filter to
137     *              beyondwords_settings_player_styles.
138     *
139     * @return string[] Associative array of Player styles and labels.
140     **/
141    public static function getOptions()
142    {
143        $styles = [
144            PlayerStyle::STANDARD => [
145                'value' => PlayerStyle::STANDARD,
146                'label' => __('Standard', 'speechkit'),
147            ],
148            PlayerStyle::SMALL => [
149                'value' => PlayerStyle::SMALL,
150                'label' => __('Small', 'speechkit'),
151            ],
152            PlayerStyle::LARGE => [
153                'value' => PlayerStyle::LARGE,
154                'label' => __('Large', 'speechkit'),
155            ],
156            PlayerStyle::VIDEO => [
157                'value'    => PlayerStyle::VIDEO,
158                'label'    => __('Video', 'speechkit'),
159                'disabled' => true,
160            ],
161        ];
162
163        /**
164         * Which player style is the default?
165         * This is used to preselect the default option.
166         */
167        $defaultPlayerStyle = get_option(self::OPTION_NAME, PlayerStyle::STANDARD);
168
169        if (isset($styles[$defaultPlayerStyle])) {
170            $styles[$defaultPlayerStyle]['default'] = true;
171        }
172
173        /**
174         * Filters the player styles – the "Player style" `<select>` options
175         * presented on the plugin settings page and post edit screens.
176         *
177         * Each player style is an associative array with the following keys:
178         * - string  `label`    The option label e.g. "Standard"
179         * - string  `value`    The option value e.g. "standard"
180         * - boolean `disabled` (Optional) Is this option disabled?
181         * - boolean `default`  (Optional) Is this the default player style, assigned in the plugin settings?
182         *
183         * @since 4.1.0 Introduced as beyondwords_player_styles.
184         * @since 5.0.0 Renamed from beyondwords_player_styles to beyondwords_settings_player_styles.
185         *
186         * @param array $styles Associative array of player styles.
187         */
188        $styles = apply_filters('beyondwords_settings_player_styles', $styles);
189
190        if (empty($styles) || ! is_array($styles)) {
191            return [];
192        }
193
194        /**
195         * Is video enabled for this project?
196         * If so, we remove the [disabled] attribute from the video <option>.
197         * If not, we force a [disabled] attribute on the video <option>.
198         */
199        if (isset($styles[PlayerStyle::VIDEO]) && is_array($styles[PlayerStyle::VIDEO])) {
200            $videoEnabled = get_option('beyondwords_video_enabled');
201
202            if ($videoEnabled) {
203                unset($styles[PlayerStyle::VIDEO]['disabled']);
204            } else {
205                $styles[PlayerStyle::VIDEO]['disabled'] = true;
206            }
207        }
208
209        return $styles;
210    }
211}