Merge pull request #28679 from woocommerce/fix/woocommerce-gutenberg-products-block-issues-3565

Show correct WooCommerce pages status if they are using blocks vs shortcode.
This commit is contained in:
Claudio Sanches 2021-01-18 19:26:34 -03:00 committed by GitHub
commit ea54d5ad5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 221 additions and 49 deletions

View File

@ -844,10 +844,11 @@ if ( 0 < count( $dropins_mu_plugins['mu_plugins'] ) ) :
echo '<mark class="error"><span class="dashicons dashicons-warning"></span> ' . wp_kses_post( sprintf( __( 'Page visibility should be <a href="%s" target="_blank">public</a>', 'woocommerce' ), 'https://wordpress.org/support/article/content-visibility/' ) ) . '</mark>'; echo '<mark class="error"><span class="dashicons dashicons-warning"></span> ' . wp_kses_post( sprintf( __( 'Page visibility should be <a href="%s" target="_blank">public</a>', 'woocommerce' ), 'https://wordpress.org/support/article/content-visibility/' ) ) . '</mark>';
$found_error = true; $found_error = true;
} else { } else {
// Shortcode check. // Shortcode and block check.
if ( $_page['shortcode_required'] ) { if ( $_page['shortcode_required'] || $_page['block_required'] ) {
if ( ! $_page['shortcode_present'] ) { if ( ! $_page['shortcode_present'] && ! $_page['block_present'] ) {
echo '<mark class="error"><span class="dashicons dashicons-warning"></span> ' . sprintf( esc_html__( 'Page does not contain the shortcode.', 'woocommerce' ), esc_html( $_page['shortcode'] ) ) . '</mark>'; /* Translators: %1$s: shortcode text, %2$s: block slug. */
echo '<mark class="error"><span class="dashicons dashicons-warning"></span> ' . ( $_page['block_required'] ? sprintf( esc_html__( 'Page does not contain the %1$s shortcode or the %2$s block.', 'woocommerce' ), esc_html( $_page['shortcode'] ), esc_html( $_page['block'] ) ) : sprintf( esc_html__( 'Page does not contain the %s shortcode.', 'woocommerce' ), esc_html( $_page['shortcode'] ) ) ) . '</mark>'; /* phpcs:ignore WordPress.XSS.EscapeOutput.OutputNotEscaped */
$found_error = true; $found_error = true;
} }
} }

View File

@ -0,0 +1,84 @@
<?php
/**
* Blocks Utils
*
* Used by core components that need to work with blocks.
*
* @package WooCommerce\Blocks\Utils
* @version 5.0.0
*/
defined( 'ABSPATH' ) || exit;
/**
* Blocks Utility class.
*/
class WC_Blocks_Utils {
/**
* Get blocks from a woocommerce page.
*
* @param string $woo_page_name A woocommerce page e.g. `checkout` or `cart`.
* @return array Array of blocks as returned by parse_blocks().
*/
private static function get_all_blocks_from_page( $woo_page_name ) {
$page_id = wc_get_page_id( $woo_page_name );
$page = get_post( $page_id );
if ( ! $page ) {
return array();
}
$blocks = parse_blocks( $page->post_content );
if ( ! $blocks ) {
return array();
}
return $blocks;
}
/**
* Get all instances of the specified block on a specific woo page
* (e.g. `cart` or `checkout` page).
*
* @param string $block_name The name (id) of a block, e.g. `woocommerce/cart`.
* @param string $woo_page_name The woo page to search, e.g. `cart`.
* @return array Array of blocks as returned by parse_blocks().
*/
public static function get_blocks_from_page( $block_name, $woo_page_name ) {
$page_blocks = self::get_all_blocks_from_page( $woo_page_name );
// Get any instances of the specified block.
return array_values(
array_filter(
$page_blocks,
function ( $block ) use ( $block_name ) {
return ( $block_name === $block['blockName'] );
}
)
);
}
/**
* Check if a given page contains a particular block.
*
* @param int|WP_Post $page Page post ID or post object.
* @param string $block_name The name (id) of a block, e.g. `woocommerce/cart`.
* @return bool Boolean value if the page contains the block or not. Null in case the page does not exist.
*/
public static function has_block_in_page( $page, $block_name ) {
$page_to_check = get_post( $page );
if ( null === $page_to_check ) {
return false;
}
$blocks = parse_blocks( $page_to_check->post_content );
foreach ( $blocks as $block ) {
if ( $block_name === $block['blockName'] ) {
return true;
}
}
return false;
}
}

View File

@ -660,49 +660,6 @@ class WC_Tracker {
return ( '0' !== $result ) ? 'Yes' : 'No'; return ( '0' !== $result ) ? 'Yes' : 'No';
} }
/**
* Get blocks from a woocommerce page.
*
* @param string $woo_page_name A woocommerce page e.g. `checkout` or `cart`.
* @return array Array of blocks as returned by parse_blocks().
*/
private static function get_all_blocks_from_page( $woo_page_name ) {
$page_id = wc_get_page_id( $woo_page_name );
$page = get_post( $page_id );
if ( ! $page ) {
return array();
}
$blocks = parse_blocks( $page->post_content );
if ( ! $blocks ) {
return array();
}
return $blocks;
}
/**
* Get all instances of the specified block on a specific woo page
* (e.g. `cart` or `checkout` page).
*
* @param string $block_name The name (id) of a block, e.g. `woocommerce/cart`.
* @param string $woo_page_name The woo page to search, e.g. `cart`.
* @return array Array of blocks as returned by parse_blocks().
*/
private static function get_blocks_from_page( $block_name, $woo_page_name ) {
$page_blocks = self::get_all_blocks_from_page( $woo_page_name );
// Get any instances of the specified block.
return array_values(
array_filter(
$page_blocks,
function ( $block ) use ( $block_name ) {
return ( $block_name === $block['blockName'] );
}
)
);
}
/** /**
* Get tracker data for a specific block type on a woocommerce page. * Get tracker data for a specific block type on a woocommerce page.
@ -714,7 +671,7 @@ class WC_Tracker {
* - block_attributes * - block_attributes
*/ */
public static function get_block_tracker_data( $block_name, $woo_page_name ) { public static function get_block_tracker_data( $block_name, $woo_page_name ) {
$blocks = self::get_blocks_from_page( $block_name, $woo_page_name ); $blocks = WC_Blocks_Utils::get_blocks_from_page( $block_name, $woo_page_name );
$block_present = false; $block_present = false;
$attributes = array(); $attributes = array();

View File

@ -425,6 +425,7 @@ final class WooCommerce {
include_once WC_ABSPATH . 'includes/queue/class-wc-action-queue.php'; include_once WC_ABSPATH . 'includes/queue/class-wc-action-queue.php';
include_once WC_ABSPATH . 'includes/queue/class-wc-queue.php'; include_once WC_ABSPATH . 'includes/queue/class-wc-queue.php';
include_once WC_ABSPATH . 'includes/admin/marketplace-suggestions/class-wc-marketplace-updater.php'; include_once WC_ABSPATH . 'includes/admin/marketplace-suggestions/class-wc-marketplace-updater.php';
include_once WC_ABSPATH . 'includes/blocks/class-wc-blocks-utils.php';
/** /**
* Data stores - used to store and retrieve CRUD object data from the database. * Data stores - used to store and retrieve CRUD object data from the database.

View File

@ -1162,7 +1162,7 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller {
/** /**
* Returns a mini-report on WC pages and if they are configured correctly: * Returns a mini-report on WC pages and if they are configured correctly:
* Present, visible, and including the correct shortcode. * Present, visible, and including the correct shortcode or block.
* *
* @return array * @return array
*/ */
@ -1172,22 +1172,27 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller {
_x( 'Shop base', 'Page setting', 'woocommerce' ) => array( _x( 'Shop base', 'Page setting', 'woocommerce' ) => array(
'option' => 'woocommerce_shop_page_id', 'option' => 'woocommerce_shop_page_id',
'shortcode' => '', 'shortcode' => '',
'block' => '',
), ),
_x( 'Cart', 'Page setting', 'woocommerce' ) => array( _x( 'Cart', 'Page setting', 'woocommerce' ) => array(
'option' => 'woocommerce_cart_page_id', 'option' => 'woocommerce_cart_page_id',
'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']',
'block' => 'woocommerce/cart',
), ),
_x( 'Checkout', 'Page setting', 'woocommerce' ) => array( _x( 'Checkout', 'Page setting', 'woocommerce' ) => array(
'option' => 'woocommerce_checkout_page_id', 'option' => 'woocommerce_checkout_page_id',
'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']',
'block' => 'woocommerce/checkout',
), ),
_x( 'My account', 'Page setting', 'woocommerce' ) => array( _x( 'My account', 'Page setting', 'woocommerce' ) => array(
'option' => 'woocommerce_myaccount_page_id', 'option' => 'woocommerce_myaccount_page_id',
'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']',
'block' => '',
), ),
_x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array( _x( 'Terms and conditions', 'Page setting', 'woocommerce' ) => array(
'option' => 'woocommerce_terms_page_id', 'option' => 'woocommerce_terms_page_id',
'shortcode' => '', 'shortcode' => '',
'block' => '',
), ),
); );
@ -1199,6 +1204,8 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller {
$page_visible = false; $page_visible = false;
$shortcode_present = false; $shortcode_present = false;
$shortcode_required = false; $shortcode_required = false;
$block_present = false;
$block_required = false;
// Page checks. // Page checks.
if ( $page_id ) { if ( $page_id ) {
@ -1220,6 +1227,12 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller {
} }
} }
// Block checks.
if ( $values['block'] && get_post( $page_id ) ) {
$block_required = true;
$block_present = WC_Blocks_Utils::has_block_in_page( $page_id, $values['block'] );
}
// Wrap up our findings into an output array. // Wrap up our findings into an output array.
$pages_output[] = array( $pages_output[] = array(
'page_name' => $page_name, 'page_name' => $page_name,
@ -1228,8 +1241,11 @@ class WC_REST_System_Status_V2_Controller extends WC_REST_Controller {
'page_exists' => $page_exists, 'page_exists' => $page_exists,
'page_visible' => $page_visible, 'page_visible' => $page_visible,
'shortcode' => $values['shortcode'], 'shortcode' => $values['shortcode'],
'block' => $values['block'],
'shortcode_required' => $shortcode_required, 'shortcode_required' => $shortcode_required,
'shortcode_present' => $shortcode_present, 'shortcode_present' => $shortcode_present,
'block_present' => $block_present,
'block_required' => $block_required,
); );
} }

View File

@ -0,0 +1,113 @@
<?php
/**
* Tests for the WC_Data class.
*
* @package WooCommerce\Tests\Blocks
*/
/**
* Class WC_Test_Blocks_Utils
*/
class WC_Test_Blocks_Utils extends WC_Unit_Test_Case {
/**
* @group block-utils
* Test: has_block_in_page.
*
*/
public function test_has_block_in_page_on_page_with_single_block() {
$page = array(
'name' => 'blocks-page',
'title' => 'Checkout',
'content' => '<!-- wp:woocommerce/checkout {"showOrderNotes":false} --> <div class="wp-block-woocommerce-checkout is-loading"></div> <!-- /wp:woocommerce/checkout -->',
);
$page_id = wc_create_page( $page['name'], '', $page['title'], $page['content'] );
$this->assertTrue( WC_Blocks_Utils::has_block_in_page( $page_id, 'woocommerce/checkout' ) );
$this->assertFalse( WC_Blocks_Utils::has_block_in_page( $page_id, 'woocommerce/cart' ) );
}
/**
* @group block-utils
* Test: has_block_in_page.
*
*/
public function test_has_block_in_page_on_page_with_no_blocks() {
$page = array(
'name' => 'shortcode-page',
'title' => 'Checkout',
'content' => '<!-- wp:shortcode --> [woocommerce_checkout] <!-- /wp:shortcode -->',
);
$page_id = wc_create_page( $page['name'], '', $page['title'], $page['content'] );
$this->assertFalse( WC_Blocks_Utils::has_block_in_page( $page_id, 'woocommerce/checkout' ) );
$this->assertFalse( WC_Blocks_Utils::has_block_in_page( $page_id, 'woocommerce/cart' ) );
}
/**
* @group block-utils
* Test: has_block_in_page.
*
*/
public function test_has_block_in_page_on_page_with_multiple_blocks() {
$page = array(
'name' => 'shortcode-page',
'title' => 'Checkout',
'content' => '<!-- wp:woocommerce/featured-product {"editMode":false,"productId":17} -->
<!-- wp:button {"align":"center"} -->
<div class="wp-block-button aligncenter"><a class="wp-block-button__link" href="https://blocks.local/product/beanie/">Shop now</a></div>
<!-- /wp:button -->
<!-- /wp:woocommerce/featured-product -->
<!-- wp:heading -->
<h2>test</h2>
<!-- /wp:heading -->',
);
$page_id = wc_create_page( $page['name'], '', $page['title'], $page['content'] );
$this->assertTrue( WC_Blocks_Utils::has_block_in_page( $page_id, 'woocommerce/featured-product' ) );
$this->assertTrue( WC_Blocks_Utils::has_block_in_page( $page_id, 'core/heading' ) );
}
/**
* @group block-utils
* Test: get_all_blocks_from_page.
*
*/
public function test_get_all_blocks_from_page() {
$page = array(
'name' => 'cart',
'title' => 'Checkout',
'content' => '<!-- wp:heading --><h2>test1</h2><!-- /wp:heading --><!-- wp:heading --><h1>test2</h1><!-- /wp:heading -->',
);
wc_create_page( $page['name'], 'woocommerce_cart_page_id', $page['title'], $page['content'] );
$expected = array(
0 => array(
'blockName' => 'core/heading',
'attrs' => array(),
'innerBlocks' => array(),
'innerHTML' => '<h2>test1</h2>',
'innerContent' => array(
0 => '<h2>test1</h2>',
),
),
1 => array(
'blockName' => 'core/heading',
'attrs' => array(),
'innerBlocks' => array(),
'innerHTML' => '<h1>test2</h1>',
'innerContent' => array(
0 => '<h1>test2</h1>',
),
),
);
$blocks = WC_Blocks_Utils::get_blocks_from_page( 'core/heading', 'cart' );
$this->assertEquals( $expected, $blocks );
}
}