Commit 3efc8b28d99 for woocommerce
commit 3efc8b28d997b5bd5e1cb5809bda4eb2a076402a
Author: Albert Juhé Lluveras <contact@albertjuhe.com>
Date: Wed Apr 29 16:54:25 2026 +0200
Add wc-visual attribute type to allow setting colors for attributes (#64324)
* Add wc-visual attribute type to allow setting colors for attributes
* Add changelog
* PHPStan
* Update test
* Remove unnecessary formatting changes
* Minor cleanups
* Make sure test is correctly reset
* Update comment
* Change default attribute label from Select to Text
* Add testdox annotation for visual attribute type registration test
* Don't delete attribute color when updating term programatically
* Fix attribute selector not showing up for wc-visual attributes
* Lint
* Add feature flag for wc-visual attribute type (#64344)
* Add feature flag for wc-visual attribute type
* Add changelog
* Rename the feature flag to use singular
* Linting
diff --git a/plugins/woocommerce/changelog/add-wc-visual-attribute-type-feature-flag b/plugins/woocommerce/changelog/add-wc-visual-attribute-type-feature-flag
new file mode 100644
index 00000000000..ad7d87dc717
--- /dev/null
+++ b/plugins/woocommerce/changelog/add-wc-visual-attribute-type-feature-flag
@@ -0,0 +1,5 @@
+Significance: patch
+Type: add
+Comment: Add feature flag for wc-visual attribute type
+
+
diff --git a/plugins/woocommerce/changelog/fix-add-wc-visual-attribute-type b/plugins/woocommerce/changelog/fix-add-wc-visual-attribute-type
new file mode 100644
index 00000000000..4a0a34a049a
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-add-wc-visual-attribute-type
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add wc-visual attribute type to allow setting colors for attributes
diff --git a/plugins/woocommerce/client/admin/config/core.json b/plugins/woocommerce/client/admin/config/core.json
index 83b2902f3b2..221e75c4bfa 100644
--- a/plugins/woocommerce/client/admin/config/core.json
+++ b/plugins/woocommerce/client/admin/config/core.json
@@ -39,6 +39,7 @@
"woo-mobile-welcome": true,
"wc-pay-promotion": true,
"wc-pay-welcome-page": true,
+ "wc-visual-attribute": false,
"async-product-editor-category-field": false,
"launch-your-store": true,
"product-editor-template-system": false,
diff --git a/plugins/woocommerce/client/admin/config/development.json b/plugins/woocommerce/client/admin/config/development.json
index b14ae52bab7..4605c0171d3 100644
--- a/plugins/woocommerce/client/admin/config/development.json
+++ b/plugins/woocommerce/client/admin/config/development.json
@@ -39,6 +39,7 @@
"woo-mobile-welcome": true,
"wc-pay-promotion": true,
"wc-pay-welcome-page": true,
+ "wc-visual-attribute": true,
"async-product-editor-category-field": true,
"launch-your-store": true,
"product-editor-template-system": false,
diff --git a/plugins/woocommerce/client/legacy/css/admin.scss b/plugins/woocommerce/client/legacy/css/admin.scss
index 931440c62eb..aa08c5ff83d 100644
--- a/plugins/woocommerce/client/legacy/css/admin.scss
+++ b/plugins/woocommerce/client/legacy/css/admin.scss
@@ -9585,3 +9585,14 @@ body.woocommerce-settings-payments-section_legacy {
background: #f0f0f1;
}
}
+
+.wc-admin-color-swatch {
+ display: inline-block;
+ vertical-align: middle;
+ vertical-align: center;
+ border: 1px solid #7e8993;
+ border-radius: 2px;
+ margin-right: 6px;
+ width: 12px;
+ height: 12px;
+}
diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-attributes.php b/plugins/woocommerce/includes/admin/class-wc-admin-attributes.php
index 2b5bf985b07..9157f2d5ca6 100644
--- a/plugins/woocommerce/includes/admin/class-wc-admin-attributes.php
+++ b/plugins/woocommerce/includes/admin/class-wc-admin-attributes.php
@@ -261,7 +261,7 @@ class WC_Admin_Attributes {
</td>
</tr>
<?php
- }
+ }//end if
?>
<tr class="form-field form-required">
<th scope="row" valign="top">
@@ -283,7 +283,9 @@ class WC_Admin_Attributes {
<p class="submit"><button type="submit" name="save_attribute" id="submit" class="button-primary" value="<?php esc_attr_e( 'Update', 'woocommerce' ); ?>"><?php esc_html_e( 'Update', 'woocommerce' ); ?></button></p>
<?php wp_nonce_field( 'woocommerce-save-attribute_' . $edit ); ?>
</form>
- <?php } ?>
+ <?php
+ }//end if
+ ?>
</div>
<?php
}
@@ -392,10 +394,10 @@ class WC_Admin_Attributes {
} else {
/* translators: %s: Total count of terms available for the attribute */
echo esc_html( sprintf( __( '%s terms', 'woocommerce' ), $total_count ) );
- }
+ }//end if
} else {
echo '<span class="na">–</span><br />';
- }
+ }//end if
?>
<br /><a href="edit-tags.php?taxonomy=<?php echo esc_attr( wc_attribute_taxonomy_name( $tax->attribute_name ) ); ?>&post_type=product" class="configure-terms"><?php esc_html_e( 'Configure terms', 'woocommerce' ); ?></a>
</td>
@@ -403,12 +405,13 @@ class WC_Admin_Attributes {
<?php
endforeach;
} else {
+ $column_count = wc_has_custom_attribute_types() ? '5' : '4';
?>
<tr>
- <td colspan="6"><?php esc_html_e( 'No attributes currently exist.', 'woocommerce' ); ?></td>
+ <td colspan="<?php echo esc_attr( $column_count ); ?>"><?php esc_html_e( 'No attributes currently exist.', 'woocommerce' ); ?></td>
</tr>
<?php
- }
+ }//end if
?>
</tbody>
</table>
@@ -469,7 +472,7 @@ class WC_Admin_Attributes {
<p class="description"><?php esc_html_e( "Determines how this attribute's values are displayed.", 'woocommerce' ); ?></p>
</div>
<?php
- }
+ }//end if
?>
<div class="form-field">
diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-taxonomies.php b/plugins/woocommerce/includes/admin/class-wc-admin-taxonomies.php
index 16d02bd44fb..1ccbce52456 100644
--- a/plugins/woocommerce/includes/admin/class-wc-admin-taxonomies.php
+++ b/plugins/woocommerce/includes/admin/class-wc-admin-taxonomies.php
@@ -53,7 +53,7 @@ class WC_Admin_Taxonomies {
add_action( 'create_term', array( $this, 'create_term' ), 5, 3 );
add_action(
'delete_product_cat',
- function() {
+ function () {
wc_get_container()->get( AssignDefaultCategory::class )->schedule_action();
}
);
@@ -80,15 +80,21 @@ class WC_Admin_Taxonomies {
if ( ! empty( $attribute_taxonomies ) ) {
foreach ( $attribute_taxonomies as $attribute ) {
- add_action( 'pa_' . $attribute->attribute_name . '_pre_add_form', array( $this, 'product_attribute_description' ) );
+ $taxonomy = 'pa_' . $attribute->attribute_name;
+ add_action( $taxonomy . '_pre_add_form', array( $this, 'product_attribute_description' ) );
+ add_action( $taxonomy . '_add_form_fields', array( $this, 'add_product_attribute_term_fields' ) );
+ add_action( $taxonomy . '_edit_form_fields', array( $this, 'edit_product_attribute_term_fields' ), 10, 1 );
+ add_filter( "manage_edit-{$taxonomy}_columns", array( $this, 'add_term_color_columns' ) );
+ add_filter( "manage_{$taxonomy}_custom_column", array( $this, 'render_term_color_column' ), 10, 3 );
}
}
// Maintain hierarchy of terms.
add_filter( 'wp_terms_checklist_args', array( $this, 'disable_checked_ontop' ) );
- // Admin footer scripts for this product categories admin screen.
+ // Admin footer scripts for taxonomy screens.
add_action( 'admin_footer', array( $this, 'scripts_at_product_cat_screen_footer' ) );
+ add_action( 'admin_footer', array( $this, 'scripts_at_visual_attribute_screen_footer' ) );
}
/**
@@ -305,6 +311,74 @@ class WC_Admin_Taxonomies {
<?php
}
+ /**
+ * Check if the current taxonomy should show visual swatch controls.
+ *
+ * @param string $taxonomy Taxonomy slug.
+ * @return bool
+ *
+ * @internal
+ */
+ private function is_visual_product_attribute_taxonomy( $taxonomy ) {
+ if ( ! taxonomy_is_product_attribute( $taxonomy ) ) {
+ return false;
+ }
+
+ $attribute_slug = wc_attribute_taxonomy_slug( $taxonomy );
+
+ foreach ( wc_get_attribute_taxonomies() as $attribute_taxonomy ) {
+ if ( $attribute_slug === $attribute_taxonomy->attribute_name ) {
+ return 'wc-visual' === $attribute_taxonomy->attribute_type;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Add custom fields for product attribute terms.
+ *
+ * @param string $taxonomy Taxonomy slug.
+ * @return void
+ *
+ * @internal
+ */
+ public function add_product_attribute_term_fields( $taxonomy ) {
+ if ( ! $this->is_visual_product_attribute_taxonomy( $taxonomy ) ) {
+ return;
+ }
+ ?>
+ <div class="form-field term-color-wrap">
+ <label for="term_color"><?php esc_html_e( 'Color value', 'woocommerce' ); ?></label>
+ <input name="term_color" id="term_color" type="color" value="" />
+ </div>
+ <?php
+ }
+
+ /**
+ * Edit custom fields for product attribute terms.
+ *
+ * @param WP_Term $term Current term.
+ * @return void
+ *
+ * @internal
+ */
+ public function edit_product_attribute_term_fields( $term ) {
+ if ( ! $this->is_visual_product_attribute_taxonomy( $term->taxonomy ) ) {
+ return;
+ }
+
+ $color_value = get_term_meta( $term->term_id, 'color', true );
+ ?>
+ <tr class="form-field term-color-wrap">
+ <th scope="row" valign="top"><label for="term_color"><?php esc_html_e( 'Color value', 'woocommerce' ); ?></label></th>
+ <td>
+ <input name="term_color" id="term_color" type="color" value="<?php echo esc_attr( $color_value ); ?>" />
+ </td>
+ </tr>
+ <?php
+ }
+
/**
* Save category fields
*
@@ -319,6 +393,13 @@ class WC_Admin_Taxonomies {
if ( isset( $_POST['product_cat_thumbnail_id'] ) && 'product_cat' === $taxonomy ) { // WPCS: CSRF ok, input var ok.
update_term_meta( $term_id, 'thumbnail_id', absint( $_POST['product_cat_thumbnail_id'] ) ); // WPCS: CSRF ok, input var ok.
}
+ if ( $this->is_visual_product_attribute_taxonomy( $taxonomy ) ) {
+ $color_value = isset( $_POST['term_color'] ) ? sanitize_hex_color( wp_unslash( $_POST['term_color'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing
+
+ if ( $color_value ) {
+ update_term_meta( $term_id, 'color', $color_value );
+ }
+ }
}
/**
@@ -364,6 +445,75 @@ class WC_Admin_Taxonomies {
);
}
+ /**
+ * Add custom columns for product attribute terms.
+ *
+ * @param array $columns Existing columns.
+ * @return array
+ *
+ * @internal
+ */
+ public function add_term_color_columns( $columns ) {
+ $taxonomy = isset( $_GET['taxonomy'] ) ? sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( ! $this->is_visual_product_attribute_taxonomy( $taxonomy ) ) {
+ return $columns;
+ }
+
+ $new_columns = array();
+ foreach ( $columns as $key => $label ) {
+ if ( 'slug' === $key ) {
+ $new_columns['color'] = __( 'Color value', 'woocommerce' );
+ }
+ $new_columns[ $key ] = $label;
+ }
+
+ if ( ! isset( $new_columns['color'] ) ) {
+ $new_columns['color'] = __( 'Color value', 'woocommerce' );
+ }
+
+ return $new_columns;
+ }
+
+ /**
+ * Render color column for product attribute terms.
+ *
+ * @param string $columns Existing columns HTML.
+ * @param string $column Current column key.
+ * @param int $term_id Term ID.
+ * @return string
+ *
+ * @internal
+ */
+ public function render_term_color_column( $columns, $column, $term_id ) {
+ if ( 'color' !== $column ) {
+ return $columns;
+ }
+
+ $taxonomy = isset( $_GET['taxonomy'] ) ? sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( ! $this->is_visual_product_attribute_taxonomy( $taxonomy ) ) {
+ return $columns;
+ }
+
+ $color_value = get_term_meta( $term_id, 'color', true );
+
+ if ( ! $color_value ) {
+ return '–';
+ }
+
+ $color_value = sanitize_hex_color( $color_value );
+
+ if ( ! $color_value ) {
+ return '–';
+ }
+
+ $swatch = sprintf(
+ '<span class="wc-admin-color-swatch" style="background-color:%s;" aria-hidden="true"></span>',
+ esc_attr( $color_value )
+ );
+
+ return $swatch . esc_html( strtoupper( $color_value ) );
+ }
+
/**
* Thumbnail column added to category admin.
*
@@ -477,33 +627,70 @@ class WC_Admin_Taxonomies {
* @return void
*/
public function scripts_at_product_cat_screen_footer() {
- if ( ! isset( $_GET['taxonomy'] ) || 'product_cat' !== $_GET['taxonomy'] ) { // WPCS: CSRF ok, input var ok.
+ $taxonomy = isset( $_GET['taxonomy'] ) ? sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( 'product_cat' !== $taxonomy ) {
return;
}
- // Ensure the tooltip is displayed when the image column is disabled on product categories.
$handle = 'wc-admin-taxonomies';
wp_register_script( $handle, '', array(), WC_VERSION, array( 'in_footer' => true ) );
wp_enqueue_script( $handle );
+
+ // Ensure the tooltip is displayed when the image column is disabled on product categories.
wp_add_inline_script(
$handle,
sprintf(
"(function() {
- 'use strict';
- const product_cat = document.getElementById('tag-%d');
- if (product_cat) {
- const th = product_cat.querySelector('th');
- const thumbSpan = product_cat.querySelector('td.thumb span');
- if (th && thumbSpan) {
- th.innerHTML = '';
- th.appendChild(thumbSpan);
- }
- }
- })();",
+ 'use strict';
+ const product_cat = document.getElementById('tag-%d');
+ if (product_cat) {
+ const th = product_cat.querySelector('th');
+ const thumbSpan = product_cat.querySelector('td.thumb span');
+ if (th && thumbSpan) {
+ th.innerHTML = '';
+ th.appendChild(thumbSpan);
+ }
+ }
+ })();",
absint( $this->default_cat_id )
)
);
}
+
+ /**
+ * Admin footer scripts for visual attribute taxonomy screens.
+ *
+ * @return void
+ *
+ * @internal
+ */
+ public function scripts_at_visual_attribute_screen_footer() {
+ $taxonomy = isset( $_GET['taxonomy'] ) ? sanitize_text_field( wp_unslash( $_GET['taxonomy'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
+ if ( ! $this->is_visual_product_attribute_taxonomy( $taxonomy ) ) {
+ return;
+ }
+
+ $handle = 'wc-admin-visual-attribute';
+ wp_register_script( $handle, '', array(), WC_VERSION, array( 'in_footer' => true ) );
+ wp_enqueue_script( $handle );
+ wp_add_inline_script(
+ $handle,
+ "(function() {
+ 'use strict';
+ const addFormColor = document.querySelector('.form-field.term-color-wrap');
+ const addFormSlug = document.querySelector('.form-field.term-slug-wrap');
+ if (addFormColor && addFormSlug) {
+ addFormSlug.parentNode.insertBefore(addFormColor, addFormSlug);
+ }
+
+ const editFormColor = document.querySelector('tr.form-field.term-color-wrap');
+ const editFormSlug = document.querySelector('tr.form-field.term-slug-wrap');
+ if (editFormColor && editFormSlug) {
+ editFormSlug.parentNode.insertBefore(editFormColor, editFormSlug);
+ }
+ })();"
+ );
+ }
}
$wc_admin_taxonomies = WC_Admin_Taxonomies::get_instance();
diff --git a/plugins/woocommerce/includes/admin/meta-boxes/views/html-product-attribute-inner.php b/plugins/woocommerce/includes/admin/meta-boxes/views/html-product-attribute-inner.php
index 9d742f1e11f..0b9fca21e01 100644
--- a/plugins/woocommerce/includes/admin/meta-boxes/views/html-product-attribute-inner.php
+++ b/plugins/woocommerce/includes/admin/meta-boxes/views/html-product-attribute-inner.php
@@ -35,7 +35,10 @@ if ( ! defined( 'ABSPATH' ) ) {
$attribute_taxonomy->attribute_type = 'select';
}
- if ( 'select' === $attribute_taxonomy->attribute_type ) {
+ if (
+ 'select' === $attribute_taxonomy->attribute_type ||
+ 'wc-visual' === $attribute_taxonomy->attribute_type
+ ) {
$attribute_orderby = ! empty( $attribute_taxonomy->attribute_orderby ) ? $attribute_taxonomy->attribute_orderby : 'name';
/**
* Filter the length (number of terms) rendered in the list.
diff --git a/plugins/woocommerce/includes/wc-attribute-functions.php b/plugins/woocommerce/includes/wc-attribute-functions.php
index cb043264cce..bcbbae57f05 100644
--- a/plugins/woocommerce/includes/wc-attribute-functions.php
+++ b/plugins/woocommerce/includes/wc-attribute-functions.php
@@ -211,7 +211,7 @@ function wc_attribute_label( $name, $product = '' ) {
}
} else {
$label = $name;
- }
+ }//end if
return apply_filters( 'woocommerce_attribute_label', $label, $name, $product );
}
@@ -253,16 +253,38 @@ function wc_get_attribute_taxonomy_names() {
* @return array
*/
function wc_get_attribute_types() {
+ $attribute_types = array(
+ 'select' => __( 'Text', 'woocommerce' ),
+ );
+
+ $allow_visual_attribute_type =
+ wp_is_block_theme() &&
+ \Automattic\WooCommerce\Admin\Features\Features::is_enabled( 'wc-visual-attribute' );
+
+ // If the store already has some visual attributes, let's allow them even
+ // if the current theme is not a block theme.
+ if ( ! $allow_visual_attribute_type ) {
+ foreach ( wc_get_attribute_taxonomies() as $attribute_taxonomy ) {
+ if ( isset( $attribute_taxonomy->attribute_type ) && 'wc-visual' === $attribute_taxonomy->attribute_type ) {
+ $allow_visual_attribute_type = true;
+ break;
+ }
+ }
+ }
+
+ if ( $allow_visual_attribute_type ) {
+ $attribute_types['wc-visual'] = __( 'Color / Image', 'woocommerce' );
+ }
+
return (array) apply_filters(
'product_attributes_type_selector',
- array(
- 'select' => __( 'Select', 'woocommerce' ),
- )
+ $attribute_types
);
}
/**
- * Check if there are custom attribute types.
+ * Check if there are attribute types different than the default `select` type.
+ * Note: `wc-visual` is considered a custom attribute type.
*
* @since 3.3.2
* @return bool True if there are custom types, otherwise false.
@@ -283,7 +305,7 @@ function wc_has_custom_attribute_types() {
function wc_get_attribute_type_label( $type ) {
$types = wc_get_attribute_types();
- return isset( $types[ $type ] ) ? $types[ $type ] : __( 'Select', 'woocommerce' );
+ return isset( $types[ $type ] ) ? $types[ $type ] : __( 'Text', 'woocommerce' );
}
/**
@@ -621,8 +643,8 @@ function wc_create_attribute( $args ) {
if ( isset( $wp_taxonomies[ $old_taxonomy_name ] ) && ! isset( $wp_taxonomies[ $new_taxonomy_name ] ) ) {
$wp_taxonomies[ $new_taxonomy_name ] = $wp_taxonomies[ $old_taxonomy_name ]; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
}
- }
- }
+ }//end if
+ }//end if
// Clear cache and flush rewrite rules.
wp_schedule_single_event( time(), 'woocommerce_flush_rewrite_rules' );
@@ -730,7 +752,7 @@ function wc_delete_attribute( $id ) {
WC_Cache_Helper::invalidate_cache_group( 'woocommerce-attributes' );
return true;
- }
+ }//end if
return false;
}
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartForm.php b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartForm.php
index b15b68c2b93..21d95528fa9 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartForm.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AddToCartForm.php
@@ -3,7 +3,6 @@ declare(strict_types=1);
namespace Automattic\WooCommerce\Blocks\BlockTypes;
-use Automattic\WooCommerce\Admin\Features\Features;
use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils;
use Automattic\WooCommerce\Blocks\BlockTypes\AddToCartWithOptions\Utils;
use Automattic\WooCommerce\Enums\ProductType;
diff --git a/plugins/woocommerce/tests/php/includes/wc-attribute-functions-test.php b/plugins/woocommerce/tests/php/includes/wc-attribute-functions-test.php
index 2b4a1193648..1b509fd30bd 100644
--- a/plugins/woocommerce/tests/php/includes/wc-attribute-functions-test.php
+++ b/plugins/woocommerce/tests/php/includes/wc-attribute-functions-test.php
@@ -29,7 +29,7 @@ class WC_Attribute_Functions_Test extends \WC_Unit_Test_Case {
$this->filter_recorder = $this->any();
$filter_mock = $this->getMockBuilder( stdClass::class )
- ->setMethods( [ '__invoke' ] )
+ ->setMethods( array( '__invoke' ) )
->getMock();
$filter_mock->expects( $this->filter_recorder )
->method( '__invoke' )
@@ -55,14 +55,14 @@ class WC_Attribute_Functions_Test extends \WC_Unit_Test_Case {
*/
public function test_wc_get_attribute_taxonomy_ids() {
$ids = wc_get_attribute_taxonomy_ids();
- $this->assertEquals( [], $ids );
+ $this->assertEquals( array(), $ids );
$this->assertEquals(
1,
$this->filter_recorder->getInvocationCount(),
'Filter `woocommerce_attribute_taxonomies` should have been triggered once after fetching all attribute taxonomies.'
);
$ids = wc_get_attribute_taxonomy_ids();
- $this->assertEquals( [], $ids );
+ $this->assertEquals( array(), $ids );
$this->assertEquals(
1,
$this->filter_recorder->getInvocationCount(),
@@ -76,14 +76,14 @@ class WC_Attribute_Functions_Test extends \WC_Unit_Test_Case {
*/
public function test_wc_get_attribute_taxonomy_labels() {
$labels = wc_get_attribute_taxonomy_labels();
- $this->assertEquals( [], $labels );
+ $this->assertEquals( array(), $labels );
$this->assertEquals(
1,
$this->filter_recorder->getInvocationCount(),
'Filter `woocommerce_attribute_taxonomies` should have been triggered once after fetching all attribute taxonomies.'
);
$labels = wc_get_attribute_taxonomy_labels();
- $this->assertEquals( [], $labels );
+ $this->assertEquals( array(), $labels );
$this->assertEquals(
1,
$this->filter_recorder->getInvocationCount(),
@@ -215,12 +215,60 @@ class WC_Attribute_Functions_Test extends \WC_Unit_Test_Case {
$this->assertEquals( 'menu_order', $attribute->order_by, 'Any invalid property changes will be reset to their defaults.' );
}
+ /**
+ * Test visual attribute type registration and persistence.
+ *
+ * @testdox Should have the `wc-visual` attribute type registered in block themes.
+ */
+ public function test_wc_visual_attribute_type() {
+ $original_theme = wp_get_theme()->get_stylesheet();
+ $attribute_id = null;
+
+ $enable_visual_attribute_feature = function ( $features ) {
+ $features[] = 'wc-visual-attribute';
+ return array_unique( $features );
+ };
+
+ add_filter( 'woocommerce_admin_features', $enable_visual_attribute_feature );
+ try {
+ switch_theme( 'twentytwentyfour' );
+
+ $this->assertArrayHasKey( 'wc-visual', wc_get_attribute_types(), 'The visual attribute type should be available in block themes.' );
+
+ $attribute_id = wc_create_attribute(
+ array(
+ 'name' => 'Visual Color',
+ 'type' => 'wc-visual',
+ )
+ );
+
+ $this->assertIsInt( $attribute_id );
+ $this->assertEquals( 'wc-visual', wc_get_attribute( $attribute_id )->type, 'The attribute type should be `wc-visual` in block themes.' );
+
+ switch_theme( 'storefront' );
+ $this->assertEquals( 'wc-visual', wc_get_attribute( $attribute_id )->type, 'The attribute type should be `wc-visual` in classic themes.' );
+ $this->assertArrayHasKey( 'wc-visual', wc_get_attribute_types(), 'The visual attribute type should be available in classic themes with a visual attribute.' );
+
+ wc_delete_attribute( $attribute_id );
+ $attribute_id = null;
+
+ $this->assertArrayNotHasKey( 'wc-visual', wc_get_attribute_types(), 'The visual attribute type should not be available in classic themes without a visual attribute.' );
+ } finally {
+ if ( is_int( $attribute_id ) ) {
+ wc_delete_attribute( $attribute_id );
+ }
+
+ remove_filter( 'woocommerce_admin_features', $enable_visual_attribute_feature );
+ switch_theme( $original_theme );
+ }//end try
+ }
+
public function get_attribute_names_and_slugs() {
- return [
- [ 'Dash Me', 'dash-me' ],
- [ '', '' ],
- [ 'pa_SubStr', 'substr' ],
- [ 'ĂnîC°Dę', 'anicde' ],
- ];
+ return array(
+ array( 'Dash Me', 'dash-me' ),
+ array( '', '' ),
+ array( 'pa_SubStr', 'substr' ),
+ array( 'ĂnîC°Dę', 'anicde' ),
+ );
}
}