Completed
Push — fix/settings-access-offline-mo... ( b2c0f3...c44966 )
by Jeremy
35:02 queued 24:17
created

Blocks::is_fse_theme()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/** Blocks package.
3
 *
4
 * @since 9.0.0
5
 *
6
 * This package lifts elements from Jetpack's Jetpack_Gutenberg class.
7
 * It is now an standalone package reusable outside Jetpack.
8
 *
9
 * @package automattic/jetpack-blocks
10
 */
11
12
namespace Automattic\Jetpack;
13
14
use Jetpack_Gutenberg;
15
16
/**
17
 * Register and manage blocks within a plugin. Used to manage block registration, enqueues, and more.
18
 *
19
 * @since 9.0.0
20
 */
21
class Blocks {
22
	/**
23
	 * Wrapper function to safely register a Gutenberg block type
24
	 *
25
	 * @see register_block_type
26
	 * @see Automattic\Jetpack\Blocks::is_gutenberg_version_available
27
	 *
28
	 * @since 9.0.0
29
	 *
30
	 * @param string $slug Slug of the block.
31
	 * @param array  $args {
32
	 *     Arguments that are passed into register_block_type.
33
	 *     See register_block_type for full list of arguments.
34
	 *     Can also include 2 extra arguments not currently supported by register_block_type.
35
	 *
36
	 *     @type array $version_requirements Array containing required Gutenberg version and, if known, the WordPress version that was released with this minimum version.
37
	 *     @type bool  $plan_check           Should we check for a specific plan before registering the block.
38
	 * }
39
	 *
40
	 * @return WP_Block_Type|false The registered block type on success, or false on failure.
41
	 */
42
	public static function jetpack_register_block( $slug, $args = array() ) {
43
		if ( 0 !== strpos( $slug, 'jetpack/' ) && ! strpos( $slug, '/' ) ) {
44
			_doing_it_wrong( 'jetpack_register_block', 'Prefix the block with jetpack/ ', 'Jetpack 9.0.0' );
45
			$slug = 'jetpack/' . $slug;
46
		}
47
48
		if (
49
			isset( $args['version_requirements'] )
50
			&& ! self::is_gutenberg_version_available( $args['version_requirements'], $slug )
51
		) {
52
			return false;
53
		}
54
55
		// Checking whether block is registered to ensure it isn't registered twice.
56
		if ( self::is_registered( $slug ) ) {
57
			return false;
58
		}
59
60
		$feature_name = self::remove_extension_prefix( $slug );
61
62
		// This is only useful in Jetpack.
63
		if ( ! self::is_standalone_block() ) {
64
			// If the block is dynamic, and a Jetpack block, wrap the render_callback to check availability.
65
			if ( ! empty( $args['plan_check'] ) ) {
66
				// Set up attributes.
67
				if ( ! isset( $args['attributes'] ) ) {
68
					$args['attributes'] = array();
69
				}
70
				$args['attributes'] = array_merge(
71
					$args['attributes'],
72
					array(
73
						// Indicates that this block should display an upgrade nudge on the frontend when applicable.
74
						'shouldDisplayFrontendBanner' => array(
75
							'type'    => 'boolean',
76
							'default' => true,
77
						),
78
					)
79
				);
80
				if ( isset( $args['render_callback'] ) ) {
81
					$args['render_callback'] = Jetpack_Gutenberg::get_render_callback_with_availability_check( $feature_name, $args['render_callback'] );
82
				}
83
				$method_name = 'set_availability_for_plan';
84
			} else {
85
				$method_name = 'set_extension_available';
86
			}
87
88
			add_action(
89
				'jetpack_register_gutenberg_extensions',
90
				function () use ( $feature_name, $method_name ) {
91
					call_user_func( array( 'Jetpack_Gutenberg', $method_name ), $feature_name );
92
				}
93
			);
94
95
			// Ensure editor styles are registered so that the site editor knows about the
96
			// editor style dependency when copying styles to the editor iframe.
97
			if ( ! isset( $args['editor_style'] ) ) {
98
				$args['editor_style'] = 'jetpack-blocks-editor';
99
			}
100
		}
101
102
		return register_block_type( $slug, $args );
103
	}
104
105
	/**
106
	 * Check if an extension/block is already registered
107
	 *
108
	 * @since 9.0.0
109
	 *
110
	 * @param string $slug Name of extension/block to check.
111
	 *
112
	 * @return bool
113
	 */
114
	public static function is_registered( $slug ) {
115
		return \WP_Block_Type_Registry::get_instance()->is_registered( $slug );
116
	}
117
118
	/**
119
	 * Remove the 'jetpack/' or jetpack-' prefix from an extension name
120
	 *
121
	 * @since 9.0.0
122
	 *
123
	 * @param string $extension_name The extension name.
124
	 *
125
	 * @return string The unprefixed extension name.
126
	 */
127
	public static function remove_extension_prefix( $extension_name ) {
128 View Code Duplication
		if ( 0 === strpos( $extension_name, 'jetpack/' ) || 0 === strpos( $extension_name, 'jetpack-' ) ) {
129
			return substr( $extension_name, strlen( 'jetpack/' ) );
130
		}
131
		return $extension_name;
132
	}
133
134
	/**
135
	 * Check to see if a minimum version of Gutenberg is available. Because a Gutenberg version is not available in
136
	 * php if the Gutenberg plugin is not installed, if we know which minimum WP release has the required version we can
137
	 * optionally fall back to that.
138
	 *
139
	 * @since 9.0.0
140
	 *
141
	 * @param array  $version_requirements {
142
	 *     An array containing the required Gutenberg version and, if known, the WordPress version that was released with this minimum version.
143
	 *
144
	 *     @type string $gutenberg Gutenberg version.
145
	 *     @type string $wp        Optional. WordPress version.
146
	 * }
147
	 * @param string $slug The slug of the block or plugin that has the Gutenberg version requirement.
148
	 *
149
	 * @return boolean True if the version of Gutenberg required by the block or plugin is available.
150
	 */
151 View Code Duplication
	public static function is_gutenberg_version_available( $version_requirements, $slug ) {
152
		global $wp_version;
153
154
		// Bail if we don't at least have the Gutenberg version requirement, the WP version is optional.
155
		if ( empty( $version_requirements['gutenberg'] ) ) {
156
			return false;
157
		}
158
159
		// If running a local dev build of Gutenberg plugin GUTENBERG_DEVELOPMENT_MODE is set so assume correct version.
160
		if ( defined( 'GUTENBERG_DEVELOPMENT_MODE' ) && GUTENBERG_DEVELOPMENT_MODE ) {
161
			return true;
162
		}
163
164
		$version_available = false;
165
166
		// If running a production build of the Gutenberg plugin then GUTENBERG_VERSION is set, otherwise if WP version
167
		// with required version of Gutenberg is known check that.
168
		if ( defined( 'GUTENBERG_VERSION' ) ) {
169
			$version_available = version_compare( GUTENBERG_VERSION, $version_requirements['gutenberg'], '>=' );
170
		} elseif ( ! empty( $version_requirements['wp'] ) ) {
171
			$version_available = version_compare( $wp_version, $version_requirements['wp'], '>=' );
172
		}
173
174
		if (
175
			! $version_available
176
			&& ! self::is_standalone_block() // This is only useful in Jetpack.
177
		) {
178
			Jetpack_Gutenberg::set_extension_unavailable(
179
				$slug,
180
				'incorrect_gutenberg_version',
181
				array(
182
					'required_feature' => $slug,
183
					'required_version' => $version_requirements,
184
					'current_version'  => array(
185
						'wp'        => $wp_version,
186
						'gutenberg' => defined( 'GUTENBERG_VERSION' ) ? GUTENBERG_VERSION : null,
187
					),
188
				)
189
			);
190
		}
191
192
		return $version_available;
193
	}
194
195
	/**
196
	 * Get CSS classes for a block.
197
	 *
198
	 * @since 9.0.0
199
	 *
200
	 * @param string $slug  Block slug.
201
	 * @param array  $attr  Block attributes.
202
	 * @param array  $extra Potential extra classes you may want to provide.
203
	 *
204
	 * @return string $classes List of CSS classes for a block.
205
	 */
206
	public static function classes( $slug, $attr, $extra = array() ) {
207
		if ( empty( $slug ) ) {
208
			return '';
209
		}
210
211
		// Basic block name class.
212
		$classes = array(
213
			'wp-block-jetpack-' . $slug,
214
		);
215
216
		// Add alignment if provided.
217
		if (
218
			! empty( $attr['align'] )
219
			&& in_array( $attr['align'], array( 'left', 'center', 'right', 'wide', 'full' ), true )
220
		) {
221
			$classes[] = 'align' . $attr['align'];
222
		}
223
224
		// Add custom classes if provided in the block editor.
225
		if ( ! empty( $attr['className'] ) ) {
226
			$classes[] = $attr['className'];
227
		}
228
229
		// Add any extra classes.
230
		if ( is_array( $extra ) && ! empty( $extra ) ) {
231
			$classes = array_merge( $classes, array_filter( $extra ) );
232
		}
233
234
		return implode( ' ', $classes );
235
	}
236
237
	/**
238
	 * Does the page return AMP content.
239
	 *
240
	 * @since 9.0.0
241
	 *
242
	 * @return bool $is_amp_request Are we on an AMP view.
243
	 */
244
	public static function is_amp_request() {
245
		$is_amp_request = ( function_exists( 'is_amp_endpoint' ) && is_amp_endpoint() );
246
247
		/** This filter is documented in 3rd-party/class.jetpack-amp-support.php */
248
		return apply_filters( 'jetpack_is_amp_request', $is_amp_request );
249
	}
250
251
	/**
252
	 * Is the current theme an FSE/Site Editor theme.
253
	 *
254
	 * @since 9.8.0
255
	 *
256
	 * @return bool True if the current theme is an FSE/Site Editor theme.
257
	 */
258
	public static function is_fse_theme() {
259
		$is_fse_theme = function_exists( 'gutenberg_is_fse_theme' ) && gutenberg_is_fse_theme();
260
261
		/**
262
		 * Returns true if the current theme is an FSE/Site Editor theme.
263
		 *
264
		 * @since 9.8.0
265
		 *
266
		 * @param boolean $is_fse_theme Is the theme an FSE theme.
267
		 */
268
		return apply_filters( 'jetpack_is_fse_theme', $is_fse_theme );
269
	}
270
271
	/**
272
	 * Check whether or the block being registered is a standalone block,
273
	 * running in a context outside of the Jetpack plugin.
274
	 *
275
	 * @since 9.6.0
276
	 *
277
	 * @return bool
278
	 */
279
	public static function is_standalone_block() {
280
		$is_standalone_block = ! class_exists( Jetpack_Gutenberg::class );
281
282
		/**
283
		 * Returns true if the block is not being registered within a Jetpack plugin context.
284
		 *
285
		 * @since 9.6.0
286
		 *
287
		 * @param boolean $is_standalone_block Is the block running standalone versus as part of the Jetpack plugin.
288
		 */
289
		return apply_filters( 'jetpack_is_standalone_block', $is_standalone_block );
290
	}
291
}
292