/** * Save variations * * @since 2.2 * @param int $id * @param array $data * @return bool */ protected function save_variations($id, $data) { global $wpdb; $variations = $data['variations']; $attributes = (array) maybe_unserialize(get_post_meta($id, '_product_attributes', true)); foreach ($variations as $menu_order => $variation) { $variation_id = isset($variation['id']) ? absint($variation['id']) : 0; // Generate a useful post title $variation_post_title = sprintf(__('Variation #%s of %s', 'woocommerce'), $variation_id, esc_html(get_the_title($id))); // Update or Add post if (!$variation_id) { $post_status = isset($variation['visible']) && false === $variation['visible'] ? 'private' : 'publish'; $new_variation = array('post_title' => $variation_post_title, 'post_content' => '', 'post_status' => $post_status, 'post_author' => get_current_user_id(), 'post_parent' => $id, 'post_type' => 'product_variation', 'menu_order' => $menu_order); $variation_id = wp_insert_post($new_variation); do_action('woocommerce_create_product_variation', $variation_id); } else { $update_variation = array('post_title' => $variation_post_title, 'menu_order' => $menu_order); if (isset($variation['visible'])) { $post_status = false === $variation['visible'] ? 'private' : 'publish'; $update_variation['post_status'] = $post_status; } $wpdb->update($wpdb->posts, $update_variation, array('ID' => $variation_id)); do_action('woocommerce_update_product_variation', $variation_id); } // Stop with we don't have a variation ID if (is_wp_error($variation_id)) { throw new WC_API_Exception('woocommerce_api_cannot_save_product_variation', $variation_id->get_error_message(), 400); } // SKU if (isset($variation['sku'])) { $sku = get_post_meta($variation_id, '_sku', true); $new_sku = wc_clean($variation['sku']); if ('' == $new_sku) { update_post_meta($variation_id, '_sku', ''); } elseif ($new_sku !== $sku) { if (!empty($new_sku)) { $unique_sku = wc_product_has_unique_sku($variation_id, $new_sku); if (!$unique_sku) { throw new WC_API_Exception('woocommerce_api_product_sku_already_exists', __('The SKU already exists on another product', 'woocommerce'), 400); } else { update_post_meta($variation_id, '_sku', $new_sku); } } else { update_post_meta($variation_id, '_sku', ''); } } } // Thumbnail if (isset($variation['image']) && is_array($variation['image'])) { $image = current($variation['image']); if ($image && is_array($image)) { if (isset($image['position']) && isset($image['src']) && $image['position'] == 0) { $upload = $this->upload_product_image(wc_clean($image['src'])); if (is_wp_error($upload)) { throw new WC_API_Exception('woocommerce_api_cannot_upload_product_image', $upload->get_error_message(), 400); } $attachment_id = $this->set_product_image_as_attachment($upload, $id); update_post_meta($variation_id, '_thumbnail_id', $attachment_id); } } else { delete_post_meta($variation_id, '_thumbnail_id'); } } // Virtual variation if (isset($variation['virtual'])) { $is_virtual = true === $variation['virtual'] ? 'yes' : 'no'; update_post_meta($variation_id, '_virtual', $is_virtual); } // Downloadable variation if (isset($variation['downloadable'])) { $is_downloadable = true === $variation['downloadable'] ? 'yes' : 'no'; update_post_meta($variation_id, '_downloadable', $is_downloadable); } else { $is_downloadable = get_post_meta($variation_id, '_downloadable', true); } // Shipping data $this->save_product_shipping_data($variation_id, $variation); // Stock handling if (isset($variation['managing_stock'])) { $managing_stock = true === $variation['managing_stock'] ? 'yes' : 'no'; update_post_meta($variation_id, '_manage_stock', $managing_stock); } else { $managing_stock = get_post_meta($variation_id, '_manage_stock', true); } // Only update stock status to user setting if changed by the user, but do so before looking at stock levels at variation level if (isset($variation['in_stock'])) { $stock_status = true === $variation['in_stock'] ? 'instock' : 'outofstock'; wc_update_product_stock_status($variation_id, $stock_status); } if ('yes' === $managing_stock) { if (isset($variation['backorders'])) { if ('notify' == $variation['backorders']) { $backorders = 'notify'; } else { $backorders = true === $variation['backorders'] ? 'yes' : 'no'; } } else { $backorders = 'no'; } update_post_meta($variation_id, '_backorders', $backorders); if (isset($variation['stock_quantity'])) { wc_update_product_stock($variation_id, wc_stock_amount($variation['stock_quantity'])); } else { if (isset($data['inventory_delta'])) { $stock_quantity = wc_stock_amount(get_post_meta($variation_id, '_stock', true)); $stock_quantity += wc_stock_amount($data['inventory_delta']); wc_update_product_stock($variation_id, wc_stock_amount($stock_quantity)); } } } else { delete_post_meta($variation_id, '_backorders'); delete_post_meta($variation_id, '_stock'); } // Regular Price if (isset($variation['regular_price'])) { $regular_price = '' === $variation['regular_price'] ? '' : wc_format_decimal($variation['regular_price']); update_post_meta($variation_id, '_regular_price', $regular_price); } else { $regular_price = get_post_meta($variation_id, '_regular_price', true); } // Sale Price if (isset($variation['sale_price'])) { $sale_price = '' === $variation['sale_price'] ? '' : wc_format_decimal($variation['sale_price']); update_post_meta($variation_id, '_sale_price', $sale_price); } else { $sale_price = get_post_meta($variation_id, '_sale_price', true); } $date_from = isset($variation['sale_price_dates_from']) ? strtotime($variation['sale_price_dates_from']) : get_post_meta($variation_id, '_sale_price_dates_from', true); $date_to = isset($variation['sale_price_dates_to']) ? strtotime($variation['sale_price_dates_to']) : get_post_meta($variation_id, '_sale_price_dates_to', true); // Save Dates if ($date_from) { update_post_meta($variation_id, '_sale_price_dates_from', $date_from); } else { update_post_meta($variation_id, '_sale_price_dates_from', ''); } if ($date_to) { update_post_meta($variation_id, '_sale_price_dates_to', $date_to); } else { update_post_meta($variation_id, '_sale_price_dates_to', ''); } if ($date_to && !$date_from) { update_post_meta($variation_id, '_sale_price_dates_from', strtotime('NOW', current_time('timestamp'))); } // Update price if on sale if ('' != $sale_price && '' == $date_to && '' == $date_from) { update_post_meta($variation_id, '_price', $sale_price); } else { update_post_meta($variation_id, '_price', $regular_price); } if ('' != $sale_price && $date_from && $date_from < strtotime('NOW', current_time('timestamp'))) { update_post_meta($variation_id, '_price', $sale_price); } if ($date_to && $date_to < strtotime('NOW', current_time('timestamp'))) { update_post_meta($variation_id, '_price', $regular_price); update_post_meta($variation_id, '_sale_price_dates_from', ''); update_post_meta($variation_id, '_sale_price_dates_to', ''); } // Tax class if (isset($variation['tax_class'])) { if ($variation['tax_class'] !== 'parent') { update_post_meta($variation_id, '_tax_class', wc_clean($variation['tax_class'])); } else { delete_post_meta($variation_id, '_tax_class'); } } // Downloads if ('yes' == $is_downloadable) { // Downloadable files if (isset($variation['downloads']) && is_array($variation['downloads'])) { $this->save_downloadable_files($id, $variation['downloads'], $variation_id); } // Download limit if (isset($variation['download_limit'])) { $download_limit = absint($variation['download_limit']); update_post_meta($variation_id, '_download_limit', !$download_limit ? '' : $download_limit); } // Download expiry if (isset($variation['download_expiry'])) { $download_expiry = absint($variation['download_expiry']); update_post_meta($variation_id, '_download_expiry', !$download_expiry ? '' : $download_expiry); } } else { update_post_meta($variation_id, '_download_limit', ''); update_post_meta($variation_id, '_download_expiry', ''); update_post_meta($variation_id, '_downloadable_files', ''); } // Update taxonomies if (isset($variation['attributes'])) { $updated_attribute_keys = array(); foreach ($variation['attributes'] as $attribute_key => $attribute) { if (!isset($attribute['name'])) { continue; } $_attribute = array(); if (isset($attribute['slug'])) { $taxonomy = $this->get_attribute_taxonomy_by_slug($attribute['slug']); } if (!$taxonomy) { $taxonomy = sanitize_title($attribute['name']); } if (isset($attributes[$taxonomy])) { $_attribute = $attributes[$taxonomy]; } if (isset($_attribute['is_variation']) && $_attribute['is_variation']) { $_attribute_key = 'attribute_' . sanitize_title($_attribute['name']); $updated_attribute_keys[] = $_attribute_key; if (isset($_attribute['is_taxonomy']) && $_attribute['is_taxonomy']) { // Don't use wc_clean as it destroys sanitized characters $_attribute_value = isset($attribute['option']) ? sanitize_title(stripslashes($attribute['option'])) : ''; } else { $_attribute_value = isset($attribute['option']) ? wc_clean(stripslashes($attribute['option'])) : ''; } update_post_meta($variation_id, $_attribute_key, $_attribute_value); } } // Remove old taxonomies attributes so data is kept up to date - first get attribute key names $delete_attribute_keys = $wpdb->get_col($wpdb->prepare("SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE 'attribute_%%' AND meta_key NOT IN ( '" . implode("','", $updated_attribute_keys) . "' ) AND post_id = %d;", $variation_id)); foreach ($delete_attribute_keys as $key) { delete_post_meta($variation_id, $key); } } do_action('woocommerce_api_save_product_variation', $variation_id, $menu_order, $variation); } // Update parent if variable so price sorting works and stays in sync with the cheapest child WC_Product_Variable::sync($id); // Update default attributes options setting if (isset($data['default_attribute'])) { $data['default_attributes'] = $data['default_attribute']; } if (isset($data['default_attributes']) && is_array($data['default_attributes'])) { $default_attributes = array(); foreach ($data['default_attributes'] as $default_attr_key => $default_attr) { if (!isset($default_attr['name'])) { continue; } $taxonomy = sanitize_title($default_attr['name']); if (isset($default_attr['slug'])) { $taxonomy = $this->get_attribute_taxonomy_by_slug($default_attr['slug']); } if (isset($attributes[$taxonomy])) { $_attribute = $attributes[$taxonomy]; if ($_attribute['is_variation']) { $value = ''; if (isset($default_attr['option'])) { if ($_attribute['is_taxonomy']) { // Don't use wc_clean as it destroys sanitized characters $value = sanitize_title(trim(stripslashes($default_attr['option']))); } else { $value = wc_clean(trim(stripslashes($default_attr['option']))); } } if ($value) { $default_attributes[$taxonomy] = $value; } } } } update_post_meta($id, '_default_attributes', $default_attributes); } return true; }
/** * Bulk edit variations via AJAX */ public static function bulk_edit_variations() { ob_start(); check_ajax_referer('bulk-edit-variations', 'security'); // Check permissions again and make sure we have what we need if (!current_user_can('edit_products') || empty($_POST['product_id']) || empty($_POST['bulk_action'])) { die(-1); } $product_id = absint($_POST['product_id']); $bulk_action = wc_clean($_POST['bulk_action']); $data = !empty($_POST['data']) ? array_map('wc_clean', $_POST['data']) : array(); $variations = array(); if (apply_filters('woocommerce_bulk_edit_variations_need_children', true)) { $variations = get_posts(array('post_parent' => $product_id, 'posts_per_page' => -1, 'post_type' => 'product_variation', 'fields' => 'ids', 'post_status' => array('publish', 'private'))); } if (method_exists(__CLASS__, "variation_bulk_action_{$bulk_action}")) { call_user_func(array(__CLASS__, "variation_bulk_action_{$bulk_action}"), $variations, $data); } else { do_action('woocommerce_bulk_edit_variations_default', $bulk_action, $data, $product_id, $variations); } do_action('woocommerce_bulk_edit_variations', $bulk_action, $data, $product_id, $variations); // Sync and update transients WC_Product_Variable::sync($product_id); wc_delete_product_transients($product_id); die; }
/** * Save meta box data * * @deprecated 2.4.0 Deprecated in favor to WC_AJAX::save_variations() */ public static function save_variations($post_id, $post) { global $wpdb; $attributes = (array) maybe_unserialize(get_post_meta($post_id, '_product_attributes', true)); if (isset($_POST['variable_sku'])) { $variable_post_id = $_POST['variable_post_id']; $variable_sku = $_POST['variable_sku']; $variable_regular_price = $_POST['variable_regular_price']; $variable_sale_price = $_POST['variable_sale_price']; $upload_image_id = $_POST['upload_image_id']; $variable_download_limit = $_POST['variable_download_limit']; $variable_download_expiry = $_POST['variable_download_expiry']; $variable_shipping_class = $_POST['variable_shipping_class']; $variable_tax_class = isset($_POST['variable_tax_class']) ? $_POST['variable_tax_class'] : array(); $variable_menu_order = $_POST['variation_menu_order']; $variable_sale_price_dates_from = $_POST['variable_sale_price_dates_from']; $variable_sale_price_dates_to = $_POST['variable_sale_price_dates_to']; $variable_weight = isset($_POST['variable_weight']) ? $_POST['variable_weight'] : array(); $variable_length = isset($_POST['variable_length']) ? $_POST['variable_length'] : array(); $variable_width = isset($_POST['variable_width']) ? $_POST['variable_width'] : array(); $variable_height = isset($_POST['variable_height']) ? $_POST['variable_height'] : array(); $variable_enabled = isset($_POST['variable_enabled']) ? $_POST['variable_enabled'] : array(); $variable_is_virtual = isset($_POST['variable_is_virtual']) ? $_POST['variable_is_virtual'] : array(); $variable_is_downloadable = isset($_POST['variable_is_downloadable']) ? $_POST['variable_is_downloadable'] : array(); $variable_manage_stock = isset($_POST['variable_manage_stock']) ? $_POST['variable_manage_stock'] : array(); $variable_stock = isset($_POST['variable_stock']) ? $_POST['variable_stock'] : array(); $variable_backorders = isset($_POST['variable_backorders']) ? $_POST['variable_backorders'] : array(); $variable_stock_status = isset($_POST['variable_stock_status']) ? $_POST['variable_stock_status'] : array(); $variable_description = isset($_POST['variable_description']) ? $_POST['variable_description'] : array(); $max_loop = max(array_keys($_POST['variable_post_id'])); for ($i = 0; $i <= $max_loop; $i++) { if (!isset($variable_post_id[$i])) { continue; } $variation_id = absint($variable_post_id[$i]); // Checkboxes $is_virtual = isset($variable_is_virtual[$i]) ? 'yes' : 'no'; $is_downloadable = isset($variable_is_downloadable[$i]) ? 'yes' : 'no'; $post_status = isset($variable_enabled[$i]) ? 'publish' : 'private'; $manage_stock = isset($variable_manage_stock[$i]) ? 'yes' : 'no'; // Generate a useful post title $variation_post_title = sprintf(__('Variation #%s of %s', 'woocommerce'), absint($variation_id), esc_html(get_the_title($post_id))); // Update or Add post if (!$variation_id) { $variation = array('post_title' => $variation_post_title, 'post_content' => '', 'post_status' => $post_status, 'post_author' => get_current_user_id(), 'post_parent' => $post_id, 'post_type' => 'product_variation', 'menu_order' => $variable_menu_order[$i]); $variation_id = wp_insert_post($variation); do_action('woocommerce_create_product_variation', $variation_id); } else { $wpdb->update($wpdb->posts, array('post_status' => $post_status, 'post_title' => $variation_post_title, 'menu_order' => $variable_menu_order[$i]), array('ID' => $variation_id)); do_action('woocommerce_update_product_variation', $variation_id); } // Only continue if we have a variation ID if (!$variation_id) { continue; } // Unique SKU $sku = get_post_meta($variation_id, '_sku', true); $new_sku = wc_clean(stripslashes($variable_sku[$i])); if ('' == $new_sku) { update_post_meta($variation_id, '_sku', ''); } elseif ($new_sku !== $sku) { if (!empty($new_sku)) { $unique_sku = wc_product_has_unique_sku($variation_id, $new_sku); if (!$unique_sku) { WC_Admin_Meta_Boxes::add_error(__('Variation SKU must be unique.', 'woocommerce')); } else { update_post_meta($variation_id, '_sku', $new_sku); } } else { update_post_meta($variation_id, '_sku', ''); } } // Update post meta update_post_meta($variation_id, '_thumbnail_id', absint($upload_image_id[$i])); update_post_meta($variation_id, '_virtual', wc_clean($is_virtual)); update_post_meta($variation_id, '_downloadable', wc_clean($is_downloadable)); if (isset($variable_weight[$i])) { update_post_meta($variation_id, '_weight', '' === $variable_weight[$i] ? '' : wc_format_decimal($variable_weight[$i])); } if (isset($variable_length[$i])) { update_post_meta($variation_id, '_length', '' === $variable_length[$i] ? '' : wc_format_decimal($variable_length[$i])); } if (isset($variable_width[$i])) { update_post_meta($variation_id, '_width', '' === $variable_width[$i] ? '' : wc_format_decimal($variable_width[$i])); } if (isset($variable_height[$i])) { update_post_meta($variation_id, '_height', '' === $variable_height[$i] ? '' : wc_format_decimal($variable_height[$i])); } // Stock handling update_post_meta($variation_id, '_manage_stock', $manage_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($variable_stock_status[$i])) { wc_update_product_stock_status($variation_id, $variable_stock_status[$i]); } if ('yes' === $manage_stock) { update_post_meta($variation_id, '_backorders', wc_clean($variable_backorders[$i])); wc_update_product_stock($variation_id, wc_stock_amount($variable_stock[$i])); } else { delete_post_meta($variation_id, '_backorders'); delete_post_meta($variation_id, '_stock'); } // Price handling $regular_price = wc_format_decimal($variable_regular_price[$i]); $sale_price = $variable_sale_price[$i] === '' ? '' : wc_format_decimal($variable_sale_price[$i]); $date_from = wc_clean($variable_sale_price_dates_from[$i]); $date_to = wc_clean($variable_sale_price_dates_to[$i]); update_post_meta($variation_id, '_regular_price', $regular_price); update_post_meta($variation_id, '_sale_price', $sale_price); // Save Dates update_post_meta($variation_id, '_sale_price_dates_from', $date_from ? strtotime($date_from) : ''); update_post_meta($variation_id, '_sale_price_dates_to', $date_to ? strtotime($date_to) : ''); if ($date_to && !$date_from) { update_post_meta($variation_id, '_sale_price_dates_from', strtotime('NOW', current_time('timestamp'))); } // Update price if on sale if ('' !== $sale_price && '' === $date_to && '' === $date_from) { update_post_meta($variation_id, '_price', $sale_price); } else { update_post_meta($variation_id, '_price', $regular_price); } if ('' !== $sale_price && $date_from && strtotime($date_from) < strtotime('NOW', current_time('timestamp'))) { update_post_meta($variation_id, '_price', $sale_price); } if ($date_to && strtotime($date_to) < strtotime('NOW', current_time('timestamp'))) { update_post_meta($variation_id, '_price', $regular_price); update_post_meta($variation_id, '_sale_price_dates_from', ''); update_post_meta($variation_id, '_sale_price_dates_to', ''); } if (isset($variable_tax_class[$i]) && $variable_tax_class[$i] !== 'parent') { update_post_meta($variation_id, '_tax_class', wc_clean($variable_tax_class[$i])); } else { delete_post_meta($variation_id, '_tax_class'); } if ('yes' == $is_downloadable) { update_post_meta($variation_id, '_download_limit', wc_clean($variable_download_limit[$i])); update_post_meta($variation_id, '_download_expiry', wc_clean($variable_download_expiry[$i])); $files = array(); $file_names = isset($_POST['_wc_variation_file_names'][$variation_id]) ? array_map('wc_clean', $_POST['_wc_variation_file_names'][$variation_id]) : array(); $file_urls = isset($_POST['_wc_variation_file_urls'][$variation_id]) ? array_map('wc_clean', $_POST['_wc_variation_file_urls'][$variation_id]) : array(); $file_url_size = sizeof($file_urls); $allowed_file_types = get_allowed_mime_types(); for ($ii = 0; $ii < $file_url_size; $ii++) { if (!empty($file_urls[$ii])) { // Find type and file URL if (0 === strpos($file_urls[$ii], 'http')) { $file_is = 'absolute'; $file_url = esc_url_raw($file_urls[$ii]); } elseif ('[' === substr($file_urls[$ii], 0, 1) && ']' === substr($file_urls[$ii], -1)) { $file_is = 'shortcode'; $file_url = wc_clean($file_urls[$ii]); } else { $file_is = 'relative'; $file_url = wc_clean($file_urls[$ii]); } $file_name = wc_clean($file_names[$ii]); $file_hash = md5($file_url); // Validate the file extension if (in_array($file_is, array('absolute', 'relative'))) { $file_type = wp_check_filetype(strtok($file_url, '?')); $parsed_url = parse_url($file_url, PHP_URL_PATH); $extension = pathinfo($parsed_url, PATHINFO_EXTENSION); if (!empty($extension) && !in_array($file_type['type'], $allowed_file_types)) { WC_Admin_Meta_Boxes::add_error(sprintf(__('The downloadable file %s cannot be used as it does not have an allowed file type. Allowed types include: %s', 'woocommerce'), '<code>' . basename($file_url) . '</code>', '<code>' . implode(', ', array_keys($allowed_file_types)) . '</code>')); continue; } } // Validate the file exists if ('relative' === $file_is && !apply_filters('woocommerce_downloadable_file_exists', file_exists($file_url), $file_url)) { WC_Admin_Meta_Boxes::add_error(sprintf(__('The downloadable file %s cannot be used as it does not exist on the server.', 'woocommerce'), '<code>' . $file_url . '</code>')); continue; } $files[$file_hash] = array('name' => $file_name, 'file' => $file_url); } } // grant permission to any newly added files on any existing orders for this product prior to saving do_action('woocommerce_process_product_file_download_paths', $post_id, $variation_id, $files); update_post_meta($variation_id, '_downloadable_files', $files); } else { update_post_meta($variation_id, '_download_limit', ''); update_post_meta($variation_id, '_download_expiry', ''); update_post_meta($variation_id, '_downloadable_files', ''); } update_post_meta($variation_id, '_variation_description', wp_kses_post($variable_description[$i])); // Save shipping class $variable_shipping_class[$i] = !empty($variable_shipping_class[$i]) ? (int) $variable_shipping_class[$i] : ''; wp_set_object_terms($variation_id, $variable_shipping_class[$i], 'product_shipping_class'); // Update Attributes $updated_attribute_keys = array(); foreach ($attributes as $attribute) { if ($attribute['is_variation']) { $attribute_key = 'attribute_' . sanitize_title($attribute['name']); $updated_attribute_keys[] = $attribute_key; if ($attribute['is_taxonomy']) { // Don't use wc_clean as it destroys sanitized characters $value = isset($_POST[$attribute_key][$i]) ? sanitize_title(stripslashes($_POST[$attribute_key][$i])) : ''; } else { $value = isset($_POST[$attribute_key][$i]) ? wc_clean(stripslashes($_POST[$attribute_key][$i])) : ''; } update_post_meta($variation_id, $attribute_key, $value); } } // Remove old taxonomies attributes so data is kept up to date - first get attribute key names $delete_attribute_keys = $wpdb->get_col($wpdb->prepare("SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE 'attribute_%%' AND meta_key NOT IN ( '" . implode("','", $updated_attribute_keys) . "' ) AND post_id = %d;", $variation_id)); foreach ($delete_attribute_keys as $key) { delete_post_meta($variation_id, $key); } do_action('woocommerce_save_product_variation', $variation_id, $i); } } // Update parent if variable so price sorting works and stays in sync with the cheapest child WC_Product_Variable::sync($post_id); // Update default attribute options setting $default_attributes = array(); foreach ($attributes as $attribute) { if ($attribute['is_variation']) { // Don't use wc_clean as it destroys sanitized characters if (isset($_POST['default_attribute_' . sanitize_title($attribute['name'])])) { $value = sanitize_title(trim(stripslashes($_POST['default_attribute_' . sanitize_title($attribute['name'])]))); } else { $value = ''; } if ($value) { $default_attributes[sanitize_title($attribute['name'])] = $value; } } } update_post_meta($post_id, '_default_attributes', $default_attributes); }
/** * Set stock level of the product variation. * * Uses queries rather than update_post_meta so we can do this in one query (to avoid stock issues). * We cannot rely on the original loaded value in case another order was made since then. * * @param int $amount * @param string $mode can be set, add, or subtract * @return int new stock level */ public function set_stock($amount = null, $mode = 'set') { global $wpdb; if (!is_null($amount) && true === $this->managing_stock()) { // Ensure key exists add_post_meta($this->variation_id, '_stock', 0, true); // Update stock in DB directly switch ($mode) { case 'add': $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = meta_value + %f WHERE post_id = %d AND meta_key='_stock'", $amount, $this->variation_id)); break; case 'subtract': $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = meta_value - %f WHERE post_id = %d AND meta_key='_stock'", $amount, $this->variation_id)); break; default: $wpdb->query($wpdb->prepare("UPDATE {$wpdb->postmeta} SET meta_value = %f WHERE post_id = %d AND meta_key='_stock'", $amount, $this->variation_id)); break; } // Clear caches wp_cache_delete($this->variation_id, 'post_meta'); // Clear total stock transient delete_transient('wc_product_total_stock_' . $this->id . WC_Cache_Helper::get_transient_version('product')); // Stock status $this->check_stock_status(); // Sync the parent WC_Product_Variable::sync($this->id); // Trigger action do_action('woocommerce_variation_set_stock', $this); } elseif (!is_null($amount)) { return $this->parent->set_stock($amount, $mode); } return $this->get_stock_quantity(); }
/** * Set stock level of the product variation. * @param int $amount * @param bool $force_variation_stock If true, the variation's stock will be updated and not the parents. * @return int * @todo Need to return 0 if is_null? Or something. Should not be just return. */ function set_stock($amount = null, $force_variation_stock = false) { if (is_null($amount)) { return; } if ($amount === '' && $force_variation_stock) { // If amount is an empty string, stock management is being turned off at variation level $this->variation_has_stock = false; $this->stock = ''; unset($this->manage_stock); // Update meta update_post_meta($this->variation_id, '_stock', ''); // Refresh parent prices WC_Product_Variable::sync($this->id); } elseif ($this->variation_has_stock || $force_variation_stock) { // Update stock amount $this->stock = intval($amount); $this->variation_has_stock = true; $this->manage_stock = 'yes'; // Update meta update_post_meta($this->variation_id, '_stock', $this->stock); // Clear total stock transient delete_transient('wc_product_total_stock_' . $this->id); // Check parents out of stock attribute if (!$this->is_in_stock()) { // Check parent $parent_product = get_product($this->id); // Only continue if the parent has backorders off and all children are stock managed and out of stock if (!$parent_product->backorders_allowed() && $parent_product->get_total_stock() <= get_option('woocommerce_notify_no_stock_amount')) { $all_managed = true; if (sizeof($parent_product->get_children()) > 0) { foreach ($parent_product->get_children() as $child_id) { $stock = get_post_meta($child_id, '_stock', true); if ($stock == '') { $all_managed = false; break; } } } if ($all_managed) { $this->set_stock_status('outofstock'); } } } elseif ($this->is_in_stock()) { $this->set_stock_status('instock'); } // Refresh parent prices WC_Product_Variable::sync($this->id); // Trigger action do_action('woocommerce_product_set_stock', $this); return $this->get_stock_quantity(); } else { return parent::set_stock($amount); } }
function dokan_save_variations($post_id) { global $woocommerce, $wpdb; $attributes = (array) maybe_unserialize(get_post_meta($post_id, '_product_attributes', true)); if (isset($_POST['variable_sku'])) { $variable_post_id = $_POST['variable_post_id']; $variable_sku = $_POST['variable_sku']; $variable_mrp_var = $_POST['_mrp_var']; $variable_regular_price = $_POST['variable_regular_price']; $variable_sale_price = $_POST['variable_sale_price']; $upload_image_id = $_POST['upload_image_id']; $variable_download_limit = $_POST['variable_download_limit']; $variable_download_expiry = $_POST['variable_download_expiry']; $variable_shipping_class = $_POST['variable_shipping_class']; $variable_tax_class = isset($_POST['variable_tax_class']) ? $_POST['variable_tax_class'] : array(); $variable_menu_order = $_POST['variation_menu_order']; $variable_sale_price_dates_from = $_POST['variable_sale_price_dates_from']; $variable_sale_price_dates_to = $_POST['variable_sale_price_dates_to']; $variable_weight = isset($_POST['variable_weight']) ? $_POST['variable_weight'] : array(); $variable_length = isset($_POST['variable_length']) ? $_POST['variable_length'] : array(); $variable_width = isset($_POST['variable_width']) ? $_POST['variable_width'] : array(); $variable_height = isset($_POST['variable_height']) ? $_POST['variable_height'] : array(); $variable_stock = isset($_POST['variable_stock']) ? $_POST['variable_stock'] : array(); $variable_enabled = isset($_POST['variable_enabled']) ? $_POST['variable_enabled'] : array(); $variable_is_virtual = isset($_POST['variable_is_virtual']) ? $_POST['variable_is_virtual'] : array(); $variable_is_downloadable = isset($_POST['variable_is_downloadable']) ? $_POST['variable_is_downloadable'] : array(); $max_loop = max(array_keys($_POST['variable_post_id'])); for ($i = 0; $i <= $max_loop; $i++) { if (!isset($variable_post_id[$i])) { continue; } $variation_id = absint($variable_post_id[$i]); // Virtal/Downloadable $is_virtual = isset($variable_is_virtual[$i]) ? 'yes' : 'no'; $is_downloadable = isset($variable_is_downloadable[$i]) ? 'yes' : 'no'; $manage_stock = isset($variable_stock[$i]) ? 'yes' : 'no'; // Enabled or disabled $post_status = isset($variable_enabled[$i]) ? 'publish' : 'private'; // Generate a useful post title $variation_post_title = sprintf(__('Variation #%s of %s', 'woocommerce'), absint($variation_id), esc_html(get_the_title($post_id))); // Update or Add post if (!$variation_id) { $variation = array('post_title' => $variation_post_title, 'post_content' => '', 'post_status' => $post_status, 'post_author' => get_current_user_id(), 'post_parent' => $post_id, 'post_type' => 'product_variation', 'menu_order' => $variable_menu_order[$i]); $variation_id = wp_insert_post($variation); do_action('woocommerce_create_product_variation', $variation_id); } else { $wpdb->update($wpdb->posts, array('post_status' => $post_status, 'post_title' => $variation_post_title, 'menu_order' => $variable_menu_order[$i]), array('ID' => $variation_id)); do_action('woocommerce_update_product_variation', $variation_id); } // Update post meta update_post_meta($variation_id, '_sku', wc_clean($variable_sku[$i])); update_post_meta($variation_id, '_thumbnail_id', absint($upload_image_id[$i])); update_post_meta($variation_id, '_virtual', wc_clean($is_virtual)); update_post_meta($variation_id, '_downloadable', wc_clean($is_downloadable)); update_post_meta($variation_id, '_manage_stock', wc_clean($manage_stock)); if (isset($variable_weight[$i])) { update_post_meta($variation_id, '_weight', $variable_weight[$i] === '' ? '' : wc_format_decimal($variable_weight[$i])); } if (isset($variable_length[$i])) { update_post_meta($variation_id, '_length', $variable_length[$i] === '' ? '' : wc_format_decimal($variable_length[$i])); } if (isset($variable_width[$i])) { update_post_meta($variation_id, '_width', $variable_width[$i] === '' ? '' : wc_format_decimal($variable_width[$i])); } if (isset($variable_height[$i])) { update_post_meta($variation_id, '_height', $variable_height[$i] === '' ? '' : wc_format_decimal($variable_height[$i])); } // Stock handling if (isset($variable_stock[$i])) { wc_update_product_stock($variation_id, wc_clean($variable_stock[$i])); } // Price handling $mrp = wc_format_decimal($variable_mrp_var[$i]); $regular_price = wc_format_decimal($variable_regular_price[$i]); $sale_price = $variable_sale_price[$i] === '' ? '' : wc_format_decimal($variable_sale_price[$i]); $date_from = wc_clean($variable_sale_price_dates_from[$i]); $date_to = wc_clean($variable_sale_price_dates_to[$i]); update_post_meta($variation_id, '_regular_price', $regular_price); update_post_meta($variation_id, '_sale_price', $sale_price); update_post_meta($variation_id, '_list_price_mrp', $mrp); // Save Dates if ($date_from) { update_post_meta($variation_id, '_sale_price_dates_from', strtotime($date_from)); } else { update_post_meta($variation_id, '_sale_price_dates_from', ''); } if ($date_to) { update_post_meta($variation_id, '_sale_price_dates_to', strtotime($date_to)); } else { update_post_meta($variation_id, '_sale_price_dates_to', ''); } if ($date_to && !$date_from) { update_post_meta($variation_id, '_sale_price_dates_from', strtotime('NOW', current_time('timestamp'))); } // Update price if on sale if ($sale_price != '' && $date_to == '' && $date_from == '') { update_post_meta($variation_id, '_price', $sale_price); } else { update_post_meta($variation_id, '_price', $regular_price); } if ($sale_price != '' && $date_from && strtotime($date_from) < strtotime('NOW', current_time('timestamp'))) { update_post_meta($variation_id, '_price', $sale_price); } if ($date_to && strtotime($date_to) < strtotime('NOW', current_time('timestamp'))) { update_post_meta($variation_id, '_price', $regular_price); update_post_meta($variation_id, '_sale_price_dates_from', ''); update_post_meta($variation_id, '_sale_price_dates_to', ''); } if (isset($variable_tax_class[$i]) && $variable_tax_class[$i] !== 'parent') { update_post_meta($variation_id, '_tax_class', wc_clean($variable_tax_class[$i])); } else { delete_post_meta($variation_id, '_tax_class'); } if ($is_downloadable == 'yes') { update_post_meta($variation_id, '_download_limit', wc_clean($variable_download_limit[$i])); update_post_meta($variation_id, '_download_expiry', wc_clean($variable_download_expiry[$i])); $files = array(); $file_names = isset($_POST['_wc_variation_file_names'][$variation_id]) ? array_map('wc_clean', $_POST['_wc_variation_file_names'][$variation_id]) : array(); $file_urls = isset($_POST['_wc_variation_file_urls'][$variation_id]) ? array_map('esc_url_raw', array_map('trim', $_POST['_wc_variation_file_urls'][$variation_id])) : array(); $file_url_size = sizeof($file_urls); for ($ii = 0; $ii < $file_url_size; $ii++) { if (!empty($file_urls[$ii])) { $files[md5($file_urls[$ii])] = array('name' => $file_names[$ii], 'file' => $file_urls[$ii]); } } // grant permission to any newly added files on any existing orders for this product prior to saving do_action('woocommerce_process_product_file_download_paths', $post_id, $variation_id, $files); update_post_meta($variation_id, '_downloadable_files', $files); } else { update_post_meta($variation_id, '_download_limit', ''); update_post_meta($variation_id, '_download_expiry', ''); update_post_meta($variation_id, '_downloadable_files', ''); } // Save shipping class $variable_shipping_class[$i] = !empty($variable_shipping_class[$i]) ? (int) $variable_shipping_class[$i] : ''; wp_set_object_terms($variation_id, $variable_shipping_class[$i], 'product_shipping_class'); // Remove old taxonomies attributes so data is kept up to date if ($variation_id) { $wpdb->query($wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE meta_key LIKE 'attribute_%%' AND post_id = %d;", $variation_id)); wp_cache_delete($variation_id, 'post_meta'); } // Update taxonomies foreach ($attributes as $attribute) { if ($attribute['is_variation']) { // Don't use wc_clean as it destroys sanitized characters if (isset($_POST['attribute_' . sanitize_title($attribute['name'])][$i])) { $value = sanitize_title(trim(stripslashes($_POST['attribute_' . sanitize_title($attribute['name'])][$i]))); } else { $value = ''; } update_post_meta($variation_id, 'attribute_' . sanitize_title($attribute['name']), $value); } } do_action('woocommerce_save_product_variation', $variation_id, $i); } } // Update parent if variable so price sorting works and stays in sync with the cheapest child WC_Product_Variable::sync($post_id); // Update default attribute options setting $default_attributes = array(); foreach ($attributes as $attribute) { if ($attribute['is_variation']) { // Don't use wc_clean as it destroys sanitized characters if (isset($_POST['default_attribute_' . sanitize_title($attribute['name'])])) { $value = sanitize_title(trim(stripslashes($_POST['default_attribute_' . sanitize_title($attribute['name'])]))); } else { $value = ''; } if ($value) { $default_attributes[sanitize_title($attribute['name'])] = $value; } } } update_post_meta($post_id, '_default_attributes', $default_attributes); }
/** * Update post meta fields. * * @param WP_Post $post Post data. * @param WP_REST_Request $request Request data. * @return bool|WP_Error */ protected function update_post_meta_fields($post, $request) { $product = wc_get_product($post); // Check for featured/gallery images, upload it and set it. if (isset($request['images'])) { $product = $this->save_product_images($product, $request['images']); } // Save product meta fields. $product = $this->save_product_meta($product, $request); // Save variations. if ($product->is_type('variable')) { if (isset($request['variations']) && is_array($request['variations'])) { $this->save_variations_data($product, $request); } else { // Just sync variations. $product = WC_Product_Variable::sync($product, false); } } $product->save(); return true; }
/** * Registered callback function for the WordPress Importer * * Manages the three separate stages of the CSV import process */ public function dispatch() { global $woocommerce, $wpdb; if (!empty($_POST['delimiter'])) { $this->delimiter = stripslashes(trim($_POST['delimiter'])); } if (!$this->delimiter) { $this->delimiter = ','; } if (!empty($_POST['merge_empty_cells'])) { $this->merge_empty_cells = 1; } else { $this->merge_empty_cells = 0; } $step = empty($_GET['step']) ? 0 : (int) $_GET['step']; switch ($step) { case 0: $this->header(); $this->greet(); break; case 1: $this->header(); check_admin_referer('import-upload'); if ($this->handle_upload()) { $this->import_options(); } else { _e('Error with handle_upload!', 'wc_csv_import'); } break; case 2: $this->header(); check_admin_referer('import-woocommerce'); $this->id = (int) $_POST['import_id']; if ($this->file_url_import_enabled) { $this->file_url = esc_attr($_POST['import_url']); } if ($this->id) { $file = get_attached_file($this->id); } else { if ($this->file_url_import_enabled) { $file = ABSPATH . $this->file_url; } } $file = str_replace("\\", "/", $file); if ($file) { ?> <table id="import-progress" class="widefat_importer widefat"> <thead> <tr> <th class="status"> </th> <th class="row"><?php _e('Row', 'wc_csv_import'); ?> </th> <th><?php _e('SKU', 'wc_csv_import'); ?> </th> <th><?php _e('Product', 'wc_csv_import'); ?> </th> <th class="reason"><?php _e('Status Msg', 'wc_csv_import'); ?> </th> </tr> </thead> <tfoot> <tr class="importer-loading"> <td colspan="5"></td> </tr> </tfoot> <tbody></tbody> </table> <script type="text/javascript"> jQuery(document).ready(function($) { if ( ! window.console ) { window.console = function(){}; } var processed_terms = []; var processed_posts = []; var post_orphans = []; var attachments = []; var upsell_skus = []; var crosssell_skus = []; var i = 1; var done_count = 0; function import_rows( start_pos, end_pos ) { var data = { action: 'woocommerce_csv_import_request', file: '<?php echo addslashes($file); ?> ', mapping: '<?php echo json_encode($_POST['map_to']); ?> ', delimiter: '<?php echo $this->delimiter; ?> ', merge_empty_cells: '<?php echo $this->merge_empty_cells; ?> ', start_pos: start_pos, end_pos: end_pos, }; return $.ajax({ url: '<?php echo add_query_arg(array('import_page' => $this->import_page, 'step' => '3', 'merge' => !empty($_GET['merge']) ? '1' : '0'), admin_url('admin-ajax.php')); ?> ', data: data, type: 'POST', success: function( response ) { console.log( response ); if ( response ) { try { // Get the valid JSON only from the returned string if ( response.indexOf("<!--WC_START-->") >= 0 ) response = response.split("<!--WC_START-->")[1]; // Strip off before after WC_START if ( response.indexOf("<!--WC_END-->") >= 0 ) response = response.split("<!--WC_END-->")[0]; // Strip off anything after WC_END // Parse var results = $.parseJSON( response ); if ( results.error ) { $('#import-progress tbody').append( '<tr id="row-' + i + '" class="error"><td class="status" colspan="5">' + results.error + '</td></tr>' ); i++; } else if ( results.import_results && $( results.import_results ).size() > 0 ) { $.each( results.processed_terms, function( index, value ) { processed_terms.push( value ); }); $.each( results.processed_posts, function( index, value ) { processed_posts.push( value ); }); $.each( results.post_orphans, function( index, value ) { post_orphans.push( value ); }); $.each( results.attachments, function( index, value ) { attachments.push( value ); }); upsell_skus = jQuery.extend( {}, upsell_skus, results.upsell_skus ); crosssell_skus = jQuery.extend( {}, crosssell_skus, results.crosssell_skus ); $( results.import_results ).each(function( index, row ) { $('#import-progress tbody').append( '<tr id="row-' + i + '" class="' + row['status'] + '"><td><mark class="result" title="' + row['status'] + '">' + row['status'] + '</mark></td><td class="row">' + i + '</td><td>' + row['sku'] + '</td><td>' + row['post_id'] + ' - ' + row['post_title'] + '</td><td class="reason">' + row['reason'] + '</td></tr>' ); i++; }); } } catch(err) {} } else { $('#import-progress tbody').append( '<tr class="error"><td class="status" colspan="5">' + '<?php _e('AJAX Error', 'wc_csv_import'); ?> ' + '</td></tr>' ); } var w = $(window); var row = $( "#row-" + ( i - 1 ) ); if ( row.length ) { w.scrollTop( row.offset().top - (w.height()/2) ); } done_count++; $('body').trigger( 'woocommerce_csv_import_request_complete' ); } }); } var rows = []; <?php $limit = apply_filters('woocommerce_csv_import_limit_per_request', 10); $enc = mb_detect_encoding($file, 'UTF-8, ISO-8859-1', true); if ($enc) { setlocale(LC_ALL, 'en_US.' . $enc); } @ini_set('auto_detect_line_endings', true); $count = 0; $previous_position = 0; $position = 0; $import_count = 0; // Get CSV positions if (($handle = fopen($file, "r")) !== FALSE) { while (($postmeta = fgetcsv($handle, 0, $this->delimiter)) !== FALSE) { $count++; if ($count >= $limit) { $previous_position = $position; $position = ftell($handle); $count = 0; $import_count++; // Import rows between $previous_position $position ?> rows.push( [ <?php echo $previous_position; ?> , <?php echo $position; ?> ] ); <?php } } // Remainder if ($count > 0) { ?> rows.push( [ <?php echo $position; ?> , '' ] ); <?php $import_count++; } fclose($handle); } ?> var data = rows.shift(); var regen_count = 0; import_rows( data[0], data[1] ); $('body').on( 'woocommerce_csv_import_request_complete', function() { if ( done_count == <?php echo $import_count; ?> ) { if ( attachments.length ) { $('#import-progress tbody').append( '<tr class="regenerating"><td colspan="5"><div class="progress"></div></td></tr>' ); index = 0; $.each( attachments, function( i, value ) { regenerate_thumbnail( value ); index ++; if ( index == attachments.length ) { import_done(); } }); } else { import_done(); } } else { // Call next request data = rows.shift(); import_rows( data[0], data[1] ); } } ); // Regenerate a specified image via AJAX function regenerate_thumbnail( id ) { $.ajax({ type: 'POST', url: ajaxurl, data: { action: "woocommerce_csv_import_regenerate_thumbnail", id: id }, success: function( response ) { if ( response !== Object( response ) || ( typeof response.success === "undefined" && typeof response.error === "undefined" ) ) { response = new Object; response.success = false; response.error = "<?php printf(esc_js(__('The resize request was abnormally terminated (ID %s). This is likely due to the image exceeding available memory or some other type of fatal error.', 'wc_csv_import')), '" + id + "'); ?> "; } regen_count ++; $('#import-progress tbody .regenerating .progress').css( 'width', ( ( regen_count / attachments.length ) * 100 ) + '%' ).html( regen_count + ' / ' + attachments.length + ' <?php echo esc_js(__('thumbnails regenerated', 'wc_csv_import')); ?> ' ); if ( ! response.success ) { $('#import-progress tbody').append( '<tr><td colspan="5">' + response.error + '</td></tr>' ); } }, error: function( response ) { $('#import-progress tbody').append( '<tr><td colspan="5">' + response.error + '</td></tr>' ); } }); } function import_done() { var data = { action: 'woocommerce_csv_import_request', file: '<?php echo $file; ?> ', processed_terms: processed_terms, processed_posts: processed_posts, post_orphans: post_orphans, upsell_skus: upsell_skus, crosssell_skus: crosssell_skus }; $.ajax({ url: '<?php echo add_query_arg(array('import_page' => $this->import_page, 'step' => '4', 'merge' => !empty($_GET['merge']) ? 1 : 0), admin_url('admin-ajax.php')); ?> ', data: data, type: 'POST', success: function( response ) { console.log( response ); $('#import-progress tbody').append( '<tr class="complete"><td colspan="5">' + response + '</td></tr>' ); $('.importer-loading').hide(); } }); } }); </script> <?php } else { echo '<p class="error">' . __('Error finding uploaded file!', 'wc_csv_import') . '</p>'; } break; case 3: // Check access - cannot use nonce here as it will expire after multiple requests if (!current_user_can('manage_woocommerce')) { die; } add_filter('http_request_timeout', array($this, 'bump_request_timeout')); if (function_exists('gc_enable')) { gc_enable(); } @set_time_limit(0); @ob_flush(); @flush(); $wpdb->hide_errors(); $file = stripslashes($_POST['file']); $mapping = json_decode(stripslashes($_POST['mapping']), true); $start_pos = isset($_POST['start_pos']) ? absint($_POST['start_pos']) : 0; $end_pos = isset($_POST['end_pos']) ? absint($_POST['end_pos']) : ''; $position = $this->import_start($file, $mapping, $start_pos, $end_pos); $this->import(); $this->import_end(); $results = array(); $results['import_results'] = $this->import_results; $results['processed_terms'] = $this->processed_terms; $results['processed_posts'] = $this->processed_posts; $results['post_orphans'] = $this->post_orphans; $results['attachments'] = $this->attachments; $results['upsell_skus'] = $this->upsell_skus; $results['crosssell_skus'] = $this->crosssell_skus; echo "<!--WC_START-->"; echo json_encode($results); echo "<!--WC_END-->"; exit; break; case 4: // Check access - cannot use nonce here as it will expire after multiple requests if (!current_user_can('manage_woocommerce')) { die; } add_filter('http_request_timeout', array($this, 'bump_request_timeout')); if (function_exists('gc_enable')) { gc_enable(); } @set_time_limit(0); @ob_flush(); @flush(); $wpdb->hide_errors(); $this->processed_terms = isset($_POST['processed_terms']) ? $_POST['processed_terms'] : array(); $this->processed_posts = isset($_POST['processed_posts']) ? $_POST['processed_posts'] : array(); $this->post_orphans = isset($_POST['post_orphans']) ? $_POST['post_orphans'] : array(); $this->crosssell_skus = isset($_POST['crosssell_skus']) ? array_filter((array) $_POST['crosssell_skus']) : array(); $this->upsell_skus = isset($_POST['upsell_skus']) ? array_filter((array) $_POST['upsell_skus']) : array(); _e('Cleaning up...', 'wc_csv_import') . ' '; wp_defer_term_counting(true); wp_defer_comment_counting(true); _e('Clearing transients...', 'wc_csv_import') . ' '; echo 'Reticulating Splines...' . ' '; // Easter egg // reset transients for products if (function_exists('wc_delete_product_transients')) { wc_delete_product_transients(); } else { $woocommerce->clear_product_transients(); } delete_transient('wc_attribute_taxonomies'); $wpdb->query("DELETE FROM `{$wpdb->options}` WHERE `option_name` LIKE ('_transient_wc_product_type_%')"); _e('Backfilling parents...', 'wc_csv_import') . ' '; $this->backfill_parents(); if (!empty($this->upsell_skus)) { _e('Linking upsells...', 'wc_csv_import') . ' '; foreach ($this->upsell_skus as $post_id => $skus) { $this->link_product_skus('upsell', $post_id, $skus); } } if (!empty($this->crosssell_skus)) { _e('Linking crosssells...', 'wc_csv_import') . ' '; foreach ($this->crosssell_skus as $post_id => $skus) { $this->link_product_skus('crosssell', $post_id, $skus); } } if ('woocommerce_variation_csv' == $this->import_page && !empty($this->processed_posts)) { _e('Syncing variations...', 'wc_csv_import') . ' '; $synced = array(); foreach ($this->processed_posts as $post_id) { $parent = wp_get_post_parent_id($post_id); if (!in_array($parent, $synced)) { WC_Product_Variable::sync($parent); $synced[] = $parent; } } } // SUCCESS _e('Finished. Import complete.', 'wc_csv_import'); $this->import_end(); exit; break; } $this->footer(); }
/** * Update post meta fields. * * @param WP_Post $post * @param WP_REST_Request $request * @return bool|WP_Error */ protected function update_post_meta_fields($post, $request) { try { $product = wc_get_product($post); // Check for featured/gallery images, upload it and set it. if (isset($request['images'])) { $this->save_product_images($product->id, $request['images']); } // Save product meta fields. $this->save_product_meta($product, $request); // Save variations. if ($product->is_type('variable')) { if (isset($request['variations']) && is_array($request['variations'])) { $this->save_variations_data($product, $request); } else { // Just sync variations. WC_Product_Variable::sync($product->id); WC_Product_Variable::sync_stock_status($product->id); } } return true; } catch (WC_REST_Exception $e) { return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode())); } }
/** * Bulk edit variations via AJAX */ public static function bulk_edit_variations() { ob_start(); check_ajax_referer('bulk-edit-variations', 'security'); // Check permissions again and make sure we have what we need if (!current_user_can('edit_products') || empty($_POST['product_id']) || empty($_POST['bulk_action'])) { die(-1); } global $wpdb; $product_id = absint($_POST['product_id']); $bulk_action = wc_clean($_POST['bulk_action']); $data = !empty($_POST['data']) ? array_map('wc_clean', $_POST['data']) : array(); $variations = array(); if (apply_filters('woocommerce_bulk_edit_variations_need_children', !in_array($bulk_action, array('variable_weight', 'variable_length', 'variable_width', 'variable_height')))) { $variations = get_posts(array('post_parent' => $product_id, 'posts_per_page' => -1, 'post_type' => 'product_variation', 'fields' => 'ids', 'post_status' => array('publish', 'private'))); } switch ($bulk_action) { case 'toggle_enabled': foreach ($variations as $variation_id) { $post_status = get_post_status($variation_id); $new_status = 'private' === $post_status ? 'publish' : 'private'; $wpdb->update($wpdb->posts, array('post_status' => $new_status), array('ID' => $variation_id)); } break; case 'toggle_downloadable': foreach ($variations as $variation_id) { $_downloadable = get_post_meta($variation_id, '_downloadable', true); $is_downloadable = 'no' === $_downloadable ? 'yes' : 'no'; update_post_meta($variation_id, '_downloadable', wc_clean($is_downloadable)); } break; case 'toggle_virtual': foreach ($variations as $variation_id) { $_virtual = get_post_meta($variation_id, '_virtual', true); $is_virtual = 'no' === $_virtual ? 'yes' : 'no'; update_post_meta($variation_id, '_virtual', wc_clean($is_virtual)); } break; case 'toggle_manage_stock': foreach ($variations as $variation_id) { $_manage_stock = get_post_meta($variation_id, '_manage_stock', true); $is_manage_stock = 'no' === $_manage_stock ? 'yes' : 'no'; update_post_meta($variation_id, '_manage_stock', wc_clean($is_manage_stock)); } break; case 'variable_regular_price': case 'variable_sale_price': if (empty($data['value'])) { break; } $field = str_replace('variable', '', $bulk_action); foreach ($variations as $variation_id) { // Price fields $regular_price = '_regular_price' === $field ? $data['value'] : get_post_meta($variation_id, '_regular_price', true); $sale_price = '_sale_price' === $field ? $data['value'] : get_post_meta($variation_id, '_sale_price', true); // Date fields $date_from = get_post_meta($variation_id, '_sale_price_dates_from', true); $date_to = get_post_meta($variation_id, '_sale_price_dates_to', true); $date_from = !empty($date_from) ? date('Y-m-d', $date_from) : ''; $date_to = !empty($date_to) ? date('Y-m-d', $date_to) : ''; _wc_save_product_price($variation_id, $regular_price, $sale_price, $date_from, $date_to); } break; case 'variable_stock': if (empty($data['value'])) { break; } $value = wc_clean($data['value']); foreach ($variations as $variation_id) { if ('yes' === get_post_meta($variation_id, '_manage_stock', true)) { wc_update_product_stock($variation_id, wc_stock_amount($value)); } else { delete_post_meta($variation_id, '_stock'); } } break; case 'variable_weight': case 'variable_length': case 'variable_width': case 'variable_height': if (empty($data['value'])) { break; } $value = wc_clean($data['value']); $field = str_replace('variable', '', $bulk_action); $wpdb->query($wpdb->prepare("\n\t\t\t\t\tUPDATE {$wpdb->postmeta} AS postmeta\n\t\t\t\t\tINNER JOIN {$wpdb->posts} AS posts ON posts.post_parent = %d\n\t\t\t\t\tSET postmeta.meta_value = %s\n\t\t\t\t\tWHERE postmeta.meta_key = '%s'\n\t\t\t\t\tAND postmeta.post_id = posts.ID\n\t\t\t\t ", $product_id, $value, $field)); break; case 'variable_download_limit': case 'variable_download_expiry': if (empty($data['value'])) { break; } $value = wc_clean($data['value']); $field = str_replace('variable', '', $bulk_action); foreach ($variations as $variation_id) { if ('yes' === get_post_meta($variation_id, '_downloadable', true)) { update_post_meta($variation_id, $field, $value); } else { update_post_meta($variation_id, $field, ''); } } break; case 'delete_all': if (isset($data['allowed']) && 'true' === $data['allowed']) { foreach ($variations as $variation_id) { wp_delete_post($variation_id); } } break; case 'variable_regular_price_increase': case 'variable_regular_price_decrease': case 'variable_sale_price_increase': case 'variable_sale_price_decrease': if (empty($data['value'])) { break; } $field = str_replace(array('variable', '_increase', '_decrease'), '', $bulk_action); $operator = 'increase' === substr($bulk_action, -8) ? +1 : -1; foreach ($variations as $variation_id) { // Price fields $regular_price = get_post_meta($variation_id, '_regular_price', true); $sale_price = get_post_meta($variation_id, '_sale_price', true); // Date fields $date_from = get_post_meta($variation_id, '_sale_price_dates_from', true); $date_to = get_post_meta($variation_id, '_sale_price_dates_to', true); $date_from = !empty($date_from) ? date('Y-m-d', $date_from) : ''; $date_to = !empty($date_to) ? date('Y-m-d', $date_to) : ''; if ('%' === substr($data['value'], -1)) { $percent = wc_format_decimal(substr($data['value'], 0, -1)); if ('_regular_price' === $field) { $regular_price += $regular_price / 100 * $percent * $operator; } else { $sale_price += $sale_price / 100 * $percent * $operator; } } else { if ('_regular_price' === $field) { $regular_price += $data['value']; } else { $sale_price += $data['value']; } } _wc_save_product_price($variation_id, $regular_price, $sale_price, $date_from, $date_to); } break; case 'variable_sale_schedule': if (!isset($data['date_from']) && !isset($data['date_to'])) { break; } foreach ($variations as $variation_id) { // Price fields $regular_price = get_post_meta($variation_id, '_regular_price', true); $sale_price = get_post_meta($variation_id, '_sale_price', true); // Date fields $date_from = get_post_meta($variation_id, '_sale_price_dates_from', true); $date_to = get_post_meta($variation_id, '_sale_price_dates_to', true); if ('false' === $data['date_from']) { $date_from = !empty($date_from) ? date('Y-m-d', $date_from) : ''; } else { $date_from = $data['date_from']; } if ('false' === $data['date_to']) { $date_to = !empty($date_to) ? date('Y-m-d', $date_to) : ''; } else { $date_to = $data['date_to']; } _wc_save_product_price($variation_id, $regular_price, $sale_price, $date_from, $date_to); } break; default: do_action('woocommerce_bulk_edit_variations_default', $bulk_action, $data, $product_id, $variations); break; } do_action('woocommerce_bulk_edit_variations', $bulk_action, $data, $product_id, $variations); // Sync and update transients WC_Product_Variable::sync($product_id); wc_delete_product_transients($product_id); die; }
} /* update _price with sale price */ $rows = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE meta_value !='' AND meta_key = %s", $pre_meta_key . '_sale_price')); foreach ($rows as $row) { update_post_meta($row->post_id, $pre_meta_key . '_price', $row->meta_value); } } } /* rename options regions */ delete_option('_oga_wppbc_countries_groups'); add_option('wc_price_based_country_regions', $regions); /* sync variable products */ require_once WC()->plugin_path() . '/includes/class-wc-product-variable.php'; $rows = $wpdb->get_results($wpdb->prepare("SELECT distinct post_parent FROM {$wpdb->posts} where post_type = %s", 'product_variation')); foreach ($rows as $row) { WC_Product_Variable::sync($row->post_parent); } /* rename and update test options */ add_option('wc_price_based_country_test_mode', get_option('wc_price_based_country_debug_mode')); delete_option('wc_price_based_country_debug_mode'); $test_ip = get_option('wc_price_based_country_debug_ip'); if ($test_ip) { $country = WC_Geolocation::geolocate_ip($test_ip); add_option('wc_price_based_country_test_country', $country['country']); } delete_option('wc_price_based_country_debug_ip'); /* unschedule geoip donwload */ if (wp_next_scheduled('wcpbc_update_geoip')) { wp_clear_scheduled_hook('wcpbc_update_geoip'); } delete_option('wc_price_based_country_update_geoip');
/** * Edit a product * * @since 2.2 * @param int $id the product ID * @param array $data * @return array */ public function edit_product($id, $data) { try { if (!isset($data['product'])) { throw new WC_API_Exception('woocommerce_api_missing_product_data', sprintf(__('No %1$s data specified to edit %1$s', 'woocommerce'), 'product'), 400); } $data = $data['product']; $id = $this->validate_request($id, 'product', 'edit'); if (is_wp_error($id)) { return $id; } $product = wc_get_product($id); $data = apply_filters('woocommerce_api_edit_product_data', $data, $this); // Product title. if (isset($data['title'])) { $product->set_name(wc_clean($data['title'])); } // Product name (slug). if (isset($data['name'])) { $product->set_slug(wc_clean($data['name'])); } // Product status. if (isset($data['status'])) { $product->set_status(wc_clean($data['status'])); } // Product short description. if (isset($data['short_description'])) { // Enable short description html tags. $post_excerpt = isset($data['enable_html_short_description']) && true === $data['enable_html_short_description'] ? $data['short_description'] : wc_clean($data['short_description']); $product->set_short_description($post_excerpt); } // Product description. if (isset($data['description'])) { // Enable description html tags. $post_content = isset($data['enable_html_description']) && true === $data['enable_html_description'] ? $data['description'] : wc_clean($data['description']); $product->set_description($post_content); } // Validate the product type. if (isset($data['type']) && !in_array(wc_clean($data['type']), array_keys(wc_get_product_types()))) { throw new WC_API_Exception('woocommerce_api_invalid_product_type', sprintf(__('Invalid product type - the product type must be any of these: %s', 'woocommerce'), implode(', ', array_keys(wc_get_product_types()))), 400); } // Check for featured/gallery images, upload it and set it. if (isset($data['images'])) { $product = $this->save_product_images($product, $data['images']); } // Save product meta fields. $product = $this->save_product_meta($product, $data); // Save variations. if ($product->is_type('variable')) { if (isset($data['variations']) && is_array($data['variations'])) { $this->save_variations($product, $data); } else { // Just sync variations. $product = WC_Product_Variable::sync($product, false); } } $product->save(); do_action('woocommerce_api_edit_product', $id, $data); // Clear cache/transients. wc_delete_product_transients($id); return $this->get_product($id); } catch (WC_Data_Exception $e) { return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode())); } catch (WC_API_Exception $e) { return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode())); } }
/** * Updates product * * @access public * @param int $ID * @param array $data * @return void */ public static function updateProduct($ID, $data) { global $wpdb; $redirect = false; if (empty($ID)) { $ID = self::addProduct(); $redirect = true; } $args = array('ID' => $ID); //title $args['post_title'] = themex_value('title', $data); if (empty($args['post_title'])) { ThemexInterface::$messages[] = __('Product name field is required', 'makery'); } //category if (themex_taxonomy('product_cat')) { $category = intval(themex_value('category', $data)); if (empty($category)) { ThemexInterface::$messages[] = __('Item category field is required', 'makery'); } else { $term = get_term($category, 'product_cat'); if (empty($term)) { ThemexInterface::$messages[] = __('This item category does not exist', 'makery'); } else { wp_set_object_terms($ID, $term->name, 'product_cat'); } } } //tags if (!ThemexCore::checkOption('product_tags')) { $tags = sanitize_text_field(themex_value('tags', $data)); $tags = array_map('trim', explode(',', $tags)); if (!empty($tags)) { $tag = reset($tags); if (empty($tag)) { wp_set_object_terms($ID, null, 'product_tag'); } else { wp_set_object_terms($ID, $tags, 'product_tag'); } } } //type $virtual = 'no'; $ending = 'yes'; if (themex_value('type', $data) == 'virtual' || ThemexCore::getOption('product_type', 'all') == 'virtual') { $virtual = 'yes'; $ending = 'no'; } update_post_meta($ID, '_virtual', $virtual); update_post_meta($ID, '_downloadable', $virtual); update_post_meta($ID, '_manage_stock', $ending); update_post_meta($ID, '_stock_status', 'instock'); update_post_meta($ID, '_visibility', 'visible'); //price if (!ThemexCore::checkOption('product_price')) { if (isset($data['regular_price'])) { $regular_price = round(floatval(themex_value('regular_price', $data)), 2); update_post_meta($ID, '_price', $regular_price); update_post_meta($ID, '_regular_price', $regular_price); } if (isset($data['sale_price'])) { $sale_price = round(floatval(themex_value('sale_price', $data)), 2); if (empty($sale_price)) { $sale_price = ''; } update_post_meta($ID, '_sale_price', $sale_price); if (!empty($sale_price)) { update_post_meta($ID, '_price', $sale_price); } } } //stock if ($virtual == 'no' && isset($data['stock'])) { $stock = intval(themex_value('stock', $data)); update_post_meta($ID, '_stock', $stock); } //shipping if (themex_taxonomy('product_shipping_class')) { $class = intval(themex_value('shipping_class', $data)); $term = get_term($class, 'product_shipping_class'); if (empty($class)) { wp_set_object_terms($ID, '', 'product_shipping_class'); } else { if (!is_wp_error($term)) { wp_set_object_terms($ID, $term->name, 'product_shipping_class'); } } } //file if ($virtual == 'yes' && isset($_FILES['file'])) { $files = get_post_meta($ID, '_downloadable_files', true); if (empty($files) || !is_array($files)) { $files = array(); } $extensions = array_map('trim', explode(',', ThemexCore::getOption('product_extensions', 'zip'))); $attachment = ThemexCore::addFile($_FILES['file'], $extensions); if (isset($attachment['ID']) && $attachment['ID'] != 0) { $file = array_shift($files); if (is_array($file) && isset($file['file'])) { $current = $wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE guid='%s'", $file['file'])); if (!empty($current)) { wp_delete_attachment($current); } } $files = array_merge(array(md5($attachment['guid']) => array('name' => themex_filename($attachment['guid']), 'file' => $attachment['guid'])), $files); update_post_meta($ID, '_downloadable_files', $files); } } //attributes if (!ThemexCore::checkOption('product_attributes')) { $attributes = self::getAttributes(); $options = get_post_meta($ID, '_product_attributes', true); if (empty($options) || !is_array($options)) { $options = array(); } foreach ($attributes as $attribute) { if (isset($data[$attribute['name']]) && taxonomy_exists($attribute['name'])) { $name = stripslashes(strip_tags($data[$attribute['name']])); $value = sanitize_title($data[$attribute['name']]); if ($attribute['type'] != 'select' || (isset($attribute['options'][$value]) || $value == '')) { if ($attribute['type'] == 'select') { wp_set_object_terms($ID, $value, $attribute['name']); } else { wp_set_object_terms($ID, $name, $attribute['name']); } if ($value != '') { $options[$attribute['name']] = array('name' => $attribute['name'], 'value' => $value, 'position' => '0', 'is_visible' => 1, 'is_variation' => 0, 'is_taxonomy' => 1); } else { unset($options[$attribute['name']]); } } } } update_post_meta($ID, '_product_attributes', $options); } //options $option_names = themex_array('option_names', $data); $option_values = themex_array('option_values', $data); if (is_array($option_names) && is_array($option_values)) { $slugs = array(); $options = get_post_meta($ID, '_product_attributes', true); if (empty($options) || !is_array($options)) { $options = array(); } foreach ($option_names as $index => $name) { if (isset($option_values[$index])) { $name = sanitize_text_field($name); $slug = sanitize_title($name); $value = implode('|', array_map('trim', explode(',', sanitize_text_field($option_values[$index])))); if (!empty($slug) && !empty($name) && !empty($value)) { $slugs[] = $slug; $options[$slug] = array('name' => $name, 'value' => $value, 'position' => '0', 'is_visible' => 0, 'is_variation' => 1, 'is_taxonomy' => 0); } } } foreach ($options as $slug => $option) { if (isset($option['is_taxonomy']) && empty($option['is_taxonomy']) && !in_array($slug, $slugs)) { unset($options[$slug]); } } update_post_meta($ID, '_product_attributes', $options); } //variations $variation_ids = themex_array('variation_ids', $data); $variation_stocks = themex_array('variation_stocks', $data); $variation_regular_prices = themex_array('variation_regular_prices', $data); $variation_sale_prices = themex_array('variation_sale_prices', $data); if (is_array($variation_ids) && is_array($variation_stocks) && is_array($variation_regular_prices) && is_array($variation_sale_prices)) { $variations = self::getVariations($ID, array('fields' => 'ids')); $new_variations = array(); foreach ($variation_ids as $index => $variation_id) { if (isset($variation_stocks[$index]) && isset($variation_regular_prices[$index]) && isset($variation_sale_prices[$index])) { $variation_id = intval($variation_id); $stock = intval($variation_stocks[$index]); $regular_price = intval($variation_regular_prices[$index]); $sale_price = $variation_sale_prices[$index]; if (!empty($stock) && (empty($variation_id) || !in_array($variation_id, $variations))) { $variation_id = wp_insert_post(array('post_type' => 'product_variation', 'post_parent' => $ID, 'post_status' => 'publish', 'post_author' => 1, 'post_title' => sprintf(__('Variation #%s', 'makery'), count($variations) + 1))); } if (!empty($variation_id)) { $new_variations[] = $variation_id; if (($variation_index = array_search($variation_id, $variations)) !== false) { unset($variations[$variation_index]); } update_post_meta($variation_id, '_manage_stock', 'yes'); update_post_meta($variation_id, '_stock_status', 'instock'); update_post_meta($variation_id, '_stock', $stock); update_post_meta($variation_id, '_regular_price', $regular_price); update_post_meta($variation_id, '_price', $regular_price); if ($sale_price != '') { update_post_meta($variation_id, '_sale_price', intval($sale_price)); update_post_meta($variation_id, '_price', intval($sale_price)); } $options = self::getOptions($ID); foreach ($options as $name => $option) { $values = themex_array('variation_' . $name . 's', $data); $items = array_map('trim', explode(',', $option['value'])); if (is_array($values) && isset($values[$index]) && (in_array($values[$index], $items) || $values[$index] == '')) { update_post_meta($variation_id, 'attribute_' . $name, $values[$index]); } } } } } set_transient('wc_product_children_ids_' . $ID . WC_Cache_Helper::get_transient_version('product'), $new_variations, 84600 * 365); foreach ($variations as $variation) { wp_delete_post($variation, true); } WC_Product_Variable::sync($ID); if (empty($new_variations)) { wp_set_object_terms($ID, 'simple', 'product_type'); } else { wp_set_object_terms($ID, 'variable', 'product_type'); } } //content $args['post_content'] = trim(themex_value('content', $data)); $args['post_content'] = wp_kses($args['post_content'], array('strong' => array(), 'em' => array(), 'a' => array('href' => array(), 'title' => array(), 'target' => array()), 'p' => array(), 'br' => array())); if (empty(ThemexInterface::$messages)) { $status = get_post_status($ID); if ($status == 'draft') { $args['post_status'] = 'pending'; if (ThemexCore::checkOption('shop_approve')) { $args['post_status'] = 'publish'; } $redirect = true; } ThemexInterface::$messages[] = __('Product has been successfully saved', 'makery'); $_POST['success'] = true; } //update post wp_update_post($args); if ($redirect) { wp_redirect(ThemexCore::getURL('shop-product', $ID)); exit; } }
function woo_insert_update_data($post) { global $wpdb, $woocommerce; $_POST = $post; // Fix: PHP 5.4 $editable_fields = array('_billing_first_name', '_billing_last_name', '_billing_email', '_billing_address_1', '_billing_address_2', '_billing_city', '_billing_state', '_billing_country', '_billing_postcode', '_billing_phone', '_shipping_first_name', '_shipping_last_name', '_shipping_address_1', '_shipping_address_2', '_shipping_city', '_shipping_state', '_shipping_country', '_shipping_postcode', 'order_status'); $new_product = json_decode($_POST['edited']); $edited_prod_ids = array(); $edited_prod_slug = array(); if (!empty($new_product)) { foreach ($new_product as $product) { $edited_prod_ids[] = $product->id; } } //Code for getting the product slugs if (!empty($edited_prod_ids)) { $query_prod_slug = "SELECT id, post_name\n FROM {$wpdb->prefix}posts\n WHERE id IN (" . implode(",", $edited_prod_ids) . ")"; $results_prod_slug = $wpdb->get_results($query_prod_slug, 'ARRAY_A'); $prod_slug_rows = $wpdb->num_rows; if ($prod_slug_rows > 0) { foreach ($results_prod_slug as $result_prod_slug) { $edited_prod_slug[$result_prod_slug['id']] = $result_prod_slug['post_name']; } } } $product_descrip = array(); if (!empty($edited_prod_ids)) { $query_descrip = "SELECT id, post_content, post_excerpt\n FROM {$wpdb->prefix}posts\n WHERE id IN (" . implode(",", $edited_prod_ids) . ")\n GROUP BY id"; $results_descrip = $wpdb->get_results($query_descrip, 'ARRAY_A'); $descrip_rows = $wpdb->num_rows; if ($descrip_rows > 0) { foreach ($results_descrip as $result_descrip) { $product_descrip[$result_descrip['id']] = array(); $product_descrip[$result_descrip['id']]['post_content'] = $result_descrip['post_content']; $product_descrip[$result_descrip['id']]['post_excerpt'] = $result_descrip['post_excerpt']; } } } $result = array('productId' => array()); $post_meta_info = array(); // To get distinct meta_key for Simple Products. => Executed only once $post_meta_info = $wpdb->get_col("SELECT distinct postmeta.meta_key FROM {$wpdb->prefix}postmeta AS postmeta INNER JOIN {$wpdb->prefix}posts AS posts on posts.ID = postmeta.post_id WHERE posts.post_type='product' AND posts.post_status IN ('publish', 'pending', 'draft')"); // To get distinct meta_key for Child Products i.e. Variations. => Executed only once $post_meta_info_variations = $wpdb->get_col("SELECT distinct postmeta.meta_key FROM {$wpdb->prefix}postmeta AS postmeta INNER JOIN {$wpdb->prefix}posts AS posts on posts.ID = postmeta.post_id WHERE posts.post_type='product_variation' AND posts.post_status IN ('publish', 'pending', 'draft') AND posts.post_parent > 0"); // meta_key required for new products, that are entered through Smart Manager // if (count($post_meta_info) <= 0 || count($post_meta_info) < 23) { $post_meta_reqd_keys = array('_edit_last', '_edit_lock', '_regular_price', '_sale_price', '_weight', '_length', '_width', '_height', '_tax_status', '_tax_class', '_stock_status', '_visibility', '_featured', '_sku', '_product_attributes', '_downloadable', '_virtual', '_sale_price_dates_from', '_sale_price_dates_to', '_price', '_stock', '_manage_stock', '_backorders'); // } $post_meta_info = array_unique(array_merge($post_meta_info, $post_meta_reqd_keys)); // for adding the meta_keys if not present if (is_foreachable($new_product)) { $woo_prod_obj = ''; // if ($_POST['SM_IS_WOO21'] == "true" || $_POST['SM_IS_WOO22'] == "true") { // $woo_prod_obj = new WC_Product_Variable(); // } foreach ($new_product as $obj) { if ($_POST['active_module'] == 'Products') { $price = get_price($obj->_regular_price, $obj->_sale_price, $obj->_sale_price_dates_from, $obj->_sale_price_dates_to); $post_content = $post_excerpt = ''; if (isset($obj->id) && $obj->id != '') { //Code for handling the description and addl. description $post_content = !empty($product_descrip[$obj->id]['post_content']) ? $product_descrip[$obj->id]['post_content'] : ''; $post_excerpt = !empty($product_descrip[$obj->id]['post_excerpt']) ? $product_descrip[$obj->id]['post_excerpt'] : ''; $product_custom_fields = get_post_custom($obj->id); // woocommerce uses this method to load product's details before creating WooCommerce Product Object $post = get_post($obj->id); // woocommerce load posts from cache $terms = wp_get_object_terms($obj->id, 'product_type', array('fields' => 'names')); // woocommerce gets product_type using this method $product_type = isset($terms[0]) ? sanitize_title($terms[0]) : 'simple'; if ($product_type == 'variable') { // To unset price fields for Parent Products having variations $obj->_regular_price = ''; $obj->_sale_price = ''; $obj->_price = $price = $product_custom_fields['_min_variation_sale_price'][0] === '' || $product_custom_fields['_min_variation_regular_price'][0] < $product_custom_fields['_min_variation_sale_price'][0] ? $product_custom_fields['_min_variation_regular_price'][0] : $product_custom_fields['_min_variation_sale_price'][0]; } } else { //to not include current date for sales price for new product $obj->_sale_price_dates_from = ''; $obj->_sale_price_dates_to = ''; $price = get_price($obj->_regular_price, $obj->_sale_price, $obj->_sale_price_dates_from, $obj->_sale_price_dates_to); } if (!(empty($obj->post_parent) || $obj->post_parent == '')) { $id = $obj->post_parent; $product_type_parent = wp_get_object_terms($id, 'product_type', array('fields' => 'slugs')); } if ($_POST['SM_IS_WOO16'] == "true") { if ($obj->post_parent > 0 && $product_type_parent[0] != "grouped") { $price = $obj->_regular_price; } } // create an array to be used for updating product's details. add modified value from Smart Manager & rest same as in original post $postarr = array('ID' => isset($obj->id) ? $obj->id : '', 'post_author' => isset($post->post_author) ? $post->post_author : '', 'post_content' => $post_content, 'post_title' => isset($obj->post_title) ? $obj->post_title : '', 'post_name' => !empty($obj->id) && !empty($edited_prod_slug[$obj->id]) ? $edited_prod_slug[$obj->id] : '', 'post_excerpt' => $post_excerpt, 'post_date' => isset($post->post_date) ? $post->post_date : '', 'post_date_gmt' => isset($post->post_date_gmt) ? $post->post_date_gmt : '', 'post_status' => isset($obj->post_status) ? $obj->post_status : '', 'comment_status' => isset($post->comment_status) ? $post->comment_status : 'open', 'ping_status' => isset($post->ping_status) ? $post->ping_status : 'open', 'post_parent' => isset($obj->post_parent) ? $obj->post_parent : $post->post_parent, 'guid' => isset($post->guid) ? $post->guid : site_url() . '/?post_type=product&p=' . $post->ID, 'menu_order' => isset($post->menu_order) ? $post->menu_order : 0, 'post_type' => isset($post->post_type) ? $post->post_type : 'product', 'comment_count' => isset($post->comment_count) ? $post->comment_count : 0, 'ancestors' => isset($post->ancestors) ? $post->ancestors : array(), 'filter' => isset($post->filter) ? $post->filter : 'raw', '_product_attributes' => isset($obj->_product_attributes) ? $obj->_product_attributes : serialize(array()), 'user_ID' => 1, 'action' => 'editpost', 'originalaction' => 'editpost', 'original_post_status' => 'auto-draft', 'auto_draft' => 1, 'post_ID' => $obj->id, 'hidden_post_status' => 'draft', 'hidden_post_visibility' => 'public', '_visibility' => isset($obj->_visibility) ? $obj->_visibility : 'visible', 'original_publish' => 'Publish', 'publish' => 'Publish', 'newproduct_cat' => 'New Product Category Name', 'newproduct_cat_parent' => -1, 'content' => $post_content, 'product-type' => isset($product_type) ? $product_type : 'simple', '_virtual' => isset($obj->_virtual) ? $obj->_virtual : 'no', '_downloadable' => isset($obj->_downloadable) ? $obj->_downloadable : 'no', '_featured' => isset($obj->_featured) ? $obj->_featured : 'no', '_sku' => isset($obj->_sku) ? $obj->_sku : '', '_price' => $price, '_regular_price' => isset($obj->_regular_price) ? $obj->_regular_price : '', '_sale_price' => isset($obj->_sale_price) ? $obj->_sale_price : '', '_sale_price_dates_from' => !empty($obj->_sale_price_dates_from) ? strtotime($obj->_sale_price_dates_from) : '', '_sale_price_dates_to' => !empty($obj->_sale_price_dates_to) ? strtotime($obj->_sale_price_dates_to) : '', '_weight' => isset($obj->_weight) ? $obj->_weight : '', '_length' => isset($obj->_length) ? $obj->_length : '', '_width' => isset($obj->_width) ? $obj->_width : '', '_height' => isset($obj->_height) ? $obj->_height : '', '_tax_status' => isset($obj->_tax_status) ? $obj->_tax_status : 'taxable', '_stock' => isset($obj->_stock) ? $obj->_stock : '', 'excerpt' => $post_excerpt, 'advanced_view' => 1); if (defined('SMPRO') && SMPRO === true || $obj->id == '') { $postarr['_tax_class'] = isset($obj->_tax_class) ? $obj->_tax_class : ''; $postarr['_stock_status'] = isset($obj->_stock_status) ? $obj->_stock_status : 'instock'; $postarr['_manage_stock'] = isset($obj->_manage_stock) ? $obj->_manage_stock : 'no'; $postarr['_backorders'] = isset($obj->_backorders) ? $obj->_backorders : 'no'; } //Code to handle inline editing for custom columns foreach ($obj as $key => $value) { if (!isset($postarr[$key])) { $postarr[$key] = !empty($value) ? $value : ''; } } if ($obj->post_parent == 0 && $obj->product_type != 'variable' || $product_type_parent[0] == "grouped") { $post_id = wp_insert_post($postarr); $post_meta_key = $post_meta_info; } else { $parent_id = $postarr['post_parent']; $post_id = $postarr['ID']; $post_meta_key = $post_meta_info_variations; } array_push($result['productId'], $post_id); foreach ($post_meta_key as $object) { // ================================================================================================ // Code for enabling negative values for inline editing // ================================================================================================ // if ( $object == '_sale_price' || $object == '_price' || $object == '_regular_price' ) { // update_post_meta($wpdb->_real_escape($post_id), $wpdb->_real_escape($object), $wpdb->_real_escape($postarr[$object]) ); // continue; // } // ================================================================================================ if (isset($postarr[$object]) && $postarr[$object] > -1) { // to skip query for blank value //Code to handle the condition for the attribute visibility on product page issue while save action if ($object == '_product_attributes' && isset($product_custom_fields['_product_attributes'][0])) { continue; } if (empty($obj->id) || $obj->id == '') { $query = "INSERT INTO {$wpdb->prefix}postmeta(post_id,meta_key,meta_value) values(" . $wpdb->_real_escape($post_id) . ", '" . $wpdb->_real_escape($object) . "', '" . $wpdb->_real_escape($postarr[$object]) . "')"; $var = $wpdb->query($query); wp_set_object_terms($post_id, 'simple', 'product_type'); } else { //$query = "UPDATE {$wpdb->prefix}postmeta SET meta_value = '".$wpdb->_real_escape($postarr[$object])."' WHERE post_id = " . $wpdb->_real_escape($post_id) . " AND meta_key = '" . $wpdb->_real_escape($object) . "'"; update_post_meta($wpdb->_real_escape($post_id), $wpdb->_real_escape($object), $wpdb->_real_escape($postarr[$object])); if ($object == '_stock') { if ($_POST['SM_IS_WOO21'] == "true" || $_POST['SM_IS_WOO22'] == "true") { $woo_version = defined('WOOCOMMERCE_VERSION') ? WOOCOMMERCE_VERSION : $woocommerce->version; if ($postarr['post_parent'] > 0) { $woo_prod_obj_stock_status = new WC_Product_Variation($post_id); } else { $woo_prod_obj_stock_status = new WC_Product($post_id); } if (version_compare($woo_version, '2.4', ">=")) { $woo_prod_obj_stock_status->check_stock_status(); } else { $woo_prod_obj_stock_status->set_stock($wpdb->_real_escape($postarr[$object])); } } } } } } //Code For updating the parent price of the product if ($parent_id > 0) { if ($_POST['SM_IS_WOO21'] == "true" || $_POST['SM_IS_WOO22'] == "true") { WC_Product_Variable::sync($parent_id); delete_transient('wc_product_children_' . $parent_id); //added in woo24 } else { variable_price_sync($parent_id); } } } elseif ($_POST['active_module'] == 'Orders') { foreach ($obj as $key => $value) { if (in_array($key, $editable_fields)) { if ($key == 'order_status') { // $term_taxonomy_id = get_term_taxonomy_id ( $value ); // $query = "UPDATE {$wpdb->prefix}term_relationships SET term_taxonomy_id = " . $wpdb->_real_escape($term_taxonomy_id) . " WHERE object_id = " . $wpdb->_real_escape($obj->id) . ";"; // if ( $value == 'processing' || $value == 'completed' ) { $order = new WC_Order($obj->id); $order->update_status($value); // } } else { $query = "UPDATE {$wpdb->prefix}postmeta SET meta_value = '" . $wpdb->_real_escape($value) . "' WHERE post_id = " . $wpdb->_real_escape($obj->id) . " AND meta_key = '" . $wpdb->_real_escape($key) . "';"; $wpdb->query($query); } } } } elseif ($_POST['active_module'] == 'Customers') { //Query to get the email and customer_user for all the selected ids $query_email = "SELECT DISTINCT(GROUP_CONCAT( meta_value\n ORDER BY meta_id SEPARATOR '###' ) )AS meta_value,\n GROUP_CONCAT(distinct meta_key\n ORDER BY meta_id SEPARATOR '###' ) AS meta_key\n FROM {$wpdb->prefix}postmeta \n WHERE meta_key in ('_billing_email','_customer_user') \n AND post_id={$wpdb->_real_escape}({$obj->id})"; $result_email = $wpdb->get_results($query_email, 'ARRAY_A'); $email = ""; $users = ""; for ($i = 0; $i < sizeof($result_email); $i++) { $meta_key = explode("###", $result_email[$i]['meta_key']); $meta_value = explode("###", $result_email[$i]['meta_value']); $postmeta[$i] = array_combine($meta_key, $meta_value); $email[$i] = $postmeta[$i]['_billing_email']; $users[$i] = $postmeta[$i]['_customer_user']; unset($meta_key); unset($meta_value); } $email = "'" . implode("','", $email) . "'"; $users = implode(",", $users); //Query for getting al the post ids using the email id if ($users == 0) { $query_ids = "SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_value = {$email}"; $id = implode(", ", $wpdb->get_col($query_ids)); } foreach ($obj as $key => $value) { if (in_array($key, $editable_fields)) { if ($users == 0) { $query = "UPDATE {$wpdb->prefix}postmeta SET meta_value = '" . $wpdb->_real_escape($value) . "' WHERE post_id IN ({$id}) AND meta_key = '" . $wpdb->_real_escape($key) . "';"; } elseif ($users > 0) { $key = substr($key, 1); //removing the first underscore from the column name as the columns for p_usermeta are different from that of wp_postmeta //Code for updating the email of the Customer in the wp_users Table if ($key == "billing_email") { $query = "UPDATE {$wpdb->prefix}users SET user_email = '" . $wpdb->_real_escape($value) . "' WHERE id IN ({$users}) ;"; $wpdb->query($query); } $query = "UPDATE {$wpdb->prefix}usermeta SET meta_value = '" . $wpdb->_real_escape($value) . "' WHERE user_id IN ({$users}) AND meta_key = '" . $wpdb->_real_escape($key) . "';"; } $wpdb->query($query); } } } if (empty($obj->id) || $obj->id == '') { if (!isset($result['inserted'])) { $result['inserted'] = 1; $result['insertCnt'] = 1; } else { $result['insertCnt']++; } } else { if (!isset($result['updated'])) { $result['updated'] = 1; $result['updateCnt'] = 1; } else { $result['updateCnt']++; } } } } else { $result = array('inserted' => 0, 'insertCnt' => 0, 'updated' => 0, 'updateCnt' => 0); } //Clearing the transients to handle the proper functioning of the widgets if ($_POST['SM_IS_WOO21'] == "true" || $_POST['SM_IS_WOO22'] == "true") { wc_delete_product_transients(); } else { $woocommerce->clear_product_transients(); } return $result; }
/** * Bulk edit. * * @param integer $post_id * @param WC_Product $product */ public function bulk_edit_save($post_id, $product) { $old_regular_price = $product->get_regular_price(); $old_sale_price = $product->get_sale_price(); // Save fields if (!empty($_REQUEST['change_weight']) && isset($_REQUEST['_weight'])) { $product->set_weight(wc_clean(stripslashes($_REQUEST['_weight']))); } if (!empty($_REQUEST['change_dimensions'])) { if (isset($_REQUEST['_length'])) { $product->set_length(wc_clean(stripslashes($_REQUEST['_length']))); } if (isset($_REQUEST['_width'])) { $product->set_width(wc_clean(stripslashes($_REQUEST['_width']))); } if (isset($_REQUEST['_height'])) { $product->set_height(wc_clean(stripslashes($_REQUEST['_height']))); } } if (!empty($_REQUEST['_tax_status'])) { $product->set_tax_status(wc_clean($_REQUEST['_tax_status'])); } if (!empty($_REQUEST['_tax_class'])) { $tax_class = wc_clean($_REQUEST['_tax_class']); if ('standard' == $tax_class) { $tax_class = ''; } $product->set_tax_class($tax_class); } if (!empty($_REQUEST['_shipping_class'])) { $shipping_class = '_no_shipping_class' == $_REQUEST['_shipping_class'] ? '' : wc_clean($_REQUEST['_shipping_class']); $shipping_class_id = $data_store->get_shipping_class_id_by_slug($shipping_class); if ($shipping_class_id) { $product->set_shipping_class_id($shipping_class_id); } } if (!empty($_REQUEST['_visibility'])) { $product->set_catalog_visibility(wc_clean($_REQUEST['_visibility'])); } if (!empty($_REQUEST['_featured'])) { $product->set_featured(stripslashes($_REQUEST['_featured'])); } // Sold Individually if (!empty($_REQUEST['_sold_individually'])) { if ('yes' === $_REQUEST['_sold_individually']) { $product->set_sold_individually('yes'); } else { $product->set_sold_individually(''); } } // Handle price - remove dates and set to lowest $change_price_product_types = apply_filters('woocommerce_bulk_edit_save_price_product_types', array('simple', 'external')); $can_product_type_change_price = false; foreach ($change_price_product_types as $product_type) { if ($product->is_type($product_type)) { $can_product_type_change_price = true; break; } } if ($can_product_type_change_price) { $price_changed = false; if (!empty($_REQUEST['change_regular_price'])) { $change_regular_price = absint($_REQUEST['change_regular_price']); $regular_price = esc_attr(stripslashes($_REQUEST['_regular_price'])); switch ($change_regular_price) { case 1: $new_price = $regular_price; break; case 2: if (strstr($regular_price, '%')) { $percent = str_replace('%', '', $regular_price) / 100; $new_price = $old_regular_price + round($old_regular_price * $percent, wc_get_price_decimals()); } else { $new_price = $old_regular_price + $regular_price; } break; case 3: if (strstr($regular_price, '%')) { $percent = str_replace('%', '', $regular_price) / 100; $new_price = max(0, $old_regular_price - round($old_regular_price * $percent, wc_get_price_decimals())); } else { $new_price = max(0, $old_regular_price - $regular_price); } break; default: break; } if (isset($new_price) && $new_price != $old_regular_price) { $price_changed = true; $new_price = round($new_price, wc_get_price_decimals()); $product->set_regular_price($new_price); } } if (!empty($_REQUEST['change_sale_price'])) { $change_sale_price = absint($_REQUEST['change_sale_price']); $sale_price = esc_attr(stripslashes($_REQUEST['_sale_price'])); switch ($change_sale_price) { case 1: $new_price = $sale_price; break; case 2: if (strstr($sale_price, '%')) { $percent = str_replace('%', '', $sale_price) / 100; $new_price = $old_sale_price + $old_sale_price * $percent; } else { $new_price = $old_sale_price + $sale_price; } break; case 3: if (strstr($sale_price, '%')) { $percent = str_replace('%', '', $sale_price) / 100; $new_price = max(0, $old_sale_price - $old_sale_price * $percent); } else { $new_price = max(0, $old_sale_price - $sale_price); } break; case 4: if (strstr($sale_price, '%')) { $percent = str_replace('%', '', $sale_price) / 100; $new_price = max(0, $product->regular_price - $product->regular_price * $percent); } else { $new_price = max(0, $product->regular_price - $sale_price); } break; default: break; } if (isset($new_price) && $new_price != $old_sale_price) { $price_changed = true; $new_price = !empty($new_price) || '0' === $new_price ? round($new_price, wc_get_price_decimals()) : ''; $product->set_sale_price($new_price); } } if ($price_changed) { $product->set_date_on_sale_to(''); $product->set_date_on_sale_from(''); if ($product->get_regular_price() < $product->get_sale_price()) { $product->set_sale_price(''); } } } // Handle Stock Data $was_managing_stock = $product->get_manage_stock() ? 'yes' : 'no'; $stock_status = $product->get_stock_status(); $backorders = $product->get_backorders(); $backorders = !empty($_REQUEST['_backorders']) ? wc_clean($_REQUEST['_backorders']) : $backorders; $stock_status = !empty($_REQUEST['_stock_status']) ? wc_clean($_REQUEST['_stock_status']) : $stock_status; if (!empty($_REQUEST['_manage_stock'])) { $manage_stock = 'yes' === wc_clean($_REQUEST['_manage_stock']) && 'grouped' !== $product->product_type ? 'yes' : 'no'; } else { $manage_stock = $was_managing_stock; } $stock_amount = 'yes' === $manage_stock && isset($_REQUEST['_change_stock']) ? wc_stock_amount($_REQUEST['_change_stock']) : ''; if ('yes' === get_option('woocommerce_manage_stock')) { // Apply product type constraints to stock status if ($product->is_type('external')) { // External always in stock $stock_status = 'instock'; } elseif ($product->is_type('variable')) { // Stock status is always determined by children foreach ($product->get_children() as $child_id) { $child = wc_get_product($child_id); if (!$product->get_manage_stock()) { $child->set_stock_status($stock_status); $child->save(); } } $product = WC_Product_Variable::sync($product, false); } $product->set_manage_stock($manage_stock); $product->set_backorders($backorders); $product->save(); if (!$product->is_type('variable')) { wc_update_product_stock_status($post_id, $stock_status); } wc_update_product_stock($post_id, $stock_amount); } else { $product->save(); wc_update_product_stock_status($post_id, $stock_status); } do_action('woocommerce_product_bulk_edit_save', $product); }
update_post_meta($variation_id, '_download_expiry', ""); update_post_meta($variation_id, '_downloadable_files', ""); update_post_meta($variation_id, '_variation_description', ""); update_post_meta($variation_id, 'attribute_' . $size_tax, strtolower($s)); $i++; $k++; $wpdb->update($wpdb->posts, array('post_status' => 'publish', 'post_title' => 'Variación #' . $variation_id . ' de ' . $title, 'menu_order' => $i), array('ID' => $variation_id)); delete_post_meta($variation_id, '_backorders'); delete_post_meta($variation_id, '_stock'); update_post_meta($variation_id, '_sale_price_dates_from', ''); update_post_meta($variation_id, '_sale_price_dates_to', ''); do_action('woocommerce_save_product_variation', $variation_id); do_action('woocommerce_update_product_variation', $variation_id); } } WC_Product_Variable::sync($post_id); } /*****************************************************************************/ //$variation_color = wp_get_attachment_image_src(current($images_id) , array(400,400)); /*$extract = new ColorExtractor(); $ex = $extract->getColors($variation_color[0], 9, 255, "hex"); $count = count($ex); echo json_encode(array( "url" => $guid, "message" => "EN ESTA CAMISA EXISTEN " . $count . " TIPOS DE COLORES" )); return;*/ echo $guid;