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