File "class-wc-cart.php"
Full path: /home/kosmetik/public_html/wp-content/plugins/woocommerce/includes/class-wc-cart.php
File
size: 47.68 B
MIME-type: text/x-php
Charset: utf-8
Download Open Edit Advanced Editor Back
<?php
use Automattic\WooCommerce\Utilities\NumberUtil;
defined('ABSPATH') || exit;
require_once WC_ABSPATH . 'includes/legacy/class-wc-legacy-cart.php';
require_once WC_ABSPATH . 'includes/class-wc-cart-fees.php';
require_once WC_ABSPATH . 'includes/class-wc-cart-session.php';
class WC_Cart extends WC_Legacy_Cart
{
public $cart_contents = array();
public $removed_cart_contents = array();
public $applied_coupons = array();
protected $shipping_methods;
protected $default_totals = array('subtotal' => 0, 'subtotal_tax' => 0, 'shipping_total' => 0, 'shipping_tax' => 0, 'shipping_taxes' => array(), 'discount_total' => 0, 'discount_tax' => 0, 'cart_contents_total' => 0, 'cart_contents_tax' => 0, 'cart_contents_taxes' => array(), 'fee_total' => 0, 'fee_tax' => 0, 'fee_taxes' => array(), 'total' => 0, 'total_tax' => 0);
protected $totals = array();
protected $session;
protected $fees_api;
public function __construct()
{
$this->session = new WC_Cart_Session($this);
$this->fees_api = new WC_Cart_Fees($this);
$this->session->init();
add_action('woocommerce_add_to_cart', array($this, 'calculate_totals'), 20, 0);
add_action('woocommerce_applied_coupon', array($this, 'calculate_totals'), 20, 0);
add_action('woocommerce_cart_item_removed', array($this, 'calculate_totals'), 20, 0);
add_action('woocommerce_cart_item_restored', array($this, 'calculate_totals'), 20, 0);
add_action('woocommerce_check_cart_items', array($this, 'check_cart_items'), 1);
add_action('woocommerce_check_cart_items', array($this, 'check_cart_coupons'), 1);
add_action('woocommerce_after_checkout_validation', array($this, 'check_customer_coupons'), 1, 2);
}
public function __clone()
{
$this->session = clone $this->session;
$this->fees_api = clone $this->fees_api;
}
public function get_cart_contents()
{
return apply_filters('woocommerce_get_cart_contents', (array) $this->cart_contents);
}
public function get_removed_cart_contents()
{
return (array) $this->removed_cart_contents;
}
public function get_applied_coupons()
{
return (array) $this->applied_coupons;
}
public function get_coupon_discount_totals()
{
return (array) $this->coupon_discount_totals;
}
public function get_coupon_discount_tax_totals()
{
return (array) $this->coupon_discount_tax_totals;
}
public function get_totals()
{
return empty($this->totals) ? $this->default_totals : $this->totals;
}
protected function get_totals_var($key)
{
return isset($this->totals[$key]) ? $this->totals[$key] : $this->default_totals[$key];
}
public function get_subtotal()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('subtotal'));
}
public function get_subtotal_tax()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('subtotal_tax'));
}
public function get_discount_total()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('discount_total'));
}
public function get_discount_tax()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('discount_tax'));
}
public function get_shipping_total()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('shipping_total'));
}
public function get_shipping_tax()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('shipping_tax'));
}
public function get_cart_contents_total()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('cart_contents_total'));
}
public function get_cart_contents_tax()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('cart_contents_tax'));
}
public function get_total($context = 'view')
{
$total = apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('total'));
return 'view' === $context ? apply_filters('woocommerce_cart_total', wc_price($total)) : $total;
}
public function get_total_tax()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('total_tax'));
}
public function get_fee_total()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('fee_total'));
}
public function get_fee_tax()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('fee_tax'));
}
public function get_shipping_taxes()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('shipping_taxes'));
}
public function get_cart_contents_taxes()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('cart_contents_taxes'));
}
public function get_fee_taxes()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, $this->get_totals_var('fee_taxes'));
}
public function display_prices_including_tax()
{
return apply_filters('woocommerce_cart_' . __FUNCTION__, 'incl' === $this->get_tax_price_display_mode());
}
public function set_cart_contents($value)
{
$this->cart_contents = (array) $value;
}
public function set_removed_cart_contents($value = array())
{
$this->removed_cart_contents = (array) $value;
}
public function set_applied_coupons($value = array())
{
$this->applied_coupons = (array) $value;
}
public function set_coupon_discount_totals($value = array())
{
$this->coupon_discount_totals = (array) $value;
}
public function set_coupon_discount_tax_totals($value = array())
{
$this->coupon_discount_tax_totals = (array) $value;
}
public function set_totals($value = array())
{
$this->totals = wp_parse_args($value, $this->default_totals);
}
public function set_subtotal($value)
{
$this->totals['subtotal'] = wc_format_decimal($value);
}
public function set_subtotal_tax($value)
{
$this->totals['subtotal_tax'] = $value;
}
public function set_discount_total($value)
{
$this->totals['discount_total'] = $value;
}
public function set_discount_tax($value)
{
$this->totals['discount_tax'] = $value;
}
public function set_shipping_total($value)
{
$this->totals['shipping_total'] = wc_format_decimal($value);
}
public function set_shipping_tax($value)
{
$this->totals['shipping_tax'] = $value;
}
public function set_cart_contents_total($value)
{
$this->totals['cart_contents_total'] = wc_format_decimal($value);
}
public function set_cart_contents_tax($value)
{
$this->totals['cart_contents_tax'] = $value;
}
public function set_total($value)
{
$this->totals['total'] = wc_format_decimal($value, wc_get_price_decimals());
}
public function set_total_tax($value)
{
$this->totals['total_tax'] = wc_round_tax_total($value);
}
public function set_fee_total($value)
{
$this->totals['fee_total'] = wc_format_decimal($value);
}
public function set_fee_tax($value)
{
$this->totals['fee_tax'] = $value;
}
public function set_shipping_taxes($value)
{
$this->totals['shipping_taxes'] = (array) $value;
}
public function set_cart_contents_taxes($value)
{
$this->totals['cart_contents_taxes'] = (array) $value;
}
public function set_fee_taxes($value)
{
$this->totals['fee_taxes'] = (array) $value;
}
public function get_taxes()
{
return apply_filters('woocommerce_cart_get_taxes', wc_array_merge_recursive_numeric($this->get_shipping_taxes(), $this->get_cart_contents_taxes(), $this->get_fee_taxes()), $this);
}
public function get_cart()
{
if (!did_action('wp_loaded')) {
wc_doing_it_wrong(__FUNCTION__, __('Get cart should not be called before the wp_loaded action.', 'woocommerce'), '2.3');
}
if (!did_action('woocommerce_load_cart_from_session')) {
$this->session->get_cart_from_session();
}
return array_filter($this->get_cart_contents());
}
public function get_cart_item($item_key)
{
return isset($this->cart_contents[$item_key]) ? $this->cart_contents[$item_key] : array();
}
public function is_empty()
{
return 0 === count($this->get_cart());
}
public function empty_cart($clear_persistent_cart = true)
{
do_action('woocommerce_before_cart_emptied', $clear_persistent_cart);
$this->cart_contents = array();
$this->removed_cart_contents = array();
$this->shipping_methods = array();
$this->coupon_discount_totals = array();
$this->coupon_discount_tax_totals = array();
$this->applied_coupons = array();
$this->totals = $this->default_totals;
if ($clear_persistent_cart) {
$this->session->persistent_cart_destroy();
}
$this->fees_api->remove_all_fees();
do_action('woocommerce_cart_emptied', $clear_persistent_cart);
}
public function get_cart_contents_count()
{
return apply_filters('woocommerce_cart_contents_count', array_sum(wp_list_pluck($this->get_cart(), 'quantity')));
}
public function get_cart_contents_weight()
{
$weight = 0.0;
foreach ($this->get_cart() as $cart_item_key => $values) {
if ($values['data']->has_weight()) {
$weight += (float) $values['data']->get_weight() * $values['quantity'];
}
}
return apply_filters('woocommerce_cart_contents_weight', $weight);
}
public function get_cart_item_quantities()
{
$quantities = array();
foreach ($this->get_cart() as $cart_item_key => $values) {
$product = $values['data'];
$quantities[$product->get_stock_managed_by_id()] = isset($quantities[$product->get_stock_managed_by_id()]) ? $quantities[$product->get_stock_managed_by_id()] + $values['quantity'] : $values['quantity'];
}
return $quantities;
}
public function check_cart_items()
{
$return = true;
$result = $this->check_cart_item_validity();
if (is_wp_error($result)) {
wc_add_notice($result->get_error_message(), 'error');
$return = false;
}
$result = $this->check_cart_item_stock();
if (is_wp_error($result)) {
wc_add_notice($result->get_error_message(), 'error');
$return = false;
}
return $return;
}
public function check_cart_coupons()
{
foreach ($this->get_applied_coupons() as $code) {
$coupon = new WC_Coupon($code);
if (!$coupon->is_valid()) {
$coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_INVALID_REMOVED);
$this->remove_coupon($code);
}
}
}
public function check_cart_item_validity()
{
$return = true;
foreach ($this->get_cart() as $cart_item_key => $values) {
$product = $values['data'];
if (!$product || !$product->exists() || 'trash' === $product->get_status()) {
$this->set_quantity($cart_item_key, 0);
$return = new WP_Error('invalid', __('An item which is no longer available was removed from your cart.', 'woocommerce'));
}
}
return $return;
}
public function check_cart_item_stock()
{
$error = new WP_Error();
$product_qty_in_cart = $this->get_cart_item_quantities();
$current_session_order_id = isset(WC()->session->order_awaiting_payment) ? absint(WC()->session->order_awaiting_payment) : 0;
foreach ($this->get_cart() as $cart_item_key => $values) {
$product = $values['data'];
if (!$product->is_in_stock()) {
$error->add('out-of-stock', sprintf(__('Sorry, "%s" is not in stock. Please edit your cart and try again. We apologize for any inconvenience caused.', 'woocommerce'), $product->get_name()));
return $error;
}
if (!$product->managing_stock() || $product->backorders_allowed()) {
continue;
}
$held_stock = wc_get_held_stock_quantity($product, $current_session_order_id);
$required_stock = $product_qty_in_cart[$product->get_stock_managed_by_id()];
if (apply_filters('woocommerce_cart_item_required_stock_is_not_enough', $product->get_stock_quantity() < $held_stock + $required_stock, $product, $values)) {
$error->add('out-of-stock', sprintf(__('Sorry, we do not have enough "%1$s" in stock to fulfill your order (%2$s available). We apologize for any inconvenience caused.', 'woocommerce'), $product->get_name(), wc_format_stock_quantity_for_display($product->get_stock_quantity() - $held_stock, $product)));
return $error;
}
}
return true;
}
public function get_item_data($cart_item, $flat = false)
{
wc_deprecated_function('WC_Cart::get_item_data', '3.3', 'wc_get_formatted_cart_item_data');
return wc_get_formatted_cart_item_data($cart_item, $flat);
}
public function get_cross_sells()
{
$cross_sells = array();
$in_cart = array();
if (!$this->is_empty()) {
foreach ($this->get_cart() as $cart_item_key => $values) {
if ($values['quantity'] > 0) {
$cross_sells = array_merge($values['data']->get_cross_sell_ids(), $cross_sells);
$in_cart[] = $values['product_id'];
}
}
}
$cross_sells = array_diff($cross_sells, $in_cart);
return apply_filters('woocommerce_cart_crosssell_ids', wp_parse_id_list($cross_sells), $this);
}
public function get_remove_url($cart_item_key)
{
wc_deprecated_function('WC_Cart::get_remove_url', '3.3', 'wc_get_cart_remove_url');
return wc_get_cart_remove_url($cart_item_key);
}
public function get_undo_url($cart_item_key)
{
wc_deprecated_function('WC_Cart::get_undo_url', '3.3', 'wc_get_cart_undo_url');
return wc_get_cart_undo_url($cart_item_key);
}
public function get_tax_totals()
{
$shipping_taxes = $this->get_shipping_taxes();
$taxes = $this->get_taxes();
$tax_totals = array();
foreach ($taxes as $key => $tax) {
$code = WC_Tax::get_rate_code($key);
if ($code || apply_filters('woocommerce_cart_remove_taxes_zero_rate_id', 'zero-rated') === $key) {
if (!isset($tax_totals[$code])) {
$tax_totals[$code] = new stdClass();
$tax_totals[$code]->amount = 0;
}
$tax_totals[$code]->tax_rate_id = $key;
$tax_totals[$code]->is_compound = WC_Tax::is_compound($key);
$tax_totals[$code]->label = WC_Tax::get_rate_label($key);
if (isset($shipping_taxes[$key])) {
$tax -= $shipping_taxes[$key];
$tax = wc_round_tax_total($tax);
$tax += NumberUtil::round($shipping_taxes[$key], wc_get_price_decimals());
unset($shipping_taxes[$key]);
}
$tax_totals[$code]->amount += wc_round_tax_total($tax);
$tax_totals[$code]->formatted_amount = wc_price($tax_totals[$code]->amount);
}
}
if (apply_filters('woocommerce_cart_hide_zero_taxes', true)) {
$amounts = array_filter(wp_list_pluck($tax_totals, 'amount'));
$tax_totals = array_intersect_key($tax_totals, $amounts);
}
return apply_filters('woocommerce_cart_tax_totals', $tax_totals, $this);
}
public function get_cart_item_tax_classes()
{
$found_tax_classes = array();
foreach (WC()->cart->get_cart() as $item) {
if ($item['data'] && ($item['data']->is_taxable() || $item['data']->is_shipping_taxable())) {
$found_tax_classes[] = $item['data']->get_tax_class();
}
}
return array_unique($found_tax_classes);
}
public function get_cart_item_tax_classes_for_shipping()
{
$found_tax_classes = array();
foreach (WC()->cart->get_cart() as $item) {
if ($item['data'] && $item['data']->is_shipping_taxable()) {
$found_tax_classes[] = $item['data']->get_tax_class();
}
}
return array_unique($found_tax_classes);
}
public function get_displayed_subtotal()
{
return $this->display_prices_including_tax() ? $this->get_subtotal() + $this->get_subtotal_tax() : $this->get_subtotal();
}
public function find_product_in_cart($cart_id = false)
{
if (false !== $cart_id) {
if (is_array($this->cart_contents) && isset($this->cart_contents[$cart_id])) {
return $cart_id;
}
}
return '';
}
public function generate_cart_id($product_id, $variation_id = 0, $variation = array(), $cart_item_data = array())
{
$id_parts = array($product_id);
if ($variation_id && 0 !== $variation_id) {
$id_parts[] = $variation_id;
}
if (is_array($variation) && !empty($variation)) {
$variation_key = '';
foreach ($variation as $key => $value) {
$variation_key .= trim($key) . trim($value);
}
$id_parts[] = $variation_key;
}
if (is_array($cart_item_data) && !empty($cart_item_data)) {
$cart_item_data_key = '';
foreach ($cart_item_data as $key => $value) {
if (is_array($value) || is_object($value)) {
$value = http_build_query($value);
}
$cart_item_data_key .= trim($key) . trim($value);
}
$id_parts[] = $cart_item_data_key;
}
return apply_filters('woocommerce_cart_id', md5(implode('_', $id_parts)), $product_id, $variation_id, $variation, $cart_item_data);
}
public function add_to_cart($product_id = 0, $quantity = 1, $variation_id = 0, $variation = array(), $cart_item_data = array())
{
try {
$product_id = absint($product_id);
$variation_id = absint($variation_id);
if ('product_variation' === get_post_type($product_id)) {
$variation_id = $product_id;
$product_id = wp_get_post_parent_id($variation_id);
}
$product_data = wc_get_product($variation_id ? $variation_id : $product_id);
$quantity = apply_filters('woocommerce_add_to_cart_quantity', $quantity, $product_id);
if ($quantity <= 0 || !$product_data || 'trash' === $product_data->get_status()) {
return false;
}
if ($product_data->is_type('variation')) {
$missing_attributes = array();
$parent_data = wc_get_product($product_data->get_parent_id());
$variation_attributes = $product_data->get_variation_attributes();
$variation_attributes = array_filter($variation_attributes);
$posted_attributes = array();
foreach ($parent_data->get_attributes() as $attribute) {
if (!$attribute['is_variation']) {
continue;
}
$attribute_key = 'attribute_' . sanitize_title($attribute['name']);
if (isset($variation[$attribute_key])) {
if ($attribute['is_taxonomy']) {
$value = sanitize_title(wp_unslash($variation[$attribute_key]));
} else {
$value = html_entity_decode(wc_clean(wp_unslash($variation[$attribute_key])), ENT_QUOTES, get_bloginfo('charset'));
}
if (!empty($value) || '0' === $value) {
$posted_attributes[$attribute_key] = $value;
}
}
}
$posted_and_variation_attributes = array_merge($variation_attributes, $posted_attributes);
if (empty($variation_id)) {
$data_store = WC_Data_Store::load('product');
$variation_id = $data_store->find_matching_product_variation($parent_data, $posted_attributes);
}
if (empty($variation_id)) {
throw new Exception(__('Please choose product options…', 'woocommerce'));
}
$variation_data = wc_get_product_variation_attributes($variation_id);
$attributes = array();
foreach ($parent_data->get_attributes() as $attribute) {
if (!$attribute['is_variation']) {
continue;
}
$attribute_key = 'attribute_' . sanitize_title($attribute['name']);
$valid_value = isset($variation_data[$attribute_key]) ? $variation_data[$attribute_key] : '';
if (isset($posted_and_variation_attributes[$attribute_key])) {
$value = $posted_and_variation_attributes[$attribute_key];
if ($valid_value === $value) {
$attributes[$attribute_key] = $value;
} elseif ('' === $valid_value && in_array($value, $attribute->get_slugs(), true)) {
$attributes[$attribute_key] = $value;
} else {
throw new Exception(sprintf(__('Invalid value posted for %s', 'woocommerce'), wc_attribute_label($attribute['name'])));
}
} elseif ('' === $valid_value) {
$missing_attributes[] = wc_attribute_label($attribute['name']);
}
$variation = $attributes;
}
if (!empty($missing_attributes)) {
throw new Exception(sprintf(_n('%s is a required field', '%s are required fields', count($missing_attributes), 'woocommerce'), wc_format_list_of_items($missing_attributes)));
}
}
if (0 < $variation_id && (!$product_data->is_type('variation') || $product_data->get_parent_id() !== $product_id)) {
$product = wc_get_product($product_id);
throw new Exception(sprintf(__('The selected product isn\'t a variation of %2$s, please choose product options by visiting <a href="%1$s" title="%2$s">%2$s</a>.', 'woocommerce'), esc_url($product->get_permalink()), esc_html($product->get_name())));
}
$cart_item_data = (array) apply_filters('woocommerce_add_cart_item_data', $cart_item_data, $product_id, $variation_id, $quantity);
$cart_id = $this->generate_cart_id($product_id, $variation_id, $variation, $cart_item_data);
$cart_item_key = $this->find_product_in_cart($cart_id);
if ($product_data->is_sold_individually()) {
$quantity = apply_filters('woocommerce_add_to_cart_sold_individually_quantity', 1, $quantity, $product_id, $variation_id, $cart_item_data);
$found_in_cart = apply_filters('woocommerce_add_to_cart_sold_individually_found_in_cart', $cart_item_key && $this->cart_contents[$cart_item_key]['quantity'] > 0, $product_id, $variation_id, $cart_item_data, $cart_id);
if ($found_in_cart) {
$message = sprintf(__('You cannot add another "%s" to your cart.', 'woocommerce'), $product_data->get_name());
$message = apply_filters('woocommerce_cart_product_cannot_add_another_message', $message, $product_data);
throw new Exception(sprintf('<a href="%s" class="button wc-forward">%s</a> %s', wc_get_cart_url(), __('View cart', 'woocommerce'), $message));
}
}
if (!$product_data->is_purchasable()) {
$message = __('Sorry, this product cannot be purchased.', 'woocommerce');
$message = apply_filters('woocommerce_cart_product_cannot_be_purchased_message', $message, $product_data);
throw new Exception($message);
}
if (!$product_data->is_in_stock()) {
$message = sprintf(__('You cannot add "%s" to the cart because the product is out of stock.', 'woocommerce'), $product_data->get_name());
$message = apply_filters('woocommerce_cart_product_out_of_stock_message', $message, $product_data);
throw new Exception($message);
}
if (!$product_data->has_enough_stock($quantity)) {
$stock_quantity = $product_data->get_stock_quantity();
$message = sprintf(__('You cannot add that amount of "%1$s" to the cart because there is not enough stock (%2$s remaining).', 'woocommerce'), $product_data->get_name(), wc_format_stock_quantity_for_display($stock_quantity, $product_data));
$message = apply_filters('woocommerce_cart_product_not_enough_stock_message', $message, $product_data, $stock_quantity);
throw new Exception($message);
}
if ($product_data->managing_stock()) {
$products_qty_in_cart = $this->get_cart_item_quantities();
if (isset($products_qty_in_cart[$product_data->get_stock_managed_by_id()]) && !$product_data->has_enough_stock($products_qty_in_cart[$product_data->get_stock_managed_by_id()] + $quantity)) {
$stock_quantity = $product_data->get_stock_quantity();
$stock_quantity_in_cart = $products_qty_in_cart[$product_data->get_stock_managed_by_id()];
$message = sprintf('<a href="%s" class="button wc-forward">%s</a> %s', wc_get_cart_url(), __('View cart', 'woocommerce'), sprintf(__('You cannot add that amount to the cart — we have %1$s in stock and you already have %2$s in your cart.', 'woocommerce'), wc_format_stock_quantity_for_display($stock_quantity, $product_data), wc_format_stock_quantity_for_display($stock_quantity_in_cart, $product_data)));
$message = apply_filters('woocommerce_cart_product_not_enough_stock_already_in_cart_message', $message, $product_data, $stock_quantity, $stock_quantity_in_cart);
throw new Exception($message);
}
}
if ($cart_item_key) {
$new_quantity = $quantity + $this->cart_contents[$cart_item_key]['quantity'];
$this->set_quantity($cart_item_key, $new_quantity, false);
} else {
$cart_item_key = $cart_id;
$this->cart_contents[$cart_item_key] = apply_filters('woocommerce_add_cart_item', array_merge($cart_item_data, array('key' => $cart_item_key, 'product_id' => $product_id, 'variation_id' => $variation_id, 'variation' => $variation, 'quantity' => $quantity, 'data' => $product_data, 'data_hash' => wc_get_cart_item_data_hash($product_data))), $cart_item_key);
}
$this->cart_contents = apply_filters('woocommerce_cart_contents_changed', $this->cart_contents);
do_action('woocommerce_add_to_cart', $cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data);
return $cart_item_key;
} catch (Exception $e) {
if ($e->getMessage()) {
wc_add_notice($e->getMessage(), 'error');
}
return false;
}
}
public function remove_cart_item($cart_item_key)
{
if (isset($this->cart_contents[$cart_item_key])) {
$this->removed_cart_contents[$cart_item_key] = $this->cart_contents[$cart_item_key];
unset($this->removed_cart_contents[$cart_item_key]['data']);
do_action('woocommerce_remove_cart_item', $cart_item_key, $this);
unset($this->cart_contents[$cart_item_key]);
do_action('woocommerce_cart_item_removed', $cart_item_key, $this);
return true;
}
return false;
}
public function restore_cart_item($cart_item_key)
{
if (isset($this->removed_cart_contents[$cart_item_key])) {
$restore_item = $this->removed_cart_contents[$cart_item_key];
$this->cart_contents[$cart_item_key] = $restore_item;
$this->cart_contents[$cart_item_key]['data'] = wc_get_product($restore_item['variation_id'] ? $restore_item['variation_id'] : $restore_item['product_id']);
do_action('woocommerce_restore_cart_item', $cart_item_key, $this);
unset($this->removed_cart_contents[$cart_item_key]);
do_action('woocommerce_cart_item_restored', $cart_item_key, $this);
return true;
}
return false;
}
public function set_quantity($cart_item_key, $quantity = 1, $refresh_totals = true)
{
if (0 === $quantity || $quantity < 0) {
wc_do_deprecated_action('woocommerce_before_cart_item_quantity_zero', array($cart_item_key, $this), '3.7.0', 'woocommerce_remove_cart_item');
return $this->remove_cart_item($cart_item_key);
}
$old_quantity = $this->cart_contents[$cart_item_key]['quantity'];
$this->cart_contents[$cart_item_key]['quantity'] = $quantity;
do_action('woocommerce_after_cart_item_quantity_update', $cart_item_key, $quantity, $old_quantity, $this);
if ($refresh_totals) {
$this->calculate_totals();
}
do_action('woocommerce_cart_item_set_quantity', $cart_item_key, $quantity, $this);
return true;
}
public function get_customer()
{
return WC()->customer;
}
public function calculate_totals()
{
$this->reset_totals();
if ($this->is_empty()) {
$this->session->set_session();
return;
}
do_action('woocommerce_before_calculate_totals', $this);
new WC_Cart_Totals($this);
do_action('woocommerce_after_calculate_totals', $this);
}
public function needs_payment()
{
return apply_filters('woocommerce_cart_needs_payment', 0 < $this->get_total('edit'), $this);
}
public function calculate_shipping()
{
$this->shipping_methods = $this->needs_shipping() ? $this->get_chosen_shipping_methods(WC()->shipping()->calculate_shipping($this->get_shipping_packages())) : array();
$shipping_taxes = wp_list_pluck($this->shipping_methods, 'taxes');
$merged_taxes = array();
foreach ($shipping_taxes as $taxes) {
foreach ($taxes as $tax_id => $tax_amount) {
if (!isset($merged_taxes[$tax_id])) {
$merged_taxes[$tax_id] = 0;
}
$merged_taxes[$tax_id] += $tax_amount;
}
}
$this->set_shipping_total(array_sum(wp_list_pluck($this->shipping_methods, 'cost')));
$this->set_shipping_tax(array_sum($merged_taxes));
$this->set_shipping_taxes($merged_taxes);
return $this->shipping_methods;
}
protected function get_chosen_shipping_methods($calculated_shipping_packages = array())
{
$chosen_methods = array();
foreach ($calculated_shipping_packages as $key => $package) {
$chosen_method = wc_get_chosen_shipping_method_for_package($key, $package);
if ($chosen_method) {
$chosen_methods[$key] = $package['rates'][$chosen_method];
}
}
return $chosen_methods;
}
protected function filter_items_needing_shipping($item)
{
$product = $item['data'];
return $product && $product->needs_shipping();
}
protected function get_items_needing_shipping()
{
return array_filter($this->get_cart(), array($this, 'filter_items_needing_shipping'));
}
public function get_shipping_packages()
{
return apply_filters('woocommerce_cart_shipping_packages', array(array('contents' => $this->get_items_needing_shipping(), 'contents_cost' => array_sum(wp_list_pluck($this->get_items_needing_shipping(), 'line_total')), 'applied_coupons' => $this->get_applied_coupons(), 'user' => array('ID' => get_current_user_id()), 'destination' => array('country' => $this->get_customer()->get_shipping_country(), 'state' => $this->get_customer()->get_shipping_state(), 'postcode' => $this->get_customer()->get_shipping_postcode(), 'city' => $this->get_customer()->get_shipping_city(), 'address' => $this->get_customer()->get_shipping_address(), 'address_1' => $this->get_customer()->get_shipping_address(), 'address_2' => $this->get_customer()->get_shipping_address_2()), 'cart_subtotal' => $this->get_displayed_subtotal())));
}
public function needs_shipping()
{
if (!wc_shipping_enabled() || 0 === wc_get_shipping_method_count(true)) {
return false;
}
$needs_shipping = false;
foreach ($this->get_cart_contents() as $cart_item_key => $values) {
if ($values['data']->needs_shipping()) {
$needs_shipping = true;
break;
}
}
return apply_filters('woocommerce_cart_needs_shipping', $needs_shipping);
}
public function needs_shipping_address()
{
return apply_filters('woocommerce_cart_needs_shipping_address', true === $this->needs_shipping() && !wc_ship_to_billing_address_only());
}
public function show_shipping()
{
if (!wc_shipping_enabled() || !$this->get_cart_contents()) {
return false;
}
if ('yes' === get_option('woocommerce_shipping_cost_requires_address')) {
$country = $this->get_customer()->get_shipping_country();
if (!$country) {
return false;
}
$country_fields = WC()->countries->get_address_fields($country, 'shipping_');
if (isset($country_fields['shipping_state']) && $country_fields['shipping_state']['required'] && !$this->get_customer()->get_shipping_state()) {
return false;
}
if (isset($country_fields['shipping_postcode']) && $country_fields['shipping_postcode']['required'] && !$this->get_customer()->get_shipping_postcode()) {
return false;
}
}
return apply_filters('woocommerce_cart_ready_to_calc_shipping', true);
}
public function get_cart_shipping_total()
{
$total = __('Free!', 'woocommerce');
if (0 < $this->get_shipping_total()) {
if ($this->display_prices_including_tax()) {
$total = wc_price($this->shipping_total + $this->shipping_tax_total);
if ($this->shipping_tax_total > 0 && !wc_prices_include_tax()) {
$total .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$total = wc_price($this->shipping_total);
if ($this->shipping_tax_total > 0 && wc_prices_include_tax()) {
$total .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
}
return apply_filters('woocommerce_cart_shipping_total', $total, $this);
}
public function check_customer_coupons($posted)
{
foreach ($this->get_applied_coupons() as $code) {
$coupon = new WC_Coupon($code);
if ($coupon->is_valid()) {
$current_user = wp_get_current_user();
$billing_email = isset($posted['billing_email']) ? $posted['billing_email'] : '';
$check_emails = array_unique(array_filter(array_map('strtolower', array_map('sanitize_email', array($billing_email, $current_user->user_email)))));
$restrictions = $coupon->get_email_restrictions();
if (is_array($restrictions) && 0 < count($restrictions) && !$this->is_coupon_emails_allowed($check_emails, $restrictions)) {
$coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_NOT_YOURS_REMOVED);
$this->remove_coupon($code);
}
$coupon_usage_limit = $coupon->get_usage_limit_per_user();
if (0 < $coupon_usage_limit && 0 === get_current_user_id()) {
$coupon_data_store = $coupon->get_data_store();
$billing_email = strtolower(sanitize_email($billing_email));
if ($coupon_data_store && $coupon_data_store->get_usage_by_email($coupon, $billing_email) >= $coupon_usage_limit) {
if ($coupon_data_store->get_tentative_usages_for_user($coupon->get_id(), array($billing_email))) {
$coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_USAGE_LIMIT_COUPON_STUCK_GUEST);
} else {
$coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_USAGE_LIMIT_REACHED);
}
}
}
}
}
}
public function is_coupon_emails_allowed($check_emails, $restrictions)
{
foreach ($check_emails as $check_email) {
if (in_array($check_email, $restrictions, true)) {
return true;
}
foreach ($restrictions as $restriction) {
$regex = '/^' . str_replace('*', '(.+)?', $restriction) . '$/';
preg_match($regex, $check_email, $match);
if (!empty($match)) {
return true;
}
}
}
return false;
}
public function has_discount($coupon_code = '')
{
return $coupon_code ? in_array(wc_format_coupon_code($coupon_code), $this->applied_coupons, true) : count($this->applied_coupons) > 0;
}
public function apply_coupon($coupon_code)
{
if (!wc_coupons_enabled()) {
return false;
}
$coupon_code = wc_format_coupon_code($coupon_code);
$the_coupon = new WC_Coupon($coupon_code);
if ($the_coupon->get_code() !== $coupon_code) {
$the_coupon->set_code($coupon_code);
$the_coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_NOT_EXIST);
return false;
}
if (!$the_coupon->is_valid()) {
wc_add_notice($the_coupon->get_error_message(), 'error');
return false;
}
if ($this->has_discount($coupon_code)) {
$the_coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_ALREADY_APPLIED);
return false;
}
if ($the_coupon->get_individual_use()) {
$coupons_to_keep = apply_filters('woocommerce_apply_individual_use_coupon', array(), $the_coupon, $this->applied_coupons);
foreach ($this->applied_coupons as $applied_coupon) {
$keep_key = array_search($applied_coupon, $coupons_to_keep, true);
if (false === $keep_key) {
$this->remove_coupon($applied_coupon);
} else {
unset($coupons_to_keep[$keep_key]);
}
}
if (!empty($coupons_to_keep)) {
$this->applied_coupons += $coupons_to_keep;
}
}
if ($this->applied_coupons) {
foreach ($this->applied_coupons as $code) {
$coupon = new WC_Coupon($code);
if ($coupon->get_individual_use() && false === apply_filters('woocommerce_apply_with_individual_use_coupon', false, $the_coupon, $coupon, $this->applied_coupons)) {
$coupon->add_coupon_message(WC_Coupon::E_WC_COUPON_ALREADY_APPLIED_INDIV_USE_ONLY);
return false;
}
}
}
$this->applied_coupons[] = $coupon_code;
if ($the_coupon->get_free_shipping()) {
$packages = WC()->shipping()->get_packages();
$chosen_shipping_methods = WC()->session->get('chosen_shipping_methods');
foreach ($packages as $i => $package) {
$chosen_shipping_methods[$i] = 'free_shipping';
}
WC()->session->set('chosen_shipping_methods', $chosen_shipping_methods);
}
$the_coupon->add_coupon_message(WC_Coupon::WC_COUPON_SUCCESS);
do_action('woocommerce_applied_coupon', $coupon_code);
return true;
}
public function get_coupons($deprecated = null)
{
$coupons = array();
if ('order' === $deprecated) {
return $coupons;
}
foreach ($this->get_applied_coupons() as $code) {
$coupon = new WC_Coupon($code);
$coupons[$code] = $coupon;
}
return $coupons;
}
public function get_coupon_discount_amount($code, $ex_tax = true)
{
$totals = $this->get_coupon_discount_totals();
$discount_amount = isset($totals[$code]) ? $totals[$code] : 0;
if (!$ex_tax) {
$discount_amount += $this->get_coupon_discount_tax_amount($code);
}
return wc_cart_round_discount($discount_amount, wc_get_price_decimals());
}
public function get_coupon_discount_tax_amount($code)
{
$totals = $this->get_coupon_discount_tax_totals();
return wc_cart_round_discount(isset($totals[$code]) ? $totals[$code] : 0, wc_get_price_decimals());
}
public function remove_coupons($deprecated = null)
{
$this->set_coupon_discount_totals(array());
$this->set_coupon_discount_tax_totals(array());
$this->set_applied_coupons(array());
$this->session->set_session();
}
public function remove_coupon($coupon_code)
{
$coupon_code = wc_format_coupon_code($coupon_code);
$position = array_search($coupon_code, array_map('wc_format_coupon_code', $this->get_applied_coupons()), true);
if (false !== $position) {
unset($this->applied_coupons[$position]);
}
WC()->session->set('refresh_totals', true);
do_action('woocommerce_removed_coupon', $coupon_code);
return true;
}
public function calculate_fees()
{
do_action('woocommerce_cart_calculate_fees', $this);
}
public function fees_api()
{
return $this->fees_api;
}
public function add_fee($name, $amount, $taxable = false, $tax_class = '')
{
$this->fees_api()->add_fee(array('name' => $name, 'amount' => (float) $amount, 'taxable' => $taxable, 'tax_class' => $tax_class));
}
public function get_fees()
{
$fees = $this->fees_api()->get_fees();
if (property_exists($this, 'fees')) {
$fees = $fees + (array) $this->fees;
}
return $fees;
}
public function get_total_ex_tax()
{
return apply_filters('woocommerce_cart_total_ex_tax', wc_price(max(0, $this->get_total('edit') - $this->get_total_tax())));
}
public function get_cart_total()
{
return apply_filters('woocommerce_cart_contents_total', wc_price(wc_prices_include_tax() ? $this->get_cart_contents_total() + $this->get_cart_contents_tax() : $this->get_cart_contents_total()));
}
public function get_cart_subtotal($compound = false)
{
if ($compound) {
$cart_subtotal = wc_price($this->get_cart_contents_total() + $this->get_shipping_total() + $this->get_taxes_total(false, false));
} elseif ($this->display_prices_including_tax()) {
$cart_subtotal = wc_price($this->get_subtotal() + $this->get_subtotal_tax());
if ($this->get_subtotal_tax() > 0 && !wc_prices_include_tax()) {
$cart_subtotal .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$cart_subtotal = wc_price($this->get_subtotal());
if ($this->get_subtotal_tax() > 0 && wc_prices_include_tax()) {
$cart_subtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
return apply_filters('woocommerce_cart_subtotal', $cart_subtotal, $compound, $this);
}
public function get_product_price($product)
{
if ($this->display_prices_including_tax()) {
$product_price = wc_get_price_including_tax($product);
} else {
$product_price = wc_get_price_excluding_tax($product);
}
return apply_filters('woocommerce_cart_product_price', wc_price($product_price), $product);
}
public function get_product_subtotal($product, $quantity)
{
$price = $product->get_price();
if ($product->is_taxable()) {
if ($this->display_prices_including_tax()) {
$row_price = wc_get_price_including_tax($product, array('qty' => $quantity));
$product_subtotal = wc_price($row_price);
if (!wc_prices_include_tax() && $this->get_subtotal_tax() > 0) {
$product_subtotal .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$row_price = wc_get_price_excluding_tax($product, array('qty' => $quantity));
$product_subtotal = wc_price($row_price);
if (wc_prices_include_tax() && $this->get_subtotal_tax() > 0) {
$product_subtotal .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
} else {
$row_price = $price * $quantity;
$product_subtotal = wc_price($row_price);
}
return apply_filters('woocommerce_cart_product_subtotal', $product_subtotal, $product, $quantity, $this);
}
public function get_cart_tax()
{
$cart_total_tax = wc_round_tax_total($this->get_cart_contents_tax() + $this->get_shipping_tax() + $this->get_fee_tax());
return apply_filters('woocommerce_get_cart_tax', $cart_total_tax ? wc_price($cart_total_tax) : '');
}
public function get_tax_amount($tax_rate_id)
{
$taxes = wc_array_merge_recursive_numeric($this->get_cart_contents_taxes(), $this->get_fee_taxes());
return isset($taxes[$tax_rate_id]) ? $taxes[$tax_rate_id] : 0;
}
public function get_shipping_tax_amount($tax_rate_id)
{
$taxes = $this->get_shipping_taxes();
return isset($taxes[$tax_rate_id]) ? $taxes[$tax_rate_id] : 0;
}
public function get_taxes_total($compound = true, $display = true)
{
$total = 0;
$taxes = $this->get_taxes();
foreach ($taxes as $key => $tax) {
if (!$compound && WC_Tax::is_compound($key)) {
continue;
}
$total += $tax;
}
if ($display) {
$total = wc_format_decimal($total, wc_get_price_decimals());
}
return apply_filters('woocommerce_cart_taxes_total', $total, $compound, $display, $this);
}
public function get_total_discount()
{
return apply_filters('woocommerce_cart_total_discount', $this->get_discount_total() ? wc_price($this->get_discount_total()) : false, $this);
}
private function reset_totals()
{
$this->totals = $this->default_totals;
$this->fees_api->remove_all_fees();
do_action('woocommerce_cart_reset', $this, false);
}
public function get_tax_price_display_mode()
{
if ($this->get_customer() && $this->get_customer()->get_is_vat_exempt()) {
return 'excl';
}
return get_option('woocommerce_tax_display_cart');
}
public function get_cart_hash()
{
$cart_session = $this->session->get_cart_for_session();
$hash = $cart_session ? md5(wp_json_encode($cart_session) . $this->get_total('edit')) : '';
$hash = apply_filters_deprecated('woocommerce_add_to_cart_hash', array($hash, $cart_session), '3.6.0', 'woocommerce_cart_hash');
return apply_filters('woocommerce_cart_hash', $hash, $cart_session);
}
}