Completed
Push — try/namespacing-all-the-things ( 457764 )
by
unknown
08:24
created

class.jetpack-gutenberg.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
/**
3
 * Handles server-side registration and use of all blocks and plugins 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
use Automattic\Jetpack\Constants;
10
11
/**
12
 * Wrapper function to safely register a gutenberg block type
13
 *
14
 * @param string $slug Slug of the block.
15
 * @param array  $args Arguments that are passed into register_block_type.
16
 *
17
 * @see register_block_type
18
 *
19
 * @since 6.7.0
20
 *
21
 * @return WP_Block_Type|false The registered block type on success, or false on failure.
22
 */
23
function jetpack_register_block( $slug, $args = array() ) {
24
	if ( 0 !== strpos( $slug, 'jetpack/' ) && ! strpos( $slug, '/' ) ) {
25
		_doing_it_wrong( 'jetpack_register_block', 'Prefix the block with jetpack/ ', '7.1.0' );
26
		$slug = 'jetpack/' . $slug;
27
	}
28
29
	// Checking whether block is registered to ensure it isn't registered twice.
30
	if ( Jetpack_Gutenberg::is_registered( $slug ) ) {
31
		return false;
32
	}
33
34
	return register_block_type( $slug, $args );
35
}
36
37
/**
38
 * Helper function to register a Jetpack Gutenberg plugin
39
 *
40
 * @deprecated 7.1.0 Use Jetpack_Gutenberg::set_extension_available() instead
41
 *
42
 * @param string $slug Slug of the plugin.
43
 *
44
 * @since 6.9.0
45
 *
46
 * @return void
47
 */
48
function jetpack_register_plugin( $slug ) {
49
	_deprecated_function( __FUNCTION__, '7.1', 'Jetpack_Gutenberg::set_extension_available' );
50
51
	Jetpack_Gutenberg::register_plugin( $slug );
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Gutenberg::register_plugin() has been deprecated with message: 7.1.0 Use Jetpack_Gutenberg::set_extension_available() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
52
}
53
54
/**
55
 * Set the reason why an extension (block or plugin) is unavailable
56
 *
57
 * @deprecated 7.1.0 Use Jetpack_Gutenberg::set_extension_unavailable() instead
58
 *
59
 * @param string $slug Slug of the block.
60
 * @param string $reason A string representation of why the extension is unavailable.
61
 *
62
 * @since 7.0.0
63
 *
64
 * @return void
65
 */
66
function jetpack_set_extension_unavailability_reason( $slug, $reason ) {
67
	_deprecated_function( __FUNCTION__, '7.1', 'Jetpack_Gutenberg::set_extension_unavailable' );
68
69
	Jetpack_Gutenberg::set_extension_unavailability_reason( $slug, $reason );
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Gutenberg::set_e...unavailability_reason() has been deprecated with message: 7.1.0 Use set_extension_unavailable() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
70
}
71
72
/**
73
 * General Gutenberg editor specific functionality
74
 */
75
class Jetpack_Gutenberg {
76
77
	/**
78
	 * Only these extensions can be registered. Used to control availability of beta blocks.
79
	 *
80
	 * @var array Extensions whitelist
81
	 */
82
	private static $extensions = array();
83
84
	/**
85
	 * Keeps track of the reasons why a given extension is unavailable.
86
	 *
87
	 * @var array Extensions availability information
88
	 */
89
	private static $availability = array();
90
91
	/**
92
	 * Prepend the 'jetpack/' prefix to a block name
93
	 *
94
	 * @param string $block_name The block name.
95
	 *
96
	 * @return string The prefixed block name.
97
	 */
98
	private static function prepend_block_prefix( $block_name ) {
99
		return 'jetpack/' . $block_name;
100
	}
101
102
	/**
103
	 * Remove the 'jetpack/' or jetpack-' prefix from an extension name
104
	 *
105
	 * @param string $extension_name The extension name.
106
	 *
107
	 * @return string The unprefixed extension name.
108
	 */
109
	private static function remove_extension_prefix( $extension_name ) {
110
		if ( wp_startswith( $extension_name, 'jetpack/' ) || wp_startswith( $extension_name, 'jetpack-' ) ) {
111
			return substr( $extension_name, strlen( 'jetpack/' ) );
112
		}
113
		return $extension_name;
114
	}
115
116
	/**
117
	 * Whether two arrays share at least one item
118
	 *
119
	 * @param array $a An array.
120
	 * @param array $b Another array.
121
	 *
122
	 * @return boolean True if $a and $b share at least one item
123
	 */
124
	protected static function share_items( $a, $b ) {
125
		return count( array_intersect( $a, $b ) ) > 0;
126
	}
127
128
	/**
129
	 * Register a block
130
	 *
131
	 * @deprecated 7.1.0 Use jetpack_register_block() instead
132
	 *
133
	 * @param string $slug Slug of the block.
134
	 * @param array  $args Arguments that are passed into register_block_type().
135
	 */
136
	public static function register_block( $slug, $args ) {
137
		_deprecated_function( __METHOD__, '7.1', 'jetpack_register_block' );
138
139
		jetpack_register_block( 'jetpack/' . $slug, $args );
140
	}
141
142
	/**
143
	 * Register a plugin
144
	 *
145
	 * @deprecated 7.1.0 Use Jetpack_Gutenberg::set_extension_available() instead
146
	 *
147
	 * @param string $slug Slug of the plugin.
148
	 */
149
	public static function register_plugin( $slug ) {
150
		_deprecated_function( __METHOD__, '7.1', 'Jetpack_Gutenberg::set_extension_available' );
151
152
		self::set_extension_available( $slug );
153
	}
154
155
	/**
156
	 * Register a block
157
	 *
158
	 * @deprecated 7.0.0 Use jetpack_register_block() instead
159
	 *
160
	 * @param string $slug Slug of the block.
161
	 * @param array  $args Arguments that are passed into the register_block_type.
162
	 * @param array  $availability array containing if a block is available and the reason when it is not.
163
	 */
164
	public static function register( $slug, $args, $availability ) {
165
		_deprecated_function( __METHOD__, '7.0', 'jetpack_register_block' );
166
167
		if ( isset( $availability['available'] ) && ! $availability['available'] ) {
168
			self::set_extension_unavailability_reason( $slug, $availability['unavailable_reason'] );
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Gutenberg::set_e...unavailability_reason() has been deprecated with message: 7.1.0 Use set_extension_unavailable() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
169
		} else {
170
			self::register_block( $slug, $args );
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Gutenberg::register_block() has been deprecated with message: 7.1.0 Use jetpack_register_block() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
171
		}
172
	}
173
174
	/**
175
	 * Set a (non-block) extension as available
176
	 *
177
	 * @param string $slug Slug of the extension.
178
	 */
179
	public static function set_extension_available( $slug ) {
180
		self::$availability[ self::remove_extension_prefix( $slug ) ] = true;
181
	}
182
183
	/**
184
	 * Set the reason why an extension (block or plugin) is unavailable
185
	 *
186
	 * @param string $slug Slug of the extension.
187
	 * @param string $reason A string representation of why the extension is unavailable.
188
	 */
189
	public static function set_extension_unavailable( $slug, $reason ) {
190
		self::$availability[ self::remove_extension_prefix( $slug ) ] = $reason;
191
	}
192
193
	/**
194
	 * Set the reason why an extension (block or plugin) is unavailable
195
	 *
196
	 * @deprecated 7.1.0 Use set_extension_unavailable() instead
197
	 *
198
	 * @param string $slug Slug of the extension.
199
	 * @param string $reason A string representation of why the extension is unavailable.
200
	 */
201
	public static function set_extension_unavailability_reason( $slug, $reason ) {
202
		_deprecated_function( __METHOD__, '7.1', 'Jetpack_Gutenberg::set_extension_unavailable' );
203
204
		self::set_extension_unavailable( $slug, $reason );
205
	}
206
207
	/**
208
	 * Set up a whitelist of allowed block editor extensions
209
	 *
210
	 * @return void
211
	 */
212
	public static function init() {
213
		if ( ! self::should_load() ) {
214
			return;
215
		}
216
217
		/**
218
		 * Alternative to `JETPACK_BETA_BLOCKS`, set to `true` to load Beta Blocks.
219
		 *
220
		 * @since 6.9.0
221
		 *
222
		 * @param boolean
223
		 */
224
		if ( apply_filters( 'jetpack_load_beta_blocks', false ) ) {
225
			Constants::set_constant( 'JETPACK_BETA_BLOCKS', true );
226
		}
227
228
		/**
229
		 * Filter the whitelist of block editor extensions that are available through Jetpack.
230
		 *
231
		 * @since 7.0.0
232
		 *
233
		 * @param array
234
		 */
235
		self::$extensions = apply_filters( 'jetpack_set_available_extensions', self::get_available_extensions() );
236
237
		/**
238
		 * Filter the whitelist of block editor plugins that are available through Jetpack.
239
		 *
240
		 * @deprecated 7.0.0 Use jetpack_set_available_extensions instead
241
		 *
242
		 * @since 6.8.0
243
		 *
244
		 * @param array
245
		 */
246
		self::$extensions = apply_filters( 'jetpack_set_available_blocks', self::$extensions );
247
248
		/**
249
		 * Filter the whitelist of block editor plugins that are available through Jetpack.
250
		 *
251
		 * @deprecated 7.0.0 Use jetpack_set_available_extensions instead
252
		 *
253
		 * @since 6.9.0
254
		 *
255
		 * @param array
256
		 */
257
		self::$extensions = apply_filters( 'jetpack_set_available_plugins', self::$extensions );
258
	}
259
260
	/**
261
	 * Resets the class to its original state
262
	 *
263
	 * Used in unit tests
264
	 *
265
	 * @return void
266
	 */
267
	public static function reset() {
268
		self::$extensions   = array();
269
		self::$availability = array();
270
	}
271
272
	/**
273
	 * Return the Gutenberg extensions (blocks and plugins) directory
274
	 *
275
	 * @return string The Gutenberg extensions directory
276
	 */
277
	public static function get_blocks_directory() {
278
		/**
279
		 * Filter to select Gutenberg blocks directory
280
		 *
281
		 * @since 6.9.0
282
		 *
283
		 * @param string default: '_inc/blocks/'
284
		 */
285
		return apply_filters( 'jetpack_blocks_directory', '_inc/blocks/' );
286
	}
287
288
	/**
289
	 * Checks for a given .json file in the blocks folder.
290
	 *
291
	 * @param string $preset The name of the .json file to look for.
292
	 *
293
	 * @return bool True if the file is found.
294
	 */
295
	public static function preset_exists( $preset ) {
296
		return file_exists( JETPACK__PLUGIN_DIR . self::get_blocks_directory() . $preset . '.json' );
297
	}
298
299
	/**
300
	 * Decodes JSON loaded from a preset file in the blocks folder
301
	 *
302
	 * @param string $preset The name of the .json file to load.
303
	 *
304
	 * @return mixed Returns an object if the file is present, or false if a valid .json file is not present.
305
	 */
306
	public static function get_preset( $preset ) {
307
		return json_decode(
308
			// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
309
			file_get_contents( JETPACK__PLUGIN_DIR . self::get_blocks_directory() . $preset . '.json' )
310
		);
311
	}
312
313
	/**
314
	 * Returns a whitelist of Jetpack Gutenberg extensions (blocks and plugins), based on index.json
315
	 *
316
	 * @return array A list of blocks: eg [ 'publicize', 'markdown' ]
317
	 */
318
	public static function get_jetpack_gutenberg_extensions_whitelist() {
319
		$preset_extensions_manifest = self::preset_exists( 'index' ) ? self::get_preset( 'index' ) : (object) array();
320
321
		$preset_extensions = isset( $preset_extensions_manifest->production ) ? (array) $preset_extensions_manifest->production : array();
322
323
		if ( Constants::is_true( 'JETPACK_BETA_BLOCKS' ) ) {
324
			$beta_extensions = isset( $preset_extensions_manifest->beta ) ? (array) $preset_extensions_manifest->beta : array();
325
			return array_unique( array_merge( $preset_extensions, $beta_extensions ) );
326
		}
327
328
		return $preset_extensions;
329
	}
330
331
	/**
332
	 * Returns a diff from a combined list of whitelisted extensions and extensions determined to be excluded
333
	 *
334
	 * @param  array $whitelisted_extensions An array of whitelisted extensions.
335
	 *
336
	 * @return array A list of blocks: eg array( 'publicize', 'markdown' )
337
	 */
338
	public static function get_available_extensions( $whitelisted_extensions = null ) {
339
		$exclusions             = get_option( 'jetpack_excluded_extensions', array() );
340
		$whitelisted_extensions = is_null( $whitelisted_extensions ) ? self::get_jetpack_gutenberg_extensions_whitelist() : $whitelisted_extensions;
341
342
		return array_diff( $whitelisted_extensions, $exclusions );
343
	}
344
345
	/**
346
	 * Get availability of each block / plugin.
347
	 *
348
	 * @return array A list of block and plugins and their availablity status
349
	 */
350
	public static function get_availability() {
351
		/**
352
		 * Fires before Gutenberg extensions availability is computed.
353
		 *
354
		 * In the function call you supply, use `jetpack_register_block()` to set a block as available.
355
		 * Alternatively, use `Jetpack_Gutenberg::set_extension_available()` (for a non-block plugin), and
356
		 * `Jetpack_Gutenberg::set_extension_unavailable()` (if the block or plugin should not be registered
357
		 * but marked as unavailable).
358
		 *
359
		 * @since 7.0.0
360
		 */
361
		do_action( 'jetpack_register_gutenberg_extensions' );
362
363
		$available_extensions = array();
364
365
		foreach ( self::$extensions as $extension ) {
366
			$is_available = self::is_registered( 'jetpack/' . $extension ) ||
367
			( isset( self::$availability[ $extension ] ) && true === self::$availability[ $extension ] );
368
369
			$available_extensions[ $extension ] = array(
370
				'available' => $is_available,
371
			);
372
373
			if ( ! $is_available ) {
374
				$reason = isset( self::$availability[ $extension ] ) ? self::$availability[ $extension ] : 'missing_module';
375
				$available_extensions[ $extension ]['unavailable_reason'] = $reason;
376
			}
377
		}
378
379
		return $available_extensions;
380
	}
381
382
	/**
383
	 * Check if an extension/block is already registered
384
	 *
385
	 * @since 7.2
386
	 *
387
	 * @param string $slug Name of extension/block to check.
388
	 *
389
	 * @return bool
390
	 */
391
	public static function is_registered( $slug ) {
392
		return WP_Block_Type_Registry::get_instance()->is_registered( $slug );
393
	}
394
395
	/**
396
	 * Check if Gutenberg editor is available
397
	 *
398
	 * @since 6.7.0
399
	 *
400
	 * @return bool
401
	 */
402
	public static function is_gutenberg_available() {
403
		return true;
404
	}
405
406
	/**
407
	 * Check whether conditions indicate Gutenberg Extensions (blocks and plugins) should be loaded
408
	 *
409
	 * Loading blocks and plugins is enabled by default and may be disabled via filter:
410
	 *   add_filter( 'jetpack_gutenberg', '__return_false' );
411
	 *
412
	 * @since 6.9.0
413
	 *
414
	 * @return bool
415
	 */
416
	public static function should_load() {
417
		if ( ! Jetpack::is_active() && ! Jetpack::is_development_mode() ) {
418
			return false;
419
		}
420
421
		/**
422
		 * Filter to disable Gutenberg blocks
423
		 *
424
		 * @since 6.5.0
425
		 *
426
		 * @param bool true Whether to load Gutenberg blocks
427
		 */
428
		return (bool) apply_filters( 'jetpack_gutenberg', true );
429
	}
430
431
	/**
432
	 * Only enqueue block assets when needed.
433
	 *
434
	 * @param string $type Slug of the block.
435
	 * @param array  $script_dependencies Script dependencies. Will be merged with automatically
436
	 *                                    detected script dependencies from the webpack build.
437
	 *
438
	 * @return void
439
	 */
440
	public static function load_assets_as_required( $type, $script_dependencies = array() ) {
441
		if ( is_admin() ) {
442
			// A block's view assets will not be required in wp-admin.
443
			return;
444
		}
445
446
		$type = sanitize_title_with_dashes( $type );
447
		self::load_styles_as_required( $type );
448
		self::load_scripts_as_required( $type, $script_dependencies );
449
	}
450
451
	/**
452
	 * Only enqueue block sytles when needed.
453
	 *
454
	 * @param string $type Slug of the block.
455
	 *
456
	 * @since 7.2.0
457
	 *
458
	 * @return void
459
	 */
460
	public static function load_styles_as_required( $type ) {
461
		if ( is_admin() ) {
462
			// A block's view assets will not be required in wp-admin.
463
			return;
464
		}
465
466
		// Enqueue styles.
467
		$style_relative_path = self::get_blocks_directory() . $type . '/view' . ( is_rtl() ? '.rtl' : '' ) . '.css';
468
		if ( self::block_has_asset( $style_relative_path ) ) {
469
			$style_version = self::get_asset_version( $style_relative_path );
470
			$view_style    = plugins_url( $style_relative_path, JETPACK__PLUGIN_FILE );
471
			wp_enqueue_style( 'jetpack-block-' . $type, $view_style, array(), $style_version );
472
		}
473
474
	}
475
476
	/**
477
	 * Only enqueue block scripts when needed.
478
	 *
479
	 * @param string $type Slug of the block.
480
	 * @param array  $dependencies Script dependencies. Will be merged with automatically
481
	 *                             detected script dependencies from the webpack build.
482
	 *
483
	 * @since 7.2.0
484
	 *
485
	 * @return void
486
	 */
487
	public static function load_scripts_as_required( $type, $dependencies = array() ) {
488
		if ( is_admin() ) {
489
			// A block's view assets will not be required in wp-admin.
490
			return;
491
		}
492
493
		// Enqueue script.
494
		$script_relative_path = self::get_blocks_directory() . $type . '/view.js';
495
		$script_deps_path     = JETPACK__PLUGIN_DIR . self::get_blocks_directory() . $type . '/view.deps.json';
496
497
		$script_dependencies = file_exists( $script_deps_path )
498
			// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
499
			? json_decode( file_get_contents( $script_deps_path ) )
500
			: array();
501
		$script_dependencies = array_merge( $script_dependencies, $dependencies, array( 'wp-polyfill' ) );
502
503
		if ( ( ! class_exists( 'Jetpack_AMP_Support' ) || ! Jetpack_AMP_Support::is_amp_request() ) && self::block_has_asset( $script_relative_path ) ) {
504
			$script_version = self::get_asset_version( $script_relative_path );
505
			$view_script    = plugins_url( $script_relative_path, JETPACK__PLUGIN_FILE );
506
			wp_enqueue_script( 'jetpack-block-' . $type, $view_script, $script_dependencies, $script_version, false );
507
		}
508
509
		wp_localize_script(
510
			'jetpack-block-' . $type,
511
			'Jetpack_Block_Assets_Base_Url',
512
			plugins_url( self::get_blocks_directory(), JETPACK__PLUGIN_FILE )
513
		);
514
	}
515
516
	/**
517
	 * Check if an asset exists for a block.
518
	 *
519
	 * @param string $file Path of the file we are looking for.
520
	 *
521
	 * @return bool $block_has_asset Does the file exist.
522
	 */
523
	public static function block_has_asset( $file ) {
524
		return file_exists( JETPACK__PLUGIN_DIR . $file );
525
	}
526
527
	/**
528
	 * Get the version number to use when loading the file. Allows us to bypass cache when developing.
529
	 *
530
	 * @param string $file Path of the file we are looking for.
531
	 *
532
	 * @return string $script_version Version number.
533
	 */
534
	public static function get_asset_version( $file ) {
535
		return Jetpack::is_development_version() && self::block_has_asset( $file )
536
			? filemtime( JETPACK__PLUGIN_DIR . $file )
537
			: JETPACK__VERSION;
538
	}
539
540
	/**
541
	 * Load Gutenberg editor assets
542
	 *
543
	 * @since 6.7.0
544
	 *
545
	 * @return void
546
	 */
547
	public static function enqueue_block_editor_assets() {
548
		if ( ! self::should_load() ) {
549
			return;
550
		}
551
552
		$rtl        = is_rtl() ? '.rtl' : '';
553
		$beta       = Constants::is_true( 'JETPACK_BETA_BLOCKS' ) ? '-beta' : '';
554
		$blocks_dir = self::get_blocks_directory();
555
556
		$editor_script = plugins_url( "{$blocks_dir}editor{$beta}.js", JETPACK__PLUGIN_FILE );
557
		$editor_style  = plugins_url( "{$blocks_dir}editor{$beta}{$rtl}.css", JETPACK__PLUGIN_FILE );
558
559
		$editor_deps_path = JETPACK__PLUGIN_DIR . $blocks_dir . "editor{$beta}.deps.json";
560
		$editor_deps      = file_exists( $editor_deps_path )
561
			// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
562
			? json_decode( file_get_contents( $editor_deps_path ) )
563
			: array();
564
		$editor_deps[] = 'wp-polyfill';
565
566
		$version = Jetpack::is_development_version() && file_exists( JETPACK__PLUGIN_DIR . $blocks_dir . 'editor.js' )
567
			? filemtime( JETPACK__PLUGIN_DIR . $blocks_dir . 'editor.js' )
568
			: JETPACK__VERSION;
569
570
		if ( method_exists( 'Jetpack', 'build_raw_urls' ) ) {
571
			$site_fragment = Jetpack::build_raw_urls( home_url() );
572
		} elseif ( class_exists( 'WPCOM_Masterbar' ) && method_exists( 'WPCOM_Masterbar', 'get_calypso_site_slug' ) ) {
573
			$site_fragment = WPCOM_Masterbar::get_calypso_site_slug( get_current_blog_id() );
574
		} else {
575
			$site_fragment = '';
576
		}
577
578
		wp_enqueue_script(
579
			'jetpack-blocks-editor',
580
			$editor_script,
581
			$editor_deps,
582
			$version,
583
			false
584
		);
585
586
		wp_localize_script(
587
			'jetpack-blocks-editor',
588
			'Jetpack_Block_Assets_Base_Url',
589
			plugins_url( $blocks_dir . '/', JETPACK__PLUGIN_FILE )
590
		);
591
592
		wp_localize_script(
593
			'jetpack-blocks-editor',
594
			'Jetpack_Editor_Initial_State',
595
			array(
596
				'available_blocks' => self::get_availability(),
597
				'jetpack'          => array( 'is_active' => Jetpack::is_active() ),
598
				'siteFragment'     => $site_fragment,
599
			)
600
		);
601
602
		wp_set_script_translations( 'jetpack-blocks-editor', 'jetpack', plugins_url( 'languages/json', JETPACK__PLUGIN_FILE ) );
603
604
		// Adding a filter late to allow every other filter to process the path, including the CDN.
605
		add_filter( 'pre_load_script_translations', array( __CLASS__, 'filter_pre_load_script_translations' ), 1000, 3 );
606
607
		wp_enqueue_style( 'jetpack-blocks-editor', $editor_style, array(), $version );
608
	}
609
610
	/**
611
	 * A workaround for setting i18n data for WordPress client-side i18n mechanism.
612
	 * We are not yet using dotorg language packs for the editor file, so this short-circuits
613
	 * the translation loading and feeds our JSON data directly into the translation getter.
614
	 *
615
	 * @param NULL   $null     not used.
616
	 * @param String $file     the file path that is being loaded, ignored.
617
	 * @param String $handle   the script handle.
618
	 * @return NULL|String the translation data only if we're working with our handle.
619
	 */
620
	public static function filter_pre_load_script_translations( $null, $file, $handle ) {
621
		if ( 'jetpack-blocks-editor' !== $handle ) {
622
			return null;
623
		}
624
625
		return Jetpack::get_i18n_data_json();
626
	}
627
628
	/**
629
	 * Some blocks do not depend on a specific module,
630
	 * and can consequently be loaded outside of the usual modules.
631
	 * We will look for such modules in the extensions/ directory.
632
	 *
633
	 * @since 7.1.0
634
	 */
635
	public static function load_independent_blocks() {
636
		if ( self::should_load() ) {
637
			/**
638
			 * Look for files that match our list of available Jetpack Gutenberg extensions (blocks and plugins).
639
			 * If available, load them.
640
			 */
641
			foreach ( self::$extensions as $extension ) {
642
				$extension_file_glob = glob( JETPACK__PLUGIN_DIR . 'extensions/*/' . $extension . '/' . $extension . '.php' );
643
				if ( ! empty( $extension_file_glob ) ) {
644
					include_once $extension_file_glob[0];
645
				}
646
			}
647
		}
648
	}
649
}
650