Commit e83c78ded57 for woocommerce
commit e83c78ded57e1dabbe9c4a4f701a2833aaa9b9f8
Author: Lucio Giannotta <lucio.giannotta@a8c.com>
Date: Tue Oct 27 17:43:03 2026 +0000
Keep regular upload filenames unchanged (#66011)
diff --git a/plugins/woocommerce/changelog/wooplug-6192-incorrect-conditional-causes-filename-change-for-non b/plugins/woocommerce/changelog/wooplug-6192-incorrect-conditional-causes-filename-change-for-non
new file mode 100644
index 00000000000..a1e066909d2
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooplug-6192-incorrect-conditional-causes-filename-change-for-non
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Keep regular upload filenames unchanged when files are sent to the WooCommerce download folder.
diff --git a/plugins/woocommerce/includes/admin/class-wc-admin-upload-downloadable-product.php b/plugins/woocommerce/includes/admin/class-wc-admin-upload-downloadable-product.php
index 8fa673bde62..0156979fbb3 100644
--- a/plugins/woocommerce/includes/admin/class-wc-admin-upload-downloadable-product.php
+++ b/plugins/woocommerce/includes/admin/class-wc-admin-upload-downloadable-product.php
@@ -64,7 +64,7 @@ class WC_Admin_Upload_Downloadable_Product {
*/
public function update_filename( $full_filename, $ext, $dir ) {
// phpcs:disable WordPress.Security.NonceVerification.Missing
- if ( ! isset( $_POST['type'] ) || ! 'downloadable_product' === $_POST['type'] ) {
+ if ( ! isset( $_POST['type'] ) || 'downloadable_product' !== $_POST['type'] ) {
return $full_filename;
}
diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index 0fbf9bcb600..434d6e46702 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -3078,12 +3078,6 @@ parameters:
count: 1
path: includes/admin/class-wc-admin-upload-downloadable-product.php
- -
- message: '#^Negated boolean expression is always false\.$#'
- identifier: booleanNot.alwaysFalse
- count: 1
- path: includes/admin/class-wc-admin-upload-downloadable-product.php
-
-
message: '#^Parameter \#2 \$callback of function add_action expects callable\(\)\: mixed, array\{\$this\(WC_Admin_Upload_Downloadable_Product\), ''media_upload…''\} given\.$#'
identifier: argument.type
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/core/post-types-admin.php b/plugins/woocommerce/tests/legacy/unit-tests/core/post-types-admin.php
index 0d536b14086..dd949c35938 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/core/post-types-admin.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/core/post-types-admin.php
@@ -1,51 +1,106 @@
<?php
/**
- * Tests for WC_Test_Admin_Post_Types class.
+ * Tests for downloadable product uploads.
*
* @package WooCommerce\Tests\Util
*/
+declare( strict_types = 1 );
+
/**
- * WooCommerce Post Type class.
+ * Tests for WC_Admin_Upload_Downloadable_Product.
*/
class WC_Test_Admin_Post_Types extends WC_Unit_Test_Case {
/**
- * Instance of WC_Admin_Upload_Downloadable_Product.
+ * The System Under Test.
*
- * @var \WC_Admin_Upload_Downloadable_Product
+ * @var WC_Admin_Upload_Downloadable_Product
*/
- protected $wc_cpt;
-
+ private $sut;
/**
- * Setup. Create a instance to use throughout.
+ * Set up the upload handler.
*/
public function setUp(): void {
parent::setUp();
- $this->wc_cpt = new WC_Admin_Upload_Downloadable_Product();
+ $this->sut = new WC_Admin_Upload_Downloadable_Product();
+ }
+
+ /**
+ * @testdox A unique filename retains its original name and extension with six added characters.
+ */
+ public function test_unique_filename(): void {
+ $result = $this->sut->unique_filename( 'release-notes.csv', '.csv' );
+
+ $this->assertMatchesRegularExpression( '/^release-notes-[a-z0-9]{6}\.csv$/', $result, 'The random suffix should be inserted before the extension.' );
}
/**
- * Check if filename is extended and extension is preserved.
+ * @testdox A filename near the length limit keeps its extension without exceeding the limit.
*/
- public function test_unique_filename() {
- $full_filename = 'dummy_filename.csv';
- $ext = '.csv';
+ public function test_unique_filename_for_large_name(): void {
+ $filename = str_repeat( 'w', 250 ) . '.csv';
+
+ $result = $this->sut->unique_filename( $filename, '.csv' );
- $unique_filename = $this->wc_cpt->unique_filename( $full_filename, $ext );
- $this->assertEquals( strlen( $full_filename ) + 6 + 1, strlen( $unique_filename ) );
- $this->assertEquals( $ext, substr( $unique_filename, -4 ) );
+ $this->assertSame( $filename, $result, 'A filename without room for a suffix should remain unchanged.' );
}
/**
- * Check if filename is extended properly when its very long.
+ * @testdox Uploads keep their filename unless the type, folder and setting all require a suffix.
+ * @testWith ["image", "/uploads/woocommerce_uploads", "yes"]
+ * [null, "/uploads/woocommerce_uploads", "yes"]
+ * [["downloadable_product"], "/uploads/woocommerce_uploads", "yes"]
+ * ["", "/uploads/woocommerce_uploads", "yes"]
+ * ["downloadable_product", "/uploads/2026/10", "yes"]
+ * ["downloadable_product", "/uploads/woocommerce_uploads", "no"]
+ *
+ * @param mixed $upload_type Request type, or null to omit it.
+ * @param string $directory Destination directory.
+ * @param string $add_suffix Whether the filename suffix setting is enabled.
*/
- public function test_unique_filename_for_large_name() {
- $full_filename = str_repeat( 'w', 250 ) . '.csv';
- $ext = '.csv';
- $unique_filename = $this->wc_cpt->unique_filename( $full_filename, $ext );
- $this->assertEquals( 254, strlen( $unique_filename ) );
- $this->assertEquals( $ext, substr( $unique_filename, - 4 ) );
+ public function test_update_filename_keeps_original_when_suffix_not_required( $upload_type, string $directory, string $add_suffix ): void {
+ if ( null !== $upload_type ) {
+ $_POST['type'] = $upload_type;
+ }
+ update_option( 'woocommerce_downloads_add_hash_to_filename', $add_suffix );
+
+ $result = $this->sut->update_filename( 'release-notes.csv', '.csv', $directory );
+
+ $this->assertSame( 'release-notes.csv', $result, 'The filename should remain unchanged when any required condition is absent.' );
+ }
+
+ /**
+ * @testdox Downloadable product uploads still receive a suffix when the setting is enabled.
+ */
+ public function test_update_filename_hashes_downloadable_product(): void {
+ $_POST['type'] = 'downloadable_product';
+ update_option( 'woocommerce_downloads_add_hash_to_filename', 'yes' );
+
+ $result = $this->sut->update_filename( 'download-guide.csv', '.csv', '/uploads/woocommerce_uploads' );
+
+ $this->assertMatchesRegularExpression( '/^download-guide-[a-z0-9]{6}\.csv$/', $result, 'A genuine product download should retain the existing filename protection.' );
+ }
+
+ /**
+ * @testdox Missing, other and array upload types keep the original upload directory.
+ * @testWith [null]
+ * ["image"]
+ * [["downloadable_product"]]
+ *
+ * @param mixed $upload_type Request type, or null to omit it.
+ */
+ public function test_upload_dir_ignores_non_downloadable_types( $upload_type ): void {
+ if ( null !== $upload_type ) {
+ $_POST['type'] = $upload_type;
+ }
+ $directory = array(
+ 'path' => '/uploads/2026/10',
+ 'url' => 'https://example.com/uploads/2026/10',
+ 'subdir' => '/2026/10',
+ );
+
+ $this->assertSame( $directory, $this->sut->upload_dir( $directory ), 'Only the exact downloadable-product type should change the upload directory.' );
}
}