Completed
Push — sync-available-blocks ( b84b90...5ead0d )
by
unknown
07:19
created

Jetpack_Gutenberg::get_asset_version()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 1
dl 0
loc 5
rs 10
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 ( 'publicize' === $type ) {
76
				// publicize is not actually a block, it's a gutenberg plugin.
77
				// We will handle it's registration on the client-side.
78
				continue;
79
			}
80
			if ( isset( $args['availability']['available'] ) && $args['availability']['available'] && in_array( $type, self::$blocks_index ) ) {
81
				register_block_type( 'jetpack/' . $type, $args['args'] );
82
			}
83
		}
84
	}
85
86
	/**
87
	 * Checks for a given .json file in the `_inc/blocks` folder.
88
	 *
89
	 * @param $preset The name of the .json file to look for.
90
	 *
91
	 * @return bool True if the file is found.
92
	 */
93
	public static function preset_exists( $preset ) {
94
		return file_exists( JETPACK__PLUGIN_DIR . '/_inc/blocks/' . $preset . '.json' );
95
	}
96
97
	/**
98
	 * Decodes JSON loaded from a preset file in `_inc/blocks`
99
	 *
100
	 * @param $preset The name of the .json file to load.
101
	 *
102
	 * @return mixed Returns an object if the file is present, or false if a valid .json file is not present.
103
	 */
104
	public static function get_preset( $preset ) {
105
		return json_decode( file_get_contents(  JETPACK__PLUGIN_DIR . '/_inc/blocks/' . $preset . '.json' ) );
106
	}
107
108
	/**
109
	 * Filters the results of `apply_filter( 'jetpack_set_available_blocks', array() )`
110
	 * using the contents of `_inc/blocks/blocks-manifest.json`
111
	 *
112
	 * @param $blocks The default list.
113
	 *
114
	 * @return array A list of blocks: eg [ 'publicize', 'markdown' ]
115
	 */
116
	public static function jetpack_set_available_blocks( $blocks ) {
117
		$preset_blocks_manifest =  self::preset_exists( 'block-manifest' ) ? self::get_preset( 'block-manifest' ) : (object) array( 'blocks' => $blocks );
118
		$preset_blocks = isset( $preset_blocks_manifest->blocks ) ? (array) $preset_blocks_manifest->blocks : array() ;
119
		if ( Jetpack_Constants::is_true( 'JETPACK_BETA_BLOCKS' ) ) {
120
			$beta_blocks = isset( $preset_blocks_manifest->betaBlocks ) ? (array) $preset_blocks_manifest->betaBlocks : array();
121
			return array_merge( $preset_blocks, $beta_blocks );
122
		}
123
124
		return $preset_blocks;
125
	}
126
127
	/**
128
	 * @return array A list of block-availability information, eg: [ "publicize" => ["available" => true ], "markdown" => [ "available" => false, "unavailable_reason" => 'missing_module' ] ]
129
	 */
130
	public static function get_block_availability() {
131
132
		if ( ! self::should_load_blocks() ) {
133
			return array();
134
		}
135
136
		$blocks_availability = array(); // default
137
138
		foreach ( self::$jetpack_blocks as $type => $args ) {
139
			if ( ! in_array( $type,  self::$blocks_index ) ) {
140
				// Jetpack shouldn't expose blocks that are not in the manifest.
141
				continue;
142
			}
143
			$availability = $args['availability'];
144
			$available = array(
145
				'available' => ( isset( $availability['available'] ) ? (bool) $availability['available'] : true ),
146
			);
147
			$unavailability_reason = array();
148
			if ( ! $available['available'] ) {
149
				$unavailability_reason = array(
150
					'unavailable_reason' => ( isset( $availability['unavailable_reason'] ) ? $availability['unavailable_reason'] : 'unknown' )
151
				);
152
			}
153
			$blocks_availability[ $type ] = array_merge( $available, $unavailability_reason );
154
		}
155
156
		foreach ( self::$blocks_index as $block ) {
157
			if ( ! isset( $blocks_availability[ $block ] ) ) {
158
				$blocks_availability[ $block ] = array( 'available' => false, 'unavailable_reason' => 'missing_module' );
159
			}
160
		}
161
162
		return $blocks_availability;
163
	}
164
165
	/**
166
	 * Check if Gutenberg editor is available
167
	 *
168
	 * @since 6.7.0
169
	 *
170
	 * @return bool
171
	 */
172
	public static function is_gutenberg_available() {
173
		return function_exists( 'register_block_type' );
174
	}
175
176
	/**
177
	 * Check whether conditions indicate Gutenberg blocks should be loaded
178
	 *
179
	 * Loading blocks is enabled by default and may be disabled via filter:
180
	 *   add_filter( 'jetpack_gutenberg', '__return_false' );
181
	 *
182
	 * @since 6.7.0
183
	 *
184
	 * @return bool
185
	 */
186
	public static function should_load_blocks() {
187
		if ( ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) {
188
			return false;
189
		}
190
191
		/**
192
		 * Filter to disable Gutenberg blocks
193
		 *
194
		 * @since 6.5.0
195
		 *
196
		 * @param bool true Whether to load Gutenberg blocks
197
		 */
198
		return (bool) apply_filters( 'jetpack_gutenberg', true );
199
	}
200
201
	/**
202
	 * Only enqueue block assets when needed.
203
	 *
204
	 * @param string $type slug of the block.
205
	 * @param array $script_dependencies An array of view-side Javascript dependencies to be enqueued.
206
	 *
207
	 * @return void
208
	 */
209
	public static function load_assets_as_required( $type, $script_dependencies = array() ) {
210
		$type = sanitize_title_with_dashes( $type );
211
		// Enqueue styles.
212
		$style_relative_path = '_inc/blocks/' . $type . '/view' . ( is_rtl() ? '.rtl' : '' ) . '.css';
213 View Code Duplication
		if ( self::block_has_asset( $style_relative_path ) ) {
214
			$style_version = self::get_asset_version( $style_relative_path );
215
			$view_style    = plugins_url( $style_relative_path, JETPACK__PLUGIN_DIR );
216
			wp_enqueue_style( 'jetpack-block-' . $type, $view_style, array(), $style_version );
217
		}
218
219
		// Enqueue script.
220
		$script_relative_path = '_inc/blocks/' . $type . '/view.js';
221 View Code Duplication
		if ( self::block_has_asset( $script_relative_path ) ) {
222
			$script_version = self::get_asset_version( $script_relative_path );
223
			$view_script    = plugins_url( $script_relative_path, JETPACK__PLUGIN_FILE );
224
			wp_enqueue_script( 'jetpack-block-' . $type, $view_script, $script_dependencies, $script_version, false );
225
		}
226
	}
227
228
	/**
229
	 * Check if an asset exists for a block.
230
	 *
231
	 * @param string $file Path of the file we are looking for.
232
	 *
233
	 * @return bool $block_has_asset Does the file exist.
234
	 */
235
	public static function block_has_asset( $file ) {
236
		return file_exists( JETPACK__PLUGIN_DIR . $file );
237
	}
238
239
	/**
240
	 * Get the version number to use when loading the file. Allows us to bypass cache when developing.
241
	 *
242
	 * @param string $file Path of the file we are looking for.
243
	 *
244
	 * @return string $script_version Version number.
245
	 */
246
	public static function get_asset_version( $file ) {
247
		return Jetpack::is_development_version() && self::block_has_asset( $file )
248
			? filemtime( JETPACK__PLUGIN_DIR . $file )
249
			: JETPACK__VERSION;
250
	}
251
252
	/**
253
	 * Load Gutenberg editor assets
254
	 *
255
	 * @since 6.7.0
256
	 *
257
	 * @return void
258
	 */
259
	public static function enqueue_block_editor_assets() {
260
		if ( ! self::should_load_blocks() ) {
261
			return;
262
		}
263
264
		$rtl = is_rtl() ? '.rtl' : '';
265
		$beta = Jetpack_Constants::is_true('JETPACK_BETA_BLOCKS' ) ? '-beta' : '';
266
267
		$editor_script = plugins_url( "_inc/blocks/editor{$beta}.js", JETPACK__PLUGIN_FILE );
268
		$editor_style  = plugins_url( "_inc/blocks/editor{$beta}{$rtl}.css", JETPACK__PLUGIN_FILE );
269
270
		$version       = Jetpack::is_development_version() && file_exists( JETPACK__PLUGIN_DIR . '_inc/blocks/editor.js' )
271
			? filemtime( JETPACK__PLUGIN_DIR . '_inc/blocks/editor.js' )
272
			: JETPACK__VERSION;
273
274
		wp_enqueue_script(
275
			'jetpack-blocks-editor',
276
			$editor_script,
277
			array(
278
				'lodash',
279
				'wp-api-fetch',
280
				'wp-blocks',
281
				'wp-components',
282
				'wp-compose',
283
				'wp-data',
284
				'wp-date',
285
				'wp-edit-post',
286
				'wp-editor',
287
				'wp-element',
288
				'wp-hooks',
289
				'wp-i18n',
290
				'wp-keycodes',
291
				'wp-plugins',
292
				'wp-token-list',
293
				'wp-url',
294
			),
295
			$version,
296
			false
297
		);
298
299
		wp_localize_script(
300
			'jetpack-blocks-editor',
301
			'Jetpack_Block_Assets_Base_Url',
302
			plugins_url( '_inc/blocks/', JETPACK__PLUGIN_FILE )
303
		);
304
305
		wp_localize_script(
306
			'jetpack-blocks-editor',
307
			'Jetpack_Editor_Initial_State',
308
			array(
309
				'available_blocks' => self::get_block_availability(),
310
				'jetpack' => array( 'is_active' => Jetpack::is_active() ),
311
			)
312
		);
313
314
		Jetpack::setup_wp_i18n_locale_data();
315
316
		wp_enqueue_style( 'jetpack-blocks-editor', $editor_style, array(), $version );
317
	}
318
}
319