Completed
Push — update/jitm-test ( 03ced2...c48940 )
by
unknown
212:35 queued 203:56
created

Jetpack_Gutenberg::block_has_asset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 3
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 `index.json`
5
 *
6
 * @package Jetpack
7
 */
8
9
/**
10
 * Helper function to register a Jetpack Gutenberg block
11
 *
12
 * @param string $slug Slug of the block
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( $slug, $args = array(), $availability = array( 'available' => true ) ) {
23
	Jetpack_Gutenberg::register( $slug, $args, $availability );
24
}
25
26
/**
27
 * Helper function to register a Jetpack Gutenberg plugin
28
 *
29
 * @param string $slug Slug of the plugin.
30
 * @param array  $avalibility Arguments that tells us what kind of avalibility the plugin 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...
31
 *
32
 * @see register_block_type
33
 *
34
 * @since 6.9.0
35
 *
36
 * @return void
37
 */
38
function jetpack_register_plugin( $slug, $availability = array( 'available' => true ) ) {
39
	Jetpack_Gutenberg::register( $slug, array(), $availability );
40
}
41
42
/**
43
 * General Gutenberg editor specific functionality
44
 */
45
class Jetpack_Gutenberg {
46
47
	// BLOCKS
48
	private static $default_blocks = array(
49
		'map',
50
		'markdown',
51
		'simple-payments',
52
		'related-posts',
53
		'contact-form',
54
		'field-text',
55
		'field-name',
56
		'field-email',
57
		'field-url',
58
		'field-date',
59
		'field-telephone',
60
		'field-textarea',
61
		'field-checkbox',
62
		'field-checkbox-multiple',
63
		'field-radio',
64
		'field-select'
65
	);
66
67
	/**
68
	 * @var array Array of blocks information.
69
	 *
70
	 * For each block we have information about the availability for the current user
71
	 */
72
	private static $blocks = array();
73
74
	private static $availability = array();
75
76
	// PLUGINS
77
	private static $default_plugins = array(
78
		'publicize',
79
		'shortlinks',
80
	);
81
	/**
82
	 * @var array Array of plugins information.
83
	 *
84
	 * For each block we have information about the availability for the current user
85
	 */
86
	private static $plugins = array();
87
88
	/**
89
	 * @var array Array of extensions we will be registering.
90
	 */
91
	private static $registered = array();
92
93
	/**
94
	 * Add a block to the list of blocks to be registered.
95
	 *
96
	 * @param string $slug Slug of the block.
97
	 * @param array  $args Arguments that are passed into the register_block_type.
98
	 * @param array $availability array containing if a block is available and the reason when it is not.
99
	 */
100
	public static function register( $slug, $args, $availability ) {
101
		$sanitized_slug = sanitize_title_with_dashes( $slug );
102
		self::$registered[ $sanitized_slug ] = array( 'args' => $args, 'availability' => $availability );
103
	}
104
105
	/**
106
	 * Register all Jetpack blocks available.
107
	 *
108
	 * @return void
109
	 */
110
	public static function init() {
111
		if ( ! self::is_gutenberg_available() ) {
112
			return;
113
		}
114
115
		if ( ! self::should_load() ) {
116
			return;
117
		}
118
119
		if ( Jetpack_Constants::is_true( 'REST_API_REQUEST' ) ) {
120
			// We defer the loading of the blocks until we have a better scope in reset requests.
121
122
			add_filter( 'rest_request_before_callbacks', array( __CLASS__, 'load' ) );
123
			return;
124
		}
125
126
		self::load();
127
	}
128
129
	/**
130
	 * @deprecated
131
	 */
132
	static function load_blocks() {
133
		self::init();
134
	}
135
136
	/**
137
	 * Add a block to the list of blocks to be registered.
138
	 *
139
	 * @param string $slug Slug of the block.
0 ignored issues
show
Bug introduced by
There is no parameter named $slug. 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...
140
	 * @param array  $args Arguments that are passed into the register_block_type.
141
	 * @param array $availability array containing if a block is available and the reason when it is not.
142
	 *
143
	 * @deprecated
144
	 */
145
	static function add_block( $type, $args, $availability ) {
146
		self::register( $type, $args, $availability );
147
	}
148
149
	static function load( $request = null ) {
150
		/**
151
		 * Filter the list of block editor blocks that are available through jetpack.
152
		 *
153
		 * This filter is populated by Jetpack_Gutenberg::jetpack_set_available_blocks
154
		 *
155
		 * @since 6.8.0
156
		 *
157
		 * @param array
158
		 */
159
		self::$blocks = apply_filters( 'jetpack_set_available_blocks', self::$default_blocks );
160
161
		/**
162
		 * Filter the list of block editor plugins that are available through jetpack.
163
		 *
164
		 * This filter is populated by Jetpack_Gutenberg::jetpack_set_available_blocks
165
		 *
166
		 * @since 6.9.0
167
		 *
168
		 * @param array
169
		 */
170
		self::$plugins = apply_filters( 'jetpack_set_available_plugins', self::$default_plugins );
171
		self::set_blocks_availability();
172
		self::set_plugins_availability();
173
		self::register_blocks();
174
		return $request;
175
	}
176
177
	static function is_registered( $slug ) {
178
		return isset( self::$registered[ $slug ] );
179
	}
180
181
	static function get_registered_args( $slug ) {
182
		return self::$registered[ $slug ]['args'];
183
	}
184
	static function get_registered_type( $slug ) {
185
		return self::$registered[ $slug ]['type'];
186
	}
187
188
	static function is_available( $slug ) {
189
		if ( ! isset( self::$availability[ $slug ]['available'] ) ) {
190
			return false;
191
		}
192
		return (bool) self::$availability[ $slug ]['available'];
193
	}
194
195
196
	static function get_extension_availability( $slug ) {
197
		if ( ! self::is_registered( $slug ) ) {
198
			return array( 'available' => false, 'unavailable_reason' => 'missing_module' );
199
		}
200
201
		$availability = self::$registered[ $slug ]['availability'];
202
203
		if ( isset( $availability['callback'] ) ) {
204
			$availability = call_user_func( $availability['callback'] );
205
		}
206
207
		$availability['available'] = isset( $availability['available'] )
208
			? (bool) $availability['available']
209
			: true ; // this is the default value
210
211
		if ( ! $availability['available'] ) {
212
			$availability['unavailable_reason'] = isset( $availability['unavailable_reason'] )
213
				? $availability['unavailable_reason']
214
				: 'unknown'; //
215
		}
216
217
		return $availability;
218
	}
219
220
	static function set_blocks_availability() {
221
		foreach ( self::$blocks as $slug ) {
222
			self::$availability[ $slug ] = self::get_extension_availability( $slug );
223
		}
224
	}
225
226
	static function set_plugins_availability() {
227
		foreach ( self::$plugins as $slug ) {
228
			self::$availability[ $slug ] = self::get_extension_availability( $slug );
229
		}
230
	}
231
232
	static function register_blocks() {
233
		foreach ( self::$blocks as $slug ) {
234
			if ( self::is_available( $slug ) ) {
235
				register_block_type( 'jetpack/' . $slug, self::get_registered_args( $slug ) );
236
			}
237
		}
238
	}
239
240
	/**
241
	 * Return the Gutenberg extensions (blocks and plugins) directory
242
	 *
243
	 * @return string The Gutenberg extensions directory
244
	 */
245
	public static function get_blocks_directory() {
246
		/**
247
		 * Filter to select Gutenberg blocks directory
248
		 *
249
		 * @since 6.9
250
		 *
251
		 * @param string default: '_inc/blocks/'
252
		 */
253
		return apply_filters( 'jetpack_blocks_directory', '_inc/blocks/' );
254
	}
255
256
	/**
257
	 * Checks for a given .json file in the blocks folder.
258
	 *
259
	 * @param $preset The name of the .json file to look for.
260
	 *
261
	 * @return bool True if the file is found.
262
	 */
263
	public static function preset_exists( $preset ) {
264
		return file_exists( JETPACK__PLUGIN_DIR . self::get_blocks_directory() . $preset . '.json' );
265
	}
266
267
	/**
268
	 * Decodes JSON loaded from a preset file in the blocks folder
269
	 *
270
	 * @param $preset The name of the .json file to load.
271
	 *
272
	 * @return mixed Returns an object if the file is present, or false if a valid .json file is not present.
273
	 */
274
	public static function get_preset( $preset ) {
275
		return json_decode( file_get_contents(  JETPACK__PLUGIN_DIR .self::get_blocks_directory() . $preset . '.json' ) );
276
	}
277
278
	/**
279
	 * Filters the results of `apply_filter( 'jetpack_set_available_blocks', array() )`
280
	 * using the merged contents of `blocks-manifest.json` ( $preset_blocks )
281
	 * and self::$jetpack_blocks ( $internal_blocks )
282
	 *
283
	 * @param $blocks The default list.
284
	 *
285
	 * @return array A list of blocks: eg [ 'publicize', 'markdown' ]
286
	 */
287
	public static function jetpack_set_available_blocks( $blocks ) {
288
		$preset_blocks_manifest =  self::preset_exists( 'index' ) ? self::get_preset( 'index' ) : (object) array( 'blocks' => $blocks );
289
		// manifest shouldn't remove default blocks...
290
291
		$preset_blocks = isset( $preset_blocks_manifest->production ) ? (array) $preset_blocks_manifest->production : array() ;
292
		$preset_blocks = array_unique( array_merge( $preset_blocks, $blocks ) );
293
294
		if ( Jetpack_Constants::is_true( 'JETPACK_BETA_BLOCKS' ) ) {
295
			$beta_blocks = isset( $preset_blocks_manifest->beta ) ? (array) $preset_blocks_manifest->beta : array();
296
			return array_unique( array_merge( $preset_blocks, $beta_blocks ) );
297
		}
298
299
		return $preset_blocks;
300
	}
301
302
	/**
303
	 * @deprecated
304
	 * @return array A list of block-availability information, eg: [ "publicize" => ["available" => true ], "markdown" => [ "available" => false, "unavailable_reason" => 'missing_module' ] ]
305
	 */
306
	public static function get_block_availability() {
307
		return self::get_availability();
308
	}
309
310
	/**
311
	 * @return array A list of block and plugins and their availablity status
312
	 */
313
	public static function get_availability() {
314
		if ( ! self::should_load() ) {
315
			return array();
316
		}
317
318
		return self::$availability;
319
	}
320
321
	/**
322
	 * Check if Gutenberg editor is available
323
	 *
324
	 * @since 6.7.0
325
	 *
326
	 * @return bool
327
	 */
328
	public static function is_gutenberg_available() {
329
		return function_exists( 'register_block_type' );
330
	}
331
332
	/**
333
	 * Check whether conditions indicate Gutenberg blocks should be loaded
334
	 *
335
	 * Loading blocks is enabled by default and may be disabled via filter:
336
	 *   add_filter( 'jetpack_gutenberg', '__return_false' );
337
	 *
338
	 * @since 6.7.0
339
	 * @deprecated
340
	 * @return bool
341
	 */
342
	public static function should_load_blocks() {
343
		return self::should_load();
344
	}
345
346
	/**
347
	 * Check whether conditions indicate Gutenberg Extensions (blocks and plugins) should be loaded
348
	 *
349
	 * Loading blocks and plugins is enabled by default and may be disabled via filter:
350
	 *   add_filter( 'jetpack_gutenberg', '__return_false' );
351
	 *
352
	 * @since 6.9.0
353
	 *
354
	 * @return bool
355
	 */
356
	public static function should_load() {
357
		if ( ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) {
358
			return false;
359
		}
360
361
		/**
362
		 * Filter to disable Gutenberg blocks
363
		 *
364
		 * @since 6.5.0
365
		 *
366
		 * @param bool true Whether to load Gutenberg blocks
367
		 */
368
		return (bool) apply_filters( 'jetpack_gutenberg', true );
369
	}
370
371
	/**
372
	 * Only enqueue block assets when needed.
373
	 *
374
	 * @param string $type slug of the block.
375
	 * @param array $script_dependencies An array of view-side Javascript dependencies to be enqueued.
376
	 *
377
	 * @return void
378
	 */
379
	public static function load_assets_as_required( $type, $script_dependencies = array() ) {
380
		if ( is_admin() ) {
381
			// A block's view assets will not be required in wp-admin.
382
			return;
383
		}
384
385
		$type = sanitize_title_with_dashes( $type );
386
		// Enqueue styles.
387
		$style_relative_path = self::get_blocks_directory() . $type . '/view' . ( is_rtl() ? '.rtl' : '' ) . '.css';
388 View Code Duplication
		if ( self::block_has_asset( $style_relative_path ) ) {
389
			$style_version = self::get_asset_version( $style_relative_path );
390
			$view_style    = plugins_url( $style_relative_path, JETPACK__PLUGIN_FILE );
391
			wp_enqueue_style( 'jetpack-block-' . $type, $view_style, array(), $style_version );
392
		}
393
394
		// Enqueue script.
395
		$script_relative_path = self::get_blocks_directory() . $type . '/view.js';
396 View Code Duplication
		if ( self::block_has_asset( $script_relative_path ) ) {
397
			$script_version = self::get_asset_version( $script_relative_path );
398
			$view_script    = plugins_url( $script_relative_path, JETPACK__PLUGIN_FILE );
399
			wp_enqueue_script( 'jetpack-block-' . $type, $view_script, $script_dependencies, $script_version, false );
400
		}
401
402
		wp_localize_script(
403
			'jetpack-block-' . $type,
404
			'Jetpack_Block_Assets_Base_Url',
405
			plugins_url( self::get_blocks_directory(), JETPACK__PLUGIN_FILE )
406
		);
407
	}
408
409
	/**
410
	 * Check if an asset exists for a block.
411
	 *
412
	 * @param string $file Path of the file we are looking for.
413
	 *
414
	 * @return bool $block_has_asset Does the file exist.
415
	 */
416
	public static function block_has_asset( $file ) {
417
		return file_exists( JETPACK__PLUGIN_DIR . $file );
418
	}
419
420
	/**
421
	 * Get the version number to use when loading the file. Allows us to bypass cache when developing.
422
	 *
423
	 * @param string $file Path of the file we are looking for.
424
	 *
425
	 * @return string $script_version Version number.
426
	 */
427
	public static function get_asset_version( $file ) {
428
		return Jetpack::is_development_version() && self::block_has_asset( $file )
429
			? filemtime( JETPACK__PLUGIN_DIR . $file )
430
			: JETPACK__VERSION;
431
	}
432
433
	/**
434
	 * Load Gutenberg editor assets
435
	 *
436
	 * @since 6.7.0
437
	 *
438
	 * @return void
439
	 */
440
	public static function enqueue_block_editor_assets() {
441
		if ( ! self::should_load_blocks() ) {
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Gutenberg::should_load_blocks() has been deprecated.

This method has been deprecated.

Loading history...
442
			return;
443
		}
444
445
		$rtl = is_rtl() ? '.rtl' : '';
446
		$beta = Jetpack_Constants::is_true('JETPACK_BETA_BLOCKS' ) ? '-beta' : '';
447
		$blocks_dir = self::get_blocks_directory();
448
449
		$editor_script = plugins_url( "{$blocks_dir}editor{$beta}.js", JETPACK__PLUGIN_FILE );
450
		$editor_style  = plugins_url( "{$blocks_dir}editor{$beta}{$rtl}.css", JETPACK__PLUGIN_FILE );
451
452
		$version       = Jetpack::is_development_version() && file_exists( JETPACK__PLUGIN_DIR . $blocks_dir . 'editor.js' )
453
			? filemtime( JETPACK__PLUGIN_DIR . $blocks_dir . 'editor.js' )
454
			: JETPACK__VERSION;
455
456
		wp_enqueue_script(
457
			'jetpack-blocks-editor',
458
			$editor_script,
459
			array(
460
				'lodash',
461
				'wp-api-fetch',
462
				'wp-blocks',
463
				'wp-components',
464
				'wp-compose',
465
				'wp-data',
466
				'wp-date',
467
				'wp-edit-post',
468
				'wp-editor',
469
				'wp-element',
470
				'wp-hooks',
471
				'wp-i18n',
472
				'wp-keycodes',
473
				'wp-plugins',
474
				'wp-rich-text',
475
				'wp-token-list',
476
				'wp-url',
477
			),
478
			$version,
479
			false
480
		);
481
482
		wp_localize_script(
483
			'jetpack-blocks-editor',
484
			'Jetpack_Block_Assets_Base_Url',
485
			plugins_url( $blocks_dir . '/', JETPACK__PLUGIN_FILE )
486
		);
487
488
		wp_localize_script(
489
			'jetpack-blocks-editor',
490
			'Jetpack_Editor_Initial_State',
491
			array(
492
				'available_blocks' => self::get_block_availability(),
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Gutenberg::get_block_availability() has been deprecated.

This method has been deprecated.

Loading history...
493
				'jetpack' => array( 'is_active' => Jetpack::is_active() ),
494
			)
495
		);
496
497
		Jetpack::setup_wp_i18n_locale_data();
498
499
		wp_enqueue_style( 'jetpack-blocks-editor', $editor_style, array(), $version );
500
501
		// The social-logos styles are used for Publicize service icons
502
		// TODO: Remove when we ship the icons with the Gutenberg blocks build
503
		wp_enqueue_style( 'social-logos' );
504
	}
505
}
506