/** * 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); }