/** * Clear the product/shop transients cache. * * ## EXAMPLES * * wp wc tool clear_transients * * @since 2.5.0 */ public function clear_transients($args, $assoc_args) { wc_delete_product_transients(); wc_delete_shop_order_transients(); WC_Cache_Helper::get_transient_version('shipping', true); WP_CLI::success('Product transients and shop order transients were cleared.'); }
/** * Save Meta Box * * The function to be called to save the meta box options. * * @param $post_id object the current product id * @param $post object the current product * @since 1.0.0 * @author Alberto Ruggiero * @return void */ public static function save($post_id, $post) { global $wpdb; $product_type = empty($_POST['product-type']) ? 'simple' : sanitize_title(stripslashes($_POST['product-type'])); $catalog_mode = isset($_POST['_ywctm_exclude_catalog_mode']) ? 'yes' : 'no'; $hide_price = isset($_POST['_ywctm_exclude_hide_price']) ? 'yes' : 'no'; update_post_meta($post_id, '_ywctm_exclude_catalog_mode', $catalog_mode); update_post_meta($post_id, '_ywctm_exclude_hide_price', $hide_price); do_action('woocommerce_process_product_meta_' . $product_type, $post_id); // Clear cache/transients wc_delete_product_transients($post_id); }
/** * Sync grouped products with the children lowest price (so they can be sorted by price accurately). * * @access public * @return void */ public function grouped_product_sync() { global $wpdb, $woocommerce; if (!$this->get_parent()) { return; } $children_by_price = get_posts(array('post_parent' => $this->get_parent(), 'orderby' => 'meta_value_num', 'order' => 'asc', 'meta_key' => '_price', 'posts_per_page' => 1, 'post_type' => 'product', 'fields' => 'ids')); if ($children_by_price) { foreach ($children_by_price as $child) { $child_price = get_post_meta($child, '_price', true); update_post_meta($this->get_parent(), '_price', $child_price); } } wc_delete_product_transients($this->id); }
/** * Test wc_delete_product_transients() * * @since 2.4 */ public function test_wc_delete_product_transients() { // Create product $product = \WC_Helper_Product::create_simple_product(); update_post_meta($product->id, '_regular_price', wc_format_decimal(10)); update_post_meta($product->id, '_price', wc_format_decimal(5)); update_post_meta($product->id, '_sale_price', wc_format_decimal(5)); update_post_meta($product->id, '_featured', 'yes'); wc_get_product_ids_on_sale(); // Creates the transient for on sale products wc_get_featured_product_ids(); // Creates the transient for featured products wc_delete_product_transients(); $this->assertFalse(get_transient('wc_products_onsale')); $this->assertFalse(get_transient('wc_featured_products')); \WC_Helper_Product::delete_product($product->id); }
/** * Save the settings */ public static function save() { global $current_section, $current_tab; if (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'], 'woocommerce-settings')) { die(__('Action failed. Please refresh the page and retry.', 'woocommerce')); } // Trigger actions do_action('woocommerce_settings_save_' . $current_tab); do_action('woocommerce_update_options_' . $current_tab); do_action('woocommerce_update_options'); // Clear any unwanted data wc_delete_product_transients(); delete_transient('woocommerce_cache_excluded_uris'); self::add_message(__('Your settings have been saved.', 'woocommerce')); self::check_download_folder_protection(); // Re-add endpoints and flush rules WC()->query->init_query_vars(); WC()->query->add_endpoints(); flush_rewrite_rules(); do_action('woocommerce_settings_saved'); }
/** * Save meta box data */ public static function save($post_id, $post) { global $wpdb; // Add any default post meta add_post_meta($post_id, 'total_sales', '0', true); // Get types $product_type = empty($_POST['product-type']) ? 'simple' : sanitize_title(stripslashes($_POST['product-type'])); $is_downloadable = isset($_POST['_downloadable']) ? 'yes' : 'no'; $is_virtual = isset($_POST['_virtual']) ? 'yes' : 'no'; // Product type + Downloadable/Virtual wp_set_object_terms($post_id, $product_type, 'product_type'); update_post_meta($post_id, '_downloadable', $is_downloadable); update_post_meta($post_id, '_virtual', $is_virtual); // Update post meta if (isset($_POST['_regular_price'])) { update_post_meta($post_id, '_regular_price', $_POST['_regular_price'] === '' ? '' : wc_format_decimal($_POST['_regular_price'])); } if (isset($_POST['_sale_price'])) { update_post_meta($post_id, '_sale_price', $_POST['_sale_price'] === '' ? '' : wc_format_decimal($_POST['_sale_price'])); } if (isset($_POST['_tax_status'])) { update_post_meta($post_id, '_tax_status', wc_clean($_POST['_tax_status'])); } if (isset($_POST['_tax_class'])) { update_post_meta($post_id, '_tax_class', wc_clean($_POST['_tax_class'])); } if (isset($_POST['_purchase_note'])) { update_post_meta($post_id, '_purchase_note', wp_kses_post(stripslashes($_POST['_purchase_note']))); } // Featured if (update_post_meta($post_id, '_featured', isset($_POST['_featured']) ? 'yes' : 'no')) { delete_transient('wc_featured_products'); } // Dimensions if ('no' == $is_virtual) { if (isset($_POST['_weight'])) { update_post_meta($post_id, '_weight', '' === $_POST['_weight'] ? '' : wc_format_decimal($_POST['_weight'])); } if (isset($_POST['_length'])) { update_post_meta($post_id, '_length', '' === $_POST['_length'] ? '' : wc_format_decimal($_POST['_length'])); } if (isset($_POST['_width'])) { update_post_meta($post_id, '_width', '' === $_POST['_width'] ? '' : wc_format_decimal($_POST['_width'])); } if (isset($_POST['_height'])) { update_post_meta($post_id, '_height', '' === $_POST['_height'] ? '' : wc_format_decimal($_POST['_height'])); } } else { update_post_meta($post_id, '_weight', ''); update_post_meta($post_id, '_length', ''); update_post_meta($post_id, '_width', ''); update_post_meta($post_id, '_height', ''); } // Save shipping class $product_shipping_class = $_POST['product_shipping_class'] > 0 && $product_type != 'external' ? absint($_POST['product_shipping_class']) : ''; wp_set_object_terms($post_id, $product_shipping_class, 'product_shipping_class'); // Unique SKU $sku = get_post_meta($post_id, '_sku', true); $new_sku = wc_clean(stripslashes($_POST['_sku'])); if ('' == $new_sku) { update_post_meta($post_id, '_sku', ''); } elseif ($new_sku !== $sku) { if (!empty($new_sku)) { $unique_sku = wc_product_has_unique_sku($post_id, $new_sku); if (!$unique_sku) { WC_Admin_Meta_Boxes::add_error(__('Product SKU must be unique.', 'woocommerce')); } else { update_post_meta($post_id, '_sku', $new_sku); } } else { update_post_meta($post_id, '_sku', ''); } } // Save Attributes $attributes = array(); if (isset($_POST['attribute_names']) && isset($_POST['attribute_values'])) { $attribute_names = $_POST['attribute_names']; $attribute_values = $_POST['attribute_values']; if (isset($_POST['attribute_visibility'])) { $attribute_visibility = $_POST['attribute_visibility']; } if (isset($_POST['attribute_variation'])) { $attribute_variation = $_POST['attribute_variation']; } $attribute_is_taxonomy = $_POST['attribute_is_taxonomy']; $attribute_position = $_POST['attribute_position']; $attribute_names_max_key = max(array_keys($attribute_names)); for ($i = 0; $i <= $attribute_names_max_key; $i++) { if (empty($attribute_names[$i])) { continue; } $is_visible = isset($attribute_visibility[$i]) ? 1 : 0; $is_variation = isset($attribute_variation[$i]) ? 1 : 0; $is_taxonomy = $attribute_is_taxonomy[$i] ? 1 : 0; if ($is_taxonomy) { if (isset($attribute_values[$i])) { // Select based attributes - Format values (posted values are slugs) if (is_array($attribute_values[$i])) { $values = array_map('sanitize_title', $attribute_values[$i]); // Text based attributes - Posted values are term names - don't change to slugs } else { $values = array_map('stripslashes', array_map('strip_tags', explode(WC_DELIMITER, $attribute_values[$i]))); } // Remove empty items in the array $values = array_filter($values, 'strlen'); } else { $values = array(); } // Update post terms if (taxonomy_exists($attribute_names[$i])) { foreach ($values as $key => $value) { $term = get_term_by('name', trim($value), $attribute_names[$i]); if ($term) { $values[$key] = intval($term->term_id); } else { $term = wp_insert_term(trim($value), $attribute_names[$i]); if (isset($term->term_id)) { $values[$key] = intval($term->term_id); } } } wp_set_object_terms($post_id, $values, $attribute_names[$i]); } if (!empty($values)) { // Add attribute to array, but don't set values $attributes[sanitize_title($attribute_names[$i])] = array('name' => wc_clean($attribute_names[$i]), 'value' => '', 'position' => $attribute_position[$i], 'is_visible' => $is_visible, 'is_variation' => $is_variation, 'is_taxonomy' => $is_taxonomy); } } elseif (isset($attribute_values[$i])) { // Text based, separate by pipe $values = implode(' ' . WC_DELIMITER . ' ', array_map('wc_clean', wc_get_text_attributes($attribute_values[$i]))); // Custom attribute - Add attribute to array and set the values $attributes[sanitize_title($attribute_names[$i])] = array('name' => wc_clean($attribute_names[$i]), 'value' => $values, 'position' => $attribute_position[$i], 'is_visible' => $is_visible, 'is_variation' => $is_variation, 'is_taxonomy' => $is_taxonomy); } } } if (!function_exists('attributes_cmp')) { function attributes_cmp($a, $b) { if ($a['position'] == $b['position']) { return 0; } return $a['position'] < $b['position'] ? -1 : 1; } } uasort($attributes, 'attributes_cmp'); update_post_meta($post_id, '_product_attributes', $attributes); // Sales and prices if (in_array($product_type, array('variable', 'grouped'))) { // Variable and grouped products have no prices update_post_meta($post_id, '_regular_price', ''); update_post_meta($post_id, '_sale_price', ''); update_post_meta($post_id, '_sale_price_dates_from', ''); update_post_meta($post_id, '_sale_price_dates_to', ''); update_post_meta($post_id, '_price', ''); } else { $date_from = isset($_POST['_sale_price_dates_from']) ? wc_clean($_POST['_sale_price_dates_from']) : ''; $date_to = isset($_POST['_sale_price_dates_to']) ? wc_clean($_POST['_sale_price_dates_to']) : ''; // Dates if ($date_from) { update_post_meta($post_id, '_sale_price_dates_from', strtotime($date_from)); } else { update_post_meta($post_id, '_sale_price_dates_from', ''); } if ($date_to) { update_post_meta($post_id, '_sale_price_dates_to', strtotime($date_to)); } else { update_post_meta($post_id, '_sale_price_dates_to', ''); } if ($date_to && !$date_from) { $date_from = date('Y-m-d'); update_post_meta($post_id, '_sale_price_dates_from', strtotime($date_from)); } // Update price if on sale if ('' !== $_POST['_sale_price'] && '' == $date_to && '' == $date_from) { update_post_meta($post_id, '_price', wc_format_decimal($_POST['_sale_price'])); } else { update_post_meta($post_id, '_price', $_POST['_regular_price'] === '' ? '' : wc_format_decimal($_POST['_regular_price'])); } if ('' !== $_POST['_sale_price'] && $date_from && strtotime($date_from) <= strtotime('NOW', current_time('timestamp'))) { update_post_meta($post_id, '_price', wc_format_decimal($_POST['_sale_price'])); } if ($date_to && strtotime($date_to) < strtotime('NOW', current_time('timestamp'))) { update_post_meta($post_id, '_price', $_POST['_regular_price'] === '' ? '' : wc_format_decimal($_POST['_regular_price'])); update_post_meta($post_id, '_sale_price_dates_from', ''); update_post_meta($post_id, '_sale_price_dates_to', ''); } } // Update parent if grouped so price sorting works and stays in sync with the cheapest child if ($post->post_parent > 0 || 'grouped' == $product_type || $_POST['previous_parent_id'] > 0) { $clear_parent_ids = array(); if ($post->post_parent > 0) { $clear_parent_ids[] = $post->post_parent; } if ('grouped' == $product_type) { $clear_parent_ids[] = $post_id; } if ($_POST['previous_parent_id'] > 0) { $clear_parent_ids[] = absint($_POST['previous_parent_id']); } if (!empty($clear_parent_ids)) { foreach ($clear_parent_ids as $clear_id) { $children_by_price = get_posts(array('post_parent' => $clear_id, 'orderby' => 'meta_value_num', 'order' => 'asc', 'meta_key' => '_price', 'posts_per_page' => 1, 'post_type' => 'product', 'fields' => 'ids')); if ($children_by_price) { foreach ($children_by_price as $child) { $child_price = get_post_meta($child, '_price', true); update_post_meta($clear_id, '_price', $child_price); } } wc_delete_product_transients($clear_id); } } } // Sold Individually if (!empty($_POST['_sold_individually'])) { update_post_meta($post_id, '_sold_individually', 'yes'); } else { update_post_meta($post_id, '_sold_individually', ''); } // Stock Data if ('yes' === get_option('woocommerce_manage_stock')) { $manage_stock = 'no'; $backorders = 'no'; $stock_status = wc_clean($_POST['_stock_status']); if ('external' === $product_type) { $stock_status = 'instock'; } elseif ('variable' === $product_type) { // Stock status is always determined by children so sync later $stock_status = ''; if (!empty($_POST['_manage_stock'])) { $manage_stock = 'yes'; $backorders = wc_clean($_POST['_backorders']); } } elseif ('grouped' !== $product_type && !empty($_POST['_manage_stock'])) { $manage_stock = 'yes'; $backorders = wc_clean($_POST['_backorders']); } update_post_meta($post_id, '_manage_stock', $manage_stock); update_post_meta($post_id, '_backorders', $backorders); if ($stock_status) { wc_update_product_stock_status($post_id, $stock_status); } if (!empty($_POST['_manage_stock'])) { wc_update_product_stock($post_id, wc_stock_amount($_POST['_stock'])); } else { update_post_meta($post_id, '_stock', ''); } } else { wc_update_product_stock_status($post_id, wc_clean($_POST['_stock_status'])); } // Cross sells and upsells $upsells = isset($_POST['upsell_ids']) ? array_filter(array_map('intval', explode(',', $_POST['upsell_ids']))) : array(); $crosssells = isset($_POST['crosssell_ids']) ? array_filter(array_map('intval', explode(',', $_POST['crosssell_ids']))) : array(); update_post_meta($post_id, '_upsell_ids', $upsells); update_post_meta($post_id, '_crosssell_ids', $crosssells); // Downloadable options if ('yes' == $is_downloadable) { $_download_limit = absint($_POST['_download_limit']); if (!$_download_limit) { $_download_limit = ''; // 0 or blank = unlimited } $_download_expiry = absint($_POST['_download_expiry']); if (!$_download_expiry) { $_download_expiry = ''; // 0 or blank = unlimited } // file paths will be stored in an array keyed off md5(file path) $files = array(); if (isset($_POST['_wc_file_urls'])) { $file_names = isset($_POST['_wc_file_names']) ? $_POST['_wc_file_names'] : array(); $file_urls = isset($_POST['_wc_file_urls']) ? array_map('trim', $_POST['_wc_file_urls']) : array(); $file_url_size = sizeof($file_urls); $allowed_file_types = apply_filters('woocommerce_downloadable_file_allowed_mime_types', get_allowed_mime_types()); for ($i = 0; $i < $file_url_size; $i++) { if (!empty($file_urls[$i])) { // Find type and file URL if (0 === strpos($file_urls[$i], 'http')) { $file_is = 'absolute'; $file_url = esc_url_raw($file_urls[$i]); } elseif ('[' === substr($file_urls[$i], 0, 1) && ']' === substr($file_urls[$i], -1)) { $file_is = 'shortcode'; $file_url = wc_clean($file_urls[$i]); } else { $file_is = 'relative'; $file_url = wc_clean($file_urls[$i]); } $file_name = wc_clean($file_names[$i]); $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) { $_file_url = $file_url; if ('..' === substr($file_url, 0, 2) || '/' !== substr($file_url, 0, 1)) { $_file_url = realpath(ABSPATH . $file_url); } if (!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, 0, $files); update_post_meta($post_id, '_downloadable_files', $files); update_post_meta($post_id, '_download_limit', $_download_limit); update_post_meta($post_id, '_download_expiry', $_download_expiry); if (isset($_POST['_download_type'])) { update_post_meta($post_id, '_download_type', wc_clean($_POST['_download_type'])); } } // Product url if ('external' == $product_type) { if (isset($_POST['_product_url'])) { update_post_meta($post_id, '_product_url', esc_url_raw($_POST['_product_url'])); } if (isset($_POST['_button_text'])) { update_post_meta($post_id, '_button_text', wc_clean($_POST['_button_text'])); } } // Save variations if ('variable' == $product_type) { // Deprecated since WooCommerce 2.4.0 in favor to WC_AJAX::save_variations() // self::save_variations( $post_id, $post ); // Update parent if variable so price sorting works and stays in sync with the cheapest child WC_Product_Variable::sync($post_id); } // Update version after saving update_post_meta($post_id, '_product_version', WC_VERSION); // Do action for product type do_action('woocommerce_process_product_meta_' . $product_type, $post_id); // Clear cache/transients wc_delete_product_transients($post_id); }
/** * */ public function trs2_clear_transients() { global $woocommerce; if (is_checkout()) { wc_delete_product_transients(); } }
/** * Link all variations via ajax function */ public function link_all_variations() { if (!defined('WC_MAX_LINKED_VARIATIONS')) { define('WC_MAX_LINKED_VARIATIONS', 49); } check_ajax_referer('link-variations', 'security'); @set_time_limit(0); $post_id = intval($_POST['post_id']); if (!$post_id) { die; } $variations = array(); $_product = get_product($post_id, array('product_type' => 'variable')); // Put variation attributes into an array foreach ($_product->get_attributes() as $attribute) { if (!$attribute['is_variation']) { continue; } $attribute_field_name = 'attribute_' . sanitize_title($attribute['name']); if ($attribute['is_taxonomy']) { $options = wc_get_product_terms($post_id, $attribute['name'], array('fields' => 'slugs')); } else { $options = explode(WC_DELIMITER, $attribute['value']); } $options = array_map('sanitize_title', array_map('trim', $options)); $variations[$attribute_field_name] = $options; } // Quit out if none were found if (sizeof($variations) == 0) { die; } // Get existing variations so we don't create duplicates $available_variations = array(); foreach ($_product->get_children() as $child_id) { $child = $_product->get_child($child_id); if (!empty($child->variation_id)) { $available_variations[] = $child->get_variation_attributes(); } } // Created posts will all have the following data $variation_post_data = array('post_title' => 'Product #' . $post_id . ' Variation', 'post_content' => '', 'post_status' => 'publish', 'post_author' => get_current_user_id(), 'post_parent' => $post_id, 'post_type' => 'product_variation'); // Now find all combinations and create posts if (!function_exists('array_cartesian')) { /** * @param array $input * @return array */ function array_cartesian($input) { $result = array(); while (list($key, $values) = each($input)) { // If a sub-array is empty, it doesn't affect the cartesian product if (empty($values)) { continue; } // Special case: seeding the product array with the values from the first sub-array if (empty($result)) { foreach ($values as $value) { $result[] = array($key => $value); } } else { // Second and subsequent input sub-arrays work like this: // 1. In each existing array inside $product, add an item with // key == $key and value == first item in input sub-array // 2. Then, for each remaining item in current input sub-array, // add a copy of each existing array inside $product with // key == $key and value == first item in current input sub-array // Store all items to be added to $product here; adding them on the spot // inside the foreach will result in an infinite loop $append = array(); foreach ($result as &$product) { // Do step 1 above. array_shift is not the most efficient, but it // allows us to iterate over the rest of the items with a simple // foreach, making the code short and familiar. $product[$key] = array_shift($values); // $product is by reference (that's why the key we added above // will appear in the end result), so make a copy of it here $copy = $product; // Do step 2 above. foreach ($values as $item) { $copy[$key] = $item; $append[] = $copy; } // Undo the side effecst of array_shift array_unshift($values, $product[$key]); } // Out of the foreach, we can add to $results now $result = array_merge($result, $append); } } return $result; } } $variation_ids = array(); $added = 0; $possible_variations = array_cartesian($variations); foreach ($possible_variations as $variation) { // Check if variation already exists if (in_array($variation, $available_variations)) { continue; } $variation_id = wp_insert_post($variation_post_data); $variation_ids[] = $variation_id; foreach ($variation as $key => $value) { update_post_meta($variation_id, $key, $value); } $added++; do_action('product_variation_linked', $variation_id); if ($added > WC_MAX_LINKED_VARIATIONS) { break; } } wc_delete_product_transients($post_id); echo $added; die; }
/** * Update one or more products. * * ## OPTIONS * * <id> * : Product ID * * --<field>=<value> * : One or more fields to update. * * ## AVAILABLE_FIELDS * * For more fields, see: wp wc product create --help * * ## EXAMPLES * * wp wc product update 123 --title="New Product Title" --description="New description" * * @since 2.5.0 */ public function update($args, $assoc_args) { try { $id = $args[0]; $data = apply_filters('woocommerce_cli_update_product_data', $this->unflatten_array($assoc_args)); // Product title. if (isset($data['title'])) { wp_update_post(array('ID' => $id, 'post_title' => wc_clean($data['title']))); } // Product name (slug). if (isset($data['name'])) { wp_update_post(array('ID' => $id, 'post_name' => sanitize_title($data['name']))); } // Product status. if (isset($data['status'])) { wp_update_post(array('ID' => $id, 'post_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']); wp_update_post(array('ID' => $id, 'post_excerpt' => $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']); wp_update_post(array('ID' => $id, 'post_content' => $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_CLI_Exception('woocommerce_cli_invalid_product_type', sprintf(__('Invalid product type - the product type must be any of these: %s', 'woocommerce'), implode(', ', array_keys(wc_get_product_types())))); } // Check for featured/gallery images, upload it and set it if (isset($data['images'])) { $this->save_product_images($id, $data['images']); } // Save product meta fields $this->save_product_meta($id, $data); // Save variations if (isset($data['type']) && 'variable' == $data['type'] && isset($data['variations']) && is_array($data['variations'])) { $this->save_variations($id, $data); } do_action('woocommerce_cli_update_product', $id, $data); // Clear cache/transients wc_delete_product_transients($id); WP_CLI::success("Updated product {$id}."); } catch (WC_CLI_Exception $e) { WP_CLI::error($e->getMessage()); } }
/** * Delete a product. * * @since 2.2 * @param int $id the product ID. * @param bool $force true to permanently delete order, false to move to trash. * @return array */ public function delete_product($id, $force = false) { $id = $this->validate_request($id, 'product', 'delete'); if (is_wp_error($id)) { return $id; } do_action('woocommerce_api_delete_product', $id, $this); // If we're forcing, then delete permanently. if ($force) { $child_product_variations = get_children('post_parent=' . $id . '&post_type=product_variation'); if (!empty($child_product_variations)) { foreach ($child_product_variations as $child) { wp_delete_post($child->ID, true); } } $child_products = get_children('post_parent=' . $id . '&post_type=product'); if (!empty($child_products)) { foreach ($child_products as $child) { $child_post = array(); $child_post['ID'] = $child->ID; $child_post['post_parent'] = 0; wp_update_post($child_post); } } $result = wp_delete_post($id, true); } else { $result = wp_trash_post($id); } if (!$result) { return new WP_Error('woocommerce_api_cannot_delete_product', sprintf(__('This %s cannot be deleted', 'woocommerce'), 'product'), array('status' => 500)); } // Delete parent product transients. if ($parent_id = wp_get_post_parent_id($id)) { wc_delete_product_transients($parent_id); } if ($force) { return array('message' => sprintf(__('Permanently deleted %s', 'woocommerce'), 'product')); } else { $this->server->send_status('202'); return array('message' => sprintf(__('Deleted %s', 'woocommerce'), 'product')); } }
public function save() { //save the post $this->body = apply_filters('woocsv_product_before_body', $this->body, $this->new); $this->meta = apply_filters('woocsv_product_before_meta', $this->meta, $this->new); $post_id = wp_insert_post($this->body); $this->body['ID'] = $post_id; do_action('woocsv_before_save', $this); do_action('woocsv_product_after_body_save'); // fixed bug with if condition wp_set_object_terms($post_id, $this->product_type, 'product_type', false); do_action('woocsv_product_before_meta_save'); //save the meta foreach ($this->meta as $key => $value) { update_post_meta($post_id, $key, $value); } do_action('woocsv_product_before_tags_save'); //save tags if ($this->tags) { $this->saveTags($post_id); } do_action('woocsv_product_before_categorie_save'); //save categories if (!empty($this->categories)) { $this->saveCategories($post_id); } do_action('woocsv_product_before_images_save'); /* !--deprecated */ if ($this->images) { $this->saveImages($post_id); } // added empty() else it overrrides the above function) if (!empty($this->featuredImage)) { $this->saveFeaturedImage(); } if (!empty($this->productGallery)) { $this->saveProductGallery(); } do_action('woocsv_product_before_shipping_save'); if ($this->shippingClass) { $this->saveShippingClass(); } do_action('woocsv_after_save', $this); /* !version 2.0.4 */ if (function_exists('wc_delete_product_transients')) { wc_delete_product_transients($post_id); } //and return the ID return $post_id; }
/** * Save the product data meta box. * * @access public * @param mixed $post_id * @return void */ function dokan_process_product_meta($post_id) { global $wpdb, $woocommerce, $woocommerce_errors; // Add any default post meta add_post_meta($post_id, 'total_sales', '0', true); // Get types $product_type = empty($_POST['_product_type']) ? 'simple' : sanitize_title(stripslashes($_POST['_product_type'])); $is_downloadable = isset($_POST['_downloadable']) ? 'yes' : 'no'; $is_virtual = isset($_POST['_virtual']) ? 'yes' : 'no'; // Product type + Downloadable/Virtual wp_set_object_terms($post_id, $product_type, 'product_type'); update_post_meta($post_id, '_downloadable', $is_downloadable); update_post_meta($post_id, '_virtual', $is_virtual); // Gallery Images $attachment_ids = array_filter(explode(',', woocommerce_clean($_POST['product_image_gallery']))); update_post_meta($post_id, '_product_image_gallery', implode(',', $attachment_ids)); // Update post meta update_post_meta($post_id, '_regular_price', stripslashes($_POST['_regular_price'])); update_post_meta($post_id, '_sale_price', stripslashes($_POST['_sale_price'])); if (isset($_POST['_tax_status'])) { update_post_meta($post_id, '_tax_status', stripslashes($_POST['_tax_status'])); } if (isset($_POST['_tax_class'])) { update_post_meta($post_id, '_tax_class', stripslashes($_POST['_tax_class'])); } update_post_meta($post_id, '_visibility', stripslashes($_POST['_visibility'])); update_post_meta($post_id, '_purchase_note', stripslashes($_POST['_purchase_note'])); // Dimensions if ($is_virtual == 'no') { update_post_meta($post_id, '_weight', stripslashes($_POST['_weight'])); update_post_meta($post_id, '_length', stripslashes($_POST['_length'])); update_post_meta($post_id, '_width', stripslashes($_POST['_width'])); update_post_meta($post_id, '_height', stripslashes($_POST['_height'])); } else { update_post_meta($post_id, '_weight', ''); update_post_meta($post_id, '_length', ''); update_post_meta($post_id, '_width', ''); update_post_meta($post_id, '_height', ''); } //For pin code if ($_POST['sell_in'] == 'all') { $sell_in = $_POST['sell_in']; } elseif ($_POST['sell_in'] == 'state') { $sell_in = $_POST['sell_in']; foreach ($_POST['states_state'] as $p_states) { $p_state .= '"' . $p_states . '",'; } $p_state = rtrim($p_state, ','); } elseif ($_POST['sell_in'] == 'city') { $sell_in = $_POST['sell_in']; $p_state = '"' . $_POST['cities_state'] . '"'; foreach ($_POST['cities_city'] as $p_cities) { $p_city .= '"' . $p_cities . '",'; } $p_city = rtrim($p_city, ','); } if ($_POST['enable_cod'] == 'Y') { $cod = $_POST['enable_cod']; } else { $cod = 'N'; } $sell = array('cod' => $cod, 'sell_in' => $sell_in, 'state' => $p_state, 'city' => $p_city); update_post_meta($post_id, 'sell_in', $sell); // Shipping Type update_post_meta($post_id, '_shipping_type', stripslashes($_POST['_shipping_type'])); update_post_meta($post_id, '_flat_shipping_cost', stripslashes($_POST['_flat_shipping_cost'])); // Save shipping class $product_shipping_class = $_POST['product_shipping_class'] > 0 && $product_type != 'external' ? absint($_POST['product_shipping_class']) : ''; wp_set_object_terms($post_id, $product_shipping_class, 'product_shipping_class'); // Unique SKU $sku = get_post_meta($post_id, '_sku', true); $new_sku = woocommerce_clean(stripslashes($_POST['_sku'])); if ($new_sku == '') { update_post_meta($post_id, '_sku', ''); } elseif ($new_sku !== $sku) { if (!empty($new_sku)) { if ($wpdb->get_var($wpdb->prepare("\n SELECT {$wpdb->posts}.ID\n FROM {$wpdb->posts}\n LEFT JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id)\n WHERE {$wpdb->posts}.post_type = 'product'\n AND {$wpdb->posts}.post_status = 'publish'\n AND {$wpdb->postmeta}.meta_key = '_sku' AND {$wpdb->postmeta}.meta_value = '%s'\n ", $new_sku))) { $woocommerce_errors[] = __('Product SKU must be unique.', 'woocommerce'); } else { update_post_meta($post_id, '_sku', $new_sku); } } else { update_post_meta($post_id, '_sku', ''); } } // Save Attributes $attributes = array(); if (isset($_POST['attribute_names'])) { $attribute_names = $_POST['attribute_names']; $attribute_values = $_POST['attribute_values']; if (isset($_POST['attribute_visibility'])) { $attribute_visibility = $_POST['attribute_visibility']; } if (isset($_POST['attribute_variation'])) { $attribute_variation = $_POST['attribute_variation']; } $attribute_is_taxonomy = $_POST['attribute_is_taxonomy']; $attribute_position = $_POST['attribute_position']; $attribute_names_count = sizeof($attribute_names); for ($i = 0; $i < $attribute_names_count; $i++) { if (!$attribute_names[$i]) { continue; } $is_visible = isset($attribute_visibility[$i]) ? 1 : 0; $is_variation = isset($attribute_variation[$i]) ? 1 : 0; $is_taxonomy = $attribute_is_taxonomy[$i] ? 1 : 0; if ($is_taxonomy) { if (isset($attribute_values[$i])) { // Select based attributes - Format values (posted values are slugs) if (is_array($attribute_values[$i])) { $values = array_map('sanitize_title', $attribute_values[$i]); // Text based attributes - Posted values are term names - don't change to slugs } else { $values = array_map('stripslashes', array_map('strip_tags', explode('|', $attribute_values[$i]))); } // Remove empty items in the array $values = array_filter($values, 'strlen'); } else { $values = array(); } // Update post terms if (taxonomy_exists($attribute_names[$i])) { wp_set_object_terms($post_id, $values, $attribute_names[$i]); } if ($values) { // Add attribute to array, but don't set values $attributes[sanitize_title($attribute_names[$i])] = array('name' => woocommerce_clean($attribute_names[$i]), 'value' => '', 'position' => $attribute_position[$i], 'is_visible' => $is_visible, 'is_variation' => $is_variation, 'is_taxonomy' => $is_taxonomy); } } elseif (isset($attribute_values[$i])) { // Text based, separate by pipe $values = implode(' | ', array_map('woocommerce_clean', $attribute_values[$i])); // Custom attribute - Add attribute to array and set the values $attributes[sanitize_title($attribute_names[$i])] = array('name' => woocommerce_clean($attribute_names[$i]), 'value' => $values, 'position' => $attribute_position[$i], 'is_visible' => $is_visible, 'is_variation' => $is_variation, 'is_taxonomy' => $is_taxonomy); } } } if (!function_exists('attributes_cmp')) { function attributes_cmp($a, $b) { if ($a['position'] == $b['position']) { return 0; } return $a['position'] < $b['position'] ? -1 : 1; } } uasort($attributes, 'attributes_cmp'); update_post_meta($post_id, '_product_attributes', $attributes); // Sales and prices if (in_array($product_type, array('variable'))) { // Variable products have no prices update_post_meta($post_id, '_regular_price', ''); update_post_meta($post_id, '_sale_price', ''); update_post_meta($post_id, '_sale_price_dates_from', ''); update_post_meta($post_id, '_sale_price_dates_to', ''); update_post_meta($post_id, '_price', ''); } else { $date_from = isset($_POST['_sale_price_dates_from']) ? $_POST['_sale_price_dates_from'] : ''; $date_to = isset($_POST['_sale_price_dates_to']) ? $_POST['_sale_price_dates_to'] : ''; // Dates if ($date_from) { update_post_meta($post_id, '_sale_price_dates_from', strtotime($date_from)); } else { update_post_meta($post_id, '_sale_price_dates_from', ''); } if ($date_to) { update_post_meta($post_id, '_sale_price_dates_to', strtotime($date_to)); } else { update_post_meta($post_id, '_sale_price_dates_to', ''); } if ($date_to && !$date_from) { update_post_meta($post_id, '_sale_price_dates_from', strtotime('NOW', current_time('timestamp'))); } // Update price if on sale if ($_POST['_sale_price'] != '' && $date_to == '' && $date_from == '') { update_post_meta($post_id, '_price', stripslashes($_POST['_sale_price'])); } else { update_post_meta($post_id, '_price', stripslashes($_POST['_regular_price'])); } if ($_POST['_sale_price'] != '' && $date_from && strtotime($date_from) < strtotime('NOW', current_time('timestamp'))) { update_post_meta($post_id, '_price', stripslashes($_POST['_sale_price'])); } if ($date_to && strtotime($date_to) < strtotime('NOW', current_time('timestamp'))) { update_post_meta($post_id, '_price', stripslashes($_POST['_regular_price'])); update_post_meta($post_id, '_sale_price_dates_from', ''); update_post_meta($post_id, '_sale_price_dates_to', ''); } } // Sold Individuall if (!empty($_POST['_sold_individually'])) { update_post_meta($post_id, '_sold_individually', 'yes'); } else { update_post_meta($post_id, '_sold_individually', ''); } // Stock Data if (get_option('woocommerce_manage_stock') == 'yes') { if (!empty($_POST['_manage_stock'])) { // Manage stock update_post_meta($post_id, '_stock', (int) $_POST['_stock']); update_post_meta($post_id, '_stock_status', stripslashes($_POST['_stock_status'])); update_post_meta($post_id, '_backorders', stripslashes($_POST['_backorders'])); update_post_meta($post_id, '_manage_stock', 'yes'); // Check stock level if ($product_type !== 'variable' && $_POST['_backorders'] == 'no' && (int) $_POST['_stock'] < 1) { update_post_meta($post_id, '_stock_status', 'outofstock'); } } else { // Don't manage stock update_post_meta($post_id, '_stock', ''); update_post_meta($post_id, '_stock_status', stripslashes($_POST['_stock_status'])); update_post_meta($post_id, '_backorders', stripslashes($_POST['_backorders'])); update_post_meta($post_id, '_manage_stock', 'no'); } } else { update_post_meta($post_id, '_stock_status', stripslashes($_POST['_stock_status'])); } // Upsells if (isset($_POST['upsell_ids'])) { $upsells = array(); $ids = $_POST['upsell_ids']; foreach ($ids as $id) { if ($id && $id > 0) { $upsells[] = $id; } } update_post_meta($post_id, '_upsell_ids', $upsells); } else { delete_post_meta($post_id, '_upsell_ids'); } // Cross sells if (isset($_POST['crosssell_ids'])) { $crosssells = array(); $ids = $_POST['crosssell_ids']; foreach ($ids as $id) { if ($id && $id > 0) { $crosssells[] = $id; } } update_post_meta($post_id, '_crosssell_ids', $crosssells); } else { delete_post_meta($post_id, '_crosssell_ids'); } // Downloadable options if ($is_downloadable == 'yes') { $_download_limit = absint($_POST['_download_limit']); if (!$_download_limit) { $_download_limit = ''; } // 0 or blank = unlimited $_download_expiry = absint($_POST['_download_expiry']); if (!$_download_expiry) { $_download_expiry = ''; } // 0 or blank = unlimited // file paths will be stored in an array keyed off md5(file path) if (isset($_POST['_wc_file_urls'])) { $files = array(); $file_names = isset($_POST['_wc_file_names']) ? array_map('wc_clean', $_POST['_wc_file_names']) : array(); $file_urls = isset($_POST['_wc_file_urls']) ? array_map('esc_url_raw', array_map('trim', $_POST['_wc_file_urls'])) : array(); $file_url_size = sizeof($file_urls); for ($i = 0; $i < $file_url_size; $i++) { if (!empty($file_urls[$i])) { $files[md5($file_urls[$i])] = array('name' => $file_names[$i], 'file' => $file_urls[$i]); } } // 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, 0, $files); update_post_meta($post_id, '_downloadable_files', $files); } update_post_meta($post_id, '_download_limit', $_download_limit); update_post_meta($post_id, '_download_expiry', $_download_expiry); if (isset($_POST['_download_limit'])) { update_post_meta($post_id, '_download_limit', esc_attr($_download_limit)); } if (isset($_POST['_download_expiry'])) { update_post_meta($post_id, '_download_expiry', esc_attr($_download_expiry)); } } // Save variations if ($product_type == 'variable') { dokan_save_variations($post_id); } // Do action for product type do_action('woocommerce_process_product_meta_' . $product_type, $post_id); do_action('dokan_process_product_meta', $post_id); // Clear cache/transients wc_delete_product_transients($post_id); }
/** * Actually executes a a tool. * * @param string $tool * @return array */ public function execute_tool($tool) { global $wpdb; $ran = true; switch ($tool) { case 'clear_transients': wc_delete_product_transients(); wc_delete_shop_order_transients(); WC_Cache_Helper::get_transient_version('shipping', true); $message = __('Product Transients Cleared', 'woocommerce'); break; case 'clear_expired_transients': /* * Deletes all expired transients. The multi-table delete syntax is used. * to delete the transient record from table a, and the corresponding. * transient_timeout record from table b. * * Based on code inside core's upgrade_network() function. */ $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\tWHERE a.option_name LIKE %s\n\t\t\t\t\tAND a.option_name NOT LIKE %s\n\t\t\t\t\tAND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )\n\t\t\t\t\tAND b.option_value < %d"; $rows = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_transient_') . '%', $wpdb->esc_like('_transient_timeout_') . '%', time())); $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\tWHERE a.option_name LIKE %s\n\t\t\t\t\tAND a.option_name NOT LIKE %s\n\t\t\t\t\tAND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )\n\t\t\t\t\tAND b.option_value < %d"; $rows2 = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_site_transient_') . '%', $wpdb->esc_like('_site_transient_timeout_') . '%', time())); $message = sprintf(__('%d Transients Rows Cleared', 'woocommerce'), $rows + $rows2); break; case 'reset_roles': // Remove then re-add caps and roles WC_Install::remove_roles(); WC_Install::create_roles(); $message = __('Roles successfully reset', 'woocommerce'); break; case 'recount_terms': $product_cats = get_terms('product_cat', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_cats, get_taxonomy('product_cat'), true, false); $product_tags = get_terms('product_tag', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_tags, get_taxonomy('product_tag'), true, false); $message = __('Terms successfully recounted', 'woocommerce'); break; case 'clear_sessions': $wpdb->query("TRUNCATE {$wpdb->prefix}woocommerce_sessions"); wp_cache_flush(); $message = __('Sessions successfully cleared', 'woocommerce'); break; case 'install_pages': WC_Install::create_pages(); return __('All missing WooCommerce pages was installed successfully.', 'woocommerce'); break; case 'delete_taxes': $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rates;"); $wpdb->query("TRUNCATE TABLE {$wpdb->prefix}woocommerce_tax_rate_locations;"); WC_Cache_Helper::incr_cache_prefix('taxes'); $message = __('Tax rates successfully deleted', 'woocommerce'); break; case 'reset_tracking': delete_option('woocommerce_allow_tracking'); WC_Admin_Notices::add_notice('tracking'); $message = __('Usage tracking settings successfully reset.', 'woocommerce'); break; default: $tools = $this->get_tools(); if (isset($tools[$tool]['callback'])) { $callback = $tools[$tool]['callback']; $return = call_user_func($callback); if ($return === false) { $callback_string = is_array($callback) ? get_class($callback[0]) . '::' . $callback[1] : $callback; $ran = false; $message = sprintf(__('There was an error calling %s', 'woocommerce'), $callback_string); } else { $message = __('Tool ran.', 'woocommerce'); } } else { $ran = false; $message = __('There was an error calling this tool. There is no callback present.', 'woocommerce'); } break; } return array('success' => $ran, 'message' => $message); }
/** * Fetches inventory from fortnox and updates WooCommerce inventory * * @return string */ public function run_inventory_cron_job() { include_once "class-fortnox3-api.php"; $options = get_option('woocommerce_fortnox_general_settings'); if (!isset($options['activate-fortnox-products-sync'])) { return; } //Init API $apiInterface = new WCF_API(); if (!$apiInterface->create_api_validation_request()) { return $this->ERROR_API_KEY; } if ($apiInterface->has_error) { return $this->ERROR_LOGIN; } //fetch all articles $articles = $apiInterface->get_inventory(); $pf = new WC_Product_Factory(); $product = null; include_once "class-fortnox3-product-xml.php"; foreach ($articles as $article) { //Query DB for id by SKU $args = array('post_type' => array('product', 'product_variation'), 'orderby' => 'id', 'meta_key' => '_sku', 'meta_value' => $article['ArticleNumber']); $query = new WP_Query($args); if ($query->post_count == 1) { $product = $pf->get_product($query->posts[0]->ID); } else { $article = null; continue; } if (!$product || null === $product) { $product = null; $article = null; continue; } if ($product instanceof WC_Product_Variation) { if ($product->parent == '') { $product = null; $article = null; continue; } } if ($product instanceof WC_Product_Variable) { $this->update_product_inventory($product, null); } else { $this->update_product_inventory($product, $article['QuantityInStock']); } wc_delete_product_transients($product->id); $product = null; } $articles = null; return "Lager uppdaterat"; }
/** * Quick and bulk edit saving * * @access public * @param int $post_id * @param WP_Post $post * @return int */ public function bulk_and_quick_edit_save_post($post_id, $post) { // If this is an autosave, our form has not been submitted, so we don't want to do anything. if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; } // Don't save revisions and autosaves if (wp_is_post_revision($post_id) || wp_is_post_autosave($post_id)) { return $post_id; } // Check post type is product if ($post->post_type != 'product') { return $post_id; } // Check user permission if (!current_user_can('edit_post', $post_id)) { return $post_id; } // Check nonces if (!isset($_REQUEST['woocommerce_quick_edit_nonce']) && !isset($_REQUEST['woocommerce_bulk_edit_nonce'])) { return $post_id; } if (isset($_REQUEST['woocommerce_quick_edit_nonce']) && !wp_verify_nonce($_REQUEST['woocommerce_quick_edit_nonce'], 'woocommerce_quick_edit_nonce')) { return $post_id; } if (isset($_REQUEST['woocommerce_bulk_edit_nonce']) && !wp_verify_nonce($_REQUEST['woocommerce_bulk_edit_nonce'], 'woocommerce_bulk_edit_nonce')) { return $post_id; } // Get the product and save $product = get_product($post); if (!empty($_REQUEST['woocommerce_quick_edit'])) { $this->quick_edit_save($post_id, $product); } else { $this->bulk_edit_save($post_id, $product); } // Clear transient wc_delete_product_transients($post_id); return $post_id; }
/** * Save the product data meta box. * * @access public * @param mixed $post_id * @return void */ function dokan_process_product_meta($post_id) { global $wpdb, $woocommerce, $woocommerce_errors; // Add any default post meta add_post_meta($post_id, 'total_sales', '0', true); // Get types $product_type = 'simple'; $is_downloadable = isset($_POST['_downloadable']) ? 'yes' : 'no'; $is_virtual = isset($_POST['_virtual']) ? 'yes' : 'no'; // Product type + Downloadable/Virtual wp_set_object_terms($post_id, $product_type, 'product_type'); update_post_meta($post_id, '_downloadable', $is_downloadable); update_post_meta($post_id, '_virtual', $is_virtual); // Gallery Images $attachment_ids = array_filter(explode(',', woocommerce_clean($_POST['product_image_gallery']))); update_post_meta($post_id, '_product_image_gallery', implode(',', $attachment_ids)); // Update post meta if (isset($_POST['_regular_price'])) { update_post_meta($post_id, '_regular_price', $_POST['_regular_price'] === '' ? '' : wc_format_decimal($_POST['_regular_price'])); } if (isset($_POST['_sale_price'])) { update_post_meta($post_id, '_sale_price', $_POST['_sale_price'] === '' ? '' : wc_format_decimal($_POST['_sale_price'])); } if (isset($_POST['_tax_status'])) { update_post_meta($post_id, '_tax_status', stripslashes($_POST['_tax_status'])); } if (isset($_POST['_tax_class'])) { update_post_meta($post_id, '_tax_class', stripslashes($_POST['_tax_class'])); } update_post_meta($post_id, '_visibility', stripslashes($_POST['_visibility'])); // Unique SKU $sku = get_post_meta($post_id, '_sku', true); $new_sku = woocommerce_clean(stripslashes($_POST['_sku'])); if ($new_sku == '') { update_post_meta($post_id, '_sku', ''); } elseif ($new_sku !== $sku) { if (!empty($new_sku)) { if ($wpdb->get_var($wpdb->prepare("\n SELECT {$wpdb->posts}.ID\n FROM {$wpdb->posts}\n LEFT JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id)\n WHERE {$wpdb->posts}.post_type = 'product'\n AND {$wpdb->posts}.post_status = 'publish'\n AND {$wpdb->postmeta}.meta_key = '_sku' AND {$wpdb->postmeta}.meta_value = '%s'\n ", $new_sku))) { $woocommerce_errors[] = __('Product SKU must be unique.', 'woocommerce'); } else { update_post_meta($post_id, '_sku', $new_sku); } } else { update_post_meta($post_id, '_sku', ''); } } // Sales and prices $date_from = isset($_POST['_sale_price_dates_from']) ? $_POST['_sale_price_dates_from'] : ''; $date_to = isset($_POST['_sale_price_dates_to']) ? $_POST['_sale_price_dates_to'] : ''; // Dates if ($date_from) { update_post_meta($post_id, '_sale_price_dates_from', strtotime($date_from)); } else { update_post_meta($post_id, '_sale_price_dates_from', ''); } if ($date_to) { update_post_meta($post_id, '_sale_price_dates_to', strtotime($date_to)); } else { update_post_meta($post_id, '_sale_price_dates_to', ''); } if ($date_to && !$date_from) { update_post_meta($post_id, '_sale_price_dates_from', strtotime('NOW', current_time('timestamp'))); } // Update price if on sale if ('' !== $_POST['_sale_price'] && '' == $date_to && '' == $date_from) { update_post_meta($post_id, '_price', wc_format_decimal($_POST['_sale_price'])); } else { update_post_meta($post_id, '_price', $_POST['_regular_price'] === '' ? '' : wc_format_decimal($_POST['_regular_price'])); } if ('' !== $_POST['_sale_price'] && $date_from && strtotime($date_from) < strtotime('NOW', current_time('timestamp'))) { update_post_meta($post_id, '_price', wc_format_decimal($_POST['_sale_price'])); } if ($date_to && strtotime($date_to) < strtotime('NOW', current_time('timestamp'))) { update_post_meta($post_id, '_price', $_POST['_regular_price'] === '' ? '' : wc_format_decimal($_POST['_regular_price'])); update_post_meta($post_id, '_sale_price_dates_from', ''); update_post_meta($post_id, '_sale_price_dates_to', ''); } // reset price is discounted checkbox was not checked if (!isset($_POST['_discounted_price'])) { update_post_meta($post_id, '_price', wc_format_decimal($_POST['_regular_price'])); update_post_meta($post_id, '_regular_price', wc_format_decimal($_POST['_regular_price'])); update_post_meta($post_id, '_sale_price', ''); } // Sold Individuall if (isset($_POST['_sold_individually'])) { update_post_meta($post_id, '_sold_individually', 'yes'); } else { update_post_meta($post_id, '_sold_individually', ''); } // Stock Data if (get_option('woocommerce_manage_stock') == 'yes') { if (!empty($_POST['_manage_stock'])) { // Manage stock update_post_meta($post_id, '_stock', (int) $_POST['_stock']); update_post_meta($post_id, '_stock_status', stripslashes($_POST['_stock_status'])); update_post_meta($post_id, '_backorders', stripslashes($_POST['_backorders'])); update_post_meta($post_id, '_manage_stock', 'yes'); // Check stock level if ($product_type !== 'variable' && $_POST['_backorders'] == 'no' && (int) $_POST['_stock'] < 1) { update_post_meta($post_id, '_stock_status', 'outofstock'); } } else { // Don't manage stock update_post_meta($post_id, '_stock', ''); update_post_meta($post_id, '_stock_status', stripslashes($_POST['_stock_status'])); update_post_meta($post_id, '_backorders', stripslashes($_POST['_backorders'])); update_post_meta($post_id, '_manage_stock', 'no'); } } else { update_post_meta($post_id, '_stock_status', stripslashes($_POST['_stock_status'])); } // Upsells if (isset($_POST['upsell_ids'])) { $upsells = array(); $ids = $_POST['upsell_ids']; foreach ($ids as $id) { if ($id && $id > 0) { $upsells[] = $id; } } update_post_meta($post_id, '_upsell_ids', $upsells); } else { delete_post_meta($post_id, '_upsell_ids'); } // Cross sells if (isset($_POST['crosssell_ids'])) { $crosssells = array(); $ids = $_POST['crosssell_ids']; foreach ($ids as $id) { if ($id && $id > 0) { $crosssells[] = $id; } } update_post_meta($post_id, '_crosssell_ids', $crosssells); } else { delete_post_meta($post_id, '_crosssell_ids'); } // Downloadable options if ($is_downloadable == 'yes') { // file paths will be stored in an array keyed off md5(file path) if (isset($_POST['_wc_file_urls'])) { $files = array(); $file_names = isset($_POST['_wc_file_names']) ? array_map('wc_clean', $_POST['_wc_file_names']) : array(); $file_urls = isset($_POST['_wc_file_urls']) ? array_map('esc_url_raw', array_map('trim', $_POST['_wc_file_urls'])) : array(); $file_url_size = sizeof($file_urls); for ($i = 0; $i < $file_url_size; $i++) { if (!empty($file_urls[$i])) { $files[md5($file_urls[$i])] = array('name' => $file_names[$i], 'file' => $file_urls[$i]); } } // 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, 0, $files); update_post_meta($post_id, '_downloadable_files', $files); } } // Do action for product type do_action('woocommerce_process_product_meta_simple', $post_id); do_action('dokan_process_product_meta', $post_id); // Clear cache/transients wc_delete_product_transients($post_id); }
/** * Removes variations etc belonging to a deleted post, and clears transients * * @param mixed $id ID of post being deleted */ public function delete_post($id) { global $woocommerce, $wpdb; if (!current_user_can('delete_posts')) { return; } if ($id > 0) { $post_type = get_post_type($id); switch ($post_type) { case 'product': $child_product_variations = get_children('post_parent=' . $id . '&post_type=product_variation'); if (!empty($child_product_variations)) { foreach ($child_product_variations as $child) { wp_delete_post($child->ID, true); } } $child_products = get_children('post_parent=' . $id . '&post_type=product'); if (!empty($child_products)) { foreach ($child_products as $child) { $child_post = array(); $child_post['ID'] = $child->ID; $child_post['post_parent'] = 0; wp_update_post($child_post); } } if ($parent_id = wp_get_post_parent_id($id)) { wc_delete_product_transients($parent_id); } break; case 'product_variation': wc_delete_product_transients(wp_get_post_parent_id($id)); break; case 'shop_order': $refunds = $wpdb->get_results($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'shop_order_refund' AND post_parent = %d", $id)); if (!is_null($refunds)) { foreach ($refunds as $refund) { wp_delete_post($refund->ID, true); } } break; } } }
/** * Clear all transients cache for product data. * * @param int $post_id (default: 0) */ function wc_delete_product_transients($post_id = 0) { // Core transients $transients_to_clear = array('wc_products_onsale', 'wc_featured_products', 'wc_outofstock_count', 'wc_low_stock_count'); // Transient names that include an ID $post_transient_names = array('wc_product_children_', 'wc_product_total_stock_', 'wc_var_prices_', 'wc_related_'); if ($post_id > 0) { foreach ($post_transient_names as $transient) { $transients_to_clear[] = $transient . $post_id; } // Does this product have a parent? if ($parent_id = wp_get_post_parent_id($post_id)) { wc_delete_product_transients($parent_id); } } // Delete transients foreach ($transients_to_clear as $transient) { delete_transient($transient); } // Increments the transient version to invalidate cache WC_Cache_Helper::get_transient_version('product', true); do_action('woocommerce_delete_product_transients', $post_id); }
/** * Clear any caches. * * @param WC_Product * @since 2.7.0 */ protected function clear_caches(&$product) { wc_delete_product_transients($product->get_id()); wp_cache_delete('product-' . $product->get_id(), 'products'); }
/** * Delete a single item. * * @param WP_REST_Request $request Full details about the request. * @return WP_REST_Response|WP_Error */ public function delete_item($request) { $id = (int) $request['id']; $force = (bool) $request['force']; $post = get_post($id); $product = wc_get_product($id); if (!empty($post->post_type) && 'product_variation' === $post->post_type && 'product' === $this->post_type) { return new WP_Error("woocommerce_rest_invalid_{$this->post_type}_id", __('To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce'), array('status' => 404)); } elseif (empty($id) || empty($post->ID) || $post->post_type !== $this->post_type) { return new WP_Error("woocommerce_rest_{$this->post_type}_invalid_id", __('Invalid post ID.', 'woocommerce'), array('status' => 404)); } $supports_trash = EMPTY_TRASH_DAYS > 0; /** * Filter whether an item is trashable. * * Return false to disable trash support for the item. * * @param boolean $supports_trash Whether the item type support trashing. * @param WP_Post $post The Post object being considered for trashing support. */ $supports_trash = apply_filters("woocommerce_rest_{$this->post_type}_trashable", $supports_trash, $post); if (!wc_rest_check_post_permissions($this->post_type, 'delete', $post->ID)) { /* translators: %s: post type */ return new WP_Error("woocommerce_rest_user_cannot_delete_{$this->post_type}", sprintf(__('Sorry, you are not allowed to delete %s.', 'woocommerce'), $this->post_type), array('status' => rest_authorization_required_code())); } $request->set_param('context', 'edit'); $response = $this->prepare_item_for_response($post, $request); // If we're forcing, then delete permanently. if ($force) { if ($product->is_type('variable')) { foreach ($product->get_children() as $child_id) { $child = wc_get_product($child_id); $child->delete(true); } } elseif ($product->is_type('grouped')) { foreach ($product->get_children() as $child_id) { $child = wc_get_product($child_id); $child->set_parent_id(0); $child->save(); } } $product->delete(true); $result = $product->get_id() > 0 ? false : true; } else { // If we don't support trashing for this type, error out. if (!$supports_trash) { /* translators: %s: post type */ return new WP_Error('woocommerce_rest_trash_not_supported', sprintf(__('The %s does not support trashing.', 'woocommerce'), $this->post_type), array('status' => 501)); } // Otherwise, only trash if we haven't already. if ('trash' === $post->post_status) { /* translators: %s: post type */ return new WP_Error('woocommerce_rest_already_trashed', sprintf(__('The %s has already been deleted.', 'woocommerce'), $this->post_type), array('status' => 410)); } // (Note that internally this falls through to `wp_delete_post` if // the trash is disabled.) $product->delete(); $result = 'trash' === $product->get_status(); } if (!$result) { /* translators: %s: post type */ return new WP_Error('woocommerce_rest_cannot_delete', sprintf(__('The %s cannot be deleted.', 'woocommerce'), $this->post_type), array('status' => 500)); } // Delete parent product transients. if ($parent_id = wp_get_post_parent_id($id)) { wc_delete_product_transients($parent_id); } /** * Fires after a single item is deleted or trashed via the REST API. * * @param object $post The deleted or trashed item. * @param WP_REST_Response $response The response data. * @param WP_REST_Request $request The request sent to the API. */ do_action("woocommerce_rest_delete_{$this->post_type}", $post, $response, $request); return $response; }
function woo_pi_ajax_product_importer() { if (isset($_POST['step'])) { global $import; @ini_set('memory_limit', WP_MAX_MEMORY_LIMIT); ob_start(); // Split the CSV data from the main transient if ($_POST['step'] != 'prepare_data') { $import = get_transient(WOO_PI_PREFIX . '_import'); if (is_object($import)) { if (isset($_POST['settings']) && !is_string($_POST['settings'])) { foreach ($_POST['settings'] as $key => $value) { if (is_array($value)) { foreach ($value as $value_key => $value_value) { if (!is_array($value_value)) { $value[$value_key] = stripslashes($value_value); } } $import->{$key} = $value; } else { $import->{$key} = stripslashes($value); } } } // Merge the split transients into the $import global if (isset($import->headers)) { $args = array('generate_categories', 'generate_tags', 'prepare_product_import', 'save_product'); foreach ($import->headers as $header) { // Exclude $import->csv_category and $import->csv_brand for most of the import if (in_array($header, array('category', 'brand'))) { if (in_array($_POST['step'], $args)) { $import->{'csv_' . $header} = get_transient(WOO_PI_PREFIX . '_csv_' . $header); } } else { $import->{'csv_' . $header} = get_transient(WOO_PI_PREFIX . '_csv_' . $header); } } } } else { $import = new stdClass(); $import->cancel_import = true; $troubleshooting_url = 'http://www.visser.com.au/woocommerce/documentation/plugins/product-importer-deluxe/usage/'; $import->failed_import = sprintf(__('Your CSV contained special characters that WordPress and Product Importer Deluxe could not filter. %s', 'woo_pi'), __('Need help?', 'woo_pi') . ' ' . $troubleshooting_url); } } $timeout = 0; if (isset($import->timeout)) { $timeout = $import->timeout; } if (!ini_get('safe_mode')) { @set_time_limit($timeout); } switch ($_POST['step']) { case 'prepare_data': $import = new stdClass(); $import->start_time = time(); $import->cancel_import = false; $import->failed_import = ''; $import->log = ''; $import->timeout = isset($_POST['timeout']) ? $_POST['timeout'] : false; $import->delimiter = $_POST['delimiter']; $import->category_separator = $_POST['category_separator']; $import->parent_child_delimiter = $_POST['parent_child_delimiter']; $import->delete_file = woo_pi_get_option('delete_file', 0); $import->import_method = isset($_POST['import_method']) ? $_POST['import_method'] : 'new'; $import->advanced_log = isset($_POST['advanced_log']) ? (int) $_POST['advanced_log'] : 0; $import->log .= '<br />' . sprintf(__('Import method: %s', 'woo_pi'), $import->import_method); woo_pi_prepare_data('prepare_data'); if ($import->advanced_log) { $import->log .= "<br />" . __('Validating required columns...', 'woo_pi'); } if (!$import->cancel_import) { woo_pi_prepare_columns(); } $import->skip_first = $_POST['skip_first']; $import->log .= "<br />" . __('Product columns have been grouped', 'woo_pi'); $import->log .= "<br /><br />" . __('Generating Categories...', 'woo_pi'); $import->loading_text = __('Generating Categories...', 'woo_pi'); break; case 'generate_categories': $import->products_added = 0; $import->products_deleted = 0; $import->products_failed = 0; // Category generation if (in_array($import->import_method, array('new')) && isset($import->csv_category)) { woo_pi_generate_categories(); } else { $import->log .= "<br />" . __('Categories skipped', 'woo_pi'); } $import->log .= "<br /><br />" . __('Generating Tags...', 'woo_pi'); $import->loading_text = __('Generating Tags...', 'woo_pi'); break; case 'generate_tags': // Tag generation if (in_array($import->import_method, array('new')) && isset($import->csv_tag)) { woo_pi_generate_tags(); } else { $import->log .= "<br />" . __('Tags skipped', 'woo_pi'); } if ($import->import_method == 'new') { $import->log .= "<br /><br />" . __('Generating Products...', 'woo_pi'); } else { if ($import->import_method == 'delete') { $import->log .= "<br /><br />" . __('Checking for matching Products to delete...', 'woo_pi'); } } $import->loading_text = __('Importing Products...', 'woo_pi'); break; case 'prepare_product_import': global $import, $product; if ($import->advanced_log) { $import->log .= "<br />>>> " . __('Including non-essential reporting in this import log', 'woo_pi'); } if ($import->skip_first) { $import->i = 1; $import->log .= "<br />>>> " . __('Skipping import of first CSV row', 'woo_pi'); } else { $import->i = 0; $import->log .= "<br />>>> " . __('Starting import at first CSV row', 'woo_pi'); } $import->failed_products = array(); $i = $import->i; woo_pi_prepare_product($i); // This runs once as part of the import preparation $import->active_product = $product; if ($import->import_method == 'delete') { if (!empty($product->name)) { $import->log .= "<br />>>> " . sprintf(__('Searching for %s...', 'woo_pi'), $product->name); } else { $import->log .= "<br />>>> " . sprintf(__('Searching for (no title) - SKU: %s...', 'woo_pi'), $product->sku); } $import->loading_text = sprintf(__('Searching for Product %d of %d...', 'woo_pi'), $i, $import->skip_first ? $import->rows - 1 : $import->rows); } else { if (!empty($product->name)) { $import->log .= "<br />>>> " . sprintf(__('Importing %s...', 'woo_pi'), $product->name); } else { $import->log .= "<br />>>> " . sprintf(__('Importing (no title) - SKU: %s...', 'woo_pi'), $product->sku); } $import->loading_text = sprintf(__('Importing Product %d of %d...', 'woo_pi'), $i, $import->skip_first ? $import->rows - 1 : $import->rows); } break; case 'save_product': global $import, $product; $i = $_POST['i']; if ($import->active_product) { if (!isset($product)) { $product = new stdClass(); } foreach ($import->active_product as $key => $value) { $product->{$key} = $value; } } $import->product_start_time = microtime(true); if (in_array($import->import_method, array('new'))) { // Build Categories woo_pi_process_categories(); // Build Tags woo_pi_process_tags(); } // Check for duplicate SKU woo_pi_duplicate_product_exists(); woo_pi_validate_product(); if ($product->fail_requirements) { if ($import->advanced_log) { $import->log .= "<br />>>>>>> " . sprintf(__('Skipping Product, see Import Report for full explanation. Reason: %s', 'woo_pi'), $product->failed_reason); } else { $import->log .= "<br />>>>>>> " . sprintf(__('Skipping Product, reason: %s', 'woo_pi'), $product->failed_reason); } $import->products_failed++; } else { if ($import->import_method == 'delete' && $product->duplicate_exists) { woo_pi_delete_product(); } else { if (in_array($import->import_method, array('new')) && !$product->duplicate_exists) { woo_pi_create_product(); } } if ($import->import_method == 'delete') { if ($product->deleted) { if (!empty($product->name)) { $import->log .= "<br />>>>>>> " . sprintf(__('%s successfully deleted', 'woo_pi'), $product->name); } else { $import->log .= "<br />>>>>>> " . sprintf(__('(no title) - SKU: %s successfully deleted', 'woo_pi'), $product->sku); } } else { if ($import->advanced_log) { $import->log .= "<br />>>>>>> " . sprintf(__('Skipping Product, see Import Report for full explanation. Reason: %s', 'woo_pi'), $product->failed_reason); } else { $import->log .= "<br />>>>>>> " . sprintf(__('Skipping Product, reason: %s', 'woo_pi'), $product->failed_reason); } } } else { if ($product->imported) { if ($import->import_method == 'new') { if (!empty($product->name)) { $import->log .= "<br />>>>>>> " . sprintf(__('%s successfully imported', 'woo_pi'), $product->name); } else { $import->log .= "<br />>>>>>> " . sprintf(__('(no title) - SKU: %s successfully imported', 'woo_pi'), $product->sku); } } } else { if ($import->advanced_log) { $import->log .= "<br />>>>>>> " . sprintf(__('Skipping Product, see Import Report for full explanation. Reason: %s', 'woo_pi'), $product->failed_reason); } else { $import->log .= "<br />>>>>>> " . sprintf(__('Skipping Product, reason: %s', 'woo_pi'), $product->failed_reason); } } } } $import->product_end_time = microtime(true); $import->product_min_time = isset($import->product_min_time) ? $import->product_min_time : $import->product_end_time - $import->product_start_time; $import->product_max_time = isset($import->product_max_time) ? $import->product_max_time : $import->product_end_time - $import->product_start_time; // Update minimum product import time if it is shorter than the last if ($import->product_end_time - $import->product_start_time < $import->product_min_time) { $import->product_min_time = $import->product_end_time - $import->product_start_time; } // Update maximum product import time if it is longer than the last if ($import->product_end_time - $import->product_start_time > $import->product_max_time) { $import->product_max_time = $import->product_end_time - $import->product_start_time; } // All import rows have been processed if ($i + 1 == $import->rows) { if ($import->import_method == 'new') { $import->log .= "<br />" . __('Products have been generated', 'woo_pi'); } else { if ($import->import_method == 'delete') { $import->log .= "<br />" . __('Products have been deleted', 'woo_pi'); } } $import->log .= "<br /><br />" . __('Cleaning up...', 'woo_pi'); $import->loading_text = __('Cleaning up...', 'woo_pi'); } else { unset($import->active_product); woo_pi_prepare_product($i + 1); // This runs for each additional Product imported $import->active_product = $product; if ($import->import_method == 'delete') { if (!empty($product->name)) { $import->log .= "<br />>>> " . sprintf(__('Searching for %s...', 'woo_pi'), $product->name); } else { $import->log .= "<br />>>> " . sprintf(__('Searching for (no title) - SKU: %s...', 'woo_pi'), $product->sku); } $import->loading_text = sprintf(__('Searching for Product %d of %d...', 'woo_pi'), $i + 1, $import->skip_first ? $import->rows - 1 : $import->rows); } else { if (!empty($product->name)) { $import->log .= "<br />>>> " . sprintf(__('Importing %s...', 'woo_pi'), $product->name); } else { $import->log .= "<br />>>> " . sprintf(__('Importing (no title) - SKU: %s...', 'woo_pi'), $product->sku); } $import->loading_text = sprintf(__('Importing Product %d of %d...', 'woo_pi'), $i + 1, $import->skip_first ? $import->rows - 1 : $import->rows); } } break; case 'clean_up': global $wpdb, $product; // Organise Categories if (isset($import->csv_category)) { $term_taxonomy = 'product_cat'; $import->log .= "<br />>>> " . __('Organise Categories', 'woo_pi'); } // Organise Tags if (isset($import->csv_tag)) { $import->log .= "<br />>>> " . __('Organise Tags', 'woo_pi'); } $import->log .= "<br />" . __('Clean up has completed', 'woo_pi'); $import->end_time = time(); // Post-import Product details if ($import->advanced_log) { $import->log .= "<br /><br />" . __('Import summary', 'woo_pi'); if (in_array($import->import_method, array('new', 'merge'))) { $import->log .= "<br />>>> " . sprintf(__('%d Products added', 'woo_pi'), $import->products_added); } else { if ($import->import_method == 'delete') { $import->log .= "<br />>>> " . sprintf(__('%d Products deleted', 'woo_pi'), $import->products_deleted); } } $import->log .= "<br />>>> " . sprintf(__('%d Products skipped', 'woo_pi'), $import->products_failed); $import->log .= "<br />>>> " . sprintf(__('Import took %s to complete', 'woo_pi'), woo_pi_display_time_elapsed($import->start_time, $import->end_time)); $import->log .= "<br />>>> " . sprintf(__('Fastest Product took < %s to process', 'woo_pi'), woo_pi_display_time_elapsed(time(), strtotime(sprintf('+%d seconds', $import->product_min_time)))); $import->log .= "<br />>>> " . sprintf(__('Slowest Product took > %s to process', 'woo_pi'), woo_pi_display_time_elapsed(time(), strtotime(sprintf('+%d seconds', $import->product_max_time)))); } $import->log .= "<br /><br />" . __('Import complete!', 'woo_pi'); $import->loading_text = __('Completed', 'woo_pi'); break; } // Clear transients if (function_exists('wc_delete_product_transients')) { wc_delete_product_transients(); } $import->step = $_POST['step']; $import->errors = ob_get_clean(); // Encode our transients in UTF-8 before storing them add_filter('pre_set_transient_woo_pi_import', 'woo_pi_filter_set_transient'); // Split the import data from the main transient if (isset($import->headers)) { foreach ($import->headers as $header) { if (isset($import->{'csv_' . $header})) { $response = set_transient(WOO_PI_PREFIX . '_csv_' . $header, $import->{'csv_' . $header}); // Check if the Transient was saved if (is_wp_error($response)) { error_log(sprintf(__('[product-importer] Could not save the import data Transient for the column %s', 'woo_pi'), $header)); } unset($import->{'csv_' . $header}); } } } $response = set_transient(WOO_PI_PREFIX . '_import', $import); // Check if the Transient was saved if (is_wp_error($response)) { error_log('[product-importer] Could not save the import Transient prior to starting AJAX import engine', 'woo_pi'); } $return = array(); if (isset($import->log)) { $return['log'] = $import->log; } if (isset($import->rows)) { $return['rows'] = $import->rows; } if (isset($import->skip_first)) { $return['skip_first'] = $import->skip_first; } if (isset($import->loading_text)) { $return['loading_text'] = $import->loading_text; } if (isset($import->cancel_import)) { $return['cancel_import'] = $import->cancel_import; } if (isset($import->failed_import)) { $return['failed_import'] = $import->failed_import; } if (isset($i)) { $return['i'] = $i; } if (isset($import->next)) { $return['next'] = $import->next; } if (isset($import->html)) { $return['html'] = $import->html; } if (isset($import->step)) { $return['step'] = $import->step; } @array_map('utf8_encode', $return); header("Content-type: application/json"); echo json_encode($return); } die; }
/** * Install WC */ public function install() { $this->create_options(); $this->create_tables(); $this->create_roles(); // Register post types include_once 'class-wc-post-types.php'; WC_Post_types::register_taxonomies(); $this->create_terms(); $this->create_cron_jobs(); $this->create_files(); $this->create_css_from_less(); // Clear transient cache wc_delete_product_transients(); // Queue upgrades $current_version = get_option('woocommerce_version', null); $current_db_version = get_option('woocommerce_db_version', null); if (version_compare($current_db_version, '2.1.0', '<') && null !== $current_db_version) { update_option('_wc_needs_update', 1); } else { update_option('woocommerce_db_version', WC()->version); } // Update version update_option('woocommerce_version', WC()->version); // Check if pages are needed if (wc_get_page_id('shop') < 1) { update_option('_wc_needs_pages', 1); } // Flush rewrite rules flush_rewrite_rules(); // Redirect to welcome screen set_transient('_wc_activation_redirect', 1, 60 * 60); }
public function run_import() { global $woocsv_product; /** * Are we starting for the first time, than create a batch and continue, else just pick uo the batch code and start where you left */ do_action('woocsv_start_import'); if (empty($_POST['batch_code'])) { //create a new batch $batch_code = woocsv_batches::create(); if ($batch_code) { //get max time we have and set the block size $max_execution_time = @ini_get('max_execution_time'); if ($max_execution_time == 0) { $max_execution_time = 30; } $block_size = $this->get_blocksize(); $data = array('filename' => $_POST['filename'], 'row' => 0, 'block_size' => $block_size, 'header_name' => $_POST['header_name'], 'seperator' => $_POST['seperator'], 'total_rows' => (int) $_POST['total_rows'], 'start_date' => time(), 'max_execution_time' => $max_execution_time); woocsv_batches::update($batch_code, $data); } else { //@todo die nice } //and get the batch $batch = woocsv_batches::get_batch($batch_code); } else { $batch_code = $_POST['batch_code']; $batch = woocsv_batches::get_batch($_POST['batch_code']); } //lets check if we are done? if ($batch['row'] >= $batch['total_rows']) { $batch['end_date'] = time(); $batch['status'] = 'done'; woocsv_batches::update($batch_code, $batch); do_action('woocsv_after_import_finished'); //@todo DIE NICE $this->die_nicer($batch_code, $batch); } // do we need to skip the first line? if ($this->get_skip_first_line() == 1 && $batch['row'] == 0) { $batch['row'] = 1; } //get the from and till $from = $batch['row']; $till = $batch['row'] + $batch['block_size'] < $batch['total_rows'] ? $batch['row'] + $batch['block_size'] : $batch['total_rows']; //get the lines $lines = $this->get_lines_from_file($batch['filename'], $from, $till, $batch['seperator']); //get the header $header = $this->get_header_from_name($batch['header_name']); //turn stuff off if (function_exists('wp_suspend_cache_invalidation')) { wp_suspend_cache_invalidation(true); } if (function_exists('wp_defer_term_counting ')) { wp_defer_term_counting(true); } $time_started = microtime(true); //loop over the lines and fill,pase and save the lines foreach ($lines['lines'] as $line) { //reset time ever time around @set_time_limit(0); //new one and fill in the header and the raw data $woocsv_product = new woocsv_import_product(); $woocsv_product->header = $header; $woocsv_product->raw_data = $line; //fill it, parse it and save it $woocsv_product->fill_in_data(); $this->write_to_log($batch_code, '-----> row: ' . $batch['row']); $woocsv_product->parse_data(); $this->write_to_log($batch_code, $woocsv_product->log); $woocsv_product->save(); $this->write_to_log($batch_code, $woocsv_product->log); //write tot log if debug is on if ($this->get_debug() == 0) { $this->write_to_log($batch_code, '-----> product dump'); $this->write_to_log($batch_code, $woocsv_product); } //close log $this->write_to_log($batch_code, '-----> end row: ' . $batch['row']); $this->write_to_log($batch_code, ''); //goto the next row $batch['row']++; //delete transionts if (function_exists('wc_delete_product_transients')) { wc_delete_product_transients($woocsv_product->body['ID']); } } $time_finished = microtime(true); if (!$this->get_blocksize()) { $time_factor = ceil(($batch['max_execution_time'] - ($time_finished - $time_started)) / $batch['max_execution_time'] * 100); switch ($time_factor) { case $time_factor > 90: $block_size = 10; break; case $time_factor > 50: $block_size = 5; break; case $time_factor > 10: $block_size = 1; break; default: $block_size = 0; } $batch['block_size'] += $block_size; woocsv_batches::update($batch_code, $batch); } $this->die_nicer($batch_code, $batch); }
/** * @deprecated 2.1.0 * @param int $post_id */ public function clear_product_transients($post_id = 0) { _deprecated_function('Woocommerce->clear_product_transients', '2.1', 'wc_delete_product_transients'); wc_delete_product_transients($post_id); }
/** * 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; }
/** * Handles output of tools */ public static function status_tools() { global $wpdb; $tools = self::get_tools(); if (!empty($_GET['action']) && !empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'debug_action')) { switch ($_GET['action']) { case 'clear_transients': wc_delete_product_transients(); wc_delete_shop_order_transients(); WC_Cache_Helper::get_transient_version('shipping', true); echo '<div class="updated"><p>' . __('Product Transients Cleared', 'woocommerce') . '</p></div>'; break; case 'clear_expired_transients': // http://w-shadow.com/blog/2012/04/17/delete-stale-transients/ $rows = $wpdb->query("\n\t\t\t\t\t\tDELETE\n\t\t\t\t\t\t\ta, b\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t{$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\ta.option_name LIKE '_transient_%' AND\n\t\t\t\t\t\t\ta.option_name NOT LIKE '_transient_timeout_%' AND\n\t\t\t\t\t\t\tb.option_name = CONCAT(\n\t\t\t\t\t\t\t\t'_transient_timeout_',\n\t\t\t\t\t\t\t\tSUBSTRING(\n\t\t\t\t\t\t\t\t\ta.option_name,\n\t\t\t\t\t\t\t\t\tCHAR_LENGTH('_transient_') + 1\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tAND b.option_value < UNIX_TIMESTAMP()\n\t\t\t\t\t"); $rows2 = $wpdb->query("\n\t\t\t\t\t\tDELETE\n\t\t\t\t\t\t\ta, b\n\t\t\t\t\t\tFROM\n\t\t\t\t\t\t\t{$wpdb->options} a, {$wpdb->options} b\n\t\t\t\t\t\tWHERE\n\t\t\t\t\t\t\ta.option_name LIKE '_site_transient_%' AND\n\t\t\t\t\t\t\ta.option_name NOT LIKE '_site_transient_timeout_%' AND\n\t\t\t\t\t\t\tb.option_name = CONCAT(\n\t\t\t\t\t\t\t\t'_site_transient_timeout_',\n\t\t\t\t\t\t\t\tSUBSTRING(\n\t\t\t\t\t\t\t\t\ta.option_name,\n\t\t\t\t\t\t\t\t\tCHAR_LENGTH('_site_transient_') + 1\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tAND b.option_value < UNIX_TIMESTAMP()\n\t\t\t\t\t"); echo '<div class="updated"><p>' . sprintf(__('%d Transients Rows Cleared', 'woocommerce'), $rows + $rows2) . '</p></div>'; break; case 'reset_roles': // Remove then re-add caps and roles WC_Install::remove_roles(); WC_Install::create_roles(); echo '<div class="updated"><p>' . __('Roles successfully reset', 'woocommerce') . '</p></div>'; break; case 'recount_terms': $product_cats = get_terms('product_cat', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_cats, get_taxonomy('product_cat'), true, false); $product_tags = get_terms('product_tag', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_tags, get_taxonomy('product_tag'), true, false); echo '<div class="updated"><p>' . __('Terms successfully recounted', 'woocommerce') . '</p></div>'; break; case 'clear_sessions': $wpdb->query("\n\t\t\t\t\t\tDELETE FROM {$wpdb->options}\n\t\t\t\t\t\tWHERE option_name LIKE '_wc_session_%' OR option_name LIKE '_wc_session_expires_%'\n\t\t\t\t\t"); wp_cache_flush(); echo '<div class="updated"><p>' . __('Sessions successfully cleared', 'woocommerce') . '</p></div>'; break; case 'install_pages': WC_Install::create_pages(); echo '<div class="updated"><p>' . __('All missing WooCommerce pages was installed successfully.', 'woocommerce') . '</p></div>'; break; case 'delete_taxes': $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rates"); $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rate_locations"); echo '<div class="updated"><p>' . __('Tax rates successfully deleted', 'woocommerce') . '</p></div>'; break; case 'reset_tracking': delete_option('woocommerce_allow_tracking'); WC_Admin_Notices::add_notice('tracking'); echo '<div class="updated"><p>' . __('Usage tracking settings successfully reset.', 'woocommerce') . '</p></div>'; break; default: $action = esc_attr($_GET['action']); if (isset($tools[$action]['callback'])) { $callback = $tools[$action]['callback']; $return = call_user_func($callback); if ($return === false) { if (is_array($callback)) { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s::%s', 'woocommerce'), get_class($callback[0]), $callback[1]) . '</p></div>'; } else { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s', 'woocommerce'), $callback) . '</p></div>'; } } } break; } } // Manual translation update messages if (isset($_GET['translation_updated'])) { switch ($_GET['translation_updated']) { case 2: echo '<div class="error"><p>' . __('Failed to install/update the translation:', 'woocommerce') . ' ' . __('Seems you don\'t have permission to do this!', 'woocommerce') . '</p></div>'; break; case 3: echo '<div class="error"><p>' . __('Failed to install/update the translation:', 'woocommerce') . ' ' . sprintf(__('An authentication error occurred while updating the translation. Please try again or configure your %sUpgrade Constants%s.', 'woocommerce'), '<a href="http://codex.wordpress.org/Editing_wp-config.php#WordPress_Upgrade_Constants">', '</a>') . '</p></div>'; break; case 4: echo '<div class="error"><p>' . __('Failed to install/update the translation:', 'woocommerce') . ' ' . __('Sorry but there is no translation available for your language =/', 'woocommerce') . '</p></div>'; break; default: // Force WordPress find for new updates and hide the WooCommerce translation update set_site_transient('update_plugins', null); echo '<div class="updated"><p>' . __('Translations installed/updated successfully!', 'woocommerce') . '</p></div>'; break; } } // Display message if settings settings have been saved if (isset($_REQUEST['settings-updated'])) { echo '<div class="updated"><p>' . __('Your changes have been saved.', 'woocommerce') . '</p></div>'; } include_once 'views/html-admin-page-status-tools.php'; }
/** * Sync variable product prices with the childs lowest/highest prices. * * @access public * @return void */ public function variable_product_sync($product_id = '') { global $woocommerce; parent::variable_product_sync(); $children = get_posts(array('post_parent' => $this->id, 'posts_per_page' => -1, 'post_type' => 'product_variation', 'fields' => 'ids', 'post_status' => 'publish')); $lowest_initial_amount = $highest_initial_amount = $lowest_price = $highest_price = ''; $shortest_initial_period = $longest_initial_period = $shortest_trial_period = $longest_trial_period = $shortest_trial_length = $longest_trial_length = ''; $longest_initial_interval = $shortest_initial_interval = $variable_subscription_period = $variable_subscription_period_interval = ''; $lowest_regular_price = $highest_regular_price = $lowest_sale_price = $highest_sale_price = $max_subscription_period = $max_subscription_period_interval = ''; $variable_subscription_sign_up_fee = $variable_subscription_trial_period = $variable_subscription_trial_length = $variable_subscription_length = $variable_subscription_sign_up_fee = $variable_subscription_trial_period = $variable_subscription_trial_length = $variable_subscription_length = ''; $min_variation_id = $max_variation_id = NULL; if ($children) { foreach ($children as $child) { $is_max = $is_min = false; // WC has already determined the correct price which accounts for sale price $child_price = get_post_meta($child, '_price', true); $child_billing_period = get_post_meta($child, '_subscription_period', true); $child_billing_interval = get_post_meta($child, '_subscription_period_interval', true); $child_sign_up_fee = get_post_meta($child, '_subscription_sign_up_fee', true); $child_free_trial_length = get_post_meta($child, '_subscription_trial_length', true); $child_free_trial_period = get_post_meta($child, '_subscription_trial_period', true); if ($child_price === '' && $child_sign_up_fee === '') { continue; } $child_price = $child_price === '' ? 0 : $child_price; $child_sign_up_fee = $child_sign_up_fee === '' ? 0 : $child_sign_up_fee; $has_free_trial = $child_free_trial_length !== '' && $child_free_trial_length > 0 ? true : false; // Determine some recurring price flags $is_lowest_price = $child_price < $lowest_price || '' === $lowest_price ? true : false; $is_longest_period = $child_billing_period === WC_Subscriptions::get_longest_period($variable_subscription_period, $child_billing_period) ? true : false; $is_longest_interval = $child_billing_interval >= $variable_subscription_period_interval || '' === $variable_subscription_period_interval ? true : false; // Find the amount the subscriber will have to pay up-front if ($has_free_trial) { $initial_amount = $child_sign_up_fee; $initial_period = $child_free_trial_period; $initial_interval = $child_free_trial_length; } else { $initial_amount = $child_price + $child_sign_up_fee; $initial_period = $child_billing_period; $initial_interval = $child_billing_interval; } // We have a free trial & no sign-up fee, so need to choose the longest free trial (and maybe the shortest) if ($has_free_trial && $child_sign_up_fee == 0) { // First variation if ('' === $longest_trial_period) { $is_min = true; // If two variations have the same free trial, choose the variation with the lowest recurring price for the longest period } elseif ($variable_subscription_trial_period === $child_free_trial_period && $child_free_trial_length === $variable_subscription_trial_length) { // If the variation has the lowest recurring price, it's the cheapest if ($is_lowest_price) { $is_min = true; // When current variation's free trial is the same as the lowest, it's the cheaper if it has a longer billing schedule } elseif ($child_price === $lowest_price) { if ($is_longest_period && $is_longest_interval) { $is_min = true; // Longest with a new billing period } elseif ($is_longest_period && $child_billing_period !== $variable_subscription_trial_period) { $is_min = true; } } // Otherwise the cheapest variation is the one with the longer trial } elseif ($variable_subscription_trial_period === $child_free_trial_period) { $is_min = $child_free_trial_length > $variable_subscription_trial_length ? true : false; // Otherwise just a longer trial period (that isn't equal to the longest period) } elseif ($child_free_trial_period === WC_Subscriptions::get_longest_period($longest_trial_period, $child_free_trial_period)) { $is_min = true; } if ($is_min) { $longest_trial_period = $child_free_trial_period; $longest_trial_length = $child_free_trial_length; } // If the current cheapest variation is also free then the shortest trial period is the most expensive if (0 == $lowest_price || '' === $lowest_price) { if ('' === $shortest_trial_period) { $is_max = true; // Need to check trial length } elseif ($shortest_trial_period === $child_free_trial_period) { $is_max = $child_free_trial_length < $shortest_trial_length ? true : false; // Need to find shortest period } elseif ($child_free_trial_period === WC_Subscriptions::get_shortest_period($shortest_trial_period, $child_free_trial_period)) { $is_max = true; } if ($is_max) { $shortest_trial_period = $child_free_trial_period; $shortest_trial_length = $child_free_trial_length; } } } else { $longest_initial_period = WC_Subscriptions::get_longest_period($longest_initial_period, $initial_period); $shortest_initial_period = WC_Subscriptions::get_shortest_period($shortest_initial_period, $initial_period); $is_lowest_initial_amount = $initial_amount < $lowest_initial_amount || '' === $lowest_initial_amount ? true : false; $is_longest_initial_period = $initial_period === $longest_initial_period ? true : false; $is_longest_initial_interval = $initial_interval >= $longest_initial_interval || '' === $longest_initial_interval ? true : false; $is_highest_initial = $initial_amount > $highest_initial_amount || '' === $highest_initial_amount ? true : false; $is_shortest_period = $initial_period === $shortest_initial_period || '' === $shortest_initial_period ? true : false; $is_shortest_interval = $initial_interval < $shortest_initial_interval || '' === $shortest_initial_interval ? true : false; // If we're not dealing with the lowest initial access amount, then ignore this variation if (!$is_lowest_initial_amount && $initial_amount !== $lowest_initial_amount) { continue; } // If the variation has the lowest price, it's the cheapest if ($is_lowest_initial_amount) { $is_min = true; // When current variation's price is the same as the lowest, it's the cheapest only if it has a longer billing schedule } elseif ($initial_amount === $lowest_initial_amount) { // We need to check the recurring schedule when the sign-up fee & free trial periods are equal if ($has_free_trial && $initial_period == $longest_initial_period && $initial_interval == $longest_initial_interval) { // If the variation has the lowest recurring price, it's the cheapest if ($is_lowest_price) { $is_min = true; // When current variation's price is the same as the lowest, it's the cheapest only if it has a longer billing schedule } elseif ($child_price === $lowest_price) { if ($is_longest_period && $is_longest_interval) { $is_min = true; // Longest with a new billing period } elseif ($is_longest_period && $child_billing_period !== $variable_subscription_period) { $is_min = true; } } // Longest initial term is the cheapest } elseif ($is_longest_initial_period && $is_longest_initial_interval) { $is_min = true; // Longest with a new billing period } elseif ($is_longest_initial_period && $initial_period !== $longest_initial_period) { $is_min = true; } } // If we have the highest price for the shortest period, we might have the maximum variation if ($is_highest_initial && $is_shortest_period && $is_shortest_interval) { $is_max = true; // But only if its for the shortest billing period } elseif ($child_price === $highest_price) { if ($is_shortest_period && $is_shortest_interval) { $is_max = true; } elseif ($is_shortest_period) { $is_max = true; } } } // If it's the min subscription terms if ($is_min) { $min_variation_id = $child; $lowest_price = $child_price; $lowest_regular_price = get_post_meta($child, '_regular_price', true); $lowest_sale_price = get_post_meta($child, '_sale_price', true); $lowest_regular_price = '' === $lowest_regular_price ? 0 : $lowest_regular_price; $lowest_sale_price = '' === $lowest_sale_price ? 0 : $lowest_sale_price; $lowest_initial_amount = $initial_amount; $longest_initial_period = $initial_period; $longest_initial_interval = $initial_interval; $variable_subscription_sign_up_fee = $child_sign_up_fee; $variable_subscription_period = $child_billing_period; $variable_subscription_period_interval = $child_billing_interval; $variable_subscription_trial_length = $child_free_trial_length; $variable_subscription_trial_period = $child_free_trial_period; $variable_subscription_length = get_post_meta($child, '_subscription_length', true); } if ($is_max) { $max_variation_id = $child; $highest_price = $child_price; $highest_regular_price = get_post_meta($child, '_regular_price', true); $highest_sale_price = get_post_meta($child, '_sale_price', true); $highest_initial_amount = $initial_amount; $highest_regular_price = '' === $highest_regular_price ? 0 : $highest_regular_price; $highest_sale_price = '' === $highest_sale_price ? 0 : $highest_sale_price; $max_subscription_period = $child_billing_period; $max_subscription_period_interval = $child_billing_interval; } } update_post_meta($this->id, '_min_price_variation_id', $min_variation_id); update_post_meta($this->id, '_max_price_variation_id', $max_variation_id); update_post_meta($this->id, '_price', $lowest_price); update_post_meta($this->id, '_min_variation_price', $lowest_price); update_post_meta($this->id, '_max_variation_price', $highest_price); update_post_meta($this->id, '_min_variation_regular_price', $lowest_regular_price); update_post_meta($this->id, '_max_variation_regular_price', $highest_regular_price); update_post_meta($this->id, '_min_variation_sale_price', $lowest_sale_price); update_post_meta($this->id, '_max_variation_sale_price', $highest_sale_price); update_post_meta($this->id, '_min_variation_period', $variable_subscription_period); update_post_meta($this->id, '_max_variation_period', $variable_subscription_period_interval); update_post_meta($this->id, '_min_variation_period_interval', $max_subscription_period); update_post_meta($this->id, '_max_variation_period_interval', $max_subscription_period_interval); update_post_meta($this->id, '_subscription_price', $lowest_price); update_post_meta($this->id, '_subscription_sign_up_fee', $variable_subscription_sign_up_fee); update_post_meta($this->id, '_subscription_period', $variable_subscription_period); update_post_meta($this->id, '_subscription_period_interval', $variable_subscription_period_interval); update_post_meta($this->id, '_subscription_trial_period', $variable_subscription_trial_period); update_post_meta($this->id, '_subscription_trial_length', $variable_subscription_trial_length); update_post_meta($this->id, '_subscription_length', $variable_subscription_length); $this->subscription_price = $lowest_price; $this->subscription_sign_up_fee = $variable_subscription_sign_up_fee; $this->subscription_period = $variable_subscription_period; $this->subscription_period_interval = $variable_subscription_period_interval; $this->subscription_trial_period = $variable_subscription_trial_period; $this->subscription_trial_length = $variable_subscription_trial_length; $this->subscription_length = $variable_subscription_length; if (function_exists('wc_delete_product_transients')) { wc_delete_product_transients($this->id); } else { $woocommerce->clear_product_transients($this->id); } } else { // No variations yet $this->subscription_price = ''; $this->subscription_sign_up_fee = ''; $this->subscription_period = 'day'; $this->subscription_period_interval = 1; $this->subscription_trial_period = 'day'; $this->subscription_trial_length = 1; $this->subscription_length = 0; } }
/** * Handles output of tools */ public static function status_tools() { global $wpdb; $tools = self::get_tools(); if (!empty($_GET['action']) && !empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], 'debug_action')) { switch ($_GET['action']) { case 'clear_transients': wc_delete_product_transients(); wc_delete_shop_order_transients(); WC_Cache_Helper::get_transient_version('shipping', true); echo '<div class="updated"><p>' . __('Product Transients Cleared', 'woocommerce') . '</p></div>'; break; case 'clear_expired_transients': /* * Deletes all expired transients. The multi-table delete syntax is used * to delete the transient record from table a, and the corresponding * transient_timeout record from table b. * * Based on code inside core's upgrade_network() function. */ $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\r\n\t\t\t\t\t\tWHERE a.option_name LIKE %s\r\n\t\t\t\t\t\tAND a.option_name NOT LIKE %s\r\n\t\t\t\t\t\tAND b.option_name = CONCAT( '_transient_timeout_', SUBSTRING( a.option_name, 12 ) )\r\n\t\t\t\t\t\tAND b.option_value < %d"; $rows = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_transient_') . '%', $wpdb->esc_like('_transient_timeout_') . '%', time())); $sql = "DELETE a, b FROM {$wpdb->options} a, {$wpdb->options} b\r\n\t\t\t\t\t\tWHERE a.option_name LIKE %s\r\n\t\t\t\t\t\tAND a.option_name NOT LIKE %s\r\n\t\t\t\t\t\tAND b.option_name = CONCAT( '_site_transient_timeout_', SUBSTRING( a.option_name, 17 ) )\r\n\t\t\t\t\t\tAND b.option_value < %d"; $rows2 = $wpdb->query($wpdb->prepare($sql, $wpdb->esc_like('_site_transient_') . '%', $wpdb->esc_like('_site_transient_timeout_') . '%', time())); echo '<div class="updated"><p>' . sprintf(__('%d Transients Rows Cleared', 'woocommerce'), $rows + $rows2) . '</p></div>'; break; case 'reset_roles': // Remove then re-add caps and roles WC_Install::remove_roles(); WC_Install::create_roles(); echo '<div class="updated"><p>' . __('Roles successfully reset', 'woocommerce') . '</p></div>'; break; case 'recount_terms': $product_cats = get_terms('product_cat', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_cats, get_taxonomy('product_cat'), true, false); $product_tags = get_terms('product_tag', array('hide_empty' => false, 'fields' => 'id=>parent')); _wc_term_recount($product_tags, get_taxonomy('product_tag'), true, false); echo '<div class="updated"><p>' . __('Terms successfully recounted', 'woocommerce') . '</p></div>'; break; case 'clear_sessions': $wpdb->query("\r\n\t\t\t\t\t\tDELETE FROM {$wpdb->options}\r\n\t\t\t\t\t\tWHERE option_name LIKE '_wc_session_%' OR option_name LIKE '_wc_session_expires_%'\r\n\t\t\t\t\t"); wp_cache_flush(); echo '<div class="updated"><p>' . __('Sessions successfully cleared', 'woocommerce') . '</p></div>'; break; case 'install_pages': WC_Install::create_pages(); echo '<div class="updated"><p>' . __('All missing WooCommerce pages was installed successfully.', 'woocommerce') . '</p></div>'; break; case 'delete_taxes': $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rates"); $wpdb->query("TRUNCATE " . $wpdb->prefix . "woocommerce_tax_rate_locations"); echo '<div class="updated"><p>' . __('Tax rates successfully deleted', 'woocommerce') . '</p></div>'; break; case 'reset_tracking': delete_option('woocommerce_allow_tracking'); WC_Admin_Notices::add_notice('tracking'); echo '<div class="updated"><p>' . __('Usage tracking settings successfully reset.', 'woocommerce') . '</p></div>'; break; default: $action = esc_attr($_GET['action']); if (isset($tools[$action]['callback'])) { $callback = $tools[$action]['callback']; $return = call_user_func($callback); if ($return === false) { if (is_array($callback)) { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s::%s', 'woocommerce'), get_class($callback[0]), $callback[1]) . '</p></div>'; } else { echo '<div class="error"><p>' . sprintf(__('There was an error calling %s', 'woocommerce'), $callback) . '</p></div>'; } } } break; } } // Manual translation update messages if (isset($_GET['translation_updated'])) { WC_Language_Pack_Upgrader::language_update_messages(); } // Display message if settings settings have been saved if (isset($_REQUEST['settings-updated'])) { echo '<div class="updated"><p>' . __('Your changes have been saved.', 'woocommerce') . '</p></div>'; } include_once 'views/html-admin-page-status-tools.php'; }
/** * 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; } $data = apply_filters('woocommerce_api_edit_product_data', $data, $this); // Product title. if (isset($data['title'])) { wp_update_post(array('ID' => $id, 'post_title' => wc_clean($data['title']))); } // Product name (slug). if (isset($data['name'])) { wp_update_post(array('ID' => $id, 'post_name' => sanitize_title($data['name']))); } // Product status. if (isset($data['status'])) { wp_update_post(array('ID' => $id, 'post_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']); wp_update_post(array('ID' => $id, 'post_excerpt' => $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']); wp_update_post(array('ID' => $id, 'post_content' => $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'])) { $this->save_product_images($id, $data['images']); } // Save product meta fields $this->save_product_meta($id, $data); // Save variations $product = get_product($id); if ($product->is_type('variable')) { if (isset($data['variations']) && is_array($data['variations'])) { $this->save_variations($id, $data); } else { // Just sync variations WC_Product_Variable::sync($id); } } do_action('woocommerce_api_edit_product', $id, $data); // Clear cache/transients wc_delete_product_transients($id); return $this->get_product($id); } catch (WC_API_Exception $e) { return new WP_Error($e->getErrorCode(), $e->getMessage(), array('status' => $e->getCode())); } }
/** * Delete a product. * * @since 2.2 * @param int $id the product ID. * @param bool $force true to permanently delete order, false to move to trash. * @return array */ public function delete_product($id, $force = false) { $id = $this->validate_request($id, 'product', 'delete'); if (is_wp_error($id)) { return $id; } do_action('woocommerce_api_delete_product', $id, $this); $parent_id = wp_get_post_parent_id($id); $result = $force ? wp_delete_post($id, true) : wp_trash_post($id); if (!$result) { return new WP_Error('woocommerce_api_cannot_delete_product', sprintf(__('This %s cannot be deleted', 'woocommerce'), 'product'), array('status' => 500)); } // Delete parent product transients. if ($parent_id) { wc_delete_product_transients($parent_id); } if ($force) { return array('message' => sprintf(__('Permanently deleted %s', 'woocommerce'), 'product')); } else { $this->server->send_status('202'); return array('message' => sprintf(__('Deleted %s', 'woocommerce'), 'product')); } }