Product Import Export for WooCommerce - Version 1.5.4

Version Description

  • Updates: Tested OK with WC 3.5.4
  • Bug Fix:- Importing hierarchical category
  • Content Update.
Download this release

Release Info

Developer webtoffee
Plugin Icon 128x128 Product Import Export for WooCommerce
Version 1.5.4
Comparing to
See all releases

Code changes from version 1.5.3 to 1.5.4

includes/class-wf-prodimpexpcsv-admin-screen.php CHANGED
@@ -40,8 +40,12 @@ class WF_ProdImpExpCsv_Admin_Screen {
40
* Admin Scripts
41
*/
42
public function admin_scripts() {
43
- wp_enqueue_style('woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css');
44
- wp_enqueue_style('woocommerce-product-csv-importer', plugins_url(basename(plugin_dir_path(WF_ProdImpExpCsv_FILE)) . '/styles/wf-style.css', basename(__FILE__)), '', '1.4.4', 'screen');
45
}
46
47
/**
40
* Admin Scripts
41
*/
42
public function admin_scripts() {
43
+ $screen = get_current_screen();
44
+ $allowed_creen_id = array('product_page_wf_woocommerce_csv_im_ex');
45
+ if (in_array($screen->id, $allowed_creen_id)) {
46
+ wp_enqueue_style('woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css');
47
+ wp_enqueue_style('woocommerce-product-csv-importer', plugins_url(basename(plugin_dir_path(WF_ProdImpExpCsv_FILE)) . '/styles/wf-style.css', basename(__FILE__)), '', '1.4.4', 'screen');
48
+ }
49
}
50
51
/**
includes/importer/class-wf-csv-parser.php CHANGED
@@ -4,210 +4,206 @@
4
*/
5
class WF_CSV_Parser {
6
7
- var $row;
8
- var $post_type;
9
- var $reserved_fields; // Fields we map/handle (not custom fields)
10
- var $post_defaults; // Default post data
11
- var $postmeta_defaults; // default post meta
12
- var $postmeta_allowed; // post meta validation
13
- var $allowed_product_types; // Allowed product types
14
-
15
- /**
16
- * Constructor
17
- */
18
- public function __construct( $post_type = 'product' ) {
19
-
20
- $this->post_type = $post_type;
21
- $this->reserved_fields = include( 'data/data-wf-reserved-fields.php' );
22
- $this->post_defaults = include( 'data/data-wf-post-defaults.php' );
23
- $this->postmeta_defaults = include( 'data/data-wf-postmeta-defaults.php' );
24
- $this->postmeta_allowed = include( 'data/data-wf-postmeta-allowed.php' );
25
-
26
- $simple_term = get_term_by( 'slug', 'simple', 'product_type' );
27
- $variable_term = get_term_by( 'slug', 'variable', 'product_type' );
28
- $grouped_term = get_term_by( 'slug', 'grouped', 'product_type' );
29
- $external_term = get_term_by( 'slug', 'external', 'product_type' );
30
-
31
- $this->allowed_product_types = array(
32
- 'simple' => $simple_term->term_id,
33
- 'variable' => $variable_term->term_id,
34
- 'grouped' => $grouped_term->term_id,
35
- 'external' => $external_term->term_id
36
- );
37
-
38
- }
39
-
40
- /**
41
- * Format data from the csv file
42
- * @param string $data
43
- * @param string $enc
44
- * @return string
45
- */
46
- public function format_data_from_csv( $data, $enc ) {
47
- return ( $enc == 'UTF-8' ) ? $data : utf8_encode( $data );
48
- }
49
-
50
- /**
51
- * Parse the data
52
- * @param string $file [description]
53
- * @param string $delimiter [description]
54
- * @param array $mapping [description]
55
- * @param integer $start_pos [description]
56
- * @param integer $end_pos [description]
57
- * @return array
58
- */
59
- public function parse_data( $file, $delimiter, $mapping, $start_pos = 0, $end_pos = null, $eval_field ) {
60
- // Set locale
61
- $enc = mb_detect_encoding( $file, 'UTF-8, ISO-8859-1', true );
62
- if ( $enc )
63
- setlocale( LC_ALL, 'en_US.' . $enc );
64
- @ini_set( 'auto_detect_line_endings', true );
65
-
66
- $parsed_data = array();
67
- $raw_headers = array();
68
-
69
- // Put all CSV data into an associative array
70
- if ( ( $handle = fopen( $file, "r" ) ) !== FALSE ) {
71
-
72
- $header = fgetcsv( $handle, 0, $delimiter );
73
- if ( $start_pos != 0 )
74
- fseek( $handle, $start_pos );
75
-
76
- while ( ( $postmeta = fgetcsv( $handle, 0, $delimiter ) ) !== FALSE ) {
77
- $row = array();
78
-
79
- foreach ( $header as $key => $heading ) {
80
- // Heading is the lowercase version of the column name
81
- $s_heading = strtolower( $heading );
82
-
83
- // Check if this heading is being mapped to a different field
84
- if ( isset( $mapping[$s_heading] ) ) {
85
- if ( $mapping[$s_heading] == 'import_as_meta' ) {
86
-
87
- $s_heading = 'meta:' . $s_heading;
88
-
89
- } elseif ( $mapping[$s_heading] == 'import_as_images' ) {
90
-
91
- $s_heading = 'images';
92
-
93
- } else {
94
- $s_heading = esc_attr( $mapping[$s_heading] );
95
- }
96
- }
97
- if( !empty($mapping) )
98
- {
99
foreach ($mapping as $mkey => $mvalue) {
100
- if(trim($mvalue) === trim($heading)){
101
- $s_heading = $mkey;
102
- }
103
}
104
}
105
106
- if ( $s_heading == '' )
107
- continue;
108
-
109
- // Add the heading to the parsed data
110
- $row[$s_heading] = ( isset( $postmeta[$key] ) ) ? $this->format_data_from_csv( $postmeta[$key], $enc ) : '';
111
-
112
- if(!empty($eval_field[strtolower( $heading )]))
113
- $row[$s_heading] = $this->evaluate_field($row[$s_heading], $eval_field[strtolower( $heading )]);
114
-
115
- // Raw Headers stores the actual column name in the CSV
116
- $raw_headers[ $s_heading ] = $heading;
117
- }
118
- $parsed_data[] = $row;
119
-
120
- unset( $postmeta, $row );
121
-
122
- $position = ftell( $handle );
123
-
124
- if ( $end_pos && $position >= $end_pos )
125
- break;
126
- }
127
- fclose( $handle );
128
- }
129
- return array( $parsed_data, $raw_headers, $position );
130
- }
131
-
132
- private function evaluate_field($value, $evaluation_field){
133
-
134
- $processed_value = $value;
135
- if(!empty($evaluation_field)){
136
- $operator = substr($evaluation_field, 0, 1);
137
- if(in_array($operator, array('=', '+', '-', '*', '/', '&'))){
138
- $eval_val = substr($evaluation_field, 1);
139
-
140
- switch($operator){
141
- case '=':
142
- $processed_value = trim($eval_val);
143
- break;
144
- case '+':
145
- $processed_value = $value + $eval_val;
146
- break;
147
- case '-':
148
- $processed_value = $value - $eval_val;
149
- break;
150
- case '*':
151
- $processed_value = $value * $eval_val;
152
- break;
153
- case '/':
154
- $processed_value = $value / $eval_val;
155
- break;
156
- case '&':
157
- if (strpos($eval_val, '[VAL]') !== false) {
158
- $processed_value = str_replace('[VAL]',$value,$eval_val);
159
- }
160
- else{
161
- $processed_value = $value . $eval_val;
162
- }
163
- break;
164
- }
165
- }
166
- }
167
- return $processed_value;
168
- }
169
-
170
- /**
171
- * Parse product
172
- * @param array $item
173
- * @param integer $merge_empty_cells
174
- * @return array
175
- */
176
- public function parse_product( $item, $merge_empty_cells = 0 ) {
177
- global $WF_CSV_Product_Import, $wpdb;
178
- $this->row++;
179
-
180
- $terms_array = $postmeta = $product = array();
181
- $attributes = $default_attributes = $gpf_data = null;
182
-
183
- // Merging
184
- $merging = ( ! empty( $_GET['merge'] ) && $_GET['merge'] ) ? 1 : 0;
185
- //if($item['post_parent']!== '' && $item['parent_sku'] !== ''){
186
-
187
- $this->post_defaults['post_type'] = 'product';
188
- $this->post_type = 'product';
189
- // Post ID field mapping
190
- $post_id = ( ! empty( $item['id'] ) ) ? $item['id'] : 0;
191
- $post_id = ( ! empty( $item['post_id'] ) ) ? $item['post_id'] : $post_id;
192
- if ( $merging ) {
193
-
194
- $product['merging'] = true;
195
-
196
-
197
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __('> Row %s - preparing for merge.', 'wf_csv_import_export'), $this->row ) );
198
-
199
- // Required fields
200
- if ( ! $post_id && empty( $item['sku'] ) ) {
201
-
202
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', __( '> > Cannot merge without id or sku. Importing instead.', 'wf_csv_import_export') );
203
-
204
- $merging = false;
205
- } else {
206
-
207
- // Check product exists
208
- if ( ! $post_id ) {
209
- // Check product to merge exists
210
- $db_query = $wpdb->prepare("
211
SELECT $wpdb->posts.ID
212
FROM $wpdb->posts
213
LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
@@ -215,642 +211,612 @@ class WF_CSV_Parser {
215
AND $wpdb->posts.post_status IN ( 'publish', 'private', 'draft', 'pending', 'future' )
216
AND $wpdb->postmeta.meta_key = '_sku' AND $wpdb->postmeta.meta_value = '%s'
217
", $item['sku']);
218
- $found_product_id = $wpdb->get_var($db_query);
219
- if ( ! $found_product_id ) {
220
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf(__( '> > Skipped. Cannot find product with sku %s. Importing instead.', 'wf_csv_import_export'), $item['sku']) );
221
- $merging = false;
222
-
223
- } else {
224
-
225
- $post_id = $found_product_id;
226
-
227
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf(__( '> > Found product with ID %s.', 'wf_csv_import_export'), $post_id) );
228
-
229
- }
230
- }
231
-
232
- }
233
- }
234
-
235
- if ( ! $merging ) {
236
-
237
- $product['merging'] = false;
238
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __('> Row %s - preparing for import.', 'wf_csv_import_export'), $this->row ) );
239
-
240
- // Required fields
241
- if ( isset($item['post_parent']) && $item['post_parent']=== '' && $item['post_title']=== '') {
242
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', __( '> > Skipped. No post_title set for new product.', 'wf_csv_import_export') );
243
- return new WP_Error( 'parse-error', __( 'No post_title set for new product.', 'wf_csv_import_export' ) );
244
- }
245
- if ( !empty($item['post_parent']) && $item['post_parent']!== '' && $item['post_parent']!== null && $item['parent_sku'] === '' ) {
246
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', __( '> > Skipped. No parent set for new variation product.', 'wf_csv_import_export') );
247
- //return new WP_Error( 'parse-error', __( 'No post_title set for new product.', 'wf_csv_import_export' ) );
248
- return new WP_Error( 'parse-error', __( 'No parent set for new variation product.', 'wf_csv_import_export' ) );
249
- }
250
-
251
- }
252
-
253
- $product['post_id'] = $post_id;
254
-
255
-
256
- // Get post fields
257
- foreach ( $this->post_defaults as $column => $default ) {
258
- if ( isset( $item[ $column ] ) ) $product[ $column ] = $item[ $column ];
259
- }
260
-
261
- // Get custom fields
262
- foreach ( $this->postmeta_defaults as $column => $default ) {
263
- if ( isset( $item[$column] ) )
264
- $postmeta[$column] = (string) $item[$column];
265
- elseif ( isset( $item['_' . $column] ) )
266
- $postmeta[$column] = (string) $item['_' . $column];
267
-
268
- // Check custom fields are valid
269
- if ( isset( $postmeta[$column] ) && isset( $this->postmeta_allowed[$column] ) && ! in_array( $postmeta[$column], $this->postmeta_allowed[$column] ) ) {
270
- $postmeta[$column] = $this->postmeta_defaults[$column];
271
- }
272
- }
273
-
274
- if ( ! $merging ) {
275
- // Merge post meta with defaults
276
- $product = wp_parse_args( $product, $this->post_defaults );
277
- $postmeta = wp_parse_args( $postmeta, $this->postmeta_defaults );
278
- }
279
-
280
- // Handle special meta fields
281
- // price
282
- if ( $merging ) {
283
- if ( ! isset( $postmeta['regular_price'] ) )
284
- $postmeta['regular_price'] = get_post_meta( $post_id, '_regular_price', true );
285
- $postmeta['regular_price'] = $this->hf_currency_formatter($postmeta['regular_price']);
286
- if ( ! isset( $postmeta['sale_price'] ) )
287
- $postmeta['sale_price'] = get_post_meta( $post_id, '_sale_price', true );
288
- $postmeta['sale_price'] = $this->hf_currency_formatter($postmeta['sale_price']);
289
- }
290
-
291
- if ( isset( $postmeta['regular_price'] ) && isset( $postmeta['sale_price'] ) && $postmeta['sale_price'] !== '' ) {
292
- $postmeta['sale_price'] = $this->hf_currency_formatter($postmeta['sale_price']);
293
- $postmeta['regular_price'] = $this->hf_currency_formatter($postmeta['regular_price']);
294
- $price = min( $postmeta['sale_price'], $postmeta['regular_price']);
295
- $postmeta['price'] = $price;
296
- } elseif ( isset( $postmeta['regular_price'] ) ) {
297
- $postmeta['price'] = $this->hf_currency_formatter($postmeta['regular_price']);
298
- }
299
-
300
- // Reset dynamically generated meta
301
- if ( !isset($item['post_parent']) ) {
302
- $postmeta['min_variation_price'] = $postmeta['max_variation_price'] = $postmeta['min_variation_regular_price'] =$postmeta['max_variation_regular_price'] = $postmeta['min_variation_sale_price'] = $postmeta['max_variation_sale_price'] = '';
303
- }
304
-
305
- // upsells
306
- if ( isset( $postmeta['upsell_ids'] ) && ! is_array( $postmeta['upsell_ids'] ) ) {
307
- $ids = array_filter( array_map( 'trim', explode( '|', $postmeta['upsell_ids'] ) ) );
308
- $postmeta['upsell_ids'] = $ids;
309
- }
310
-
311
- // crosssells
312
- if ( isset( $postmeta['crosssell_ids'] ) && ! is_array( $postmeta['crosssell_ids'] ) ) {
313
- $ids = array_filter( array_map( 'trim', explode( '|', $postmeta['crosssell_ids'] ) ) );
314
- $postmeta['crosssell_ids'] = $ids;
315
- }
316
-
317
- // Sale dates
318
- if ( isset( $postmeta['sale_price_dates_from'] ) ) {
319
- $postmeta['sale_price_dates_from'] = empty( $postmeta['sale_price_dates_from'] ) ? '' : strtotime( $postmeta['sale_price_dates_from'] );
320
- }
321
-
322
- if ( isset( $postmeta['sale_price_dates_to'] ) ) {
323
- $postmeta['sale_price_dates_to'] = empty( $postmeta['sale_price_dates_to'] ) ? '' : strtotime( $postmeta['sale_price_dates_to'] );
324
- }
325
-
326
- // Relative stock updates
327
- if ( $merging ) {
328
- if ( isset( $postmeta['stock'] ) ) {
329
-
330
- $postmeta['stock'] = trim( $postmeta['stock'] );
331
-
332
- $mode = substr( $postmeta['stock'], 0, 3 );
333
-
334
- if ( $mode == '(+)' ) {
335
- $old_stock = absint( get_post_meta( $post_id, '_stock', true ) );
336
- $amount = absint( substr( $postmeta['stock'], 3 ) );
337
- $new_stock = $old_stock + $amount;
338
- $postmeta['stock'] = $new_stock;
339
- }
340
-
341
- if ( $mode == '(-)' ) {
342
- $old_stock = absint( get_post_meta( $post_id, '_stock', true ) );
343
- $amount = absint( substr( $postmeta['stock'], 3 ) );
344
- $new_stock = $old_stock - $amount;
345
- $postmeta['stock'] = $new_stock;
346
- }
347
- }
348
- }
349
-
350
- // Format post status
351
- if ( ! empty( $product['post_status'] ) ) {
352
- $product['post_status'] = strtolower( $product['post_status'] );
353
-
354
- if ( empty($item['post_parent']) ) {
355
- if ( ! in_array( $product['post_status'], array( 'publish', 'private', 'draft', 'pending', 'future', 'inherit', 'trash' ) ) ) {
356
- $product['post_status'] = 'publish';
357
- }
358
- } else {
359
- if ( ! in_array( $product['post_status'], array( 'private', 'publish' ) ) ) {
360
- $product['post_status'] = 'publish';
361
- }
362
- }
363
- }
364
-
365
- // Put set core product postmeta into product array
366
- foreach ( $postmeta as $key => $value ) {
367
- $product['postmeta'][] = array( 'key' => '_' . esc_attr($key), 'value' => $value );
368
- }
369
-
370
- /**
371
- * Handle other columns
372
- */
373
- foreach ( $item as $key => $value ) {
374
-
375
- if ( empty($item['post_parent']) && ! $merge_empty_cells && $value == "" )
376
- continue;
377
-
378
- /**
379
- * File path handling
380
- */
381
- if ( $key == 'file_paths' || $key == 'downloadable_files' ) {
382
-
383
- $file_paths = explode( '|', $value );
384
- $_file_paths = array();
385
- foreach ( $file_paths as $file_path ) {
386
- // 2.1
387
- if ( function_exists( 'wc_get_filename_from_url' ) ) {
388
- $file_path = array_map( 'trim', explode( '::', $file_path ) );
389
- if ( sizeof( $file_path ) === 2 ) {
390
- $file_name = $file_path[0];
391
- $file_path = $file_path[1];
392
- } else {
393
- $file_name = wc_get_filename_from_url( $file_path[0] );
394
- $file_path = $file_path[0];
395
- }
396
- $_file_paths[ md5( $file_path ) ] = array(
397
- 'name' => $file_name,
398
- 'file' => $file_path
399
- );
400
- } else {
401
- $file_path = trim( $file_path );
402
- $_file_paths[ md5( $file_path ) ] = $file_path;
403
- }
404
- }
405
- $value = $_file_paths;
406
-
407
- $product['postmeta'][] = array( 'key' => '_' . esc_attr( $key ), 'value' => $value );
408
- }
409
-
410
- elseif ( strstr( $key, 'tax:' ) ) {
411
-
412
- // Get taxonomy
413
- $taxonomy = trim( str_replace( 'tax:', '', $key ) );
414
-
415
- // Exists?
416
- if ( ! taxonomy_exists( $taxonomy ) ) {
417
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __('> > Skipping taxonomy "%s" - it does not exist.', 'wf_csv_import_export'), $taxonomy ) );
418
- continue;
419
- }
420
-
421
- // Product type check
422
- if ( $taxonomy == 'product_type' ) {
423
- $term = strtolower(trim($value));
424
-
425
- if ( ! array_key_exists( $term, $this->allowed_product_types ) ) {
426
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __('> > > Product type "%s" not allowed - using simple.', 'wf_csv_import_export'), $term ) );
427
- $term_id = $this->allowed_product_types['simple'];
428
- } else {
429
- $term_id = $this->allowed_product_types[ $term ];
430
- }
431
-
432
- // Add to array
433
- $terms_array[] = array(
434
- 'taxonomy' => $taxonomy,
435
- 'terms' => array( $term_id )
436
- );
437
-
438
- continue;
439
- }
440
-
441
- // Get terms - ID => parent
442
- $terms = array();
443
- $raw_terms = explode( '|', $value );
444
- $raw_terms = array_map( 'trim', $raw_terms );
445
-
446
- // Handle term hierachy (>)
447
- foreach ( $raw_terms as $raw_term ) {
448
-
449
- if ( strstr( $raw_term, '>' ) ) {
450
-
451
- $raw_term = explode( '>', $raw_term );
452
- $raw_term = array_map( 'trim', $raw_term );
453
-
454
- if(WC()->version < '2.7.0')
455
- {
456
- $raw_term = array_map( 'wp_specialchars', $raw_term );
457
- $raw_term = array_filter( $raw_term );
458
-
459
- }
460
- else
461
- {
462
- $raw_term = array_map( 'esc_html', $raw_term );
463
- $raw_term = array_filter( $raw_term );
464
465
- }
466
-
467
- $parent = 0;
468
- $loop = 0;
469
470
- foreach ( $raw_term as $term ) {
471
- $loop ++;
472
- $term_id = '';
473
-
474
- if ( isset( $this->inserted_terms[ $taxonomy ][ $parent ][ $term ] ) ) {
475
- $term_id = $this->inserted_terms[ $taxonomy ][ $parent ][ $term ];
476
- } elseif ( $term ) {
477
-
478
- /**
479
- * Check term existance
480
- */
481
- $term_may_exist = term_exists( $term, $taxonomy, absint( $parent ) );
482
-
483
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __( '> > (' . __LINE__ . ') Term %s (%s) exists? %s', 'wf_csv_import_export' ), sanitize_text_field( $term ), esc_html( $taxonomy ), $term_may_exist ? print_r( $term_may_exist, true ) : '-' ) );
484
-
485
- if ( is_array( $term_may_exist ) ) {
486
- $possible_term = get_term( $term_may_exist['term_id'], 'product_cat' );
487
488
- if (!empty($possible_term) && $possible_term->parent == $parent ) {
489
- $term_id = $term_may_exist['term_id'];
490
- }
491
- }
492
493
- if ( ! $term_id ) {
494
495
- // Create appropriate slug
496
- $slug = array();
497
498
- for ( $i = 0; $i < $loop; $i ++ )
499
- $slug[] = $raw_term[ $i ];
500
501
- $slug = sanitize_title( implode( '-', $slug ) );
502
503
- $t = wp_insert_term( $term, $taxonomy, array( 'parent' => $parent, 'slug' => $slug ) );
504
505
- if ( ! is_wp_error( $t ) ) {
506
- $term_id = $t['term_id'];
507
- } else {
508
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __( '> > (' . __LINE__ . ') Failed to import term %s, parent %s - %s', 'wf_csv_import_export' ), sanitize_text_field( $term ), sanitize_text_field( $parent ), sanitize_text_field( $taxonomy ) ) );
509
- break;
510
- }
511
- }
512
513
- $this->inserted_terms[$taxonomy][$parent][$term] = $term_id;
514
515
- }
516
517
- if ( ! $term_id )
518
- break;
519
520
- // Add to product terms, ready to set if this is the final term
521
- if ( sizeof( $raw_term ) == $loop )
522
- $terms[] = $term_id;
523
524
- $parent = $term_id;
525
- }
526
527
- } else {
528
529
- $term_id = '';
530
- $raw_term = (WC()->version < '2.7.0') ? wp_specialchars( $raw_term ) : esc_html( $raw_term );
531
532
- if ( isset( $this->inserted_terms[$taxonomy][0][$raw_term] ) ) {
533
534
- $term_id = $this->inserted_terms[$taxonomy][0][$raw_term];
535
536
- } elseif ( $raw_term ) {
537
538
- // Check term existance
539
- $term_exists = term_exists( $raw_term, $taxonomy, 0 );
540
- $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : 0;
541
542
- if ( ! $term_id ) {
543
- $t = wp_insert_term( trim( $raw_term ), $taxonomy, array( 'parent' => 0 ) );
544
545
- if ( ! is_wp_error( $t ) ) {
546
- $term_id = $t['term_id'];
547
- } else {
548
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __( '> > Failed to import term %s %s', 'wf_csv_import_export' ), esc_html($raw_term), esc_html($taxonomy) ) );
549
- break;
550
- }
551
- }
552
553
- $this->inserted_terms[$taxonomy][0][$raw_term] = $term_id;
554
555
- }
556
557
- // Store terms for later insertion
558
- if ( $term_id )
559
- $terms[] = $term_id;
560
561
- }
562
563
- }
564
565
- // Any defined?
566
- if ( sizeof( $terms ) == 0 )
567
- continue;
568
569
- // Add to array
570
- $terms_array[] = array(
571
- 'taxonomy' => $taxonomy,
572
- 'terms' => $terms
573
- );
574
- }
575
576
- /**
577
- * Handle Attributes
578
- */
579
- elseif ( strstr( $key, 'attribute:' ) ) {
580
581
- $attribute_key = sanitize_title( trim( str_replace( 'attribute:', '', $key ) ) );
582
- $attribute_name = str_replace( 'attribute:', '', $WF_CSV_Product_Import->raw_headers[ $key ] );
583
584
- if ( ! $attribute_key )
585
- continue;
586
587
- // Taxonomy
588
- if ( substr( $attribute_key, 0, 3 ) == 'pa_' ) {
589
590
- $taxonomy = $attribute_key;
591
592
- // Exists?
593
- if ( ! taxonomy_exists( $taxonomy ) ) {
594
-
595
596
- $nicename = strtolower( sanitize_title( str_replace( 'pa_', '', $taxonomy ) ) );
597
-
598
- $attribute_label = ucwords(str_replace('-',' ',$nicename)); // for importing attribute name as human readable string
599
-
600
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __('> > Attribute taxonomy "%s" does not exist. Adding it. Nicename: %s', 'wf_csv_import_export'), $taxonomy, $nicename ) );
601
602
- $exists_in_db = $wpdb->get_var( "SELECT attribute_id FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = '" . $nicename . "';" );
603
604
- if ( ! $exists_in_db ) {
605
- // Create the taxonomy
606
- $wpdb->insert( $wpdb->prefix . "woocommerce_attribute_taxonomies", array( 'attribute_name' => $nicename, 'attribute_label' => $attribute_label, 'attribute_type' => 'select', 'attribute_orderby' => 'menu_order' ) );
607
- } else {
608
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __('> > Attribute taxonomy %s already exists in DB.', 'wf_csv_import_export'), $taxonomy ) );
609
- }
610
611
- // Register the taxonomy now so that the import works!
612
- register_taxonomy( $taxonomy,
613
- array( 'product', 'product_variation' ),
614
- array(
615
- 'hierarchical' => true,
616
- 'show_ui' => false,
617
- 'query_var' => true,
618
- 'rewrite' => false,
619
- )
620
- );
621
- }
622
623
- // Get terms
624
- $terms = array();
625
- $raw_terms = explode( '|', $value );
626
- if(WC()->version < '2.7.0')
627
- {
628
- $raw_terms = array_map( 'wp_specialchars', $raw_terms );
629
- $raw_terms = array_map( 'trim', $raw_terms );
630
-
631
- }else{
632
-
633
- $raw_terms = array_map( 'esc_html', $raw_terms );
634
- $raw_terms = array_map( 'trim', $raw_terms );
635
-
636
- }
637
-
638
- if ( sizeof( $raw_terms ) > 0 ) {
639
-
640
- foreach ( $raw_terms as $raw_term ) {
641
-
642
- if ( empty( $raw_term ) && 0 != $raw_term ) {
643
- continue;
644
- }
645
-
646
- // Check term existance
647
- $term_exists = term_exists( $raw_term, $taxonomy, 0 );
648
- $term_id = is_array( $term_exists ) ? $term_exists['term_id'] : 0;
649
-
650
- if ( ! $term_id ) {
651
- $t = wp_insert_term( trim( $raw_term ), $taxonomy );
652
-
653
- if ( ! is_wp_error( $t ) ) {
654
- $term_id = $t['term_id'];
655
-
656
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __( '> > Inserted Raw Term %s ID = %s', 'wf_csv_import_export' ), esc_html( $raw_term ), $term_id ) );
657
- } else {
658
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __( '> > Failed to import term %s %s', 'wf_csv_import_export' ), esc_html($raw_term), esc_html($taxonomy) ) );
659
- break;
660
- }
661
- } else {
662
- $WF_CSV_Product_Import->hf_log_data_change( 'csv-import', sprintf( __( '> > Raw Term %s ID = %s', 'wf_csv_import_export' ), esc_html( $raw_term ), $term_id ) );
663
- }
664
-
665
- if ( $term_id ) {
666
- $terms[] = $term_id;
667
- }
668
- }
669
-
670
- }
671
-
672
- // Add to array
673
- $terms_array[] = array(
674
- 'taxonomy' => $taxonomy,
675
- 'terms' => $terms
676
- );
677
-
678
- // Ensure we have original attributes
679
- if ( is_null( $attributes ) && $merging ) {
680
- $attributes = array_filter( (array) maybe_unserialize( get_post_meta( $post_id, '_product_attributes', true ) ) );
681
- } elseif ( is_null( $attributes ) ) {
682
- $attributes = array();
683
- }
684
-
685
- // Set attribute
686
- if ( ! isset( $attributes[$taxonomy] ) )
687
- $attributes[$taxonomy] = array();
688
-
689
- $attributes[$taxonomy]['name'] = $taxonomy;
690
- $attributes[$taxonomy]['value'] = null;
691
- $attributes[$taxonomy]['is_taxonomy'] = 1;
692
-
693
- if ( ! isset( $attributes[$taxonomy]['position'] ) )
694
- $attributes[$taxonomy]['position'] = 0;
695
- if ( ! isset( $attributes[$taxonomy]['is_visible'] ) )
696
- $attributes[$taxonomy]['is_visible'] = 1;
697
- if ( ! isset( $attributes[$taxonomy]['is_variation'] ) )
698
- $attributes[$taxonomy]['is_variation'] = 0;
699
-
700
- } else {
701
-
702
- if ( ! $value || ! $attribute_key ) continue;
703
-
704
- // Set attribute
705
- if ( ! isset( $attributes[$attribute_key] ) )
706
- $attributes[$attribute_key] = array();
707
-
708
- $attributes[$attribute_key]['name'] = $attribute_name;
709
- $attributes[$attribute_key]['value'] = $value;
710
- $attributes[$attribute_key]['is_taxonomy'] = 0;
711
-
712
- if ( ! isset( $attributes[$attribute_key]['position'] ) )
713
- $attributes[$attribute_key]['position'] = 0;
714
- if ( ! isset( $attributes[$attribute_key]['is_visible'] ) )
715
- $attributes[$attribute_key]['is_visible'] = 1;
716
- if ( ! isset( $attributes[$attribute_key]['is_variation'] ) )
717
- $attributes[$attribute_key]['is_variation'] = 0;
718
- }
719
-
720
- }
721
-
722
- /**
723
- * Handle Attributes Data - position|is_visible|is_variation
724
- */
725
- elseif ( strstr( $key, 'attribute_data:' ) ) {
726
-
727
- $attribute_key = sanitize_title( trim( str_replace( 'attribute_data:', '', $key ) ) );
728
-
729
- if ( ! $attribute_key ) {
730
- continue;
731
- }
732
-
733
- $values = explode( '|', $value );
734
- $position = isset( $values[0] ) ? (int) $values[0] : 0;
735
- $visible = isset( $values[1] ) ? (int) $values[1] : 1;
736
- $variation = isset( $values[2] ) ? (int) $values[2] : 0;
737
-
738
- // Ensure we have original attributes
739
- if ( ! isset( $attributes[ $attribute_key ] ) ) {
740
- if ( $merging ) {
741
- $existing_attributes = array_filter( (array) maybe_unserialize( get_post_meta( $post_id, '_product_attributes', true ) ) );
742
- $attributes[ $attribute_key ] = isset( $existing_attributes[ $attribute_key ] ) ? $existing_attributes[ $attribute_key ] : array();
743
- } else {
744
- $attributes[ $attribute_key ] = array();
745
- }
746
- }
747
-
748
- $attributes[ $attribute_key ]['position'] = $position;
749
- $attributes[ $attribute_key ]['is_visible'] = $visible;
750
- $attributes[ $attribute_key ]['is_variation'] = $variation;
751
- }
752
-
753
- /**
754
- * Handle Attributes Default Values
755
- */
756
- elseif ( strstr( $key, 'attribute_default:' ) ) {
757
-
758
- $attribute_key = sanitize_title( trim( str_replace( 'attribute_default:', '', $key ) ) );
759
-
760
- if ( ! $attribute_key ) continue;
761
-
762
- // Ensure we have original attributes
763
- if ( is_null( $default_attributes ) && $merging ) {
764
- $default_attributes = array_filter( (array) maybe_unserialize( get_post_meta( $post_id, '_default_attributes', true ) ) );
765
- } elseif ( is_null( $default_attributes ) ) {
766
- $default_attributes = array();
767
- }
768
-
769
- $default_attributes[ $attribute_key ] = $value;
770
- }
771
-
772
- /**
773
- * Handle gpf: google product feed columns
774
- */
775
- elseif ( strstr( $key, 'gpf:' ) ) {
776
-
777
- $gpf_key = trim( str_replace( 'gpf:', '', $key ) );
778
-
779
- // Get original values
780
- if ( is_null( $gpf_data ) && $merging ) {
781
- $gpf_data = array_filter( (array) maybe_unserialize( get_post_meta( $post_id, '_woocommerce_gpf_data', true ) ) );
782
- } elseif ( is_null( $gpf_data ) ) {
783
- $gpf_data = array(
784
- 'availability' => '',
785
- 'condition' => '',
786
- 'brand' => '',
787
- 'product_type' => '',
788
- 'google_product_category' => '',
789
- 'gtin' => '',
790
- 'mpn' => '',
791
- 'gender' => '',
792
- 'age_group' => '',
793
- 'color' => '',
794
- 'size' => ''
795
- );
796
- }
797
-
798
- $gpf_data[$gpf_key] = $value;
799
-
800
- }
801
-
802
- /**
803
- * Handle upsell SKUs which we cannot assign until we get IDs later on
804
- */
805
- elseif ( strstr( $key, 'upsell_skus' ) ) {
806
- if ( $value ) {
807
- $skus = array_filter( array_map( 'trim', explode( '|', $value ) ) );
808
- $product['upsell_skus'] = $skus;
809
- }
810
- }
811
-
812
- /**
813
- * Handle crosssells SKUs which we cannot assign until we get IDs later on
814
- */
815
- elseif ( strstr( $key, 'crosssell_skus' ) ) {
816
- if ( $value ) {
817
- $skus = array_filter( array_map( 'trim', explode( '|', $value ) ) );
818
- $product['crosssell_skus'] = $skus;
819
- }
820
- }
821
-
822
- }
823
-
824
- // Remove empty attribues
825
- if(!empty($attributes))
826
- foreach ( $attributes as $key => $value ) {
827
- if ( ! isset($value['name']) ) unset( $attributes[$key] );
828
- }
829
-
830
- /**
831
- * Handle images
832
- */
833
- if ( ! empty( $item['images'] ) ) {
834
- $images = array_map( 'trim', explode( '|', $item['images'] ) );
835
- } else {
836
- $images = '';
837
- }
838
-
839
- $product['postmeta'][] = array( 'key' => '_default_attributes', 'value' => $default_attributes );
840
- $product['attributes'] = $attributes;
841
- $product['gpf_data'] = $gpf_data;
842
- $product['images'] = $images;
843
- $product['terms'] = $terms_array;
844
- $product['sku'] = ( ! empty( $item['sku'] ) ) ? $item['sku'] : '';
845
- $product['post_title'] = ( ! empty( $item['post_title'] ) ) ? $item['post_title'] : '';
846
- $product['post_type'] = $this->post_type;
847
- unset( $item, $terms_array, $postmeta, $attributes, $gpf_data, $images );
848
-
849
- return $product;
850
- }
851
- public function hf_currency_formatter($price){
852
-
853
- $decimal_seperator = wc_get_price_decimal_separator();
854
- return preg_replace("[^0-9\\'.$decimal_seperator.']", "", $price);
855
}
856
}
4
*/
5
class WF_CSV_Parser {
6
7
+ var $row;
8
+ var $post_type;
9
+ var $reserved_fields; // Fields we map/handle (not custom fields)
10
+ var $post_defaults; // Default post data
11
+ var $postmeta_defaults; // default post meta
12
+ var $postmeta_allowed; // post meta validation
13
+ var $allowed_product_types; // Allowed product types
14
+
15
+ /**
16
+ * Constructor
17
+ */
18
+
19
+ public function __construct($post_type = 'product') {
20
+
21
+ $this->post_type = $post_type;
22
+ $this->reserved_fields = include( 'data/data-wf-reserved-fields.php' );
23
+ $this->post_defaults = include( 'data/data-wf-post-defaults.php' );
24
+ $this->postmeta_defaults = include( 'data/data-wf-postmeta-defaults.php' );
25
+ $this->postmeta_allowed = include( 'data/data-wf-postmeta-allowed.php' );
26
+
27
+ $simple_term = get_term_by('slug', 'simple', 'product_type');
28
+ $variable_term = get_term_by('slug', 'variable', 'product_type');
29
+ $grouped_term = get_term_by('slug', 'grouped', 'product_type');
30
+ $external_term = get_term_by('slug', 'external', 'product_type');
31
+
32
+ $this->allowed_product_types = array(
33
+ 'simple' => $simple_term->term_id,
34
+ 'variable' => $variable_term->term_id,
35
+ 'grouped' => $grouped_term->term_id,
36
+ 'external' => $external_term->term_id
37
+ );
38
+ }
39
+
40
+ /**
41
+ * Format data from the csv file
42
+ * @param string $data
43
+ * @param string $enc
44
+ * @return string
45
+ */
46
+ public function format_data_from_csv($data, $enc) {
47
+ return ( $enc == 'UTF-8' ) ? $data : utf8_encode($data);
48
+ }
49
+
50
+ /**
51
+ * Parse the data
52
+ * @param string $file [description]
53
+ * @param string $delimiter [description]
54
+ * @param array $mapping [description]
55
+ * @param integer $start_pos [description]
56
+ * @param integer $end_pos [description]
57
+ * @return array
58
+ */
59
+ public function parse_data($file, $delimiter, $mapping, $start_pos = 0, $end_pos = null, $eval_field) {
60
+ // Set locale
61
+ $enc = mb_detect_encoding($file, 'UTF-8, ISO-8859-1', true);
62
+ if ($enc)
63
+ setlocale(LC_ALL, 'en_US.' . $enc);
64
+ @ini_set('auto_detect_line_endings', true);
65
+
66
+ $parsed_data = array();
67
+ $raw_headers = array();
68
+
69
+ // Put all CSV data into an associative array
70
+ if (( $handle = fopen($file, "r") ) !== FALSE) {
71
+
72
+ $header = fgetcsv($handle, 0, $delimiter);
73
+ if ($start_pos != 0)
74
+ fseek($handle, $start_pos);
75
+
76
+ while (( $postmeta = fgetcsv($handle, 0, $delimiter) ) !== FALSE) {
77
+ $row = array();
78
+
79
+ foreach ($header as $key => $heading) {
80
+ // Heading is the lowercase version of the column name
81
+ $s_heading = strtolower($heading);
82
+
83
+ // Check if this heading is being mapped to a different field
84
+ if (isset($mapping[$s_heading])) {
85
+ if ($mapping[$s_heading] == 'import_as_meta') {
86
+
87
+ $s_heading = 'meta:' . $s_heading;
88
+ } elseif ($mapping[$s_heading] == 'import_as_images') {
89
+
90
+ $s_heading = 'images';
91
+ } else {
92
+ $s_heading = esc_attr($mapping[$s_heading]);
93
+ }
94
+ }
95
+ if (!empty($mapping)) {
96
foreach ($mapping as $mkey => $mvalue) {
97
+ if (trim($mvalue) === trim($heading)) {
98
+ $s_heading = $mkey;
99
+ }
100
}
101
}
102
103
+ if ($s_heading == '')
104
+ continue;
105
+
106
+ // Add the heading to the parsed data
107
+ $row[$s_heading] = ( isset($postmeta[$key]) ) ? $this->format_data_from_csv($postmeta[$key], $enc) : '';
108
+
109
+ if (!empty($eval_field[strtolower($heading)]))
110
+ $row[$s_heading] = $this->evaluate_field($row[$s_heading], $eval_field[strtolower($heading)]);
111
+
112
+ // Raw Headers stores the actual column name in the CSV
113
+ $raw_headers[$s_heading] = $heading;
114
+ }
115
+ $parsed_data[] = $row;
116
+
117
+ unset($postmeta, $row);
118
+
119
+ $position = ftell($handle);
120
+
121
+ if ($end_pos && $position >= $end_pos)
122
+ break;
123
+ }
124
+ fclose($handle);
125
+ }
126
+ return array($parsed_data, $raw_headers, $position);
127
+ }
128
+
129
+ private function evaluate_field($value, $evaluation_field) {
130
+
131
+ $processed_value = $value;
132
+ if (!empty($evaluation_field)) {
133
+ $operator = substr($evaluation_field, 0, 1);
134
+ if (in_array($operator, array('=', '+', '-', '*', '/', '&'))) {
135
+ $eval_val = substr($evaluation_field, 1);
136
+
137
+ switch ($operator) {
138
+ case '=':
139
+ $processed_value = trim($eval_val);
140
+ break;
141
+ case '+':
142
+ $processed_value = $value + $eval_val;
143
+ break;
144
+ case '-':
145
+ $processed_value = $value - $eval_val;
146
+ break;
147
+ case '*':
148
+ $processed_value = $value * $eval_val;
149
+ break;
150
+ case '/':
151
+ $processed_value = $value / $eval_val;
152
+ break;
153
+ case '&':
154
+ if (strpos($eval_val, '[VAL]') !== false) {
155
+ $processed_value = str_replace('[VAL]', $value, $eval_val);
156
+ } else {
157
+ $processed_value = $value . $eval_val;
158
+ }
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ return $processed_value;
164
+ }
165
+
166
+ /**
167
+ * Parse product
168
+ * @param array $item
169
+ * @param integer $merge_empty_cells
170
+ * @return array
171
+ */
172
+ public function parse_product($item, $merge_empty_cells = 0) {
173
+ global $WF_CSV_Product_Import, $wpdb;
174
+ $this->row++;
175
+
176
+ $terms_array = $postmeta = $product = array();
177
+ $attributes = $default_attributes = $gpf_data = null;
178
+
179
+ // Merging
180
+ $merging = (!empty($_GET['merge']) && $_GET['merge'] ) ? 1 : 0;
181
+ //if($item['post_parent']!== '' && $item['parent_sku'] !== ''){
182
+
183
+ $this->post_defaults['post_type'] = 'product';
184
+ $this->post_type = 'product';
185
+ // Post ID field mapping
186
+ $post_id = (!empty($item['id']) ) ? $item['id'] : 0;
187
+ $post_id = (!empty($item['post_id']) ) ? $item['post_id'] : $post_id;
188
+ if ($merging) {
189
+
190
+ $product['merging'] = true;
191
+
192
+
193
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> Row %s - preparing for merge.', 'wf_csv_import_export'), $this->row));
194
+
195
+ // Required fields
196
+ if (!$post_id && empty($item['sku'])) {
197
+
198
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', __('> > Cannot merge without id or sku. Importing instead.', 'wf_csv_import_export'));
199
+
200
+ $merging = false;
201
+ } else {
202
+
203
+ // Check product exists
204
+ if (!$post_id) {
205
+ // Check product to merge exists
206
+ $db_query = $wpdb->prepare("
207
SELECT $wpdb->posts.ID
208
FROM $wpdb->posts
209
LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
211
AND $wpdb->posts.post_status IN ( 'publish', 'private', 'draft', 'pending', 'future' )
212
AND $wpdb->postmeta.meta_key = '_sku' AND $wpdb->postmeta.meta_value = '%s'
213
", $item['sku']);
214
+ $found_product_id = $wpdb->get_var($db_query);
215
+ if (!$found_product_id) {
216
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > Skipped. Cannot find product with sku %s. Importing instead.', 'wf_csv_import_export'), $item['sku']));
217
+ $merging = false;
218
+ } else {
219
+
220
+ $post_id = $found_product_id;
221
+
222
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > Found product with ID %s.', 'wf_csv_import_export'), $post_id));
223
+ }
224
+ }
225
+ }
226
+ }
227
+
228
+ if (!$merging) {
229
+
230
+ $product['merging'] = false;
231
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> Row %s - preparing for import.', 'wf_csv_import_export'), $this->row));
232
+
233
+ // Required fields
234
+ if (isset($item['post_parent']) && $item['post_parent'] === '' && $item['post_title'] === '') {
235
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', __('> > Skipped. No post_title set for new product.', 'wf_csv_import_export'));
236
+ return new WP_Error('parse-error', __('No post_title set for new product.', 'wf_csv_import_export'));
237
+ }
238
+ if (!empty($item['post_parent']) && $item['post_parent'] !== '' && $item['post_parent'] !== null && $item['parent_sku'] === '') {
239
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', __('> > Skipped. No parent set for new variation product.', 'wf_csv_import_export'));
240
+ //return new WP_Error( 'parse-error', __( 'No post_title set for new product.', 'wf_csv_import_export' ) );
241
+ return new WP_Error('parse-error', __('No parent set for new variation product.', 'wf_csv_import_export'));
242
+ }
243
+ }
244
+
245
+ $product['post_id'] = $post_id;
246
+
247
+
248
+ // Get post fields
249
+ foreach ($this->post_defaults as $column => $default) {
250
+ if (isset($item[$column]))
251
+ $product[$column] = $item[$column];
252
+ }
253
+
254
+ // Get custom fields
255
+ foreach ($this->postmeta_defaults as $column => $default) {
256
+ if (isset($item[$column]))
257
+ $postmeta[$column] = (string) $item[$column];
258
+ elseif (isset($item['_' . $column]))
259
+ $postmeta[$column] = (string) $item['_' . $column];
260
+
261
+ // Check custom fields are valid
262
+ if (isset($postmeta[$column]) && isset($this->postmeta_allowed[$column]) && !in_array($postmeta[$column], $this->postmeta_allowed[$column])) {
263
+ $postmeta[$column] = $this->postmeta_defaults[$column];
264
+ }
265
+ }
266
+
267
+ if (!$merging) {
268
+ // Merge post meta with defaults
269
+ $product = wp_parse_args($product, $this->post_defaults);
270
+ $postmeta = wp_parse_args($postmeta, $this->postmeta_defaults);
271
+ }
272
+
273
+ // Handle special meta fields
274
+ // price
275
+ if ($merging) {
276
+ if (!isset($postmeta['regular_price']))
277
+ $postmeta['regular_price'] = get_post_meta($post_id, '_regular_price', true);
278
+ $postmeta['regular_price'] = $this->hf_currency_formatter($postmeta['regular_price']);
279
+ if (!isset($postmeta['sale_price']))
280
+ $postmeta['sale_price'] = get_post_meta($post_id, '_sale_price', true);
281
+ $postmeta['sale_price'] = $this->hf_currency_formatter($postmeta['sale_price']);
282
+ }
283
+
284
+ if (isset($postmeta['regular_price']) && isset($postmeta['sale_price']) && $postmeta['sale_price'] !== '') {
285
+ $postmeta['sale_price'] = $this->hf_currency_formatter($postmeta['sale_price']);
286
+ $postmeta['regular_price'] = $this->hf_currency_formatter($postmeta['regular_price']);
287
+ $price = min($postmeta['sale_price'], $postmeta['regular_price']);
288
+ $postmeta['price'] = $price;
289
+ } elseif (isset($postmeta['regular_price'])) {
290
+ $postmeta['price'] = $this->hf_currency_formatter($postmeta['regular_price']);
291
+ }
292
+
293
+ // Reset dynamically generated meta
294
+ if (!isset($item['post_parent'])) {
295
+ $postmeta['min_variation_price'] = $postmeta['max_variation_price'] = $postmeta['min_variation_regular_price'] = $postmeta['max_variation_regular_price'] = $postmeta['min_variation_sale_price'] = $postmeta['max_variation_sale_price'] = '';
296
+ }
297
+
298
+ // upsells
299
+ if (isset($postmeta['upsell_ids']) && !is_array($postmeta['upsell_ids'])) {
300
+ $ids = array_filter(array_map('trim', explode('|', $postmeta['upsell_ids'])));
301
+ $postmeta['upsell_ids'] = $ids;
302
+ }
303
+
304
+ // crosssells
305
+ if (isset($postmeta['crosssell_ids']) && !is_array($postmeta['crosssell_ids'])) {
306
+ $ids = array_filter(array_map('trim', explode('|', $postmeta['crosssell_ids'])));
307
+ $postmeta['crosssell_ids'] = $ids;
308
+ }
309
+
310
+ // Sale dates
311
+ if (isset($postmeta['sale_price_dates_from'])) {
312
+ $postmeta['sale_price_dates_from'] = empty($postmeta['sale_price_dates_from']) ? '' : strtotime($postmeta['sale_price_dates_from']);
313
+ }
314
+
315
+ if (isset($postmeta['sale_price_dates_to'])) {
316
+ $postmeta['sale_price_dates_to'] = empty($postmeta['sale_price_dates_to']) ? '' : strtotime($postmeta['sale_price_dates_to']);
317
+ }
318
+
319
+ // Relative stock updates
320
+ if ($merging) {
321
+ if (isset($postmeta['stock'])) {
322
323
+ $postmeta['stock'] = trim($postmeta['stock']);
324
325
+ $mode = substr($postmeta['stock'], 0, 3);
326
327
+ if ($mode == '(+)') {
328
+ $old_stock = absint(get_post_meta($post_id, '_stock', true));
329
+ $amount = absint(substr($postmeta['stock'], 3));
330
+ $new_stock = $old_stock + $amount;
331
+ $postmeta['stock'] = $new_stock;
332
+ }
333
334
+ if ($mode == '(-)') {
335
+ $old_stock = absint(get_post_meta($post_id, '_stock', true));
336
+ $amount = absint(substr($postmeta['stock'], 3));
337
+ $new_stock = $old_stock - $amount;
338
+ $postmeta['stock'] = $new_stock;
339
+ }
340
+ }
341
+ }
342
+
343
+ // Format post status
344
+ if (!empty($product['post_status'])) {
345
+ $product['post_status'] = strtolower($product['post_status']);
346
+
347
+ if (empty($item['post_parent'])) {
348
+ if (!in_array($product['post_status'], array('publish', 'private', 'draft', 'pending', 'future', 'inherit', 'trash'))) {
349
+ $product['post_status'] = 'publish';
350
+ }
351
+ } else {
352
+ if (!in_array($product['post_status'], array('private', 'publish'))) {
353
+ $product['post_status'] = 'publish';
354
+ }
355
+ }
356
+ }
357
+
358
+ // Put set core product postmeta into product array
359
+ foreach ($postmeta as $key => $value) {
360
+ $product['postmeta'][] = array('key' => '_' . esc_attr($key), 'value' => $value);
361
+ }
362
+
363
+ /**
364
+ * Handle other columns
365
+ */
366
+ foreach ($item as $key => $value) {
367
+
368
+ if (empty($item['post_parent']) && !$merge_empty_cells && $value == "")
369
+ continue;
370
+
371
+ /**
372
+ * File path handling
373
+ */
374
+ if ($key == 'file_paths' || $key == 'downloadable_files') {
375
+
376
+ $file_paths = explode('|', $value);
377
+ $_file_paths = array();
378
+ foreach ($file_paths as $file_path) {
379
+ // 2.1
380
+ if (function_exists('wc_get_filename_from_url')) {
381
+ $file_path = array_map('trim', explode('::', $file_path));
382
+ if (sizeof($file_path) === 2) {
383
+ $file_name = $file_path[0];
384
+ $file_path = $file_path[1];
385
+ } else {
386
+ $file_name = wc_get_filename_from_url($file_path[0]);
387
+ $file_path = $file_path[0];
388
+ }
389
+ $_file_paths[md5($file_path)] = array(
390
+ 'name' => $file_name,
391
+ 'file' => $file_path
392
+ );
393
+ } else {
394
+ $file_path = trim($file_path);
395
+ $_file_paths[md5($file_path)] = $file_path;
396
+ }
397
+ }
398
+ $value = $_file_paths;
399
+
400
+ $product['postmeta'][] = array('key' => '_' . esc_attr($key), 'value' => $value);
401
+ } elseif (strstr($key, 'tax:')) {
402
+
403
+ // Get taxonomy
404
+ $taxonomy = trim(str_replace('tax:', '', $key));
405
+
406
+ // Exists?
407
+ if (!taxonomy_exists($taxonomy)) {
408
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > Skipping taxonomy "%s" - it does not exist.', 'wf_csv_import_export'), $taxonomy));
409
+ continue;
410
+ }
411
+
412
+ // Product type check
413
+ if ($taxonomy == 'product_type') {
414
+ $term = strtolower(trim($value));
415
+
416
+ if (!array_key_exists($term, $this->allowed_product_types)) {
417
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > > Product type "%s" not allowed - using simple.', 'wf_csv_import_export'), $term));
418
+ $term_id = $this->allowed_product_types['simple'];
419
+ } else {
420
+ $term_id = $this->allowed_product_types[$term];
421
+ }
422
+
423
+ // Add to array
424
+ $terms_array[] = array(
425
+ 'taxonomy' => $taxonomy,
426
+ 'terms' => array($term_id)
427
+ );
428
+
429
+ continue;
430
+ }
431
+
432
+ // Get terms - ID => parent
433
+ $terms = array();
434
+ $raw_terms = explode('|', $value);
435
+ $raw_terms = array_map('trim', $raw_terms);
436
+
437
+ // Handle term hierachy (>)
438
+ foreach ($raw_terms as $raw_term) {
439
+
440
+ if (strstr($raw_term, '>')) {
441
+
442
+ $raw_term = explode('>', $raw_term);
443
+ $raw_term = array_map('trim', $raw_term);
444
+
445
+ if (WC()->version < '2.7.0') {
446
+ $raw_term = array_map('wp_specialchars', $raw_term);
447
+ $raw_term = array_filter($raw_term);
448
+ } else {
449
+ $raw_term = array_map('esc_html', $raw_term);
450
+ $raw_term = array_filter($raw_term);
451
+ }
452
+
453
+ $parent = 0;
454
+ $loop = 0;
455
+
456
+ foreach ($raw_term as $term) {
457
+ $loop ++;
458
+ $term_id = '';
459
+
460
+ if (isset($this->inserted_terms[$taxonomy][$parent][$term])) {
461
+ $term_id = $this->inserted_terms[$taxonomy][$parent][$term];
462
+ } elseif ($term) {
463
+
464
+ /**
465
+ * Check term existance
466
+ */
467
+ $term_may_exist = term_exists($term, $taxonomy, absint($parent));
468
+
469
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > (' . __LINE__ . ') Term %s (%s) exists? %s', 'wf_csv_import_export'), sanitize_text_field($term), esc_html($taxonomy), $term_may_exist ? print_r($term_may_exist, true) : '-' ));
470
+
471
+ if (is_array($term_may_exist)) {
472
+ $possible_term = get_term($term_may_exist['term_id'], 'product_cat');
473
+
474
+ if (!empty($possible_term) && $possible_term->parent == $parent) {
475
+ $term_id = $term_may_exist['term_id'];
476
+ }
477
+ }
478
+
479
+ if (!$term_id) {
480
481
+ //Create appropriate slug for the category
482
+ $slug = sanitize_title( $raw_term[$loop - 1] );
483
484
+ $t = wp_insert_term($term, $taxonomy, array('parent' => $parent, 'slug' => $slug));
485
486
+ if (!is_wp_error($t)) {
487
+ $term_id = $t['term_id'];
488
+ } else {
489
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > (' . __LINE__ . ') Failed to import term %s, parent %s - %s', 'wf_csv_import_export'), sanitize_text_field($term), sanitize_text_field($parent), sanitize_text_field($taxonomy)));
490
+ break;
491
+ }
492
+ }
493
+
494
+ $this->inserted_terms[$taxonomy][$parent][$term] = $term_id;
495
+ }
496
497
+ if (!$term_id)
498
+ break;
499
500
+ // Add to product terms, ready to set if this is the final term
501
+ if (sizeof($raw_term) == $loop)
502
+ $terms[] = $term_id;
503
504
+ $parent = $term_id;
505
+ }
506
+ } else {
507
508
+ $term_id = '';
509
+ $raw_term = (WC()->version < '2.7.0') ? wp_specialchars($raw_term) : esc_html($raw_term);
510
511
+ if (isset($this->inserted_terms[$taxonomy][0][$raw_term])) {
512
513
+ $term_id = $this->inserted_terms[$taxonomy][0][$raw_term];
514
+ } elseif ($raw_term) {
515
516
+ // Check term existance
517
+ $term_exists = term_exists($raw_term, $taxonomy, 0);
518
+ $term_id = is_array($term_exists) ? $term_exists['term_id'] : 0;
519
520
+ if (!$term_id) {
521
+ $t = wp_insert_term(trim($raw_term), $taxonomy, array('parent' => 0));
522
523
+ if (!is_wp_error($t)) {
524
+ $term_id = $t['term_id'];
525
+ } else {
526
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > Failed to import term %s %s', 'wf_csv_import_export'), esc_html($raw_term), esc_html($taxonomy)));
527
+ break;
528
+ }
529
+ }
530
531
+ $this->inserted_terms[$taxonomy][0][$raw_term] = $term_id;
532
+ }
533
+
534
+ // Store terms for later insertion
535
+ if ($term_id)
536
+ $terms[] = $term_id;
537
+ }
538
+ }
539
540
+ // Any defined?
541
+ if (sizeof($terms) == 0)
542
+ continue;
543
544
+ // Add to array
545
+ $terms_array[] = array(
546
+ 'taxonomy' => $taxonomy,
547
+ 'terms' => $terms
548
+ );
549
+ }
550
551
+ /**
552
+ * Handle Attributes
553
+ */
554
+ elseif (strstr($key, 'attribute:')) {
555
556
+ $attribute_key = sanitize_title(trim(str_replace('attribute:', '', $key)));
557
+ $attribute_name = str_replace('attribute:', '', $WF_CSV_Product_Import->raw_headers[$key]);
558
559
+ if (!$attribute_key)
560
+ continue;
561
562
+ // Taxonomy
563
+ if (substr($attribute_key, 0, 3) == 'pa_') {
564
565
+ $taxonomy = $attribute_key;
566
567
+ // Exists?
568
+ if (!taxonomy_exists($taxonomy)) {
569
570
571
+ $nicename = strtolower(sanitize_title(str_replace('pa_', '', $taxonomy)));
572
+
573
+ $attribute_label = ucwords(str_replace('-', ' ', $nicename)); // for importing attribute name as human readable string
574
+
575
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > Attribute taxonomy "%s" does not exist. Adding it. Nicename: %s', 'wf_csv_import_export'), $taxonomy, $nicename));
576
+
577
+ $exists_in_db = $wpdb->get_var("SELECT attribute_id FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = '" . $nicename . "';");
578
+
579
+ if (!$exists_in_db) {
580
+ // Create the taxonomy
581
+ $wpdb->insert($wpdb->prefix . "woocommerce_attribute_taxonomies", array('attribute_name' => $nicename, 'attribute_label' => $attribute_label, 'attribute_type' => 'select', 'attribute_orderby' => 'menu_order'));
582
+ } else {
583
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > Attribute taxonomy %s already exists in DB.', 'wf_csv_import_export'), $taxonomy));
584
+ }
585
+
586
+ // Register the taxonomy now so that the import works!
587
+ register_taxonomy($taxonomy, array('product', 'product_variation'), array(
588
+ 'hierarchical' => true,
589
+ 'show_ui' => false,
590
+ 'query_var' => true,
591
+ 'rewrite' => false,
592
+ )
593
+ );
594
+ }
595
596
+ // Get terms
597
+ $terms = array();
598
+ $raw_terms = explode('|', $value);
599
+ if (WC()->version < '2.7.0') {
600
+ $raw_terms = array_map('wp_specialchars', $raw_terms);
601
+ $raw_terms = array_map('trim', $raw_terms);
602
+ } else {
603
604
+ $raw_terms = array_map('esc_html', $raw_terms);
605
+ $raw_terms = array_map('trim', $raw_terms);
606
+ }
607
608
+ if (sizeof($raw_terms) > 0) {
609
610
+ foreach ($raw_terms as $raw_term) {
611
612
+ if (empty($raw_term) && 0 != $raw_term) {
613
+ continue;
614
+ }
615
616
+ // Check term existance
617
+ $term_exists = term_exists($raw_term, $taxonomy, 0);
618
+ $term_id = is_array($term_exists) ? $term_exists['term_id'] : 0;
619
620
+ if (!$term_id) {
621
+ $t = wp_insert_term(trim($raw_term), $taxonomy);
622
623
+ if (!is_wp_error($t)) {
624
+ $term_id = $t['term_id'];
625
626
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > Inserted Raw Term %s ID = %s', 'wf_csv_import_export'), esc_html($raw_term), $term_id));
627
+ } else {
628
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > Failed to import term %s %s', 'wf_csv_import_export'), esc_html($raw_term), esc_html($taxonomy)));
629
+ break;
630
+ }
631
+ } else {
632
+ $WF_CSV_Product_Import->hf_log_data_change('csv-import', sprintf(__('> > Raw Term %s ID = %s', 'wf_csv_import_export'), esc_html($raw_term), $term_id));
633
+ }
634
635
+ if ($term_id) {
636
+ $terms[] = $term_id;
637
+ }
638
+ }
639
+ }
640
641
+ // Add to array
642
+ $terms_array[] = array(
643
+ 'taxonomy' => $taxonomy,
644
+ 'terms' => $terms
645
+ );
646
+
647
+ // Ensure we have original attributes
648
+ if (is_null($attributes) && $merging) {
649
+ $attributes = array_filter((array) maybe_unserialize(get_post_meta($post_id, '_product_attributes', true)));
650
+ } elseif (is_null($attributes)) {
651
+ $attributes = array();
652
+ }
653
654
+ // Set attribute
655
+ if (!isset($attributes[$taxonomy]))
656
+ $attributes[$taxonomy] = array();
657
+
658
+ $attributes[$taxonomy]['name'] = $taxonomy;
659
+ $attributes[$taxonomy]['value'] = null;
660
+ $attributes[$taxonomy]['is_taxonomy'] = 1;
661
+
662
+ if (!isset($attributes[$taxonomy]['position']))
663
+ $attributes[$taxonomy]['position'] = 0;
664
+ if (!isset($attributes[$taxonomy]['is_visible']))
665
+ $attributes[$taxonomy]['is_visible'] = 1;
666
+ if (!isset($attributes[$taxonomy]['is_variation']))
667
+ $attributes[$taxonomy]['is_variation'] = 0;
668
+ } else {
669
+
670
+ if (!$value || !$attribute_key)
671
+ continue;
672
+
673
+ // Set attribute
674
+ if (!isset($attributes[$attribute_key]))
675
+ $attributes[$attribute_key] = array();
676
+
677
+ $attributes[$attribute_key]['name'] = $attribute_name;
678
+ $attributes[$attribute_key]['value'] = $value;
679
+ $attributes[$attribute_key]['is_taxonomy'] = 0;
680
+
681
+ if (!isset($attributes[$attribute_key]['position']))
682
+ $attributes[$attribute_key]['position'] = 0;
683
+ if (!isset($attributes[$attribute_key]['is_visible']))
684
+ $attributes[$attribute_key]['is_visible'] = 1;
685
+ if (!isset($attributes[$attribute_key]['is_variation']))
686
+ $attributes[$attribute_key]['is_variation'] = 0;
687
+ }
688
+ }
689
+
690
+ /**
691
+ * Handle Attributes Data - position|is_visible|is_variation
692
+ */
693
+ elseif (strstr($key, 'attribute_data:')) {
694
+
695
+ $attribute_key = sanitize_title(trim(str_replace('attribute_data:', '', $key)));
696
+
697
+ if (!$attribute_key) {
698
+ continue;
699
+ }
700
+
701
+ $values = explode('|', $value);
702
+ $position = isset($values[0]) ? (int) $values[0] : 0;
703
+ $visible = isset($values[1]) ? (int) $values[1] : 1;
704
+ $variation = isset($values[2]) ? (int) $values[2] : 0;
705
+
706
+ // Ensure we have original attributes
707
+ if (!isset($attributes[$attribute_key])) {
708
+ if ($merging) {
709
+ $existing_attributes = array_filter((array) maybe_unserialize(get_post_meta($post_id, '_product_attributes', true)));
710
+ $attributes[$attribute_key] = isset($existing_attributes[$attribute_key]) ? $existing_attributes[$attribute_key] : array();
711
+ } else {
712
+ $attributes[$attribute_key] = array();
713
+ }
714
+ }
715
+
716
+ $attributes[$attribute_key]['position'] = $position;
717
+ $attributes[$attribute_key]['is_visible'] = $visible;
718
+ $attributes[$attribute_key]['is_variation'] = $variation;
719
+ }
720
+
721
+ /**
722
+ * Handle Attributes Default Values
723
+ */ elseif (strstr($key, 'attribute_default:')) {
724
+
725
+ $attribute_key = sanitize_title(trim(str_replace('attribute_default:', '', $key)));
726
+
727
+ if (!$attribute_key)
728
+ continue;
729
+
730
+ // Ensure we have original attributes
731
+ if (is_null($default_attributes) && $merging) {
732
+ $default_attributes = array_filter((array) maybe_unserialize(get_post_meta($post_id, '_default_attributes', true)));
733
+ } elseif (is_null($default_attributes)) {
734
+ $default_attributes = array();
735
+ }
736
+
737
+ $default_attributes[$attribute_key] = $value;
738
+ }
739
+
740
+ /**
741
+ * Handle gpf: google product feed columns
742
+ */ elseif (strstr($key, 'gpf:')) {
743
+
744
+ $gpf_key = trim(str_replace('gpf:', '', $key));
745
+
746
+ // Get original values
747
+ if (is_null($gpf_data) && $merging) {
748
+ $gpf_data = array_filter((array) maybe_unserialize(get_post_meta($post_id, '_woocommerce_gpf_data', true)));
749
+ } elseif (is_null($gpf_data)) {
750
+ $gpf_data = array(
751
+ 'availability' => '',
752
+ 'condition' => '',
753
+ 'brand' => '',
754
+ 'product_type' => '',
755
+ 'google_product_category' => '',
756
+ 'gtin' => '',
757
+ 'mpn' => '',
758
+ 'gender' => '',
759
+ 'age_group' => '',
760
+ 'color' => '',
761
+ 'size' => ''
762
+ );
763
+ }
764
+
765
+ $gpf_data[$gpf_key] = $value;
766
+ }
767
+
768
+ /**
769
+ * Handle upsell SKUs which we cannot assign until we get IDs later on
770
+ */ elseif (strstr($key, 'upsell_skus')) {
771
+ if ($value) {
772
+ $skus = array_filter(array_map('trim', explode('|', $value)));
773
+ $product['upsell_skus'] = $skus;
774
+ }
775
+ }
776
+
777
+ /**
778
+ * Handle crosssells SKUs which we cannot assign until we get IDs later on
779
+ */ elseif (strstr($key, 'crosssell_skus')) {
780
+ if ($value) {
781
+ $skus = array_filter(array_map('trim', explode('|', $value)));
782
+ $product['crosssell_skus'] = $skus;
783
+ }
784
+ }
785
+ }
786
787
+ // Remove empty attribues
788
+ if (!empty($attributes))
789
+ foreach ($attributes as $key => $value) {
790
+ if (!isset($value['name']))
791
+ unset($attributes[$key]);
792
+ }
793
+
794
+ /**
795
+ * Handle images
796
+ */
797
+ if (!empty($item['images'])) {
798
+ $images = array_map('trim', explode('|', $item['images']));
799
+ } else {
800
+ $images = '';
801
}
802
+
803
+ $product['postmeta'][] = array('key' => '_default_attributes', 'value' => $default_attributes);
804
+ $product['attributes'] = $attributes;
805
+ $product['gpf_data'] = $gpf_data;
806
+ $product['images'] = $images;
807
+ $product['terms'] = $terms_array;
808
+ $product['sku'] = (!empty($item['sku']) ) ? $item['sku'] : '';
809
+ $product['post_title'] = (!empty($item['post_title']) ) ? $item['post_title'] : '';
810
+ $product['post_type'] = $this->post_type;
811
+ unset($item, $terms_array, $postmeta, $attributes, $gpf_data, $images);
812
+
813
+ return $product;
814
+ }
815
+
816
+ public function hf_currency_formatter($price) {
817
+
818
+ $decimal_seperator = wc_get_price_decimal_separator();
819
+ return preg_replace("[^0-9\\'.$decimal_seperator.']", "", $price);
820
+ }
821
+
822
}
includes/importer/class-wf-prodimpexpcsv-product-import.php CHANGED
@@ -578,11 +578,11 @@ class WF_ProdImpExpCsv_Product_Import extends WP_Importer {
578
foreach ( $this->parsed_data as $key => &$item ) {
579
580
$product = $this->parser->parse_product( $item, $this->merge_empty_cells );
581
- if ( ! is_wp_error( $product ) )
582
$this->process_product( $product );
583
- else
584
- $this->add_import_result( 'failed', $product->get_error_message(), 'Not parsed', json_encode( $item ), '-' );
585
-
586
unset( $item, $product );
587
}
588
$this->hf_log_data_change( 'csv-import', __( 'Finished processing products.', 'wf_csv_import_export' ) );
@@ -1231,7 +1231,8 @@ class WF_ProdImpExpCsv_Product_Import extends WP_Importer {
1231
$this->add_import_result( 'imported', 'Import successful', $post_id, $processing_product_title, $processing_product_sku );
1232
$this->hf_log_data_change( 'csv-import', sprintf( __('> Finished importing post ID %s.', 'wf_csv_import_export'), $post_id ) );
1233
}
1234
-
1235
unset( $post );
1236
}
1237
578
foreach ( $this->parsed_data as $key => &$item ) {
579
580
$product = $this->parser->parse_product( $item, $this->merge_empty_cells );
581
+ if ( ! is_wp_error( $product ) ){
582
$this->process_product( $product );
583
+ }else{
584
+ $this->add_import_result( 'failed', $product->get_error_message(), 'Not parsed', json_encode( $item ), '-' );
585
+ }
586
unset( $item, $product );
587
}
588
$this->hf_log_data_change( 'csv-import', __( 'Finished processing products.', 'wf_csv_import_export' ) );
1231
$this->add_import_result( 'imported', 'Import successful', $post_id, $processing_product_title, $processing_product_sku );
1232
$this->hf_log_data_change( 'csv-import', sprintf( __('> Finished importing post ID %s.', 'wf_csv_import_export'), $post_id ) );
1233
}
1234
+
1235
+ do_action('wf_refresh_after_product_import',$processing_product_object); // hook for forcefully refresh product
1236
unset( $post );
1237
}
1238
includes/importer/views/html-wf-import-options.php CHANGED
@@ -25,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
25
<th><?php _e('CSV column header(from imported file)', 'wf_csv_import_export'); ?></th>
26
<th><?php _e('Evaluation Field', 'wf_csv_import_export'); ?>
27
<?php $plugin_url = WC()->plugin_url(); ?>
28
- <img class="help_tip" style="float:none;" data-tip="<?php _e('Assign constant value HikeFoce to post_author:</br>=HikeFoce</br>Add $5 to Price:sale_price:</br>+5</br>Reduce $5 to Price:sale_price:</br>-5</br>Multiple 1.05 to Price:sale_price:</br>*1.05</br>Divide Price:sale_price by 2:</br>/2</br>Append a value By HikeFoce to post_title:</br>&By HikeFoce</br>Prepend a value HikeFoce to post_title:</br>&HikeFoce [VAL].', 'wf_csv_import_export'); ?>" src="<?php echo $plugin_url; ?>/assets/images/help.png" height="20" width="20" />
29
</th>
30
</tr>
31
</thead>
25
<th><?php _e('CSV column header(from imported file)', 'wf_csv_import_export'); ?></th>
26
<th><?php _e('Evaluation Field', 'wf_csv_import_export'); ?>
27
<?php $plugin_url = WC()->plugin_url(); ?>
28
+ <img class="help_tip" style="float:none;" data-tip="<?php _e('Assign constant value WebToffe to post_author:</br>=WebToffe</br>Add $5 to Price:sale_price:</br>+5</br>Reduce $5 to Price:sale_price:</br>-5</br>Multiple 1.05 to Price:sale_price:</br>*1.05</br>Divide Price:sale_price by 2:</br>/2</br>Append a value By WebToffe to post_title:</br>&By WebToffe</br>Prepend a value WebToffe to post_title:</br>&WebToffe [VAL].', 'wf_csv_import_export'); ?>" src="<?php echo $plugin_url; ?>/assets/images/help.png" height="20" width="20" />
29
</th>
30
</tr>
31
</thead>
product-csv-import-export.php CHANGED
@@ -5,8 +5,8 @@
5
Description: Import and Export Products From and To your WooCommerce Store.
6
Author: WebToffee
7
Author URI: https://www.webtoffee.com/product/product-import-export-woocommerce/
8
- Version: 1.5.3
9
- WC tested up to: 3.5.3
10
License: GPLv3
11
License URI: https://www.gnu.org/licenses/gpl-3.0.html
12
Text Domain: wf_csv_import_export
@@ -18,7 +18,7 @@ if (!defined('ABSPATH') || !is_admin()) {
18
19
20
if (!defined('WF_PIPE_CURRENT_VERSION')) {
21
- define("WF_PIPE_CURRENT_VERSION", "1.5.3");
22
}
23
if (!defined('WF_PROD_IMP_EXP_ID')) {
24
define("WF_PROD_IMP_EXP_ID", "wf_prod_imp_exp");
5
Description: Import and Export Products From and To your WooCommerce Store.
6
Author: WebToffee
7
Author URI: https://www.webtoffee.com/product/product-import-export-woocommerce/
8
+ Version: 1.5.4
9
+ WC tested up to: 3.5.4
10
License: GPLv3
11
License URI: https://www.gnu.org/licenses/gpl-3.0.html
12
Text Domain: wf_csv_import_export
18
19
20
if (!defined('WF_PIPE_CURRENT_VERSION')) {
21
+ define("WF_PIPE_CURRENT_VERSION", "1.5.4");
22
}
23
if (!defined('WF_PROD_IMP_EXP_ID')) {
24
define("WF_PROD_IMP_EXP_ID", "wf_prod_imp_exp");
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.webtoffee.com/plugins/
4
Tags: woocommerce product import, woocommerce import products, woocommerce export products, export woocommerce products, import products into woocommerce
5
Requires at least: 3.0.1
6
Tested up to: 5.0.3
7
- Stable tag: 1.5.3
8
License: GPLv3 or later
9
License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
@@ -20,7 +20,7 @@ Are you trying to import products into WooCommerce store or export WooCommerce p
20
21
&#128312; Export Simple Products in to a CSV file.
22
&#128312; Import Simple Products in CSV format in to WooCommerce Store.
23
- &#128312; Tested OK with WooCommerce 3.5.3.
24
25
26
Highlights: WooCommerce Product Export, WooCommerce Product CSV Import Suite, WooCommerce bulk product upload, WooCommerce import products with images, import amazon products to WooCommerce, Export Products to xls. Pro Version supports both Simple and Variable products.
@@ -149,6 +149,11 @@ LibreOffice.
149
150
== Changelog ==
151
152
= 1.5.3 =
153
* Updates: Tested OK with WP 5.0.3 and WC 3.5.3
154
* Bug Fix:- Image Thumbnail Regeneration error reporting.
@@ -279,7 +284,7 @@ LibreOffice.
279
280
== Upgrade Notice ==
281
282
- = 1.5.3 =
283
- * Updates: Tested OK with WP 5.0.3 and WC 3.5.3
284
- * Bug Fix:- Image Thumbnail Regeneration error reporting.
285
* Content Update.
4
Tags: woocommerce product import, woocommerce import products, woocommerce export products, export woocommerce products, import products into woocommerce
5
Requires at least: 3.0.1
6
Tested up to: 5.0.3
7
+ Stable tag: 1.5.4
8
License: GPLv3 or later
9
License URI: http://www.gnu.org/licenses/gpl-3.0.html
10
20
21
&#128312; Export Simple Products in to a CSV file.
22
&#128312; Import Simple Products in CSV format in to WooCommerce Store.
23
+ &#128312; Tested OK with WooCommerce 3.5.4.
24
25
26
Highlights: WooCommerce Product Export, WooCommerce Product CSV Import Suite, WooCommerce bulk product upload, WooCommerce import products with images, import amazon products to WooCommerce, Export Products to xls. Pro Version supports both Simple and Variable products.
149
150
== Changelog ==
151
152
+ = 1.5.4 =
153
+ * Updates: Tested OK with WC 3.5.4
154
+ * Bug Fix:- Importing hierarchical category
155
+ * Content Update.
156
+
157
= 1.5.3 =
158
* Updates: Tested OK with WP 5.0.3 and WC 3.5.3
159
* Bug Fix:- Image Thumbnail Regeneration error reporting.
284
285
== Upgrade Notice ==
286
287
+ = 1.5.4 =
288
+ * Updates: Tested OK with WC 3.5.4
289
+ * Bug Fix:- Importing hierarchical category
290
* Content Update.