Import Products from any XML or CSV to WooCommerce - Version 1.4.4

Version Description

  • API: add wp_all_import_regenerate_lookup_tables filter to control lookup tables generation
Download this release

Release Info

Developer soflyy
Plugin Icon 128x128 Import Products from any XML or CSV to WooCommerce
Version 1.4.4
Comparing to
See all releases

Code changes from version 1.4.3 to 1.4.4

actions/pmxi_after_xml_import.php CHANGED
@@ -104,8 +104,12 @@ function pmwi_pmxi_after_xml_import($importID) {
104
  }
105
  delete_option('wp_all_import_not_linked_products_' . $importID);
106
  // Regenerate product lookup tables.
107
- if ( ! wc_update_product_lookup_tables_is_running() ) {
108
- wc_update_product_lookup_tables();
 
 
 
 
109
  }
110
  }
111
  }
104
  }
105
  delete_option('wp_all_import_not_linked_products_' . $importID);
106
  // Regenerate product lookup tables.
107
+ $regenerate_lookup_tables = TRUE;
108
+ $regenerate_lookup_tables = apply_filters('wp_all_import_regenerate_lookup_tables', $regenerate_lookup_tables, $importID);
109
+ if ( $regenerate_lookup_tables && function_exists('wc_update_product_lookup_tables_is_running') && ! wc_update_product_lookup_tables_is_running() ) {
110
+ try {
111
+ wc_update_product_lookup_tables();
112
+ } catch (Exception $e) {}
113
  }
114
  }
115
  }
actions/pmxi_options_tab.php CHANGED
@@ -11,7 +11,7 @@ function pmwi_pmxi_options_tab($isWizard, $post) {
11
  $pmwi_controller->options( $isWizard, $post );
12
  }
13
  if ( $post['custom_type'] == 'product' && class_exists('WooCommerce') ) {
14
- wp_enqueue_script('pmwi-admin-options-script', PMWI_ROOT_URL . '/static/js/admin-options.js', array('jquery'), PMWI_VERSION);
15
- wp_enqueue_style('pmwi-admin-options-style', PMWI_ROOT_URL . '/static/css/admin-options.css', array(), PMWI_VERSION);
16
  }
17
  }
11
  $pmwi_controller->options( $isWizard, $post );
12
  }
13
  if ( $post['custom_type'] == 'product' && class_exists('WooCommerce') ) {
14
+ wp_enqueue_script('pmwi-admin-options-script', PMWI_ROOT_URL . '/static/js/admin-options.js', array('jquery'), PMWI_FREE_VERSION);
15
+ wp_enqueue_style('pmwi-admin-options-style', PMWI_ROOT_URL . '/static/css/admin-options.css', array(), PMWI_FREE_VERSION);
16
  }
17
  }
controllers/controller/admin.php CHANGED
@@ -44,14 +44,14 @@ abstract class PMWI_Controller_Admin extends PMWI_Controller {
44
  if ( ! is_a($wp_styles, 'WP_Styles'))
45
  $wp_styles = new WP_Styles();
46
 
47
- wp_enqueue_style('pmwi-admin-style', PMWI_ROOT_URL . '/static/css/admin.css', array(), PMWI_VERSION);
48
 
49
  if ( version_compare(get_bloginfo('version'), '3.8-RC1') >= 0 ){
50
  wp_enqueue_style('pmwi-admin-style-wp-3.8', PMWI_ROOT_URL . '/static/css/admin-wp-3.8.css');
51
  }
52
 
53
  wp_enqueue_script('pmwi-script', PMWI_ROOT_URL . '/static/js/pmwi.js', array('jquery'));
54
- wp_enqueue_script('pmwi-admin-script', PMWI_ROOT_URL . '/static/js/admin.js', array('jquery', 'jquery-ui-core', 'jquery-ui-resizable', 'jquery-ui-dialog', 'jquery-ui-datepicker', 'jquery-ui-draggable', 'jquery-ui-droppable', 'pmxi-admin-script'), PMWI_VERSION);
55
 
56
  global $woocommerce;
57
 
44
  if ( ! is_a($wp_styles, 'WP_Styles'))
45
  $wp_styles = new WP_Styles();
46
 
47
+ wp_enqueue_style('pmwi-admin-style', PMWI_ROOT_URL . '/static/css/admin.css', array(), PMWI_FREE_VERSION);
48
 
49
  if ( version_compare(get_bloginfo('version'), '3.8-RC1') >= 0 ){
50
  wp_enqueue_style('pmwi-admin-style-wp-3.8', PMWI_ROOT_URL . '/static/css/admin-wp-3.8.css');
51
  }
52
 
53
  wp_enqueue_script('pmwi-script', PMWI_ROOT_URL . '/static/js/pmwi.js', array('jquery'));
54
+ wp_enqueue_script('pmwi-admin-script', PMWI_ROOT_URL . '/static/js/admin.js', array('jquery', 'jquery-ui-core', 'jquery-ui-resizable', 'jquery-ui-dialog', 'jquery-ui-datepicker', 'jquery-ui-draggable', 'jquery-ui-droppable', 'pmxi-admin-script'), PMWI_FREE_VERSION);
55
 
56
  global $woocommerce;
57
 
filters/wp_all_import_existing_meta_keys.php CHANGED
@@ -18,7 +18,7 @@ function pmwi_wp_all_import_existing_meta_keys($existing_meta_keys, $custom_type
18
  $hide_fields[] = '_featured';
19
  }
20
  foreach ($existing_meta_keys as $key => $value) {
21
- if ( in_array($value, $hide_fields) || strpos($value, '_v_') === 0 ) {
22
  unset($existing_meta_keys[$key]);
23
  }
24
  }
18
  $hide_fields[] = '_featured';
19
  }
20
  foreach ($existing_meta_keys as $key => $value) {
21
+ if ( in_array($value, $hide_fields) || strpos($value, '_v_') === 0 || strpos($value, 'attribute_') === 0 ) {
22
  unset($existing_meta_keys[$key]);
23
  }
24
  }
i18n/languages/wpai_woocommerce_addon_plugin-ja.mo CHANGED
File without changes
i18n/languages/wpai_woocommerce_addon_plugin-ja.po CHANGED
File without changes
libraries/XmlImportWooCommerceService.php CHANGED
@@ -162,11 +162,22 @@ final class XmlImportWooCommerceService {
162
  $parentAttributes = get_post_meta($product->get_id(), '_product_attributes', TRUE);
163
  // Sync attribute terms with parent product.
164
  if (!empty($parentAttributes)) {
 
165
  foreach ($parentAttributes as $name => $parentAttribute) {
166
  // Only in case if attribute marked to import as taxonomy terms.
167
  if ($parentAttribute['is_taxonomy']) {
168
- $terms = explode("|", $parentAttribute['value']);
169
- $terms = array_filter($terms);
 
 
 
 
 
 
 
 
 
 
170
  if (!empty($terms)) {
171
  $this->getTaxonomiesService()->associateTerms($parentID, $terms, $name);
172
  }
@@ -174,32 +185,37 @@ final class XmlImportWooCommerceService {
174
  }
175
  }
176
  $isNewProduct = get_post_meta($product->get_id(), self::FLAG_IS_NEW_PRODUCT, true);
 
 
177
  // Sync parent product with variation if at least one variation exist.
178
  if (!empty($variations)) {
179
  /** @var WC_Product_Variable_Data_Store_CPT $data_store */
180
- if (!$this->getImport()->options['link_all_variations'] && (count($variationIDs) > 1 || !$this->getImport()->options['make_simple_product'])) {
181
  $data_store = WC_Data_Store::load( 'product-' . $product->get_type() );
182
  $data_store->sync_price( $product );
183
  $data_store->sync_stock_status( $product );
184
  }
185
  // Set product default attributes.
186
- if ($this->isUpdateDataAllowed('is_update_attributes', $isNewProduct) && $this->getImport()->options['is_default_attributes']) {
187
- $defaultVariation = FALSE;
188
- // Set first variation as the default selection.
189
- if ($this->getImport()->options['default_attributes_type'] == 'first') {
190
- $defaultVariation = array_shift($variations);
191
- }
192
- // Set first in stock variation as the default selection.
193
- if ($this->getImport()->options['default_attributes_type'] == 'instock') {
194
- /** @var \WC_Product_Variation $variation */
195
- foreach ($variations as $variation) {
196
- if ($variation->is_in_stock()) {
197
- $defaultVariation = $variation;
198
- break;
 
 
 
199
  }
200
  }
 
201
  }
202
- $defaultAttributes = $defaultVariation ? $defaultVariation->get_attributes() : array();
203
  $product->set_default_attributes($defaultAttributes);
204
  }
205
  $product->save();
@@ -208,9 +224,11 @@ final class XmlImportWooCommerceService {
208
  $firstVariationID = get_post_meta($product->get_id(), self::FIRST_VARIATION, TRUE);
209
  if ($firstVariationID) {
210
  $parentMeta = get_post_meta($product->get_id(), '');
211
- foreach ($this->getImport()->options['custom_name'] as $customFieldName) {
212
- if ($this->isUpdateCustomField($customFieldName)) {
213
- update_post_meta($firstVariationID, $customFieldName, $parentMeta[$customFieldName][0]);
 
 
214
  }
215
  }
216
  // Sync all ACF fields.
@@ -228,8 +246,7 @@ final class XmlImportWooCommerceService {
228
  }
229
 
230
  update_post_meta($product->get_id(), '_product_attributes', $parentAttributes);
231
- // Make product simple it has less than minimum number of variations.
232
- $minimumVariations = apply_filters('wp_all_import_minimum_number_of_variations', 2, $product->get_id(), $this->getImport()->id);
233
  if (count($variationIDs) < $minimumVariations) {
234
  $this->maybeMakeProductSimple($product, $variationIDs);
235
  }
@@ -267,7 +284,7 @@ final class XmlImportWooCommerceService {
267
  $price = get_post_meta($firstVariationID, '_price', TRUE);
268
  }
269
  if (!empty($parsedData)) {
270
- if (empty($variationIDs)) {
271
  // Sync product data in case variations weren't created for this product.
272
  $simpleProduct = new \WC_Product_Simple($product->get_id());
273
  $simpleProduct->set_stock_status($parsedData['stock_status']);
@@ -300,6 +317,19 @@ final class XmlImportWooCommerceService {
300
  catch(\Exception $e) {
301
  self::getLogger() && call_user_func(self::getLogger(), '<b>ERROR:</b> ' . $e->getMessage());
302
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
303
  do_action('wp_all_import_make_product_simple', $product->get_id(), $this->getImport()->id);
304
  }
305
  }
@@ -334,14 +364,16 @@ final class XmlImportWooCommerceService {
334
  $attributes = $product->get_attributes();
335
  /** @var \WC_Product_Attribute $attribute */
336
  foreach ($attributes as $attributeName => $attribute) {
337
- if ($attribute->is_taxonomy()) {
338
- $attribute_values = $attribute->get_terms();
339
- if (!empty($attribute_values)) {
340
- $terms = [];
341
- foreach ($attribute_values as $key => $object) {
342
- $terms[] = $object->term_id;
343
- }
344
- wp_update_term_count_now($terms, $attributeName);
 
 
345
  }
346
  }
347
  }
@@ -429,9 +461,9 @@ final class XmlImportWooCommerceService {
429
  * @param $meta_key
430
  * @return bool
431
  */
432
- public function isUpdateCustomField($meta_key) {
433
 
434
- $options = $this->getImport()->options;
435
 
436
  if ($options['update_all_data'] == 'yes') {
437
  return TRUE;
162
  $parentAttributes = get_post_meta($product->get_id(), '_product_attributes', TRUE);
163
  // Sync attribute terms with parent product.
164
  if (!empty($parentAttributes)) {
165
+ $variation_attributes = $product->get_variation_attributes();
166
  foreach ($parentAttributes as $name => $parentAttribute) {
167
  // Only in case if attribute marked to import as taxonomy terms.
168
  if ($parentAttribute['is_taxonomy']) {
169
+ $terms = [];
170
+ if (!empty($variation_attributes[$name])) {
171
+ foreach ($variation_attributes[$name] as $attribute_term_slug) {
172
+ $term = get_term_by('slug', $attribute_term_slug, $name);
173
+ if ($term && !is_wp_error($term)) {
174
+ $terms[] = $term->term_taxonomy_id;
175
+ }
176
+ }
177
+ } else {
178
+ $terms = explode("|", $parentAttribute['value']);
179
+ $terms = array_filter($terms);
180
+ }
181
  if (!empty($terms)) {
182
  $this->getTaxonomiesService()->associateTerms($parentID, $terms, $name);
183
  }
185
  }
186
  }
187
  $isNewProduct = get_post_meta($product->get_id(), self::FLAG_IS_NEW_PRODUCT, true);
188
+ // Make product simple it has less than minimum number of variations.
189
+ $minimumVariations = apply_filters('wp_all_import_minimum_number_of_variations', 2, $product->get_id(), $this->getImport()->id);
190
  // Sync parent product with variation if at least one variation exist.
191
  if (!empty($variations)) {
192
  /** @var WC_Product_Variable_Data_Store_CPT $data_store */
193
+ if (!$this->getImport()->options['link_all_variations'] && (count($variationIDs) >= $minimumVariations || !$this->getImport()->options['make_simple_product'])) {
194
  $data_store = WC_Data_Store::load( 'product-' . $product->get_type() );
195
  $data_store->sync_price( $product );
196
  $data_store->sync_stock_status( $product );
197
  }
198
  // Set product default attributes.
199
+ if ($isNewProduct || $this->isUpdateCustomField('_default_attributes')) {
200
+ $defaultAttributes = [];
201
+ if ($this->getImport()->options['is_default_attributes']) {
202
+ $defaultVariation = FALSE;
203
+ // Set first variation as the default selection.
204
+ if ($this->getImport()->options['default_attributes_type'] == 'first') {
205
+ $defaultVariation = array_shift($variations);
206
+ }
207
+ // Set first in stock variation as the default selection.
208
+ if ($this->getImport()->options['default_attributes_type'] == 'instock') {
209
+ /** @var \WC_Product_Variation $variation */
210
+ foreach ($variations as $variation) {
211
+ if ($variation->is_in_stock()) {
212
+ $defaultVariation = $variation;
213
+ break;
214
+ }
215
  }
216
  }
217
+ $defaultAttributes = $defaultVariation ? $defaultVariation->get_attributes() : array();
218
  }
 
219
  $product->set_default_attributes($defaultAttributes);
220
  }
221
  $product->save();
224
  $firstVariationID = get_post_meta($product->get_id(), self::FIRST_VARIATION, TRUE);
225
  if ($firstVariationID) {
226
  $parentMeta = get_post_meta($product->get_id(), '');
227
+ if ("manual" !== $this->getImport()->options['duplicate_matching']) {
228
+ foreach ($this->getImport()->options['custom_name'] as $customFieldName) {
229
+ if ($this->isUpdateCustomField($customFieldName)) {
230
+ update_post_meta($firstVariationID, $customFieldName, maybe_unserialize($parentMeta[$customFieldName][0]));
231
+ }
232
  }
233
  }
234
  // Sync all ACF fields.
246
  }
247
 
248
  update_post_meta($product->get_id(), '_product_attributes', $parentAttributes);
249
+
 
250
  if (count($variationIDs) < $minimumVariations) {
251
  $this->maybeMakeProductSimple($product, $variationIDs);
252
  }
284
  $price = get_post_meta($firstVariationID, '_price', TRUE);
285
  }
286
  if (!empty($parsedData)) {
287
+ if (empty($variationIDs) && $this->getImport()->options['make_simple_product']) {
288
  // Sync product data in case variations weren't created for this product.
289
  $simpleProduct = new \WC_Product_Simple($product->get_id());
290
  $simpleProduct->set_stock_status($parsedData['stock_status']);
317
  catch(\Exception $e) {
318
  self::getLogger() && call_user_func(self::getLogger(), '<b>ERROR:</b> ' . $e->getMessage());
319
  }
320
+ // Delete all variations.
321
+ $children = get_posts(array(
322
+ 'post_parent' => $product->get_id(),
323
+ 'posts_per_page' => -1,
324
+ 'post_type' => 'product_variation',
325
+ 'fields' => 'ids',
326
+ 'post_status' => 'any'
327
+ ));
328
+ if (!empty($children)) {
329
+ foreach ($children as $child) {
330
+ wp_delete_post($child, TRUE);
331
+ }
332
+ }
333
  do_action('wp_all_import_make_product_simple', $product->get_id(), $this->getImport()->id);
334
  }
335
  }
364
  $attributes = $product->get_attributes();
365
  /** @var \WC_Product_Attribute $attribute */
366
  foreach ($attributes as $attributeName => $attribute) {
367
+ if ( ! empty( $attribute ) ) {
368
+ if ($attribute->is_taxonomy()) {
369
+ $attribute_values = $attribute->get_terms();
370
+ if (!empty($attribute_values)) {
371
+ $terms = [];
372
+ foreach ($attribute_values as $key => $object) {
373
+ $terms[] = $object->term_id;
374
+ }
375
+ wp_update_term_count_now($terms, $attributeName);
376
+ }
377
  }
378
  }
379
  }
461
  * @param $meta_key
462
  * @return bool
463
  */
464
+ public function isUpdateCustomField($meta_key) {
465
 
466
+ $options = $this->getImport()->options;
467
 
468
  if ($options['update_all_data'] == 'yes') {
469
  return TRUE;
libraries/importer/products/ImportProduct.php CHANGED
@@ -78,12 +78,7 @@ abstract class ImportProduct extends ImportProductBase {
78
  * Save product data into database.
79
  */
80
  public function save() {
81
- /**
82
- * @since 3.0.0 to set props before save.
83
- */
84
- do_action( 'woocommerce_admin_process_product_object', $this->product );
85
  $this->product->save();
86
- do_action( 'woocommerce_process_product_meta_' . $this->product->get_type(), $this->product->get_id() );
87
  wc_delete_product_transients($this->product->get_id());
88
  }
89
 
78
  * Save product data into database.
79
  */
80
  public function save() {
 
 
 
 
81
  $this->product->save();
 
82
  wc_delete_product_transients($this->product->get_id());
83
  }
84
 
libraries/importer/products/ImportProductBase.php CHANGED
@@ -172,7 +172,7 @@ abstract class ImportProductBase extends ImportBase {
172
  'type' => $type,
173
  'not_linked_products' => $not_found
174
  ];
175
- update_option('wp_all_import_not_linked_products_' . $this->getImport()->id, $not_founded_linked_products);
176
  }
177
  }
178
  return $linked_products;
172
  'type' => $type,
173
  'not_linked_products' => $not_found
174
  ];
175
+ update_option('wp_all_import_not_linked_products_' . $this->getImport()->id, $not_founded_linked_products, false);
176
  }
177
  }
178
  return $linked_products;
plugin.php CHANGED
@@ -3,9 +3,9 @@
3
  Plugin Name: WP All Import - WooCommerce Add-On
4
  Plugin URI: http://www.wpallimport.com/woocommerce-product-import/?utm_source=import-wooco-products-addon-free&utm_medium=wp-plugins-page&utm_campaign=upgrade-to-pro
5
  Description: An extremely easy, drag & drop importer to import WooCommerce simple products. A paid upgrade is available for premium support and support for Variable, Grouped, and External/Affiliate products
6
- Version: 1.4.3
7
  Author: Soflyy
8
- WC tested up to: 3.7.0
9
  */
10
 
11
  if ( ! function_exists( 'is_plugin_active' ) ) {
@@ -25,7 +25,7 @@ if ( is_plugin_active('wpai-woocommerce-add-on/wpai-woocommerce-add-on.php') ) {
25
  }
26
  else {
27
 
28
- define('PMWI_FREE_VERSION', '1.4.3');
29
 
30
  define('PMWI_EDITION', 'free');
31
 
3
  Plugin Name: WP All Import - WooCommerce Add-On
4
  Plugin URI: http://www.wpallimport.com/woocommerce-product-import/?utm_source=import-wooco-products-addon-free&utm_medium=wp-plugins-page&utm_campaign=upgrade-to-pro
5
  Description: An extremely easy, drag & drop importer to import WooCommerce simple products. A paid upgrade is available for premium support and support for Variable, Grouped, and External/Affiliate products
6
+ Version: 1.4.4
7
  Author: Soflyy
8
+ WC tested up to: 4.0.1
9
  */
10
 
11
  if ( ! function_exists( 'is_plugin_active' ) ) {
25
  }
26
  else {
27
 
28
+ define('PMWI_FREE_VERSION', '1.4.4');
29
 
30
  define('PMWI_EDITION', 'free');
31
 
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
  === Import Products from any XML or CSV to WooCommerce ===
2
  Contributors: soflyy, wpallimport
3
  Requires at least: 4.1
4
- Tested up to: 5.2.3
5
- Stable tag: 1.4.3
6
  License: GPLv2 or later
7
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
8
  Tags: woocommerce xml import, woocommerce csv import, woocommerce, import, xml, csv, wp all import, csv import, import csv, xml import, import xml, woocommerce csv importer, woocommerce xml importer, csv importer, csv import suite
@@ -83,6 +83,9 @@ The WooCommerce add-on will appear in the Step 4 of WP All Import.
83
 
84
  == Changelog ==
85
 
 
 
 
86
  = 1.4.3 =
87
  * bug fix: lookup table not updating after import
88
  * bug fix: attributes not re-counting after import
1
  === Import Products from any XML or CSV to WooCommerce ===
2
  Contributors: soflyy, wpallimport
3
  Requires at least: 4.1
4
+ Tested up to: 5.3
5
+ Stable tag: 1.4.4
6
  License: GPLv2 or later
7
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
8
  Tags: woocommerce xml import, woocommerce csv import, woocommerce, import, xml, csv, wp all import, csv import, import csv, xml import, import xml, woocommerce csv importer, woocommerce xml importer, csv importer, csv import suite
83
 
84
  == Changelog ==
85
 
86
+ = 1.4.4 =
87
+ * API: add wp_all_import_regenerate_lookup_tables filter to control lookup tables generation
88
+
89
  = 1.4.3 =
90
  * bug fix: lookup table not updating after import
91
  * bug fix: attributes not re-counting after import