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

Version Description

  • fixed compatibility with WPML ( import multilingual attributes )
  • added possibility to import up & cross sells by product SKU, ID, Title
Download this release

Release Info

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

Code changes from version 1.2.6 to 1.2.7

actions/pmxi_after_xml_import.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ function pmwi_pmxi_after_xml_import($import_id)
4
+ {
5
+ $import = new PMXI_Import_Record();
6
+
7
+ $import->getById($import_id);
8
+
9
+ if ( ! $import->isEmpty() and in_array($import->options['custom_type'], array('product', 'product_variation')) )
10
+ {
11
+ $product_cats = get_terms( 'product_cat', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
12
+
13
+ _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false );
14
+
15
+ $product_tags = get_terms( 'product_tag', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
16
+
17
+ _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false );
18
+ }
19
+ }
actions/pmxi_before_xml_import.php ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <?php
2
+ function pmwi_pmxi_before_xml_import( $import_id )
3
+ {
4
+ delete_option('wp_all_import_' . $import_id . '_parent_product');
5
+ delete_option('wp_all_import_not_linked_products_' . $import_id);
6
+ }
actions/pmxi_do_not_update_existing.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
- function pmwi_pmxi_do_not_update_existing($post_to_update_id, $import_id, $iteration){
3
- $children = get_posts( array(
4
- 'post_parent' => $post_to_update_id,
5
- 'posts_per_page'=> -1,
6
- 'post_type' => 'product_variation',
7
- 'fields' => 'ids',
8
- 'post_status' => 'publish'
9
- ) );
10
-
11
- if ( $children ) {
12
- $postRecord = new PMXI_Post_Record();
13
- foreach ( $children as $child ) {
14
- $postRecord->clear();
15
- $postRecord->getBy(array(
16
- 'post_id' => $child,
17
- 'import_id' => $import_id
18
- ));
19
- if ( ! $postRecord->isEmpty() ) $postRecord->set(array('iteration' => $iteration))->update();
20
- }
21
- }
22
-
23
- }
24
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
filters/pmxi_article_data.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  function pmwi_pmxi_article_data($articleData, $import, $post_to_update){
3
- if ( $articleData['post_type'] == 'product' and $import->options['update_all_data'] == 'no' and ! $import->options['is_update_product_type']){
4
  $articleData['post_type'] = $post_to_update->post_type;
5
  }
6
  return $articleData;
1
  <?php
2
  function pmwi_pmxi_article_data($articleData, $import, $post_to_update){
3
+ if ( ! empty($articleData['post_type']) and $articleData['post_type'] == 'product' and $import->options['update_all_data'] == 'no' and ! $import->options['is_update_product_type']){
4
  $articleData['post_type'] = $post_to_update->post_type;
5
  }
6
  return $articleData;
filters/pmxi_custom_types.php CHANGED
@@ -1,7 +1,9 @@
1
  <?php
2
  function pmwi_pmxi_custom_types($custom_types){
3
- if ( ! empty($custom_types['product']) ) $custom_types['product']->labels->name = __('WooCommerce Products','wpai_woocommerce_addon_plugin');
4
  if ( ! empty($custom_types['product_variation'])) unset($custom_types['product_variation']);
 
 
5
  return $custom_types;
6
  }
7
  ?>
1
  <?php
2
  function pmwi_pmxi_custom_types($custom_types){
3
+ if ( ! empty($custom_types['product']) and class_exists('WooCommerce') ) $custom_types['product']->labels->name = __('WooCommerce Products','wpai_woocommerce_addon_plugin');
4
  if ( ! empty($custom_types['product_variation'])) unset($custom_types['product_variation']);
5
+ if ( ! empty($custom_types['shop_order']) and class_exists('WooCommerce') ) $custom_types['shop_order']->labels->name = __('WooCommerce Orders','wpai_woocommerce_addon_plugin');
6
+
7
  return $custom_types;
8
  }
9
  ?>
models/import/record.php CHANGED
@@ -274,8 +274,8 @@ class PMWI_Import_Record extends PMWI_Model_Record {
274
  $count and $this->data['product_sold_individually'] = array_fill(0, $count, $import->options['product_sold_individually']);
275
  }
276
 
277
- if ("" != $import->options['single_product_weight']){
278
- $this->data['product_weight'] = XmlImportParser::factory($xml, $cxpath, $import->options['single_product_weight'], $file)->parse($records); $tmp_files[] = $file;
279
  }
280
  else{
281
  $count and $this->data['product_weight'] = array_fill(0, $count, "");
@@ -599,11 +599,7 @@ class PMWI_Import_Record extends PMWI_Model_Record {
599
 
600
  foreach ($tmp_files as $file) { // remove all temporary files created
601
  unlink($file);
602
- }
603
-
604
- if ($import->options['put_variation_image_to_gallery']){
605
- add_action('pmxi_gallery_image', array($this, 'wpai_gallery_image'), 10, 3);
606
- }
607
 
608
  return $this->data;
609
  }
@@ -658,7 +654,7 @@ class PMWI_Import_Record extends PMWI_Model_Record {
658
 
659
  // Product type + Downloadable/Virtual
660
  if ($is_new_product or $this->options['update_all_data'] == 'yes' or ($this->options['update_all_data'] == 'no' and $this->options['is_update_product_type'])) {
661
- $product_type_term = term_exists($product_type, 'product_type', 0);
662
  if ( ! empty($product_type_term) and ! is_wp_error($product_type_term) ){
663
  $this->associate_terms( $pid, array( (int) $product_type_term['term_taxonomy_id'] ), 'product_type' );
664
  }
@@ -681,9 +677,9 @@ class PMWI_Import_Record extends PMWI_Model_Record {
681
  $this->pushmeta($pid, '_purchase_note', stripslashes( $product_purchase_note[$i] ) );
682
  $this->pushmeta($pid, '_featured', ($is_featured == "yes") ? 'yes' : 'no' );
683
 
684
- // Dimensions
685
- if ( $is_virtual == 'no' ) {
686
- $this->pushmeta($pid, '_weight', stripslashes( $product_weight[$i] ) );
687
  $this->pushmeta($pid, '_length', stripslashes( $product_length[$i] ) );
688
  $this->pushmeta($pid, '_width', stripslashes( $product_width[$i] ) );
689
  $this->pushmeta($pid, '_height', stripslashes( $product_height[$i] ) );
@@ -712,7 +708,9 @@ class PMWI_Import_Record extends PMWI_Model_Record {
712
 
713
  if ( (int) $product_shipping_class[$i] > 0){
714
 
715
- $t_shipping_class = get_term_by('slug', $p_shipping_class, 'product_shipping_class');
 
 
716
 
717
  if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) )
718
  {
@@ -720,7 +718,7 @@ class PMWI_Import_Record extends PMWI_Model_Record {
720
  }
721
  else
722
  {
723
- $t_shipping_class = term_exists( (int) $p_shipping_class, 'product_shipping_class', 0);
724
 
725
  if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) )
726
  {
@@ -747,7 +745,7 @@ class PMWI_Import_Record extends PMWI_Model_Record {
747
  }
748
  else{
749
 
750
- $t_shipping_class = term_exists($product_shipping_class[$i], 'product_shipping_class', 0);
751
 
752
  if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) )
753
  {
@@ -755,7 +753,7 @@ class PMWI_Import_Record extends PMWI_Model_Record {
755
  }
756
  else
757
  {
758
- $t_shipping_class = term_exists(htmlspecialchars(strtolower($product_shipping_class[$i])), 'product_shipping_class', 0);
759
 
760
  if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) )
761
  {
@@ -898,13 +896,16 @@ class PMWI_Import_Record extends PMWI_Model_Record {
898
  $value = substr($val, 0, 199);
899
 
900
  $term = get_term_by('name', $value, wc_attribute_taxonomy_name( $attr_name ), ARRAY_A);
 
 
 
901
 
902
  if ( empty($term) and !is_wp_error($term) ){
903
 
904
- $term = term_exists($value, wc_attribute_taxonomy_name( $attr_name ));
905
 
906
  if ( empty($term) and !is_wp_error($term) ){
907
- $term = term_exists(htmlspecialchars($value), wc_attribute_taxonomy_name( $attr_name ));
908
  if ( empty($term) and !is_wp_error($term) and intval($attr_data['is_create_taxonomy_terms'][$i])){
909
 
910
  $term = wp_insert_term(
@@ -915,8 +916,10 @@ class PMWI_Import_Record extends PMWI_Model_Record {
915
  }
916
  }
917
 
918
- if ( ! is_wp_error($term) )
 
919
  $attr_values[] = (int) $term['term_taxonomy_id'];
 
920
 
921
  }
922
 
@@ -1125,7 +1128,7 @@ class PMWI_Import_Record extends PMWI_Model_Record {
1125
  } elseif ( 'variable' === $product_type and ! $this->options['link_all_variations'] ) {
1126
 
1127
  // Stock status is always determined by children so sync later
1128
- $stock_status = '';
1129
 
1130
  if ( $product_manage_stock[$i] == 'yes' ) {
1131
  $manage_stock = 'yes';
@@ -1152,61 +1155,13 @@ class PMWI_Import_Record extends PMWI_Model_Record {
1152
 
1153
  } else {
1154
  update_post_meta( $pid, '_stock_status', wc_clean( $product_stock_status[$i] ) );
1155
- }
1156
 
1157
  // Upsells
1158
- if ( !empty( $product_up_sells[$i] ) ) {
1159
- $upsells = array();
1160
- $ids = array_filter(explode(',', $product_up_sells[$i]), 'trim');
1161
- foreach ( $ids as $id ){
1162
- $args = array(
1163
- 'post_type' => 'product',
1164
- 'meta_query' => array(
1165
- array(
1166
- 'key' => '_sku',
1167
- 'value' => $id,
1168
- )
1169
- )
1170
- );
1171
- $query = new WP_Query( $args );
1172
-
1173
- if ( $query->have_posts() ) $upsells[] = $query->post->ID;
1174
-
1175
- wp_reset_postdata();
1176
- }
1177
-
1178
- $this->pushmeta($pid, '_upsell_ids', $upsells);
1179
-
1180
- } else {
1181
- if ($is_new_product or $this->is_update_cf('_upsell_ids')) delete_post_meta( $pid, '_upsell_ids' );
1182
- }
1183
 
1184
  // Cross sells
1185
- if ( !empty( $product_cross_sells[$i] ) ) {
1186
- $crosssells = array();
1187
- $ids = array_filter(explode(',', $product_cross_sells[$i]), 'trim');
1188
- foreach ( $ids as $id ){
1189
- $args = array(
1190
- 'post_type' => 'product',
1191
- 'meta_query' => array(
1192
- array(
1193
- 'key' => '_sku',
1194
- 'value' => $id,
1195
- )
1196
- )
1197
- );
1198
- $query = new WP_Query( $args );
1199
-
1200
- if ( $query->have_posts() ) $crosssells[] = $query->post->ID;
1201
-
1202
- wp_reset_postdata();
1203
- }
1204
-
1205
- $this->pushmeta($pid, '_crosssell_ids', $crosssells);
1206
-
1207
- } else {
1208
- if ($is_new_product or $this->is_update_cf('_crosssell_ids')) delete_post_meta( $pid, '_crosssell_ids' );
1209
- }
1210
 
1211
  // Downloadable options
1212
  if ( $is_downloadable == 'yes' ) {
@@ -1243,37 +1198,71 @@ class PMWI_Import_Record extends PMWI_Model_Record {
1243
  if ( isset( $product_download_type[$i] ) )
1244
  $this->pushmeta($pid, '_download_type', esc_attr( $product_download_type[$i] ));
1245
 
1246
- }
1247
-
1248
  // prepare bulk SQL query
1249
  //$this->executeSQL();
1250
 
1251
  wc_delete_product_transients($pid);
1252
 
1253
- }
1254
 
1255
- public function wpai_gallery_image($pid, $attid, $image_filepath){
 
1256
 
 
 
1257
  $table = $this->wpdb->posts;
1258
 
1259
- $p = $this->wpdb->get_row($this->wpdb->prepare("SELECT * FROM $table WHERE ID = %d;", (int) $pid));
1260
 
1261
- if ($p and $p->post_parent){
 
 
1262
 
1263
- $gallery = explode(",", get_post_meta($p->post_parent, '_product_image_gallery', true));
1264
- if (is_array($gallery)){
1265
- $gallery = array_filter($gallery);
1266
- if ( ! in_array($attid, $gallery) ) $gallery[] = $attid;
1267
- }
1268
- else{
1269
- $gallery = array($attid);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1270
  }
 
1271
 
1272
- update_post_meta($p->post_parent, '_product_image_gallery', implode(',', $gallery));
1273
-
1274
  }
1275
-
1276
- }
 
1277
 
1278
  protected function executeSQL(){
1279
  // prepare bulk SQL query
@@ -1298,34 +1287,12 @@ class PMWI_Import_Record extends PMWI_Model_Record {
1298
  protected function pushmeta($pid, $meta_key, $meta_value){
1299
 
1300
  if (empty($meta_key)) return;
1301
-
1302
- //$table = _get_meta_table( 'post' );
1303
 
1304
  if ( empty($this->articleData['ID']) or $this->is_update_cf($meta_key)){
1305
 
1306
  update_post_meta($pid, $meta_key, $meta_value);
1307
-
1308
- /*$this->wpdb->query($this->wpdb->prepare("DELETE FROM $table WHERE `post_id` = $pid AND `meta_key` = %s", $meta_key));
1309
-
1310
- $this->post_meta_to_insert[] = array(
1311
- 'meta_key' => $meta_key,
1312
- 'meta_value' => $meta_value,
1313
- 'pid' => $pid
1314
- );*/
1315
- }
1316
- /*elseif ($this->is_update_cf($meta_key)){
1317
-
1318
- $this->wpdb->query($this->wpdb->prepare("DELETE FROM $table WHERE `post_id` = $pid AND `meta_key` = %s", $meta_key));
1319
-
1320
- // previous meta field is not found
1321
- $this->post_meta_to_insert[] = array(
1322
- 'meta_key' => $meta_key,
1323
- 'meta_value' => $meta_value,
1324
- 'pid' => $pid
1325
- );
1326
 
1327
- }*/
1328
-
1329
  }
1330
 
1331
  /**
@@ -1358,6 +1325,7 @@ class PMWI_Import_Record extends PMWI_Model_Record {
1358
  if ( ! is_wp_error( $terms ) ) {
1359
  foreach ($terms as $term_info) {
1360
  $term_ids[] = $term_info->term_taxonomy_id;
 
1361
  $this->wpdb->query( $this->wpdb->prepare("UPDATE {$this->wpdb->term_taxonomy} SET count = count - 1 WHERE term_taxonomy_id = %d", $term_info->term_taxonomy_id) );
1362
  }
1363
  $in_tt_ids = "'" . implode( "', '", $term_ids ) . "'";
@@ -1385,6 +1353,7 @@ class PMWI_Import_Record extends PMWI_Model_Record {
1385
  $values[] = $this->wpdb->prepare( "(%d, %d, %d)", $pid, $tt, ++$term_order);
1386
  $this->wpdb->query( "UPDATE {$this->wpdb->term_taxonomy} SET count = count + 1 WHERE term_taxonomy_id = $tt" );
1387
  delete_transient( 'wc_ln_count_' . md5( sanitize_key( $tx_name ) . sanitize_key( $tt ) ) );
 
1388
  }
1389
 
1390
 
@@ -1397,7 +1366,7 @@ class PMWI_Import_Record extends PMWI_Model_Record {
1397
  wp_cache_delete( $pid, $tx_name . '_relationships' );
1398
 
1399
  //_wc_term_recount( $assign_taxes, $tx_name );
1400
- }
1401
 
1402
  function create_taxonomy($attr_name, $logger){
1403
 
@@ -1457,14 +1426,116 @@ class PMWI_Import_Record extends PMWI_Model_Record {
1457
  }
1458
  }
1459
  }
1460
- }
1461
-
1462
  public function _filter_has_cap_unfiltered_html($caps)
1463
  {
1464
  $caps['unfiltered_html'] = true;
1465
  return $caps;
1466
  }
1467
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1468
  function is_update_custom_field($existing_meta_keys, $options, $meta_key){
1469
 
1470
  if ($options['update_all_data'] == 'yes') return true;
274
  $count and $this->data['product_sold_individually'] = array_fill(0, $count, $import->options['product_sold_individually']);
275
  }
276
 
277
+ if ("" != $import->options['single_product_weight']){
278
+ $this->data['product_weight'] = XmlImportParser::factory($xml, $cxpath, $import->options['single_product_weight'], $file)->parse($records); $tmp_files[] = $file;
279
  }
280
  else{
281
  $count and $this->data['product_weight'] = array_fill(0, $count, "");
599
 
600
  foreach ($tmp_files as $file) { // remove all temporary files created
601
  unlink($file);
602
+ }
 
 
 
 
603
 
604
  return $this->data;
605
  }
654
 
655
  // Product type + Downloadable/Virtual
656
  if ($is_new_product or $this->options['update_all_data'] == 'yes' or ($this->options['update_all_data'] == 'no' and $this->options['is_update_product_type'])) {
657
+ $product_type_term = is_exists_term($product_type, 'product_type', 0);
658
  if ( ! empty($product_type_term) and ! is_wp_error($product_type_term) ){
659
  $this->associate_terms( $pid, array( (int) $product_type_term['term_taxonomy_id'] ), 'product_type' );
660
  }
677
  $this->pushmeta($pid, '_purchase_note', stripslashes( $product_purchase_note[$i] ) );
678
  $this->pushmeta($pid, '_featured', ($is_featured == "yes") ? 'yes' : 'no' );
679
 
680
+ // Dimensions
681
+ if ( $is_virtual == 'no' ) {
682
+ $this->pushmeta($pid, '_weight', stripslashes( $product_weight[$i] ) );
683
  $this->pushmeta($pid, '_length', stripslashes( $product_length[$i] ) );
684
  $this->pushmeta($pid, '_width', stripslashes( $product_width[$i] ) );
685
  $this->pushmeta($pid, '_height', stripslashes( $product_height[$i] ) );
708
 
709
  if ( (int) $product_shipping_class[$i] > 0){
710
 
711
+ $t_shipping_class = get_term_by('slug', $p_shipping_class, 'product_shipping_class');
712
+ // For compatibility with WPML plugin
713
+ $t_shipping_class = apply_filters('wp_all_import_term_exists', $t_shipping_class, 'product_shipping_class', $p_shipping_class, null);
714
 
715
  if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) )
716
  {
718
  }
719
  else
720
  {
721
+ $t_shipping_class = is_exists_term( (int) $p_shipping_class, 'product_shipping_class', 0);
722
 
723
  if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) )
724
  {
745
  }
746
  else{
747
 
748
+ $t_shipping_class = is_exists_term($product_shipping_class[$i], 'product_shipping_class', 0);
749
 
750
  if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) )
751
  {
753
  }
754
  else
755
  {
756
+ $t_shipping_class = is_exists_term(htmlspecialchars(strtolower($product_shipping_class[$i])), 'product_shipping_class', 0);
757
 
758
  if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) )
759
  {
896
  $value = substr($val, 0, 199);
897
 
898
  $term = get_term_by('name', $value, wc_attribute_taxonomy_name( $attr_name ), ARRAY_A);
899
+
900
+ // For compatibility with WPML plugin
901
+ $term = apply_filters('wp_all_import_term_exists', $term, wc_attribute_taxonomy_name( $attr_name ), $value, null);
902
 
903
  if ( empty($term) and !is_wp_error($term) ){
904
 
905
+ $term = is_exists_term($value, wc_attribute_taxonomy_name( $attr_name ));
906
 
907
  if ( empty($term) and !is_wp_error($term) ){
908
+ $term = is_exists_term(htmlspecialchars($value), wc_attribute_taxonomy_name( $attr_name ));
909
  if ( empty($term) and !is_wp_error($term) and intval($attr_data['is_create_taxonomy_terms'][$i])){
910
 
911
  $term = wp_insert_term(
916
  }
917
  }
918
 
919
+ if ( ! is_wp_error($term) )
920
+ {
921
  $attr_values[] = (int) $term['term_taxonomy_id'];
922
+ }
923
 
924
  }
925
 
1128
  } elseif ( 'variable' === $product_type and ! $this->options['link_all_variations'] ) {
1129
 
1130
  // Stock status is always determined by children so sync later
1131
+ // $stock_status = '';
1132
 
1133
  if ( $product_manage_stock[$i] == 'yes' ) {
1134
  $manage_stock = 'yes';
1155
 
1156
  } else {
1157
  update_post_meta( $pid, '_stock_status', wc_clean( $product_stock_status[$i] ) );
1158
+ }
1159
 
1160
  // Upsells
1161
+ $this->import_linked_products($pid, $product_up_sells[$i], '_upsell_ids', $is_new_product, $logger, $import->id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1162
 
1163
  // Cross sells
1164
+ $this->import_linked_products($pid, $product_cross_sells[$i], '_crosssell_ids', $is_new_product, $logger, $import->id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1165
 
1166
  // Downloadable options
1167
  if ( $is_downloadable == 'yes' ) {
1198
  if ( isset( $product_download_type[$i] ) )
1199
  $this->pushmeta($pid, '_download_type', esc_attr( $product_download_type[$i] ));
1200
 
1201
+ }
1202
+
1203
  // prepare bulk SQL query
1204
  //$this->executeSQL();
1205
 
1206
  wc_delete_product_transients($pid);
1207
 
1208
+ }
1209
 
1210
+ public function saved_post( $importData )
1211
+ {
1212
 
1213
+ if ( ! in_array($importData['import']->options['custom_type'], array('product', 'product_variation'))) return;
1214
+
1215
  $table = $this->wpdb->posts;
1216
 
1217
+ $p = $this->wpdb->get_row($this->wpdb->prepare("SELECT * FROM $table WHERE ID = %d;", $importData['pid']));
1218
 
1219
+ if ($p)
1220
+ {
1221
+ $post_to_update_id = $importData['pid'];
1222
 
1223
+ update_post_meta( $post_to_update_id, '_product_version', WC_VERSION );
1224
+
1225
+ // [associate linked products]
1226
+ $wp_all_import_not_linked_products = get_option('wp_all_import_not_linked_products_' . $importData['import']->id );
1227
+
1228
+ if ( ! empty($wp_all_import_not_linked_products) )
1229
+ {
1230
+ $post_to_update_sku = get_post_meta($post_to_update_id, '_sku', true);
1231
+
1232
+ foreach ($wp_all_import_not_linked_products as $product)
1233
+ {
1234
+ if ( $product['pid'] != $post_to_update_id && ! empty($product['not_linked_products']) )
1235
+ {
1236
+ if ( in_array($post_to_update_sku, $product['not_linked_products'])
1237
+ or in_array( (string) $post_to_update_id, $product['not_linked_products'])
1238
+ or in_array($p->post_title, $product['not_linked_products'])
1239
+ or in_array($p->post_name, $product['not_linked_products'])
1240
+ )
1241
+ {
1242
+ $linked_products = get_post_meta($product['pid'], $product['type'], true);
1243
+
1244
+ if (empty($linked_products)) $linked_products = array();
1245
+
1246
+ if ( ! in_array($post_to_update_id, $linked_products))
1247
+ {
1248
+ $linked_products[] = $post_to_update_id;
1249
+
1250
+ $importData['logger'] and call_user_func($importData['logger'], sprintf(__('Added to %s list of product ID %d.', 'wpai_woocommerce_addon_plugin'), $product['type'] == '_upsell_ids' ? 'Up-Sells' : 'Cross-Sells', $product['pid']) );
1251
+
1252
+ update_post_meta($product['pid'], $product['type'], $linked_products);
1253
+
1254
+ }
1255
+ }
1256
+ }
1257
+ }
1258
  }
1259
+ // [\associate linked products]
1260
 
1261
+ wc_delete_product_transients($post_to_update_id);
 
1262
  }
1263
+
1264
+
1265
+ }
1266
 
1267
  protected function executeSQL(){
1268
  // prepare bulk SQL query
1287
  protected function pushmeta($pid, $meta_key, $meta_value){
1288
 
1289
  if (empty($meta_key)) return;
 
 
1290
 
1291
  if ( empty($this->articleData['ID']) or $this->is_update_cf($meta_key)){
1292
 
1293
  update_post_meta($pid, $meta_key, $meta_value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1294
 
1295
+ }
 
1296
  }
1297
 
1298
  /**
1325
  if ( ! is_wp_error( $terms ) ) {
1326
  foreach ($terms as $term_info) {
1327
  $term_ids[] = $term_info->term_taxonomy_id;
1328
+ delete_woocommerce_term_meta( $term_info->term_taxonomy_id, 'product_ids' );
1329
  $this->wpdb->query( $this->wpdb->prepare("UPDATE {$this->wpdb->term_taxonomy} SET count = count - 1 WHERE term_taxonomy_id = %d", $term_info->term_taxonomy_id) );
1330
  }
1331
  $in_tt_ids = "'" . implode( "', '", $term_ids ) . "'";
1353
  $values[] = $this->wpdb->prepare( "(%d, %d, %d)", $pid, $tt, ++$term_order);
1354
  $this->wpdb->query( "UPDATE {$this->wpdb->term_taxonomy} SET count = count + 1 WHERE term_taxonomy_id = $tt" );
1355
  delete_transient( 'wc_ln_count_' . md5( sanitize_key( $tx_name ) . sanitize_key( $tt ) ) );
1356
+ delete_woocommerce_term_meta( $tt, 'product_ids' );
1357
  }
1358
 
1359
 
1366
  wp_cache_delete( $pid, $tx_name . '_relationships' );
1367
 
1368
  //_wc_term_recount( $assign_taxes, $tx_name );
1369
+ }
1370
 
1371
  function create_taxonomy($attr_name, $logger){
1372
 
1426
  }
1427
  }
1428
  }
1429
+ }
1430
+
1431
  public function _filter_has_cap_unfiltered_html($caps)
1432
  {
1433
  $caps['unfiltered_html'] = true;
1434
  return $caps;
1435
  }
1436
 
1437
+ function import_linked_products($pid, $products, $type, $is_new_product, $logger, $import_id)
1438
+ {
1439
+ if ( ! $is_new_product and ! $this->is_update_cf($type) ) return;
1440
+
1441
+ if ( ! empty( $products ) )
1442
+ {
1443
+ $not_found = array();
1444
+
1445
+ $linked_products = array();
1446
+
1447
+ $ids = array_filter(explode(',', $products), 'trim');
1448
+
1449
+ foreach ( $ids as $id )
1450
+ {
1451
+ // search linked product by _SKU
1452
+ $args = array(
1453
+ 'post_type' => 'product',
1454
+ 'meta_query' => array(
1455
+ array(
1456
+ 'key' => '_sku',
1457
+ 'value' => $id,
1458
+ )
1459
+ )
1460
+ );
1461
+ $query = new WP_Query( $args );
1462
+
1463
+ $linked_product = false;
1464
+
1465
+ if ( $query->have_posts() )
1466
+ {
1467
+ $linked_product = get_post($query->post->ID);
1468
+ }
1469
+
1470
+ wp_reset_postdata();
1471
+
1472
+ if ( ! $linked_product )
1473
+ {
1474
+ if (is_numeric($id))
1475
+ {
1476
+ // search linked product by ID
1477
+ $query = new WP_Query( array( 'post_type' => 'product', 'post__in' => array( $id ) ) );
1478
+ if ( $query->have_posts() )
1479
+ {
1480
+ $linked_product = get_post($query->post->ID);
1481
+ }
1482
+ wp_reset_postdata();
1483
+ }
1484
+ if ( ! $linked_product )
1485
+ {
1486
+ // search linked product by slug
1487
+ $args = array(
1488
+ 'name' => $id,
1489
+ 'post_type' => 'product',
1490
+ 'post_status' => 'publish',
1491
+ 'numberposts' => 1
1492
+ );
1493
+ $query = get_posts($args);
1494
+ if( $query )
1495
+ {
1496
+ $linked_product = $query[0];
1497
+ }
1498
+ wp_reset_postdata();
1499
+ }
1500
+ }
1501
+
1502
+ if ($linked_product)
1503
+ {
1504
+ $linked_products[] = $linked_product->ID;
1505
+
1506
+ $logger and call_user_func($logger, sprintf(__('Product `%s` with ID `%d` added to %s list.', 'wpai_woocommerce_addon_plugin'), $linked_product->post_title, $linked_product->ID, $type == '_upsell_ids' ? 'Up-Sells' : 'Cross-Sells') );
1507
+ }
1508
+ else
1509
+ {
1510
+ $not_found[] = $id;
1511
+ }
1512
+ }
1513
+
1514
+ // not all linked products founded
1515
+ if ( ! empty($not_found))
1516
+ {
1517
+ $not_founded_linked_products = get_option( 'wp_all_import_not_linked_products_' . $import_id );
1518
+
1519
+ if (empty($not_founded_linked_products)) $not_founded_linked_products = array();
1520
+
1521
+ $not_founded_linked_products[] = array(
1522
+ 'pid' => $pid,
1523
+ 'type' => $type,
1524
+ 'not_linked_products' => $not_found
1525
+ );
1526
+
1527
+ update_option( 'wp_all_import_not_linked_products_' . $import_id, $not_founded_linked_products );
1528
+ }
1529
+
1530
+ $this->pushmeta($pid, $type, $linked_products);
1531
+
1532
+ }
1533
+ else
1534
+ {
1535
+ delete_post_meta( $pid, $type );
1536
+ }
1537
+ }
1538
+
1539
  function is_update_custom_field($existing_meta_keys, $options, $meta_key){
1540
 
1541
  if ($options['update_all_data'] == 'yes') return true;
plugin.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: WP All Import - WooCommerce Add-On
4
  Plugin URI: http://www.wpallimport.com/
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.2.6
7
  Author: Soflyy
8
  */
9
  /**
@@ -24,7 +24,7 @@ define('PMWI_ROOT_URL', rtrim(plugin_dir_url(__FILE__), '/'));
24
  */
25
  define('PMWI_PREFIX', 'pmwi_');
26
 
27
- define('PMWI_FREE_VERSION', '1.2.6');
28
 
29
  define('PMWI_EDITION', 'free');
30
 
3
  Plugin Name: WP All Import - WooCommerce Add-On
4
  Plugin URI: http://www.wpallimport.com/
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.2.7
7
  Author: Soflyy
8
  */
9
  /**
24
  */
25
  define('PMWI_PREFIX', 'pmwi_');
26
 
27
+ define('PMWI_FREE_VERSION', '1.2.7');
28
 
29
  define('PMWI_EDITION', 'free');
30
 
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: 4.4.1
5
- Stable tag: 1.2.6
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,10 @@ The WooCommerce add-on will appear in the Step 4 of WP All Import.
83
 
84
  == Changelog ==
85
 
 
 
 
 
86
  = 1.2.6 =
87
  * fixed setting up shipping class to -1 when «No shipping class» option chosen
88
 
1
  === Import Products from any XML or CSV to WooCommerce ===
2
  Contributors: soflyy, wpallimport
3
  Requires at least: 4.1
4
+ Tested up to: 4.4.2
5
+ Stable tag: 1.2.7
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.2.7 =
87
+ * fixed compatibility with WPML ( import multilingual attributes )
88
+ * added possibility to import up & cross sells by product SKU, ID, Title
89
+
90
  = 1.2.6 =
91
  * fixed setting up shipping class to -1 when «No shipping class» option chosen
92
 
views/admin/import/_tabs/_linked_product.php CHANGED
@@ -6,11 +6,13 @@
6
  <div class="options_group">
7
  <p class="form-field">
8
  <label><?php _e("Up-Sells", "wpai_woocommerce_addon_plugin"); ?></label>
9
- <input type="text" class="" placeholder="<?php _e('Product SKUs, comma separated', 'wpai_woocommerce_addon_plugin');?>" name="single_product_up_sells" style="" value="<?php echo esc_attr($post['single_product_up_sells']) ?>"/>
 
10
  </p>
11
  <p class="form-field">
12
  <label><?php _e("Cross-Sells", "wpai_woocommerce_addon_plugin"); ?></label>
13
- <input type="text" class="" placeholder="<?php _e('Product SKUs, comma separated', 'wpai_woocommerce_addon_plugin');?>" name="single_product_cross_sells" value="<?php echo esc_attr($post['single_product_cross_sells']) ?>"/>
 
14
  </p>
15
  </div> <!-- End options group -->
16
  <div class="options_group grouping show_if_simple show_if_external">
6
  <div class="options_group">
7
  <p class="form-field">
8
  <label><?php _e("Up-Sells", "wpai_woocommerce_addon_plugin"); ?></label>
9
+ <input type="text" class="" name="single_product_up_sells" style="" value="<?php echo esc_attr($post['single_product_up_sells']) ?>"/>
10
+ <a href="#help" class="wpallimport-help" title="<?php _e('Products can be matched by SKU, ID, or Title, and must be comma separated.', 'wpai_woocommerce_addon_plugin'); ?>">?</a>
11
  </p>
12
  <p class="form-field">
13
  <label><?php _e("Cross-Sells", "wpai_woocommerce_addon_plugin"); ?></label>
14
+ <input type="text" class="" name="single_product_cross_sells" value="<?php echo esc_attr($post['single_product_cross_sells']) ?>"/>
15
+ <a href="#help" class="wpallimport-help" title="<?php _e('Products can be matched by SKU, ID, or Title, and must be comma separated.', 'wpai_woocommerce_addon_plugin'); ?>">?</a>
16
  </p>
17
  </div> <!-- End options group -->
18
  <div class="options_group grouping show_if_simple show_if_external">