diff --git a/includes/admin/class-wc-admin-importers.php b/includes/admin/class-wc-admin-importers.php
index 015fdde3525..8c02b9642cd 100644
--- a/includes/admin/class-wc-admin-importers.php
+++ b/includes/admin/class-wc-admin-importers.php
@@ -192,6 +192,8 @@ class WC_Admin_Importers {
* Ajax callback for importing one batch of products from a CSV.
*/
public function do_ajax_product_import() {
+ global $wpdb;
+
check_ajax_referer( 'wc-product-import', 'security' );
if ( ! current_user_can( 'edit_products' ) || ! isset( $_POST['file'] ) ) {
@@ -226,6 +228,10 @@ class WC_Admin_Importers {
update_user_option( get_current_user_id(), 'product_import_error_log', $error_log );
if ( 100 === $percent_complete ) {
+ // Clear temp meta.
+ $wpdb->delete( $wpdb->postmeta, array( 'meta_key' => '_original_id' ) );
+
+ // Send success.
wp_send_json_success( array(
'position' => 'done',
'percentage' => 100,
diff --git a/includes/admin/importers/views/html-product-csv-import-form.php b/includes/admin/importers/views/html-product-csv-import-form.php
index 08aa61af473..16525304fc4 100644
--- a/includes/admin/importers/views/html-product-csv-import-form.php
+++ b/includes/admin/importers/views/html-product-csv-import-form.php
@@ -49,7 +49,7 @@ if ( ! defined( 'ABSPATH' ) ) {
-
+
|
diff --git a/includes/data-stores/class-wc-product-variation-data-store-cpt.php b/includes/data-stores/class-wc-product-variation-data-store-cpt.php
index a82ab99b562..18351e29eb7 100644
--- a/includes/data-stores/class-wc-product-variation-data-store-cpt.php
+++ b/includes/data-stores/class-wc-product-variation-data-store-cpt.php
@@ -38,23 +38,10 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
public function read( &$product ) {
$product->set_defaults();
- if ( ! $product->get_id() || ! ( $post_object = get_post( $product->get_id() ) ) || 'product_variation' !== $post_object->post_type ) {
+ if ( ! $product->get_id() || ! ( $post_object = get_post( $product->get_id() ) ) || ! in_array( $post_object->post_type, array( 'product', 'product_variation' ) ) ) {
return;
}
- $product->set_parent_id( $post_object->post_parent );
- $parent_id = $product->get_parent_id();
-
- // The post doesn't have a parent id, therefore its invalid and we should prevent this being created.
- if ( empty( $parent_id ) ) {
- throw new Exception( sprintf( 'No parent product set for variation #%d', $product->get_id() ), 422 );
- }
-
- // The post parent is not a valid variable product so we should prevent this being created.
- if ( 'product' !== get_post_type( $product->get_parent_id() ) ) {
- throw new Exception( sprintf( 'Invalid parent for variation #%d', $product->get_id() ), 422 );
- }
-
$product->set_props( array(
'name' => $post_object->post_title,
'slug' => $post_object->post_name,
@@ -63,8 +50,14 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
'status' => $post_object->post_status,
'menu_order' => $post_object->menu_order,
'reviews_allowed' => 'open' === $post_object->comment_status,
+ 'parent_id' => $post_object->post_parent,
) );
+ // The post parent is not a valid variable product so we should prevent this.
+ if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) {
+ $product->set_parent_id( 0 );
+ }
+
$this->read_downloads( $product );
$this->read_product_data( $product );
$this->read_extra_data( $product );
@@ -102,6 +95,11 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
$product->set_name( $new_title );
}
+ // The post parent is not a valid variable product so we should prevent this.
+ if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) {
+ $product->set_parent_id( 0 );
+ }
+
$id = wp_insert_post( apply_filters( 'woocommerce_new_product_variation_data', array(
'post_type' => 'product_variation',
'post_status' => $product->get_status() ? $product->get_status() : 'publish',
@@ -114,6 +112,7 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
'menu_order' => $product->get_menu_order(),
'post_date' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getOffsetTimestamp() ),
'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $product->get_date_created( 'edit' )->getTimestamp() ),
+ 'post_name' => $product->get_slug( 'edit' ),
) ), true );
if ( $id && ! is_wp_error( $id ) ) {
@@ -150,6 +149,11 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
$product->set_name( $new_title );
}
+ // The post parent is not a valid variable product so we should prevent this.
+ if ( $product->get_parent_id( 'edit' ) && 'product' !== get_post_type( $product->get_parent_id( 'edit' ) ) ) {
+ $product->set_parent_id( 0 );
+ }
+
$changes = $product->get_changes();
// Only update the post when the post data changes.
@@ -165,6 +169,7 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
'post_modified' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getOffsetTimestamp() ) : current_time( 'mysql' ),
'post_modified_gmt' => isset( $changes['date_modified'] ) ? gmdate( 'Y-m-d H:i:s', $product->get_date_modified( 'edit' )->getTimestamp() ) : current_time( 'mysql', 1 ),
'post_type' => 'product_variation',
+ 'post_name' => $product->get_slug( 'edit' ),
);
/**
diff --git a/includes/import/abstract-wc-product-importer.php b/includes/import/abstract-wc-product-importer.php
index 004bd46e4a4..ce660eb2dda 100644
--- a/includes/import/abstract-wc-product-importer.php
+++ b/includes/import/abstract-wc-product-importer.php
@@ -197,6 +197,11 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
unset( $data['manage_stock'], $data['stock_status'], $data['backorders'] );
}
+ if ( 'importing' === $object->get_status() ) {
+ $object->set_status( 'publish' );
+ $object->set_slug( '' );
+ }
+
$result = $object->set_props( array_diff_key( $data, array_flip( array( 'meta_data', 'raw_image_id', 'raw_gallery_image_ids', 'raw_attributes' ) ) ) );
if ( is_wp_error( $result ) ) {
@@ -212,10 +217,6 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
$this->set_image_data( $object, $data );
$this->set_meta_data( $object, $data );
- if ( 'importing' === $object->get_status() ) {
- $object->set_status( 'publish' );
- }
-
$object = apply_filters( 'woocommerce_product_import_pre_insert_product_object', $object, $data );
$object->save();
diff --git a/includes/import/class-wc-product-csv-importer.php b/includes/import/class-wc-product-csv-importer.php
index 57b01ab68f5..d00b8473863 100644
--- a/includes/import/class-wc-product-csv-importer.php
+++ b/includes/import/class-wc-product-csv-importer.php
@@ -107,12 +107,17 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
* @return int|string
*/
protected function parse_relative_field( $field ) {
+ global $wpdb;
+
if ( empty( $field ) ) {
return '';
}
if ( preg_match( '/^id:(\d+)$/', $field, $matches ) ) {
- return intval( $matches[1] );
+ $id = intval( $matches[1] );
+ $original_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_original_id' AND meta_value = %s;", $id ) );
+
+ return $original_id ? $original_id : $id;
}
if ( $id = wc_get_product_id_by_sku( $field ) ) {
@@ -136,6 +141,29 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
return '';
}
+ /**
+ * Parse the ID field.
+ *
+ * If we're not doing an update, create a placeholder product so mapping works
+ * for rows following this one.
+ *
+ * @return int
+ */
+ protected function parse_id_field( $field ) {
+ $field = absint( $field );
+
+ // Not updating? Make sure we have a new placeholder for this ID.
+ if ( $field && ! $this->params['update_existing'] ) {
+ $product = new WC_Product_Simple();
+ $product->set_name( 'Import placeholder for ' . $field );
+ $product->set_status( 'importing' );
+ $product->add_meta_data( '_original_id', $field, true );
+ $field = $product->save();
+ }
+
+ return $field && ! is_wp_error( $field ) ? $field : 0;
+ }
+
/**
* Parse reletive comma-delineated field and return product ID.
*
@@ -357,7 +385,7 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
* column_name => callback.
*/
$data_formatting = array(
- 'id' => 'absint',
+ 'id' => array( $this, 'parse_id_field' ),
'type' => array( $this, 'parse_comma_field' ),
'published' => array( $this, 'parse_bool_field' ),
'featured' => array( $this, 'parse_bool_field' ),