Set up and migration to use BlockTemplate classes (#39814)
* Initial set up and migration for the BlockTemplate * Migrate remaining fields to the new SimpleProductTemplate * Remove re-usable functions and clean up * Add interfaces * Add changelogs * Remove unused id from block attributes * Update changelog * Address refactor suggestions * Fix lint errors * Add tests * Address PR feedback * Extend from BlockContainerInterface instead of BlockInterface
This commit is contained in:
parent
79edab17bc
commit
9198596918
|
@ -0,0 +1,5 @@
|
|||
Significance: patch
|
||||
Type: tweak
|
||||
Comment: Fix mis spelling of variable name visibility.
|
||||
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
"type": "string",
|
||||
"__experimentalRole": "content"
|
||||
},
|
||||
"visibilty": {
|
||||
"visibility": {
|
||||
"type": "string",
|
||||
"enum": [ "visible", "catalog", "search", "hidden" ],
|
||||
"default": "visible"
|
||||
|
|
|
@ -17,7 +17,7 @@ export function Edit( {
|
|||
}: {
|
||||
attributes: CatalogVisibilityBlockAttributes;
|
||||
} ) {
|
||||
const { label, visibilty } = attributes;
|
||||
const { label, visibility } = attributes;
|
||||
|
||||
const blockProps = useBlockProps();
|
||||
|
||||
|
@ -26,22 +26,22 @@ export function Edit( {
|
|||
>( 'postType', 'product', 'catalog_visibility' );
|
||||
|
||||
const checked =
|
||||
catalogVisibility === visibilty || catalogVisibility === 'hidden';
|
||||
catalogVisibility === visibility || catalogVisibility === 'hidden';
|
||||
|
||||
function handleChange( selected: boolean ) {
|
||||
if ( selected ) {
|
||||
if ( catalogVisibility === 'visible' ) {
|
||||
setCatalogVisibility( visibilty );
|
||||
setCatalogVisibility( visibility );
|
||||
return;
|
||||
}
|
||||
setCatalogVisibility( 'hidden' );
|
||||
} else {
|
||||
if ( catalogVisibility === 'hidden' ) {
|
||||
if ( visibilty === 'catalog' ) {
|
||||
if ( visibility === 'catalog' ) {
|
||||
setCatalogVisibility( 'search' );
|
||||
return;
|
||||
}
|
||||
if ( visibilty === 'search' ) {
|
||||
if ( visibility === 'search' ) {
|
||||
setCatalogVisibility( 'catalog' );
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -6,5 +6,5 @@ import { BlockAttributes } from '@wordpress/blocks';
|
|||
|
||||
export interface CatalogVisibilityBlockAttributes extends BlockAttributes {
|
||||
label: string;
|
||||
visibilty: Product[ 'catalog_visibility' ];
|
||||
visibility: Product[ 'catalog_visibility' ];
|
||||
}
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
"keywords": [ "products", "notice" ],
|
||||
"textdomain": "default",
|
||||
"attributes": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: major
|
||||
Type: update
|
||||
|
||||
Update the simple product template implementation to use the product form template API.
|
|
@ -6,6 +6,7 @@
|
|||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
use Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates\SimpleProductTemplate;
|
||||
use Automattic\WooCommerce\Admin\Features\TransientNotices;
|
||||
use Automattic\WooCommerce\Admin\PageController;
|
||||
use Automattic\WooCommerce\Internal\Admin\Loader;
|
||||
|
@ -34,15 +35,23 @@ class Init {
|
|||
*/
|
||||
private $redirection_controller;
|
||||
|
||||
/**
|
||||
* Simple product block template.
|
||||
*
|
||||
* @var AbstractBlockTemplate
|
||||
*/
|
||||
public $simple_product_template;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( Features::is_enabled( 'product-variation-management' ) ) {
|
||||
array_push($this->supported_post_types, 'variable');
|
||||
array_push( $this->supported_post_types, 'variable' );
|
||||
}
|
||||
|
||||
$this->redirection_controller = new RedirectionController( $this->supported_post_types );
|
||||
$this->simple_product_template = new SimpleProductTemplate();
|
||||
$this->redirection_controller = new RedirectionController( $this->supported_post_types );
|
||||
|
||||
if ( \Automattic\WooCommerce\Utilities\FeaturesUtil::feature_is_enabled( 'product_block_editor' ) ) {
|
||||
if ( ! Features::is_enabled( 'new-product-management-experience' ) ) {
|
||||
|
@ -257,555 +266,7 @@ class Init {
|
|||
public function add_product_template( $args ) {
|
||||
if ( ! isset( $args['template'] ) ) {
|
||||
$args['template_lock'] = 'all';
|
||||
$args['template'] = array(
|
||||
array(
|
||||
'woocommerce/product-tab',
|
||||
array(
|
||||
'id' => 'general',
|
||||
'title' => __( 'General', 'woocommerce' ),
|
||||
'order' => 10,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Basic details', 'woocommerce' ),
|
||||
'description' => __( 'This info will be displayed on the product page, category pages, social media, and search results.', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-name-field',
|
||||
array(
|
||||
'name' => 'Product name',
|
||||
'autoFocus' => true,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-summary-field',
|
||||
),
|
||||
array(
|
||||
'core/columns',
|
||||
array(),
|
||||
array(
|
||||
array(
|
||||
'core/column',
|
||||
array(
|
||||
'templateLock' => 'all',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-regular-price-field',
|
||||
array(
|
||||
'name' => 'regular_price',
|
||||
'label' => __( 'List price', 'woocommerce' ),
|
||||
'help' => __( 'Manage more settings in <PricingTab>Pricing.</PricingTab>', 'woocommerce' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'core/column',
|
||||
array(
|
||||
'templateLock' => 'all',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-sale-price-field',
|
||||
array(
|
||||
'label' => __( 'Sale price', 'woocommerce' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Description', 'woocommerce' ),
|
||||
'description' => __( 'What makes this product unique? What are its most important features? Enrich the product page by adding rich content using blocks.', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-description-field',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Images', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Images guide link opening tag. %2$s: Images guide link closing tag.*/
|
||||
__( 'Drag images, upload new ones or select files from your library. For best results, use JPEG files that are 1000 by 1000 pixels or larger. %1$sHow to prepare images?%2$s', 'woocommerce' ),
|
||||
'<a href="http://woocommerce.com/#" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-images-field',
|
||||
array(
|
||||
'images' => array(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-tab',
|
||||
array(
|
||||
'id' => 'organization',
|
||||
'title' => __( 'Organization', 'woocommerce' ),
|
||||
'order' => 15,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Product catalog', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-category-field',
|
||||
array(
|
||||
'name' => 'categories',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-catalog-visibility-field',
|
||||
array(
|
||||
'label' => __( 'Hide in product catalog', 'woocommerce' ),
|
||||
'visibilty' => 'search',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-catalog-visibility-field',
|
||||
array(
|
||||
'label' => __( 'Hide from search results', 'woocommerce' ),
|
||||
'visibilty' => 'catalog',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-checkbox-field',
|
||||
array(
|
||||
'label' => __( 'Enable product reviews', 'woocommerce' ),
|
||||
'property' => 'reviews_allowed',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-password-field',
|
||||
array(
|
||||
'label' => __( 'Require a password', 'woocommerce' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Attributes', 'woocommerce' ),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-attributes-field',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-tab',
|
||||
array(
|
||||
'id' => 'pricing',
|
||||
'title' => __( 'Pricing', 'woocommerce' ),
|
||||
'order' => 20,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-has-variations-notice',
|
||||
array(
|
||||
'id' => 'wc-product-notice-has-options',
|
||||
'content' => __( 'This product has options, such as size or color. You can now manage each variation\'s price and other details individually.', 'woocommerce' ),
|
||||
'buttonText' => __( 'Go to Variations', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Pricing', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Images guide link opening tag. %2$s: Images guide link closing tag.*/
|
||||
__( 'Set a competitive price, put the product on sale, and manage tax calculations. %1$sHow to price your product?%2$s', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-price-products-strategies-expert-tips/" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'blockGap' => 'unit-40',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(),
|
||||
array(
|
||||
array(
|
||||
'core/columns',
|
||||
array(),
|
||||
array(
|
||||
array(
|
||||
'core/column',
|
||||
array(
|
||||
'templateLock' => 'all',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-regular-price-field',
|
||||
array(
|
||||
'name' => 'regular_price',
|
||||
'label' => __( 'List price', 'woocommerce' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'core/column',
|
||||
array(
|
||||
'templateLock' => 'all',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-sale-price-field',
|
||||
array(
|
||||
'label' => __( 'Sale price', 'woocommerce' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-schedule-sale-fields',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-radio-field',
|
||||
array(
|
||||
'title' => __( 'Charge sales tax on', 'woocommerce' ),
|
||||
'property' => 'tax_status',
|
||||
'options' => array(
|
||||
array(
|
||||
'label' => __( 'Product and shipping', 'woocommerce' ),
|
||||
'value' => 'taxable',
|
||||
),
|
||||
array(
|
||||
'label' => __( 'Only shipping', 'woocommerce' ),
|
||||
'value' => 'shipping',
|
||||
),
|
||||
array(
|
||||
'label' => __( "Don't charge tax", 'woocommerce' ),
|
||||
'value' => 'none',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-collapsible',
|
||||
array(
|
||||
'toggleText' => __( 'Advanced', 'woocommerce' ),
|
||||
'initialCollapsed' => true,
|
||||
'persistRender' => true,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-radio-field',
|
||||
array(
|
||||
'title' => __( 'Tax class', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Learn more link opening tag. %2$s: Learn more link closing tag.*/
|
||||
__( 'Apply a tax rate if this product qualifies for tax reduction or exemption. %1$sLearn more%2$s.', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/document/setting-up-taxes-in-woocommerce/#shipping-tax-class" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'property' => 'tax_class',
|
||||
'options' => array(
|
||||
array(
|
||||
'label' => __( 'Standard', 'woocommerce' ),
|
||||
'value' => '',
|
||||
),
|
||||
array(
|
||||
'label' => __( 'Reduced rate', 'woocommerce' ),
|
||||
'value' => 'reduced-rate',
|
||||
),
|
||||
array(
|
||||
'label' => __( 'Zero rate', 'woocommerce' ),
|
||||
'value' => 'zero-rate',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-tab',
|
||||
array(
|
||||
'id' => 'inventory',
|
||||
'title' => __( 'Inventory', 'woocommerce' ),
|
||||
'order' => 30,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-has-variations-notice',
|
||||
array(
|
||||
'id' => 'wc-product-notice-has-options',
|
||||
'content' => __( 'This product has options, such as size or color. You can now manage each variation\'s price and other details individually.', 'woocommerce' ),
|
||||
'buttonText' => __( 'Go to Variations', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Inventory', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Inventory settings link opening tag. %2$s: Inventory settings link closing tag.*/
|
||||
__( 'Set up and manage inventory for this product, including status and available quantity. %1$sManage store inventory settings%2$s', 'woocommerce' ),
|
||||
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' ) . '" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'blockGap' => 'unit-40',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-sku-field',
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-toggle-field',
|
||||
array(
|
||||
'label' => __( 'Track stock quantity for this product', 'woocommerce' ),
|
||||
'property' => 'manage_stock',
|
||||
'disabled' => 'yes' !== get_option( 'woocommerce_manage_stock' ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/conditional',
|
||||
array(
|
||||
'mustMatch' => array(
|
||||
'manage_stock' => array( true ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-inventory-quantity-field',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/conditional',
|
||||
array(
|
||||
'mustMatch' => array(
|
||||
'manage_stock' => array( false ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-radio-field',
|
||||
array(
|
||||
'title' => __( 'Stock status', 'woocommerce' ),
|
||||
'property' => 'stock_status',
|
||||
'options' => array(
|
||||
array(
|
||||
'label' => __( 'In stock', 'woocommerce' ),
|
||||
'value' => 'instock',
|
||||
),
|
||||
array(
|
||||
'label' => __( 'Out of stock', 'woocommerce' ),
|
||||
'value' => 'outofstock',
|
||||
),
|
||||
array(
|
||||
'label' => __( 'On backorder', 'woocommerce' ),
|
||||
'value' => 'onbackorder',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-collapsible',
|
||||
array(
|
||||
'toggleText' => __( 'Advanced', 'woocommerce' ),
|
||||
'initialCollapsed' => true,
|
||||
'persistRender' => true,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'blockGap' => 'unit-40',
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/conditional',
|
||||
array(
|
||||
'mustMatch' => array(
|
||||
'manage_stock' => array( true ),
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-radio-field',
|
||||
array(
|
||||
'title' => __( 'When out of stock', 'woocommerce' ),
|
||||
'property' => 'backorders',
|
||||
'options' => array(
|
||||
array(
|
||||
'label' => __( 'Allow purchases', 'woocommerce' ),
|
||||
'value' => 'yes',
|
||||
),
|
||||
array(
|
||||
'label' => __(
|
||||
'Allow purchases, but notify customers',
|
||||
'woocommerce'
|
||||
),
|
||||
'value' => 'notify',
|
||||
),
|
||||
array(
|
||||
'label' => __( "Don't allow purchases", 'woocommerce' ),
|
||||
'value' => 'no',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-inventory-email-field',
|
||||
),
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-checkbox-field',
|
||||
array(
|
||||
'title' => __(
|
||||
'Restrictions',
|
||||
'woocommerce'
|
||||
),
|
||||
'label' => __(
|
||||
'Limit purchases to 1 item per order',
|
||||
'woocommerce'
|
||||
),
|
||||
'property' => 'sold_individually',
|
||||
'tooltip' => __(
|
||||
'When checked, customers will be able to purchase only 1 item in a single order. This is particularly useful for items that have limited quantity, like art or handmade goods.',
|
||||
'woocommerce'
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-tab',
|
||||
array(
|
||||
'id' => 'shipping',
|
||||
'title' => __( 'Shipping', 'woocommerce' ),
|
||||
'order' => 40,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-has-variations-notice',
|
||||
array(
|
||||
'id' => 'wc-product-notice-has-options',
|
||||
'content' => __( 'This product has options, such as size or color. You can now manage each variation\'s price and other details individually.', 'woocommerce' ),
|
||||
'buttonText' => __( 'Go to Variations', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Fees & dimensions', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: How to get started? link opening tag. %2$s: How to get started? link closing tag.*/
|
||||
__( 'Set up shipping costs and enter dimensions used for accurate rate calculations. %1$sHow to get started?%2$s.', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-calculate-shipping-costs-for-your-woocommerce-store/" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-shipping-class-field',
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-shipping-dimensions-fields',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
if ( Features::is_enabled( 'product-variation-management' ) ) {
|
||||
array_push(
|
||||
$args['template'],
|
||||
array(
|
||||
'woocommerce/product-tab',
|
||||
array(
|
||||
'id' => 'variations',
|
||||
'title' => __( 'Variations', 'woocommerce' ),
|
||||
'order' => 40,
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-variations-fields',
|
||||
array(
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Sell your product in multiple variations like size or color. strong opening tag. %2$s: Sell your product in multiple variations like size or color. strong closing tag.*/
|
||||
__( '%1$sSell your product in multiple variations like size or color.%2$s Get started by adding options for the buyers to choose on the product page.', 'woocommerce' ),
|
||||
'<strong>',
|
||||
'</strong>'
|
||||
),
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Variation options', 'woocommerce' ),
|
||||
),
|
||||
array( array( 'woocommerce/product-variations-options-field' ) ),
|
||||
),
|
||||
array(
|
||||
'woocommerce/product-section',
|
||||
array(
|
||||
'title' => __( 'Variations', 'woocommerce' ),
|
||||
),
|
||||
array( array( 'woocommerce/product-variation-items-field' ) ),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
$args['template'] = $this->simple_product_template->get_formatted_template();
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\AbstractBlockTemplate;
|
||||
|
||||
/**
|
||||
* Block template class.
|
||||
*/
|
||||
abstract class AbstractProductFormTemplate extends AbstractBlockTemplate implements ProductFormTemplateInterface {
|
||||
/**
|
||||
* Get a group block by ID.
|
||||
*
|
||||
* @param string $group_id The group block ID.
|
||||
* @throws \UnexpectedValueException If block is not of type GroupInterface.
|
||||
*/
|
||||
public function get_group_by_id( string $group_id ): ?GroupInterface {
|
||||
$group = $this->get_block( $group_id );
|
||||
if ( $group && ! $group instanceof GroupInterface ) {
|
||||
throw new \UnexpectedValueException( 'Block with specified ID is not a group.' );
|
||||
}
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a section block by ID.
|
||||
*
|
||||
* @param string $section_id The section block ID.
|
||||
* @throws \UnexpectedValueException If block is not of type SectionInterface.
|
||||
*/
|
||||
public function get_section_by_id( string $section_id ): ?SectionInterface {
|
||||
$section = $this->get_block( $section_id );
|
||||
if ( $section && ! $section instanceof SectionInterface ) {
|
||||
throw new \UnexpectedValueException( 'Block with specified ID is not a section.' );
|
||||
}
|
||||
return $section;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a block by ID.
|
||||
*
|
||||
* @param string $block_id The block block ID.
|
||||
*/
|
||||
public function get_block_by_id( string $block_id ): ?BlockInterface {
|
||||
return $this->get_block( $block_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom block type to this template.
|
||||
*
|
||||
* @param array $block_config The block data.
|
||||
*/
|
||||
public function add_group( array $block_config ): GroupInterface {
|
||||
$block = new Group( $block_config, $this->get_root_template(), $this );
|
||||
return $this->add_inner_block( $block );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
/**
|
||||
* WooCommerce Product Group Block class.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockTemplateInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\ContainerInterface;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\BlockContainerTrait;
|
||||
|
||||
/**
|
||||
* Class for Group block.
|
||||
*/
|
||||
class Group extends ProductBlock implements GroupInterface {
|
||||
use BlockContainerTrait;
|
||||
|
||||
/**
|
||||
* Group Block constructor.
|
||||
*
|
||||
* @param array $config The block configuration.
|
||||
* @param BlockTemplateInterface $root_template The block template that this block belongs to.
|
||||
* @param ContainerInterface|null $parent The parent block container.
|
||||
*
|
||||
* @throws \ValueError If the block configuration is invalid.
|
||||
* @throws \ValueError If the parent block container does not belong to the same template as the block.
|
||||
* @throws \InvalidArgumentException If blockName key and value are passed into block configuration.
|
||||
*/
|
||||
public function __construct( array $config, BlockTemplateInterface &$root_template, ContainerInterface &$parent = null ) {
|
||||
if ( ! empty( $config['blockName'] ) ) {
|
||||
throw new \InvalidArgumentException( 'Unexpected key "blockName", this defaults to "woocommerce/product-tab".' );
|
||||
}
|
||||
if ( $config['id'] && ( empty( $config['attributes'] ) || empty( $config['attributes']['id'] ) ) ) {
|
||||
$config['attributes'] = empty( $config['attributes'] ) ? [] : $config['attributes'];
|
||||
$config['attributes']['id'] = $config['id'];
|
||||
}
|
||||
parent::__construct( array_merge( array( 'blockName' => 'woocommerce/product-tab' ), $config ), $root_template, $parent );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a section block type to this template.
|
||||
*
|
||||
* @param array $block_config The block data.
|
||||
*/
|
||||
public function add_section( array $block_config ): SectionInterface {
|
||||
$block = new Section( $block_config, $this->get_root_template(), $this );
|
||||
return $this->add_inner_block( $block );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockContainerInterface;
|
||||
|
||||
/**
|
||||
* Interface for block containers.
|
||||
*/
|
||||
interface GroupInterface extends BlockContainerInterface {
|
||||
|
||||
/**
|
||||
* Adds a new section block.
|
||||
*
|
||||
* @param array $block_config block config.
|
||||
* @return SectionInterface new block section.
|
||||
*/
|
||||
public function add_section( array $block_config ): SectionInterface;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
/**
|
||||
* WooCommerce Product Block class.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\ContainerInterface;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\AbstractBlock;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\BlockContainerTrait;
|
||||
|
||||
/**
|
||||
* Class for Product block.
|
||||
*/
|
||||
class ProductBlock extends AbstractBlock implements ContainerInterface {
|
||||
use BlockContainerTrait;
|
||||
/**
|
||||
* Adds block to the section block.
|
||||
*
|
||||
* @param array $block_config The block data.
|
||||
*/
|
||||
public function &add_block( array $block_config ): BlockInterface {
|
||||
$block = new ProductBlock( $block_config, $this->get_root_template(), $this );
|
||||
return $this->add_inner_block( $block );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockTemplateInterface;
|
||||
|
||||
/**
|
||||
* Interface for block containers.
|
||||
*/
|
||||
interface ProductFormTemplateInterface extends BlockTemplateInterface {
|
||||
|
||||
/**
|
||||
* Adds a new group block.
|
||||
*
|
||||
* @param array $block_config block config.
|
||||
* @return BlockInterface new block section.
|
||||
*/
|
||||
public function add_group( array $block_config ): GroupInterface;
|
||||
|
||||
/**
|
||||
* Gets Group block by id.
|
||||
*
|
||||
* @param string $group_id group id.
|
||||
* @return GroupInterface|null
|
||||
*/
|
||||
public function get_group_by_id( string $group_id ): ?GroupInterface;
|
||||
|
||||
/**
|
||||
* Gets Section block by id.
|
||||
*
|
||||
* @param string $section_id section id.
|
||||
* @return SectionInterface|null
|
||||
*/
|
||||
public function get_section_by_id( string $section_id ): ?SectionInterface;
|
||||
|
||||
/**
|
||||
* Gets Block by id.
|
||||
*
|
||||
* @param string $block_id block id.
|
||||
* @return BlockInterface|null
|
||||
*/
|
||||
public function get_block_by_id( string $block_id ): ?BlockInterface;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
/**
|
||||
* WooCommerce Section Block class.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockTemplateInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class for Section block.
|
||||
*/
|
||||
class Section extends ProductBlock implements SectionInterface {
|
||||
|
||||
/**
|
||||
* Section Block constructor.
|
||||
*
|
||||
* @param array $config The block configuration.
|
||||
* @param BlockTemplateInterface $root_template The block template that this block belongs to.
|
||||
* @param ContainerInterface|null $parent The parent block container.
|
||||
*
|
||||
* @throws \ValueError If the block configuration is invalid.
|
||||
* @throws \ValueError If the parent block container does not belong to the same template as the block.
|
||||
* @throws \InvalidArgumentException If blockName key and value are passed into block configuration.
|
||||
*/
|
||||
public function __construct( array $config, BlockTemplateInterface &$root_template, ContainerInterface &$parent = null ) {
|
||||
if ( ! empty( $config['blockName'] ) ) {
|
||||
throw new \InvalidArgumentException( 'Unexpected key "blockName", this defaults to "woocommerce/product-section".' );
|
||||
}
|
||||
parent::__construct( array_merge( array( 'blockName' => 'woocommerce/product-section' ), $config ), $root_template, $parent );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a section block type to this template.
|
||||
*
|
||||
* @param array $block_config The block data.
|
||||
*/
|
||||
public function add_section( array $block_config ): SectionInterface {
|
||||
$block = new Section( $block_config, $this->get_root_template(), $this );
|
||||
return $this->add_inner_block( $block );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockContainerInterface;
|
||||
|
||||
/**
|
||||
* Interface for block containers.
|
||||
*/
|
||||
interface SectionInterface extends BlockContainerInterface {
|
||||
|
||||
/**
|
||||
* Adds a new section block.
|
||||
*
|
||||
* @param array $block_config block config.
|
||||
* @return SectionInterface new block section.
|
||||
*/
|
||||
public function add_section( array $block_config ): SectionInterface;
|
||||
}
|
|
@ -0,0 +1,754 @@
|
|||
<?php
|
||||
/**
|
||||
* SimpleProductTemplate
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
|
||||
/**
|
||||
* Simple Product Template.
|
||||
*/
|
||||
class SimpleProductTemplate extends AbstractProductFormTemplate implements ProductFormTemplateInterface {
|
||||
/**
|
||||
* The context name used to identify the editor.
|
||||
*/
|
||||
const GROUP_IDS = array(
|
||||
'GENERAL' => 'general',
|
||||
'ORGANIZATION' => 'organization',
|
||||
'PRICING' => 'pricing',
|
||||
'INVENTORY' => 'inventory',
|
||||
'SHIPPING' => 'shipping',
|
||||
'VARIATIONS' => 'variations',
|
||||
);
|
||||
|
||||
/**
|
||||
* SimpleProductTemplate constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->add_group_blocks();
|
||||
$this->add_general_group_blocks();
|
||||
$this->add_organization_group_blocks();
|
||||
$this->add_pricing_group_blocks();
|
||||
$this->add_inventory_group_blocks();
|
||||
$this->add_shipping_group_blocks();
|
||||
$this->add_variation_group_blocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template ID.
|
||||
*/
|
||||
public function get_id(): string {
|
||||
return 'simple-product';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template title.
|
||||
*/
|
||||
public function get_title(): string {
|
||||
return __( 'Simple Product Template', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template description.
|
||||
*/
|
||||
public function get_description(): string {
|
||||
return __( 'Template for the simple product form', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the group blocks to the template.
|
||||
*/
|
||||
private function add_group_blocks() {
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['GENERAL'],
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'General', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['ORGANIZATION'],
|
||||
'order' => 15,
|
||||
'attributes' => [
|
||||
'title' => __( 'Organization', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['PRICING'],
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Pricing', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['INVENTORY'],
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'title' => __( 'Inventory', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['SHIPPING'],
|
||||
'order' => 40,
|
||||
'attributes' => [
|
||||
'title' => __( 'Shipping', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
if ( Features::is_enabled( 'product-variation-management' ) ) {
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['VARIATIONS'],
|
||||
'order' => 50,
|
||||
'attributes' => [
|
||||
'title' => __( 'Variations', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the general group blocks to the template.
|
||||
*/
|
||||
private function add_general_group_blocks() {
|
||||
$general_group = $this->get_group_by_id( $this::GROUP_IDS['GENERAL'] );
|
||||
// Basic Details Section.
|
||||
$basic_details = $general_group->add_section(
|
||||
[
|
||||
'id' => 'basic-details',
|
||||
'attributes' => [
|
||||
'title' => __( 'Basic details', 'woocommerce' ),
|
||||
'description' => __( 'This info will be displayed on the product page, category pages, social media, and search results.', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$basic_details->add_block(
|
||||
[
|
||||
'id' => 'product-name',
|
||||
'blockName' => 'woocommerce/product-name-field',
|
||||
'attributes' => [
|
||||
'name' => 'Product name',
|
||||
'autoFocus' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
$basic_details->add_block(
|
||||
[
|
||||
'id' => 'product-summary',
|
||||
'blockName' => 'woocommerce/product-summary-field',
|
||||
]
|
||||
);
|
||||
$pricing_columns = $basic_details->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-columns',
|
||||
'blockName' => 'core/columns',
|
||||
]
|
||||
);
|
||||
$pricing_column_1 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-column-1',
|
||||
'blockName' => 'core/column',
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_1->add_block(
|
||||
[
|
||||
'id' => 'product-regular-price',
|
||||
'blockName' => 'woocommerce/product-regular-price-field',
|
||||
'attributes' => [
|
||||
'name' => 'regular_price',
|
||||
'label' => __( 'List price', 'woocommerce' ),
|
||||
/* translators: PricingTab: This is a link tag to the pricing tab. */
|
||||
'help' => __( 'Manage more settings in <PricingTab>Pricing.</PricingTab>', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-column-2',
|
||||
'blockName' => 'core/column',
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2->add_block(
|
||||
[
|
||||
'id' => 'product-sale-price',
|
||||
'blockName' => 'woocommerce/product-sale-price-field',
|
||||
'attributes' => [
|
||||
'label' => __( 'Sale price', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
// Description section.
|
||||
$description_section = $general_group->add_section(
|
||||
[
|
||||
'id' => 'product-description-section',
|
||||
'attributes' => [
|
||||
'title' => __( 'Description', 'woocommerce' ),
|
||||
'description' => __( 'What makes this product unique? What are its most important features? Enrich the product page by adding rich content using blocks.', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$description_section->add_block(
|
||||
[
|
||||
'id' => 'product-description',
|
||||
'blockName' => 'woocommerce/product-description-field',
|
||||
]
|
||||
);
|
||||
// Images section.
|
||||
$images_section = $general_group->add_section(
|
||||
[
|
||||
'id' => 'product-images-section',
|
||||
'attributes' => [
|
||||
'title' => __( 'Images', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Images guide link opening tag. %2$s: Images guide link closing tag. */
|
||||
__( 'Drag images, upload new ones or select files from your library. For best results, use JPEG files that are 1000 by 1000 pixels or larger. %1$sHow to prepare images?%2$s', 'woocommerce' ),
|
||||
'<a href="http://woocommerce.com/#" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$images_section->add_block(
|
||||
[
|
||||
'id' => 'product-images',
|
||||
'blockName' => 'woocommerce/product-images-field',
|
||||
'attributes' => [
|
||||
'images' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the organization group blocks to the template.
|
||||
*/
|
||||
private function add_organization_group_blocks() {
|
||||
$organization_group = $this->get_group_by_id( $this::GROUP_IDS['ORGANIZATION'] );
|
||||
// Product Catalog Section.
|
||||
$product_catalog_section = $organization_group->add_section(
|
||||
[
|
||||
'id' => 'product-catalog-section',
|
||||
'attributes' => [
|
||||
'title' => __( 'Product catalog', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-categories',
|
||||
'blockName' => 'woocommerce/product-category-field',
|
||||
'attributes' => [
|
||||
'name' => 'categories',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-catalog-search-visibility',
|
||||
'blockName' => 'woocommerce/product-catalog-visibility-field',
|
||||
'attributes' => [
|
||||
'label' => __( 'Hide in product catalog', 'woocommerce' ),
|
||||
'visibility' => 'search',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-catalog-catalog-visibility',
|
||||
'blockName' => 'woocommerce/product-catalog-visibility-field',
|
||||
'attributes' => [
|
||||
'label' => __( 'Hide from search results', 'woocommerce' ),
|
||||
'visibility' => 'catalog',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-enable-product-reviews',
|
||||
'blockName' => 'woocommerce/product-checkbox-field',
|
||||
'attributes' => [
|
||||
'label' => __( 'Enable product reviews', 'woocommerce' ),
|
||||
'property' => 'reviews_allowed',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-post-password',
|
||||
'blockName' => 'woocommerce/product-password-field',
|
||||
'attributes' => [
|
||||
'label' => __( 'Require a password', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
// Attributes section.
|
||||
$product_catalog_section = $organization_group->add_section(
|
||||
[
|
||||
'id' => 'product-attributes-section',
|
||||
'attributes' => [
|
||||
'title' => __( 'Attributes', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-attributes',
|
||||
'blockName' => 'woocommerce/product-attributes-field',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the pricing group blocks to the template.
|
||||
*/
|
||||
private function add_pricing_group_blocks() {
|
||||
$pricing_group = $this->get_group_by_id( $this::GROUP_IDS['PRICING'] );
|
||||
$pricing_group->add_block(
|
||||
[
|
||||
'id' => 'pricing-has-variations-notice',
|
||||
'blockName' => 'woocommerce/product-has-variations-notice',
|
||||
'attributes' => [
|
||||
'content' => __( 'This product has options, such as size or color. You can now manage each variation\'s price and other details individually.', 'woocommerce' ),
|
||||
'buttonText' => __( 'Go to Variations', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
],
|
||||
]
|
||||
);
|
||||
// Product Pricing Section.
|
||||
$product_pricing_section = $pricing_group->add_section(
|
||||
[
|
||||
'id' => 'product-pricing-section',
|
||||
'attributes' => [
|
||||
'title' => __( 'Pricing', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Images guide link opening tag. %2$s: Images guide link closing tag.*/
|
||||
__( 'Set a competitive price, put the product on sale, and manage tax calculations. %1$sHow to price your product?%2$s', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-price-products-strategies-expert-tips/" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'blockGap' => 'unit-40',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_columns = $product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-columns',
|
||||
'blockName' => 'core/columns',
|
||||
]
|
||||
);
|
||||
$pricing_column_1 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-column-1',
|
||||
'blockName' => 'core/column',
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_1->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-regular-price',
|
||||
'blockName' => 'woocommerce/product-regular-price-field',
|
||||
'attributes' => [
|
||||
'name' => 'regular_price',
|
||||
'label' => __( 'List price', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-column-2',
|
||||
'blockName' => 'core/column',
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-sale-price',
|
||||
'blockName' => 'woocommerce/product-sale-price-field',
|
||||
'attributes' => [
|
||||
'label' => __( 'Sale price', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-schedule-sale-fields',
|
||||
'blockName' => 'woocommerce/product-schedule-sale-fields',
|
||||
]
|
||||
);
|
||||
$product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-sale-tax',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'attributes' => [
|
||||
'title' => __( 'Charge sales tax on', 'woocommerce' ),
|
||||
'property' => 'tax_status',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'Product and shipping', 'woocommerce' ),
|
||||
'value' => 'taxable',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Only shipping', 'woocommerce' ),
|
||||
'value' => 'shipping',
|
||||
],
|
||||
[
|
||||
'label' => __( "Don't charge tax", 'woocommerce' ),
|
||||
'value' => 'none',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_advanced_block = $product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-advanced',
|
||||
'blockName' => 'woocommerce/product-collapsible',
|
||||
'attributes' => [
|
||||
'toggleText' => __( 'Advanced', 'woocommerce' ),
|
||||
'initialCollapsed' => true,
|
||||
'persistRender' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_advanced_block->add_block(
|
||||
[
|
||||
'id' => 'product-tax-class',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'attributes' => [
|
||||
'title' => __( 'Tax class', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Learn more link opening tag. %2$s: Learn more link closing tag.*/
|
||||
__( 'Apply a tax rate if this product qualifies for tax reduction or exemption. %1$sLearn more%2$s.', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/document/setting-up-taxes-in-woocommerce/#shipping-tax-class" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'property' => 'tax_class',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'Standard', 'woocommerce' ),
|
||||
'value' => '',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Reduced rate', 'woocommerce' ),
|
||||
'value' => 'reduced-rate',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Zero rate', 'woocommerce' ),
|
||||
'value' => 'zero-rate',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the inventory group blocks to the template.
|
||||
*/
|
||||
private function add_inventory_group_blocks() {
|
||||
$inventory_group = $this->get_group_by_id( $this::GROUP_IDS['INVENTORY'] );
|
||||
$inventory_group->add_block(
|
||||
[
|
||||
'id' => 'product_variation_notice_inventory_tab',
|
||||
'blockName' => 'woocommerce/product-has-variations-notice',
|
||||
'attributes' => [
|
||||
'content' => __( 'This product has options, such as size or color. You can now manage each variation\'s price and other details individually.', 'woocommerce' ),
|
||||
'buttonText' => __( 'Go to Variations', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
],
|
||||
]
|
||||
);
|
||||
// Product Pricing Section.
|
||||
$product_inventory_section = $inventory_group->add_section(
|
||||
[
|
||||
'id' => 'product-inventory-section',
|
||||
'attributes' => [
|
||||
'title' => __( 'Inventory', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Inventory settings link opening tag. %2$s: Inventory settings link closing tag.*/
|
||||
__( 'Set up and manage inventory for this product, including status and available quantity. %1$sManage store inventory settings%2$s', 'woocommerce' ),
|
||||
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' ) . '" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'blockGap' => 'unit-40',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_inner_section = $product_inventory_section->add_section(
|
||||
[
|
||||
'id' => 'product-inventory-inner-section',
|
||||
]
|
||||
);
|
||||
$product_inventory_inner_section->add_block(
|
||||
[
|
||||
'id' => 'product-sku-field',
|
||||
'blockName' => 'woocommerce/product-sku-field',
|
||||
]
|
||||
);
|
||||
$product_inventory_inner_section->add_block(
|
||||
[
|
||||
'id' => 'product-track-stock',
|
||||
'blockName' => 'woocommerce/product-toggle-field',
|
||||
'attributes' => [
|
||||
'label' => __( 'Track stock quantity for this product', 'woocommerce' ),
|
||||
'property' => 'manage_stock',
|
||||
'disabled' => 'yes' !== get_option( 'woocommerce_manage_stock' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_quantity_conditional = $product_inventory_inner_section->add_block(
|
||||
[
|
||||
'id' => 'product-inventory-quantity-conditional-wrapper',
|
||||
'blockName' => 'woocommerce/conditional',
|
||||
'attributes' => [
|
||||
'mustMatch' => [
|
||||
'manage_stock' => [ true ],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_quantity_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-inventory-quantity',
|
||||
'blockName' => 'woocommerce/product-inventory-quantity-field',
|
||||
]
|
||||
);
|
||||
$product_stock_status_conditional = $product_inventory_section->add_block(
|
||||
[
|
||||
'id' => 'product-stock-status-conditional-wrapper',
|
||||
'blockName' => 'woocommerce/conditional',
|
||||
'attributes' => [
|
||||
'mustMatch' => [
|
||||
'manage_stock' => [ false ],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_stock_status_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-stock-status',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'attributes' => [
|
||||
'title' => __( 'Stock status', 'woocommerce' ),
|
||||
'property' => 'stock_status',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'In stock', 'woocommerce' ),
|
||||
'value' => 'instock',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Out of stock', 'woocommerce' ),
|
||||
'value' => 'outofstock',
|
||||
],
|
||||
[
|
||||
'label' => __( 'On backorder', 'woocommerce' ),
|
||||
'value' => 'onbackorder',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_advanced = $product_inventory_section->add_block(
|
||||
[
|
||||
'id' => 'product-inventory-advanced',
|
||||
'blockName' => 'woocommerce/product-collapsible',
|
||||
'attributes' => [
|
||||
'toggleText' => __( 'Advanced', 'woocommerce' ),
|
||||
'initialCollapsed' => true,
|
||||
'persistRender' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_advanced_wrapper = $product_inventory_advanced->add_block(
|
||||
[
|
||||
'blockName' => 'woocommerce/product-section',
|
||||
'attributes' => [
|
||||
'blockGap' => 'unit-40',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_out_of_stock_conditional = $product_inventory_advanced_wrapper->add_block(
|
||||
[
|
||||
'id' => 'product-out-of-stock-conditional-wrapper',
|
||||
'blockName' => 'woocommerce/conditional',
|
||||
'attributes' => [
|
||||
'mustMatch' => [
|
||||
'manage_stock' => [ true ],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_out_of_stock_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-out-of-stock',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'attributes' => [
|
||||
'title' => __( 'When out of stock', 'woocommerce' ),
|
||||
'property' => 'backorders',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'Allow purchases', 'woocommerce' ),
|
||||
'value' => 'yes',
|
||||
],
|
||||
[
|
||||
'label' => __(
|
||||
'Allow purchases, but notify customers',
|
||||
'woocommerce'
|
||||
),
|
||||
'value' => 'notify',
|
||||
],
|
||||
[
|
||||
'label' => __( "Don't allow purchases", 'woocommerce' ),
|
||||
'value' => 'no',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_out_of_stock_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-inventory-email',
|
||||
'blockName' => 'woocommerce/product-inventory-email-field',
|
||||
]
|
||||
);
|
||||
|
||||
$product_inventory_advanced_wrapper->add_block(
|
||||
[
|
||||
'id' => 'product-limit-purchase',
|
||||
'blockName' => 'woocommerce/product-checkbox-field',
|
||||
'attributes' => [
|
||||
'title' => __(
|
||||
'Restrictions',
|
||||
'woocommerce'
|
||||
),
|
||||
'label' => __(
|
||||
'Limit purchases to 1 item per order',
|
||||
'woocommerce'
|
||||
),
|
||||
'property' => 'sold_individually',
|
||||
'tooltip' => __(
|
||||
'When checked, customers will be able to purchase only 1 item in a single order. This is particularly useful for items that have limited quantity, like art or handmade goods.',
|
||||
'woocommerce'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the shipping group blocks to the template.
|
||||
*/
|
||||
private function add_shipping_group_blocks() {
|
||||
$shipping_group = $this->get_group_by_id( $this::GROUP_IDS['SHIPPING'] );
|
||||
$shipping_group->add_block(
|
||||
[
|
||||
'id' => 'product_variation_notice_shipping_tab',
|
||||
'blockName' => 'woocommerce/product-has-variations-notice',
|
||||
'attributes' => [
|
||||
'content' => __( 'This product has options, such as size or color. You can now manage each variation\'s price and other details individually.', 'woocommerce' ),
|
||||
'buttonText' => __( 'Go to Variations', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
],
|
||||
]
|
||||
);
|
||||
// Product Pricing Section.
|
||||
$product_fee_and_dimensions_section = $shipping_group->add_section(
|
||||
[
|
||||
'id' => 'product-fee-and-dimensions-section',
|
||||
'attributes' => [
|
||||
'title' => __( 'Fees & dimensions', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: How to get started? link opening tag. %2$s: How to get started? link closing tag.*/
|
||||
__( 'Set up shipping costs and enter dimensions used for accurate rate calculations. %1$sHow to get started?%2$s.', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-calculate-shipping-costs-for-your-woocommerce-store/" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_fee_and_dimensions_section->add_block(
|
||||
[
|
||||
'id' => 'product-shipping-class',
|
||||
'blockName' => 'woocommerce/product-shipping-class-field',
|
||||
]
|
||||
);
|
||||
$product_fee_and_dimensions_section->add_block(
|
||||
[
|
||||
'id' => 'product-shipping-dimensions',
|
||||
'blockName' => 'woocommerce/product-shipping-dimensions-fields',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the variation group blocks to the template.
|
||||
*/
|
||||
private function add_variation_group_blocks() {
|
||||
$variation_group = $this->get_group_by_id( $this::GROUP_IDS['VARIATIONS'] );
|
||||
if ( ! $variation_group ) {
|
||||
return;
|
||||
}
|
||||
$variation_fields = $variation_group->add_block(
|
||||
[
|
||||
'id' => 'product_variation-field-group',
|
||||
'blockName' => 'woocommerce/product-variations-fields',
|
||||
'attributes' => [
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Sell your product in multiple variations like size or color. strong opening tag. %2$s: Sell your product in multiple variations like size or color. strong closing tag.*/
|
||||
__( '%1$sSell your product in multiple variations like size or color.%2$s Get started by adding options for the buyers to choose on the product page.', 'woocommerce' ),
|
||||
'<strong>',
|
||||
'</strong>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$variation_fields->add_block(
|
||||
[
|
||||
'id' => 'product-variation-options',
|
||||
'blockName' => 'woocommerce/product-variations-options-field',
|
||||
'attributes' => [
|
||||
'title' => __( 'Variation options', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$variation_section = $variation_fields->add_block(
|
||||
[
|
||||
'id' => 'product-variation-section',
|
||||
'blockName' => 'woocommerce/product-section',
|
||||
'attributes' => [
|
||||
'title' => __( 'Variations', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$variation_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-items',
|
||||
'blockName' => 'woocommerce/product-variation-items-field',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
namespace Automattic\WooCommerce\Internal\Admin\BlockTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\ContainerInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockTemplateInterface;
|
||||
|
||||
|
@ -15,7 +14,7 @@ abstract class AbstractBlockTemplate implements BlockTemplateInterface {
|
|||
/**
|
||||
* Get the template ID.
|
||||
*/
|
||||
public abstract function get_id(): string;
|
||||
abstract public function get_id(): string;
|
||||
|
||||
/**
|
||||
* Get the template title.
|
||||
|
@ -110,7 +109,7 @@ abstract class AbstractBlockTemplate implements BlockTemplateInterface {
|
|||
$inner_blocks = $this->get_inner_blocks_sorted_by_order();
|
||||
|
||||
$inner_blocks_formatted_template = array_map(
|
||||
function( Block $block ) {
|
||||
function( BlockInterface $block ) {
|
||||
return $block->get_formatted_template();
|
||||
},
|
||||
$inner_blocks
|
||||
|
|
|
@ -12,31 +12,6 @@ use Automattic\WooCommerce\Admin\BlockTemplates\BlockTemplateInterface;
|
|||
class Block extends AbstractBlock implements BlockContainerInterface {
|
||||
use BlockContainerTrait;
|
||||
|
||||
/**
|
||||
* Get the block configuration as a formatted template.
|
||||
*
|
||||
* @return array The block configuration as a formatted template.
|
||||
*/
|
||||
public function get_formatted_template(): array {
|
||||
$arr = [
|
||||
$this->get_name(),
|
||||
$this->get_attributes(),
|
||||
];
|
||||
|
||||
$inner_blocks = $this->get_inner_blocks_sorted_by_order();
|
||||
|
||||
if ( ! empty( $inner_blocks ) ) {
|
||||
$arr[] = array_map(
|
||||
function( BlockInterface $block ) {
|
||||
return $block->get_formatted_template();
|
||||
},
|
||||
$inner_blocks
|
||||
);
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an inner block to this block.
|
||||
*
|
||||
|
|
|
@ -52,7 +52,7 @@ trait BlockContainerTrait {
|
|||
|
||||
usort(
|
||||
$sorted_inner_blocks,
|
||||
function( Block $a, Block $b ) {
|
||||
function( BlockInterface $a, BlockInterface $b ) {
|
||||
return $a->get_order() <=> $b->get_order();
|
||||
}
|
||||
);
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Tests\Admin\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates\AbstractProductFormTemplate;
|
||||
use Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates\ProductFormTemplateInterface;
|
||||
|
||||
class CustomProductFormTemplate extends AbstractProductFormTemplate implements ProductFormTemplateInterface {
|
||||
/**
|
||||
* SimpleProductTemplate constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$general_group = $this->add_group(
|
||||
[
|
||||
'id' => 'general',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => 'General',
|
||||
],
|
||||
]
|
||||
);
|
||||
$basic_details = $general_group->add_section(
|
||||
[
|
||||
'id' => 'basic-details',
|
||||
'attributes' => [
|
||||
'title' => 'Basic details',
|
||||
'description' => 'Description',
|
||||
],
|
||||
]
|
||||
);
|
||||
$basic_details->add_block(
|
||||
[
|
||||
'id' => 'product-name',
|
||||
'blockName' => 'woocommerce/product-name-field',
|
||||
'attributes' => [
|
||||
'name' => 'Product name',
|
||||
'autoFocus' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_group = $this->add_group(
|
||||
[
|
||||
'id' => 'pricing',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => 'Pricing',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_pricing_section = $pricing_group->add_section(
|
||||
[
|
||||
'id' => 'product-pricing-section',
|
||||
'attributes' => [
|
||||
'title' => 'Pricing',
|
||||
'description' => '',
|
||||
'blockGap' => 'unit-40',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-columns',
|
||||
'blockName' => 'core/columns',
|
||||
]
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Get the template ID.
|
||||
*/
|
||||
public function get_id(): string {
|
||||
return 'custom-product';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template title.
|
||||
*/
|
||||
public function get_title(): string {
|
||||
return 'Custom Product Template';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Tests\Admin\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use WC_Unit_Test_Case;
|
||||
|
||||
/**
|
||||
* Tests for the CustomBlockTemplate class.
|
||||
*/
|
||||
class CustomProductFormTemplateTest extends WC_Unit_Test_Case {
|
||||
/**
|
||||
* Test getting the template ID.
|
||||
*/
|
||||
public function test_get_id() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
$this->assertEquals( $template->get_id(), 'custom-product' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get group block by id.
|
||||
*/
|
||||
public function test_get_group_by_id() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
$block = $template->get_group_by_id( 'general' );
|
||||
$this->assertEquals( $block->get_attributes()['title'], 'General' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test throw error get group block with section id.
|
||||
*/
|
||||
public function test_get_group_by_id_with_section_id() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
|
||||
$this->expectException( \UnexpectedValueException::class );
|
||||
$template->get_group_by_id('basic-details' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get section block by id.
|
||||
*/
|
||||
public function test_get_section_by_id() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
$block = $template->get_section_by_id( 'product-pricing-section' );
|
||||
$this->assertEquals( $block->get_attributes()['title'], 'Pricing' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test throw error get section block with section id.
|
||||
*/
|
||||
public function test_get_section_by_id_with_block_id() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
$this->expectException( \UnexpectedValueException::class );
|
||||
$template->get_section_by_id( 'product-pricing-group-pricing-columns' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get block by id.
|
||||
*/
|
||||
public function test_get_block_by_id() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
$block = $template->get_block_by_id( 'product-name' );
|
||||
$this->assertEquals( $block->get_attributes()['name'], 'Product name' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add custom block to section.
|
||||
*/
|
||||
public function test_add_custom_block_to_section() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
$block = $template->get_section_by_id( 'product-pricing-section' );
|
||||
$new_block = $block->add_block( [
|
||||
'id' => 'test-block-id',
|
||||
'blockName' => 'test-block-name',
|
||||
'attributes' => [
|
||||
'name' => 'A name'
|
||||
]
|
||||
] );
|
||||
|
||||
$this->assertEquals( $new_block->get_parent(), $block );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test add custom group.
|
||||
*/
|
||||
public function test_add_custom_group() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
$new_group = $template->add_group( [
|
||||
'id' => 'new-group',
|
||||
'order' => 0,
|
||||
'attributes' => [
|
||||
'title' => 'Group title'
|
||||
]
|
||||
] );
|
||||
|
||||
$this->assertEquals( $new_group->get_parent(), $template );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test throw error when passing blockName to add_group.
|
||||
*/
|
||||
public function test_passing_blockname_to_add_group() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
$this->expectException( \InvalidArgumentException::class );
|
||||
$template->add_group( [
|
||||
'id' => 'new-group',
|
||||
'blockName' => 'block-name',
|
||||
'order' => 0,
|
||||
'attributes' => [
|
||||
'title' => 'Group title'
|
||||
]
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test throw error when passing blockName to add_section.
|
||||
*/
|
||||
public function test_passing_blockname_to_add_section() {
|
||||
$template = new CustomProductFormTemplate();
|
||||
$group = $template->get_group_by_id( 'general' );
|
||||
$this->expectException( \InvalidArgumentException::class );
|
||||
$group->add_section( [
|
||||
'id' => 'new-section',
|
||||
'blockName' => 'block-name',
|
||||
'attributes' => [
|
||||
'title' => 'Section title'
|
||||
]
|
||||
] );
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue