Created
June 10, 2015 08:46
-
-
Save Langmans/9e9dc43ec60cc928813c to your computer and use it in GitHub Desktop.
woocommerce product variation importer - two columns required: post_parent and sku.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
if ( $_SERVER['HTTP_HOST'] != 'localhost' ) { | |
die( 'Only locally enabled! change import-csv.php.' ); | |
} | |
$csv = filter_input( INPUT_GET, 'csv' ); | |
if ( ! $csv ) { | |
?> | |
<form> | |
<p> | |
<label> | |
<select name="csv" required> | |
CSV file | |
<option value="" disabled>Kies</option> | |
<?php | |
if ( $csv_files = glob( 'csv/*.csv' ) ) { | |
foreach ( $csv_files as $file ) { | |
echo '<option>', $file, '</option>'; | |
} | |
}?> | |
</select> | |
</label> | |
</p> | |
<button>Import variations</button> | |
</form> | |
<?php | |
die; | |
} | |
if ( $fh = fopen( $csv, 'r' ) ) { | |
include 'wp-load.php'; | |
set_time_limit( 0 ); | |
error_reporting( - 1 ); | |
ini_set( 'display_errors', 'On' ); | |
$columns = null; | |
while ( ob_get_level() ) { | |
ob_end_flush(); | |
} | |
ob_implicit_flush( true ); | |
//http://woothemes.github.io/woocommerce-rest-api-docs/#products-properties | |
$editable_meta = array( | |
//If the variation is downloadable or not. Downloadable variations give access to a file upon purchase | |
'downloadable' => 'boolean', | |
//If the variation is virtual or not. Virtual variations are intangible and aren’t shipped | |
'virtual' => 'boolean', | |
//SKU refers to a Stock-keeping unit, a unique identifier for each distinct product and service that can be purchased | |
'sku' => 'string', | |
//Variation regular price | |
'regular_price' => 'float', | |
//Variation sale price | |
'sale_price' => 'float', | |
//Sets the sale start date. Date in the YYYY-MM-DD format WRITE-ONLY | |
'sale_price_dates_from' => 'float', | |
//Sets the sale end date. Date in the YYYY-MM-DD format WRITE-ONLY | |
'sale_price_dates_to' => 'float', | |
//Tax status. The options are: taxable, shipping (Shipping only) and none | |
'tax_status' => 'string', | |
//Tax class | |
'tax_class' => 'string', | |
//Enable stock management at variation level | |
'managing_stock' => 'boolean', | |
//Stock quantity. If is a variable variation this value will be used to control stock for all variations, unless you define stock at variation level. | |
'stock_quantity' => 'integer', | |
//Controls whether or not the variation is listed as “in stock” or “out of stock” on the frontend. | |
'in_stock' => 'boolean', | |
//Variation weight in decimal format | |
'weight' => 'string', | |
//List of the variation dimensions. See Dimensions Properties | |
'dimensions' => 'array', | |
//Shipping class slug. Shipping classes are used by certain shipping methods to group similar products | |
'shipping_class' => 'string', | |
//Variation featured image. See Images Properties | |
'images' => 'array', | |
//List of variation attributes. Similar to a simple or variable product, but for variation indicate the attributes used to form the variation. See Attributes Properties | |
'attributes' => 'array', | |
//List of downloadable files. See Downloads Properties | |
'downloads' => 'array', | |
//Amount of times the variation can be downloaded. In write-mode you can sent a blank string for unlimited re-downloads. e.g '' | |
'download_limit' => 'integer', | |
//Number of days that the customer has up to be able to download the varition. In write-mode you can sent a blank string for never expiry. e.g '' | |
'download_expiry' => 'integer', | |
); | |
$str2number = function ( $str ) { | |
$number_unformat = function ( $number, $force_number = true, $dec_point = '.', $thousands_sep = ',' ) { | |
if ( $force_number ) { | |
$number = preg_replace( '/^[^\d]+/', '', $number ); | |
} else if ( preg_match( '/^[^\d]+/', $number ) ) { | |
return false; | |
} | |
$type = ( strpos( $number, $dec_point ) === false ) ? 'int' : 'float'; | |
$number = str_replace( array( $dec_point, $thousands_sep ), array( '.', '' ), $number ); | |
settype( $number, $type ); | |
return $number; | |
}; | |
// 0 -9, . and , | |
$str = preg_replace( '@[^\d,\.]+@', '', $str ); | |
$point_pos = strpos( $str, '.' ); | |
$comma_pos = strpos( $str, ',' ); | |
// both comma and point found, and comma is later then point (comma as decimal seperator); | |
if ( $point_pos && $comma_pos ) { | |
return $number_unformat( $str, | |
true, | |
$point_pos > $comma_pos ? '.' : ',', | |
$point_pos > $comma_pos ? ',' : '.' | |
); | |
} elseif ( $point_pos ) { | |
return $number_unformat( $str, true, '.', '' ); | |
} else { | |
return $number_unformat( $str, true, ',', '' ); | |
} | |
}; | |
while ( $values = fgetcsv( $fh, 1024 * 8, ';' ) ) { | |
sleep( 1 ); | |
if ( ! $columns ) { | |
$columns = $values; | |
if ( ! in_array( 'post_parent', $columns ) ) { | |
die( 'there is no post_parent column in that csv file.' ); | |
} | |
if ( ! in_array( 'sku', $columns ) ) { | |
die( 'there is no sku column in that csv file.' ); | |
} | |
continue; | |
} | |
// convert the csv to assoc array. | |
$row = array(); | |
foreach ( $columns as $i => $column ) { | |
$row[ $column ] = $values[ $i ]; | |
} | |
echo '<hr>'/*, json_encode( $row ), '<br>'*/ | |
; | |
/** @var $parent_product WC_Product_Variable */ | |
/** @var $product WC_Product_Variation */ | |
// find the product by sku. | |
if ( ! ( $product = wc_get_product( wc_get_product_id_by_sku( $row['sku'] ) ) ) ) { | |
$parent_product = wc_get_product( $row['post_parent'] ); | |
if ( ! $parent_product ) { | |
echo 'Parent product not found!<br>'; | |
continue; | |
} | |
/** @var WP_Post $parent_post */ | |
$parent_post = $parent_product->post; | |
$variation_post_id = wp_insert_post( array( | |
'post_author' => $parent_post->post_author, | |
'post_parent' => $row['post_parent'], | |
'post_type' => 'product_variation', | |
'post_status' => 'publish', | |
'ping_status' => 'open', | |
'comment_status' => 'open' | |
) ); | |
update_post_meta( $variation_post_id, '_sku', $row['sku'] ); | |
echo 'Adding variation: ', $variation_post_id, json_encode( $row ), '<br>'; | |
$product = wc_get_product( $variation_post_id ); | |
} else { | |
// var_dump($product); | |
echo 'Updating variation: ', $product->variation_id, json_encode( $row ), '<br>'; | |
} | |
echo 'Title: ', json_encode( $product->get_title() ), '<br>'; | |
foreach ( $editable_meta as $meta_key => $meta_type ) { | |
if ( in_array( $meta_key, $columns ) ) { | |
// it's set in the csv. | |
// convert the value. | |
$new_value = $row[ $meta_key ]; | |
// arrays are a little weird. | |
if ( $meta_type == 'array' ) { | |
// parse_str( $new_value, $new_value ); | |
continue; | |
} else { | |
if ( $meta_type == 'float' || $meta_type == 'integer' ) { | |
$new_value = trim( $new_value ); | |
if ( $new_value !== '' ) { | |
$new_value = $str2number( $new_value ); | |
} | |
} else { | |
settype( $new_value, $meta_type ); | |
} | |
} | |
echo 'Setting meta:', json_encode( compact( 'meta_key', 'new_value' ) ), '<br>'; | |
update_post_meta( $product->variation_id, '_' . $meta_key, $new_value ); | |
} else { | |
echo 'Meta not found:', $meta_key, '(', $meta_type, ')<br>'; | |
} | |
} | |
foreach ( $product->get_attributes() as $attribute_slug => $attribute ) { | |
$options = preg_split( '@\s*|\s*@', $attribute['value'] ); | |
$slug = 'attribute_' . $attribute_slug; | |
if ( isset( $row[ $slug ] ) ) { | |
$val = $row[ $slug ]; | |
echo 'Setting attribute:', json_encode( compact( 'slug', 'val' ) ), '<br>'; | |
update_post_meta( $product->variation_id, $slug, $val ); | |
} else { | |
echo 'Attribute not found in csv: ', $attribute_slug, '<br>'; | |
} | |
} | |
// wc_delete_product_transients( $row['post_parent'] ); | |
// wc_delete_product_transients( $product->variation_id ); | |
// | |
// WC_Product_Variable::sync( $row['post_parent'] ); | |
// WC_Product_Variable::sync( $product->variation_id ); | |
} | |
fclose( $fh ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment