<?php require_once dirname(__FILE__) . '/XmlImportWooCommerce.php'; class XmlImportWooCommerceProduct extends XmlImportWooCommerce{ public $previousID; public $product_taxonomies; public $reserved_terms = array( 'attachment', 'attachment_id', 'author', 'author_name', 'calendar', 'cat', 'category', 'category__and', 'category__in', 'category__not_in', 'category_name', 'comments_per_page', 'comments_popup', 'cpage', 'day', 'debug', 'error', 'exact', 'feed', 'hour', 'link_category', 'm', 'minute', 'monthnum', 'more', 'name', 'nav_menu', 'nopaging', 'offset', 'order', 'orderby', 'p', 'page', 'page_id', 'paged', 'pagename', 'pb', 'perm', 'post', 'post__in', 'post__not_in', 'post_format', 'post_mime_type', 'post_status', 'post_tag', 'post_type', 'posts', 'posts_per_archive_page', 'posts_per_page', 'preview', 'robots', 's', 'search', 'second', 'sentence', 'showposts', 'static', 'subpost', 'subpost_id', 'tag', 'tag__and', 'tag__in', 'tag__not_in', 'tag_id', 'tag_slug__and', 'tag_slug__in', 'taxonomy', 'tb', 'term', 'type', 'w', 'withcomments', 'withoutcomments', 'year', ); public function __construct( $options ){ global $wpdb; $this->wpdb = $wpdb; $this->import = $options['import']; $this->count = $options['count']; $this->xml = $options['xml']; $this->logger = $options['logger']; $this->chunk = $options['chunk']; $this->xpath = $options['xpath_prefix']; $product_taxonomies = array('post_format', 'product_type', 'product_shipping_class'); $this->product_taxonomies = array_diff_key(get_taxonomies_by_object_type(array('product'), 'object'), array_flip($product_taxonomies)); } public function parse() { $cxpath = $this->xpath . $this->import->xpath; $this->data = array(); $records = array(); $tmp_files = array(); $this->chunk == 1 and $this->logger and call_user_func($this->logger, __('Composing product data...', 'wpai_woocommerce_addon_plugin')); $options = array('virtual', 'downloadable', 'enabled', 'featured', 'visibility', 'enable_reviews', 'manage_stock'); foreach ($options as $option) { if ($this->import->options['is_product_' . $option] == 'xpath' and "" != $this->import->options['single_product_' . $option]) { $this->data['product_' . $option] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_product_' . $option], $file)->parse($records); $tmp_files[] = $file; } else { $this->count and $this->data['product_' . $option] = array_fill(0, $this->count, $this->import->options['is_product_' . $option]); } } $options = array('sku', 'variation_description', 'url', 'button_text', 'regular_price', 'sale_price', 'whosale_price', 'files', 'files_names', 'download_limit', 'download_expiry', 'download_type', 'stock_qty', 'weight', 'length', 'width', 'height', 'up_sells', 'cross_sells', 'purchase_note', 'menu_order'); foreach ($options as $option) { if ( "" != $this->import->options['single_product_' . $option] ) { switch ($option) { case 'regular_price': case 'sale_price': $this->data['product_' . $option] = array_map(array($this, 'adjust_price'), array_map(array($this, 'prepare_price'), XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_product_' . $option], $file)->parse($records)), array_fill(0, $this->count, $option)); $tmp_files[] = $file; break; default: $this->data['product_' . $option] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_product_' . $option], $file)->parse($records); $tmp_files[] = $file; break; } } else { $this->count and $this->data['product_' . $option] = array_fill(0, $this->count, ""); } } $options = array('sale_price_dates_from', 'sale_price_dates_to'); foreach ($options as $option) { if ($this->import->options['is_regular_price_shedule'] and "" != $this->import->options['single_' . $option]) { $this->data['product_' . $option] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_' . $option], $file)->parse($records); $tmp_files[] = $file; } else { $this->count and $this->data['product_' . $option] = array_fill(0, $this->count, ""); } } $options = array('id', 'parent_id', 'id_first_is_parent_id', 'id_first_is_parent_title', 'id_first_is_variation', 'first_is_parent_id_parent_sku', 'first_is_parent_title_parent_sku'); foreach ($options as $option) { if ( isset($this->import->options['single_product_' . $option]) && "" != $this->import->options['single_product_' . $option] ) { $this->data['single_product_' . preg_replace("%id$%", "ID", $option)] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_product_' . $option], $file)->parse($records); $tmp_files[] = $file; } else { $this->count and $this->data['single_product_' . preg_replace("%id$%", "ID", $option)] = array_fill(0, $this->count, ""); } } $options = array('type', 'tax_status', 'tax_class', 'shipping_class'); foreach ($options as $option) { $option_name = ($option == 'type') ? 'types' : $option; if ($this->import->options['is_multiple_product_' . $option] != 'yes' and "" != $this->import->options['single_product_' . $option]) { $this->data['product_' . $option_name] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_product_' . $option], $file)->parse($records); $tmp_files[] = $file; } else { $this->count and $this->data['product_' . $option_name] = array_fill(0, $this->count, $this->import->options['multiple_product_' . $option]); } } // Composing product Allow Backorders? if ($this->import->options['product_allow_backorders'] == 'xpath' and "" != $this->import->options['single_product_allow_backorders']){ $this->data['product_allow_backorders'] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_product_allow_backorders'], $file)->parse($records); $tmp_files[] = $file; } else{ $this->count and $this->data['product_allow_backorders'] = array_fill(0, $this->count, $this->import->options['product_allow_backorders']); } // Composing product Sold Individually? if ($this->import->options['product_sold_individually'] == 'xpath' and "" != $this->import->options['single_product_sold_individually']){ $this->data['product_sold_individually'] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_product_sold_individually'], $file)->parse($records); $tmp_files[] = $file; } else{ $this->count and $this->data['product_sold_individually'] = array_fill(0, $this->count, $this->import->options['product_sold_individually']); } // Composing product Stock status if ($this->import->options['product_stock_status'] == 'xpath' and "" != $this->import->options['single_product_stock_status']) { $this->data['product_stock_status'] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_product_stock_status'], $file)->parse($records); $tmp_files[] = $file; } elseif($this->import->options['product_stock_status'] == 'auto') { $this->count and $this->data['product_stock_status'] = array_fill(0, $this->count, $this->import->options['product_stock_status']); $nostock = absint( max( get_option( 'woocommerce_notify_no_stock_amount' ), 0 ) ); foreach ($this->data['product_stock_qty'] as $key => $value) { if ($this->data['product_manage_stock'][$key] == 'yes') { $this->data['product_stock_status'][$key] = (( (int) $value === 0 or (int) $value <= $nostock ) and $value != "") ? 'outofstock' : 'instock'; } else{ $this->data['product_stock_status'][$key] = 'instock'; } } } else { $this->count and $this->data['product_stock_status'] = array_fill(0, $this->count, $this->import->options['product_stock_status']); } // Composing grouping product if ($this->import->options['is_multiple_grouping_product'] != 'yes') { if ($this->import->options['grouping_indicator'] == 'xpath') { if ("" != $this->import->options['single_grouping_product']) { $this->data['product_grouping_parent'] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_grouping_product'], $file)->parse($records); $tmp_files[] = $file; } else { $this->count and $this->data['product_grouping_parent'] = array_fill(0, $this->count, $this->import->options['multiple_grouping_product']); } } else { if ("" != $this->import->options['custom_grouping_indicator_name'] and "" != $this->import->options['custom_grouping_indicator_value'] ) { $this->data['custom_grouping_indicator_name'] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['custom_grouping_indicator_name'], $file)->parse($records); $tmp_files[] = $file; $this->data['custom_grouping_indicator_value'] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['custom_grouping_indicator_value'], $file)->parse($records); $tmp_files[] = $file; } else { $this->count and $this->data['custom_grouping_indicator_name'] = array_fill(0, $this->count, ""); $this->count and $this->data['custom_grouping_indicator_value'] = array_fill(0, $this->count, ""); } } } else{ $this->count and $this->data['product_grouping_parent'] = array_fill(0, $this->count, $this->import->options['multiple_grouping_product']); } // Composing product is Manage stock if ($this->import->options['is_variation_product_manage_stock'] == 'xpath' and "" != $this->import->options['single_variation_product_manage_stock']){ $this->data['v_product_manage_stock'] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_variation_product_manage_stock'], $file)->parse($records); $tmp_files[] = $file; } else{ $this->count and $this->data['v_product_manage_stock'] = array_fill(0, $this->count, $this->import->options['is_variation_product_manage_stock']); } // Composing Stock Qty if ($this->import->options['variation_stock'] != "") { $this->data['v_stock'] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['variation_stock'], $file)->parse($records); $tmp_files[] = $file; } else { $this->count and $this->data['v_stock'] = array_fill(0, $this->count, ''); } // Composing Stock Status if ($this->import->options['variation_stock_status'] == 'xpath' and "" != $this->import->options['single_variation_stock_status']) { $this->data['v_stock_status'] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['single_variation_stock_status'], $file)->parse($records); $tmp_files[] = $file; } elseif($this->import->options['variation_stock_status'] == 'auto') { $this->count and $this->data['v_stock_status'] = array_fill(0, $this->count, $this->import->options['variation_stock_status']); $nostock = absint( max( get_option( 'woocommerce_notify_no_stock_amount' ), 0 ) ); foreach ($this->data['v_stock'] as $key => $value) { if ($this->data['v_product_manage_stock'][$key] == 'yes') { $this->data['v_stock_status'][$key] = ( ( (int) $value === 0 or (int) $value <= $nostock ) and $value != "") ? 'outofstock' : 'instock'; } else { $this->data['v_stock_status'][$key] = 'instock'; } } } else{ $this->count and $this->data['v_stock_status'] = array_fill(0, $this->count, $this->import->options['variation_stock_status']); } if ($this->import->options['matching_parent'] != "auto") { switch ($this->import->options['matching_parent']) { case 'first_is_parent_id': $this->data['single_product_parent_ID'] = $this->data['single_product_ID'] = $this->data['single_product_id_first_is_parent_ID']; break; case 'first_is_parent_title': $this->data['single_product_parent_ID'] = $this->data['single_product_ID'] = $this->data['single_product_id_first_is_parent_title']; break; case 'first_is_variation': $this->data['single_product_parent_ID'] = $this->data['single_product_ID'] = $this->data['single_product_id_first_is_variation']; break; } } // Composing variations attributes $this->chunk == 1 and $this->logger and call_user_func($this->logger, __('Composing variations attributes...', 'wpai_woocommerce_addon_plugin')); $attribute_keys = array(); $attribute_values = array(); $attribute_options = array( 'in_variations' => array(), 'is_visible' => array(), 'is_taxonomy' => array(), 'is_create_terms' => array() ); if ( ! empty($this->import->options['attribute_name'][0])) { foreach ($this->import->options['attribute_name'] as $j => $attribute_name) { if ($attribute_name == "") continue; $attribute_keys[$j] = XmlImportParser::factory($this->xml, $cxpath, $attribute_name, $file)->parse($records); $tmp_files[] = $file; $attribute_values[$j] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['attribute_value'][$j], $file)->parse($records); $tmp_files[] = $file; if (empty($this->import->options['is_advanced'][$j])) { $attribute_options['in_variations'][$j] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['in_variations'][$j], $file)->parse($records); $tmp_files[] = $file; $attribute_options['is_visible'][$j] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['is_visible'][$j], $file)->parse($records); $tmp_files[] = $file; $attribute_options['is_taxonomy'][$j] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['is_taxonomy'][$j], $file)->parse($records); $tmp_files[] = $file; $attribute_options['is_create_terms'][$j] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['create_taxonomy_in_not_exists'][$j], $file)->parse($records); $tmp_files[] = $file; } else { $options = array('in_variations', 'is_visible', 'is_taxonomy', 'is_create_terms'); foreach ($options as $option) { if ($this->import->options['advanced_' . $option][$j] == 'xpath' and "" != $this->import->options['advanced_'. $option .'_xpath'][$j]) { $attribute_options[$option][$j] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['advanced_'. $option .'_xpath'][$j], $file)->parse($records); $tmp_files[] = $file; } else { $attribute_options[$option][$j] = XmlImportParser::factory($this->xml, $cxpath, $this->import->options['advanced_'. $option][$j], $file)->parse($records); $tmp_files[] = $file; } foreach ($attribute_options[$option][$j] as $key => $value) { if ( ! in_array($value, array('yes', 'no'))) { $attribute_options[$option][$j][$key] = 1; } else { $attribute_options[$option][$j][$key] = ($value == 'yes') ? 1 : 0; } } } } } } // serialized attributes for product variations $this->data['serialized_attributes'] = array(); if ( ! empty($attribute_keys) ) { foreach ($attribute_keys as $j => $attribute_name) { $this->data['serialized_attributes'][] = array( 'names' => $attribute_name, 'value' => $attribute_values[$j], 'is_visible' => $attribute_options['is_visible'][$j], 'in_variation' => $attribute_options['in_variations'][$j], 'in_taxonomy' => $attribute_options['is_taxonomy'][$j], 'is_create_taxonomy_terms' => $attribute_options['is_create_terms'][$j] ); } } foreach ($tmp_files as $file) { // remove all temporary files created unlink($file); } return $this->data; } public function is_update_data_allowed($option = '') { if ($this->import->options['is_keep_former_posts'] == 'yes') return false; if ($this->import->options['update_all_data'] == 'yes') return true; return (!empty($this->import->options[$option])) ? true : false; } public function import( $importData ) { extract($importData); $cxpath = $xpath_prefix . $this->import->xpath; global $woocommerce; extract($this->data); $is_new_product = empty($articleData['ID']); $product_type = empty( $product_types[$i] ) ? 'simple' : sanitize_title( stripslashes( $product_types[$i] ) ); $product = WC()->product_factory->get_product($pid); if ($this->import->options['update_all_data'] == 'no' and ! $this->import->options['is_update_product_type'] and ! $is_new_product ){ if ( ! empty($product->product_type) ) $product_type = $product->product_type; } $this->articleData = $articleData; $total_sales = get_post_meta($pid, 'total_sales', true); if ( empty($total_sales)) update_post_meta($pid, 'total_sales', '0'); $is_downloadable = $product_downloadable[$i]; $is_virtual = $product_virtual[$i]; $is_featured = $product_featured[$i]; // Product type + Downloadable/Virtual if ($is_new_product or $this->import->options['update_all_data'] == 'yes' or ($this->import->options['update_all_data'] == 'no' and $this->import->options['is_update_product_type'])) { $product_type_term = is_exists_term($product_type, 'product_type', 0); if ( ! empty($product_type_term) and ! is_wp_error($product_type_term) ){ $this->associate_terms( $pid, array( (int) $product_type_term['term_taxonomy_id'] ), 'product_type' ); } } if ( ! $is_new_product ) { delete_post_meta($pid, '_is_first_variation_created'); } $this->pushmeta($pid, '_downloadable', ($is_downloadable == "yes") ? 'yes' : 'no' ); $this->pushmeta($pid, '_virtual', ($is_virtual == "yes") ? 'yes' : 'no' ); // Update post meta $this->pushmeta($pid, '_regular_price', ($product_regular_price[$i] == "") ? '' : stripslashes( $product_regular_price[$i] ) ); $this->pushmeta($pid, '_sale_price', ($product_sale_price[$i] == "") ? '' : stripslashes( $product_sale_price[$i] ) ); $this->pushmeta($pid, '_tax_status', stripslashes( $product_tax_status[$i] ) ); $this->pushmeta($pid, '_tax_class', strtolower($product_tax_class[$i]) == 'standard' ? '' : stripslashes( $product_tax_class[$i] ) ); $this->pushmeta($pid, '_purchase_note', stripslashes( $product_purchase_note[$i] ) ); $this->pushmeta($pid, '_featured', ($is_featured == "yes") ? 'yes' : 'no' ); $this->pushmeta($pid, '_visibility', stripslashes( $product_visibility[$i] ) ); // Dimensions if ( $is_virtual == 'no' ) { $this->pushmeta($pid, '_weight', stripslashes( $product_weight[$i] ) ); $this->pushmeta($pid, '_length', stripslashes( $product_length[$i] ) ); $this->pushmeta($pid, '_width', stripslashes( $product_width[$i] ) ); $this->pushmeta($pid, '_height', stripslashes( $product_height[$i] ) ); } else { $this->pushmeta($pid, '_weight', '' ); $this->pushmeta($pid, '_length', '' ); $this->pushmeta($pid, '_width', '' ); $this->pushmeta($pid, '_height', '' ); } if ($is_new_product or $this->is_update_data_allowed('is_update_comment_status')) $this->wpdb->update( $this->wpdb->posts, array('comment_status' => ( in_array($product_enable_reviews[$i], array('yes', 'open')) ) ? 'open' : 'closed' ), array('ID' => $pid)); if ($is_new_product or $this->is_update_data_allowed('is_update_menu_order')) $this->wpdb->update( $this->wpdb->posts, array('menu_order' => ($product_menu_order[$i] != '') ? (int) $product_menu_order[$i] : 0 ), array('ID' => $pid)); // Save shipping class if ( pmwi_is_update_taxonomy($articleData, $this->import->options, 'product_shipping_class') ) { $p_shipping_class = ($product_type != 'external') ? $product_shipping_class[$i] : ''; if ( $p_shipping_class != '' ) { if ( (int) $product_shipping_class[$i] !== 0 ) { if ( (int) $product_shipping_class[$i] > 0){ $t_shipping_class = get_term_by('slug', $p_shipping_class, 'product_shipping_class'); // For compatibility with WPML plugin $t_shipping_class = apply_filters('wp_all_import_term_exists', $t_shipping_class, 'product_shipping_class', $p_shipping_class, null); if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) ) { $p_shipping_class = (int) $t_shipping_class->term_taxonomy_id; } else { $t_shipping_class = is_exists_term( (int) $p_shipping_class, 'product_shipping_class'); if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) ) { $p_shipping_class = (int) $t_shipping_class['term_taxonomy_id']; } else { $t_shipping_class = wp_insert_term( $p_shipping_class, // the term 'product_shipping_class' // the taxonomy ); if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) ) { $p_shipping_class = (int) $t_shipping_class['term_taxonomy_id']; } } } } else { $p_shipping_class = ''; } } else{ $t_shipping_class = is_exists_term($product_shipping_class[$i], 'product_shipping_class'); if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) ) { $p_shipping_class = (int) $t_shipping_class['term_taxonomy_id']; } else { $t_shipping_class = is_exists_term(htmlspecialchars(strtolower($product_shipping_class[$i])), 'product_shipping_class'); if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) ) { $p_shipping_class = (int) $t_shipping_class['term_taxonomy_id']; } else { $t_shipping_class = wp_insert_term( $product_shipping_class[$i], // the term 'product_shipping_class' // the taxonomy ); if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) ) { $p_shipping_class = (int) $t_shipping_class['term_taxonomy_id']; } } } } } if ( $p_shipping_class !== false and ! is_wp_error($p_shipping_class)) $this->associate_terms( $pid, array( $p_shipping_class ), 'product_shipping_class' ); } // Unique SKU $sku = ($is_new_product) ? '' : get_post_meta($pid, '_sku', true); $new_sku = wc_clean( trim( stripslashes( $product_sku[$i] ) ) ); if ( ( in_array($product_type, array('variation', 'variable')) or $product_types[$i] == "variable" ) and ! $this->import->options['link_all_variations'] ){ switch ($this->import->options['matching_parent']){ case 'first_is_parent_id': if (!empty($single_product_first_is_parent_id_parent_sku[$i])){ update_post_meta($pid, '_parent_sku', $single_product_first_is_parent_id_parent_sku[$i]); } break; case 'first_is_variation': if (!empty($single_product_first_is_parent_title_parent_sku[$i])){ update_post_meta($pid, '_parent_sku', $single_product_first_is_parent_title_parent_sku[$i]); } break; } } if ( $new_sku == '' and $this->import->options['disable_auto_sku_generation'] ) { $this->pushmeta($pid, '_sku', '' ); } elseif ( $new_sku == '' and ! $this->import->options['disable_auto_sku_generation'] ) { if ($is_new_product or $this->is_update_cf('_sku')){ $unique_keys = XmlImportParser::factory($xml, $cxpath, $this->import->options['unique_key'], $file)->parse(); $tmp_files[] = $file; foreach ($tmp_files as $file) { // remove all temporary files created @unlink($file); } $new_sku = substr(md5($unique_keys[$i]), 0, 12); if ( ( in_array($product_type, array('variation', 'variable')) or $product_types[$i] == "variable" ) and ! $this->import->options['link_all_variations'] ){ switch ($this->import->options['matching_parent']){ case 'first_is_parent_id': if (empty($single_product_first_is_parent_id_parent_sku[$i])){ update_post_meta($pid, '_parent_sku', strrev($new_sku)); } break; case 'first_is_variation': if (empty($single_product_first_is_parent_title_parent_sku[$i])){ update_post_meta($pid, '_parent_sku', strrev($new_sku)); } break; } } } } if ( $new_sku != '' and $new_sku !== $sku ) { if ( ! empty( $new_sku ) ) { if ( ! $this->import->options['disable_sku_matching'] and $this->wpdb->get_var( $this->wpdb->prepare(" SELECT ".$this->wpdb->posts.".ID FROM ".$this->wpdb->posts." LEFT JOIN ".$this->wpdb->postmeta." ON (".$this->wpdb->posts.".ID = ".$this->wpdb->postmeta.".post_id) WHERE (".$this->wpdb->posts.".post_type = 'product' OR ".$this->wpdb->posts.".post_type = 'product_variation') AND ".$this->wpdb->posts.".post_status = 'publish' AND ".$this->wpdb->postmeta.".meta_key = '_sku' AND ".$this->wpdb->postmeta.".meta_value = '%s' ", $new_sku ) ) ) { $logger and call_user_func($logger, sprintf(__('<b>WARNING</b>: Product SKU must be unique.', 'wpai_woocommerce_addon_plugin'))); } else { $this->pushmeta($pid, '_sku', $new_sku ); } } else { $this->pushmeta($pid, '_sku', '' ); } } $this->pushmeta($pid, '_variation_description', wp_kses_post($product_variation_description[$i]) ); // Save Attributes $attributes = array(); $is_variation_attributes_defined = false; if ( $this->import->options['update_all_data'] == "yes" or ( $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes']) or $is_new_product){ // Update Product Attributes $is_update_attributes = true; if ( !empty($serialized_attributes) ) { $attribute_position = 0; foreach ($serialized_attributes as $anum => $attr_data) { $attr_name = $attr_data['names'][$i]; if (empty($attr_name)) continue; // $attr_names[] = $attr_name; $is_visible = intval( $attr_data['is_visible'][$i] ); $is_variation = intval( $attr_data['in_variation'][$i] ); $is_taxonomy = intval( $attr_data['in_taxonomy'][$i] ); if ( $is_variation and $attr_data['value'][$i] != "" ) { $is_variation_attributes_defined = true; } // Update only these Attributes, leave the rest alone if ( ! $is_new_product and $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'only'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])) { if ( ! in_array( ( ($is_taxonomy) ? wc_attribute_taxonomy_name( $attr_name ) : $attr_name ) , array_filter($this->import->options['attributes_list'], 'trim'))){ $attribute_position++; continue; } } else { $is_update_attributes = false; break; } } // Leave these attributes alone, update all other Attributes if ( ! $is_new_product and $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'all_except'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])) { if ( in_array( ( ($is_taxonomy) ? wc_attribute_taxonomy_name( $attr_name ) : $attr_name ) , array_filter($this->import->options['attributes_list'], 'trim'))){ $attribute_position++; continue; } } } if ( $is_taxonomy ) { if ( isset( $attr_data['value'][$i] ) ) { $values = array_map( 'stripslashes', array_map( 'strip_tags', explode( '|', $attr_data['value'][$i] ) ) ); // Remove empty items in the array $values = array_filter( $values, array($this, "filtering") ); if (intval($attr_data['is_create_taxonomy_terms'][$i])){ $attr_name = $this->create_taxonomy($attr_name, $logger); } if ( ! empty($values) and taxonomy_exists( wc_attribute_taxonomy_name( $attr_name ) )){ $attr_values = array(); foreach ($values as $key => $val) { $value = substr($val, 0, 199); $term = get_term_by('name', $value, wc_attribute_taxonomy_name( $attr_name ), ARRAY_A); // For compatibility with WPML plugin $term = apply_filters('wp_all_import_term_exists', $term, wc_attribute_taxonomy_name( $attr_name ), $value, null); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term($value, wc_attribute_taxonomy_name( $attr_name )); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term(htmlspecialchars($value), wc_attribute_taxonomy_name( $attr_name )); if ( empty($term) and !is_wp_error($term) and intval($attr_data['is_create_taxonomy_terms'][$i])){ $term = wp_insert_term( $value, // the term wc_attribute_taxonomy_name( $attr_name ) // the taxonomy ); } } } if ( ! is_wp_error($term) ) { $attr_values[] = (int) $term['term_taxonomy_id']; } } $values = $attr_values; $values = array_map( 'intval', $values ); $values = array_unique( $values ); } else $values = array(); } // Update post terms if ( taxonomy_exists( wc_attribute_taxonomy_name( $attr_name ) )) $this->associate_terms( $pid, $values, wc_attribute_taxonomy_name( $attr_name ) ); if ( !empty($values) ) { // Add attribute to array, but don't set values $attributes[ sanitize_title(wc_attribute_taxonomy_name( $attr_name )) ] = array( 'name' => wc_attribute_taxonomy_name( $attr_name ), 'value' => $attr_data['value'][$i], 'position' => $attribute_position, 'is_visible' => $is_visible, 'is_variation' => $is_variation, 'is_taxonomy' => 1, 'is_create_taxonomy_terms' => (!empty($attr_data['is_create_taxonomy_terms'][$i])) ? 1 : 0 ); } } else { if ( taxonomy_exists( wc_attribute_taxonomy_name( $attr_name ) )){ //wp_set_object_terms( $pid, NULL, wc_attribute_taxonomy_name( $attr_name ) ); $this->associate_terms( $pid, NULL, wc_attribute_taxonomy_name( $attr_name ) ); } if (trim($attr_data['value'][$i]) != ""){ // Custom attribute - Add attribute to array and set the values $attributes[ sanitize_title( $attr_name ) ] = array( 'name' => sanitize_text_field( $attr_name ), 'value' => trim($attr_data['value'][$i]), 'position' => $attribute_position, 'is_visible' => $is_visible, 'is_variation' => $is_variation, 'is_taxonomy' => 0 ); } } $attribute_position++; } } if ($is_new_product or $is_update_attributes) { $current_product_attributes = get_post_meta($pid, '_product_attributes', true); update_post_meta($pid, '_product_attributes', ( ! empty($current_product_attributes)) ? array_merge($current_product_attributes, $attributes) : $attributes ); } }else{ $is_variation_attributes_defined = true; } // is update attributes // Sales and prices if ( ! in_array( $product_type, array( 'grouped' ) ) ) { $date_from = isset( $product_sale_price_dates_from[$i] ) ? $product_sale_price_dates_from[$i] : ''; $date_to = isset( $product_sale_price_dates_to[$i] ) ? $product_sale_price_dates_to[$i] : ''; // Dates if ( $date_from ){ $this->pushmeta($pid, '_sale_price_dates_from', strtotime( $date_from )); } else{ $this->pushmeta($pid, '_sale_price_dates_from', ''); } if ( $date_to ){ $this->pushmeta($pid, '_sale_price_dates_to', strtotime( $date_to )); } else{ $this->pushmeta($pid, '_sale_price_dates_to', ''); } if ( $date_to && ! $date_from ){ $this->pushmeta($pid, '_sale_price_dates_from', strtotime( 'NOW', current_time( 'timestamp' ) ) ); } // Update price if on sale if ( ! empty($this->articleData['ID']) and ! $this->is_update_cf('_sale_price') ) { $product_sale_price[$i] = get_post_meta($pid, '_sale_price', true); } if ( $product_sale_price[$i] != '' && $date_to == '' && $date_from == '' ){ $this->pushmeta($pid, '_price', ($product_sale_price[$i] == "") ? '' : stripslashes( $product_sale_price[$i] )); } else{ $this->pushmeta($pid, '_price', ($product_regular_price[$i] == "") ? '' : stripslashes( $product_regular_price[$i] )); } if ( $product_sale_price[$i] != '' && $date_from && strtotime( $date_from ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ){ $this->pushmeta($pid, '_price', ($product_sale_price[$i] == "") ? '' : stripslashes( $product_sale_price[$i] )); } if ( $date_to && strtotime( $date_to ) < strtotime( 'NOW', current_time( 'timestamp' ) ) ) { $this->pushmeta($pid, '_price', ($product_regular_price[$i] == "") ? '' : stripslashes( $product_regular_price[$i] )); $this->pushmeta($pid, '_sale_price_dates_from', ''); $this->pushmeta($pid, '_sale_price_dates_to', ''); } } if (in_array( $product_type, array( 'simple', 'external' ) )) { if ($this->import->options['is_multiple_grouping_product'] != 'yes'){ if ($this->import->options['grouping_indicator'] == 'xpath' and ! is_numeric($product_grouping_parent[$i])){ $dpost = pmxi_findDuplicates(array( 'post_type' => 'product', 'ID' => $pid, 'post_parent' => $articleData['post_parent'], 'post_title' => $product_grouping_parent[$i] )); if (!empty($dpost)) $product_grouping_parent[$i] = $dpost[0]; else $product_grouping_parent[$i] = 0; } elseif ($this->import->options['grouping_indicator'] != 'xpath'){ $dpost = pmxi_findDuplicates($articleData, $custom_grouping_indicator_name[$i], $custom_grouping_indicator_value[$i], 'custom field'); if (!empty($dpost)) $product_grouping_parent[$i] = array_shift($dpost); else $product_grouping_parent[$i] = 0; } } if ( "" != $product_grouping_parent[$i] and absint($product_grouping_parent[$i]) > 0){ $this->wpdb->update( $this->wpdb->posts, array('post_parent' => absint( $product_grouping_parent[$i] ) ), array('ID' => $pid)); $all_grouped_products = get_post_meta($product_grouping_parent[$i], '_children', true); if (empty($all_grouped_products)) $all_grouped_products = array(); if ( ! in_array($pid, $all_grouped_products) ){ $all_grouped_products[] = $pid; update_post_meta($product_grouping_parent[$i], '_children', $all_grouped_products); } } } // Update parent if grouped so price sorting works and stays in sync with the cheapest child if ( $product_type == 'grouped' || ( "" != $product_grouping_parent[$i] and absint($product_grouping_parent[$i]) > 0)) { $clear_parent_ids = array(); if ( $product_type == 'grouped' ) $clear_parent_ids[] = $pid; if ( "" != $product_grouping_parent[$i] and absint($product_grouping_parent[$i]) > 0 ) $clear_parent_ids[] = absint( $product_grouping_parent[$i] ); if ( $clear_parent_ids ) { foreach( $clear_parent_ids as $clear_id ) { $children_by_price = get_posts( array( 'post_parent' => $clear_id, 'orderby' => 'meta_value_num', 'order' => 'asc', 'meta_key' => '_price', 'posts_per_page'=> 1, 'post_type' => 'product', 'fields' => 'ids' ) ); if ( $children_by_price ) { foreach ( $children_by_price as $child ) { $child_price = get_post_meta( $child, '_price', true ); update_post_meta( $clear_id, '_price', $child_price ); } } // Clear cache/transients //wc_delete_product_transients( $clear_id ); } } } // Sold Individuall if ( "yes" == $product_sold_individually[$i] ) { $this->pushmeta($pid, '_sold_individually', 'yes'); } else { $this->pushmeta($pid, '_sold_individually', ''); } // Stock Data if ( 'yes' === get_option( 'woocommerce_manage_stock' ) ) { $manage_stock = 'no'; $backorders = 'no'; $stock_status = wc_clean( $product_stock_status[$i] ); if ( 'external' === $product_type ) { $stock_status = 'instock'; } elseif ( 'variable' === $product_type and ! $this->import->options['link_all_variations'] ) { // Stock status is always determined by children so sync later // $stock_status = ''; if ( $product_manage_stock[$i] == 'yes' ) { $manage_stock = 'yes'; $backorders = wc_clean( $product_allow_backorders[$i] ); } } elseif ( 'grouped' !== $product_type && $product_manage_stock[$i] == 'yes' ) { $manage_stock = 'yes'; $backorders = wc_clean( $product_allow_backorders[$i] ); } $this->pushmeta($pid, '_manage_stock', $manage_stock); $this->pushmeta($pid, '_backorders', $backorders); if ( $stock_status ) { $this->pushmeta( $pid, '_stock_status', $stock_status ); } $current_manage_stock = get_post_meta( $pid, '_manage_stock', true ); if ( $product_manage_stock[$i] == 'yes' || ! $this->is_update_cf('_manage_stock') && $current_manage_stock == 'yes') { $this->pushmeta( $pid, '_stock', wc_stock_amount( $product_stock_qty[$i] ) ); } else { $this->pushmeta($pid, '_stock', ''); } } else { update_post_meta( $pid, '_stock_status', wc_clean( $product_stock_status[$i] ) ); } // Upsells $this->import_linked_products($pid, $product_up_sells[$i], '_upsell_ids', $is_new_product); // Cross sells $this->import_linked_products($pid, $product_cross_sells[$i], '_crosssell_ids', $is_new_product); // Downloadable options if ( $is_downloadable == 'yes' ) { $_download_limit = absint( $product_download_limit[$i] ); if ( ! $_download_limit ) $_download_limit = ''; // 0 or blank = unlimited $_download_expiry = absint( $product_download_expiry[$i] ); if ( ! $_download_expiry ) $_download_expiry = ''; // 0 or blank = unlimited // file paths will be stored in an array keyed off md5(file path) if ( !empty( $product_files[$i] ) ) { $_file_paths = array(); $file_paths = explode( $this->import->options['product_files_delim'] , $product_files[$i] ); $file_names = explode( $this->import->options['product_files_names_delim'] , $product_files_names[$i] ); foreach ( $file_paths as $fn => $file_path ) { $file_path = trim( $file_path ); $_file_paths[ md5( $file_path ) ] = array('name' => ((!empty($file_names[$fn])) ? $file_names[$fn] : basename($file_path)), 'file' => $file_path); } $this->pushmeta($pid, '_downloadable_files', $_file_paths); } if ( isset( $product_download_limit[$i] ) ) $this->pushmeta($pid, '_download_limit', esc_attr( $_download_limit )); if ( isset( $product_download_expiry[$i] ) ) $this->pushmeta($pid, '_download_expiry', esc_attr( $_download_expiry )); if ( isset( $product_download_type[$i] ) ) $this->pushmeta($pid, '_download_type', esc_attr( $product_download_type[$i] )); } // Product url if ( $product_type == 'external' ) { if ( isset( $product_url[$i] ) && $product_url[$i] ){ $this->auto_cloak_links($import, $product_url[$i]); $this->pushmeta($pid, '_product_url', esc_url_raw( $product_url[$i] )); } if ( isset( $product_button_text[$i] ) && $product_button_text[$i] ){ $this->pushmeta($pid, '_button_text', esc_attr( $product_button_text[$i] )); } } // Update product visibility term WC 3.0.0 if ( version_compare(WOOCOMMERCE_VERSION, '3.0') >= 0 ) { if ( pmwi_is_update_taxonomy($articleData, $this->import->options, 'product_visibility') ){ $associate_terms = array(); if ($is_featured == "yes"){ $featured_term = get_term_by( 'name', 'featured', 'product_visibility' ); if (!empty($featured_term) && !is_wp_error($featured_term)){ $associate_terms[] = $featured_term->term_taxonomy_id; } } if (in_array($product_visibility[$i], array('hidden', 'catalog'))){ $exclude_search_term = get_term_by( 'name', 'exclude-from-search', 'product_visibility' ); if (!empty($exclude_search_term) && !is_wp_error($exclude_search_term)){ $associate_terms[] = $exclude_search_term->term_taxonomy_id; } } if (in_array($product_visibility[$i], array('hidden', 'search'))){ $exclude_catalog_term = get_term_by( 'name', 'exclude-from-catalog', 'product_visibility' ); if (!empty($exclude_catalog_term) && !is_wp_error($exclude_catalog_term)){ $associate_terms[] = $exclude_catalog_term->term_taxonomy_id; } } $_stock_status = get_post_meta( $pid, '_stock_status', true); if ( $_stock_status == 'outofstock' ){ $outofstock_term = get_term_by( 'name', 'outofstock', 'product_visibility' ); if (!empty($outofstock_term) && !is_wp_error($outofstock_term)){ $associate_terms[] = $outofstock_term->term_taxonomy_id; } } $this->associate_terms( $pid, $associate_terms, 'product_visibility' ); } } // prepare bulk SQL query //$this->executeSQL(); wc_delete_product_transients($pid); // VARIATIONS if ( ( in_array($product_type, array('variation', 'variable')) or $product_types[$i] == "variable" ) and ! $this->import->options['link_all_variations'] and "xml" != $this->import->options['matching_parent'] ){ $set_defaults = false; $product_parent_post_id = false; //[search parent product] $first_is_parent = ( in_array($this->import->options['matching_parent'], array("auto", "first_is_parent_title")) ) ? "yes" : "no"; if ( "manual" != $this->import->options['duplicate_matching'] or $is_new_product ) { // find corresponding article among previously imported if ( ! empty($single_product_parent_ID[$i]) ){ $postRecord = $this->wpdb->get_row($this->wpdb->prepare("SELECT * FROM " . $this->wpdb->prefix . "pmxi_posts WHERE `import_id` = %d AND `product_key` = %s ORDER BY post_id ASC", $this->import->id, $single_product_parent_ID[$i])); $product_parent_post = ( ! empty($postRecord) ) ? get_post($product_parent_post_id = $postRecord->post_id) : false; } else{ $product_parent_post = false; } } else { if (empty($articleData['post_parent'])){ $product_parent_post_id = $pid; $args = array( 'post_type' => 'product_variation', 'meta_query' => array( array( 'key' => '_sku', 'value' => get_post_meta($pid, '_sku', true), ) ) ); $query = new WP_Query( $args ); if ( $query->have_posts() ){ $duplicate_id = $query->post->ID; if ($duplicate_id) { $pid = $duplicate_id; $this->duplicate_post_meta($pid, $product_parent_post_id); $tmp = get_post_meta( $product_parent_post_id, '_stock', true); $this->pushmeta($product_parent_post_id, '_stock_tmp', $tmp); if ( empty($this->import->options['set_parent_stock']) ) $this->pushmeta($product_parent_post_id, '_stock', ''); $tmp = get_post_meta( $product_parent_post_id, '_regular_price', true); $this->pushmeta($product_parent_post_id, '_regular_price_tmp', $tmp); $this->pushmeta($product_parent_post_id, '_regular_price', ''); $tmp = get_post_meta( $product_parent_post_id, '_price', true); $this->pushmeta($product_parent_post_id, '_price_tmp', $tmp); $this->pushmeta($product_parent_post_id, '_price', ''); } } wp_reset_postdata(); } else { if (!empty($articleData['post_parent'])) { $product_parent_post_id = $articleData['post_parent']; } elseif($articleData['post_type'] == 'product_variation') { $variation_post = get_post($pid); $product_parent_post_id = $variation_post->post_parent; } } $product_parent_post = $product_parent_post_id ? get_post($product_parent_post_id) : false; } //[\search parent product] if (in_array($product_type, array('variation', 'variable'))) { //$first_is_parent = ( in_array($this->import->options['matching_parent'], array("auto", "first_is_parent_title")) ) ? "yes" : "no"; if ( ! empty($product_parent_post_id) and ( (int)$product_parent_post_id != (int)$pid or (int)$product_parent_post_id == (int)$pid and $first_is_parent == "no" and ( ! $this->import->options['make_simple_product'] and ("manual" != $this->import->options['duplicate_matching'] or $is_new_product) ) )) { $create_new_variation = false; $product_ids = array(); if ($first_is_parent == "no") { $is_first_variation_created = get_post_meta($product_parent_post_id, '_is_first_variation_created', true); if ( ! $is_first_variation_created ) { $create_new_variation = true; update_post_meta($product_parent_post_id, '_is_first_variation_created', 1); $product_ids[] = ("manual" == $this->import->options['duplicate_matching'] and ! $is_new_product) ? $pid : $product_parent_post_id; } if ( ! in_array($pid, $product_ids)) $product_ids[] = $pid; } else { $product_ids[] = $pid; } foreach ($product_ids as $iter => $pid): $create_new_variation = ($create_new_variation && !$iter) ? true : false; $parent_sku = get_post_meta($product_parent_post_id, '_parent_sku', true); if (empty($parent_sku)) { $parent_sku = get_post_meta($product_parent_post_id, '_sku', TRUE); } if ( $create_new_variation) { $postRecord = new PMXI_Post_Record(); $postRecord->clear(); if ("manual" != $this->import->options['duplicate_matching'] or $is_new_product){ // find corresponding article among previously imported $postRecord->getBy(array( 'unique_key' => 'Variation ' . $parent_sku, 'import_id' => $this->import->id, )); $pid = ( ! $postRecord->isEmpty() ) ? $postRecord->post_id : false; } } $is_product_enabled = ($create_new_variation and $this->import->options['make_simple_product']) ? get_post_meta($product_parent_post_id, '_v_variation_enabled', true) : $product_enabled[$i]; $variable_enabled = ($is_product_enabled == "yes") ? 'yes' : 'no'; $attributes = array(); // Enabled or disabled $post_status = ( $variable_enabled == 'yes' ) ? 'publish' : 'private'; // Generate a useful post title $variation_post_title = sprintf( __( 'Variation #%s of %s', 'wpai_woocommerce_addon_plugin' ), absint( $pid ), $product_parent_post->post_title); // Update or Add post $variation = array( 'post_title' => $variation_post_title, 'post_content' => '', 'post_status' => $post_status, 'post_parent' => $product_parent_post_id, 'post_type' => 'product_variation' ); if ( $pid and ! $is_new_product and ! $this->is_update_data_allowed('is_update_status')) { $variation['post_status'] = get_post_status($pid); } if ( ! $pid ) { if ($this->import->options['create_new_records']){ $pid = wp_insert_post( $variation ); // update first variation title with generated ID $updated_variation_title = str_replace('#0', '#'.$pid, $variation_post_title); $this->wpdb->update( $this->wpdb->posts, array( 'post_title' => $updated_variation_title, 'post_name' => sanitize_title($updated_variation_title) ), array( 'ID' => $pid ) ); //$logger and call_user_func($logger, sprintf(__('<b>CREATED</b>: %s variation from parent product %s.', 'wpai_woocommerce_addon_plugin'), $variation_post_title, $articleData['post_title'])); if ($create_new_variation){ $this->duplicate_post_meta($pid, $product_parent_post_id); // associate variation with import $postRecord->isEmpty() and $postRecord->set(array( 'post_id' => $pid, 'import_id' => $this->import->id, 'unique_key' => 'Variation ' . $parent_sku, 'product_key' => '' ))->insert(); $postRecord->set(array('iteration' => $this->import->iteration))->update(); } } } else { if ($create_new_variation) { if ("manual" != $this->import->options['duplicate_matching'] or $is_new_product) { $this->duplicate_post_meta($pid, $product_parent_post_id); } if ( ! $postRecord->isEmpty()) $postRecord->set(array('iteration' => $this->import->iteration))->update(); if ("manual" == $this->import->options['duplicate_matching'] and ! $is_new_product) { $create_new_variation = false; } } wp_update_post( array_merge($variation, array('ID' => $pid)) ); //$logger and call_user_func($logger, sprintf(__('<b>UPDATED</b>: %s variation for parent product %s.', 'wpai_woocommerce_addon_plugin'), $variation_post_title, $articleData['post_title'])); } if ( ! $this->import->options['make_simple_product'] ) $create_new_variation = false; if ($pid){ if ( $this->import->options['create_draft'] == "yes" ) $this->wpdb->update( $this->wpdb->posts, array('post_status' => 'publish' ), array('ID' => $pid)); if ( $first_is_parent == "no" ){ // if ($this->is_update_data_allowed('is_update_status')) // { // $this->wpdb->update( $this->wpdb->posts, array('post_status' => get_post_status($product_parent_post_id) ), array('ID' => $pid)); // } $_v_product_manage_stock = $create_new_variation ? get_post_meta($product_parent_post_id, '_v_product_manage_stock', true) : $v_product_manage_stock[$i]; $_v_stock = $create_new_variation ? get_post_meta($product_parent_post_id, '_v_stock', true) : $v_stock[ $i ]; $_v_stock_status = $create_new_variation ? get_post_meta($product_parent_post_id, '_v_stock_status', true) : $v_stock_status[ $i ]; // Stock handling $this->pushmeta($pid, '_manage_stock', $_v_product_manage_stock); if ( 'yes' === $_v_product_manage_stock ) { $this->is_update_cf('_stock') and update_post_meta( $pid, '_stock', wc_stock_amount( $_v_stock ) ); } else { $this->is_update_cf('_backorders') and delete_post_meta( $pid, '_backorders' ); $this->is_update_cf('_stock') and delete_post_meta( $pid, '_stock' ); } if ( empty($this->import->options['set_parent_stock']) ) { $this->pmwi_buf_prices($product_parent_post_id); $this->is_update_cf('_stock') and delete_post_meta( $product_parent_post_id, '_stock' ); } // Only update stock status to user setting if changed by the user, but do so before looking at stock levels at variation level if ( ! empty( $_v_stock_status ) and $this->is_update_cf('_stock_status') ) { update_post_meta( $pid, '_stock_status', $_v_stock_status ); } if ( pmwi_is_update_taxonomy($articleData, $this->import->options, 'product_shipping_class') ){ if ($create_new_variation) { $v_shipping_class = get_post_meta($product_parent_post_id, '_v_shipping_class', true); $this->associate_terms( $pid, array( $v_shipping_class ), 'product_shipping_class' ); } else { $this->associate_terms( $pid, array( $p_shipping_class ), 'product_shipping_class' ); } } } else { $stock_status = wc_clean( $product_stock_status[$i] ); if ( $stock_status and $this->is_update_cf('_stock_status') ) { update_post_meta( $pid, '_stock_status', $stock_status ); } if (empty($articleData['ID']) or $this->is_update_cf('_tax_class')) { if ( $product_tax_class[ $i ] !== 'parent' ) $this->pushmeta($pid, '_tax_class', strtolower($product_tax_class[ $i ]) == 'standard' ? '' : sanitize_text_field( $product_tax_class[ $i ] )); else delete_post_meta( $pid, '_tax_class' ); } if ( $is_downloadable == 'yes' ) { $this->pushmeta($pid, '_download_limit', sanitize_text_field( $product_download_limit[ $i ] )); $this->pushmeta($pid, '_download_expiry', sanitize_text_field( $product_download_expiry[ $i ] )); $this->pushmeta($pid, '_download_type', sanitize_text_field( $product_download_type[ $i ] )); $_file_paths = array(); if ( !empty($product_files[$i]) ) { $file_paths = explode( $this->import->options['product_files_delim'] , $product_files[$i] ); $file_names = explode( $this->import->options['product_files_names_delim'] , $product_files_names[$i] ); foreach ( $file_paths as $fn => $file_path ) { $file_path = sanitize_text_field( $file_path ); $_file_paths[ md5( $file_path ) ] = array('name' => ((!empty($file_names[$fn])) ? $file_names[$fn] : basename($file_path)), 'file' => $file_path); } } $this->pushmeta($pid, '_downloadable_files', $_file_paths); } else { $this->pushmeta($pid, '_download_limit', ''); $this->pushmeta($pid, '_download_expiry', ''); $this->pushmeta($pid, '_download_type', ''); $this->pushmeta($pid, '_downloadable_files', ''); } } if ($this->import->options['update_all_data'] == 'yes' or $this->import->options['update_all_data'] == 'no' and $this->import->options['is_update_product_type']){ $this->associate_terms( $pid, NULL, 'product_type' ); } // Remove old taxonomies attributes so data is kept up to date if ( $pid and ($this->import->options['update_all_data'] == "yes" or ( $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes']))) { // Update all Attributes if ( $this->import->options['update_all_data'] == "yes" or $this->import->options['update_attributes_logic'] == 'full_update' ) $this->wpdb->query( $this->wpdb->prepare( "DELETE FROM {$this->wpdb->postmeta} WHERE meta_key LIKE 'attribute_%%' AND post_id = %d;", $pid ) ); wp_cache_delete( $pid, 'post_meta'); } // Update taxonomies if ( $this->import->options['update_all_data'] == "yes" or ( $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes']) or $is_new_product){ if ( $create_new_variation ) { $parent_attributes = get_post_meta($product_parent_post_id, '_first_variation_attributes', true); if ( ! empty($parent_attributes)) { foreach ($parent_attributes as $key => $attr_data) { $attr_name = $key; if ( intval($attr_data['is_taxonomy']) and ( strpos($attr_name, "pa_") === false or strpos($attr_name, "pa_") !== 0 ) ) $attr_name = "pa_" . $attr_name; // Update only these Attributes, leave the rest alone if ( ! $is_new_product and $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'only'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])){ if ( ! in_array( $attr_name , array_filter($this->import->options['attributes_list'], 'trim'))) continue; } else break; } // Leave these attributes alone, update all other Attributes if ( ! $is_new_product and $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'all_except'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])) { if ( in_array( $attr_name , array_filter($this->import->options['attributes_list'], 'trim'))) continue; } } $is_variation = intval( $attr_data['is_variation']); if (intval($attr_data['is_taxonomy'])) { $attr_name = wc_attribute_taxonomy_name($this->create_taxonomy(preg_replace("%^pa_%", "", $attr_name), $logger)); $cname = wc_attribute_taxonomy_name( preg_replace("%^pa_%", "", $attr_name) ); $this->associate_terms( $pid, NULL, $cname ); } if ( $is_variation) { // Don't use woocommerce_clean as it destroys sanitized characters $values = substr((intval($attr_data['is_taxonomy'])) ? $attr_data['value'] : $attr_data['value'], 0, 199); if (intval($attr_data['is_taxonomy'])){ $cname = wc_attribute_taxonomy_name( preg_replace("%^pa_%", "", $attr_name) ); $term = get_term_by('name', $values, $cname, ARRAY_A); // For compatibility with WPML plugin $term = apply_filters('wp_all_import_term_exists', $term, $cname, $values, null); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term($values, $cname); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term(htmlspecialchars($values), $cname); } } if ( ! empty($term) and ! is_wp_error($term) ){ $term = get_term_by('id', $term['term_id'], $cname); if ( ! empty($term) and ! is_wp_error($term) ) update_post_meta($pid, 'attribute_' . sanitize_title( $attr_name ), $term->slug); } else{ update_post_meta($pid, 'attribute_' . sanitize_title( $attr_name ), ''); } } else { $attr_value = trim($attr_data['value']); if ( $attr_value != "" ){ update_post_meta($pid, 'attribute_' . sanitize_title( $attr_name ), $attr_value); } else{ delete_post_meta($pid, 'attribute_' . sanitize_title( $attr_name )); } } } else { delete_post_meta($pid, 'attribute_' . sanitize_title( $attr_name )); } } } } else { // $attr_names = array(); foreach ($serialized_attributes as $anum => $attr_data) { $attr_name = $attr_data['names'][$i]; if (empty($attr_name)) continue; // $attr_names[] = $attr_name; // Update only these Attributes, leave the rest alone if ( ! $is_new_product and $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'only'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])){ if ( ! in_array( ( (intval($attr_data['in_taxonomy'][$i])) ? wc_attribute_taxonomy_name( $attr_name ) : $attr_name ) , array_filter($this->import->options['attributes_list'], 'trim'))) continue; } else break; } // Leave these attributes alone, update all other Attributes if ( ! $is_new_product and $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'all_except'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])) { if ( in_array( ( ($is_taxonomy) ? wc_attribute_taxonomy_name( $attr_name ) : $attr_name ) , array_filter($this->import->options['attributes_list'], 'trim'))) continue; } } if ( intval($attr_data['in_taxonomy'][$i]) and ( strpos($attr_name, "pa_") === false or strpos($attr_name, "pa_") !== 0 ) ) $attr_name = "pa_" . $attr_name; $is_variation = intval( $attr_data['in_variation'][$i]); if (intval($attr_data['in_taxonomy'][$i])) { $attr_name = wc_attribute_taxonomy_name($this->create_taxonomy(preg_replace("%^pa_%", "", $attr_name), $logger)); $cname = wc_attribute_taxonomy_name( preg_replace("%^pa_%", "", $attr_name) ); $this->associate_terms( $pid, NULL, $cname ); } if ($is_variation){ // Don't use woocommerce_clean as it destroys sanitized characters $values = substr((intval($attr_data['in_taxonomy'][$i])) ? $attr_data['value'][$i] : $attr_data['value'][$i], 0, 199); if (intval($attr_data['in_taxonomy'][$i])){ $cname = wc_attribute_taxonomy_name( preg_replace("%^pa_%", "", $attr_name) ); $term = get_term_by('name', $values, $cname, ARRAY_A); // For compatibility with WPML plugin $term = apply_filters('wp_all_import_term_exists', $term, $cname, $values, null); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term($values, $cname); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term(htmlspecialchars($values), $cname); } } if ( ! empty($term) and ! is_wp_error($term) ){ $term = get_term_by('id', $term['term_id'], $cname); if ( ! empty($term) and ! is_wp_error($term) ) update_post_meta($pid, 'attribute_' . sanitize_title( $attr_name ), $term->slug); } else{ //$this->pushmeta($pid, 'attribute_' . sanitize_title( $attr_name ), ''); update_post_meta($pid, 'attribute_' . sanitize_title( $attr_name ), ''); } } else { $attr_value = trim($values); if ( $attr_value != "" ){ update_post_meta($pid, 'attribute_' . sanitize_title( $attr_name ), $attr_value); } else{ delete_post_meta($pid, 'attribute_' . sanitize_title( $attr_name )); } } } else{ delete_post_meta($pid, 'attribute_' . sanitize_title( $attr_name )); } } } } } $this->pmwi_buf_prices($product_parent_post_id); if ($product_parent_post_id) wc_delete_product_transients($product_parent_post_id); if ($create_new_variation) do_action( 'pmxi_saved_post', $pid, null); do_action( 'pmxi_update_product_variation', $pid ); $create_new_variation = false; endforeach; } else { if ($first_is_parent == "no") { update_post_meta($product_parent_post_id, '_v_product_manage_stock', $v_product_manage_stock[$i]); update_post_meta($product_parent_post_id, '_v_stock', $v_stock[$i]); update_post_meta($product_parent_post_id, '_v_stock_status', $v_stock_status[$i]); update_post_meta($product_parent_post_id, '_v_variation_enabled', $product_enabled[$i]); if ( !empty($serialized_attributes) ) { $attributes = array(); $attribute_position = 0; foreach ($serialized_attributes as $anum => $attr_data) { $attr_name = $attr_data['names'][$i]; $is_visible = intval( $attr_data['is_visible'][$i] ); $is_variation = intval( $attr_data['in_variation'][$i] ); $is_taxonomy = intval( $attr_data['in_taxonomy'][$i] ); // Custom attribute - Add attribute to array and set the values $attributes[ sanitize_title( $attr_name ) ] = array( 'name' => sanitize_text_field( $attr_name ), 'value' => empty($attr_data['value'][$i]) ? '' : trim($attr_data['value'][$i]), 'position' => $attribute_position, 'is_visible' => $is_visible, 'is_variation' => $is_variation, 'is_taxonomy' => $is_taxonomy ); $attribute_position++; } update_post_meta($product_parent_post_id, '_first_variation_attributes', $attributes); } $this->pmwi_buf_prices($product_parent_post_id); if ( pmwi_is_update_taxonomy($articleData, $this->import->options, 'product_shipping_class') ){ update_post_meta($product_parent_post_id, '_v_shipping_class', $p_shipping_class); } } } } $previousID = get_option('wp_all_import_' . $this->import->id . '_parent_product'); // [execute only for parent products] if ( ! isset($product_types[$i + 1]) or isset($product_types[$i + 1]) and ! in_array($product_types[$i + 1], array('variation', 'variable')) or ( ! empty($previousID) and ( empty($product_parent_post_id) or $product_parent_post_id != $previousID or "yes" == $this->import->options['is_keep_former_posts'] ) ) ){ $parent_product_ids = empty($previousID) ? array() : array($previousID); if ( ! isset($product_types[$i + 1]) and ! empty($product_parent_post_id) and ! in_array($product_parent_post_id, $parent_product_ids)) { $parent_product_ids[] = $product_parent_post_id; } if ( ! isset($product_types[$i + 1]) and ! empty($pid) and ! in_array($pid, $parent_product_ids)) { $parent_product_ids[] = $pid; } foreach ($parent_product_ids as $post_parent) { $children = get_posts( array( 'post_parent' => $post_parent, 'posts_per_page'=> -1, 'post_type' => 'product_variation', 'fields' => 'ids', 'orderby' => 'ID', 'order' => 'ASC', 'post_status' => array('draft', 'publish', 'trash', 'pending', 'future', 'private') ) ); if ( count($children) ){ $parent_sku = get_post_meta($post_parent, '_parent_sku', true); if (!empty($parent_sku)){ $first_variation_sku = get_post_meta($post_parent, '_sku', true); $this->pushmeta($post_parent, '_sku', $parent_sku); $this->pushmeta($post_parent, '_first_variation_sku', $first_variation_sku); } $product_type_term = is_exists_term('variable', 'product_type', 0); if ( ! empty($product_type_term) and ! is_wp_error($product_type_term) ){ $this->associate_terms( $post_parent, array( (int) $product_type_term['term_taxonomy_id'] ), 'product_type' ); } $lowest_price = $lowest_regular_price = $lowest_sale_price = $highest_price = $highest_regular_price = $highest_sale_price = ''; $lowest_price_id = $lowest_regular_price_id = $lowest_sale_price_id = $highest_price_id = $highest_regular_price_id = $highest_sale_price_id = ''; $total_instock = 0; if ( $children ) { foreach ( $children as $n => $child ) { $_variation_stock = get_post_meta($child, '_stock_status', true); $total_instock += ($_variation_stock == 'instock') ? 1 : 0; $child_price = get_post_meta( $child, '_price', true ); $child_regular_price = get_post_meta( $child, '_regular_price', true ); $child_sale_price = get_post_meta( $child, '_sale_price', true ); // Regular prices if ( empty( $lowest_regular_price ) || (float) $child_regular_price < (float) $lowest_regular_price ){ $lowest_regular_price = $child_regular_price; $lowest_regular_price_id = $child; } if ( empty( $highest_regular_price ) || (float) $child_regular_price > (float) $highest_regular_price ){ $highest_regular_price = $child_regular_price; $highest_regular_price_id = $child; } // Sale prices if ( $child_price == $child_sale_price ) { if ( $child_sale_price !== '' && ( ! is_numeric( $lowest_sale_price ) || (float) $child_sale_price < (float) $lowest_sale_price ) ){ $lowest_sale_price = $child_sale_price; $lowest_sale_price_id = $child; } if ( $child_sale_price !== '' && ( ! is_numeric( $highest_sale_price ) || (float) $child_sale_price > (float) $highest_sale_price ) ){ $highest_sale_price = $child_sale_price; $highest_sale_price_id = $child; } } } $lowest_price = $lowest_sale_price === '' || (float) $lowest_regular_price < (float) $lowest_sale_price ? $lowest_regular_price : $lowest_sale_price; $highest_price = $highest_sale_price === '' || (float) $highest_regular_price > (float) $highest_sale_price ? $highest_regular_price : $highest_sale_price; $lowest_price_id = $lowest_sale_price === '' || (float) $lowest_regular_price < (float) $lowest_sale_price ? $lowest_regular_price_id : $lowest_sale_price_id; $highest_price_id = $highest_sale_price === '' || (float) $highest_regular_price > (float) $highest_sale_price ? $highest_regular_price_id : $highest_sale_price_id; } //$parent_manage_stock = get_post_meta($post_parent, '_manage_stock', true); $this->pushmeta($post_parent, '_stock_status', ($total_instock > 0) ? 'instock' : 'outofstock'); $this->pushmeta($post_parent, '_price', $lowest_price); update_post_meta($post_parent, '_min_variation_price', $lowest_price); update_post_meta($post_parent, '_max_variation_price', $highest_price); update_post_meta($post_parent, '_min_variation_regular_price', $lowest_regular_price); update_post_meta($post_parent, '_max_variation_regular_price', $highest_regular_price); update_post_meta($post_parent, '_min_variation_sale_price', $lowest_sale_price); update_post_meta($post_parent, '_max_variation_sale_price', $highest_sale_price); update_post_meta($post_parent, '_min_price_variation_id', $lowest_price_id); update_post_meta($post_parent, '_max_price_variation_id', $highest_price_id); update_post_meta($post_parent, '_min_regular_price_variation_id', $lowest_regular_price_id); update_post_meta($post_parent, '_max_regular_price_variation_id', $highest_regular_price_id); update_post_meta($post_parent, '_min_sale_price_variation_id', $lowest_sale_price_id); update_post_meta($post_parent, '_max_sale_price_variation_id', $highest_sale_price_id); // Update default attribute options setting if ( $this->import->options['update_all_data'] == "yes" or ( $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'] ) or $is_new_product ){ $default_attributes = array(); $parent_attributes = array(); $unique_attributes = array(); $attribute_position = 0; $is_update_attributes = true; foreach ( $children as $child ) { $child_attributes = (array) maybe_unserialize( get_post_meta( $child, '_product_attributes', true ) ); foreach ($child_attributes as $attr) { if ( empty($attr['name']) ) continue; if ( ! in_array($attr['name'], $unique_attributes)) { $attributes[] = $attr; $unique_attributes[] = $attr['name']; } } } foreach ( $attributes as $attribute ) { $default_attributes[ sanitize_title($attribute['name']) ] = ""; $values = array(); foreach ( $children as $child_number => $child ) { $value = array(); if ( $attribute['is_variation'] ) { $value = array_map( 'stripslashes', array_map( 'strip_tags', explode("|", trim( get_post_meta($child, 'attribute_'.sanitize_title($attribute['name']), true))))); } else { $child_attributes = (array) maybe_unserialize( get_post_meta( $child, '_product_attributes', true ) ); if ( ! empty($child_attributes[sanitize_title($attribute['name'])])) { $value = array_map( 'stripslashes', array_map( 'strip_tags', explode("|", trim( $child_attributes[sanitize_title($attribute['name'])]['value'] )))); } } if ( is_array($value) and isset($value[0]) ){ //$this->pushmeta($child, 'attribute_' . sanitize_title( $attribute['name'] ), $value[0]); $value = array_map('trim', $value); foreach ($value as $val) { if ( $attribute['is_taxonomy'] ){ $term = get_term_by('slug', $val, $attribute['name'], ARRAY_A); // For compatibility with WPML plugin $term = apply_filters('wp_all_import_term_exists', $term, $attribute['name'], $val, null); if ( ! empty($term) and ! is_wp_error($term) ) { $val = $term['name']; } } if ( trim($val) != "" and ! in_array($val, $values, true) ) $values[] = trim($val); } } if ( $attribute['is_variation'] ) { if ( isset($values[0]) and empty($default_attributes[ $attribute['name'] ])){ switch ($this->import->options['default_attributes_type']) { case 'instock': $is_instock = get_post_meta($child, '_stock_status', true); if ($is_instock == 'instock'){ $default_attributes[ sanitize_title($attribute['name']) ] = sanitize_title((is_array($value)) ? $value[0] : $value); } break; case 'first': if ($first_is_parent != "no" or $first_is_parent == "no" and ! $this->import->options['make_simple_product'] ) { $default_attributes[ sanitize_title($attribute['name']) ] = sanitize_title((is_array($values)) ? $values[0] : $values); } elseif ($first_is_parent == "no" and $child_number) { if (is_array($values) and isset($values[1])) { $default_attributes[ sanitize_title($attribute['name']) ] = sanitize_title($values[1]); } else { $default_attributes[ sanitize_title($attribute['name']) ] = sanitize_title((is_array($values)) ? $values[0] : $values); } } break; default: # code... break; } } } } // Update only these Attributes, leave the rest alone if ( ! $is_new_product and $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'only'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])){ if ( ! in_array( $attribute['name'] , array_filter($this->import->options['attributes_list'], 'trim'))){ $attribute_position++; continue; } } else { $is_update_attributes = false; break; } } // Leave these attributes alone, update all other Attributes if ( ! $is_new_product and $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'all_except'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])) { if ( in_array( $attribute['name'] , array_filter($this->import->options['attributes_list'], 'trim'))){ $attribute_position++; continue; } } } // $values = array_filter($values); if ( $attribute['is_taxonomy'] ){ if ( ! empty($values) ) { // Remove empty items in the array $values = array_filter( $values, array($this, "filtering") ); $attr_values = array(); foreach ($values as $key => $value) { $term = get_term_by('name', $value, $attribute['name'], ARRAY_A); // For compatibility with WPML plugin $term = apply_filters('wp_all_import_term_exists', $term, $attribute['name'], $value, null); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term($value, $attribute['name']); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term(htmlspecialchars($value), $attribute['name']); if ( empty($term) and !is_wp_error($term) and $attribute['is_create_taxonomy_terms']){ $term = wp_insert_term( $value, // the term $attribute['name'] // the taxonomy ); } } } if ( ! is_wp_error($term) ) $attr_values[] = (int) $term['term_taxonomy_id']; } $values = $attr_values; $values = array_map( 'intval', $values ); $values = array_unique( $values ); } else { $values = array(); } // Update post terms if ( $values and taxonomy_exists( $attribute['name'] ) ) $this->associate_terms( $post_parent, $values, $attribute['name'] ); //do_action('wpai_parent_set_object_terms', $post_parent, $attribute['name']); if ( $values ) { // Add attribute to array, but don't set values $parent_attributes[ sanitize_title( $attribute['name'] ) ] = array( 'name' => $attribute['name'], 'value' => '', 'position' => $attribute_position, 'is_visible' => $attribute['is_visible'], 'is_variation' => $attribute['is_variation'], 'is_taxonomy' => 1, 'is_create_taxonomy_terms' => $attribute['is_create_taxonomy_terms'], ); } } else { if (!empty($values)){ $parent_attributes[ sanitize_title( $attribute['name'] ) ] = array( 'name' => sanitize_text_field( $attribute['name'] ), 'value' => implode('|', $values), 'position' => $attribute_position, 'is_visible' => $attribute['is_visible'], 'is_variation' => $attribute['is_variation'], 'is_taxonomy' => 0 ); } } $attribute_position++; } if ($this->import->options['is_default_attributes'] and (empty($articleData['ID']) or $this->import->options['update_all_data'] == "yes" or $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes'])) $this->pushmeta($post_parent, '_default_attributes', $default_attributes); if ($is_new_product or $this->import->options['update_all_data'] == "yes" or $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes']){ $current_product_attributes = get_post_meta($post_parent, '_product_attributes', true); update_post_meta($post_parent, '_product_attributes', (( ! empty($current_product_attributes)) ? array_merge($current_product_attributes, $parent_attributes) : $parent_attributes)); } } if (count($children) == 1 and $this->import->options['make_simple_product'] and $first_is_parent == "no"){// and "manual" != $this->import->options['duplicate_matching'] $this->make_simple_product($post_parent); } if ( $this->import->options['make_simple_product']) { // and "manual" != $this->import->options['duplicate_matching'] $product_attributes = get_post_meta($post_parent, '_product_attributes', true); if ( empty($product_attributes) ){ $this->make_simple_product($post_parent); } } wc_delete_product_transients($post_parent); do_action('wp_all_import_variable_product_imported', $post_parent); } elseif ( $this->import->options['make_simple_product']) {// and "manual" != $this->import->options['duplicate_matching'] $table = $this->wpdb->posts; $p = $this->wpdb->get_row($this->wpdb->prepare("SELECT * FROM $table WHERE ID = %d;", $post_parent)); if ($p->post_type != 'product_variation'){ $parent_sku = get_post_meta($post_parent, '_parent_sku', true); if (!empty($parent_sku)){ $first_variation_sku = get_post_meta($post_parent, '_sku', true); $this->pushmeta($post_parent, '_sku', $parent_sku); $this->pushmeta($post_parent, '_first_variation_sku', $first_variation_sku); } $this->make_simple_product($post_parent); wc_delete_product_transients($post_parent); do_action('wp_all_import_variable_product_imported', $post_parent); } } } } // \[execute only for parent products] update_option('wp_all_import_' . $this->import->id . '_parent_product', $product_parent_post_id ? $product_parent_post_id : $pid); } elseif ( in_array( $product_type, array( 'variable' ) ) ){ // Link All Variations if ( "variable" == $product_type and $this->import->options['link_all_variations'] and ($this->import->options['update_all_data'] == "yes" or ($this->import->options['update_all_data'] == "no" and $this->import->options['is_update_attributes']) or $is_new_product)){ $added_variations = $this->pmwi_link_all_variations($pid, $this->import->options, $this->import->id, $this->import->iteration); $logger and call_user_func($logger, sprintf(__('<b>CREATED</b>: %s variations for parent product %s.', 'wpai_woocommerce_addon_plugin'), $added_variations, $articleData['post_title'])); } // Variable products have no prices $this->pmwi_buf_prices($pid); } if ( in_array( $product_type, array( 'grouped' ) ) ){ $this->pushmeta($pid, '_regular_price', ''); $this->pushmeta($pid, '_sale_price', ''); $this->pushmeta($pid, '_sale_price_dates_from', ''); $this->pushmeta($pid, '_sale_price_dates_to', ''); $this->pushmeta($pid, '_price', ''); } //$this->executeSQL(); // Find children elements by XPath and create variations if ( "variable" == $product_type and "xml" == $this->import->options['matching_parent'] and "" != $this->import->options['variations_xpath'] and ! $this->import->options['link_all_variations'] and ( "" != $this->import->options['variable_sku'] or empty($this->import->options['disable_auto_sku_generation']))) { $logger and call_user_func($logger, __('- Importing Variations', 'wpai_woocommerce_addon_plugin')); $variation_xpath = $cxpath . '[' . ( $i + 1 ) . ']/'. ltrim(trim(str_replace("[*]", "", $this->import->options['variations_xpath']),'{}'), '/'); $records = array(); $variations = XmlImportParser::factory($xml, $variation_xpath, '/', $file)->parse($records); $tmp_files[] = $file; $count_variations = count($variations); if ( $count_variations > 0 ){ // Variation SKUs if ($this->import->options['variable_sku'] != ""){ $variation_sku = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_sku'], $file)->parse($records); $tmp_files[] = $file; } else{ $count_variations and $variation_sku = array_fill(0, $count_variations, ''); } // Composing product is Manage stock if ($this->import->options['is_variable_product_manage_stock'] == 'xpath' and "" != $this->import->options['single_variable_product_manage_stock']){ if ($this->import->options['single_variable_product_manage_stock_use_parent']){ $parent_variable_product_manage_stock = XmlImportParser::factory($xml, $cxpath, $this->import->options['single_variable_product_manage_stock'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_product_manage_stock = array_fill(0, $count_variations, $parent_variable_product_manage_stock[$i]); } else { $variation_product_manage_stock = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['single_variable_product_manage_stock'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_product_manage_stock = array_fill(0, $count_variations, $this->import->options['is_variable_product_manage_stock']); } // Variation Description if ($this->import->options['variable_description'] != ""){ if ($this->import->options['variable_description_use_parent']){ $parent_variation_description = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_description'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_description = array_fill(0, $count_variations, $parent_variation_description[$i]); } else { $variation_description = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_description'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_description = array_fill(0, $count_variations, ''); } // Stock Qty if ($this->import->options['variable_stock'] != ""){ if ($this->import->options['variable_stock_use_parent']){ $parent_variation_stock = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_stock'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_stock = array_fill(0, $count_variations, $parent_variation_stock[$i]); } else { $variation_stock = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_stock'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_stock = array_fill(0, $count_variations, ''); } // Stock Status if ($this->import->options['variable_stock_status'] == 'xpath' and "" != $this->import->options['single_variable_stock_status']){ $variable_stock_status = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['single_variable_stock_status'], $file)->parse($records); $tmp_files[] = $file; } elseif($this->import->options['variable_stock_status'] == 'auto'){ $count_variations and $variable_stock_status = array_fill(0, $count_variations, $this->import->options['variable_stock_status']); foreach ($variation_stock as $key => $value) { $variable_stock_status[$key] = ( (int) $value <= 0) ? 'outofstock' : 'instock'; } } else{ $count_variations and $variable_stock_status = array_fill(0, $count_variations, $this->import->options['variable_stock_status']); } // Composing product Allow Backorders? if ($import->options['variable_allow_backorders'] == 'xpath' and "" != $import->options['single_variable_allow_backorders']){ $variable_allow_backorders = XmlImportParser::factory($xml, $variation_xpath, $import->options['single_variable_allow_backorders'], $file)->parse($records); $tmp_files[] = $file; } else{ $count_variations and $variable_allow_backorders = array_fill(0, $count_variations, $import->options['variable_allow_backorders']); } // Image $variation_image = array(); if ($this->import->options['variable_image']) { if ($this->import->options['variable_image_use_parent']){ $parent_image = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_image'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_image = array_fill(0, $count_variations, $parent_image[$i]); } else { $variation_image = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_image'], $file)->parse($records); $tmp_files[] = $file; } } else { $count_variations and $variation_image = array_fill(0, $count_variations, ''); } // Regular Price if (!empty($this->import->options['variable_regular_price'])){ if ($this->import->options['variable_regular_price_use_parent']){ $parent_regular_price = array_map(array($this, 'adjust_price'), array_map(array($this, 'prepare_price'), XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_regular_price'], $file)->parse($records)), array_fill(0, $count_variations, "variable_regular_price")); $tmp_files[] = $file; $count_variations and $variation_regular_price = array_fill(0, $count_variations, $parent_regular_price[$i]); } else { $variation_regular_price = array_map(array($this, 'prepare_price'), XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_regular_price'], $file)->parse($records)); $tmp_files[] = $file; } } else{ $count_variations and $variation_regular_price = array_fill(0, $count_variations, ''); } // Sale Price if (!empty($this->import->options['variable_sale_price'])){ if ($this->import->options['variable_sale_price_use_parent']){ $parent_sale_price = array_map(array($this, 'adjust_price'), array_map(array($this, 'prepare_price'), XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_sale_price'], $file)->parse($records)), array_fill(0, $count_variations, "variable_sale_price")); $tmp_files[] = $file; $count_variations and $variation_sale_price = array_fill(0, $count_variations, $parent_sale_price[$i]); } else { $variation_sale_price = array_map(array($this, 'prepare_price'), XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_sale_price'], $file)->parse($records)); $tmp_files[] = $file; } } else{ $count_variations and $variation_sale_price = array_fill(0, $count_variations, ''); } // Who Sale Price if (!empty($this->import->options['variable_whosale_price'])){ if ($this->import->options['variable_whosale_price_use_parent']){ $parent_whosale_price = array_map(array($this, 'prepare_price'), XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_whosale_price'], $file)->parse($records)); $tmp_files[] = $file; $count_variations and $variation_whosale_price = array_fill(0, $count_variations, $parent_whosale_price[$i]); } else { $variation_whosale_price = array_map(array($this, 'prepare_price'), XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_whosale_price'], $file)->parse($records)); $tmp_files[] = $file; } } else{ $count_variations and $variation_whosale_price = array_fill(0, $count_variations, ''); } if ( $this->import->options['is_variable_sale_price_shedule']){ // Sale price dates from if (!empty($this->import->options['variable_sale_price_dates_from'])){ if ($this->import->options['variable_sale_dates_use_parent']){ $parent_sale_date_start = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_sale_price_dates_from'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_sale_price_dates_from = array_fill(0, $count_variations, $parent_sale_date_start[$i]); } else { $variation_sale_price_dates_from = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_sale_price_dates_from'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_sale_price_dates_from = array_fill(0, $count_variations, ''); } // Sale price dates to if (!empty($this->import->options['variable_sale_price_dates_to'])){ if ($this->import->options['variable_sale_dates_use_parent']){ $parent_sale_date_end = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_sale_price_dates_to'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_sale_price_dates_to = array_fill(0, $count_variations, $parent_sale_date_end[$i]); } else { $variation_sale_price_dates_to = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_sale_price_dates_to'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_sale_price_dates_to = array_fill(0, $count_variations, ''); } } // Composing product is Virtual if ($this->import->options['is_variable_product_virtual'] == 'xpath' and "" != $this->import->options['single_variable_product_virtual']){ if ($this->import->options['single_variable_product_virtual_use_parent']){ $parent_variable_product_virtual = XmlImportParser::factory($xml, $cxpath, $this->import->options['single_variable_product_virtual'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_product_virtual = array_fill(0, $count_variations, $parent_variable_product_virtual[$i]); } else { $variation_product_virtual = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['single_variable_product_virtual'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_product_virtual = array_fill(0, $count_variations, $this->import->options['is_variable_product_virtual']); } // Composing product is Downloadable if ($this->import->options['is_variable_product_downloadable'] == 'xpath' and "" != $this->import->options['single_variable_product_downloadable']){ if ($this->import->options['single_variable_product_downloadable_use_parent']){ $parent_variable_product_downloadable = XmlImportParser::factory($xml, $cxpath, $this->import->options['single_variable_product_downloadable'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_product_downloadable = array_fill(0, $count_variations, $parent_variable_product_downloadable[$i]); } else { $variation_product_downloadable = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['single_variable_product_downloadable'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_product_downloadable = array_fill(0, $count_variations, $this->import->options['is_variable_product_downloadable']); } // Weigth if (!empty($this->import->options['variable_weight'])){ if ($this->import->options['variable_weight_use_parent']){ $parent_weight = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_weight'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_weight = array_fill(0, $count_variations, $parent_weight[$i]); } else { $variation_weight = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_weight'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_weight = array_fill(0, $count_variations, ''); } // Length if (!empty($this->import->options['variable_length'])){ if ($this->import->options['variable_dimensions_use_parent']){ $parent_length = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_length'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_length = array_fill(0, $count_variations, $parent_length[$i]); } else { $variation_length = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_length'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_length = array_fill(0, $count_variations, ''); } // Width if (!empty($this->import->options['variable_width'])){ if ($this->import->options['variable_dimensions_use_parent']){ $parent_width = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_width'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_width = array_fill(0, $count_variations, $parent_width[$i]); } else { $variation_width = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_width'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_width = array_fill(0, $count_variations, ''); } // Heigth if (!empty($this->import->options['variable_height'])){ if ($this->import->options['variable_dimensions_use_parent']){ $parent_heigth = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_height'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_height = array_fill(0, $count_variations, $parent_heigth[$i]); } else { $variation_height = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_height'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_height = array_fill(0, $count_variations, ''); } // Composing product Shipping Class if ($this->import->options['is_multiple_variable_product_shipping_class'] != 'yes' and "" != $this->import->options['single_variable_product_shipping_class']){ if ($this->import->options['single_variable_product_shipping_class_use_parent']){ $parent_shipping_class = XmlImportParser::factory($xml, $cxpath, $this->import->options['single_variable_product_shipping_class'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_product_shipping_class = array_fill(0, $count_variations, $parent_shipping_class[$i]); } else { $variation_product_shipping_class = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['single_variable_product_shipping_class'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_product_shipping_class = array_fill(0, $count_variations, $this->import->options['multiple_variable_product_shipping_class']); } // Composing product Tax Class if ($this->import->options['is_multiple_variable_product_tax_class'] != 'yes' and "" != $this->import->options['single_variable_product_tax_class']){ if ($this->import->options['single_variable_product_tax_class_use_parent']){ $parent_tax_class = XmlImportParser::factory($xml, $cxpath, $this->import->options['single_variable_product_tax_class'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_product_tax_class = array_fill(0, $count_variations, $parent_tax_class[$i]); } else { $variation_product_tax_class = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['single_variable_product_tax_class'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_product_tax_class = array_fill(0, $count_variations, $this->import->options['multiple_variable_product_tax_class']); } // Download limit if (!empty($this->import->options['variable_download_limit'])){ if ($this->import->options['variable_download_limit_use_parent']){ $parent_download_limit = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_download_limit'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_download_limit = array_fill(0, $count_variations, $parent_download_limit[$i]); } else { $variation_download_limit = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_download_limit'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_download_limit = array_fill(0, $count_variations, ''); } // Download expiry if (!empty($this->import->options['variable_download_expiry'])){ if ($this->import->options['variable_download_expiry_use_parent']){ $parent_download_expiry = XmlImportParser::factory($xml, $cxpath, $this->import->options['variable_download_expiry'], $file)->parse($records); $tmp_files[] = $file; $count_variations and $variation_download_expiry = array_fill(0, $count_variations, $parent_download_expiry[$i]); } else { $variation_download_expiry = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_download_expiry'], $file)->parse($records); $tmp_files[] = $file; } } else{ $count_variations and $variation_download_expiry = array_fill(0, $count_variations, ''); } // File paths if (!empty($this->import->options['variable_file_paths'])){ $variation_file_paths = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_file_paths'], $file)->parse($records); $tmp_files[] = $file; } else{ $count_variations and $variation_file_paths = array_fill(0, $count_variations, ''); } // File names if (!empty($this->import->options['variable_file_names'])){ $variation_file_names = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_file_names'], $file)->parse($records); $tmp_files[] = $file; } else{ $count_variations and $variation_file_names = array_fill(0, $count_variations, ''); } // Variation enabled if ($this->import->options['is_variable_product_enabled'] == 'xpath' and "" != $this->import->options['single_variable_product_enabled']){ $variation_product_enabled = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['single_variable_product_enabled'], $file)->parse($records); $tmp_files[] = $file; } else{ $count_variations and $variation_product_enabled = array_fill(0, $count_variations, $this->import->options['is_variable_product_enabled']); } $variation_attribute_keys = array(); $variation_attribute_values = array(); $variation_attribute_in_variation = array(); $variation_attribute_is_visible = array(); $variation_attribute_in_taxonomy = array(); $variable_create_terms_in_not_exists = array(); if (!empty($this->import->options['variable_attribute_name'][0])){ foreach ($this->import->options['variable_attribute_name'] as $j => $attribute_name) { if ($attribute_name == "") continue; $variation_attribute_keys[$j] = XmlImportParser::factory($xml, $variation_xpath, $attribute_name, $file)->parse($records); $tmp_files[] = $file; $variation_attribute_values[$j] = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_attribute_value'][$j], $file)->parse($records); $tmp_files[] = $file; $variation_attribute_in_variation[$j] = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_in_variations'][$j], $file)->parse($records); $tmp_files[] = $file; $variation_attribute_is_visible[$j] = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_is_visible'][$j], $file)->parse($records); $tmp_files[] = $file; $variation_attribute_in_taxonomy[$j] = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_is_taxonomy'][$j], $file)->parse($records); $tmp_files[] = $file; $variable_create_terms_in_not_exists[$j] = XmlImportParser::factory($xml, $variation_xpath, $this->import->options['variable_create_taxonomy_in_not_exists'][$j], $file)->parse($records); $tmp_files[] = $file; } } // serialized attributes for product variations $variation_serialized_attributes = array(); if (!empty($variation_attribute_keys)){ foreach ($variation_attribute_keys as $j => $attribute_name) { if (!in_array($attribute_name[0], array_keys($variation_serialized_attributes))){ $variation_serialized_attributes[$attribute_name[0]] = array( 'value' => $variation_attribute_values[$j], 'is_visible' => $variation_attribute_is_visible[$j], 'in_variation' => $variation_attribute_in_variation[$j], 'in_taxonomy' => $variation_attribute_in_taxonomy[$j], 'is_create_taxonomy_terms' => $variable_create_terms_in_not_exists[$j] ); } } } // Create Variations foreach ($variations as $j => $void) { $variation_sku_for_title = ("" == $variation_sku[$j]) ? $j : $variation_sku[$j]; if ($this->import->options['variable_sku_add_parent']){ $variation_sku[$j] = $product_sku[$i] . '-' . $variation_sku[$j]; $variation_sku_for_title = $product_sku[$i] . '-' . $variation_sku[$j]; } $is_variation_have_attributes = false; foreach ($variation_serialized_attributes as $attr => $attr_options){ if ($attr_options['in_variation'][$j] && $attr_options['value'][$j] != ''){ $is_variation_have_attributes = true; break; } } // do not create variation if it doesn't have attributes if ( ! $is_variation_have_attributes && $this->import->options['make_simple_product']) continue; $variable_enabled = ($variation_product_enabled[$j] == "yes") ? 'yes' : 'no'; // Enabled or disabled $post_status = ( $variable_enabled == 'yes' ) ? 'publish' : 'private'; $variation_to_update_id = false; $postRecord = new PMXI_Post_Record(); $postRecord->clear(); // Generate a useful post title $variation_post_title = sprintf( __( 'Variation #%s of %s', 'wpai_woocommerce_addon_plugin' ), $variation_sku_for_title, $articleData['post_title'] ); // handle duplicates according to import settings /*if ($duplicates = pmxi_findDuplicates(array('post_title' => $variation_post_title, 'post_type' => 'product_variation', 'post_parent' => $pid),'','','parent')) { $duplicate_id = array_shift($duplicates); if ($duplicate_id) { $variation_to_update = get_post($variation_to_update_id = $duplicate_id); } } */ // Update or Add post $variation = array( 'post_title' => $variation_post_title, 'post_content' => '', 'post_status' => $post_status, 'post_parent' => $pid, 'post_type' => 'product_variation' ); $variation_just_created = false; $postRecord->getBy(array( 'unique_key' => 'Variation ' . $variation_sku_for_title . ' of ' . $pid, 'import_id' => $this->import->id )); if ( ! $postRecord->isEmpty() ){ $variation_to_update_id = $postRecord->post_id; $postRecord->set(array('iteration' => $this->import->iteration))->update(); } if ( ! $variation_to_update_id ) { $variation_to_update_id = wp_insert_post( $variation ); // associate variation with import $postRecord->isEmpty() and $postRecord->set(array( 'post_id' => $variation_to_update_id, 'import_id' => $this->import->id, 'unique_key' => 'Variation ' . $variation_sku_for_title . ' of ' . $pid, 'product_key' => '' ))->insert(); $postRecord->set(array('iteration' => $this->import->iteration))->update(); $variation_just_created = true; $logger and call_user_func($logger, sprintf(__('- `%s`: variation created successfully', 'wpai_woocommerce_addon_plugin'), sprintf( __( 'Variation #%s of %s', 'wpai_woocommerce_addon_plugin' ), absint( $variation_to_update_id ), esc_html( get_the_title( $pid ) ) ))); } else { $this->wpdb->update( $this->wpdb->posts, $variation, array( 'ID' => $variation_to_update_id ) ); //do_action( 'woocommerce_update_product_variation', $variation_to_update_id ); $logger and call_user_func($logger, sprintf(__('- `%s`: variation updated successfully', 'wpai_woocommerce_addon_plugin'), $variation_post_title)); if ( $this->import->options['update_all_data'] == 'yes' or ( $this->import->options['update_all_data'] == 'no' and $this->import->options['is_update_attachments'])) { $logger and call_user_func($logger, sprintf(__('Deleting attachments for `%s`', 'wp_all_import_plugin'), $variation_post_title)); wp_delete_attachments($variation_to_update_id, true, 'files'); } // handle obsolete attachments (i.e. delete or keep) according to import settings if ( $this->import->options['update_all_data'] == 'yes' or ( $this->import->options['update_all_data'] == 'no' and $this->import->options['is_update_images'] and $this->import->options['update_images_logic'] == "full_update")){ $logger and call_user_func($logger, sprintf(__('Deleting images for `%s`', 'wp_all_import_plugin'), $variation_post_title)); wp_delete_attachments($variation_to_update_id, ! $this->import->options['do_not_remove_images'], 'images'); } } do_action( 'pmxi_update_product_variation', $variation_to_update_id ); $existing_variation_meta_keys = array(); foreach (get_post_meta($variation_to_update_id, '') as $cur_meta_key => $cur_meta_val) $existing_variation_meta_keys[] = $cur_meta_key; // delete keys which are no longer correspond to import settings if ( !empty($existing_variation_meta_keys) ){ foreach ($existing_variation_meta_keys as $cur_meta_key) { // Do not delete post meta for features image if ( in_array($cur_meta_key, array('_thumbnail_id','_product_image_gallery')) ) continue; // Update all data if ($this->import->options['update_all_data'] == 'yes' or $variation_just_created) { delete_post_meta($variation_to_update_id, $cur_meta_key); continue; } // Do not update attributes if ( ! $this->import->options['is_update_attributes'] and (in_array($cur_meta_key, array('_default_attributes', '_product_attributes')) or strpos($cur_meta_key, "attribute_") === 0)) continue; // Update only these Attributes, leave the rest alone if ($this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'only'){ if ($cur_meta_key == '_product_attributes'){ $current_product_attributes = get_post_meta($variation_to_update_id, '_product_attributes', true); if ( ! empty($current_product_attributes) and ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])) foreach ($current_product_attributes as $attr_name => $attr_value) { if ( in_array($attr_name, array_filter($this->import->options['attributes_list'], 'trim'))) unset($current_product_attributes[$attr_name]); } update_post_meta($variation_to_update_id, '_product_attributes', $current_product_attributes); continue; } if ( strpos($cur_meta_key, "attribute_") === 0 and ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list']) and ! in_array(str_replace("attribute_", "", $cur_meta_key), array_filter($this->import->options['attributes_list'], 'trim'))) continue; if (in_array($cur_meta_key, array('_default_attributes'))) continue; } // Leave these attributes alone, update all other Attributes if ($this->import->options['is_update_attributes'] and $this->import->options['update_attributes_logic'] == 'all_except'){ if ($cur_meta_key == '_product_attributes'){ if (empty($this->import->options['attributes_list'])) { delete_post_meta($variation_to_update_id, $cur_meta_key); continue; } $current_product_attributes = get_post_meta($variation_to_update_id, '_product_attributes', true); if ( ! empty($current_product_attributes) and ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])) foreach ($current_product_attributes as $attr_name => $attr_value) { if ( ! in_array($attr_name, array_filter($this->import->options['attributes_list'], 'trim'))) unset($current_product_attributes[$attr_name]); } update_post_meta($variation_to_update_id, '_product_attributes', $current_product_attributes); continue; } if ( strpos($cur_meta_key, "attribute_") === 0 and ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list']) and in_array(str_replace("attribute_", "", $cur_meta_key), array_filter($this->import->options['attributes_list'], 'trim'))) continue; if (in_array($cur_meta_key, array('_default_attributes'))) continue; } // Update all Custom Fields is defined if ($this->import->options['update_custom_fields_logic'] == "full_update"){ delete_post_meta($variation_to_update_id, $cur_meta_key); } // Update only these Custom Fields, leave the rest alone elseif ($this->import->options['update_custom_fields_logic'] == "only"){ if ( ! empty($this->import->options['custom_fields_list']) and is_array($this->import->options['custom_fields_list']) and in_array($cur_meta_key, $this->import->options['custom_fields_list'])) delete_post_meta($variation_to_update_id, $cur_meta_key); } // Leave these fields alone, update all other Custom Fields elseif ($this->import->options['update_custom_fields_logic'] == "all_except"){ if ( empty($this->import->options['custom_fields_list']) or ! in_array($cur_meta_key, $this->import->options['custom_fields_list'])) delete_post_meta($variation_to_update_id, $cur_meta_key); } } } // Add any default post meta //add_post_meta( $variation_to_update_id, 'total_sales', '0', true ); $v_total_sales = get_post_meta($variation_to_update_id, 'total_sales', true); if ( empty($v_total_sales)) update_post_meta($variation_to_update_id, 'total_sales', '0'); // Product type + Downloadable/Virtual wp_set_object_terms( $variation_to_update_id, NULL, 'product_type' ); update_post_meta( $variation_to_update_id, '_downloadable', ($variation_product_downloadable[$j] == "yes") ? 'yes' : 'no' ); update_post_meta( $variation_to_update_id, '_virtual', ($variation_product_virtual[$j] == "yes") ? 'yes' : 'no' ); // Update post meta if ($variation_just_created or $this->is_update_cf('_regular_price')) update_post_meta( $variation_to_update_id, '_regular_price', stripslashes( $variation_regular_price[$j] ) ); if ($variation_just_created or $this->is_update_cf('_sale_price')) update_post_meta( $variation_to_update_id, '_sale_price', stripslashes( $variation_sale_price[$j] ) ); if ( class_exists('woocommerce_wholesale_pricing') ) update_post_meta( $variation_to_update_id, 'pmxi_wholesale_price', stripslashes( $variation_whosale_price[$j] ) ); // Dimensions if ( $variation_product_virtual[$j] == 'no' ) { if ($variation_just_created or $this->is_update_cf('_weight')) update_post_meta( $variation_to_update_id, '_weight', stripslashes( $variation_weight[$j] ) ); if ($variation_just_created or $this->is_update_cf('_length')) update_post_meta( $variation_to_update_id, '_length', stripslashes( $variation_length[$j] ) ); if ($variation_just_created or $this->is_update_cf('_width')) update_post_meta( $variation_to_update_id, '_width', stripslashes( $variation_width[$j] ) ); if ($variation_just_created or $this->is_update_cf('_height')) update_post_meta( $variation_to_update_id, '_height', stripslashes( $variation_height[$j] ) ); } else { if ($variation_just_created or $this->is_update_cf('_weight')) update_post_meta( $variation_to_update_id, '_weight', '' ); if ($variation_just_created or $this->is_update_cf('_length')) update_post_meta( $variation_to_update_id, '_length', '' ); if ($variation_just_created or $this->is_update_cf('_width')) update_post_meta( $variation_to_update_id, '_width', '' ); if ($variation_just_created or $this->is_update_cf('_height')) update_post_meta( $variation_to_update_id, '_height', '' ); } // Save shipping class if (ctype_digit($variation_product_shipping_class[ $j ])){ $t_shipping_class = get_term_by('slug', $variation_product_shipping_class[ $j ], 'product_shipping_class'); // For compatibility with WPML plugin $t_shipping_class = apply_filters('wp_all_import_term_exists', $t_shipping_class, 'product_shipping_class', $variation_product_shipping_class[ $j ], null); if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) ) { $v_shipping_class = (int) $t_shipping_class->term_taxonomy_id; } else{ $t_shipping_class = is_exists_term( (int) $variation_product_shipping_class[ $j ], 'product_shipping_class', 0); if ( ! empty($t_shipping_class) and ! is_wp_error($t_shipping_class) ) { $v_shipping_class = (int) $t_shipping_class['term_taxonomy_id']; } } } else{ $vt_shipping_class = is_exists_term($variation_product_shipping_class[ $j ], 'product_shipping_class', 0); if ( empty($vt_shipping_class) and !is_wp_error($vt_shipping_class) ){ $vt_shipping_class = is_exists_term(htmlspecialchars($variation_product_shipping_class[ $j ]), 'product_shipping_class', 0); } if ( ! is_wp_error($vt_shipping_class) ) $v_shipping_class = (int) $vt_shipping_class['term_id']; } $this->associate_terms( $variation_to_update_id, array( $v_shipping_class ), 'product_shipping_class' ); // Unique SKU $sku = get_post_meta($variation_to_update_id, '_sku', true); $new_sku = esc_html( trim( stripslashes( $variation_sku[$j] ) ) ); if ( $new_sku == '' and $this->import->options['disable_auto_sku_generation'] ) { if ($variation_just_created or $this->is_update_cf('_sku')) update_post_meta( $variation_to_update_id, '_sku', '' ); } elseif ( $new_sku == '' and ! $this->import->options['disable_auto_sku_generation'] ) { if ($variation_just_created or $this->is_update_cf('_sku')){ $new_sku = substr(md5($variation_post_title), 0, 12); } } if ( $new_sku == '' ) { update_post_meta( $variation_to_update_id, '_sku', '' ); } elseif ( $new_sku !== $sku ) { if ( ! empty( $new_sku ) ) { if ( ! $this->import->options['disable_sku_matching'] and $this->wpdb->get_var( $this->wpdb->prepare(" SELECT ".$this->wpdb->posts.".ID FROM ".$this->wpdb->posts." LEFT JOIN ".$this->wpdb->postmeta." ON (".$this->wpdb->posts.".ID = ".$this->wpdb->postmeta.".post_id) WHERE ".$this->wpdb->posts.".post_type = 'product' AND ".$this->wpdb->posts.".post_status = 'publish' AND ".$this->wpdb->postmeta.".meta_key = '_sku' AND ".$this->wpdb->postmeta.".meta_value = '%s' ", $new_sku ) ) ) { $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Product SKU must be unique.', 'wpai_woocommerce_addon_plugin'))); } else { update_post_meta( $variation_to_update_id, '_sku', $new_sku ); } } else { update_post_meta( $variation_to_update_id, '_sku', '' ); } } $date_from = isset( $variation_sale_price_dates_from[$j] ) ? $variation_sale_price_dates_from[$j] : ''; $date_to = isset( $variation_sale_price_dates_to[$i] ) ? $variation_sale_price_dates_to[$i] : ''; // Variable Description $this->pushmeta($variation_to_update_id, '_variation_description', wp_kses_post( $variation_description[$j] )); // Dates if ( $date_from ) $this->pushmeta( $variation_to_update_id, '_sale_price_dates_from', strtotime( $date_from ) ); else $this->pushmeta( $variation_to_update_id, '_sale_price_dates_from', '' ); if ( $date_to ) $this->pushmeta( $variation_to_update_id, '_sale_price_dates_to', strtotime( $date_to ) ); else $this->pushmeta( $variation_to_update_id, '_sale_price_dates_to', '' ); if ( $date_to && ! $date_from ) $this->pushmeta( $variation_to_update_id, '_sale_price_dates_from', strtotime( 'NOW', current_time( 'timestamp' ) ) ); // Update price if on sale if ( $variation_sale_price[$j] == '' ) { if ( ! empty($this->articleData['ID']) and ! $this->is_update_cf('_sale_price') ) { $variation_sale_price[$j] = get_post_meta($variation_to_update_id, '_sale_price', true); } } if ( $variation_sale_price[$j] != '' && $date_to == '' && $date_from == '' ){ $this->pushmeta($variation_to_update_id, '_price', stripslashes( $variation_sale_price[$j] )); } else{ $this->pushmeta($variation_to_update_id, '_price', stripslashes( $variation_regular_price[$j] )); } // Stock Data if ( strtolower($variation_product_manage_stock[$j]) == 'yes' ) { // Manage stock if (empty($articleData['ID']) or $this->is_update_cf('_manage_stock')) { update_post_meta( $variation_to_update_id, '_manage_stock', 'yes' ); } if (empty($articleData['ID']) or $this->is_update_cf('_stock_status')) { update_post_meta( $variation_to_update_id, '_stock_status', stripslashes( $variable_stock_status[$j] ) ); } if (empty($articleData['ID']) or $this->is_update_cf('_stock')) { update_post_meta( $variation_to_update_id, '_stock', (int) $variation_stock[$j] ); } if (empty($articleData['ID']) or $this->is_update_cf('_backorders')) { $backorders = wc_clean( $variable_allow_backorders[$j] ); update_post_meta( $variation_to_update_id, '_backorders', $backorders ); } } else { if (empty($articleData['ID']) or $this->is_update_cf('_manage_stock')) { update_post_meta( $variation_to_update_id, '_manage_stock', 'no' ); } if (empty($articleData['ID']) or $this->is_update_cf('_stock_status')) { update_post_meta( $variation_to_update_id, '_stock_status', stripslashes( $variable_stock_status[$j] ) ); } delete_post_meta( $variation_to_update_id, '_backorders' ); delete_post_meta( $variation_to_update_id, '_stock' ); } if ( $variation_product_tax_class[ $j ] !== 'parent' ) update_post_meta( $variation_to_update_id, '_tax_class', strtolower($variation_product_tax_class[ $j ]) == 'standard' ? '' : sanitize_text_field( $variation_product_tax_class[ $j ] ) ); else delete_post_meta( $variation_to_update_id, '_tax_class' ); if ( $variation_product_downloadable[$j] == 'yes' ) { update_post_meta( $variation_to_update_id, '_download_limit', sanitize_text_field( $variation_download_limit[ $j ] ) ); update_post_meta( $variation_to_update_id, '_download_expiry', sanitize_text_field( $variation_download_expiry[ $j ] ) ); $_file_paths = array(); if ( !empty($variation_file_paths[$j]) ) { $file_paths = explode( $this->import->options['variable_product_files_delim'] , $variation_file_paths[$j] ); $file_names = explode( $this->import->options['variable_product_files_names_delim'] , $variation_file_names[$j] ); foreach ( $file_paths as $fn => $file_path ) { $file_path = sanitize_text_field( $file_path ); $_file_paths[ md5( $file_path ) ] = array('name' => ((!empty($file_names[$fn])) ? $file_names[$fn] : basename($file_path)), 'file' => $file_path); } } // grant permission to any newly added files on any existing orders for this product update_post_meta( $variation_to_update_id, '_downloadable_files', $_file_paths ); } else { update_post_meta( $variation_to_update_id, '_download_limit', '' ); update_post_meta( $variation_to_update_id, '_download_expiry', '' ); update_post_meta( $variation_to_update_id, '_downloadable_files', '' ); update_post_meta( $variation_to_update_id, '_download_type', '' ); } // Remove old taxonomies attributes so data is kept up to date if ( $variation_to_update_id and ( $this->import->options['update_all_data'] == 'yes' or ($this->import->options['update_all_data'] == 'no' and $this->import->options['is_update_attributes']) or $variation_just_created) ) { if ($this->import->options['update_all_data'] == 'yes' or $this->import->options['update_attributes_logic'] == 'full_update' ) $this->wpdb->query( $this->wpdb->prepare( "DELETE FROM {$this->wpdb->postmeta} WHERE meta_key LIKE 'attribute_%%' AND post_id = %d;", $variation_to_update_id ) ); wp_cache_delete( $variation_to_update_id, 'post_meta'); } // Update taxonomies if ( $this->import->options['update_all_data'] == 'yes' or ($this->import->options['update_all_data'] == 'no' and $this->import->options['is_update_attributes']) or $variation_just_created ){ foreach ($variation_serialized_attributes as $a_name => $attr_data) { $attr_name = $a_name; // Update only these Attributes, leave the rest alone if ($this->import->options['update_all_data'] == 'no' and $this->import->options['update_attributes_logic'] == 'only' and ! $variation_just_created ){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])){ if ( ! in_array( ( (intval($attr_data['in_taxonomy'][$j])) ? wc_attribute_taxonomy_name( $attr_name ) : $attr_name ) , array_filter($this->import->options['attributes_list'], 'trim'))) continue; } else break; } // Leave these attributes alone, update all other Attributes if ($this->import->options['update_all_data'] == 'no' and $this->import->options['update_attributes_logic'] == 'all_except' and ! $variation_just_created){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])) { if ( in_array( ( (intval($attr_data['in_taxonomy'][$j])) ? wc_attribute_taxonomy_name( $attr_name ) : $attr_name ) , array_filter($this->import->options['attributes_list'], 'trim'))) continue; } } if ( intval($attr_data['in_taxonomy'][$j]) and ( strpos($attr_name, "pa_") === false or strpos($attr_name, "pa_") !== 0 ) ) $attr_name = "pa_" . $attr_name; $is_variation = intval( $attr_data['in_variation'][$j]); // Don't use woocommerce_clean as it destroys sanitized characters $values = (intval($attr_data['in_taxonomy'][$j])) ? $attr_data['value'][$j] : $attr_data['value'][$j]; if (intval($attr_data['in_taxonomy'][$j])){ if (intval($attr_data['is_create_taxonomy_terms'][0])){ $a_name = $this->create_taxonomy($a_name, $logger); } $term = get_term_by('name', $values, wc_attribute_taxonomy_name( $a_name ), ARRAY_A); // For compatibility with WPML plugin $term = apply_filters('wp_all_import_term_exists', $term, wc_attribute_taxonomy_name( $a_name ), $values, null); if ( empty($term) and ! is_wp_error($term) ){ $term = is_exists_term($values, wc_attribute_taxonomy_name( $a_name )); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term(htmlspecialchars($values), wc_attribute_taxonomy_name( $a_name )); if ( empty($term) and !is_wp_error($term) and intval($attr_data['is_create_taxonomy_terms'][0])){ $term = wp_insert_term( $values, // the term wc_attribute_taxonomy_name( $a_name ) // the taxonomy ); } } } if ( ! is_wp_error($term) ) { $term = get_term_by( 'id', $term['term_id'], wc_attribute_taxonomy_name( $a_name )); update_post_meta( $variation_to_update_id, 'attribute_' . sanitize_title( $attr_name ), $term->slug ); } } else { update_post_meta( $variation_to_update_id, 'attribute_' . sanitize_title( $attr_name ), $values ); } } } if ( ! is_array($variation_image[$j]) ) $variation_image[$j] = array($variation_image[$j]); $uploads = wp_upload_dir(); if ( ! empty($uploads) and false === $uploads['error'] and !empty($variation_image[$j]) and (empty($articleData['ID']) or $this->import->options['update_all_data'] == "yes" or ( $this->import->options['update_all_data'] == "no" and $this->import->options['is_update_images']))) { require_once(ABSPATH . 'wp-admin/includes/image.php'); $targetDir = $uploads['path']; $targetUrl = $uploads['url']; $gallery_attachment_ids = array(); foreach ($variation_image[$j] as $featured_image) { $imgs = explode(',', $featured_image); if (!empty($imgs)) { foreach ($imgs as $img_url) { if (empty($img_url)) continue; $attid = false; $attch = null; $url = str_replace(" ", "%20", trim($img_url)); $bn = wp_all_import_sanitize_filename(basename($url)); $img_ext = pmxi_getExtensionFromStr($url); $default_extension = pmxi_getExtension($bn); if ($img_ext == "") $img_ext = pmxi_get_remote_image_ext($url); // generate local file name $image_name = apply_filters("wp_all_import_image_filename", urldecode(sanitize_file_name((($img_ext) ? str_replace("." . $default_extension, "", $bn) : $bn))) . (("" != $img_ext) ? '.' . $img_ext : '')); // if wizard store image data to custom field $create_image = false; $download_image = true; $image_filename = wp_unique_filename($uploads['path'], $image_name); $image_filepath = $uploads['path'] . DIRECTORY_SEPARATOR . $image_filename; // search existing attachment if ($this->import->options['search_existing_images'] or "gallery" == $this->import->options['download_images']){ $image_filename = $image_name; $attch = wp_all_import_get_image_from_gallery($image_name, $targetDir, "images"); if ("gallery" == $this->import->options['download_images']) $download_image = false; if (empty($attch)) { $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Image %s not found in media gallery.', 'wp_all_import_plugin'), trim($image_name))); } else { $logger and call_user_func($logger, sprintf(__('- Using existing image `%s` for post `%s` ...', 'wp_all_import_plugin'), trim($image_name), $variation_post_title)); $download_image = false; $create_image = false; $attid = $attch->ID; } } if ($download_image && "gallery" != $this->import->options['download_images']){ // do not download images if ( "no" == $this->import->options['download_images'] ){ $image_filename = $image_name; $image_filepath = $targetDir . DIRECTORY_SEPARATOR . $image_filename; $wpai_uploads = $uploads['basedir'] . DIRECTORY_SEPARATOR . PMXI_Plugin::FILES_DIRECTORY . DIRECTORY_SEPARATOR; $wpai_image_path = $wpai_uploads . str_replace('%20', ' ', $url); $logger and call_user_func($logger, sprintf(__('- Searching for existing image `%s` in `%s` folder', 'wp_all_import_plugin'), $wpai_image_path, $wpai_uploads)); if ( @file_exists($wpai_image_path) and @copy( $wpai_image_path, $image_filepath )){ $download_image = false; // valdate import attachments if( ! ($image_info = @getimagesize($image_filepath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'wp_all_import_plugin'), $image_filepath)); @unlink($image_filepath); } else { $create_image = true; $logger and call_user_func($logger, sprintf(__('- Image `%s` has been successfully found', 'wp_all_import_plugin'), $wpai_image_path)); } } } else { $logger and call_user_func($logger, sprintf(__('- Downloading image from `%s`', 'wp_all_import_plugin'), $url)); $request = get_file_curl($url, $image_filepath); if ( (is_wp_error($request) or $request === false) and ! @file_put_contents($image_filepath, @file_get_contents($url))) { @unlink($image_filepath); // delete file since failed upload may result in empty file created } else{ if( ($image_info = @getimagesize($image_filepath)) and in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { $create_image = true; $logger and call_user_func($logger, sprintf(__('- Image `%s` has been successfully downloaded', 'wp_all_import_plugin'), $url)); } } if ( ! $create_image ){ $url = str_replace(" ", "%20", trim(pmxi_convert_encoding($img_url))); $request = get_file_curl($url, $image_filepath); if ( (is_wp_error($request) or $request === false) and ! @file_put_contents($image_filepath, @file_get_contents($url))) { $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: File %s cannot be saved locally as %s', 'wp_all_import_plugin'), $url, $image_filepath)); @unlink($image_filepath); // delete file since failed upload may result in empty file created } else{ if( ! ($image_info = @getimagesize($image_filepath)) or ! in_array($image_info[2], array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG))) { $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: File %s is not a valid image and cannot be set as featured one', 'wp_all_import_plugin'), $url)); @unlink($image_filepath); } else { $create_image = true; $logger and call_user_func($logger, sprintf(__('- Image `%s` has been successfully downloaded', 'wp_all_import_plugin'), $url)); } } } } } $handle_image = false; if ($create_image){ $handle_image = array( 'file' => $image_filepath, 'url' => $targetUrl . '/' . $image_filename, 'type' => image_type_to_mime_type($image_info[2]) ); $logger and call_user_func($logger, sprintf(__('- Creating an attachment for image `%s`', 'wp_all_import_plugin'), $handle_image['url'])); $attachment_title = explode(".", $image_name); if (is_array($attachment_title) and count($attachment_title) > 1) array_pop($attachment_title); $attachment = array( 'post_mime_type' => $handle_image['type'], 'guid' => $handle_image['url'], 'post_title' => implode(".", $attachment_title), 'post_content' => '' ); if ($image_meta = wp_read_image_metadata($handle_image['file'])) { if (trim($image_meta['title']) && ! is_numeric(sanitize_title($image_meta['title']))) $attachment['post_title'] = $image_meta['title']; if (trim($image_meta['caption'])) $attachment['post_content'] = $image_meta['caption']; } $attid = wp_insert_attachment($attachment, $handle_image['file'], $variation_to_update_id); if (is_wp_error($attid)) { $logger and call_user_func($logger, __('- <b>WARNING</b>', 'wp_all_import_plugin') . ': ' . $attid->get_error_message()); } else { wp_update_attachment_metadata($attid, wp_generate_attachment_metadata($attid, $handle_image['file'])); } } if ($attid) { if ($attch != null and empty($attch->post_parent)){ wp_update_post( array( 'ID' => $attch->ID, 'post_parent' => $variation_to_update_id ) ); } do_action( 'pmxi_gallery_image', $variation_to_update_id, $attid, ($handle_image) ? $handle_image['file'] : $image_filepath); $success_images = true; $post_thumbnail_id = get_post_thumbnail_id( $variation_to_update_id ); if (empty($post_thumbnail_id) and $this->import->options['is_featured'] ) { set_post_thumbnail($variation_to_update_id, $attid); } elseif(!in_array($attid, $gallery_attachment_ids) and $post_thumbnail_id != $attid){ $gallery_attachment_ids[] = $attid; } if ($attch != null and empty($attch->post_parent)) { $logger and call_user_func($logger, sprintf(__('- Attachment has been successfully updated for image `%s`', 'wp_all_import_plugin'), ($handle_image) ? $handle_image['url'] : $targetUrl . '/' . $image_filename)); } elseif(empty($attch)) { $logger and call_user_func($logger, sprintf(__('- Attachment has been successfully created for image `%s`', 'wp_all_import_plugin'), ($handle_image) ? $handle_image['url'] : $targetUrl . '/' . $image_filename)); } } } } } } wc_delete_product_transients( $variation_to_update_id ); } foreach ($tmp_files as $file) { // remove all temporary files created if (file_exists($file)) @unlink($file); } // Update parent if variable so price sorting works and stays in sync with the cheapest child $children = get_posts( array( 'post_parent' => $pid, 'posts_per_page'=> -1, 'post_type' => 'product_variation', 'fields' => 'ids', 'post_status' => array('draft', 'publish', 'trash', 'pending', 'future', 'private') ) ); $lowest_price = $lowest_regular_price = $lowest_sale_price = $highest_price = $highest_regular_price = $highest_sale_price = ''; $total_instock = 0; if ( $children ) { foreach ( $children as $child ) { $_variation_stock = get_post_meta($child, '_stock_status', true); $total_instock += ($_variation_stock == 'instock') ? 1 : 0; $child_price = get_post_meta( $child, '_price', true ); $child_regular_price = get_post_meta( $child, '_regular_price', true ); $child_sale_price = get_post_meta( $child, '_sale_price', true ); // Regular prices if ( ! is_numeric( $lowest_regular_price ) || $child_regular_price < $lowest_regular_price ) $lowest_regular_price = $child_regular_price; if ( ! is_numeric( $highest_regular_price ) || $child_regular_price > $highest_regular_price ) $highest_regular_price = $child_regular_price; // Sale prices if ( $child_price == $child_sale_price ) { if ( $child_sale_price !== '' && ( ! is_numeric( $lowest_sale_price ) || $child_sale_price < $lowest_sale_price ) ) $lowest_sale_price = $child_sale_price; if ( $child_sale_price !== '' && ( ! is_numeric( $highest_sale_price ) || $child_sale_price > $highest_sale_price ) ) $highest_sale_price = $child_sale_price; } } $lowest_price = $lowest_sale_price === '' || $lowest_regular_price < $lowest_sale_price ? $lowest_regular_price : $lowest_sale_price; $highest_price = $highest_sale_price === '' || $highest_regular_price > $highest_sale_price ? $highest_regular_price : $highest_sale_price; $this->pushmeta($pid, '_stock_status', ($total_instock > 0) ? 'instock' : 'outofstock'); $this->pushmeta($pid, '_price', $lowest_price); update_post_meta( $pid, '_min_variation_price', $lowest_price ); update_post_meta( $pid, '_max_variation_price', $highest_price ); update_post_meta( $pid, '_min_variation_regular_price', $lowest_regular_price ); update_post_meta( $pid, '_max_variation_regular_price', $highest_regular_price ); update_post_meta( $pid, '_min_variation_sale_price', $lowest_sale_price ); update_post_meta( $pid, '_max_variation_sale_price', $highest_sale_price ); // Update default attribute options setting if ( $this->import->options['update_all_data'] == 'yes' or ($this->import->options['update_all_data'] == 'no' and $this->import->options['is_update_attributes']) or $variation_just_created ){ $default_attributes = array(); $parent_attributes = array(); $attribute_position = 0; $is_update_attributes = true; foreach ($variation_serialized_attributes as $a_name => $attr_data) { $attr_name = $a_name; $values = array(); // Update only these Attributes, leave the rest alone if ($this->import->options['update_all_data'] == 'no' and $this->import->options['update_attributes_logic'] == 'only'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])){ if ( ! in_array( (( intval($attr_data['in_taxonomy'][$j]) ) ? wc_attribute_taxonomy_name( $attr_name ) : $attr_name), array_filter($this->import->options['attributes_list'], 'trim'))){ $attribute_position++; continue; } } else { $is_update_attributes = false; break; } } // Leave these attributes alone, update all other Attributes if ($this->import->options['update_all_data'] == 'no' and $this->import->options['update_attributes_logic'] == 'all_except'){ if ( ! empty($this->import->options['attributes_list']) and is_array($this->import->options['attributes_list'])) { if ( in_array( (( intval($attr_data['in_taxonomy'][$j]) ) ? wc_attribute_taxonomy_name( $attr_name ) : $attr_name) , array_filter($this->import->options['attributes_list'], 'trim'))){ $attribute_position++; continue; } } } foreach ($variation_sku as $j => $void) { $is_variation = ( intval($attr_data['in_variation'][$j]) ) ? 1 : 0; $value = esc_attr(trim( $attr_data['value'][$j] )); if ( ! in_array($value, $values, true)) $values[] = $value; if ($is_variation){ if ( ! empty($value) and empty($default_attributes[ (( intval($attr_data['in_taxonomy'][$j])) ? wc_attribute_taxonomy_name( $attr_name ) : sanitize_title($attr_name)) ])){ switch ($this->import->options['default_attributes_type']) { case 'instock': if ($variable_stock_status[$j] == 'instock'){ $default_attributes[ (( intval($attr_data['in_taxonomy'][$j]) ) ? wc_attribute_taxonomy_name( $attr_name ) : sanitize_title($attr_name)) ] = sanitize_title($value); } break; case 'first': $default_attributes[ (( intval($attr_data['in_taxonomy'][$j]) ) ? wc_attribute_taxonomy_name( $attr_name ) : sanitize_title($attr_name)) ] = sanitize_title($value); break; default: # code... break; } } } } if ( intval($attr_data['in_taxonomy'][0]) ){ if (intval($attr_data['is_create_taxonomy_terms'][0])){ $attr_name = $this->create_taxonomy($attr_name, $logger); } if ( isset($values) and taxonomy_exists( wc_attribute_taxonomy_name( $attr_name ) ) ) { // Remove empty items in the array $values = array_filter( $values, array($this, "filtering") ); if ( ! empty($values) ){ $attr_values = array(); foreach ($values as $key => $value) { $term = get_term_by('name', $value, wc_attribute_taxonomy_name( $attr_name ), ARRAY_A); // For compatibility with WPML plugin $term = apply_filters('wp_all_import_term_exists', $term, wc_attribute_taxonomy_name( $attr_name ), $value, null); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term($value, wc_attribute_taxonomy_name( $attr_name )); if ( empty($term) and !is_wp_error($term) ){ $term = is_exists_term(htmlspecialchars($value), wc_attribute_taxonomy_name( $attr_name )); if ( empty($term) and !is_wp_error($term) and intval($attr_data['is_create_taxonomy_terms'][0])){ $term = wp_insert_term( $value, // the term wc_attribute_taxonomy_name( $attr_name ) // the taxonomy ); } } } if ( ! is_wp_error($term) ) { $attr_values[] = (int) $term['term_taxonomy_id']; } } $values = $attr_values; } } else { $values = array(); } // Update post terms if ( taxonomy_exists( wc_attribute_taxonomy_name( $attr_name ) )){ $this->associate_terms( $pid, $values, wc_attribute_taxonomy_name( $attr_name ) ); } if ( $values ) { // Add attribute to array, but don't set values $parent_attributes[ sanitize_title(wc_attribute_taxonomy_name( $attr_name )) ] = array( 'name' => wc_attribute_taxonomy_name( $attr_name ), 'value' => '', 'position' => $attribute_position, 'is_visible' => (!empty($attr_data['is_visible'][0])) ? 1 : 0, 'is_variation' => (!empty($attr_data['in_variation'][0])) ? 1 : 0, 'is_taxonomy' => 1, 'is_create_taxonomy_terms' => (!empty( $attr_data['is_create_taxonomy_terms'][0] )) ? 1 : 0 ); } } else{ if ( taxonomy_exists( wc_attribute_taxonomy_name( $attr_name ) )){ $this->associate_terms( $pid, NULL, wc_attribute_taxonomy_name( $attr_name ) ); } // Remove empty items in the array $values = array_filter( $values, array($this, "filtering") ); if ( $values ){ $parent_attributes[ sanitize_title( $attr_name ) ] = array( 'name' => sanitize_text_field( $attr_name ), 'value' => implode('|', $values), 'position' => $attribute_position, 'is_visible' => (!empty($attr_data['is_visible'][0])) ? 1 : 0, 'is_variation' => (!empty($attr_data['in_variation'][0])) ? 1 : 0, 'is_taxonomy' => 0 ); } } $attribute_position++; } if ($this->import->options['is_default_attributes'] and $is_update_attributes) { $current_default_attributes = get_post_meta($pid, '_default_attributes', true); update_post_meta( $pid, '_default_attributes', (( ! empty($current_default_attributes)) ? array_merge($current_default_attributes, $default_attributes) : $default_attributes) ); } if ($is_new_product or $is_update_attributes) { $current_product_attributes = get_post_meta($pid, '_product_attributes', true); update_post_meta( $pid, '_product_attributes', (( ! empty($current_product_attributes)) ? array_merge($current_product_attributes, $parent_attributes) : $parent_attributes) ); } } } elseif ( $this->import->options['make_simple_product']){ $this->make_simple_product($pid); } } elseif ( $this->import->options['make_simple_product']){ $this->make_simple_product($pid); } } } public function after_save_post( $importData ) { $table = $this->wpdb->posts; $p = $this->wpdb->get_row($this->wpdb->prepare("SELECT * FROM $table WHERE ID = %d;", $importData['pid'])); if ($p) { $post_to_update_id = false; if ($p->post_type == 'product_variation') { if ($this->import->options['create_draft'] == 'yes' and $p->post_status == 'draft') { $this->wpdb->update( $this->wpdb->posts, array('post_status' => 'publish' ), array('ID' => $importData['pid'])); } $this->wpdb->update( $this->wpdb->posts, array( 'post_excerpt' => '', 'post_name' => sanitize_title($p->post_title), 'guid' => '' ), array('ID' => $importData['pid'])); if ( ! empty($this->product_taxonomies) ): foreach ($this->product_taxonomies as $ctx): if ( strpos($ctx->name, "pa_") === 0 ) continue; $this->associate_terms($importData['pid'], NULL, $ctx->name); endforeach; endif; delete_post_meta($importData['pid'], '_v_product_manage_stock'); delete_post_meta($importData['pid'], '_v_stock'); delete_post_meta($importData['pid'], '_v_stock_status'); delete_post_meta($importData['pid'], '_v_variation_enabled'); delete_post_meta($importData['pid'], '_first_variation_attributes'); delete_post_meta($importData['pid'], '_v_shipping_class'); $post_to_update_id = $p->post_parent; } else { // unset attributes $product_attributes = get_post_meta( $importData['pid'], '_product_attributes', true ); if ( ! empty($this->product_taxonomies) ): foreach ($this->product_taxonomies as $ctx): if ( strpos($ctx->name, "pa_") === 0 && ! isset($product_attributes[strtolower(urlencode($ctx->name))]) ){ $this->associate_terms($importData['pid'], NULL, $ctx->name); } endforeach; endif; update_post_meta( $importData['pid'], '_product_version', WC_VERSION ); $post_to_update_id = $importData['pid']; // [associate linked products] $wp_all_import_not_linked_products = get_option('wp_all_import_not_linked_products_' . $this->import->id ); if ( ! empty($wp_all_import_not_linked_products) ) { $post_to_update_sku = get_post_meta($post_to_update_id, '_sku', true); foreach ($wp_all_import_not_linked_products as $product) { if ( $product['pid'] != $post_to_update_id && ! empty($product['not_linked_products']) ) { if ( in_array($post_to_update_sku, $product['not_linked_products']) or in_array( (string) $post_to_update_id, $product['not_linked_products']) or in_array($p->post_title, $product['not_linked_products']) or in_array($p->post_name, $product['not_linked_products']) ) { $linked_products = get_post_meta($product['pid'], $product['type'], true); if (empty($linked_products)) $linked_products = array(); if ( ! in_array($post_to_update_id, $linked_products)) { $linked_products[] = $post_to_update_id; $this->logger and call_user_func($this->logger, sprintf(__('Added to %s list of product ID %d.', 'wpai_woocommerce_addon_plugin'), $product['type'] == '_upsell_ids' ? 'Up-Sells' : 'Cross-Sells', $product['pid']) ); update_post_meta($product['pid'], $product['type'], $linked_products); } } } } } // [\associate linked products] } // update first variation if ($post_to_update_id){ $postRecord = new PMXI_Post_Record(); $postRecord->clear(); // find corresponding article among previously imported $postRecord->getBy(array( 'unique_key' => 'Variation ' . get_post_meta($post_to_update_id, '_sku', true), 'import_id' => $this->import->id, )); $pid = ( ! $postRecord->isEmpty() ) ? $postRecord->post_id : false; if ( $pid ) { // check is variation already processed $is_variation_updated = get_post_meta($pid, '_variation_updated', true); if ( empty($is_variation_updated) ){ // Get all existing meta keys of parent product $existing_meta_keys = array(); $table = _get_meta_table('post'); $post_meta_infos = $this->wpdb->get_results("SELECT meta_key, meta_value FROM $table WHERE post_id = " . $importData['pid'] ); if ( ! empty($post_meta_infos) and ! empty($this->import->options['custom_name']) ) { foreach ($post_meta_infos as $meta_info) { if ( in_array($meta_info->meta_key, $this->import->options['custom_name']) ) { $this->pushmeta($pid, $meta_info->meta_key, maybe_unserialize($meta_info->meta_value)); } } } // save thumbnail $post_thumbnail_id = get_post_thumbnail_id( $importData['pid'] ); if ($post_thumbnail_id) { set_post_thumbnail($pid, $post_thumbnail_id); } if ($this->import->options['put_variation_image_to_gallery'] and $post_thumbnail_id) { do_action('pmxi_gallery_image', $pid, $post_thumbnail_id, false); } if ($this->import->options['create_draft'] == 'yes') { $this->wpdb->update( $this->wpdb->posts, array('post_status' => 'publish' ), array('ID' => $pid)); } update_post_meta($pid, '_variation_updated', 1); wc_delete_product_transients($pid); } } } // [update product gallery] $tmp_gallery = explode(",", get_post_meta( $post_to_update_id, '_product_image_gallery_tmp', true)); $gallery = explode(",", get_post_meta( $post_to_update_id, '_product_image_gallery', true)); if (is_array($gallery)){ $gallery = array_filter($gallery); if ( ! empty($tmp_gallery)) { $gallery = array_unique(array_merge($gallery, $tmp_gallery)); } } elseif ( ! empty($tmp_gallery)) { $gallery = $tmp_gallery; } $this->pushmeta( $post_to_update_id, '_product_image_gallery', implode(",", $gallery) ); // [\update product gallery] wc_delete_product_transients($importData['pid']); } } protected function associate_terms($pid, $assign_taxes, $tx_name, $logger = false){ $terms = wp_get_object_terms( $pid, $tx_name ); $term_ids = array(); $assign_taxes = (is_array($assign_taxes)) ? array_filter($assign_taxes) : false; if ( ! empty($terms) ){ if ( ! is_wp_error( $terms ) ) { foreach ($terms as $term_info) { $term_ids[] = $term_info->term_taxonomy_id; $this->wpdb->query( $this->wpdb->prepare("UPDATE {$this->wpdb->term_taxonomy} SET count = count - 1 WHERE term_taxonomy_id = %d", $term_info->term_taxonomy_id) ); } $in_tt_ids = "'" . implode( "', '", $term_ids ) . "'"; $this->wpdb->query( $this->wpdb->prepare( "DELETE FROM {$this->wpdb->term_relationships} WHERE object_id = %d AND term_taxonomy_id IN ($in_tt_ids)", $pid ) ); } } if (empty($assign_taxes)) return; // foreach ($assign_taxes as $tt) { // $this->wpdb->insert( $this->wpdb->term_relationships, array( 'object_id' => $pid, 'term_taxonomy_id' => $tt ) ); // $this->wpdb->query( "UPDATE {$this->wpdb->term_taxonomy} SET count = count + 1 WHERE term_taxonomy_id = $tt" ); // } $values = array(); $term_order = 0; foreach ( $assign_taxes as $tt ) { do_action('wp_all_import_associate_term', $pid, $tt, $tx_name); $values[] = $this->wpdb->prepare( "(%d, %d, %d)", $pid, $tt, ++$term_order); $this->wpdb->query( "UPDATE {$this->wpdb->term_taxonomy} SET count = count + 1 WHERE term_taxonomy_id = $tt" ); } if ( $values ){ if ( false === $this->wpdb->query( "INSERT INTO {$this->wpdb->term_relationships} (object_id, term_taxonomy_id, term_order) VALUES " . join( ',', $values ) . " ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)" ) ){ $logger and call_user_func($logger, __('<b>ERROR</b> Could not insert term relationship into the database', 'wp_all_import_plugin') . ': '. $this->wpdb->last_error); } } wp_cache_delete( $pid, $tx_name . '_relationships' ); } protected function duplicate_post_meta( $new_id, $id ) { $table = _get_meta_table('post'); $post_meta_infos = $this->wpdb->get_results("SELECT meta_key, meta_value FROM $table WHERE post_id=$id"); if (count($post_meta_infos)!=0) { $sql_query_sel = array(); $sql_query = "INSERT INTO $table (post_id, meta_key, meta_value) "; foreach ($post_meta_infos as $meta_info) { if (strpos($meta_info->meta_key, '_min') === false and strpos($meta_info->meta_key, '_max') === false and ! in_array($meta_info->meta_key, array('_default_attributes', '_price', '_first_variation_sku', '_product_version'))) { $cf_value = apply_filters('pmxi_custom_field', maybe_unserialize($meta_info->meta_value), $new_id, $meta_info->meta_key, $post_meta_infos, $this->import->id); $this->pushmeta($new_id, $meta_info->meta_key, $cf_value); } } $_first_variation_sku = get_post_meta($id, '_first_variation_sku', true); if (!empty($_first_variation_sku)){ $this->pushmeta($new_id, '_sku', $_first_variation_sku); delete_post_meta($id, '_first_variation_sku'); } delete_post_meta($new_id, '_product_version'); delete_post_meta($new_id, '_variation_updated'); if (empty($this->articleData['ID']) or $this->is_update_cf('_price')) { $sale_price = get_post_meta($id, '_sale_price', true); $regular_price = get_post_meta($id, '_regular_price', true); if ($sale_price != '' && $regular_price != '') { $price = ($sale_price <= $regular_price) ? $sale_price : $regular_price; } elseif ($sale_price != '') { $price = $sale_price; } else { $price = $regular_price; } $this->pushmeta($new_id, '_price', $price); } } if ($this->import->options['put_variation_image_to_gallery']) { $post_thumbnail_id = get_post_thumbnail_id( $id ); do_action('pmxi_gallery_image', $new_id, $post_thumbnail_id, false); } } function pmwi_link_all_variations($product_id, $options = array(), $import_id, $iteration = 0) { global $woocommerce; @set_time_limit(0); $post_id = intval( $product_id ); if ( ! $post_id ) return 0; $variations = array(); $_product = WC()->product_factory->get_product($post_id); $v = $_product->get_attributes(); // Put variation attributes into an array wp_cache_flush(); /** @var WC_Product_Attribute $attribute */ foreach ( $_product->get_attributes() as $attribute ) { if ( $attribute instanceof WC_Product_Attribute){ $attribute = array( 'name' => $attribute->get_name(), 'is_taxonomy' => $attribute->is_taxonomy(), 'is_variation' => $attribute->get_variation(), 'value' => wc_implode_text_attributes( $attribute->get_options() ) ); } if ( ! $attribute['is_variation'] ) { continue; } $attribute_field_name = 'attribute_' . sanitize_title( $attribute['name'] ); if ( $attribute['is_taxonomy'] ) { $options = wc_get_product_terms( $post_id, $attribute['name'], array( 'fields' => 'slugs' ) ); } else { $options = explode( '|', $attribute['value'] ); } $options = array_map( 'trim', $options ); $variations[ $attribute_field_name ] = $options; } // Quit out if none were found if ( sizeof( $variations ) == 0 ) return 0; // Get existing variations so we don't create duplicates $available_variations = array(); foreach( $_product->get_children() as $child_id ) { $child = wc_get_product( $child_id ); if ( ! empty( $child->variation_id ) ) { $postRecord = new PMXI_Post_Record(); $postRecord->getBy(array( 'post_id' => $child->variation_id, 'import_id' => $import_id, 'unique_key' => 'Variation ' . $child->variation_id . ' of ' . $post_id, )); if ( ! $postRecord->isEmpty() ){ $postRecord->set(array('iteration' => $iteration))->update(); } $variation_attributes = $child->get_variation_attributes(); foreach ($variation_attributes as $key => $value) { $variation_attributes[$key] = sanitize_title($value); } $available_variations[] = $variation_attributes; update_post_meta( $child->variation_id, '_regular_price', get_post_meta( $post_id, '_regular_price', true ) ); update_post_meta( $child->variation_id, '_sale_price', get_post_meta( $post_id, '_sale_price', true ) ); if ( class_exists('woocommerce_wholesale_pricing') ) update_post_meta( $child->variation_id, 'pmxi_wholesale_price', get_post_meta( $post_id, 'pmxi_wholesale_price', true ) ); update_post_meta( $child->variation_id, '_sale_price_dates_from', get_post_meta( $post_id, '_sale_price_dates_from', true ) ); update_post_meta( $child->variation_id, '_sale_price_dates_to', get_post_meta( $post_id, '_sale_price_dates_to', true ) ); update_post_meta( $child->variation_id, '_price', get_post_meta( $post_id, '_price', true ) ); update_post_meta( $child->variation_id, '_stock', get_post_meta( $post_id, '_stock', true ) ); update_post_meta( $child->variation_id, '_stock_status', get_post_meta( $post_id, '_stock_status', true ) ); update_post_meta( $child->variation_id, '_manage_stock', get_post_meta( $post_id, '_manage_stock', true ) ); update_post_meta( $child->variation_id, '_backorders', get_post_meta( $post_id, '_backorders', true ) ); do_action( 'pmxi_product_variation_saved', $child->variation_id ); } } // Created posts will all have the following data $variation_post_data = array( 'post_title' => 'Product #' . $post_id . ' Variation', 'post_content' => '', 'post_status' => 'publish', 'post_author' => get_current_user_id(), 'post_parent' => $post_id, 'post_type' => 'product_variation' ); $variation_ids = array(); $added = 0; $possible_variations = $this->array_cartesian( $variations ); foreach ( $possible_variations as $variation ) { // Check if variation already exists if ( in_array( $variation, $available_variations ) ) continue; $variation_id = wp_insert_post( $variation_post_data ); $postRecord = new PMXI_Post_Record(); $postRecord->isEmpty() and $postRecord->set(array( 'post_id' => $variation_id, 'import_id' => $import_id, 'unique_key' => 'Variation ' . $variation_id . ' of ' . $post_id, 'product_key' => '', 'iteration' => $iteration ))->insert(); update_post_meta( $variation_id, '_regular_price', get_post_meta( $post_id, '_regular_price', true ) ); update_post_meta( $variation_id, '_sale_price', get_post_meta( $post_id, '_sale_price', true ) ); if ( class_exists('woocommerce_wholesale_pricing') ) update_post_meta( $variation_id, 'pmxi_wholesale_price', get_post_meta( $post_id, 'pmxi_wholesale_price', true ) ); update_post_meta( $variation_id, '_sale_price_dates_from', get_post_meta( $post_id, '_sale_price_dates_from', true ) ); update_post_meta( $variation_id, '_sale_price_dates_to', get_post_meta( $post_id, '_sale_price_dates_to', true ) ); update_post_meta( $variation_id, '_price', get_post_meta( $post_id, '_price', true ) ); update_post_meta( $variation_id, '_stock', get_post_meta( $post_id, '_stock', true ) ); update_post_meta( $variation_id, '_stock_status', get_post_meta( $post_id, '_stock_status', true ) ); update_post_meta( $variation_id, '_manage_stock', get_post_meta( $post_id, '_manage_stock', true ) ); update_post_meta( $variation_id, '_backorders', get_post_meta( $post_id, '_backorders', true ) ); $variation_ids[] = $variation_id; foreach ( $variation as $key => $value ) { update_post_meta( $variation_id, $key, $value ); } $added++; do_action( 'pmxi_product_variation_saved', $variation_id ); } $children = get_posts( array( 'post_parent' => $post_id, 'posts_per_page'=> -1, 'post_type' => 'product_variation', 'fields' => 'ids', 'orderby' => 'ID', 'order' => 'ASC', 'post_status' => array('draft', 'publish', 'trash', 'pending', 'future', 'private') ) ); $default_attributes = array(); foreach ( $v as $attribute ) { $default_attributes[ sanitize_title($attribute['name']) ] = array(); $values = array(); foreach ( $children as $child ) { $value = array_map( 'stripslashes', array_map( 'strip_tags', explode("|", trim( get_post_meta($child, 'attribute_'.sanitize_title($attribute['name']), true))))); if ( ! empty($value) ){ foreach ($value as $val) { if ( ! in_array($val, $values, true) ) $values[] = $val; } } if ( $attribute['is_variation'] ) { if ( ! empty($values) and empty($default_attributes[ $attribute['name'] ])){ switch ($this->import->options['default_attributes_type']) { case 'instock': $is_instock = get_post_meta($child, '_stock_status', true); if ($is_instock == 'instock'){ $default_attributes[ sanitize_title($attribute['name']) ] = sanitize_title((is_array($value)) ? $value[0] : $value); } break; case 'first': $default_attributes[ sanitize_title($attribute['name']) ] = sanitize_title((is_array($values)) ? $values[0] : $values); break; default: # code... break; } } } } } if ($this->import->options['is_default_attributes']) $this->pushmeta($post_id, '_default_attributes', $default_attributes); wc_delete_product_transients( $post_id ); return $added; } function array_cartesian( $input ) { $result = array(); while ( list( $key, $values ) = each( $input ) ) { // If a sub-array is empty, it doesn't affect the cartesian product if ( empty( $values ) ) { continue; } // Special case: seeding the product array with the values from the first sub-array if ( empty( $result ) ) { foreach ( $values as $value ) { $result[] = array( $key => $value ); } } else { // Second and subsequent input sub-arrays work like this: // 1. In each existing array inside $product, add an item with // key == $key and value == first item in input sub-array // 2. Then, for each remaining item in current input sub-array, // add a copy of each existing array inside $product with // key == $key and value == first item in current input sub-array // Store all items to be added to $product here; adding them on the spot // inside the foreach will result in an infinite loop $append = array(); foreach( $result as &$product ) { // Do step 1 above. array_shift is not the most efficient, but it // allows us to iterate over the rest of the items with a simple // foreach, making the code short and familiar. $product[ $key ] = array_shift( $values ); // $product is by reference (that's why the key we added above // will appear in the end result), so make a copy of it here $copy = $product; // Do step 2 above. foreach( $values as $item ) { $copy[ $key ] = $item; $append[] = $copy; } // Undo the side effecst of array_shift array_unshift( $values, $product[ $key ] ); } // Out of the foreach, we can add to $results now $result = array_merge( $result, $append ); } } return $result; } function create_taxonomy($attr_name, $logger, $prefix = 1){ global $woocommerce; $attr_name_real = $prefix > 1 ? $attr_name . " " . $prefix : $attr_name; if ( ! taxonomy_exists( wc_attribute_taxonomy_name( $attr_name_real ) ) ) { // Grab the submitted data $attribute_name = ( isset( $attr_name ) ) ? wc_sanitize_taxonomy_name( stripslashes( (string) $attr_name_real ) ) : ''; $attribute_label = stripslashes( (string) $attr_name ); $attribute_type = 'select'; $attribute_orderby = 'menu_order'; if ( in_array( wc_sanitize_taxonomy_name( stripslashes( (string) $attr_name_real)), $this->reserved_terms ) ) { $prefix++; return $this->create_taxonomy($attr_name, $logger, $prefix); //$logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Slug “%s” is not allowed because it is a reserved term. Change it, please.', 'wpai_woocommerce_addon_plugin'), wc_attribute_taxonomy_name( $attribute_name ))); } else{ // Register the taxonomy now so that the import works! $domain = wc_attribute_taxonomy_name( $attr_name_real ); if (strlen($domain) <= 28){ $this->wpdb->insert( $this->wpdb->prefix . 'woocommerce_attribute_taxonomies', array( 'attribute_label' => $attribute_label, 'attribute_name' => $attribute_name, 'attribute_type' => $attribute_type, 'attribute_orderby' => $attribute_orderby, ) ); register_taxonomy( $domain, apply_filters( 'woocommerce_taxonomy_objects_' . $domain, array('product') ), apply_filters( 'woocommerce_taxonomy_args_' . $domain, array( 'hierarchical' => true, 'show_ui' => false, 'query_var' => true, 'rewrite' => false, ) ) ); delete_transient( 'wc_attribute_taxonomies' ); $attribute_taxonomies = $this->wpdb->get_results( "SELECT * FROM " . $this->wpdb->prefix . "woocommerce_attribute_taxonomies" ); set_transient( 'wc_attribute_taxonomies', $attribute_taxonomies ); apply_filters( 'woocommerce_attribute_taxonomies', $attribute_taxonomies ); $logger and call_user_func($logger, sprintf(__('- <b>CREATED</b>: Taxonomy attribute “%s” have been successfully created.', 'wpai_woocommerce_addon_plugin'), wc_attribute_taxonomy_name( $attribute_name ))); } else{ $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Taxonomy “%s” name is more than 28 characters. Change it, please.', 'wpai_woocommerce_addon_plugin'), $attr_name)); } } } else{ if ( in_array( wc_sanitize_taxonomy_name( stripslashes( (string) $attr_name_real)), $this->reserved_terms ) ) { $prefix++; return $this->create_taxonomy($attr_name, $logger, $prefix); //$logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Slug “%s” is not allowed because it is a reserved term. Change it, please.', 'wpai_woocommerce_addon_plugin'), wc_attribute_taxonomy_name( $attribute_name ))); } } return $attr_name_real; } function make_simple_product($post_parent){ if ( empty($this->articleData['ID']) or $this->import->options['is_update_product_type'] ){ $product_type_term = is_exists_term('simple', 'product_type', 0); if ( ! empty($product_type_term) and ! is_wp_error($product_type_term) ){ $this->associate_terms( $post_parent, array( (int) $product_type_term['term_taxonomy_id'] ), 'product_type' ); } $this->pmwi_update_prices( $post_parent ); do_action('wp_all_import_make_product_simple', $post_parent, $this->import->id); } } function pmwi_buf_prices($pid){ $table = _get_meta_table('post'); $post_meta_infos = $this->wpdb->get_results("SELECT meta_key, meta_value FROM $table WHERE post_id=$pid"); foreach ($post_meta_infos as $meta_info) { if (in_array($meta_info->meta_key, array('_regular_price', '_sale_price', '_sale_price_dates_from', '_sale_price_dates_from', '_sale_price_dates_to', '_price', '_stock', '_stock_status'))){ update_post_meta($pid, $meta_info->meta_key . '_tmp', $meta_info->meta_value); } } } function pmwi_update_prices($pid){ $table = _get_meta_table('post'); $post_meta_infos = $this->wpdb->get_results("SELECT meta_key, meta_value FROM $table WHERE post_id=$pid"); foreach ($post_meta_infos as $meta_info) { if (in_array($meta_info->meta_key, array('_regular_price_tmp', '_sale_price_tmp', '_sale_price_dates_from_tmp', '_sale_price_dates_from_tmp', '_sale_price_dates_to_tmp', '_price_tmp', '_stock_tmp', '_stock_status_tmp'))){ $this->pushmeta($pid, str_replace('_tmp', '', $meta_info->meta_key), $meta_info->meta_value); delete_post_meta( $pid, $meta_info->meta_key ); } } } function auto_cloak_links($import, &$url){ $url = apply_filters('pmwi_cloak_affiliate_url', trim($url), $this->import->id); // cloak urls with `WP Wizard Cloak` if corresponding option is set if ( ! empty($this->import->options['is_cloak']) and class_exists('PMLC_Plugin')) { if (preg_match('%^\w+://%i', $url)) { // mask only links having protocol // try to find matching cloaked link among already registered ones $list = new PMLC_Link_List(); $linkTable = $list->getTable(); $rule = new PMLC_Rule_Record(); $ruleTable = $rule->getTable(); $dest = new PMLC_Destination_Record(); $destTable = $dest->getTable(); $list->join($ruleTable, "$ruleTable.link_id = $linkTable.id") ->join($destTable, "$destTable.rule_id = $ruleTable.id") ->setColumns("$linkTable.*") ->getBy(array( "$linkTable.destination_type =" => 'ONE_SET', "$linkTable.is_trashed =" => 0, "$linkTable.preset =" => '', "$linkTable.expire_on =" => '0000-00-00', "$ruleTable.type =" => 'ONE_SET', "$destTable.weight =" => 100, "$destTable.url LIKE" => $url, ), NULL, 1, 1)->convertRecords(); if ($list->count()) { // matching link found $link = $list[0]; } else { // register new cloaked link global $wpdb; $slug = max( intval($wpdb->get_var("SELECT MAX(CONVERT(name, SIGNED)) FROM $linkTable")), intval($wpdb->get_var("SELECT MAX(CONVERT(slug, SIGNED)) FROM $linkTable")), 0 ); $i = 0; do { is_int(++$slug) and $slug > 0 or $slug = 1; $is_slug_found = ! intval($wpdb->get_var("SELECT COUNT(*) FROM $linkTable WHERE name = '$slug' OR slug = '$slug'")); } while( ! $is_slug_found and $i++ < 100000); if ($is_slug_found) { $link = new PMLC_Link_Record(array( 'name' => strval($slug), 'slug' => strval($slug), 'header_tracking_code' => '', 'footer_tracking_code' => '', 'redirect_type' => '301', 'destination_type' => 'ONE_SET', 'preset' => '', 'forward_url_params' => 1, 'no_global_tracking_code' => 0, 'expire_on' => '0000-00-00', 'created_on' => date('Y-m-d H:i:s'), 'is_trashed' => 0, )); $link->insert(); $rule = new PMLC_Rule_Record(array( 'link_id' => $link->id, 'type' => 'ONE_SET', 'rule' => '', )); $rule->insert(); $dest = new PMLC_Destination_Record(array( 'rule_id' => $rule->id, 'url' => $url, 'weight' => 100, )); $dest->insert(); } else { $logger and call_user_func($logger, sprintf(__('- <b>WARNING</b>: Unable to create cloaked link for %s', 'wpai_woocommerce_addon_plugin'), $url)); $link = NULL; } } if ($link) { // cloaked link is found or created for url $url = preg_replace('%' . preg_quote($url, '%') . '(?=([\s\'"]|$))%i', $link->getUrl(), $url); } } } } function import_linked_products( $pid, $products, $type, $is_new_product ) { if ( ! $is_new_product and ! $this->is_update_cf($type) ) return; if ( ! empty( $products ) ) { $not_found = array(); $linked_products = array(); $ids = array_filter(explode(',', $products), 'trim'); foreach ( $ids as $id ) { // search linked product by _SKU $args = array( 'post_type' => 'product', 'meta_query' => array( array( 'key' => '_sku', 'value' => $id, ) ) ); $query = new WP_Query( $args ); $linked_product = false; if ( $query->have_posts() ) { $linked_product = get_post($query->post->ID); } wp_reset_postdata(); if ( ! $linked_product ) { if (is_numeric($id)) { // search linked product by ID $query = new WP_Query( array( 'post_type' => 'product', 'post__in' => array( $id ) ) ); if ( $query->have_posts() ) { $linked_product = get_post($query->post->ID); } wp_reset_postdata(); } if ( ! $linked_product ) { // search linked product by slug $args = array( 'name' => $id, 'post_type' => 'product', 'post_status' => 'publish', 'numberposts' => 1 ); $query = get_posts($args); if( $query ) { $linked_product = $query[0]; } wp_reset_postdata(); } } if ($linked_product) { $linked_products[] = $linked_product->ID; $this->logger and call_user_func($this->logger, sprintf(__('Product `%s` with ID `%d` added to %s list.', 'wpai_woocommerce_addon_plugin'), $linked_product->post_title, $linked_product->ID, $type == '_upsell_ids' ? 'Up-Sells' : 'Cross-Sells') ); } else { $not_found[] = $id; } } // not all linked products founded if ( ! empty($not_found)) { $not_founded_linked_products = get_option( 'wp_all_import_not_linked_products_' . $this->import->id ); if (empty($not_founded_linked_products)) $not_founded_linked_products = array(); $not_founded_linked_products[] = array( 'pid' => $pid, 'type' => $type, 'not_linked_products' => $not_found ); update_option( 'wp_all_import_not_linked_products_' . $this->import->id, $not_founded_linked_products ); } $this->pushmeta($pid, $type, $linked_products); } else { delete_post_meta( $pid, $type ); } } function prepare_price( $price ) { return pmwi_prepare_price( $price, $this->import->options['disable_prepare_price'], $this->import->options['prepare_price_to_woo_format'], $this->import->options['convert_decimal_separator'] ); } function adjust_price( $price, $field ) { return pmwi_adjust_price( $price, $field, $this->import->options); } }