/**
  * Product Exporter Tool
  */
 public static function do_export($post_type = 'product')
 {
     global $wpdb;
     $export_limit = !empty($_POST['limit']) ? intval($_POST['limit']) : 999999999;
     $export_count = 0;
     $limit = 100;
     $current_offset = !empty($_POST['offset']) ? intval($_POST['offset']) : 0;
     $csv_columns = $post_type == 'product' ? include 'data/data-post-columns.php' : (include 'data/data-variation-columns.php');
     $product_taxonomies = get_object_taxonomies($post_type, 'name');
     $export_columns = !empty($_POST['columns']) ? $_POST['columns'] : '';
     $include_hidden_meta = !empty($_POST['include_hidden_meta']) ? true : false;
     $product_limit = !empty($_POST['product_limit']) ? sanitize_text_field($_POST['product_limit']) : '';
     $exclude_hidden_meta_columns = (include 'data/data-hidden-meta-columns.php');
     if ($limit > $export_limit) {
         $limit = $export_limit;
     }
     $wpdb->hide_errors();
     @set_time_limit(0);
     // Disable GZIP
     if (function_exists('apache_setenv')) {
         @apache_setenv('no-gzip', 1);
     }
     @ini_set('zlib.output_compression', 'Off');
     @ini_set('output_buffering', 'Off');
     @ini_set('output_handler', '');
     $filename_suffix = 'woocommerce-product-export';
     if ('product_variation' === $post_type) {
         $filename_suffix = 'woocommerce-product-variations-export';
     }
     $filename = sprintf('%s-%s.csv', $filename_suffix, date_i18n('Y_m_d_H_i_s', current_time('timestamp')));
     header('Content-Type: text/csv; charset=UTF-8');
     header('Content-Disposition: attachment; filename=' . $filename);
     header('Pragma: no-cache');
     header('Expires: 0');
     $fp = fopen('php://output', 'w');
     // Headers
     $all_meta_keys = self::get_all_metakeys($post_type);
     $found_attributes = self::get_all_product_attributes($post_type);
     // Loop products and load meta data
     $found_product_meta = array();
     // Some of the values may not be usable (e.g. arrays of arrays) but the worse
     // that can happen is we get an empty column.
     foreach ($all_meta_keys as $meta) {
         if (!$meta) {
             continue;
         }
         if (!$include_hidden_meta && !in_array($meta, array_keys($csv_columns)) && substr($meta, 0, 1) == '_') {
             continue;
         }
         if ($include_hidden_meta && (in_array($meta, $exclude_hidden_meta_columns) || in_array($meta, array_keys($csv_columns)))) {
             continue;
         }
         $found_product_meta[] = $meta;
     }
     $found_product_meta = array_diff($found_product_meta, array_keys($csv_columns));
     // Variable to hold the CSV data we're exporting
     $row = array();
     if ($post_type == 'product_variation') {
         $row[] = 'Parent';
         $row[] = 'parent_sku';
     }
     // Export header rows
     foreach ($csv_columns as $column => $value) {
         if (!$export_columns || in_array($column, $export_columns)) {
             $row[] = esc_attr($value);
         }
     }
     // Handle special fields like taxonomies
     if (!$export_columns || in_array('images', $export_columns)) {
         $row[] = 'images';
     }
     if (!$export_columns || in_array('file_paths', $export_columns)) {
         if (function_exists('wc_get_filename_from_url')) {
             $row[] = 'downloadable_files';
         } else {
             $row[] = 'file_paths';
         }
     }
     if (!$export_columns || in_array('taxonomies', $export_columns)) {
         foreach ($product_taxonomies as $taxonomy) {
             if (strstr($taxonomy->name, 'pa_')) {
                 continue;
             }
             // Skip attributes
             $row[] = 'tax:' . self::format_data($taxonomy->name);
         }
     }
     if (!$export_columns || in_array('meta', $export_columns)) {
         foreach ($found_product_meta as $product_meta) {
             $row[] = 'meta:' . self::format_data($product_meta);
         }
     }
     if (!$export_columns || in_array('attributes', $export_columns)) {
         foreach ($found_attributes as $attribute) {
             $row[] = 'attribute:' . self::format_data($attribute);
             $row[] = 'attribute_data:' . self::format_data($attribute);
             $row[] = 'attribute_default:' . self::format_data($attribute);
         }
     }
     if (function_exists('woocommerce_gpf_install') && (!$export_columns || in_array('gpf', $export_columns))) {
         $row[] = 'gpf:availability';
         $row[] = 'gpf:condition';
         $row[] = 'gpf:brand';
         $row[] = 'gpf:product_type';
         $row[] = 'gpf:google_product_category';
         $row[] = 'gpf:gtin';
         $row[] = 'gpf:mpn';
         $row[] = 'gpf:gender';
         $row[] = 'gpf:age_group';
         $row[] = 'gpf:color';
         $row[] = 'gpf:size';
         $row[] = 'gpf:delivery_label';
         $row[] = 'gpf:adwords_grouping';
         $row[] = 'gpf:adwords_labels';
         $row[] = 'gpf:custom_label_0';
         $row[] = 'gpf:custom_label_1';
         $row[] = 'gpf:custom_label_2';
         $row[] = 'gpf:custom_label_3';
         $row[] = 'gpf:custom_label_4';
     }
     $row = array_map('WC_PCSVIS_Exporter::wrap_column', $row);
     fwrite($fp, implode(',', $row) . "\n");
     unset($row);
     while ($export_count < $export_limit) {
         $product_args = apply_filters('woocommerce_csv_product_export_args', array('numberposts' => $limit, 'post_status' => array('publish', 'pending', 'private', 'draft'), 'post_type' => $post_type, 'orderby' => 'ID', 'order' => 'ASC', 'offset' => $current_offset));
         if ($post_type == 'product_variation') {
             $product_args['orderby'] = 'post_parent';
             if ($product_limit) {
                 $parent_ids = array_map('intval', explode(',', $product_limit));
                 $child_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_parent IN (" . implode(',', $parent_ids) . ");");
                 $product_args['post__in'] = $child_ids;
             }
         }
         $products = get_posts($product_args);
         if (!$products || is_wp_error($products)) {
             break;
         }
         // Loop products
         foreach ($products as $product) {
             $row = array();
             // Pre-process data
             $meta_data = get_post_custom($product->ID);
             $product->meta = new stdClass();
             $product->attributes = new stdClass();
             // Meta data
             foreach ($meta_data as $meta => $value) {
                 if (!$meta) {
                     continue;
                 }
                 if (!$include_hidden_meta && !in_array($meta, array_keys($csv_columns)) && substr($meta, 0, 1) == '_') {
                     continue;
                 }
                 if ($include_hidden_meta && in_array($meta, $exclude_hidden_meta_columns)) {
                     continue;
                 }
                 $meta_value = maybe_unserialize(maybe_unserialize($value[0]));
                 if (is_array($meta_value)) {
                     $meta_value = json_encode($meta_value);
                 }
                 $product->meta->{$meta} = self::format_export_meta($meta_value, $meta);
             }
             // Product attributes
             if (isset($meta_data['_product_attributes'][0])) {
                 $attributes = maybe_unserialize(maybe_unserialize($meta_data['_product_attributes'][0]));
                 if (!empty($attributes) && is_array($attributes)) {
                     foreach ($attributes as $key => $attribute) {
                         if (!$key) {
                             continue;
                         }
                         if ($attribute['is_taxonomy'] == 1) {
                             $terms = wp_get_post_terms($product->ID, $key, array("fields" => "names"));
                             if (!is_wp_error($terms)) {
                                 $attribute_value = implode('|', $terms);
                             } else {
                                 $attribute_value = '';
                             }
                         } else {
                             if (empty($attribute['name'])) {
                                 continue;
                             }
                             $key = $attribute['name'];
                             $attribute_value = $attribute['value'];
                         }
                         if (!isset($attribute['position'])) {
                             $attribute['position'] = 0;
                         }
                         if (!isset($attribute['is_visible'])) {
                             $attribute['is_visible'] = 0;
                         }
                         if (!isset($attribute['is_variation'])) {
                             $attribute['is_variation'] = 0;
                         }
                         $attribute_data = $attribute['position'] . '|' . $attribute['is_visible'] . '|' . $attribute['is_variation'];
                         $_default_attributes = isset($meta_data['_default_attributes'][0]) ? maybe_unserialize(maybe_unserialize($meta_data['_default_attributes'][0])) : '';
                         if (is_array($_default_attributes)) {
                             $_default_attribute = isset($_default_attributes[$key]) ? $_default_attributes[$key] : '';
                         } else {
                             $_default_attribute = '';
                         }
                         $product->attributes->{$key} = array('value' => $attribute_value, 'data' => $attribute_data, 'default' => $_default_attribute);
                     }
                 }
             }
             // GPF
             if (isset($meta_data['_woocommerce_gpf_data'][0])) {
                 $product->gpf_data = $meta_data['_woocommerce_gpf_data'][0];
             }
             if ($post_type == 'product_variation') {
                 $post_parent_title = get_the_title($product->post_parent);
                 if (!$post_parent_title) {
                     continue;
                 }
                 $row[] = self::format_data($post_parent_title);
                 $parent_sku = WC_Product_CSV_Import_Suite::get_meta_data($product->post_parent, '_sku');
                 $row[] = $parent_sku;
             }
             // Get column values
             foreach ($csv_columns as $column => $value) {
                 if (!$export_columns || in_array($column, $export_columns)) {
                     if ($post_type == 'product_variation' && $column == '_regular_price' && empty($product->meta->{$column})) {
                         $column = '_price';
                     }
                     if (isset($product->meta->{$column})) {
                         $row[] = self::format_data($product->meta->{$column});
                     } elseif (isset($product->{$column}) && !is_array($product->{$column})) {
                         if ($column === 'post_title') {
                             $row[] = sanitize_text_field($product->{$column});
                         } else {
                             $row[] = self::format_data($product->{$column});
                         }
                     } else {
                         $row[] = '';
                     }
                 }
             }
             // Export images/gallery
             if (!$export_columns || in_array('images', $export_columns)) {
                 $image_file_names = array();
                 // Featured image
                 if (($featured_image_id = get_post_thumbnail_id($product->ID)) && ($image = wp_get_attachment_image_src($featured_image_id, 'full'))) {
                     $image_file_names[] = current($image);
                 }
                 // Images
                 $images = isset($meta_data['_product_image_gallery'][0]) ? explode(',', maybe_unserialize(maybe_unserialize($meta_data['_product_image_gallery'][0]))) : false;
                 $results = array();
                 if ($images) {
                     foreach ($images as $image_id) {
                         if ($featured_image_id == $image_id) {
                             continue;
                         }
                         $image = wp_get_attachment_image_src($image_id, 'full');
                         if ($image) {
                             $image_file_names[] = current($image);
                         }
                     }
                 }
                 $row[] = implode(' | ', $image_file_names);
             }
             // Downloadable files
             if (!$export_columns || in_array('file_paths', $export_columns)) {
                 if (!function_exists('wc_get_filename_from_url')) {
                     $file_paths = maybe_unserialize(maybe_unserialize($meta_data['_file_paths'][0]));
                     $file_paths_to_export = array();
                     if ($file_paths) {
                         foreach ($file_paths as $file_path) {
                             $file_paths_to_export[] = $file_path;
                         }
                     }
                     $file_paths_to_export = implode(' | ', $file_paths_to_export);
                     $row[] = self::format_data($file_paths_to_export);
                 } elseif (isset($meta_data['_downloadable_files'][0])) {
                     $file_paths = maybe_unserialize(maybe_unserialize($meta_data['_downloadable_files'][0]));
                     $file_paths_to_export = array();
                     if ($file_paths) {
                         foreach ($file_paths as $file_path) {
                             $file_paths_to_export[] = (!empty($file_path['name']) ? $file_path['name'] : wc_get_filename_from_url($file_path['file'])) . '::' . $file_path['file'];
                         }
                     }
                     $file_paths_to_export = implode(' | ', $file_paths_to_export);
                     $row[] = self::format_data($file_paths_to_export);
                 } else {
                     $row[] = '';
                 }
             }
             // Export taxonomies
             if (!$export_columns || in_array('taxonomies', $export_columns)) {
                 foreach ($product_taxonomies as $taxonomy) {
                     if (strstr($taxonomy->name, 'pa_')) {
                         continue;
                     }
                     // Skip attributes
                     if (is_taxonomy_hierarchical($taxonomy->name)) {
                         $terms = wp_get_post_terms($product->ID, $taxonomy->name, array("fields" => "all"));
                         $formatted_terms = array();
                         foreach ($terms as $term) {
                             $ancestors = array_reverse(get_ancestors($term->term_id, $taxonomy->name));
                             $formatted_term = array();
                             foreach ($ancestors as $ancestor) {
                                 $formatted_term[] = get_term($ancestor, $taxonomy->name)->name;
                             }
                             $formatted_term[] = $term->name;
                             $formatted_terms[] = implode(' > ', $formatted_term);
                         }
                         $row[] = self::format_data(implode('|', $formatted_terms));
                     } else {
                         $terms = wp_get_post_terms($product->ID, $taxonomy->name, array('fields' => 'slugs'));
                         $row[] = self::format_data(implode('|', $terms));
                     }
                 }
             }
             // Export meta data
             if (!$export_columns || in_array('meta', $export_columns)) {
                 foreach ($found_product_meta as $product_meta) {
                     if (isset($product->meta->{$product_meta})) {
                         $row[] = self::format_data($product->meta->{$product_meta});
                     } else {
                         $row[] = '';
                     }
                 }
             }
             // Find and export attributes
             if (!$export_columns || in_array('attributes', $export_columns)) {
                 foreach ($found_attributes as $attribute) {
                     if (isset($product->attributes) && isset($product->attributes->{$attribute})) {
                         $values = $product->attributes->{$attribute};
                         $row[] = self::format_data($values['value']);
                         $row[] = self::format_data($values['data']);
                         $row[] = self::format_data($values['default']);
                     } else {
                         $row[] = '';
                         $row[] = '';
                         $row[] = '';
                     }
                 }
             }
             // Export GPF
             if (function_exists('woocommerce_gpf_install') && (!$export_columns || in_array('gpf', $export_columns))) {
                 $gpf_data = empty($product->gpf_data) ? '' : maybe_unserialize($product->gpf_data);
                 $row[] = empty($gpf_data['availability']) ? '' : $gpf_data['availability'];
                 $row[] = empty($gpf_data['condition']) ? '' : $gpf_data['condition'];
                 $row[] = empty($gpf_data['brand']) ? '' : $gpf_data['brand'];
                 $row[] = empty($gpf_data['product_type']) ? '' : $gpf_data['product_type'];
                 $row[] = empty($gpf_data['google_product_category']) ? '' : $gpf_data['google_product_category'];
                 $row[] = empty($gpf_data['gtin']) ? '' : $gpf_data['gtin'];
                 $row[] = empty($gpf_data['mpn']) ? '' : $gpf_data['mpn'];
                 $row[] = empty($gpf_data['gender']) ? '' : $gpf_data['gender'];
                 $row[] = empty($gpf_data['age_group']) ? '' : $gpf_data['age_group'];
                 $row[] = empty($gpf_data['color']) ? '' : $gpf_data['color'];
                 $row[] = empty($gpf_data['size']) ? '' : $gpf_data['size'];
                 $row[] = empty($gpf_data['adwords_grouping']) ? '' : $gpf_data['adwords_grouping'];
                 $row[] = empty($gpf_data['adwords_labels']) ? '' : $gpf_data['adwords_labels'];
                 $row[] = empty($gpf_data['custom_label_0']) ? '' : $gpf_data['custom_label_0'];
                 $row[] = empty($gpf_data['custom_label_1']) ? '' : $gpf_data['custom_label_1'];
                 $row[] = empty($gpf_data['custom_label_2']) ? '' : $gpf_data['custom_label_2'];
                 $row[] = empty($gpf_data['custom_label_3']) ? '' : $gpf_data['custom_label_3'];
                 $row[] = empty($gpf_data['custom_label_4']) ? '' : $gpf_data['custom_label_4'];
             }
             // Add to csv
             $row = array_map('WC_PCSVIS_Exporter::wrap_column', $row);
             fwrite($fp, implode(',', $row) . "\n");
             unset($row);
         }
         $current_offset += $limit;
         $export_count += $limit;
         unset($products);
     }
     fclose($fp);
     exit;
 }
 /**
  * Parses the CSV file and prepares us for the task of processing parsed data
  *
  * @param string $file Path to the CSV file for importing
  */
 function import_start($file, $mapping, $start_pos, $end_pos)
 {
     WC_Product_CSV_Import_Suite::log(__('Parsing product variations CSV.', 'woocommerce-product-csv-import-suite'));
     $this->parser = new WC_CSV_Parser('product_variation');
     list($this->parsed_data, $this->raw_headers, $position) = $this->parser->parse_data($file, $this->delimiter, $mapping, $start_pos, $end_pos);
     WC_Product_CSV_Import_Suite::log(__('Finished parsing product variations CSV.', 'woocommerce-product-csv-import-suite'));
     unset($import_data);
     wp_defer_term_counting(true);
     wp_defer_comment_counting(true);
     return $position;
 }
 /**
  * Parse product
  * @param  array  $item
  * @param  integer $merge_empty_cells
  * @return array
  */
 public function parse_product($item, $merge_empty_cells = 0)
 {
     global $WC_CSV_Product_Import, $wpdb;
     $this->row++;
     $terms_array = $postmeta = $product = array();
     $attributes = $default_attributes = $gpf_data = null;
     // Merging
     $merging = !empty($_GET['merge']) && $_GET['merge'] ? true : false;
     // Is variation
     $is_variation = false;
     if (isset($_GET['import_page']) && 'woocommerce_variation_csv' === $_GET['import_page']) {
         $is_variation = true;
     }
     // Post ID field mapping
     $post_id = !empty($item['id']) ? $item['id'] : 0;
     $post_id = !empty($item['post_id']) ? $item['post_id'] : $post_id;
     if ($merging) {
         $product['merging'] = true;
         WC_Product_CSV_Import_Suite::log(sprintf(__('> Row %s - preparing for merge.', 'woocommerce-product-csv-import-suite'), $this->row));
         // Required fields
         if (!$post_id && empty($item['sku'])) {
             WC_Product_CSV_Import_Suite::log(__('> > Cannot merge without id or sku. Importing instead.', 'woocommerce-product-csv-import-suite'));
             $merging = false;
         } else {
             // Check product exists
             if (!$post_id) {
                 // Check product to merge exists
                 $found_product_id = $wpdb->get_var($wpdb->prepare("\n\t\t\t\t\t\tSELECT {$wpdb->posts}.ID\n\t\t\t\t\t    FROM {$wpdb->posts}\n\t\t\t\t\t    LEFT JOIN {$wpdb->postmeta} ON ( {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id )\n\t\t\t\t\t    WHERE {$wpdb->posts}.post_type = '" . $this->post_type . "'\n\t\t\t\t\t    AND {$wpdb->posts}.post_status IN ( 'publish', 'private', 'draft', 'pending', 'future' )\n\t\t\t\t\t    AND {$wpdb->postmeta}.meta_key = '_sku' AND {$wpdb->postmeta}.meta_value = '%s'\n\t\t\t\t\t ", $item['sku']));
                 if ($is_variation && !$found_product_id && empty($item['post_title'])) {
                     $merging = false;
                 } else {
                     if (!$found_product_id && empty($item['post_title'])) {
                         WC_Product_CSV_Import_Suite::log(sprintf(__('> > Skipped. Cannot find product with sku %s.', 'woocommerce-product-csv-import-suite'), $item['sku']));
                         return new WP_Error('parse-error', __('Skipped. Cannot find product with sku.', 'woocommerce-product-csv-import-suite'));
                     } elseif (!$found_product_id) {
                         WC_Product_CSV_Import_Suite::log(sprintf(__('> > Skipped. Cannot find product with sku %s. Importing instead.', 'woocommerce-product-csv-import-suite'), $item['sku']));
                         $merging = false;
                     } else {
                         $post_id = $found_product_id;
                         WC_Product_CSV_Import_Suite::log(sprintf(__('> > Found product with ID %s.', 'woocommerce-product-csv-import-suite'), $post_id));
                     }
                 }
             }
         }
     }
     if (!$merging) {
         $product['merging'] = false;
         WC_Product_CSV_Import_Suite::log(sprintf(__('> Row %s - preparing for import.', 'woocommerce-product-csv-import-suite'), $this->row));
         // Required fields
         if ($this->post_type == 'product' && empty($item['post_title'])) {
             WC_Product_CSV_Import_Suite::log(__('> > Skipped. No post_title set for new product.', 'woocommerce-product-csv-import-suite'));
             return new WP_Error('parse-error', __('No post_title set for new product.', 'woocommerce-product-csv-import-suite'));
         }
     }
     $product['post_id'] = $post_id;
     // Get post fields
     foreach ($this->post_defaults as $column => $default) {
         if (isset($item[$column])) {
             $product[$column] = $item[$column];
         }
     }
     // Get custom fields
     foreach ($this->postmeta_defaults as $column => $default) {
         if (isset($item[$column])) {
             $postmeta[$column] = (string) $item[$column];
         } elseif (isset($item['_' . $column])) {
             $postmeta[$column] = (string) $item['_' . $column];
         }
         // Check custom fields are valid
         if (isset($postmeta[$column]) && isset($this->postmeta_allowed[$column]) && !in_array($postmeta[$column], $this->postmeta_allowed[$column])) {
             $postmeta[$column] = $this->postmeta_defaults[$column];
         }
     }
     if (!$merging) {
         // Merge post meta with defaults
         $product = wp_parse_args($product, $this->post_defaults);
         $postmeta = wp_parse_args($postmeta, $this->postmeta_defaults);
     }
     // Handle special meta fields
     // price
     if ($merging) {
         if (!isset($postmeta['regular_price'])) {
             $postmeta['regular_price'] = WC_Product_CSV_Import_Suite::get_meta_data($post_id, '_regular_price');
         }
         if (!isset($postmeta['sale_price'])) {
             $postmeta['sale_price'] = WC_Product_CSV_Import_Suite::get_meta_data($post_id, '_sale_price');
         }
     }
     // Sale dates
     if (isset($postmeta['sale_price_dates_from'])) {
         $postmeta['sale_price_dates_from'] = empty($postmeta['sale_price_dates_from']) ? '' : strtotime($postmeta['sale_price_dates_from']);
     }
     if (isset($postmeta['sale_price_dates_to'])) {
         $postmeta['sale_price_dates_to'] = empty($postmeta['sale_price_dates_to']) ? '' : strtotime($postmeta['sale_price_dates_to']);
     }
     // Set price to sale price
     if (isset($postmeta['regular_price']) && isset($postmeta['sale_price']) && $postmeta['sale_price'] !== '' && (empty($postmeta['sale_price_dates_from']) || current_time('timestamp') >= $postmeta['sale_price_dates_from']) && (empty($postmeta['sale_price_dates_to']) || current_time('timestamp') < $postmeta['sale_price_dates_to'])) {
         $price = min($postmeta['sale_price'], $postmeta['regular_price']);
         $postmeta['price'] = $price;
     } elseif (isset($postmeta['regular_price'])) {
         $postmeta['price'] = $postmeta['regular_price'];
     }
     // Format prices
     if (isset($postmeta['regular_price'])) {
         $postmeta['regular_price'] = wc_format_decimal($postmeta['regular_price']);
     }
     if (isset($postmeta['sale_price'])) {
         $postmeta['sale_price'] = wc_format_decimal($postmeta['sale_price']);
     }
     if (isset($postmeta['price'])) {
         $postmeta['price'] = wc_format_decimal($postmeta['price']);
     }
     // Reset dynamically generated meta
     $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'] = '';
     // upsells
     if (isset($postmeta['upsell_ids']) && !is_array($postmeta['upsell_ids'])) {
         $ids = array_filter(array_map('trim', explode('|', $postmeta['upsell_ids'])));
         $postmeta['upsell_ids'] = $ids;
     }
     // crosssells
     if (isset($postmeta['crosssell_ids']) && !is_array($postmeta['crosssell_ids'])) {
         $ids = array_filter(array_map('trim', explode('|', $postmeta['crosssell_ids'])));
         $postmeta['crosssell_ids'] = $ids;
     }
     // variation description
     if (isset($postmeta['variation_description'])) {
         $postmeta['variation_description'] = esc_textarea($postmeta['variation_description']);
     }
     // Relative stock updates
     if ($merging) {
         if (isset($postmeta['stock'])) {
             $postmeta['stock'] = trim($postmeta['stock']);
             $mode = substr($postmeta['stock'], 0, 3);
             if ($mode == '(+)') {
                 $old_stock = absint(WC_Product_CSV_Import_Suite::get_meta_data($post_id, '_stock'));
                 $amount = absint(substr($postmeta['stock'], 3));
                 $new_stock = $old_stock + $amount;
                 $postmeta['stock'] = $new_stock;
             }
             if ($mode == '(-)') {
                 $old_stock = absint(WC_Product_CSV_Import_Suite::get_meta_data($post_id, '_stock'));
                 $amount = absint(substr($postmeta['stock'], 3));
                 $new_stock = $old_stock - $amount;
                 $postmeta['stock'] = $new_stock;
             }
         }
     }
     // Format post status
     if (!empty($product['post_status'])) {
         $product['post_status'] = strtolower($product['post_status']);
         if ('product' === $this->post_type) {
             if (!in_array($product['post_status'], array('publish', 'private', 'draft', 'pending', 'future', 'inherit', 'trash'))) {
                 $product['post_status'] = 'publish';
             }
         } else {
             if (!in_array($product['post_status'], array('private', 'publish'))) {
                 $product['post_status'] = 'publish';
             }
         }
     }
     // Put set core product postmeta into product array
     foreach ($postmeta as $key => $value) {
         $product['postmeta'][] = array('key' => '_' . esc_attr($key), 'value' => $value);
     }
     /**
      * Handle other columns
      */
     foreach ($item as $key => $value) {
         if ($this->post_type == 'product' && !$merge_empty_cells && $value == "") {
             continue;
         }
         /**
          * File path handling
          */
         if ($key == 'file_paths' || $key == 'downloadable_files') {
             $file_paths = explode('|', $value);
             $_file_paths = array();
             foreach ($file_paths as $file_path) {
                 // 2.1
                 if (function_exists('wc_get_filename_from_url')) {
                     $file_path = array_map('trim', explode('::', $file_path));
                     if (sizeof($file_path) === 2) {
                         $file_name = $file_path[0];
                         $file_path = $file_path[1];
                     } else {
                         $file_name = wc_get_filename_from_url($file_path[0]);
                         $file_path = $file_path[0];
                     }
                     $_file_paths[md5($file_path)] = array('name' => $file_name, 'file' => $file_path);
                 } else {
                     $file_path = trim($file_path);
                     $_file_paths[md5($file_path)] = $file_path;
                 }
             }
             $value = $_file_paths;
             $product['postmeta'][] = array('key' => '_' . esc_attr($key), 'value' => $value);
         } elseif (strstr($key, 'meta:attribute_pa_')) {
             // Get meta key name
             $meta_key = isset($WC_CSV_Product_Import->raw_headers[$key]) ? $WC_CSV_Product_Import->raw_headers[$key] : $key;
             $meta_key = trim(str_replace('meta:', '', $meta_key));
             // Convert to slug
             $value = sanitize_title($value);
             // Add to postmeta array
             $product['postmeta'][] = array('key' => esc_attr($meta_key), 'value' => $value);
         } elseif (strstr($key, 'meta:')) {
             // Get meta key name
             $meta_key = isset($WC_CSV_Product_Import->raw_headers[$key]) ? $WC_CSV_Product_Import->raw_headers[$key] : $key;
             $meta_key = trim(str_replace('meta:', '', $meta_key));
             // Decode JSON
             $json = json_decode($value, true);
             if (is_array($json) || is_object($json)) {
                 $value = (array) $json;
             }
             // Add to postmeta array
             $product['postmeta'][] = array('key' => esc_attr($meta_key), 'value' => $value);
         } elseif (strstr($key, 'tax:')) {
             // Get taxonomy
             $taxonomy = trim(str_replace('tax:', '', $key));
             // Exists?
             if (!taxonomy_exists($taxonomy)) {
                 WC_Product_CSV_Import_Suite::log(sprintf(__('> > Skipping taxonomy "%s" - it does not exist.', 'woocommerce-product-csv-import-suite'), $taxonomy));
                 continue;
             }
             // Product type check
             if ('product_type' === $taxonomy) {
                 $term = strtolower($value);
                 if (!array_key_exists($term, $this->allowed_product_types)) {
                     WC_Product_CSV_Import_Suite::log(sprintf(__('> > > Product type "%s" not allowed - using simple.', 'woocommerce-product-csv-import-suite'), $term));
                     $term_id = $this->allowed_product_types['simple'];
                 } else {
                     $term_id = $this->allowed_product_types[$term];
                 }
                 // Add to array
                 $terms_array[] = array('taxonomy' => $taxonomy, 'terms' => array($term_id));
                 continue;
             }
             // Get terms - ID => parent
             $terms = array();
             $raw_terms = explode('|', $value);
             $raw_terms = array_map('trim', $raw_terms);
             // Handle term hierachy (>)
             foreach ($raw_terms as $raw_term) {
                 if (strstr($raw_term, '>')) {
                     $raw_term = explode('>', $raw_term);
                     $raw_term = array_map('trim', $raw_term);
                     $raw_term = array_map('esc_html', $raw_term);
                     $raw_term = array_filter($raw_term);
                     $parent = 0;
                     $loop = 0;
                     foreach ($raw_term as $term) {
                         $loop++;
                         $term_id = '';
                         if (isset($this->inserted_terms[$taxonomy][$parent][$term])) {
                             $term_id = $this->inserted_terms[$taxonomy][$parent][$term];
                         } elseif ($term) {
                             /**
                              * Check term existance
                              */
                             $term_may_exist = term_exists($term, $taxonomy, absint($parent));
                             WC_Product_CSV_Import_Suite::log(sprintf(__('> > (' . __LINE__ . ') Term %s (%s) exists? %s', 'woocommerce-product-csv-import-suite'), sanitize_text_field($term), esc_html($taxonomy), $term_may_exist ? print_r($term_may_exist, true) : '-'));
                             if (is_array($term_may_exist)) {
                                 $possible_term = get_term($term_may_exist['term_id'], $taxonomy);
                                 if ($possible_term->parent == $parent) {
                                     $term_id = $term_may_exist['term_id'];
                                 }
                             }
                             if (!$term_id) {
                                 // Create appropriate slug
                                 $slug = array();
                                 for ($i = 0; $i < $loop; $i++) {
                                     $slug[] = $raw_term[$i];
                                 }
                                 $slug = sanitize_title(implode('-', $slug));
                                 $t = wp_insert_term($term, $taxonomy, array('parent' => $parent, 'slug' => $slug));
                                 if (!is_wp_error($t)) {
                                     $term_id = $t['term_id'];
                                 } else {
                                     WC_Product_CSV_Import_Suite::log(sprintf(__('> > (' . __LINE__ . ') Failed to import term %s, parent %s - %s', 'woocommerce-product-csv-import-suite'), sanitize_text_field($term), sanitize_text_field($parent), sanitize_text_field($taxonomy)));
                                     break;
                                 }
                             }
                             $this->inserted_terms[$taxonomy][$parent][$term] = $term_id;
                         }
                         if (!$term_id) {
                             break;
                         }
                         // Add to product terms, ready to set if this is the final term
                         if (sizeof($raw_term) == $loop) {
                             $terms[] = $term_id;
                         }
                         $parent = $term_id;
                     }
                 } else {
                     $term_id = '';
                     $raw_term = esc_html($raw_term);
                     if (isset($this->inserted_terms[$taxonomy][0][$raw_term])) {
                         $term_id = $this->inserted_terms[$taxonomy][0][$raw_term];
                     } elseif ($raw_term) {
                         // Check term existance
                         $term_exists = term_exists($raw_term, $taxonomy, 0);
                         $term_id = is_array($term_exists) ? $term_exists['term_id'] : 0;
                         if (!$term_id) {
                             $t = wp_insert_term(trim($raw_term), $taxonomy, array('parent' => 0));
                             if (!is_wp_error($t)) {
                                 $term_id = $t['term_id'];
                             } else {
                                 WC_Product_CSV_Import_Suite::log(sprintf(__('> > Failed to import term %s %s', 'woocommerce-product-csv-import-suite'), esc_html($raw_term), esc_html($taxonomy)));
                                 break;
                             }
                         }
                         $this->inserted_terms[$taxonomy][0][$raw_term] = $term_id;
                     }
                     // Store terms for later insertion
                     if ($term_id) {
                         $terms[] = $term_id;
                     }
                 }
             }
             // Any defined?
             if (sizeof($terms) == 0) {
                 continue;
             }
             // Add to array
             $terms_array[] = array('taxonomy' => $taxonomy, 'terms' => $terms);
         } elseif (strstr($key, 'attribute:')) {
             $attribute_key = sanitize_title(trim(str_replace('attribute:', '', $key)));
             $attribute_name = str_replace('attribute:', '', $WC_CSV_Product_Import->raw_headers[$key]);
             if (!$attribute_key) {
                 continue;
             }
             // Taxonomy
             if (substr($attribute_key, 0, 3) == 'pa_') {
                 $taxonomy = $attribute_key;
                 // Exists?
                 if (!taxonomy_exists($taxonomy)) {
                     $nicename = strtolower(sanitize_title(str_replace('pa_', '', $taxonomy)));
                     WC_Product_CSV_Import_Suite::log(sprintf(__('> > Attribute taxonomy "%s" does not exist. Adding it. Nicename: %s', 'woocommerce-product-csv-import-suite'), $taxonomy, $nicename));
                     $exists_in_db = $wpdb->get_var("SELECT attribute_id FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = '" . $nicename . "';");
                     if (!$exists_in_db) {
                         // Create the taxonomy
                         $wpdb->insert($wpdb->prefix . "woocommerce_attribute_taxonomies", array('attribute_name' => $nicename, 'attribute_label' => $nicename, 'attribute_type' => 'select', 'attribute_orderby' => 'menu_order'));
                     } else {
                         WC_Product_CSV_Import_Suite::log(sprintf(__('> > Attribute taxonomy %s already exists in DB.', 'woocommerce-product-csv-import-suite'), $taxonomy));
                     }
                     // Register the taxonomy now so that the import works!
                     register_taxonomy($taxonomy, array('product', 'product_variation'), array('hierarchical' => true, 'show_ui' => false, 'query_var' => true, 'rewrite' => false));
                 }
                 // Get terms
                 $terms = array();
                 $raw_terms = explode('|', $value);
                 $raw_terms = array_map('esc_html', $raw_terms);
                 $raw_terms = array_map('trim', $raw_terms);
                 if (sizeof($raw_terms) > 0) {
                     foreach ($raw_terms as $raw_term) {
                         if (empty($raw_term) && 0 != $raw_term) {
                             continue;
                         }
                         // Check term existance
                         $term_exists = term_exists($raw_term, $taxonomy, 0);
                         $term_id = is_array($term_exists) ? $term_exists['term_id'] : 0;
                         if (!$term_id) {
                             $t = wp_insert_term(trim($raw_term), $taxonomy);
                             if (!is_wp_error($t)) {
                                 $term_id = $t['term_id'];
                                 WC_Product_CSV_Import_Suite::log(sprintf(__('> > Inserted Raw Term %s ID = %s', 'woocommerce-product-csv-import-suite'), esc_html($raw_term), $term_id));
                             } else {
                                 WC_Product_CSV_Import_Suite::log(sprintf(__('> > Failed to import term %s %s', 'woocommerce-product-csv-import-suite'), esc_html($raw_term), esc_html($taxonomy)));
                                 break;
                             }
                         } else {
                             WC_Product_CSV_Import_Suite::log(sprintf(__('> > Raw Term %s ID = %s', 'woocommerce-product-csv-import-suite'), esc_html($raw_term), $term_id));
                         }
                         if ($term_id) {
                             $terms[] = $term_id;
                         }
                     }
                 }
                 // Add to array
                 $terms_array[] = array('taxonomy' => $taxonomy, 'terms' => $terms);
                 // Ensure we have original attributes
                 if (is_null($attributes) && $merging) {
                     $attributes = array_filter((array) WC_Product_CSV_Import_Suite::get_meta_data($post_id, '_product_attributes'));
                 } elseif (is_null($attributes)) {
                     $attributes = array();
                 }
                 // Set attribute
                 if (!isset($attributes[$taxonomy])) {
                     $attributes[$taxonomy] = array();
                 }
                 $attributes[$taxonomy]['name'] = $taxonomy;
                 $attributes[$taxonomy]['value'] = null;
                 $attributes[$taxonomy]['is_taxonomy'] = 1;
                 if (!isset($attributes[$taxonomy]['position'])) {
                     $attributes[$taxonomy]['position'] = 0;
                 }
                 if (!isset($attributes[$taxonomy]['is_visible'])) {
                     $attributes[$taxonomy]['is_visible'] = 1;
                 }
                 if (!isset($attributes[$taxonomy]['is_variation'])) {
                     $attributes[$taxonomy]['is_variation'] = 0;
                 }
             } else {
                 if (!$value || !$attribute_key) {
                     continue;
                 }
                 // Set attribute
                 if (!isset($attributes[$attribute_key])) {
                     $attributes[$attribute_key] = array();
                 }
                 $attributes[$attribute_key]['name'] = $attribute_name;
                 $attributes[$attribute_key]['value'] = $value;
                 $attributes[$attribute_key]['is_taxonomy'] = 0;
                 if (!isset($attributes[$attribute_key]['position'])) {
                     $attributes[$attribute_key]['position'] = 0;
                 }
                 if (!isset($attributes[$attribute_key]['is_visible'])) {
                     $attributes[$attribute_key]['is_visible'] = 1;
                 }
                 if (!isset($attributes[$attribute_key]['is_variation'])) {
                     $attributes[$attribute_key]['is_variation'] = 0;
                 }
             }
         } elseif (strstr($key, 'attribute_data:')) {
             $attribute_key = sanitize_title(trim(str_replace('attribute_data:', '', $key)));
             if (!$attribute_key) {
                 continue;
             }
             $values = explode('|', $value);
             $position = isset($values[0]) ? (int) $values[0] : 0;
             $visible = isset($values[1]) ? (int) $values[1] : 1;
             $variation = isset($values[2]) ? (int) $values[2] : 0;
             // Ensure we have original attributes
             if (!isset($attributes[$attribute_key])) {
                 if ($merging) {
                     $existing_attributes = array_filter((array) WC_Product_CSV_Import_Suite::get_meta_data($post_id, '_product_attributes'));
                     $attributes[$attribute_key] = isset($existing_attributes[$attribute_key]) ? $existing_attributes[$attribute_key] : array();
                 } else {
                     $attributes[$attribute_key] = array();
                 }
             }
             $attributes[$attribute_key]['position'] = $position;
             $attributes[$attribute_key]['is_visible'] = $visible;
             $attributes[$attribute_key]['is_variation'] = $variation;
         } elseif (strstr($key, 'attribute_default:')) {
             $attribute_key = sanitize_title(trim(str_replace('attribute_default:', '', $key)));
             if (!$attribute_key) {
                 continue;
             }
             // Ensure we have original attributes
             if (is_null($default_attributes) && $merging) {
                 $default_attributes = array_filter((array) WC_Product_CSV_Import_Suite::get_meta_data($post_id, '_default_attributes'));
             } elseif (is_null($default_attributes)) {
                 $default_attributes = array();
             }
             $default_attributes[$attribute_key] = $value;
         } elseif (strstr($key, 'gpf:')) {
             $gpf_key = trim(str_replace('gpf:', '', $key));
             // Get original values
             if (is_null($gpf_data) && $merging) {
                 $gpf_data = array_filter((array) WC_Product_CSV_Import_Suite::get_meta_data($post_id, '_woocommerce_gpf_data'));
             } elseif (is_null($gpf_data)) {
                 $gpf_data = array('availability' => '', 'condition' => '', 'brand' => '', 'product_type' => '', 'google_product_category' => '', 'gtin' => '', 'mpn' => '', 'gender' => '', 'age_group' => '', 'color' => '', 'size' => '', 'delivery_label' => '', 'size' => '', 'custom_label_0' => '', 'custom_label_1' => '', 'custom_label_2' => '', 'custom_label_3' => '', 'custom_label_4' => '');
             }
             $gpf_data[$gpf_key] = $value;
         } elseif (strstr($key, 'parent_sku')) {
             if ($value) {
                 $possible_parent_ids = $wpdb->get_col($wpdb->prepare("SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key='_sku' AND meta_value = %s", $value));
                 if ($possible_parent_ids) {
                     foreach ($possible_parent_ids as $possible_parent_id) {
                         if ('product' === get_post_type($possible_parent_id) && in_array(get_post_status($possible_parent_id), array('publish', 'private', 'draft'))) {
                             $product['post_parent'] = $possible_parent_id;
                             break;
                         }
                     }
                 }
             }
         } elseif (strstr($key, 'upsell_skus')) {
             if ($value) {
                 $skus = array_filter(array_map('trim', explode('|', $value)));
                 $product['upsell_skus'] = $skus;
             }
         } elseif (strstr($key, 'crosssell_skus')) {
             if ($value) {
                 $skus = array_filter(array_map('trim', explode('|', $value)));
                 $product['crosssell_skus'] = $skus;
             }
         }
     }
     // Remove empty attribues
     if (!empty($attributes)) {
         foreach ($attributes as $key => $value) {
             if (!isset($value['name'])) {
                 unset($attributes[$key]);
             }
         }
     }
     /**
      * Handle images
      */
     if (!empty($item['images'])) {
         $images = array_map('trim', explode('|', $item['images']));
     } else {
         $images = '';
     }
     $product['postmeta'][] = array('key' => '_default_attributes', 'value' => $default_attributes);
     $product['attributes'] = $attributes;
     $product['gpf_data'] = $gpf_data;
     $product['images'] = $images;
     $product['terms'] = $terms_array;
     $product['sku'] = !empty($item['sku']) ? $item['sku'] : '';
     $product['post_title'] = !empty($item['post_title']) ? $item['post_title'] : '';
     unset($item, $terms_array, $postmeta, $attributes, $gpf_data, $images);
     return $product;
 }
 /**
  * If fetching attachments is enabled then attempt to create a new attachment
  *
  * @param array $post Attachment post details from WXR
  * @param string $url URL to fetch attachment from
  * @return int|WP_Error Post ID on success, WP_Error otherwise
  */
 public function process_attachment($post, $url, $post_id)
 {
     $attachment_id = '';
     $attachment_url = '';
     $attachment_file = '';
     $upload_dir = wp_upload_dir();
     if (strstr($url, site_url())) {
         $abs_url = str_replace(trailingslashit(site_url()), trailingslashit(ABSPATH), $url);
         $new_name = wp_unique_filename($upload_dir['path'], basename($url));
         $new_url = trailingslashit($upload_dir['path']) . $new_name;
         if (copy($abs_url, $new_url)) {
             $url = basename($new_url);
         }
     }
     if (!strstr($url, 'http')) {
         // Local file
         $attachment_file = trailingslashit($upload_dir['basedir']) . 'product_images/' . $url;
         // We have the path, check it exists
         if (!file_exists($attachment_file)) {
             $attachment_file = trailingslashit($upload_dir['path']) . $url;
         }
         // We have the path, check it exists
         if (file_exists($attachment_file)) {
             $attachment_url = str_replace(trailingslashit(ABSPATH), trailingslashit(site_url()), $attachment_file);
             if ($info = wp_check_filetype($attachment_file)) {
                 $post['post_mime_type'] = $info['type'];
             } else {
                 return new WP_Error('attachment_processing_error', __('Invalid file type', 'wordpress-importer'));
             }
             $post['guid'] = $attachment_url;
             $attachment_id = wp_insert_attachment($post, $attachment_file, $post_id);
         } else {
             return new WP_Error('attachment_processing_error', __('Local image did not exist!', 'wordpress-importer'));
         }
     } else {
         // if the URL is absolute, but does not contain address, then upload it assuming base_site_url
         if (preg_match('|^/[\\w\\W]+$|', $url)) {
             $url = rtrim(site_url(), '/') . $url;
         }
         $upload = $this->fetch_remote_file($url, $post);
         if (is_wp_error($upload)) {
             return $upload;
         }
         if ($info = wp_check_filetype($upload['file'])) {
             $post['post_mime_type'] = $info['type'];
         } else {
             return new WP_Error('attachment_processing_error', __('Invalid file type', 'wordpress-importer'));
         }
         $post['guid'] = $upload['url'];
         $attachment_file = $upload['file'];
         $attachment_url = $upload['url'];
         // as per wp-admin/includes/upload.php
         $attachment_id = wp_insert_attachment($post, $upload['file'], $post_id);
         unset($upload);
     }
     if (!is_wp_error($attachment_id) && $attachment_id > 0) {
         WC_Product_CSV_Import_Suite::log(sprintf(__('> > Inserted image attachment "%s"', 'woocommerce-product-csv-import-suite'), $url));
         $this->attachments[] = $attachment_id;
     }
     return $attachment_id;
 }
 /**
  * Get meta data direct from DB, avoiding get_post_meta and caches
  * @return string
  */
 public static function log($message)
 {
     if (!self::$logger) {
         self::$logger = new WC_Logger();
     }
     self::$logger->add('csv-import', $message);
 }