Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
7 / 7
CRAP
100.00% covered (success)
100.00%
1 / 1
AddPlayer
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
7 / 7
9
100.00% covered (success)
100.00%
1 / 1
 init
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
 register_block
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 add_plugin
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 add_button
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 add_stylesheet
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 player_preview_i18n_styles
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 filter_tiny_mce_settings
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare( strict_types = 1 );
4
5/**
6 * BeyondWords "Add Player" component.
7 *
8 * @package BeyondWords\Editor\Components
9 * @author  Stuart McAlpine <stu@beyondwords.io>
10 * @since   3.2.0
11 * @since   7.0.0 Refactored to BeyondWords namespace with snake_case methods.
12 */
13
14namespace BeyondWords\Editor\Components;
15
16/**
17 * AddPlayer
18 *
19 * @since 3.2.0
20 * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
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     * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
35     */
36    public static function init() {
37        add_action( 'init', [ self::class, 'register_block'] );
38
39        add_filter( 'tiny_mce_before_init', [ self::class, 'filter_tiny_mce_settings'] );
40
41        add_filter( 'mce_external_plugins', [ self::class, 'add_plugin'] );
42        add_filter( 'mce_buttons', [ self::class, 'add_button'] );
43        add_filter( 'mce_css', [ self::class, 'add_stylesheet'] );
44    }
45
46    /**
47     * Register Block.
48     *
49     * @since 3.2.0
50     * @since 6.0.0 Make static.
51     * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
52     */
53    public static function register_block() {
54        \register_block_type( __DIR__ );
55    }
56
57    /**
58     * Add TinyMCE buttons.
59     *
60     * @since 6.0.0 Make static.
61     * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
62     *
63     * @param array TinyMCE plugin array
64     */
65    public static function add_plugin( $plugin_array ) {
66        $plugin_array['beyondwords_player'] = BEYONDWORDS__PLUGIN_URI . 'src/editor/components/add-player/tinymce.js';
67        return $plugin_array;
68    }
69
70    /**
71     * Register TinyMCE buttons.
72     *
73     * @since 6.0.0 Make static.
74     * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
75     *
76     * @param array TinyMCE buttons array
77     */
78    public static function add_button( $buttons ) {
79        $adv_index = array_search( 'wp_adv', $buttons );
80
81        if ( $adv_index === false ) {
82            $adv_index = count( $buttons );
83        }
84
85        array_splice( $buttons, $adv_index, 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     * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
95     *
96     * @param string $stylesheets Comma-delimited list of stylesheets.
97     *
98     * @return string Comma-delimited list of stylesheets with the "Add Player" CSS appended.
99     */
100    public static function add_stylesheet( $stylesheets ) {
101        return $stylesheets . ',' . BEYONDWORDS__PLUGIN_URI . 'src/editor/components/add-player/add-player.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     * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
112     *
113     * @return string CSS Block for player preview i18n delcerations.
114     */
115    public static function player_preview_i18n_styles() {
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     * @since 7.0.0 Refactored to BeyondWords namespace with snake_case methods.
130     *
131     * @param mixed[] $setings An array with TinyMCE config.
132     *
133     * @return mixed[] An array with TinyMCE config.
134     */
135    public static function filter_tiny_mce_settings( $settings ) {
136        if ( isset( $settings['content_style'] ) ) {
137            $settings['content_style'] .= ' ' . self::player_preview_i18n_styles() . ' ';
138        } else {
139            $settings['content_style'] = self::player_preview_i18n_styles() . ' ';
140        }
141
142        return $settings;
143    }
144}