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     */
32    public function init()
33    {
34        add_action('init', array($this, 'registerBlock'));
35        add_action('enqueue_block_editor_assets', array($this, 'addBlockEditorStylesheet'));
36
37        add_action('admin_head', array($this, 'addEditorStyles'));
38        add_filter('tiny_mce_before_init', array($this, 'filterTinyMceSettings'));
39
40        add_filter('mce_external_plugins', array($this, 'addPlugin'));
41        add_filter('mce_buttons', array($this, 'addButton'));
42        add_filter('mce_css', array($this, 'addStylesheet'));
43    }
44
45    /**
46     * Register Block.
47     */
48    public function registerBlock()
49    {
50        \register_block_type(__DIR__);
51    }
52
53    /**
54     * Add TinyMCE buttons.
55     *
56     * @param array TinyMCE plugin array
57     */
58    public function addPlugin($plugin_array)
59    {
60        $plugin_array['beyondwords_player'] = BEYONDWORDS__PLUGIN_URI . 'src/Component/Post/AddPlayer/tinymce.js';
61        return $plugin_array;
62    }
63
64    /**
65     * Register TinyMCE buttons.
66     *
67     * @param array TinyMCE buttons array
68     */
69    public function addButton($buttons)
70    {
71        $advIndex = array_search('wp_adv', $buttons);
72
73        if ($advIndex === false) {
74            $advIndex = count($buttons);
75        }
76
77        array_splice($buttons, $advIndex, 0, ['beyondwords_player']);
78
79        return $buttons;
80    }
81
82    /**
83     * Filters the comma-delimited list of stylesheets to load in TinyMCE.
84     */
85    public function addStylesheet($stylesheets)
86    {
87        return $stylesheets . ',' . BEYONDWORDS__PLUGIN_URI . 'src/Component/Post/AddPlayer/AddPlayer.css';
88    }
89
90    /**
91     * "Player Preview" i18n styles.
92     *
93     * Player preview uses the CSS :after to set the content so we pass the CSS through WordPress i18n functions here.
94     *
95     * @since 3.3.0
96     *
97     * @return string CSS Block for player preview i18n delcerations.
98     */
99    public function playerPreviewI18nStyles()
100    {
101        return sprintf(
102            self::PLAYER_PREVIEW_STYLE_FORMAT,
103            esc_attr__('Player placeholder: The position of the audio player.', 'speechkit')
104        );
105    }
106
107    /**
108     * Tiny MCE before init.
109     *
110     * Adds i18n-compatible TinyMCE Classic Editor CSS for the player placeholder.
111     *
112     * @since 3.3.0
113     *
114     * @param mixed[] $setings An array with TinyMCE config.
115     *
116     * @return mixed[] An array with TinyMCE config.
117     */
118    public function filterTinyMceSettings($settings)
119    {
120        if (isset($settings['content_style'])) {
121            $settings['content_style'] .= ' ' . $this->playerPreviewI18nStyles() . ' ';
122        } else {
123            $settings['content_style'] = $this->playerPreviewI18nStyles() . ' ';
124        }
125
126        return $settings;
127    }
128
129    /**
130     * Add editor styles.
131     *
132     * Adds i18n-compatible Block Editor CSS for the player placeholder.
133     *
134     * @since 3.3.0
135     */
136    public function addEditorStyles()
137    {
138        $allowed_html = array(
139            'style' => array(),
140        );
141
142        echo wp_kses(
143            sprintf('<style>%s</style>', $this->playerPreviewI18nStyles()),
144            $allowed_html
145        );
146    }
147
148    /**
149     * Add Block Editor Stylesheet.
150     */
151    public function addBlockEditorStylesheet($hook)
152    {
153        // Only enqueue for Gutenberg/Post screens
154        if (CoreUtils::isGutenbergPage() || $hook === 'post.php' || $hook === 'post-new.php') {
155            // Register the Classic/Block Editor "Add Player" CSS
156            wp_enqueue_style(
157                'beyondwords-AddPlayer',
158                BEYONDWORDS__PLUGIN_URI . 'src/Component/Post/AddPlayer/AddPlayer.css',
159                array(),
160                BEYONDWORDS__PLUGIN_VERSION
161            );
162        }
163    }
164}