Completed
Push — add/contact-form-gutenblock-sd... ( 93c213...30deca )
by
unknown
17:44 queued 10:24
created

Jetpack_Gutenberg::load_blocks()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 5
nop 0
dl 0
loc 26
rs 8.5706
c 0
b 0
f 0
1
<?php
2
/**
3
 * Handles server-side registration and use of all blocks available in Jetpack for the block editor, aka Gutenberg.
4
 * Works in tandem with client-side block registration via `_inc/blocks/block-manifest.json`
5
 *
6
 * @package Jetpack
7
 */
8
9
/**
10
 * Helper function to register a Jetpack Gutenberg block
11
 *
12
 * @param string $type Slug of the block. Will be prefixed with jetpack/.
13
 * @param array  $args Arguments that are passed into the register_block_type.
14
 * @param array  $avalibility Arguments that tells us what kind of avalibility the block has
0 ignored issues
show
Bug introduced by
There is no parameter named $avalibility. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
15
 *
16
 * @see register_block_type
17
 *
18
 * @since 6.7.0
19
 *
20
 * @return void
21
 */
22
function jetpack_register_block( $type, $args = array(), $availability = array( 'available' => true ) ) {
23
	$type = sanitize_title_with_dashes( $type );
24
	Jetpack_Gutenberg::add_block( $type, $args, $availability );
25
}
26
27
/**
28
 * General Gutenberg editor specific functionality
29
 */
30
class Jetpack_Gutenberg {
31
32
	/**
33
	 * Array of blocks we will be registering.
34
	 *
35
	 * @var array $blocks Array of blocks we will be registering.
36
	 */
37
	private static $jetpack_blocks = array();
38
	private static $blocks_index = array();
39
	/**
40
	 * Add a block to the list of blocks to be registered.
41
	 *
42
	 * @param string $type Slug of the block.
43
	 * @param array  $args Arguments that are passed into the register_block_type.
44
	 */
45
	public static function add_block( $type, $args, $availability ) {
46
		self::$jetpack_blocks[ $type ] = array( 'args' => $args, 'availability' => $availability );
47
	}
48
49
	/**
50
	 * Register all Jetpack blocks available.
51
	 *
52
	 * @return void|WP_Block_Type|false The registered block type on success, or false on failure.
53
	 */
54
	public static function load_blocks() {
55
		if ( ! self::is_gutenberg_available() ) {
56
			return;
57
		}
58
59
		if ( ! self::should_load_blocks() ) {
60
			return;
61
		}
62
63
		/**
64
		 * Filter the list of blocks that are available through jetpack.
65
		 *
66
		 * This filter is populated by Jetpack_Gutenberg::jetpack_set_available_blocks
67
		 *
68
		 * @since 6.8.0
69
		 *
70
		 * @param array
71
		 */
72
		self::$blocks_index = apply_filters( 'jetpack_set_available_blocks', array() );
73
74
		foreach ( self::$jetpack_blocks as $type => $args ) {
75
			if ( isset( $args['availability']['available'] ) && $args['availability']['available'] && in_array( $type, self::$blocks_index ) ) {
76
				register_block_type( 'jetpack/' . $type, $args['args'] );
77
			}
78
		}
79
	}
80
81
	/**
82
	 * Checks for a given .json file in the `_inc/blocks` folder.
83
	 *
84
	 * @param $preset The name of the .json file to look for.
85
	 *
86
	 * @return bool True if the file is found.
87
	 */
88
	public static function preset_exists( $preset ) {
89
		return file_exists( JETPACK__PLUGIN_DIR . '/_inc/blocks/' . $preset . '.json' );
90
	}
91
92
	/**
93
	 * Decodes JSON loaded from a preset file in `_inc/blocks`
94
	 *
95
	 * @param $preset The name of the .json file to load.
96
	 *
97
	 * @return mixed Returns an object if the file is present, or false if a valid .json file is not present.
98
	 */
99
	public static function get_preset( $preset ) {
100
		return json_decode( file_get_contents(  JETPACK__PLUGIN_DIR . '/_inc/blocks/' . $preset . '.json' ) );
101
	}
102
103
	/**
104
	 * Filters the results of `apply_filter( 'jetpack_set_available_blocks', array() )`
105
	 * using the merged contents of `_inc/blocks/blocks-manifest.json` ( $preset_blocks )
106
	 * and self::$jetpack_blocks ( $internal_blocks )
107
	 *
108
	 * @param $blocks The default list.
109
	 *
110
	 * @return array A list of blocks: eg [ 'publicize', 'markdown' ]
111
	 */
112
	public static function jetpack_set_available_blocks( $blocks ) {
113
		$preset_blocks_manifest =  self::preset_exists( 'block-manifest' ) ? self::get_preset( 'block-manifest' ) : (object) array( 'blocks' => $blocks );
114
		$preset_blocks = isset( $preset_blocks_manifest->blocks ) ? (array) $preset_blocks_manifest->blocks : array() ;
115
		$internal_blocks = array_keys( self::$jetpack_blocks );
116
117
		if ( Jetpack_Constants::is_true( 'JETPACK_BETA_BLOCKS' ) ) {
118
			$beta_blocks = isset( $preset_blocks_manifest->betaBlocks ) ? (array) $preset_blocks_manifest->betaBlocks : array();
119
			return array_unique( array_merge( $preset_blocks, $beta_blocks, $internal_blocks ) );
120
		}
121
122
		return array_unique( array_merge( $preset_blocks, $internal_blocks ) );
123
	}
124
125
	/**
126
	 * @return array A list of block-availability information, eg: [ "publicize" => ["available" => true ], "markdown" => [ "available" => false, "unavailable_reason" => 'missing_module' ] ]
127
	 */
128
	public static function get_block_availability() {
129
130
		if ( ! self::should_load_blocks() ) {
131
			return array();
132
		}
133
134
		$blocks_availability = array(); // default
135
136
		foreach ( self::$jetpack_blocks as $type => $args ) {
137
			if ( ! in_array( $type,  self::$blocks_index ) ) {
138
				// Jetpack shouldn't expose blocks that are not in the manifest.
139
				continue;
140
			}
141
			$availability = $args['availability'];
142
			$available = array(
143
				'available' => ( isset( $availability['available'] ) ? (bool) $availability['available'] : true ),
144
			);
145
			$unavailability_reason = array();
146
			if ( ! $available['available'] ) {
147
				$unavailability_reason = array(
148
					'unavailable_reason' => ( isset( $availability['unavailable_reason'] ) ? $availability['unavailable_reason'] : 'unknown' )
149
				);
150
			}
151
			$blocks_availability[ $type ] = array_merge( $available, $unavailability_reason );
152
		}
153
154
		foreach ( self::$blocks_index as $block ) {
155
			if ( ! isset( $blocks_availability[ $block ] ) ) {
156
				$blocks_availability[ $block ] = array( 'available' => false, 'unavailable_reason' => 'missing_module' );
157
			}
158
		}
159
160
		return $blocks_availability;
161
	}
162
163
	/**
164
	 * Check if Gutenberg editor is available
165
	 *
166
	 * @since 6.7.0
167
	 *
168
	 * @return bool
169
	 */
170
	public static function is_gutenberg_available() {
171
		return function_exists( 'register_block_type' );
172
	}
173
174
	/**
175
	 * Check whether conditions indicate Gutenberg blocks should be loaded
176
	 *
177
	 * Loading blocks is enabled by default and may be disabled via filter:
178
	 *   add_filter( 'jetpack_gutenberg', '__return_false' );
179
	 *
180
	 * @since 6.7.0
181
	 *
182
	 * @return bool
183
	 */
184
	public static function should_load_blocks() {
185
		if ( ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) {
186
			return false;
187
		}
188
189
		/**
190
		 * Filter to disable Gutenberg blocks
191
		 *
192
		 * @since 6.5.0
193
		 *
194
		 * @param bool true Whether to load Gutenberg blocks
195
		 */
196
		return (bool) apply_filters( 'jetpack_gutenberg', true );
197
	}
198
199
	/**
200
	 * Only enqueue block assets when needed.
201
	 *
202
	 * @param string $type slug of the block.
203
	 * @param array $script_dependencies An array of view-side Javascript dependencies to be enqueued.
204
	 *
205
	 * @return void
206
	 */
207
	public static function load_assets_as_required( $type, $script_dependencies = array() ) {
208
		$type = sanitize_title_with_dashes( $type );
209
		// Enqueue styles.
210
		$style_relative_path = '_inc/blocks/' . $type . '/view' . ( is_rtl() ? '.rtl' : '' ) . '.css';
211 View Code Duplication
		if ( self::block_has_asset( $style_relative_path ) ) {
212
			$style_version = self::get_asset_version( $style_relative_path );
213
			$view_style    = plugins_url( $style_relative_path, JETPACK__PLUGIN_DIR );
214
			wp_enqueue_style( 'jetpack-block-' . $type, $view_style, array(), $style_version );
215
		}
216
217
		// Enqueue script.
218
		$script_relative_path = '_inc/blocks/' . $type . '/view.js';
219 View Code Duplication
		if ( self::block_has_asset( $script_relative_path ) ) {
220
			$script_version = self::get_asset_version( $script_relative_path );
221
			$view_script    = plugins_url( $script_relative_path, JETPACK__PLUGIN_FILE );
222
			wp_enqueue_script( 'jetpack-block-' . $type, $view_script, $script_dependencies, $script_version, false );
223
		}
224
	}
225
226
	/**
227
	 * Check if an asset exists for a block.
228
	 *
229
	 * @param string $file Path of the file we are looking for.
230
	 *
231
	 * @return bool $block_has_asset Does the file exist.
232
	 */
233
	public static function block_has_asset( $file ) {
234
		return file_exists( JETPACK__PLUGIN_DIR . $file );
235
	}
236
237
	/**
238
	 * Get the version number to use when loading the file. Allows us to bypass cache when developing.
239
	 *
240
	 * @param string $file Path of the file we are looking for.
241
	 *
242
	 * @return string $script_version Version number.
243
	 */
244
	public static function get_asset_version( $file ) {
245
		return Jetpack::is_development_version() && self::block_has_asset( $file )
246
			? filemtime( JETPACK__PLUGIN_DIR . $file )
247
			: JETPACK__VERSION;
248
	}
249
250
	/**
251
	 * Load Gutenberg editor assets
252
	 *
253
	 * @since 6.7.0
254
	 *
255
	 * @return void
256
	 */
257
	public static function enqueue_block_editor_assets() {
258
		if ( ! self::should_load_blocks() ) {
259
			return;
260
		}
261
262
		$rtl = is_rtl() ? '.rtl' : '';
263
		$beta = Jetpack_Constants::is_true('JETPACK_BETA_BLOCKS' ) ? '-beta' : '';
264
265
		$editor_script = plugins_url( "_inc/blocks/editor{$beta}.js", JETPACK__PLUGIN_FILE );
266
		$editor_style  = plugins_url( "_inc/blocks/editor{$beta}{$rtl}.css", JETPACK__PLUGIN_FILE );
267
268
		$version       = Jetpack::is_development_version() && file_exists( JETPACK__PLUGIN_DIR . '_inc/blocks/editor.js' )
269
			? filemtime( JETPACK__PLUGIN_DIR . '_inc/blocks/editor.js' )
270
			: JETPACK__VERSION;
271
272
		wp_enqueue_script(
273
			'jetpack-blocks-editor',
274
			$editor_script,
275
			array(
276
				'lodash',
277
				'wp-api-fetch',
278
				'wp-blocks',
279
				'wp-components',
280
				'wp-compose',
281
				'wp-data',
282
				'wp-date',
283
				'wp-edit-post',
284
				'wp-editor',
285
				'wp-element',
286
				'wp-hooks',
287
				'wp-i18n',
288
				'wp-keycodes',
289
				'wp-plugins',
290
				'wp-token-list',
291
				'wp-url',
292
			),
293
			$version,
294
			false
295
		);
296
297
		wp_localize_script(
298
			'jetpack-blocks-editor',
299
			'Jetpack_Block_Assets_Base_Url',
300
			plugins_url( '_inc/blocks/', JETPACK__PLUGIN_FILE )
301
		);
302
303
		wp_localize_script(
304
			'jetpack-blocks-editor',
305
			'Jetpack_Editor_Initial_State',
306
			array(
307
				'available_blocks' => self::get_block_availability(),
308
				'jetpack' => array( 'is_active' => Jetpack::is_active() ),
309
			)
310
		);
311
312
		Jetpack::setup_wp_i18n_locale_data();
313
314
		wp_enqueue_style( 'jetpack-blocks-editor', $editor_style, array(), $version );
315
	}
316
}
317