Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
78.95% covered (warning)
78.95%
30 / 38
77.78% covered (warning)
77.78%
7 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
AddPlayer
78.95% covered (warning)
78.95%
30 / 38
77.78% covered (warning)
77.78%
7 / 9
15.83
0.00% covered (danger)
0.00%
0 / 1
 init
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 registerBlock
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addPlugin
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 addButton
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 addStylesheet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 playerPreviewI18nStyles
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 filterTinyMceSettings
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 addEditorStyles
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 addBlockEditorStylesheet
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3declare(strict_types=1);
4
5/**
6 * BeyondWords "Add Player" component.
7 *
8 * @package Beyondwords\Wordpress
9 * @author  Stuart McAlpine <stu@beyondwords.io>
10 * @since   3.2.0
11 */
12
13namespace Beyondwords\Wordpress\Component\Post\AddPlayer;
14
15use Beyondwords\Wordpress\Core\CoreUtils;
16
17/**
18 * AddPlayer
19 *
20 * @since 3.2.0
21 */
22class AddPlayer
23{
24    // The CSS declaration block for the player preview in both Classic Editor and Block Editor.
25    public const PLAYER_PREVIEW_STYLE_FORMAT = "iframe [data-beyondwords-player]:empty:after, .edit-post-visual-editor [data-beyondwords-player]:empty:after { content: '%s'; }"; // phpcs:ignore Generic.Files.LineLength.TooLong
26
27    /**
28     * Init.
29     *
30     * @since 4.0.0
31     * @since 6.0.0 Make static.
32     */
33    public static function init()
34    {
35        add_action('init', [self::class, 'registerBlock']);
36        add_action('enqueue_block_editor_assets', [self::class, 'addBlockEditorStylesheet']);
37
38        add_action('admin_head', [self::class, 'addEditorStyles']);
39        add_filter('tiny_mce_before_init', [self::class, 'filterTinyMceSettings']);
40
41        add_filter('mce_external_plugins', [self::class, 'addPlugin']);
42        add_filter('mce_buttons', [self::class, 'addButton']);
43        add_filter('mce_css', [self::class, 'addStylesheet']);
44    }
45
46    /**
47     * Register Block.
48     *
49     * @since 3.2.0
50     * @since 6.0.0 Make static.
51     */
52    public static function registerBlock()
53    {
54        \register_block_type(__DIR__);
55    }
56
57    /**
58     * Add TinyMCE buttons.
59     *
60     * @since 6.0.0 Make static.
61     *
62     * @param array TinyMCE plugin array
63     */
64    public static function addPlugin(array $plugin_array): array
65    {
66        $plugin_array['beyondwords_player'] = BEYONDWORDS__PLUGIN_URI . 'src/Component/Post/AddPlayer/tinymce.js';
67        return $plugin_array;
68    }
69
70    /**
71     * Register TinyMCE buttons.
72     *
73     * @since 6.0.0 Make static.
74     *
75     * @param array TinyMCE buttons array
76     */
77    public static function addButton(array $buttons): array
78    {
79        $advIndex = array_search('wp_adv', $buttons);
80
81        if ($advIndex === false) {
82            $advIndex = count($buttons);
83        }
84
85        array_splice($buttons, $advIndex, 0, ['beyondwords_player']);
86
87        return $buttons;
88    }
89
90    /**
91     * Filters the comma-delimited list of stylesheets to load in TinyMCE.
92     *
93     * @since 6.0.0 Make static.
94     *
95     * @param string $stylesheets Comma-delimited list of stylesheets.
96     *
97     * @return string Comma-delimited list of stylesheets with the "Add Player" CSS appended.
98     */
99    public static function addStylesheet(string $stylesheets): string
100    {
101        return $stylesheets . ',' . BEYONDWORDS__PLUGIN_URI . 'src/Component/Post/AddPlayer/AddPlayer.css';
102    }
103
104    /**
105     * "Player Preview" i18n styles.
106     *
107     * Player preview uses the CSS :after to set the content so we pass the CSS through WordPress i18n functions here.
108     *
109     * @since 3.3.0
110     * @since 6.0.0 Make static.
111     *
112     * @return string CSS Block for player preview i18n delcerations.
113     */
114    public static function playerPreviewI18nStyles()
115    {
116        return sprintf(
117            self::PLAYER_PREVIEW_STYLE_FORMAT,
118            esc_attr__('Player placeholder: The position of the audio player.', 'speechkit')
119        );
120    }
121
122    /**
123     * Tiny MCE before init.
124     *
125     * Adds i18n-compatible TinyMCE Classic Editor CSS for the player placeholder.
126     *
127     * @since 3.3.0
128     * @since 6.0.0 Make static.
129     *
130     * @param mixed[] $setings An array with TinyMCE config.
131     *
132     * @return mixed[] An array with TinyMCE config.
133     */
134    public static function filterTinyMceSettings(array $settings): array
135    {
136        if (isset($settings['content_style'])) {
137            $settings['content_style'] .= ' ' . self::playerPreviewI18nStyles() . ' ';
138        } else {
139            $settings['content_style'] = self::playerPreviewI18nStyles() . ' ';
140        }
141
142        return $settings;
143    }
144
145    /**
146     * Add editor styles.
147     *
148     * Adds i18n-compatible Block Editor CSS for the player placeholder.
149     *
150     * @since 3.3.0
151     * @since 6.0.0 Make static.
152     */
153    public static function addEditorStyles()
154    {
155        $allowed_html = [
156            'style' => [],
157        ];
158
159        echo wp_kses(
160            sprintf('<style>%s</style>', self::playerPreviewI18nStyles()),
161            $allowed_html
162        );
163    }
164
165    /**
166     * Add Block Editor Stylesheet.
167     *
168     * @since 6.0.0 Make static.
169     */
170    public static function addBlockEditorStylesheet(string $hook): void
171    {
172        // Only enqueue for Gutenberg/Post screens
173        if (CoreUtils::isGutenbergPage() || $hook === 'post.php' || $hook === 'post-new.php') {
174            // Register the Classic/Block Editor "Add Player" CSS
175            wp_enqueue_style(
176                'beyondwords-AddPlayer',
177                BEYONDWORDS__PLUGIN_URI . 'src/Component/Post/AddPlayer/AddPlayer.css',
178                [],
179                BEYONDWORDS__PLUGIN_VERSION
180            );
181        }
182    }
183}