Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
47.14% covered (danger)
47.14%
33 / 70
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
Block_Editor_Extensions
47.14% covered (danger)
47.14%
33 / 70
20.00% covered (danger)
20.00%
1 / 5
65.85
0.00% covered (danger)
0.00%
0 / 1
 init
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
 get_list
22.22% covered (danger)
22.22%
4 / 18
0.00% covered (danger)
0.00%
0 / 1
3.88
 is_extension_available
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 get_activation_url
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 enqueue_extensions
92.59% covered (success)
92.59%
25 / 27
0.00% covered (danger)
0.00%
0 / 1
5.01
1<?php
2/**
3 * VideoPress Extensions
4 *
5 * @package automattic/jetpack-videopress
6 */
7
8namespace Automattic\Jetpack\VideoPress;
9
10use Automattic\Jetpack\Connection\Initial_State as Connection_Initial_State;
11use Automattic\Jetpack\Constants;
12use Automattic\Jetpack\My_Jetpack\Initializer as My_Jetpack_Initializer;
13use Automattic\Jetpack\Status\Host;
14
15/**
16 * VideoPress Extensions class.
17 */
18class Block_Editor_Extensions {
19    /**
20     * What version of the blocks we are loading.
21     *
22     * @var string
23     */
24    public static $blocks_variation = 'production';
25
26    /**
27     * Script handle
28     *
29     * @var string
30     */
31    public static $script_handle = '';
32
33    /**
34     * Initializer
35     *
36     * This method should be called only once by the Block registrar.
37     * Do not call this method again.
38     *
39     * @param string $script_handle - The script handle.
40     */
41    public static function init( $script_handle ) {
42        if ( ! Status::is_registrant_plugin_active() ) {
43            return;
44        }
45
46        /*
47         * Use the videopress/video editor script handle to localize enqueue scripts.
48         * @see https://developer.wordpress.org/reference/functions/generate_block_asset_handle
49         */
50        self::$script_handle = $script_handle;
51
52        /**
53        * Alternative to `JETPACK_BETA_BLOCKS`, set to `true` to load Beta Blocks.
54        *
55        * @since 6.9.0
56        * @deprecated Jetpack 11.8.0 Use jetpack_blocks_variation filter instead.
57        *
58        * @param boolean
59        */
60        if (
61            apply_filters_deprecated(
62                'jetpack_load_beta_blocks',
63                array( false ),
64                'jetpack-11.8.0',
65                'jetpack_blocks_variation'
66            )
67        ) {
68            self::$blocks_variation = 'beta';
69        }
70
71        /*
72         * Get block variation, from the new constant or the old one.
73         */
74        if ( Constants::is_true( 'JETPACK_BETA_BLOCKS' ) ) {
75            self::$blocks_variation = 'beta';
76        }
77
78        $blocks_variation = Constants::get_constant( 'JETPACK_BLOCKS_VARIATION' );
79        if ( ! empty( $blocks_variation ) ) {
80            /**
81             * Allow customizing the variation of blocks in use on a site.
82             * Overwrites any previously set values, whether by constant or filter.
83             *
84             * @since Jetpack 8.1.0
85             *
86             * @param string $block_variation Can be beta, experimental, and production. Defaults to production.
87             */
88            self::$blocks_variation = apply_filters( 'jetpack_blocks_variation', $blocks_variation );
89        }
90
91        // Register the script.
92        add_action( 'enqueue_block_editor_assets', array( __CLASS__, 'enqueue_extensions' ), 1 );
93    }
94
95    /**
96     * Return the extensions list
97     *
98     * @return array The extensions list.
99     */
100    public static function get_list() {
101        $videopress_extensions_file        = __DIR__ . '/../build/block-editor/extensions/index.json';
102        $videopress_extensions_file_exists = file_exists( $videopress_extensions_file );
103        if ( ! $videopress_extensions_file_exists ) {
104            return;
105        }
106
107        $videopress_extensions_data = (array) json_decode(
108            // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
109            file_get_contents( $videopress_extensions_file )
110        );
111
112        $extensions_list = array_map(
113            function ( $extension ) {
114                return array(
115                    'name'      => $extension,
116                    'isBeta'    => true,
117                    'isEnabled' => 'beta' === self::$blocks_variation,
118                );
119            },
120            $videopress_extensions_data['beta']
121        );
122
123        return $extensions_list;
124    }
125
126    /**
127     * Check if the extension is available
128     *
129     * @param string $slug The extension slug.
130     * @return boolean True if the extension is available, false otherwise.
131     */
132    public static function is_extension_available( $slug ) {
133        $extensions_list = self::get_list();
134        foreach ( $extensions_list as $extension ) {
135            if ( $extension['name'] === $slug ) {
136                return $extension['isEnabled'];
137            }
138        }
139
140        return false;
141    }
142
143    /**
144     * Where the block's "Activate VideoPress" button sends a connected site whose module is off.
145     *
146     * The VideoPress page only registers once the module is on, so the switch in Features is the destination.
147     *
148     * @return string
149     */
150    private static function get_activation_url() {
151        if (
152            method_exists( My_Jetpack_Initializer::class, 'is_settings_consolidation_enabled' )
153            && My_Jetpack_Initializer::is_settings_consolidation_enabled()
154        ) {
155            return admin_url( 'admin.php?page=my-jetpack#/features?search=videopress' );
156        }
157
158        return admin_url( 'admin.php?page=jetpack#/settings?term=videopress' );
159    }
160
161    /**
162     * Enqueues the extensions script.
163     */
164    public static function enqueue_extensions() {
165        $extensions_list = self::get_list();
166
167        $site_type = 'jetpack';
168        if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
169            $site_type = 'simple';
170        } elseif ( ( new Host() )->is_woa_site() ) {
171            $site_type = 'atomic';
172        }
173
174        $videopress_editor_state = array(
175            'extensions'                  => $extensions_list,
176            'siteType'                    => $site_type,
177            'myJetpackConnectUrl'         => admin_url( 'admin.php?page=my-jetpack#/connection' ),
178            'jetpackVideoPressSettingUrl' => self::get_activation_url(),
179            'isVideoPressModuleActive'    => Status::is_jetpack_plugin_and_videopress_module_active(),
180            'isStandaloneActive'          => Status::is_standalone_plugin_active(),
181            'imagesURLBase'               => plugin_dir_url( __DIR__ ) . 'build/images/',
182            'playerBridgeUrl'             => plugins_url( '../build/lib/player-bridge.js', __FILE__ ),
183            'webpackPublicPath'           => plugins_url( '../build/', __FILE__ ),
184            // Mirrors Admin_UI::is_chapters_editor_enabled() so the block editor can
185            // hide the "Manage chapters" toolbar button without a round trip.
186            // wp_localize_script() casts scalars to strings, so this arrives client-side
187            // as '1' when enabled and '' when not — same shape as isVideoPressModuleActive
188            // and isStandaloneActive above. Read it as a truthy check, never `=== true`.
189            'chaptersEditorEnabled'       => Admin_UI::is_chapters_editor_enabled(),
190            'trimCutEnabled'              => Admin_UI::is_trim_cut_enabled(),
191            // Also stringified by wp_localize_script(): '1' when the site hides the share menu on every video.
192            'shareMenuDisabled'           => Data::get_videopress_share_menu_disabled(),
193            // Set when the site renders players from the shared bundle: the block editor then previews videos the same way.
194            'inlinePlayer'                => Inline_Player::is_enabled()
195                ? array_merge(
196                    Inline_Player::get_asset_config(),
197                    array( 'preloadDisabled' => Data::get_videopress_player_preload_disabled() )
198                )
199                : null,
200        );
201
202        // Expose initial state of site connection
203        Connection_Initial_State::render_script( self::$script_handle );
204
205        // Expose initial state of videoPress editor
206        wp_localize_script( self::$script_handle, 'videoPressEditorState', $videopress_editor_state );
207    }
208}