Merge pull request #15618 from woocommerce/fix/15614

Importer; create placeholders when importing products with IDs
This commit is contained in:
Claudiu Lodromanean 2017-06-14 09:59:13 -07:00 committed by GitHub
commit 7dd1cdca0a
5 changed files with 61 additions and 21 deletions

View File

@ -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,

View File

@ -49,7 +49,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<td>
<input type="hidden" name="update_existing" value="0" />
<input type="checkbox" id="woocommerce-importer-update-existing" name="update_existing" value="1" />
<label for="woocommerce-importer-update-existing"><?php esc_html_e( 'If a product being imported matches an existing product ID or SKU, update the existing product data.', 'woocommerce' ); ?></label>
<label for="woocommerce-importer-update-existing"><?php esc_html_e( 'If a product being imported matches an existing product by ID or SKU, update the existing product rather than creating a new product or skipping the row.', 'woocommerce' ); ?></label>
</td>
</tr>
<tr class="woocommerce-importer-advanced hidden">

View File

@ -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' ),
);
/**

View File

@ -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();

View File

@ -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' ),