PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | jetpack_vendor/automattic/jetpack-blocks/src/class-blocks.php +294 -5 12.2.3 → 16.3-beta View file →
@@ -10,8 +10,9 @@
10 10 */
11 11
12 12 namespace Automattic\Jetpack;
13 13
14 +use Automattic\Jetpack\Constants as Jetpack_Constants;
14 15 use Jetpack_Gutenberg;
15 16
16 17 /**
17 18 * Register and manage blocks within a plugin. Used to manage block registration, enqueues, and more.
@@ -26,9 +27,9 @@
26 27 * @see Automattic\Jetpack\Blocks::is_gutenberg_version_available
27 28 *
28 29 * @since 1.1.0
29 30 *
30 - * @param string $slug Slug of the block.
31 + * @param string $slug Slug of the block or absolute path to the block source code directory.
31 32 * @param array $args {
32 33 * Arguments that are passed into register_block_type.
33 34 * See register_block_type for full list of arguments.
34 35 * Can also include 2 extra arguments not currently supported by register_block_type.
@@ -36,16 +37,27 @@
36 37 * @type array $version_requirements Array containing required Gutenberg version and, if known, the WordPress version that was released with this minimum version.
37 38 * @type bool $plan_check Should we check for a specific plan before registering the block.
38 39 * }
39 40 *
40 - * @return WP_Block_Type|false The registered block type on success, or false on failure.
41 + * @return \WP_Block_Type|false The registered block type on success, or false on failure.
41 42 */
42 43 public static function jetpack_register_block( $slug, $args = array() ) {
43 - if ( 0 !== strpos( $slug, 'jetpack/' ) && ! strpos( $slug, '/' ) ) {
44 + // Slug doesn't start with `jetpack/`, isn't an absolute path, or doesn't contain a slash
45 + // (synonym of a namespace) at all.
46 + if ( ! str_starts_with( $slug, 'jetpack/' ) && ! path_is_absolute( $slug ) && ! strpos( $slug, '/' ) ) {
44 47 _doing_it_wrong( 'jetpack_register_block', 'Prefix the block with jetpack/ ', 'Jetpack 9.0.0' );
45 48 $slug = 'jetpack/' . $slug;
46 49 }
47 50
51 + $block_type = $slug;
52 +
53 + // If a path is passed, make sure to get the block.json file from the build directory and get
54 + // the block name from that file.
55 + if ( path_is_absolute( $slug ) ) {
56 + $block_type = self::get_path_to_block_metadata( $slug );
57 + $slug = self::get_block_name_from_path_convention( $slug );
58 + }
59 +
48 60 if (
49 61 isset( $args['version_requirements'] )
50 62 && ! self::is_gutenberg_version_available( $args['version_requirements'], $slug )
51 63 ) {
@@ -62,13 +74,29 @@
62 74 // This is only useful in Jetpack.
63 75 if ( ! self::is_standalone_block() ) {
64 76 // If the block is dynamic, and a Jetpack block, wrap the render_callback to check availability.
65 77 if ( ! empty( $args['plan_check'] ) ) {
78 + $existing_attributes = array();
79 + $gated_blocks = array(
80 + 'jetpack/calendly',
81 + 'jetpack/donations',
82 + 'jetpack/payment-buttons',
83 + 'jetpack/paypal-payment-buttons',
84 + );
85 + if ( in_array( $slug, $gated_blocks, true ) &&
86 + is_string( $block_type ) &&
87 + file_exists( $block_type )
88 + ) {
89 + $metadata = self::get_block_metadata( $block_type );
90 + $existing_attributes = $metadata['attributes'] ?? array();
91 + }
92 +
66 93 // Set up attributes.
67 94 if ( ! isset( $args['attributes'] ) ) {
68 95 $args['attributes'] = array();
69 96 }
70 97 $args['attributes'] = array_merge(
98 + $existing_attributes,
71 99 $args['attributes'],
72 100 array(
73 101 // Indicates that this block should display an upgrade nudge on the frontend when applicable.
74 102 'shouldDisplayFrontendBanner' => array(
@@ -96,14 +124,150 @@
96 124 // editor style dependency when copying styles to the editor iframe.
97 125 if ( ! isset( $args['editor_style'] ) ) {
98 126 $args['editor_style'] = 'jetpack-blocks-editor';
99 127 }
128 +
129 + // Keep track of the JS loading strategy for any block that specifies it.
130 + if ( isset( $args['js_loading_strategy'] ) ) {
131 + Jetpack_Gutenberg::set_block_js_loading_strategy( $feature_name, $args['js_loading_strategy'] );
132 + }
100 133 }
101 134
102 - return register_block_type( $slug, $args );
135 + return register_block_type( $block_type, $args );
103 136 }
104 137
105 138 /**
139 + * Get the block metadata. Accepts a block.json file's path (or its folder's) or its content, in
140 + * which case it becomes an identity function.
141 + *
142 + * It's used by other helpers in this class so that they can accept various types as argument.
143 + *
144 + * @param string|array $arg Path to block.json or its parent folder, or its content as an array.
145 + *
146 + * @return array The block metadata.
147 + */
148 + private static function get_block_metadata( $arg ) {
149 + $metadata = is_array( $arg ) ? $arg : null;
150 +
151 + if ( ! isset( $metadata ) ) {
152 + $path = is_string( $arg ) ? $arg : null;
153 +
154 + if ( isset( $path ) && ! empty( $path ) ) {
155 + $metadata = self::get_block_metadata_from_file( self::get_path_to_block_metadata( $path ) );
156 + }
157 + }
158 +
159 + return $metadata ?? array();
160 + }
161 +
162 + /**
163 + * Read block metadata from a block.json file.
164 + *
165 + * @param string $filename The path to the block.json file or its directory.
166 + *
167 + * @return array The block metadata.
168 + */
169 + public static function get_block_metadata_from_file( $filename ) {
170 + $metadata = array();
171 + $needle = '/block.json';
172 + $filename = $needle === substr( $filename, -strlen( $needle ) ) ? $filename : $filename . $needle;
173 +
174 + if ( file_exists( $filename ) ) {
175 + try {
176 + $metadata = wp_json_file_decode( $filename, array( 'associative' => true ) );
177 + } catch ( \Exception $e ) {
178 + $metadata = array();
179 + }
180 + }
181 +
182 + return $metadata;
183 + }
184 +
185 + /**
186 + * Get the block name (includes the `jetpack` prefix).
187 + *
188 + * @param string|array $arg Path to block.json or its parent folder, or its content as an array.
189 + *
190 + * @return string The block name.
191 + */
192 + public static function get_block_name( $arg ) {
193 + $metadata = self::get_block_metadata( $arg );
194 +
195 + return self::get_block_name_from_metadata( $metadata );
196 + }
197 +
198 + /**
199 + * Get the block name from the path convention.
200 + * For example, path "./extensions/blocks/pinterest" is assumed to define
201 + * a block named "jetpack/pinterest" without checking any files.
202 + *
203 + * Any exceptions should be added to the $breaks_convention array.
204 + * For example, blocks/premium-content defines "premium-content\/container", not "jetpack/premium-content".
205 + * These paths will use the code that checks the disk for the block name.
206 + *
207 + * The unit test test_get_block_name_from_path_convention_matches_get_block_name() verifies that
208 + * all names are correctly guessed.
209 + *
210 + * Run with `./vendor/bin/phpunit --filter WP_Test_Jetpack_Gutenberg`.
211 + *
212 + * @param string $path The path to extract the block name from.
213 + *
214 + * @return string The block name with 'jetpack/' prefix.
215 + */
216 + public static function get_block_name_from_path_convention( $path ) {
217 + $path_parts = explode( '/', $path );
218 + if ( count( $path_parts ) <= 0 ) {
219 + $block_type = self::get_path_to_block_metadata( $path );
220 + return self::get_block_name( $block_type );
221 + }
222 +
223 + $last_part = $path_parts[ count( $path_parts ) - 1 ];
224 + $breaks_convention = array( 'premium-content' );
225 +
226 + if ( in_array( $last_part, $breaks_convention, true ) ) {
227 + $block_type = self::get_path_to_block_metadata( $path );
228 + return self::get_block_name( $block_type );
229 + }
230 +
231 + return 'jetpack/' . $last_part;
232 + }
233 +
234 + /**
235 + * Get the block name from the its metadata.
236 + *
237 + * @param array $metadata The block metadata.
238 + *
239 + * @return string The block name.
240 + */
241 + public static function get_block_name_from_metadata( $metadata ) {
242 + return ! isset( $metadata['name'] ) || empty( $metadata['name'] ) ? '' : $metadata['name'];
243 + }
244 +
245 + /**
246 + * Get the block feature name (i.e. the name without the `jetpack` prefix).
247 + *
248 + * @param string|array $arg Path to block.json or its parent folder, or its content as an array.
249 + *
250 + * @return string The block feature name.
251 + */
252 + public static function get_block_feature( $arg ) {
253 + $metadata = self::get_block_metadata( $arg );
254 +
255 + return self::get_block_feature_from_metadata( $metadata );
256 + }
257 +
258 + /**
259 + * Get the block feature name (i.e. the name without the `jetpack` prefix) from its metadata.
260 + *
261 + * @param array $metadata The block metadata.
262 + *
263 + * @return string The block feature name.
264 + */
265 + public static function get_block_feature_from_metadata( $metadata ) {
266 + return str_replace( 'jetpack/', '', self::get_block_name_from_metadata( $metadata ) );
267 + }
268 +
269 + /**
106 270 * Check if an extension/block is already registered
107 271 *
108 272 * @since 1.1.0
109 273 *
@@ -124,9 +288,9 @@
124 288 *
125 289 * @return string The unprefixed extension name.
126 290 */
127 291 public static function remove_extension_prefix( $extension_name ) {
128 - if ( 0 === strpos( $extension_name, 'jetpack/' ) || 0 === strpos( $extension_name, 'jetpack-' ) ) {
292 + if ( str_starts_with( $extension_name, 'jetpack/' ) || str_starts_with( $extension_name, 'jetpack-' ) ) {
129 293 return substr( $extension_name, strlen( 'jetpack/' ) );
130 294 }
131 295 return $extension_name;
132 296 }
@@ -174,8 +338,9 @@
174 338 if (
175 339 ! $version_available
176 340 && ! self::is_standalone_block() // This is only useful in Jetpack.
177 341 ) {
342 + $slug = Jetpack_Gutenberg::remove_extension_prefix( $slug );
178 343 Jetpack_Gutenberg::set_extension_unavailable(
179 344 $slug,
180 345 'incorrect_gutenberg_version',
181 346 array(
@@ -287,6 +452,130 @@
287 452 *
288 453 * @param boolean $is_standalone_block Is the block running standalone versus as part of the Jetpack plugin.
289 454 */
290 455 return apply_filters( 'jetpack_is_standalone_block', $is_standalone_block );
456 + }
457 +
458 + /**
459 + * Returns the path to the directory containing the block.json metadata file of a block, given its
460 + * source code directory and, optionally, the directory that holds the blocks built files of
461 + * the package. If the directory doesn't exist, falls back to the source directory.
462 + *
463 + * @since 1.6.0
464 + *
465 + * @param string $block_src_dir The path to the folder containing the block source code.
466 + * Typically this is done by passing __DIR__ as the argument.
467 + * @param string $package_dist_dir Optional. A full path to the directory containing the blocks
468 + * built files of the package. Default empty.
469 + *
470 + * @return string The path to the directory.
471 + */
472 + public static function get_path_to_block_metadata( $block_src_dir, $package_dist_dir = '' ) {
473 + $dir = basename( $block_src_dir );
474 + $dist_path = $package_dist_dir;
475 +
476 + if ( empty( $dist_path ) ) {
477 + $plugin_file = Jetpack_Constants::get_constant( 'JETPACK__PLUGIN_FILE' );
478 + // Guard against strange situations where JETPACK__PLUGIN_FILE is undefined.
479 + if ( empty( $plugin_file ) ) {
480 + return $block_src_dir;
481 + }
482 +
483 + $dist_path = dirname( $plugin_file ) . '/_inc/blocks';
484 + }
485 +
486 + $result = realpath( "$dist_path/$dir" );
487 +
488 + return false === $result ? $block_src_dir : $result;
489 + }
490 +
491 + /**
492 + * Determine whether a site should use the default set of blocks, or a custom set.
493 + * Possible variations are currently beta, experimental, and production.
494 + *
495 + * @since 3.1.0
496 + *
497 + * @return string $block_variation production|beta|experimental
498 + */
499 + public static function get_variation() {
500 + // Default to production blocks.
501 + $block_variation = 'production';
502 +
503 + /*
504 + * Prefer to use this JETPACK_BLOCKS_VARIATION constant
505 + * or the jetpack_blocks_variation filter
506 + * to set the block variation in your code.
507 + */
508 + $default = Constants::get_constant( 'JETPACK_BLOCKS_VARIATION' );
509 + if ( ! empty( $default ) && in_array( $default, array( 'beta', 'experimental', 'production' ), true ) ) {
510 + $block_variation = $default;
511 + }
512 +
513 + /**
514 + * Alternative to `JETPACK_BETA_BLOCKS`, set to `true` to load Beta Blocks.
515 + *
516 + * @since jetpack-6.9.0
517 + * @deprecated jetpack-11.8.0 Use jetpack_blocks_variation filter instead.
518 + *
519 + * @param boolean
520 + */
521 + $is_beta = apply_filters_deprecated(
522 + 'jetpack_load_beta_blocks',
523 + array( false ),
524 + 'jetpack-11.8.0',
525 + 'jetpack_blocks_variation'
526 + );
527 +
528 + /*
529 + * Switch to beta blocks if you use the JETPACK_BETA_BLOCKS constant
530 + * or the deprecated jetpack_load_beta_blocks filter.
531 + * This only applies when not using the newer JETPACK_BLOCKS_VARIATION constant.
532 + */
533 + if ( empty( $default )
534 + && (
535 + $is_beta
536 + || Constants::is_true( 'JETPACK_BETA_BLOCKS' )
537 + )
538 + ) {
539 + $block_variation = 'beta';
540 + }
541 +
542 + /**
543 + * Alternative to `JETPACK_EXPERIMENTAL_BLOCKS`, set to `true` to load Experimental Blocks.
544 + *
545 + * @since jetpack-6.9.0
546 + * @deprecated jetpack-11.8.0 Use jetpack_blocks_variation filter instead.
547 + *
548 + * @param boolean
549 + */
550 + $is_experimental = apply_filters_deprecated(
551 + 'jetpack_load_experimental_blocks',
552 + array( false ),
553 + 'jetpack-11.8.0',
554 + 'jetpack_blocks_variation'
555 + );
556 +
557 + /*
558 + * Switch to experimental blocks if you use the JETPACK_EXPERIMENTAL_BLOCKS constant
559 + * or the deprecated jetpack_load_experimental_blocks filter.
560 + * This only applies when not using the newer JETPACK_BLOCKS_VARIATION constant.
561 + */
562 + if ( empty( $default )
563 + && (
564 + $is_experimental
565 + || Constants::is_true( 'JETPACK_EXPERIMENTAL_BLOCKS' )
566 + )
567 + ) {
568 + $block_variation = 'experimental';
569 + }
570 +
571 + /**
572 + * Allow customizing the variation of blocks in use on a site.
573 + * Overwrites any previously set values, whether by constant or filter.
574 + *
575 + * @since jetpack-8.1.0
576 + *
577 + * @param string $block_variation Can be beta, experimental, and production. Defaults to production.
578 + */
579 + return apply_filters( 'jetpack_blocks_variation', $block_variation );
291 580 }
292 581 }