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