Completed
Push — instant-search-master ( 8be3b4...336413 )
by
unknown
06:37 queued 10s
created

get_extensions_preset_for_variation()   B

Complexity

Conditions 7
Paths 18

Size

Total Lines 38

Duplication

Lines 17
Ratio 44.74 %

Importance

Changes 0
Metric Value
cc 7
nc 18
nop 2
dl 17
loc 38
rs 8.3786
c 0
b 0
f 0
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
use Automattic\Jetpack\Status;
11
12
/**
13
 * Wrapper function to safely register a gutenberg block type
14
 *
15
 * @param string $slug Slug of the block.
16
 * @param array  $args Arguments that are passed into register_block_type.
17
 *
18
 * @see register_block_type
19
 *
20
 * @since 6.7.0
21
 *
22
 * @return WP_Block_Type|false The registered block type on success, or false on failure.
23
 */
24
function jetpack_register_block( $slug, $args = array() ) {
25
	if ( 0 !== strpos( $slug, 'jetpack/' ) && ! strpos( $slug, '/' ) ) {
26
		_doing_it_wrong( 'jetpack_register_block', 'Prefix the block with jetpack/ ', '7.1.0' );
27
		$slug = 'jetpack/' . $slug;
28
	}
29
30
	// Checking whether block is registered to ensure it isn't registered twice.
31
	if ( Jetpack_Gutenberg::is_registered( $slug ) ) {
32
		return false;
33
	}
34
35
	return register_block_type( $slug, $args );
36
}
37
38
/**
39
 * Helper function to register a Jetpack Gutenberg plugin
40
 *
41
 * @deprecated 7.1.0 Use Jetpack_Gutenberg::set_extension_available() instead
42
 *
43
 * @param string $slug Slug of the plugin.
44
 *
45
 * @since 6.9.0
46
 *
47
 * @return void
48
 */
49
function jetpack_register_plugin( $slug ) {
50
	_deprecated_function( __FUNCTION__, '7.1', 'Jetpack_Gutenberg::set_extension_available' );
51
52
	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...
53
}
54
55
/**
56
 * Set the reason why an extension (block or plugin) is unavailable
57
 *
58
 * @deprecated 7.1.0 Use Jetpack_Gutenberg::set_extension_unavailable() instead
59
 *
60
 * @param string $slug Slug of the block.
61
 * @param string $reason A string representation of why the extension is unavailable.
62
 *
63
 * @since 7.0.0
64
 *
65
 * @return void
66
 */
67
function jetpack_set_extension_unavailability_reason( $slug, $reason ) {
68
	_deprecated_function( __FUNCTION__, '7.1', 'Jetpack_Gutenberg::set_extension_unavailable' );
69
70
	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...
71
}
72
73
/**
74
 * General Gutenberg editor specific functionality
75
 */
76
class Jetpack_Gutenberg {
77
78
	/**
79
	 * Only these extensions can be registered. Used to control availability of beta blocks.
80
	 *
81
	 * @var array Extensions whitelist
82
	 */
83
	private static $extensions = array();
84
85
	/**
86
	 * Keeps track of the reasons why a given extension is unavailable.
87
	 *
88
	 * @var array Extensions availability information
89
	 */
90
	private static $availability = array();
91
92
	/**
93
	 * Prepend the 'jetpack/' prefix to a block name
94
	 *
95
	 * @param string $block_name The block name.
96
	 *
97
	 * @return string The prefixed block name.
98
	 */
99
	private static function prepend_block_prefix( $block_name ) {
100
		return 'jetpack/' . $block_name;
101
	}
102
103
	/**
104
	 * Remove the 'jetpack/' or jetpack-' prefix from an extension name
105
	 *
106
	 * @param string $extension_name The extension name.
107
	 *
108
	 * @return string The unprefixed extension name.
109
	 */
110
	private static function remove_extension_prefix( $extension_name ) {
111
		if ( wp_startswith( $extension_name, 'jetpack/' ) || wp_startswith( $extension_name, 'jetpack-' ) ) {
112
			return substr( $extension_name, strlen( 'jetpack/' ) );
113
		}
114
		return $extension_name;
115
	}
116
117
	/**
118
	 * Whether two arrays share at least one item
119
	 *
120
	 * @param array $a An array.
121
	 * @param array $b Another array.
122
	 *
123
	 * @return boolean True if $a and $b share at least one item
124
	 */
125
	protected static function share_items( $a, $b ) {
126
		return count( array_intersect( $a, $b ) ) > 0;
127
	}
128
129
	/**
130
	 * Register a block
131
	 *
132
	 * @deprecated 7.1.0 Use jetpack_register_block() instead
133
	 *
134
	 * @param string $slug Slug of the block.
135
	 * @param array  $args Arguments that are passed into register_block_type().
136
	 */
137
	public static function register_block( $slug, $args ) {
138
		_deprecated_function( __METHOD__, '7.1', 'jetpack_register_block' );
139
140
		jetpack_register_block( 'jetpack/' . $slug, $args );
141
	}
142
143
	/**
144
	 * Register a plugin
145
	 *
146
	 * @deprecated 7.1.0 Use Jetpack_Gutenberg::set_extension_available() instead
147
	 *
148
	 * @param string $slug Slug of the plugin.
149
	 */
150
	public static function register_plugin( $slug ) {
151
		_deprecated_function( __METHOD__, '7.1', 'Jetpack_Gutenberg::set_extension_available' );
152
153
		self::set_extension_available( $slug );
154
	}
155
156
	/**
157
	 * Register a block
158
	 *
159
	 * @deprecated 7.0.0 Use jetpack_register_block() instead
160
	 *
161
	 * @param string $slug Slug of the block.
162
	 * @param array  $args Arguments that are passed into the register_block_type.
163
	 * @param array  $availability array containing if a block is available and the reason when it is not.
164
	 */
165
	public static function register( $slug, $args, $availability ) {
166
		_deprecated_function( __METHOD__, '7.0', 'jetpack_register_block' );
167
168
		if ( isset( $availability['available'] ) && ! $availability['available'] ) {
169
			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...
170
		} else {
171
			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...
172
		}
173
	}
174
175
	/**
176
	 * Set a (non-block) extension as available
177
	 *
178
	 * @param string $slug Slug of the extension.
179
	 */
180
	public static function set_extension_available( $slug ) {
181
		self::$availability[ self::remove_extension_prefix( $slug ) ] = true;
182
	}
183
184
	/**
185
	 * Set the reason why an extension (block or plugin) is unavailable
186
	 *
187
	 * @param string $slug Slug of the extension.
188
	 * @param string $reason A string representation of why the extension is unavailable.
189
	 * @param array  $details A free-form array containing more information on why the extension is unavailable.
190
	 */
191
	public static function set_extension_unavailable( $slug, $reason, $details = array() ) {
192
		if (
193
			// Extensions that require a plan may be eligible for upgrades.
194
			'missing_plan' === $reason
195
			&& (
196
				/**
197
				 * Filter 'jetpack_block_editor_enable_upgrade_nudge' with `true` to enable or `false`
198
				 * to disable paid feature upgrade nudges in the block editor.
199
				 *
200
				 * When this is changed to default to `true`, you should also update `modules/memberships/class-jetpack-memberships.php`
201
				 * See https://github.com/Automattic/jetpack/pull/13394#pullrequestreview-293063378
202
				 *
203
				 * @since 7.7.0
204
				 *
205
				 * @param boolean
206
				 */
207
				! apply_filters( 'jetpack_block_editor_enable_upgrade_nudge', false )
208
				/** This filter is documented in _inc/lib/admin-pages/class.jetpack-react-page.php */
209
				|| ! apply_filters( 'jetpack_show_promotions', true )
210
			)
211
		) {
212
			// The block editor may apply an upgrade nudge if `missing_plan` is the reason.
213
			// Add a descriptive suffix to disable behavior but provide informative reason.
214
			$reason .= '__nudge_disabled';
215
		}
216
217
		self::$availability[ self::remove_extension_prefix( $slug ) ] = array(
218
			'reason'  => $reason,
219
			'details' => $details,
220
		);
221
	}
222
223
	/**
224
	 * Set the reason why an extension (block or plugin) is unavailable
225
	 *
226
	 * @deprecated 7.1.0 Use set_extension_unavailable() instead
227
	 *
228
	 * @param string $slug Slug of the extension.
229
	 * @param string $reason A string representation of why the extension is unavailable.
230
	 */
231
	public static function set_extension_unavailability_reason( $slug, $reason ) {
232
		_deprecated_function( __METHOD__, '7.1', 'Jetpack_Gutenberg::set_extension_unavailable' );
233
234
		self::set_extension_unavailable( $slug, $reason );
235
	}
236
237
	/**
238
	 * Set up a whitelist of allowed block editor extensions
239
	 *
240
	 * @return void
241
	 */
242
	public static function init() {
243
		if ( ! self::should_load() ) {
244
			return;
245
		}
246
247
		/**
248
		 * Alternative to `JETPACK_BETA_BLOCKS`, set to `true` to load Beta Blocks.
249
		 *
250
		 * @since 6.9.0
251
		 *
252
		 * @param boolean
253
		 */
254
		if ( apply_filters( 'jetpack_load_beta_blocks', false ) ) {
255
			Constants::set_constant( 'JETPACK_BETA_BLOCKS', true );
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
256
		}
257
258
		/**
259
		 * Filter the whitelist of block editor extensions that are available through Jetpack.
260
		 *
261
		 * @since 7.0.0
262
		 *
263
		 * @param array
264
		 */
265
		self::$extensions = apply_filters( 'jetpack_set_available_extensions', self::get_available_extensions() );
266
267
		/**
268
		 * Filter the whitelist of block editor plugins that are available through Jetpack.
269
		 *
270
		 * @deprecated 7.0.0 Use jetpack_set_available_extensions instead
271
		 *
272
		 * @since 6.8.0
273
		 *
274
		 * @param array
275
		 */
276
		self::$extensions = apply_filters( 'jetpack_set_available_blocks', self::$extensions );
277
278
		/**
279
		 * Filter the whitelist of block editor plugins that are available through Jetpack.
280
		 *
281
		 * @deprecated 7.0.0 Use jetpack_set_available_extensions instead
282
		 *
283
		 * @since 6.9.0
284
		 *
285
		 * @param array
286
		 */
287
		self::$extensions = apply_filters( 'jetpack_set_available_plugins', self::$extensions );
288
	}
289
290
	/**
291
	 * Resets the class to its original state
292
	 *
293
	 * Used in unit tests
294
	 *
295
	 * @return void
296
	 */
297
	public static function reset() {
298
		self::$extensions   = array();
299
		self::$availability = array();
300
	}
301
302
	/**
303
	 * Return the Gutenberg extensions (blocks and plugins) directory
304
	 *
305
	 * @return string The Gutenberg extensions directory
306
	 */
307
	public static function get_blocks_directory() {
308
		/**
309
		 * Filter to select Gutenberg blocks directory
310
		 *
311
		 * @since 6.9.0
312
		 *
313
		 * @param string default: '_inc/blocks/'
314
		 */
315
		return apply_filters( 'jetpack_blocks_directory', '_inc/blocks/' );
316
	}
317
318
	/**
319
	 * Checks for a given .json file in the blocks folder.
320
	 *
321
	 * @param string $preset The name of the .json file to look for.
322
	 *
323
	 * @return bool True if the file is found.
324
	 */
325
	public static function preset_exists( $preset ) {
326
		return file_exists( JETPACK__PLUGIN_DIR . self::get_blocks_directory() . $preset . '.json' );
327
	}
328
329
	/**
330
	 * Decodes JSON loaded from a preset file in the blocks folder
331
	 *
332
	 * @param string $preset The name of the .json file to load.
333
	 *
334
	 * @return mixed Returns an object if the file is present, or false if a valid .json file is not present.
335
	 */
336
	public static function get_preset( $preset ) {
337
		return json_decode(
338
			// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
339
			file_get_contents( JETPACK__PLUGIN_DIR . self::get_blocks_directory() . $preset . '.json' )
340
		);
341
	}
342
343
	/**
344
	 * Returns a whitelist of Jetpack Gutenberg extensions (blocks and plugins), based on index.json
345
	 *
346
	 * @return array A list of blocks: eg [ 'publicize', 'markdown' ]
347
	 */
348
	public static function get_jetpack_gutenberg_extensions_whitelist() {
349
		$preset_extensions_manifest = self::preset_exists( 'index' )
350
			? self::get_preset( 'index' )
351
			: (object) array();
352
		$blocks_variation           = self::blocks_variation();
353
354
		return self::get_extensions_preset_for_variation( $preset_extensions_manifest, $blocks_variation );
355
	}
356
357
	/**
358
	 * Returns a diff from a combined list of whitelisted extensions and extensions determined to be excluded
359
	 *
360
	 * @param  array $whitelisted_extensions An array of whitelisted extensions.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $whitelisted_extensions not be array|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
361
	 *
362
	 * @return array A list of blocks: eg array( 'publicize', 'markdown' )
363
	 */
364
	public static function get_available_extensions( $whitelisted_extensions = null ) {
365
		$exclusions             = get_option( 'jetpack_excluded_extensions', array() );
366
		$whitelisted_extensions = is_null( $whitelisted_extensions ) ? self::get_jetpack_gutenberg_extensions_whitelist() : $whitelisted_extensions;
367
368
		return array_diff( $whitelisted_extensions, $exclusions );
369
	}
370
371
	/**
372
	 * Get availability of each block / plugin.
373
	 *
374
	 * @return array A list of block and plugins and their availablity status
375
	 */
376
	public static function get_availability() {
377
		/**
378
		 * Fires before Gutenberg extensions availability is computed.
379
		 *
380
		 * In the function call you supply, use `jetpack_register_block()` to set a block as available.
381
		 * Alternatively, use `Jetpack_Gutenberg::set_extension_available()` (for a non-block plugin), and
382
		 * `Jetpack_Gutenberg::set_extension_unavailable()` (if the block or plugin should not be registered
383
		 * but marked as unavailable).
384
		 *
385
		 * @since 7.0.0
386
		 */
387
		do_action( 'jetpack_register_gutenberg_extensions' );
388
389
		$available_extensions = array();
390
391
		foreach ( self::$extensions as $extension ) {
392
			$is_available = self::is_registered( 'jetpack/' . $extension ) ||
393
			( isset( self::$availability[ $extension ] ) && true === self::$availability[ $extension ] );
394
395
			$available_extensions[ $extension ] = array(
396
				'available' => $is_available,
397
			);
398
399
			if ( ! $is_available ) {
400
				$reason  = isset( self::$availability[ $extension ] ) ? self::$availability[ $extension ]['reason'] : 'missing_module';
401
				$details = isset( self::$availability[ $extension ] ) ? self::$availability[ $extension ]['details'] : array();
402
				$available_extensions[ $extension ]['unavailable_reason'] = $reason;
403
				$available_extensions[ $extension ]['details']            = $details;
404
			}
405
		}
406
407
		return $available_extensions;
408
	}
409
410
	/**
411
	 * Check if an extension/block is already registered
412
	 *
413
	 * @since 7.2
414
	 *
415
	 * @param string $slug Name of extension/block to check.
416
	 *
417
	 * @return bool
418
	 */
419
	public static function is_registered( $slug ) {
420
		return WP_Block_Type_Registry::get_instance()->is_registered( $slug );
421
	}
422
423
	/**
424
	 * Check if Gutenberg editor is available
425
	 *
426
	 * @since 6.7.0
427
	 *
428
	 * @return bool
429
	 */
430
	public static function is_gutenberg_available() {
431
		return true;
432
	}
433
434
	/**
435
	 * Check whether conditions indicate Gutenberg Extensions (blocks and plugins) should be loaded
436
	 *
437
	 * Loading blocks and plugins is enabled by default and may be disabled via filter:
438
	 *   add_filter( 'jetpack_gutenberg', '__return_false' );
439
	 *
440
	 * @since 6.9.0
441
	 *
442
	 * @return bool
443
	 */
444
	public static function should_load() {
445
		if ( ! Jetpack::is_active() && ! ( new Status() )->is_development_mode() ) {
446
			return false;
447
		}
448
449
		/**
450
		 * Filter to disable Gutenberg blocks
451
		 *
452
		 * @since 6.5.0
453
		 *
454
		 * @param bool true Whether to load Gutenberg blocks
455
		 */
456
		return (bool) apply_filters( 'jetpack_gutenberg', true );
457
	}
458
459
	/**
460
	 * Only enqueue block assets when needed.
461
	 *
462
	 * @param string $type Slug of the block.
463
	 * @param array  $script_dependencies Script dependencies. Will be merged with automatically
464
	 *                                    detected script dependencies from the webpack build.
465
	 *
466
	 * @return void
467
	 */
468
	public static function load_assets_as_required( $type, $script_dependencies = array() ) {
469
		if ( is_admin() ) {
470
			// A block's view assets will not be required in wp-admin.
471
			return;
472
		}
473
474
		$type = sanitize_title_with_dashes( $type );
475
		self::load_styles_as_required( $type );
476
		self::load_scripts_as_required( $type, $script_dependencies );
477
	}
478
479
	/**
480
	 * Only enqueue block sytles when needed.
481
	 *
482
	 * @param string $type Slug of the block.
483
	 *
484
	 * @since 7.2.0
485
	 *
486
	 * @return void
487
	 */
488
	public static function load_styles_as_required( $type ) {
489
		if ( is_admin() ) {
490
			// A block's view assets will not be required in wp-admin.
491
			return;
492
		}
493
494
		// Enqueue styles.
495
		$style_relative_path = self::get_blocks_directory() . $type . '/view' . ( is_rtl() ? '.rtl' : '' ) . '.css';
496 View Code Duplication
		if ( self::block_has_asset( $style_relative_path ) ) {
497
			$style_version = self::get_asset_version( $style_relative_path );
498
			$view_style    = plugins_url( $style_relative_path, JETPACK__PLUGIN_FILE );
499
			wp_enqueue_style( 'jetpack-block-' . $type, $view_style, array(), $style_version );
500
		}
501
502
	}
503
504
	/**
505
	 * Only enqueue block scripts when needed.
506
	 *
507
	 * @param string $type Slug of the block.
508
	 * @param array  $dependencies Script dependencies. Will be merged with automatically
509
	 *                             detected script dependencies from the webpack build.
510
	 *
511
	 * @since 7.2.0
512
	 *
513
	 * @return void
514
	 */
515
	public static function load_scripts_as_required( $type, $dependencies = array() ) {
516
		if ( is_admin() ) {
517
			// A block's view assets will not be required in wp-admin.
518
			return;
519
		}
520
521
		// Enqueue script.
522
		$script_relative_path = self::get_blocks_directory() . $type . '/view.js';
523
		$script_deps_path     = JETPACK__PLUGIN_DIR . self::get_blocks_directory() . $type . '/view.asset.php';
524
		$script_dependencies  = array( 'wp-polyfill' );
525
		if ( file_exists( $script_deps_path ) ) {
526
			$asset_manifest      = include $script_deps_path;
527
			$script_dependencies = $asset_manifest['dependencies'];
528
		}
529
530
		if ( ( ! class_exists( 'Jetpack_AMP_Support' ) || ! Jetpack_AMP_Support::is_amp_request() ) && self::block_has_asset( $script_relative_path ) ) {
531
			$script_version = self::get_asset_version( $script_relative_path );
532
			$view_script    = plugins_url( $script_relative_path, JETPACK__PLUGIN_FILE );
533
			wp_enqueue_script( 'jetpack-block-' . $type, $view_script, $script_dependencies, $script_version, false );
534
		}
535
536
		wp_localize_script(
537
			'jetpack-block-' . $type,
538
			'Jetpack_Block_Assets_Base_Url',
539
			plugins_url( self::get_blocks_directory(), JETPACK__PLUGIN_FILE )
540
		);
541
	}
542
543
	/**
544
	 * Check if an asset exists for a block.
545
	 *
546
	 * @param string $file Path of the file we are looking for.
547
	 *
548
	 * @return bool $block_has_asset Does the file exist.
549
	 */
550
	public static function block_has_asset( $file ) {
551
		return file_exists( JETPACK__PLUGIN_DIR . $file );
552
	}
553
554
	/**
555
	 * Get the version number to use when loading the file. Allows us to bypass cache when developing.
556
	 *
557
	 * @param string $file Path of the file we are looking for.
558
	 *
559
	 * @return string $script_version Version number.
560
	 */
561
	public static function get_asset_version( $file ) {
562
		return Jetpack::is_development_version() && self::block_has_asset( $file )
563
			? filemtime( JETPACK__PLUGIN_DIR . $file )
564
			: JETPACK__VERSION;
565
	}
566
567
	/**
568
	 * Load Gutenberg editor assets
569
	 *
570
	 * @since 6.7.0
571
	 *
572
	 * @return void
573
	 */
574
	public static function enqueue_block_editor_assets() {
575
		if ( ! self::should_load() ) {
576
			return;
577
		}
578
579
		// Required for Analytics. See _inc/lib/admin-pages/class.jetpack-admin-page.php.
580
		if ( ! ( new Status() )->is_development_mode() && Jetpack::is_active() ) {
581
			wp_enqueue_script( 'jp-tracks', '//stats.wp.com/w.js', array(), gmdate( 'YW' ), true );
582
		}
583
584
		$rtl              = is_rtl() ? '.rtl' : '';
585
		$blocks_dir       = self::get_blocks_directory();
586
		$blocks_variation = self::blocks_variation();
587
588
		if ( 'production' !== $blocks_variation ) {
589
			$blocks_env = '-' . esc_attr( $blocks_variation );
590
		} else {
591
			$blocks_env = '';
592
		}
593
594
		$editor_script = plugins_url( "{$blocks_dir}editor{$blocks_env}.js", JETPACK__PLUGIN_FILE );
595
		$editor_style  = plugins_url( "{$blocks_dir}editor{$blocks_env}{$rtl}.css", JETPACK__PLUGIN_FILE );
596
597
		$editor_deps_path = JETPACK__PLUGIN_DIR . $blocks_dir . "editor{$blocks_env}.asset.php";
598
		$editor_deps      = array( 'wp-polyfill' );
599
		if ( file_exists( $editor_deps_path ) ) {
600
			$asset_manifest = include $editor_deps_path;
601
			$editor_deps    = $asset_manifest['dependencies'];
602
		}
603
604
		$version = Jetpack::is_development_version() && file_exists( JETPACK__PLUGIN_DIR . $blocks_dir . 'editor.js' )
605
			? filemtime( JETPACK__PLUGIN_DIR . $blocks_dir . 'editor.js' )
606
			: JETPACK__VERSION;
607
608
		if ( method_exists( 'Jetpack', 'build_raw_urls' ) ) {
609
			$site_fragment = Jetpack::build_raw_urls( home_url() );
610
		} elseif ( class_exists( 'WPCOM_Masterbar' ) && method_exists( 'WPCOM_Masterbar', 'get_calypso_site_slug' ) ) {
611
			$site_fragment = WPCOM_Masterbar::get_calypso_site_slug( get_current_blog_id() );
612
		} else {
613
			$site_fragment = '';
614
		}
615
616
		wp_enqueue_script(
617
			'jetpack-blocks-editor',
618
			$editor_script,
619
			$editor_deps,
620
			$version,
621
			false
622
		);
623
624
		wp_localize_script(
625
			'jetpack-blocks-editor',
626
			'Jetpack_Block_Assets_Base_Url',
627
			plugins_url( $blocks_dir . '/', JETPACK__PLUGIN_FILE )
628
		);
629
630
		if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
631
			$user      = wp_get_current_user();
632
			$user_data = array(
633
				'userid'   => $user->ID,
634
				'username' => $user->user_login,
635
			);
636
			$blog_id   = get_current_blog_id();
637
		} else {
638
			$user_data = Jetpack_Tracks_Client::get_connected_user_tracks_identity();
639
			$blog_id   = Jetpack_Options::get_option( 'id', 0 );
640
		}
641
642
		wp_localize_script(
643
			'jetpack-blocks-editor',
644
			'Jetpack_Editor_Initial_State',
645
			array(
646
				'available_blocks' => self::get_availability(),
647
				'jetpack'          => array( 'is_active' => Jetpack::is_active() ),
648
				'siteFragment'     => $site_fragment,
649
				'tracksUserData'   => $user_data,
650
				'wpcomBlogId'      => $blog_id,
651
			)
652
		);
653
654
		wp_set_script_translations( 'jetpack-blocks-editor', 'jetpack' );
655
656
		wp_enqueue_style( 'jetpack-blocks-editor', $editor_style, array(), $version );
657
	}
658
659
	/**
660
	 * Some blocks do not depend on a specific module,
661
	 * and can consequently be loaded outside of the usual modules.
662
	 * We will look for such modules in the extensions/ directory.
663
	 *
664
	 * @since 7.1.0
665
	 */
666
	public static function load_independent_blocks() {
667
		if ( self::should_load() ) {
668
			/**
669
			 * Look for files that match our list of available Jetpack Gutenberg extensions (blocks and plugins).
670
			 * If available, load them.
671
			 */
672
			foreach ( self::$extensions as $extension ) {
673
				$extension_file_glob = glob( JETPACK__PLUGIN_DIR . 'extensions/*/' . $extension . '/' . $extension . '.php' );
674
				if ( ! empty( $extension_file_glob ) ) {
675
					include_once $extension_file_glob[0];
676
				}
677
			}
678
		}
679
	}
680
681
	/**
682
	 * Get CSS classes for a block.
683
	 *
684
	 * @since 7.7.0
685
	 *
686
	 * @param string $slug  Block slug.
687
	 * @param array  $attr  Block attributes.
688
	 * @param array  $extra Potential extra classes you may want to provide.
689
	 *
690
	 * @return string $classes List of CSS classes for a block.
691
	 */
692
	public static function block_classes( $slug = '', $attr, $extra = array() ) {
693
		if ( empty( $slug ) ) {
694
			return '';
695
		}
696
697
		// Basic block name class.
698
		$classes = array(
699
			'wp-block-jetpack-' . $slug,
700
		);
701
702
		// Add alignment if provided.
703
		if (
704
			! empty( $attr['align'] )
705
			&& in_array( $attr['align'], array( 'left', 'center', 'right', 'wide', 'full' ), true )
706
		) {
707
			array_push( $classes, 'align' . $attr['align'] );
708
		}
709
710
		// Add custom classes if provided in the block editor.
711
		if ( ! empty( $attr['className'] ) ) {
712
			array_push( $classes, $attr['className'] );
713
		}
714
715
		// Add any extra classes.
716
		if ( is_array( $extra ) && ! empty( $extra ) ) {
717
			$classes = array_merge( $classes, $extra );
718
		}
719
720
		return implode( ' ', $classes );
721
	}
722
723
	/**
724
	 * Determine whether a site should use the default set of blocks, or a custom set.
725
	 * Possible variations are currently beta, experimental, and production.
726
	 *
727
	 * @since 8.1.0
728
	 *
729
	 * @return string $block_varation production|beta|experimental
730
	 */
731
	public static function blocks_variation() {
732
		// Default to production blocks.
733
		$block_varation = 'production';
734
735
		if ( Constants::is_true( 'JETPACK_BETA_BLOCKS' ) ) {
736
			$block_varation = 'beta';
737
		}
738
739
		/*
740
		 * Switch to experimental blocks if you use the JETPACK_EXPERIMENTAL_BLOCKS constant.
741
		 */
742
		if ( Constants::is_true( 'JETPACK_EXPERIMENTAL_BLOCKS' ) ) {
743
			$block_varation = 'experimental';
744
		}
745
746
		/**
747
		 * Allow customizing the variation of blocks in use on a site.
748
		 *
749
		 * @since 8.1.0
750
		 *
751
		 * @param string $block_variation Can be beta, experimental, and production. Defaults to production.
752
		 */
753
		return apply_filters( 'jetpack_blocks_variation', $block_varation );
754
	}
755
756
	/**
757
	 * Get a list of extensions available for the variation you chose.
758
	 *
759
	 * @since 8.1.0
760
	 *
761
	 * @param obj    $preset_extensions_manifest List of extensions available in Jetpack.
762
	 * @param string $blocks_variation           Subset of blocks. production|beta|experimental.
763
	 *
764
	 * @return array $preset_extensions Array of extensions for that variation
765
	 */
766
	public static function get_extensions_preset_for_variation( $preset_extensions_manifest, $blocks_variation ) {
767
		$preset_extensions = isset( $preset_extensions_manifest->{ $blocks_variation } )
768
				? (array) $preset_extensions_manifest->{ $blocks_variation }
769
				: array();
770
771
		/*
772
		 * Experimental and Beta blocks need the production blocks as well.
773
		 */
774 View Code Duplication
		if (
775
			'experimental' === $blocks_variation
776
			|| 'beta' === $blocks_variation
777
		) {
778
			$production_extensions = isset( $preset_extensions_manifest->production )
779
				? (array) $preset_extensions_manifest->production
780
				: array();
781
782
			$preset_extensions = array_unique( array_merge( $preset_extensions, $production_extensions ) );
783
		}
784
785
		/*
786
		 * Beta blocks need the experimental blocks as well.
787
		 *
788
		 * If you've chosen to see Beta blocks,
789
		 * we want to make all blocks available to you:
790
		 * - Production
791
		 * - Experimental
792
		 * - Beta
793
		 */
794 View Code Duplication
		if ( 'beta' === $blocks_variation ) {
795
			$production_extensions = isset( $preset_extensions_manifest->experimental )
796
				? (array) $preset_extensions_manifest->experimental
797
				: array();
798
799
			$preset_extensions = array_unique( array_merge( $preset_extensions, $production_extensions ) );
800
		}
801
802
		return $preset_extensions;
803
	}
804
}
805