Skip to content

Commit

Permalink
use blocks integration to add notice in blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
iyut committed Dec 31, 2024
1 parent 4310a1d commit 7e94e1a
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 71 deletions.
118 changes: 118 additions & 0 deletions classes/class-wc-connect-blocks-integration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php
/**
* Blocks Integration class.
*
* @package WooCommerce_Table_Rate_Shipping
*/

if ( ! defined( 'ABSPATH' ) ) {
exit;
}

use Automattic\WooCommerce\Blocks\Integrations\IntegrationInterface;

/**
* Class for WooCommerce Blocks integration.
*/
class WC_Connect_Blocks_Integration implements IntegrationInterface {

/**
* The name of the integration.
*
* @return string
*/
public function get_name(): string {
return 'woocommerce-services';
}

/**
* When called invokes any initialization/setup for the integratidon.
*/
public function initialize() {
$this->register_scripts();
}

/**
* Returns an array of script handles to enqueue in the frontend context.
*
* @return string[]
*/
public function get_script_handles(): array {
return array( 'woocommerce-services-checkout-' . WC_Connect_Loader::get_wcs_version() );
}

/**
* Returns an array of script handles to enqueue in the editor context.
*
* @return string[]
*/
public function get_editor_script_handles(): array {
return array();
}

/**
* An array of key, value pairs of data made available to the block on the client side.
*
* @return array
*/
public function get_script_data(): array {
return array();
}

/**
* Registers the scripts and styles for the integration.
*/
public function register_scripts() {

foreach ( $this->get_script_handles() as $handle ) {
$this->register_script( $handle );
}
}

/**
* Register a script for the integration.
*
* @param string $handle Script handle.
*/
protected function register_script( string $handle ) {
$script_path = $handle . '.js';
$script_url = WC_Connect_Loader::get_wc_connect_base_url() . $script_path;

$script_asset_path = WC_Connect_Loader::get_wc_connect_base_path() . $handle . '.asset.php';
$script_asset = file_exists( $script_asset_path )
? require $script_asset_path // nosemgrep: audit.php.lang.security.file.inclusion-arg --- This is a safe file inclusion.
: array(
'dependencies' => array(),
'version' => $this->get_file_version( WC_Connect_Loader::get_wc_connect_base_path() . $script_path ),
);

wp_register_script(
$handle,
$script_url,
$script_asset['dependencies'],
$script_asset['version'],
true
);

wp_set_script_translations(
$handle,
'woocommerce-services',
WC_Connect_Loader::get_wcs_abs_path() . 'i18n/languages'
);
}

/**
* Get the file modified time as a cache buster if we're in dev mode.
*
* @param string $file Local path to the file.
*
* @return string The cache buster value to use for the given file.
*/
protected function get_file_version( string $file ): string {
if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG && file_exists( $file ) ) {
return filemtime( $file );
}

return WC_Connect_Loader::get_wcs_version();
}
}
23 changes: 15 additions & 8 deletions classes/class-wc-connect-taxjar-integration.php
Original file line number Diff line number Diff line change
Expand Up @@ -398,25 +398,32 @@ public function _log( $message ) {
$this->logger->log( $formatted_message, 'WCS Tax' );
}

/**
* Display notice in cart or checkout page.
*
* @param string|array $message Error message.
*/
public function _notice( $message ) {
$formatted_message = is_scalar( $message ) ? $message : json_encode( $message );
$formatted_message = is_scalar( $message ) ? $message : wp_json_encode( $message );

// if on checkout page load (not ajax), don't set an error as it prevents checkout page from displaying
if (
( is_cart() || ( is_checkout() && is_ajax() ) ) ||
( WC_Connect_Functions::has_cart_or_checkout_block() || WC_Connect_functions::is_store_api_call() )
) {
$this->maybe_add_notice_error( $message, 'notice' );
$this->maybe_add_error_notice( $message, 'notice' );
}

return;
}

/**
* @param $message
* Display error on cart or checkout page.
*
* @param string|array $message Error message.
*/
public function _error( $message ) {
$formatted_message = is_scalar( $message ) ? $message : json_encode( $message );
$formatted_message = is_scalar( $message ) ? $message : wp_json_encode( $message );

// ignore error messages caused by customer input
$state_zip_mismatch = false !== strpos( $formatted_message, 'to_zip' ) && false !== strpos( $formatted_message, 'is not used within to_state' );
Expand All @@ -442,7 +449,7 @@ public function _error( $message ) {
( is_cart() || ( is_checkout() && is_ajax() ) ) ||
( WC_Connect_Functions::has_cart_or_checkout_block() || WC_Connect_functions::is_store_api_call() )
) {
$this->maybe_add_notice_error( $message, 'error' );
$this->maybe_add_error_notice( $message, 'error' );
}

return;
Expand Down Expand Up @@ -1469,15 +1476,15 @@ public function smartcalcs_request( $json ) {
}
}

public function maybe_add_notice_error( $message, $type = 'error' ) {
public function maybe_add_error_notice( $message, $type = 'error' ) {
if ( ! wc_has_notice( $message, $type ) ) {
wc_add_notice( $message, $type );
}

$this->add_notice_error( $message, $type );
$this->add_error_notice( $message, $type );
}

public function add_notice_error( $message, $type = 'error' ) {
public function add_error_notice( $message, $type = 'error' ) {
$notices = WC()->session->get( self::NOTICE_KEY );

if ( ! is_array( $notices ) ) {
Expand Down
106 changes: 53 additions & 53 deletions client/checkout-notices/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,68 +6,68 @@
* @package WooCommerce_Services
*/

window.addEventListener("load", () => {
const { useSelect } = window.wp.data;
const { registerPlugin } = window.wp.plugins;
const { ExperimentalOrderShippingPackages, StoreNotice } = window.wc.blocksCheckout;
const { RawHTML } = window.wp.element;
const { useSelect } = window.wp.data;
const { registerPlugin } = window.wp.plugins;
const { ExperimentalOrderShippingPackages, StoreNotice } = window.wc.blocksCheckout;
const { RawHTML } = window.wp.element;

const createStoreNotice = ( notice, index, type = 'info' ) => {
if ( 'debug' === type ) {
type = 'info';
}

const message = <RawHTML>{notice}</RawHTML>;
const createStoreNotice = ( notice, index, type = 'info' ) => {
if ( 'debug' === type ) {
type = 'info';
}

return (
<StoreNotice key={index} status={type} isDismissible={false}>
{message}
</StoreNotice>
);
};
// eslint-ignore-nextline
const message = <RawHTML>{notice}</RawHTML>;

Check failure on line 20 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

'React' must be in scope when using JSX

const Notices = ({ messages }) => {
if ( ! messages['notice'] ) {
return null;
}
return (
<StoreNotice key={index} status={type} isDismissible={false}>

Check failure on line 23 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

'React' must be in scope when using JSX
{message}
</StoreNotice>
);
};

const currentMessage = messages['notice'];
const Notices = ({ messages }) => {
if ( ! messages['notice'] ) {

Check failure on line 30 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

["notice"] is better written in dot notation
return null;
}

return (
<div className="woocommerce-services-block-notices">
{createStoreNotice( currentMessage, 0, 'info' )}
</div>
);
};
const currentMessage = messages['notice'];

Check failure on line 34 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

["notice"] is better written in dot notation

const render = () => {
const { errorNotices } = useSelect((select) => {
const storeCartData = select( 'wc/store/cart' ).getCartData();
return (
<div className="woocommerce-services-block-notices">

Check failure on line 37 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

'React' must be in scope when using JSX

Check failure on line 37 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

className should follow CSS namespace guidelines (expected checkout-notices__ prefix)
{createStoreNotice( currentMessage, 0, 'info' )}
</div>
);
};

if ( ! storeCartData.extensions && ! storeCartData.extensions['woocommerce_services'] && ! storeCartData.extensions['woocommerce_services'].error_notices ) {
return {};
}
const errorNotices = storeCartData.extensions['woocommerce_services'].error_notices;
const render = () => {
const { errorNotices } = useSelect((select) => {
const storeCartData = select( 'wc/store/cart' ).getCartData();

return {
errorNotices,
};
}, []);

// Ensure we only show abort messages if no shipping rates are available.
if ( ! errorNotices ) {
return null;
if ( ! storeCartData.extensions || ! storeCartData.extensions['woocommerce_services'] || ! storeCartData.extensions['woocommerce_services'].error_notices ) {

Check failure on line 47 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

["woocommerce_services"] is better written in dot notation

Check failure on line 47 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

["woocommerce_services"] is better written in dot notation
return {};
}

const errorNotices = storeCartData.extensions['woocommerce_services'].error_notices;

Check failure on line 51 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

'errorNotices' is already declared in the upper scope

Check failure on line 51 in client/checkout-notices/index.js

View workflow job for this annotation

GitHub Actions / Build Container and Run E2E Tests

["woocommerce_services"] is better written in dot notation

return {
errorNotices,
};
}, []);

// Ensure we only show abort messages if no shipping rates are available.
if ( ! errorNotices ) {
return null;
}

return (
<ExperimentalOrderShippingPackages>
<Notices messages={errorNotices} />
</ExperimentalOrderShippingPackages>
);
};
return (
<ExperimentalOrderShippingPackages>
<Notices messages={errorNotices} />
</ExperimentalOrderShippingPackages>
);
};

registerPlugin('woocommerce-services-notices', {
render,
scope: 'woocommerce-checkout',
});
registerPlugin('woocommerce-services-notices', {
render,
scope: 'woocommerce-checkout',
});
51 changes: 41 additions & 10 deletions woocommerce-services.php
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public static function get_wcs_version() {
*
* @return string
*/
private static function get_wc_connect_base_url() {
public static function get_wc_connect_base_url() {
return trailingslashit( defined( 'WOOCOMMERCE_CONNECT_DEV_SERVER_URL' ) ? WOOCOMMERCE_CONNECT_DEV_SERVER_URL : plugins_url( 'dist/', __FILE__ ) );
}

Expand All @@ -359,6 +359,24 @@ public static function get_wcs_admin_style_url() {
}
}

/**
* Get plugin absolute path.
*
* @return string
*/
public static function get_wcs_abs_path() {
return __DIR__ . '/';
}

/**
* Get plugin distribution path.
*
* @return string
*/
public static function get_wc_connect_base_path() {
return __DIR__ . '/dist/';
}

public function __construct() {
$this->wc_connect_base_url = self::get_wc_connect_base_url();
add_action(
Expand Down Expand Up @@ -663,6 +681,7 @@ function () {
}

add_action( 'before_woocommerce_init', array( $this, 'pre_wc_init' ) );
add_action( 'woocommerce_blocks_loaded', array( $this, 'register_blocks_integration' ) );
add_action( 'woocommerce_blocks_loaded', array( $this, 'extend_store_api' ) );
}

Expand Down Expand Up @@ -701,7 +720,6 @@ public function pre_wc_init() {
return;
}

add_action( 'wp_enqueue_scripts', array( $this, 'frontend_enqueue_scripts' ) );
add_action( 'woocommerce_init', array( $this, 'after_wc_init' ) );
}

Expand Down Expand Up @@ -897,6 +915,27 @@ public function attach_hooks() {
}
}

/**
* Register blocks integration.
*/
public function register_blocks_integration() {
require_once __DIR__ . '/classes/class-wc-connect-blocks-integration.php';

add_action(
'woocommerce_blocks_cart_block_registration',
function ( $integration_registry ) {
$integration_registry->register( new WC_Connect_Blocks_Integration() );
}
);

add_action(
'woocommerce_blocks_checkout_block_registration',
function ( $integration_registry ) {
$integration_registry->register( new WC_Connect_Blocks_Integration() );
}
);
}

/**
* Extend the store API.
*/
Expand Down Expand Up @@ -1616,14 +1655,6 @@ public function admin_enqueue_scripts() {
);
}

public function frontend_enqueue_scripts() {
$plugin_version = self::get_wcs_version();

if ( WC_Connect_Functions::has_cart_or_checkout_block() ) {
wp_enqueue_script( 'wc_services_checkout', $this->wc_connect_base_url . 'woocommerce-services-checkout-' . $plugin_version . '.js', array(), null );
}
}

public function get_active_shipping_services() {
global $wpdb;
$active_shipping_services = array();
Expand Down

0 comments on commit 7e94e1a

Please sign in to comment.