/** * Handle adding variable products to the cart. * @since 2.4.6 Split from add_to_cart_action * @param int $product_id * @return bool success or not */ private static function add_to_cart_handler_variable($product_id) { $adding_to_cart = wc_get_product($product_id); $variation_id = empty($_REQUEST['variation_id']) ? '' : absint($_REQUEST['variation_id']); $quantity = empty($_REQUEST['quantity']) ? 1 : wc_stock_amount($_REQUEST['quantity']); $missing_attributes = array(); $variations = array(); $attributes = $adding_to_cart->get_attributes(); // If no variation ID is set, attempt to get a variation ID from posted attributes. if (empty($variation_id)) { $data_store = WC_Data_Store::load('product'); $variation_id = $data_store->find_matching_product_variation($adding_to_cart, wp_unslash($_POST)); } // Validate the attributes. try { if (empty($variation_id)) { throw new Exception(__('Please choose product options…', 'woocommerce')); } $variation_data = wc_get_product_variation_attributes($variation_id); foreach ($attributes as $attribute) { if (!$attribute['is_variation']) { continue; } $taxonomy = 'attribute_' . sanitize_title($attribute['name']); if (isset($_REQUEST[$taxonomy])) { // Get value from post data if ($attribute['is_taxonomy']) { // Don't use wc_clean as it destroys sanitized characters $value = sanitize_title(stripslashes($_REQUEST[$taxonomy])); } else { $value = wc_clean(stripslashes($_REQUEST[$taxonomy])); } // Get valid value from variation $valid_value = isset($variation_data[$taxonomy]) ? $variation_data[$taxonomy] : ''; // Allow if valid or show error. if ('' === $valid_value || $valid_value === $value) { $variations[$taxonomy] = $value; } else { throw new Exception(sprintf(__('Invalid value posted for %s', 'woocommerce'), wc_attribute_label($attribute['name']))); } } else { $missing_attributes[] = wc_attribute_label($attribute['name']); } } if (!empty($missing_attributes)) { throw new Exception(sprintf(_n('%s is a required field', '%s are required fields', sizeof($missing_attributes), 'woocommerce'), wc_format_list_of_items($missing_attributes))); } } catch (Exception $e) { wc_add_notice($e->getMessage(), 'error'); return false; } // Add to cart validation $passed_validation = apply_filters('woocommerce_add_to_cart_validation', true, $product_id, $quantity, $variation_id, $variations); if ($passed_validation && WC()->cart->add_to_cart($product_id, $quantity, $variation_id, $variations) !== false) { wc_add_to_cart_message(array($product_id => $quantity), true); return true; } return false; }
/** * Check if we need to download a file and check validity. */ public static function download_product() { $product_id = absint($_GET['download_file']); $product = wc_get_product($product_id); $data_store = WC_Data_Store::load('customer-download'); if (!$product || !isset($_GET['key'], $_GET['order'])) { self::download_error(__('Invalid download link.', 'woocommerce')); } $download_ids = $data_store->get_downloads(array('user_email' => sanitize_email(str_replace(' ', '+', $_GET['email'])), 'order_key' => wc_clean($_GET['order']), 'product_id' => $product_id, 'download_id' => wc_clean(preg_replace('/\\s+/', ' ', $_GET['key'])), 'orderby' => 'downloads_remaining', 'order' => 'DESC', 'limit' => 1, 'return' => 'ids')); if (empty($download_ids)) { self::download_error(__('Invalid download link.', 'woocommerce')); } $download = new WC_Customer_Download(current($download_ids)); self::check_order_is_valid($download); self::check_downloads_remaining($download); self::check_download_expiry($download); self::check_download_login_required($download); do_action('woocommerce_download_product', $download->get_user_email(), $download->get_order_key(), $download->get_product_id(), $download->get_user_id(), $download->get_download_id(), $download->get_order_id()); $count = $download->get_download_count(); $remaining = $download->get_downloads_remaining(); $download->set_download_count($count++); $download->set_downloads_remaining($remaining--); $download->save(); self::download($product->get_file_download_path($download->get_download_id()), $download->get_product_id()); }
/** * When a payment is complete, we can reduce stock levels for items within an order. * @since 2.7.0 * @param int $order_id */ function wc_maybe_reduce_stock_levels($order_id) { $data_store = WC_Data_Store::load('order'); if (apply_filters('woocommerce_payment_complete_reduce_order_stock', !$data_store->get_stock_reduced($order_id), $order_id)) { wc_reduce_stock_levels($order_id); $data_store->set_stock_reduced($order_id, true); } }
/** * Create a token. * @deprecated 2.7.0 - Use ::save instead. */ public function create() { wc_deprecated_function('WC_Payment_Token::create', '2.7', 'Use ::save instead.'); $data_store = WC_Data_Store::load('payment-token'); try { $data_store->create($this); } catch (Exception $e) { return false; } }
/** * Create a zone. * @deprecated 2.7.0 - Use ::save instead. */ public function create() { wc_deprecated_function('WC_Shipping_Zone::create', '2.7', 'Use ::save instead.'); $data_store = WC_Data_Store::load('shipping-zone'); try { $data_store->create($this); } catch (Exception $e) { return false; } }
/** * Output the metabox. * * @param WP_Post $post */ public static function output($post) { global $post, $wpdb; ?> <div class="order_download_permissions wc-metaboxes-wrapper"> <div class="wc-metaboxes"><?php $data_store = WC_Data_Store::load('customer-download'); $download_permissions = $data_store->get_downloads(array('order_id' => $post->ID, 'orderby' => 'product_id')); $product = null; $loop = 0; $file_counter = 1; if ($download_permissions && sizeof($download_permissions) > 0) { foreach ($download_permissions as $download) { if (!$product || $product->get_id() !== $download->get_product_id()) { $product = wc_get_product($download->get_product_id()); $file_counter = 1; } // don't show permissions to files that have since been removed if (!$product || !$product->exists() || !$product->has_file($download->get_download_id())) { continue; } // Show file title instead of count if set $file = $product->get_file($download->get_download_id()); $file_count = isset($file['name']) ? $file['name'] : sprintf(__('File %d', 'woocommerce'), $file_counter); include 'views/html-order-download-permission.php'; $loop++; $file_counter++; } } ?> </div> <div class="toolbar"> <p class="buttons"> <input type="hidden" id="grant_access_id" name="grant_access_id" data-multiple="true" class="wc-product-search" style="width: 400px;" data-placeholder="<?php esc_attr_e('Search for a downloadable product…', 'woocommerce'); ?> " data-action="woocommerce_json_search_downloadable_products_and_variations" /> <button type="button" class="button grant_access"><?php _e('Grant access', 'woocommerce'); ?> </button> </p> <div class="clear"></div> </div> </div> <?php }
/** * Constructor. * @param int|object|array $item ID to load from the DB, or WC_Order_Item Object */ public function __construct($item = 0) { $this->data = array_merge($this->data, $this->extra_data); parent::__construct($item); if ($item instanceof WC_Order_Item) { $this->set_id($item->get_id()); } elseif (is_numeric($item) && $item > 0) { $this->set_id($item); } else { $this->set_object_read(true); } $type = 'line_item' === $this->get_type() ? 'product' : $this->get_type(); $this->data_store = WC_Data_Store::load('order-item-' . $type); if ($this->get_id() > 0) { $this->data_store->read($this); } }
/** * Constructor for zones. * * @param int|object $zone Zone ID to load from the DB or zone object. */ public function __construct($zone = null) { if (is_numeric($zone) && !empty($zone)) { $this->set_id($zone); } elseif (is_object($zone)) { $this->set_id($zone->zone_id); } elseif (0 === $zone || "0" === $zone) { $this->set_id(0); } else { $this->set_zone_name(__('Zone', 'woocommerce')); $this->set_object_read(true); } $this->data_store = WC_Data_Store::load('shipping-zone'); if (false === $this->get_object_read()) { $this->data_store->read($this); } }
/** * Get the product if ID is passed, otherwise the product is new and empty. * This class should NOT be instantiated, but the wc_get_product() function * should be used. It is possible, but the wc_get_product() is preferred. * * @param int|WC_Product|object $product Product to init. */ public function __construct($product = 0) { parent::__construct($product); if (is_numeric($product) && $product > 0) { $this->set_id($product); } elseif ($product instanceof self) { $this->set_id(absint($product->get_id())); } elseif (!empty($product->ID)) { $this->set_id(absint($product->ID)); } else { $this->set_object_read(true); } $this->data_store = WC_Data_Store::load('product-' . $this->get_type()); if ($this->get_id() > 0) { $this->data_store->read($this); } }
/** * Constructor. * * @param int|object|array $download */ public function __construct($download = 0) { parent::__construct($download); if (is_numeric($download) && $download > 0) { $this->set_id($download); } elseif ($download instanceof self) { $this->set_id($download->get_id()); } elseif (is_object($download) && !empty($download->permission_id)) { $this->set_id($download->permission_id); $this->set_props((array) $download); $this->set_object_read(true); } else { $this->set_object_read(true); } $this->data_store = WC_Data_Store::load('customer-download'); if ($this->get_id() > 0) { $this->data_store->read($this); } }
/** * Get the order if ID is passed, otherwise the order is new and empty. * This class should NOT be instantiated, but the get_order function or new WC_Order_Factory. * should be used. It is possible, but the aforementioned are preferred and are the only. * methods that will be maintained going forward. * * @param int|object|WC_Order $order Order to read. */ public function __construct($order = 0) { parent::__construct($order); if (is_numeric($order) && $order > 0) { $this->set_id($order); } elseif ($order instanceof self) { $this->set_id($order->get_id()); } elseif (!empty($order->ID)) { $this->set_id($order->ID); } else { $this->set_object_read(true); } // Set default status if none were read. if (!$this->get_status()) { $this->set_status(apply_filters('woocommerce_default_order_status', 'pending')); } $this->data_store = WC_Data_Store::load($this->data_store_name); if ($this->get_id() > 0) { $this->data_store->read($this); } }
/** * Coupon constructor. Loads coupon data. * @param mixed $data Coupon data, object, ID or code. */ public function __construct($data = '') { parent::__construct($data); if ($data instanceof WC_Coupon) { $this->set_id(absint($data->get_id())); } elseif ($coupon = apply_filters('woocommerce_get_shop_coupon_data', false, $data)) { wc_doing_it_wrong('woocommerce_get_shop_coupon_data', 'Reading a manual coupon via woocommerce_get_shop_coupon_data has been deprecated. Please sent an instance of WC_Coupon instead.', '2.7'); $this->read_manual_coupon($data, $coupon); } elseif (is_numeric($data) && 'shop_coupon' === get_post_type($data)) { $this->set_id($data); } elseif (!empty($data)) { $this->set_id(wc_get_coupon_id_by_code($data)); $this->set_code($data); } else { $this->set_object_read(true); } $this->data_store = WC_Data_Store::load('coupon'); if ($this->get_id() > 0) { $this->data_store->read($this); } }
/** * Initialize a payment token. * * These fields are accepted by all payment tokens: * is_default - boolean Optional - Indicates this is the default payment token for a user * token - string Required - The actual token to store * gateway_id - string Required - Identifier for the gateway this token is associated with * user_id - int Optional - ID for the user this token is associated with. 0 if this token is not associated with a user * * @since 2.6.0 * @param mixed $token */ public function __construct($token = '') { // Set token type (cc, echeck) if (!empty($this->type)) { $this->set_type($this->type); } if (is_numeric($token)) { $this->set_id($token); } elseif (is_object($token)) { $token_id = $token->get_id(); if (!empty($token_id)) { $this->set_id($token->get_id()); } } else { $this->set_object_read(true); } $this->data_store = WC_Data_Store::load('payment-token'); if ($this->get_id() > 0) { $this->data_store->read($this); } }
/** * Load customer data based on how WC_Customer is called. * * If $customer is 'new', you can build a new WC_Customer object. If it's empty, some * data will be pulled from the session for the current user/customer. * * @param WC_Customer|int $data Customer ID or data. * @param bool $is_session True if this is the customer session * @throws Exception if customer cannot be read/found and $data is set. */ public function __construct($data = 0, $is_session = false) { parent::__construct($data); if ($data instanceof WC_Customer) { $this->set_id(absint($data->get_id())); } elseif (is_numeric($data)) { $this->set_id($data); } $this->data_store = WC_Data_Store::load('customer'); // If we have an ID, load the user from the DB. if ($this->get_id()) { $this->data_store->read($this); } else { $this->set_object_read(true); } // If this is a session, set or change the data store to sessions. Changes do not persist in the database. if ($is_session) { $this->data_store = WC_Data_Store::load('customer-session'); $this->data_store->read($this); } }
/** * Save meta box data. * * @param int $post_id * @param WP_Post $post */ public static function save($post_id, $post) { global $wpdb; // Order data saved, now get it so we can manipulate status $order = wc_get_order($post_id); // Handle button actions if (!empty($_POST['wc_order_action'])) { $action = wc_clean($_POST['wc_order_action']); if (strstr($action, 'send_email_')) { do_action('woocommerce_before_resend_order_emails', $order); // Ensure gateways are loaded in case they need to insert data into the emails WC()->payment_gateways(); WC()->shipping(); // Load mailer $mailer = WC()->mailer(); $email_to_send = str_replace('send_email_', '', $action); $mails = $mailer->get_emails(); if (!empty($mails)) { foreach ($mails as $mail) { if ($mail->id == $email_to_send) { $mail->trigger($order->get_id()); /* translators: %s: email title */ $order->add_order_note(sprintf(__('%s email notification manually sent.', 'woocommerce'), $mail->title), false, true); } } } do_action('woocommerce_after_resend_order_email', $order, $email_to_send); // Change the post saved message add_filter('redirect_post_location', array(__CLASS__, 'set_email_sent_message')); } elseif ('regenerate_download_permissions' === $action) { $data_store = WC_Data_Store::load('customer-download'); $data_store->delete_by_order_id($post_id); wc_downloadable_product_permissions($post_id, true); } else { if (!did_action('woocommerce_order_action_' . sanitize_title($action))) { do_action('woocommerce_order_action_' . sanitize_title($action), $order); } } } }
/** * Returns what type (credit card, echeck, etc) of token a token is by ID. * * @since 2.6.0 * @param int $token_id Token ID * @return string Type */ public static function get_token_type_by_id($token_id) { $data_store = WC_Data_Store::load('payment-token'); return $data_store->get_token_type_by_id($token_id); }
/** * Sync a grouped product with it's children. These sync functions sync * upwards (from child to parent) when the variation is saved. * * @param WC_Product|int $product Product object or ID for which you wish to sync. * @param bool $save If true, the prouduct object will be saved to the DB before returning it. * @return WC_Product Synced product object. */ public static function sync($product, $save = true) { if (!is_a($product, 'WC_Product')) { $product = wc_get_product($product); } if (is_a($product, 'WC_Product_Grouped')) { $data_store = WC_Data_Store::load('product-' . $product->get_type()); $data_store->sync_price($product); if ($save) { $product->save(); } } return $product; }
/** * Find a matching zone for a given package. * @since 2.6.0 * @uses wc_make_numeric_postcode() * @param object $package * @return WC_Shipping_Zone */ public static function get_zone_matching_package($package) { $country = strtoupper(wc_clean($package['destination']['country'])); $state = strtoupper(wc_clean($package['destination']['state'])); $continent = strtoupper(wc_clean(WC()->countries->get_continent_code_for_country($country))); $postcode = wc_normalize_postcode(wc_clean($package['destination']['postcode'])); $cache_key = WC_Cache_Helper::get_cache_prefix('shipping_zones') . 'wc_shipping_zone_' . md5(sprintf('%s+%s+%s', $country, $state, $postcode)); $matching_zone_id = wp_cache_get($cache_key, 'shipping_zones'); if (false === $matching_zone_id) { $data_store = WC_Data_Store::load('shipping-zone'); $matching_zone_id = $data_store->get_zone_id_from_package($package); wp_cache_set($cache_key, $matching_zone_id, 'shipping_zones'); } return new WC_Shipping_Zone($matching_zone_id ? $matching_zone_id : 0); }
/** * Helper method that updates all the post meta for an order based on it's settings in the WC_Order class. * * @param WC_Order * @since 2.7.0 */ protected function update_post_meta(&$order) { $updated_props = array(); $changed_props = $order->get_changes(); $meta_key_to_props = array('_order_key' => 'order_key', '_customer_user' => 'customer_id', '_payment_method' => 'payment_method', '_payment_method_title' => 'payment_method_title', '_transaction_id' => 'transaction_id', '_customer_ip_address' => 'customer_ip_address', '_customer_user_agent' => 'customer_user_agent', '_created_via' => 'created_via', '_date_completed' => 'date_completed', '_date_paid' => 'date_paid', '_cart_hash' => 'cart_hash'); foreach ($meta_key_to_props as $meta_key => $prop) { if (!array_key_exists($prop, $changed_props)) { continue; } $value = $order->{"get_{$prop}"}('edit'); if ('' !== $value ? update_post_meta($order->get_id(), $meta_key, $value) : delete_post_meta($order->get_id(), $meta_key)) { $updated_props[] = $prop; } } $billing_address_props = array('_billing_first_name' => 'billing_first_name', '_billing_last_name' => 'billing_last_name', '_billing_company' => 'billing_company', '_billing_address_1' => 'billing_address_1', '_billing_address_2' => 'billing_address_2', '_billing_city' => 'billing_city', '_billing_state' => 'billing_state', '_billing_postcode' => 'billing_postcode', '_billing_country' => 'billing_country', '_billing_email' => 'billing_email', '_billing_phone' => 'billing_phone'); foreach ($billing_address_props as $meta_key => $prop) { $prop_key = substr($prop, 8); if (!isset($changed_props['billing']) || !array_key_exists($prop_key, $changed_props['billing'])) { continue; } $value = $order->{"get_{$prop}"}('edit'); if ('' !== $value ? update_post_meta($order->get_id(), $meta_key, $value) : delete_post_meta($order->get_id(), $meta_key)) { $updated_props[] = $prop; $updated_props[] = 'billing'; } } $shipping_address_props = array('_shipping_first_name' => 'shipping_first_name', '_shipping_last_name' => 'shipping_last_name', '_shipping_company' => 'shipping_company', '_shipping_address_1' => 'shipping_address_1', '_shipping_address_2' => 'shipping_address_2', '_shipping_city' => 'shipping_city', '_shipping_state' => 'shipping_state', '_shipping_postcode' => 'shipping_postcode', '_shipping_country' => 'shipping_country'); foreach ($shipping_address_props as $meta_key => $prop) { $prop_key = substr($prop, 9); if (!isset($changed_props['shipping']) || !array_key_exists($prop_key, $changed_props['shipping'])) { continue; } $value = $order->{"get_{$prop}"}('edit'); if ('' !== $value ? update_post_meta($order->get_id(), $meta_key, $value) : delete_post_meta($order->get_id(), $meta_key)) { $updated_props[] = $prop; $updated_props[] = 'shipping'; } } parent::update_post_meta($order); // If address changed, store concatinated version to make searches faster. if (in_array('billing', $updated_props) || !metadata_exists('post', $order->get_id(), '_billing_address_index')) { update_post_meta($order->get_id(), '_billing_address_index', implode(' ', $order->get_address('billing'))); } if (in_array('shipping', $updated_props) || !metadata_exists('post', $order->get_id(), '_shipping_address_index')) { update_post_meta($order->get_id(), '_shipping_address_index', implode(' ', $order->get_address('shipping'))); } // If customer changed, update any downloadable permissions. if (in_array('customer_user', $updated_props) || in_array('billing_email', $updated_props)) { $data_store = WC_Data_Store::load('customer-download'); $data_store->update_user_by_order_id($order->get_id(), $order->get_customer_id(), $order->get_billing_email()); } }
/** * Test to see if `first_second ``-> returns to `first` if unregistered. * * @since 2.7.0 */ function test_store_sub_type() { $this->load_dummy_store(); $store = WC_Data_Store::load('dummy-sub'); $this->assertEquals('WC_Dummy_Data_Store_CPT', $store->get_current_class_name()); }
/** * Cancel all unpaid orders after held duration to prevent stock lock for those products. */ function wc_cancel_unpaid_orders() { $held_duration = get_option('woocommerce_hold_stock_minutes'); if ($held_duration < 1 || 'yes' !== get_option('woocommerce_manage_stock')) { return; } $data_store = WC_Data_Store::load('order'); $unpaid_orders = $data_store->get_unpaid_orders(strtotime('-' . absint($held_duration) . ' MINUTES', current_time('timestamp'))); if ($unpaid_orders) { foreach ($unpaid_orders as $unpaid_order) { $order = wc_get_order($unpaid_order); if (apply_filters('woocommerce_cancel_unpaid_order', 'checkout' === $order->get_created_via(), $order)) { $order->update_status('cancelled', __('Unpaid order cancelled - time limit reached.', 'woocommerce')); } } } wp_clear_scheduled_hook('woocommerce_cancel_unpaid_orders'); wp_schedule_single_event(time() + absint($held_duration) * 60, 'woocommerce_cancel_unpaid_orders'); }
/** * Get related products based on product category and tags. * * @since 2.7.0 * @param int $product_id Product ID. * @param int $limit Limit of results. * @param array $exclude_ids Exclude IDs from the results. * @return array */ function wc_get_related_products($product_id, $limit = 5, $exclude_ids = array()) { global $wpdb; $product_id = absint($product_id); $exclude_ids = array_merge(array(0, $product_id), $exclude_ids); $transient_name = 'wc_related_' . $product_id; $related_posts = get_transient($transient_name); $limit = $limit > 0 ? $limit : 5; // We want to query related posts if they are not cached, or we don't have enough. if (false === $related_posts || count($related_posts) < $limit) { $cats_array = apply_filters('woocommerce_product_related_posts_relate_by_category', true, $product_id) ? apply_filters('woocommerce_get_related_product_cat_terms', wc_get_product_term_ids($product_id, 'product_cat'), $product_id) : array(); $tags_array = apply_filters('woocommerce_product_related_posts_relate_by_tag', true, $product_id) ? apply_filters('woocommerce_get_related_product_tag_terms', wc_get_product_term_ids($product_id, 'product_tag'), $product_id) : array(); // Don't bother if none are set, unless woocommerce_product_related_posts_force_display is set to true in which case all products are related. if (empty($cats_array) && empty($tags_array) && !apply_filters('woocommerce_product_related_posts_force_display', false, $product_id)) { $related_posts = array(); } else { $data_store = WC_Data_Store::load('product'); $related_posts = $data_store->get_related_products($cats_array, $tags_array, $exclude_ids, $limit + 10, $product_id); } set_transient($transient_name, $related_posts, DAY_IN_SECONDS); } shuffle($related_posts); return array_slice($related_posts, 0, $limit); }
/** * Match a variation to a given set of attributes using a WP_Query. * @deprecated 2.7.0 in favour of Product data store's find_matching_product_variation. */ public function get_matching_variation($match_attributes = array()) { wc_deprecated_function('WC_Product::get_matching_variation', '2.7', 'Product data store find_matching_product_variation'); $data_store = WC_Data_Store::load('product'); return $data_store->find_matching_product_variation($this, $match_attributes); }
/** * WooCommerce Order Item Meta API - Get term meta. * * @access public * @param mixed $item_id * @param mixed $key * @param bool $single (default: true) * @return mixed */ function wc_get_order_item_meta($item_id, $key, $single = true) { $data_store = WC_Data_Store::load('order-item'); return $data_store->get_metadata($item_id, $key, $single); }
/** * Search for customers and return json. */ public static function json_search_customers() { ob_start(); check_ajax_referer('search-customers', 'security'); if (!current_user_can('edit_shop_orders')) { die(-1); } $term = wc_clean(stripslashes($_GET['term'])); $exclude = array(); if (empty($term)) { die; } $data_store = WC_Data_Store::load('customer'); $ids = $data_store->search_customers($term); $found_customers = array(); if (!empty($_GET['exclude'])) { $ids = array_diff($ids, (array) $_GET['exclude']); } foreach ($ids as $id) { $customer = new WC_Customer($id); /* translators: 1: user display name 2: user ID 3: user email */ $found_customers[$id] = sprintf(esc_html__('%1$s (#%2$s – %3$s)', 'woocommerce'), $customer->get_first_name() . ' ' . $customer->get_last_name(), $customer->get_id(), $customer->get_email()); } wp_send_json(apply_filters('woocommerce_json_search_found_customers', $found_customers)); }
/** * Test coupon increase, decrease, user usage count methods. * @since 2.7.0 */ function test_coupon_usage_magic_methods() { $coupon = WC_Helper_Coupon::create_coupon(); $user_id = 1; $this->assertEquals(0, $coupon->get_usage_count()); $this->assertEmpty($coupon->get_used_by()); $coupon->inc_usage_count('*****@*****.**'); $this->assertEquals(1, $coupon->get_usage_count()); $this->assertEquals(array('*****@*****.**'), $coupon->get_used_by()); $coupon->inc_usage_count($user_id); $coupon->inc_usage_count($user_id); $data_store = WC_Data_Store::load('coupon'); $this->assertEquals(2, $data_store->get_usage_by_user_id($coupon, $user_id)); $coupon->dcr_usage_count('*****@*****.**'); $coupon->dcr_usage_count($user_id); $this->assertEquals(1, $coupon->get_usage_count()); $this->assertEquals(array(1), $coupon->get_used_by()); }
/** * Get coupon code by ID. * * @since 2.7.0 * @param string $code * @param int $exclude Used to exclude an ID from the check if you're checking existance. * @return int */ function wc_get_coupon_id_by_code($code, $exclude = 0) { $data_store = WC_Data_Store::load('coupon'); $ids = wp_cache_get(WC_Cache_Helper::get_cache_prefix('coupons') . 'coupon_id_from_code_' . $code, 'coupons'); if (false === $ids) { $ids = $data_store->get_ids_by_code($code); if ($ids) { wp_cache_set(WC_Cache_Helper::get_cache_prefix('coupons') . 'coupon_id_from_code_' . $code, $ids, 'coupons'); } } $ids = array_diff(array_filter(array_map('absint', (array) $ids)), array($exclude)); return apply_filters('woocommerce_get_coupon_id_from_code', absint(current($ids)), $code, $exclude); }
/** * Get any associated downloadable files. * * @return array */ public function get_item_downloads() { global $wpdb; $files = array(); $product = $this->get_product(); $order = $this->get_order(); if ($product && $order && $product->is_downloadable() && $order->is_download_permitted()) { $data_store = WC_Data_Store::load('customer-download'); $download_ids = $data_store->get_downloads(array('user_email' => $order->get_billing_email(), 'order_id' => $order->get_id(), 'product_id' => $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id(), 'return' => 'ids')); foreach ($download_ids as $download_id) { if ($product->has_file($download_id)) { $files[$download_id] = $product->get_file($download_id); $files[$download_id]['download_url'] = $this->get_item_download_url($download_id); } } } return apply_filters('woocommerce_get_item_downloads', $files, $this, $order); }
/** * Update changed downloads. * * @param int $product_id product identifier * @param int $variation_id optional product variation identifier * @param array $downloads newly set files */ public static function process_product_file_download_paths($product_id, $variation_id, $downloads) { if ($variation_id) { $product_id = $variation_id; } $product = wc_get_product($product_id); $data_store = WC_Data_Store::load('customer-download'); if ($downloads) { foreach ($downloads as $download) { $new_hash = md5($download->get_file()); if ($download->get_previous_hash() && $download->get_previous_hash() !== $new_hash) { // Update permissions. $data_store->update_download_id($product_id, $download->get_previous_hash(), $new_hash); } } } }