Add skip existing option

This commit is contained in:
claudiulodro 2017-05-19 10:58:31 -07:00
parent 142f6f5c07
commit cb297ad1b0
7 changed files with 68 additions and 36 deletions

View File

@ -5,12 +5,13 @@
* productImportForm handles the import process.
*/
var productImportForm = function( $form ) {
this.$form = $form;
this.xhr = false;
this.mapping = wc_product_import_params.mapping;
this.position = 0;
this.file = wc_product_import_params.file;
this.security = wc_product_import_params.import_nonce;
this.$form = $form;
this.xhr = false;
this.mapping = wc_product_import_params.mapping;
this.position = 0;
this.file = wc_product_import_params.file;
this.skip_existing = wc_product_import_params.skip_existing;
this.security = wc_product_import_params.import_nonce;
// Number of import successes/failures.
this.imported = 0;
@ -35,11 +36,12 @@
type: 'POST',
url: ajaxurl,
data: {
action : 'woocommerce_do_ajax_product_import',
position : $this.position,
mapping : $this.mapping,
file : $this.file,
security : $this.security
action : 'woocommerce_do_ajax_product_import',
position : $this.position,
mapping : $this.mapping,
file : $this.file,
skip_existing : $this.skip_existing,
security : $this.security
},
dataType: 'json',
success: function( response ) {

View File

@ -203,10 +203,11 @@ class WC_Admin_Importers {
$file = wc_clean( $_POST['file'] );
$params = array(
'start_pos' => isset( $_POST['position'] ) ? absint( $_POST['position'] ) : 0,
'mapping' => isset( $_POST['mapping'] ) ? (array) $_POST['mapping'] : array(),
'lines' => apply_filters( 'woocommerce_product_import_batch_size', 10 ),
'parse' => true,
'start_pos' => isset( $_POST['position'] ) ? absint( $_POST['position'] ) : 0,
'mapping' => isset( $_POST['mapping'] ) ? (array) $_POST['mapping'] : array(),
'skip_existing' => isset( $_POST['skip_existing'] ) ? (bool) $_POST['skip_existing'] : false,
'lines' => apply_filters( 'woocommerce_product_import_batch_size', 10 ),
'parse' => true,
);
$importer = WC_Product_CSV_Importer_Controller::get_importer( $file, $params );

View File

@ -52,6 +52,13 @@ class WC_Product_CSV_Importer_Controller {
*/
protected $delimiter = ',';
/**
* Whether to skip existing products.
*
* @var bool
*/
protected $skip_existing = false;
/**
* Get importer instance.
*
@ -92,6 +99,7 @@ class WC_Product_CSV_Importer_Controller {
);
$this->step = isset( $_REQUEST['step'] ) ? sanitize_key( $_REQUEST['step'] ) : current( array_keys( $this->steps ) );
$this->file = isset( $_REQUEST['file'] ) ? wc_clean( $_REQUEST['file'] ) : '';
$this->skip_existing = isset( $_REQUEST['skip_existing'] ) ? (bool) $_REQUEST['skip_existing'] : false;
}
/**
@ -119,10 +127,11 @@ class WC_Product_CSV_Importer_Controller {
}
$params = array(
'step' => $keys[ $step_index + 1 ],
'file' => $this->file,
'delimiter' => $this->delimiter,
'_wpnonce' => wp_create_nonce( 'woocommerce-csv-importer' ), // wp_nonce_url() escapes & to & breaking redirects.
'step' => $keys[ $step_index + 1 ],
'file' => $this->file,
'delimiter' => $this->delimiter,
'skip_existing' => $this->skip_existing,
'_wpnonce' => wp_create_nonce( 'woocommerce-csv-importer' ), // wp_nonce_url() escapes & to & breaking redirects.
);
return add_query_arg( $params );
@ -300,9 +309,10 @@ class WC_Product_CSV_Importer_Controller {
}
wp_localize_script( 'wc-product-import', 'wc_product_import_params', array(
'import_nonce' => wp_create_nonce( 'wc-product-import' ),
'mapping' => $mapping,
'file' => $this->file,
'import_nonce' => wp_create_nonce( 'wc-product-import' ),
'mapping' => $mapping,
'file' => $this->file,
'skip_existing' => $this->skip_existing,
) );
wp_enqueue_script( 'wc-product-import' );

View File

@ -54,6 +54,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<input type="submit" class="button button-primary button-next" value="<?php esc_attr_e( 'Run the importer', 'woocommerce' ); ?>" name="save_step" />
<input type="hidden" name="file" value="<?php echo esc_attr( $this->file ); ?>" />
<input type="hidden" name="delimiter" value="<?php echo esc_attr( $this->delimiter ); ?>" />
<input type="hidden" name="skip_existing" value="<?php echo (int) $this->skip_existing; ?>" />
<?php wp_nonce_field( 'woocommerce-csv-importer' ); ?>
</div>
</form>

View File

@ -56,6 +56,13 @@ if ( ! defined( 'ABSPATH' ) ) {
<th><label><?php _e( 'CSV Delimiter', 'woocommerce' ); ?></label><br/></th>
<td><input type="text" name="delimiter" placeholder="," size="2" /></td>
</tr>
<tr>
<th><label><?php _e( 'Skip existing products', 'woocommerce' ); ?></label><br/></th>
<td>
<input type="hidden" name="skip_existing" value="0" />
<input type="checkbox" name="skip_existing" value="1" />
</td>
</tr>
</tbody>
</table>
</section>

View File

@ -138,12 +138,8 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* @return WC_Product|WC_Error
*/
protected function process_item( $data ) {
// Ignore IDs and create new products.
// @todo Mike said that we should have something to force create.
$force_create = false;
try {
$object = $this->prepare_product( $data, $force_create );
$object = $this->prepare_product( $data );
if ( is_wp_error( $object ) ) {
return $object;
@ -182,11 +178,10 @@ abstract class WC_Product_Importer implements WC_Importer_Interface {
* Prepare a single product for create or update.
*
* @param array $data Row data.
* @param bool $creating If should force create a new product.
* @return WC_Product|WP_Error
*/
protected function prepare_product( $data, $force_create = false ) {
$id = ! $force_create && isset( $data['id'] ) ? absint( $data['id'] ) : 0;
protected function prepare_product( $data ) {
$id = isset( $data['id'] ) ? absint( $data['id'] ) : 0;
// Type is the most important part here because we need to be using the correct class and methods.
if ( isset( $data['type'] ) ) {

View File

@ -31,12 +31,13 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
*/
public function __construct( $file, $params = array() ) {
$default_args = array(
'start_pos' => 0, // File pointer start.
'end_pos' => -1, // File pointer end.
'lines' => -1, // Max lines to read.
'mapping' => array(), // Column mapping. csv_heading => schema_heading.
'parse' => false, // Whether to sanitize and format data.
'delimiter' => ',', // CSV delimiter.
'start_pos' => 0, // File pointer start.
'end_pos' => -1, // File pointer end.
'lines' => -1, // Max lines to read.
'mapping' => array(), // Column mapping. csv_heading => schema_heading.
'parse' => false, // Whether to sanitize and format data.
'skip_existing' => false, // Whether to skip existing items.
'delimiter' => ',', // CSV delimiter.
);
$this->params = wp_parse_args( $params, $default_args );
@ -270,6 +271,21 @@ class WC_Product_CSV_Importer extends WC_Product_Importer {
);
foreach ( $this->parsed_data as $parsed_data ) {
// Don't import products with IDs or SKUs that already exist if option is true.
if ( $this->params['skip_existing'] ) {
$id = isset( $parsed_data['id'] ) ? absint( $parsed_data['id'] ) : 0;
$sku = isset( $parsed_data['sku'] ) ? esc_attr( $parsed_data['sku'] ) : 0;
if ( $id && wc_get_product( $id ) ) {
$data['failed'][] = new WP_Error( 'woocommerce_product_csv_importer_error', __( 'A product with this ID already exists.', 'woocommerce' ), array( 'id' => $id ) );
continue;
} elseif( $sku && wc_get_product_id_by_sku( $sku ) ) {
$data['failed'][] = new WP_Error( 'woocommerce_product_csv_importer_error', __( 'A product with this SKU already exists.', 'woocommerce' ), array( 'sku' => $sku ) );
continue;
}
}
$result = $this->process_item( $parsed_data );
if ( is_wp_error( $result ) ) {