PluginProbe
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages / 3.4.3
Kit (formerly ConvertKit) – Email Newsletter, Email Marketing, Membership, Subscribers and Landing Pages v3.4.3
3.4.3 3.4.2 3.4.1 3.4.0 3.3.9 3.3.8 3.3.7 3.3.6 3.3.5 3.3.4 3.3.3 3.3.2 3.3.1 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3.0 2.3.1 All 196 releases
← All changes | includes/blocks/class-convertkit-block.php +258 -71 2.2.43.4.3 View file →
@@ -23,8 +23,23 @@
23 23 * @return array Blocks to Register
24 24 */
25 25 public function register( $blocks ) {
26 26
27 + // If the request is for the frontend, return the minimum block definition required
28 + // to register and render the block on the frontend site using register_block_type().
29 + if ( ! $this->is_admin_frontend_editor_or_admin_rest_request() ) {
30 + $blocks[ $this->get_name() ] = array(
31 + 'title' => $this->get_title(),
32 + 'icon' => $this->get_icon(),
33 + 'attributes' => $this->get_attributes(),
34 + 'render_callback' => array( $this, 'render' ),
35 + );
36 +
37 + return $blocks;
38 + }
39 +
40 + // Request is for the WordPress Administration, frontend editor or REST API request.
41 + // Register the full block definition, including fields, panels, default values and supports.
27 42 $blocks[ $this->get_name() ] = array_merge(
28 43 $this->get_overview(),
29 44 array(
30 45 'name' => $this->get_name(),
@@ -40,8 +55,30 @@
40 55
41 56 }
42 57
43 58 /**
59 + * Registers this block's MCP abilities.
60 + *
61 + * @since 3.4.0
62 + *
63 + * @param array $abilities Abilities to Register.
64 + * @return array
65 + */
66 + public function register_abilities( $abilities ) {
67 +
68 + return array_merge(
69 + $abilities,
70 + array(
71 + 'kit/' . $this->get_name() . '-list' => new ConvertKit_MCP_Ability_Content_List( $this ),
72 + 'kit/' . $this->get_name() . '-insert' => new ConvertKit_MCP_Ability_Content_Insert( $this ),
73 + 'kit/' . $this->get_name() . '-update' => new ConvertKit_MCP_Ability_Content_Update( $this ),
74 + 'kit/' . $this->get_name() . '-delete' => new ConvertKit_MCP_Ability_Content_Delete( $this ),
75 + )
76 + );
77 +
78 + }
79 +
80 + /**
44 81 * Returns this block's programmatic name, excluding the convertkit- prefix.
45 82 *
46 83 * @since 1.9.6
47 84 */
@@ -57,8 +94,43 @@
57 94
58 95 }
59 96
60 97 /**
98 + * Returns this block's title.
99 + *
100 + * @since 3.1.1
101 + */
102 + public function get_title() {
103 +
104 + return '';
105 +
106 + }
107 +
108 + /**
109 + * Returns this block's plural title.
110 + *
111 + * @since 3.4.0
112 + *
113 + * @return string
114 + */
115 + public function get_title_plural() {
116 +
117 + return '';
118 +
119 + }
120 +
121 + /**
122 + * Returns this block's icon.
123 + *
124 + * @since 3.1.1
125 + */
126 + public function get_icon() {
127 +
128 + return '';
129 +
130 + }
131 +
132 + /**
61 133 * Returns this block's Title, Icon, Categories, Keywords and properties.
62 134 *
63 135 * @since 1.9.6
64 136 *
@@ -219,101 +291,140 @@
219 291 break;
220 292 }
221 293 }
222 294
223 - // Build CSS class(es) that might need to be added to the top level element for this block.
224 - $atts['_css_classes'] = array( 'convertkit-' . $this->get_name() );
225 - $atts['_css_styles'] = array();
295 + // Remove some unused attributes, now they're declared above.
296 + unset( $atts['style'], $atts['backgroundColor'], $atts['textColor'], $atts['className'] );
226 297
227 - // If the block supports a text color, and a preset color was selected, add it to the
228 - // array of CSS classes.
229 - if ( $atts['textColor'] ) {
230 - $atts['_css_classes'][] = 'has-text-color';
231 - $atts['_css_classes'][] = 'has-' . $atts['textColor'] . '-color';
232 - }
298 + return $atts;
233 299
234 - // If the block supports a text color, and a custom hex color was selected, add it to the
235 - // array of CSS inline styles.
236 - if ( isset( $atts['style']['color'] ) && isset( $atts['style']['color']['text'] ) ) {
237 - $atts['_css_classes'][] = 'has-text-color';
238 - $atts['_css_styles']['color'] = 'color:' . $atts['style']['color']['text'];
300 + }
301 +
302 + /**
303 + * Removes any HTML that might be wrongly included in the shorcode attribute's values
304 + * due to e.g. copy and pasting from Documentation or other examples.
305 + *
306 + * @since 1.9.6
307 + *
308 + * @param array $atts Block or shortcode attributes.
309 + * @return array
310 + */
311 + public function sanitize_atts( $atts ) {
312 +
313 + foreach ( $atts as $key => $value ) {
314 + if ( is_array( $value ) ) {
315 + continue;
316 + }
317 +
318 + $atts[ $key ] = wp_strip_all_tags( $value );
239 319 }
240 320
241 - // If the shortcode supports a text color, and a custom hex color was selected, add it to the
242 - // array of CSS inline styles.
243 - if ( isset( $atts['text_color'] ) && ! empty( $atts['text_color'] ) ) {
244 - $atts['_css_classes'][] = 'has-text-color';
245 - $atts['_css_styles']['color'] = 'color:' . $atts['text_color'];
246 - }
321 + return $atts;
247 322
248 - // If the block supports a background color, and a preset color was selected, add it to the
249 - // array of CSS classes.
250 - if ( $atts['backgroundColor'] ) {
251 - $atts['_css_classes'][] = 'has-background';
252 - $atts['_css_classes'][] = 'has-' . $atts['backgroundColor'] . '-background-color';
253 - }
323 + }
254 324
255 - // If the block supports a background color, and a custom hex color was selected, add it to the
256 - // array of CSS inline styles.
257 - if ( isset( $atts['style']['color'] ) && isset( $atts['style']['color']['background'] ) ) {
258 - $atts['_css_classes'][] = 'has-background';
259 - $atts['_css_styles']['background'] = 'background-color:' . $atts['style']['color']['background'];
260 - }
325 + /**
326 + * Builds CSS class(es) that might need to be added to the top level element's `class` attribute
327 + * when using Gutenberg, to honor the block's styles and layout settings.
328 + *
329 + * @since 2.8.3
330 + *
331 + * @param array $additional_classes Additional classes to add to the block.
332 + * @return array
333 + */
334 + public function get_css_classes( $additional_classes = array() ) {
261 335
262 - // If the block supports a font size, and a preset font size was selected, add it to the
263 - // array of CSS classes.
264 - if ( isset( $atts['fontSize'] ) && ! empty( $atts['fontSize'] ) ) {
265 - $atts['_css_classes'][] = 'has-custom-font-size';
266 - $atts['_css_classes'][] = 'has-' . $atts['fontSize'] . '-font-size';
336 + // To avoid errors in get_block_wrapper_attributes() in non-block themes using the shortcode,
337 + // tell WordPress that a block is being rendered.
338 + // The attributes don't matter, as we send them to the render() function.
339 + if ( class_exists( 'WP_Block_Supports' ) && is_null( WP_Block_Supports::$block_to_render ) ) { // @phpstan-ignore-line
340 + WP_Block_Supports::$block_to_render = array(
341 + 'blockName' => 'convertkit/' . $this->get_name(),
342 + 'attrs' => array(),
343 + 'innerBlocks' => array(),
344 + 'innerHTML' => '',
345 + 'innerContent' => array(),
346 + );
267 347 }
268 348
269 - // If the block supports padding, and padding is set, add it to the
270 - // array of CSS inline styles.
271 - if ( isset( $atts['style']['spacing'] ) && isset( $atts['style']['spacing']['padding'] ) ) {
272 - foreach ( $atts['style']['spacing']['padding'] as $position => $value ) {
273 - $atts['_css_styles'][ 'padding-' . $position ] = 'padding-' . $position . ':' . $value;
274 - }
275 - }
349 + // Get the block wrapper attributes string.
350 + $wrapper_attributes = get_block_wrapper_attributes(
351 + array(
352 + 'class' => implode(
353 + ' ',
354 + array_merge(
355 + array(
356 + 'convertkit-' . $this->get_name(),
357 + ),
358 + $additional_classes
359 + )
360 + ),
361 + )
362 + );
276 363
277 - // If the shortcode supports a background color, and a custom hex color was selected, add it to the
278 - // array of CSS inline styles.
279 - if ( isset( $atts['background_color'] ) && ! empty( $atts['background_color'] ) ) {
280 - $atts['_css_classes'][] = 'has-background';
281 - $atts['_css_styles']['background'] = 'background-color:' . $atts['background_color'];
364 + // Extract the class attribute from the wrapper attributes string, returning as an array.
365 + // Extract just the class attribute value from the wrapper attributes string.
366 + $classes = array();
367 + if ( preg_match( '/class="([^"]*)"/', $wrapper_attributes, $matches ) ) {
368 + $classes = explode( ' ', $matches[1] );
369 + } else {
370 + $classes = array(
371 + 'convertkit-' . $this->get_name(),
372 + );
282 373 }
283 374
284 - // Remove some unused attributes, now they're declared above.
285 - unset( $atts['style'] );
375 + // Remove some classes WordPress adds that we don't want, as they break the layout.
376 + $classes = array_diff( $classes, array( 'alignfull', 'wp-block-post-content' ) );
286 377
287 - return $atts;
378 + return $classes;
288 379
289 380 }
290 381
291 382 /**
292 - * Removes any HTML that might be wrongly included in the shorcode attribute's values
293 - * due to e.g. copy and pasting from Documentation or other examples.
383 + * Builds inline CSS style(s) that might need to be added to the top level element's `style` attribute
384 + * when using Gutenberg, a shortcode or third party page builder module / widget.
294 385 *
295 - * @since 1.9.6
386 + * @since 2.8.3
296 387 *
297 388 * @param array $atts Block or shortcode attributes.
298 - * @return array Block or shortcode attributes
389 + * @return array
299 390 */
300 - public function sanitize_atts( $atts ) {
391 + public function get_css_styles( $atts ) {
301 392
302 - if ( ! is_array( $atts ) ) {
303 - return $atts;
393 + // To avoid errors in get_block_wrapper_attributes() in non-block themes using the shortcode,
394 + // tell WordPress that a block is being rendered.
395 + // The attributes don't matter, as we send them to the render() function.
396 + if ( class_exists( 'WP_Block_Supports' ) && is_null( WP_Block_Supports::$block_to_render ) ) { // @phpstan-ignore-line
397 + WP_Block_Supports::$block_to_render = array(
398 + 'blockName' => 'convertkit/' . $this->get_name(),
399 + 'attrs' => array(),
400 + 'innerBlocks' => array(),
401 + 'innerHTML' => '',
402 + 'innerContent' => array(),
403 + );
304 404 }
305 405
306 - foreach ( $atts as $key => $value ) {
307 - if ( is_array( $value ) ) {
308 - continue;
309 - }
406 + $styles = array();
310 407
311 - $atts[ $key ] = wp_strip_all_tags( $value );
408 + // Get the block wrapper attributes string, extracting any styles that the block has set,
409 + // such as margin, padding or block spacing.
410 + $wrapper_attributes = get_block_wrapper_attributes();
411 + if ( preg_match( '/style="([^"]*)"/', $wrapper_attributes, $matches ) ) {
412 + return array_filter( explode( ';', $matches[1] ) );
312 413 }
313 414
314 - return $atts;
415 + // If here, no block styles were found.
416 + // This might be a shortcode or third party page builder module / widget that has
417 + // specific attributes set.
418 + if ( isset( $atts['text_color'] ) && ! empty( $atts['text_color'] ) ) {
419 + $styles[] = 'color:' . $atts['text_color'];
420 + }
421 + if ( isset( $atts['background_color'] ) && ! empty( $atts['background_color'] ) ) {
422 + $styles[] = 'background-color:' . $atts['background_color'];
423 + }
315 424
425 + return $styles;
426 +
316 427 }
317 428
318 429 /**
319 430 * Returns the given block / shortcode attributes array as HTML data-* attributes, which can be output
@@ -330,9 +441,8 @@
330 441 // styling.
331 442 $skip_keys = array(
332 443 'backgroundColor',
333 444 'textColor',
334 - '_css_classes',
335 445 '_css_styles',
336 446 );
337 447
338 448 // Define a blank string to build the data-* attributes in.
@@ -343,8 +453,13 @@
343 453 if ( in_array( $key, $skip_keys, true ) ) {
344 454 continue;
345 455 }
346 456
457 + // Skip empty values.
458 + if ( empty( $value ) ) {
459 + continue;
460 + }
461 +
347 462 // Append to data string, replacing underscores with hyphens in the key name.
348 463 $data .= ' data-' . strtolower( str_replace( '_', '-', $key ) ) . '="' . esc_attr( $value ) . '"';
349 464 }
350 465
@@ -352,8 +467,35 @@
352 467
353 468 }
354 469
355 470 /**
471 + * Determines if the request is a WordPress REST API request
472 + * made by a logged in WordPress user who has the capability to edit posts.
473 + *
474 + * @since 3.1.0
475 + *
476 + * @return bool
477 + */
478 + public function is_admin_rest_request() {
479 +
480 + return defined( 'REST_REQUEST' ) && REST_REQUEST && current_user_can( 'edit_posts' );
481 +
482 + }
483 +
484 + /**
485 + * Determines if the request is for the WordPress Administration, frontend editor or REST API request.
486 + *
487 + * @since 3.1.0
488 + *
489 + * @return bool
490 + */
491 + public function is_admin_frontend_editor_or_admin_rest_request() {
492 +
493 + return WP_ConvertKit()->is_admin_or_frontend_editor() || $this->is_admin_rest_request();
494 +
495 + }
496 +
497 + /**
356 498 * Determines if the request for the block is from the block editor or the frontend site.
357 499 *
358 500 * @since 1.9.8.5
359 501 *
@@ -361,21 +503,66 @@
361 503 */
362 504 public function is_block_editor_request() {
363 505
364 506 // Return false if not a WordPress REST API request, which Gutenberg uses.
365 - if ( ! defined( 'REST_REQUEST' ) ) {
507 + if ( ! $this->is_admin_rest_request() ) {
366 508 return false;
367 509 }
368 - if ( REST_REQUEST !== true ) {
510 +
511 + // Return false if the context parameter isn't edit.
512 + if ( ! filter_has_var( INPUT_GET, 'context' ) ) {
369 513 return false;
370 514 }
515 + if ( filter_input( INPUT_GET, 'context', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) !== 'edit' ) {
516 + return false;
517 + }
371 518
372 - // Return false if the context parameter isn't edit.
373 - if ( filter_input( INPUT_GET, 'context', FILTER_SANITIZE_STRING ) !== 'edit' ) {
519 + // Request is for the block editor.
520 + return true;
521 +
522 + }
523 +
524 + /**
525 + * If the Block Visiblity Plugin is active, run the block through its conditions now.
526 + * We don't wait for Block Visibility to do this, as it performs this on the
527 + * `render_block` filter, by which time the code in this method has fully executed,
528 + * meaning any non-inline Forms will have had their scripts added to the
529 + * `convertkit_output_scripts_footer` hook.
530 + * As a result, the non-inline Form will always display, regardless of whether
531 + * Block Visibility's conditions are met.
532 + * We deliberately don't output non-inline Forms in their block, instead deferring
533 + * to the `convertkit_output_scripts_footer` hook, to ensure the non-inline Forms
534 + * styling are not constrained by the Theme's width, layout or other properties.
535 + *
536 + * @since 2.6.6
537 + *
538 + * @param array $atts Block Attributes.
539 + * @return bool Display Block
540 + */
541 + public function is_block_visible( $atts ) {
542 +
543 + // Display the block if the Block Visibility Plugin isn't active.
544 + if ( ! function_exists( '\BlockVisibility\Frontend\render_with_visibility' ) ) {
545 + return true;
546 + }
547 +
548 + // Determine whether the block should display.
549 + $display_block = \BlockVisibility\Frontend\render_with_visibility(
550 + 'block',
551 + array(
552 + 'blockName' => 'convertkit-' . $this->get_name(),
553 + 'attrs' => $atts,
554 + )
555 + );
556 +
557 + // If the content returned is a blank string, conditions on this block set
558 + // by the user in the Block Visibility Plugin resulted in the block not displaying.
559 + // Don't display it.
560 + if ( empty( $display_block ) ) {
374 561 return false;
375 562 }
376 563
377 - // Request is for the block editor.
564 + // If here, the block can be displayed.
378 565 return true;
379 566
380 567 }
381 568