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 93445851813..3b642fbb4bd 100644 --- a/plugins/woocommerce/includes/import/class-wc-product-csv-importer.php +++ b/plugins/woocommerce/includes/import/class-wc-product-csv-importer.php @@ -590,6 +590,35 @@ class WC_Product_CSV_Importer extends WC_Product_Importer { return null; } + /** + * Parse dates from a CSV. + * Dates can be Unix timestamps or in any format supported by strtotime(). + * + * @param string $value Field value. + * + * @return string|null + */ + public function parse_datetime_field( $value ) { + try { + // If value is a Unix timestamp, convert it to a datetime string. + if ( is_numeric( $value ) ) { + $datetime = new DateTime( "@{$value}" ); + // Return datetime string in ISO8601 format (eg. 2018-01-01T00:00:00Z) to preserve UTC timezone since Unix timestamps are always UTC. + return $datetime->format( 'Y-m-d\TH:i:s\Z' ); + } + // Check whether the value is a valid date string. + if (false !== strtotime( $value ) ) { + // If the value is a valid date string, return as is. + return $value; + } + // If value is not valid Unix timestamp or date string, return null. + return null; + } catch ( Exception $e ) { + // DateTime constructor throws an exception if the value is not a valid Unix timestamp. + return null; + } + } + /** * Parse backorders from a CSV. * @@ -725,8 +754,8 @@ class WC_Product_CSV_Importer extends WC_Product_Importer { 'type' => array( $this, 'parse_comma_field' ), 'published' => array( $this, 'parse_published_field' ), 'featured' => array( $this, 'parse_bool_field' ), - 'date_on_sale_from' => array( $this, 'parse_date_field' ), - 'date_on_sale_to' => array( $this, 'parse_date_field' ), + 'date_on_sale_from' => array( $this, 'parse_datetime_field' ), + 'date_on_sale_to' => array( $this, 'parse_datetime_field' ), 'name' => array( $this, 'parse_skip_field' ), 'short_description' => array( $this, 'parse_description_field' ), 'description' => array( $this, 'parse_description_field' ), diff --git a/plugins/woocommerce/tests/legacy/unit-tests/importer/product.php b/plugins/woocommerce/tests/legacy/unit-tests/importer/product.php index 8dab5d27b29..a5d93dd258f 100644 --- a/plugins/woocommerce/tests/legacy/unit-tests/importer/product.php +++ b/plugins/woocommerce/tests/legacy/unit-tests/importer/product.php @@ -276,8 +276,8 @@ class WC_Tests_Product_CSV_Importer extends WC_Unit_Test_Case { 'visible', 'Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.', 'Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.', - '', - '', + 'Jul 8, 2023', + '1689239400', 'taxable', 'standard', '1', @@ -290,7 +290,7 @@ class WC_Tests_Product_CSV_Importer extends WC_Unit_Test_Case { '', '1', 'Lorem ipsum dolor sit amet.', - '', + '4', '5', 'Music > Albums, Music', 'Woo', @@ -341,7 +341,7 @@ class WC_Tests_Product_CSV_Importer extends WC_Unit_Test_Case { 'short_description' => 'Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.', 'description' => 'Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.', 'date_on_sale_from' => '2017-01-01', - 'date_on_sale_to' => '2030-01-01', + 'date_on_sale_to' => '2030-01-01 0:00:00', 'tax_status' => 'taxable', 'tax_class' => 'standard', 'stock_status' => 'instock', @@ -384,8 +384,8 @@ class WC_Tests_Product_CSV_Importer extends WC_Unit_Test_Case { 'catalog_visibility' => 'visible', 'short_description' => 'Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.', 'description' => 'Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.', - 'date_on_sale_from' => null, - 'date_on_sale_to' => null, + 'date_on_sale_from' => 'Jul 8, 2023', + 'date_on_sale_to' => '2023-07-13T09:10:00Z', 'tax_status' => 'taxable', 'tax_class' => 'standard', 'stock_status' => 'instock', @@ -398,7 +398,7 @@ class WC_Tests_Product_CSV_Importer extends WC_Unit_Test_Case { 'height' => '', 'reviews_allowed' => true, 'purchase_note' => 'Lorem ipsum dolor sit amet.', - 'sale_price' => '', + 'sale_price' => '4', 'regular_price' => '5', 'shipping_class_id' => 0, 'download_limit' => 10, @@ -437,8 +437,8 @@ class WC_Tests_Product_CSV_Importer extends WC_Unit_Test_Case { 'catalog_visibility' => 'visible', 'short_description' => 'Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.', 'description' => 'Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.', - 'date_on_sale_from' => null, - 'date_on_sale_to' => null, + 'date_on_sale_from' => '2023-07-08 05:10:15', + 'date_on_sale_to' => '2023/07/13', 'tax_status' => 'taxable', 'tax_class' => 'standard', 'stock_status' => 'instock', @@ -451,7 +451,7 @@ class WC_Tests_Product_CSV_Importer extends WC_Unit_Test_Case { 'height' => '', 'reviews_allowed' => false, 'purchase_note' => 'Lorem ipsum dolor sit amet.', - 'sale_price' => '', + 'sale_price' => '180', 'regular_price' => '199', 'shipping_class_id' => 0, 'download_limit' => 0, diff --git a/plugins/woocommerce/tests/legacy/unit-tests/importer/sample.csv b/plugins/woocommerce/tests/legacy/unit-tests/importer/sample.csv index 607fb8c9247..2a9c61fc575 100644 --- a/plugins/woocommerce/tests/legacy/unit-tests/importer/sample.csv +++ b/plugins/woocommerce/tests/legacy/unit-tests/importer/sample.csv @@ -1,7 +1,7 @@ Type,SKU,Name,Published,Is featured?,Visibility in catalog,Short description,Description,Date sale price starts,Date sale price ends,Tax status,Tax class,In stock?,Stock,Backorders allowed?,Sold individually?,Weight (kg),Length (cm),Width (cm),Height (cm),Allow customer reviews?,Purchase note,Sale price,Regular price,Categories,Tags,Shipping class,Images,Download limit,Download expiry days,Parent,Upsells,Cross-sells,Grouped products,External URL,BUTTON TEXT,Position,Attribute 1 Name,Attribute 1 Value(s),Attribute 2 name,Attribute 2 value(s),Attribute 1 default,Attribute 2 default,Download 1 ID,Download 1 name,Download 1 URL simple,WOOLOGO,Woo Logo,1,,visible,"Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.","Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.",2017-01-01,2030-01-01 0:00:00,taxable,standard,1,5,notify,1,1,1,20,40,1,Lorem ipsum dolor sit amet.,18,20,"Clothing, Clothing > T-shirts",,,"http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_1_front.jpg, http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_1_back.jpg",,,,WOOALBUM,WOOALBUM,,,,0,Color,Red,,,,,,, -"simple, downloadable, virtual",WOOALBUM,Woo Album #1,1,1,visible,"Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.","Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.",,,taxable,standard,1,,,,,,,,1,Lorem ipsum dolor sit amet.,,5,"Music > Albums, Music",Woo,,"http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/cd_1_angle.jpg, http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/cd_1_flat.jpg",10,90,,WOOLOGO,WOOLOGO,,,,1,Label,WooCommerce,Vinyl,180-Gram,,,4ff604c2-97bd-4869-938b-7798ba6648ab,Album flac,http://woo.dev/albums/album.flac -external,,WooCommerce Product CSV Suite,1,,visible,"Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.","Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.",,,taxable,standard,1,,,,,,,,0,Lorem ipsum dolor sit amet.,,199,Software,WooCommerce,,,,,,,,,https://woocommerce.com/products/product-csv-import-suite/,Buy on WooCommerce.com,2,,,,,,,,, +"simple, downloadable, virtual",WOOALBUM,Woo Album #1,1,1,visible,"Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.","Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.","Jul 8, 2023",1689239400,taxable,standard,1,,,,,,,,1,Lorem ipsum dolor sit amet.,4,5,"Music > Albums, Music",Woo,,"http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/cd_1_angle.jpg, http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/cd_1_flat.jpg",10,90,,WOOLOGO,WOOLOGO,,,,1,Label,WooCommerce,Vinyl,180-Gram,,,4ff604c2-97bd-4869-938b-7798ba6648ab,Album flac,http://woo.dev/albums/album.flac +external,,WooCommerce Product CSV Suite,1,,visible,"Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.","Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.",2023-07-08 05:10:15,2023/07/13,taxable,standard,1,,,,,,,,0,Lorem ipsum dolor sit amet.,180,199,Software,WooCommerce,,,,,,,,,https://woocommerce.com/products/product-csv-import-suite/,Buy on WooCommerce.com,2,,,,,,,,, variable,WOOIDEA,Ship Your Idea,1,,visible,"Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.","Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.",,,,,,,,,,,,,1,Lorem ipsum dolor sit amet.,,,"Clothing, Clothing > T-shirts",,,"http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_4_front.jpg, http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_4_back.jpg, http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_3_front.jpg, http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_3_back.jpg",,,,,,,,,3,Color,"Black, Green",Size,"M, L",Green,L,,, variation,,,1,,visible,,"Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.",,,taxable,standard,1,6,0,,1,2,25,55,,,,20,,,,http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_4_front.jpg,,,WOOIDEA,,,,,,1,Color,Black,Size,M,,,,, variation,,,1,,visible,,"Lorem ipsum dolor sit amet, at exerci civibus appetere sit, iuvaret hendrerit mea no. Eam integre feugait liberavisse an.",,,taxable,standard,1,10,1,,1,2,25,55,,,17.99,20,,,,http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_3_front.jpg,,,WOOIDEA,,,,,,2,Color,Green,Size,L,,,,,