Commit 9a3a1a1dc41 for woocommerce

commit 9a3a1a1dc41183c133e1ae8307a9310dc8e7cbc1
Author: Peter Petrov <peter.petrov89@gmail.com>
Date:   Thu Jul 16 15:28:26 2026 +0300

    Fix CSV importer HTML-encoding attribute names (#66656)

    Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

diff --git a/plugins/woocommerce/changelog/fix-28172-csv-importer-attribute-name-sanitization b/plugins/woocommerce/changelog/fix-28172-csv-importer-attribute-name-sanitization
new file mode 100644
index 00000000000..0b84f784838
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-28172-csv-importer-attribute-name-sanitization
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix CSV importer HTML-encoding attribute names, which prevented matching existing global attributes and caused duplicate attributes or slug-too-long import errors.
diff --git a/plugins/woocommerce/includes/import/class-wc-product-csv-importer.php b/plugins/woocommerce/includes/import/class-wc-product-csv-importer.php
index 4d2c76e1e0e..b16650628e7 100644
--- a/plugins/woocommerce/includes/import/class-wc-product-csv-importer.php
+++ b/plugins/woocommerce/includes/import/class-wc-product-csv-importer.php
@@ -844,9 +844,9 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
 			if ( isset( $data_formatting[ $heading ] ) ) {
 				$callback = $data_formatting[ $heading ];
 			} else {
-				foreach ( $regex_match_data_formatting as $regex => $callback ) {
+				foreach ( $regex_match_data_formatting as $regex => $regex_callback ) {
 					if ( preg_match( $regex, $heading ) ) {
-						$callback = $callback;
+						$callback = $regex_callback;
 						break;
 					}
 				}
diff --git a/plugins/woocommerce/tests/php/includes/importer/class-wc-product-csv-importer-test.php b/plugins/woocommerce/tests/php/includes/importer/class-wc-product-csv-importer-test.php
index 52a39c1a736..631d9bc4778 100644
--- a/plugins/woocommerce/tests/php/includes/importer/class-wc-product-csv-importer-test.php
+++ b/plugins/woocommerce/tests/php/includes/importer/class-wc-product-csv-importer-test.php
@@ -293,6 +293,53 @@ class WC_Product_CSV_Importer_Test extends \WC_Unit_Test_Case {
 		);
 	}

+	/**
+	 * @testdox Attribute names with special characters should match existing global attributes on import instead of creating duplicates (issue #28172).
+	 */
+	public function test_import_matches_existing_attribute_with_special_characters_in_name_28172() {
+		// Set admin user to allow term creation.
+		wp_set_current_user( self::factory()->user->create( array( 'role' => 'administrator' ) ) );
+
+		$attribute_id = wc_create_attribute(
+			array(
+				'name' => 'ARC Flash > Gloves > CE Category',
+				'slug' => 'arc-glove-ce',
+			)
+		);
+		$taxonomy     = wc_attribute_taxonomy_name_by_id( $attribute_id );
+		register_taxonomy( $taxonomy, 'product' );
+		wp_insert_term( 'Meeny', $taxonomy );
+
+		$csv_file = __DIR__ . '/import-attribute-special-chars-28172-data.csv';
+		$args     = array(
+			'parse'   => true,
+			'mapping' => array(
+				'Name'                 => 'name',
+				'Type'                 => 'type',
+				'Attribute 1 name'     => 'attributes:name1',
+				'Attribute 1 value(s)' => 'attributes:value1',
+				'Attribute 1 visible'  => 'attributes:visible1',
+				'Attribute 1 global'   => 'attributes:taxonomy1',
+			),
+		);
+		$importer = new WC_Product_CSV_Importer( $csv_file, $args );
+
+		$parsed = $importer->get_parsed_data();
+		$this->assertSame( 'ARC Flash > Gloves > CE Category', $parsed[0]['raw_attributes'][0]['name'], 'The attribute name should not be HTML-encoded during parsing' );
+
+		$data = $importer->import();
+		$this->assertCount( 1, $data['imported'], 'Expected 1 imported product' );
+		$this->assertEmpty( $data['failed'], 'Expected 0 failed products' );
+
+		$this->assertSame( 0, wc_attribute_taxonomy_id_by_name( 'arc-flash-gloves-ce-category' ), 'A duplicate attribute should not be created' );
+
+		$product = wc_get_product( $data['imported'][0] );
+		$this->assertArrayHasKey( 'pa_arc-glove-ce', $product->get_attributes(), 'The product should use the existing attribute' );
+
+		WC_Helper_Product::delete_product( $product->get_id() );
+		wc_delete_attribute( $attribute_id );
+	}
+
 	/**
 	 * @testdox parse_float_field should return an empty string unchanged.
 	 */
diff --git a/plugins/woocommerce/tests/php/includes/importer/import-attribute-special-chars-28172-data.csv b/plugins/woocommerce/tests/php/includes/importer/import-attribute-special-chars-28172-data.csv
new file mode 100644
index 00000000000..1d00c458dfe
--- /dev/null
+++ b/plugins/woocommerce/tests/php/includes/importer/import-attribute-special-chars-28172-data.csv
@@ -0,0 +1,2 @@
+Name,Type,Attribute 1 name,Attribute 1 value(s),Attribute 1 visible,Attribute 1 global
+Special Chars Attribute Product,simple,ARC Flash > Gloves > CE Category,Meeny,1,1