From 869f413e9bf6d5c96467dc3b571c07bd331707ee Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Sun, 6 Nov 2011 13:45:18 +0000 Subject: [PATCH] New cart code adapted from Lucas Starks pull request. Cart items are indexed by an md5 hash rather than numeric keys so we can add custom data to cart items. Plugins can hook in and add meta data, load it, and display it. The adjust_price() function lets you adjust a products price too since its loaded and stored in the cart on page load. All works like a dream, all thats left is to show the values on the cart page, and store them in the order item meta. Order item meta does need a slight change though, to allow data with the same keys. Working on that next. --- admin/writepanels/writepanel-product_data.php | 12 +- assets/js/admin/write-panels.js | 14 +- assets/js/admin/write-panels.min.js | 2 +- classes/cart.class.php | 591 +++++++++++------- classes/checkout.class.php | 6 +- classes/coupons.class.php | 4 +- classes/product.class.php | 7 + classes/shipping/shipping-flat_rate.php | 2 +- classes/tax.class.php | 2 +- shortcodes/shortcode-cart.php | 6 +- shortcodes/shortcode-checkout.php | 2 +- templates/checkout/review_order.php | 4 +- widgets/widget-cart.php | 8 +- woocommerce_actions.php | 12 +- woocommerce_template_functions.php | 36 +- 15 files changed, 432 insertions(+), 276 deletions(-) diff --git a/admin/writepanels/writepanel-product_data.php b/admin/writepanels/writepanel-product_data.php index 9e44cda261b..ad11efbb8e9 100644 --- a/admin/writepanels/writepanel-product_data.php +++ b/admin/writepanels/writepanel-product_data.php @@ -39,9 +39,9 @@ function woocommerce_product_data_box() {
  • -
  • +
  • -
  • +
  • @@ -64,10 +64,10 @@ function woocommerce_product_data_box() { echo '
    '; // Price - woocommerce_wp_text_input( array( 'id' => 'regular_price', 'label' => __('Regular Price', 'woothemes') . ' ('.get_woocommerce_currency_symbol().'):' ) ); + woocommerce_wp_text_input( array( 'id' => 'regular_price', 'label' => __('Regular Price', 'woothemes') . ' ('.get_woocommerce_currency_symbol().')' ) ); // Special Price - woocommerce_wp_text_input( array( 'id' => 'sale_price', 'label' => __('Sale Price', 'woothemes') . ' ('.get_woocommerce_currency_symbol().'):' ) ); + woocommerce_wp_text_input( array( 'id' => 'sale_price', 'label' => __('Sale Price', 'woothemes') . ' ('.get_woocommerce_currency_symbol().')' ) ); // Special Price date range $field = array( 'id' => 'sale_price_dates', 'label' => __('Sale Price Dates', 'woothemes') ); @@ -76,7 +76,7 @@ function woocommerce_product_data_box() { $sale_price_dates_to = get_post_meta($thepostid, 'sale_price_dates_to', true); echo '

    - + @@ -693,7 +693,7 @@ function woocommerce_product_selection_list_remove( $posts_to_display, $name ) { $SKU = get_post_meta($related_post->ID, 'sku', true); - ?>

  • post_title; ?> – #ID; ?>
  • post_title; ?> – #ID; ?>
  • 0){for(i=0;i0){taxRate=itemTax/100;itemTaxAmount=((itemCost*taxRate)*100);itemTaxAmount=itemTaxAmount.toFixed(2);totalItemTax=Math.round(itemTaxAmount)/100;totalItemTax=totalItemTax*itemQty}j=j+totalItemCost;l=l+totalItemTax}}n=j;m=parseFloat(n)+parseFloat(l)-parseFloat(o)+parseFloat(g)+parseFloat(k);if(m<0){m=0}d("input#_order_subtotal").val(n.toFixed(2));d("input#_order_tax").val(l.toFixed(2));d("input#_order_shipping_tax").val(k.toFixed(2));d("input#_order_total").val(m.toFixed(2))}return false});d("button.add_shop_order_item").click(function(){var j=d("select.add_item_id").val();if(j){d("table.woocommerce_order_items").block({message:null,overlayCSS:{background:"#fff url("+woocommerce_writepanel_params.plugin_url+"/assets/images/ajax-loader.gif) no-repeat center",opacity:0.6}});var g=d("table.woocommerce_order_items tbody tr.item").size();var h={action:"woocommerce_add_order_item",item_to_add:d("select.add_item_id").val(),index:g,security:woocommerce_writepanel_params.add_order_item_nonce};d.post(woocommerce_writepanel_params.ajax_url,h,function(k){d("table.woocommerce_order_items tbody#order_items_list").append(k);d("table.woocommerce_order_items").unblock();d("select.add_item_id").css("border-color","").val("");d(".tips").easyTooltip()})}else{d("select.add_item_id").css("border-color","red")}});d("button.add_meta").live("click",function(){var g=d(this).closest("tr.item").attr("rel");d(this).closest("table.meta").find(".meta_items").append('');return false});d("button.remove_meta").live("click",function(){var g=confirm("Remove this meta key?");if(g){d(this).closest("tr").remove()}return false});d("button.billing-same-as-shipping").live("click",function(){var g=confirm(woocommerce_writepanel_params.copy_billing);if(g){d("input#shipping_first_name").val(d("input#billing_first_name").val());d("input#shipping_last_name").val(d("input#billing_last_name").val());d("input#shipping_company").val(d("input#billing_company").val());d("input#shipping_address_1").val(d("input#billing_address_1").val());d("input#shipping_address_2").val(d("input#billing_address_2").val());d("input#shipping_city").val(d("input#billing_city").val());d("input#shipping_postcode").val(d("input#billing_postcode").val());d("input#shipping_country").val(d("input#billing_country").val());d("input#shipping_state").val(d("input#billing_state").val())}return false});d("select#product-type").change(function(){var g=d(this).val();d(".show_if_simple, .show_if_variable, .show_if_grouped").hide();if(g=="simple"){d(".show_if_simple").show()}else{if(g=="variable"){d(".show_if_variable").show()}else{if(g=="grouped"){d(".show_if_grouped").show();d("input#downloadable").removeAttr("checked").change()}}}d("ul.tabs li:visible").eq(0).find("a").click();d("body").trigger("woocommerce-product-type-change",g,d(this))}).change();d("input#downloadable").change(function(){d(".show_if_downloadable").hide();if(d("input#downloadable").is(":checked")){d(".show_if_downloadable").show()}d("ul.tabs li:visible").eq(0).find("a").click()}).change();d("input#manage_stock").change(function(){if(d(this).is(":checked")){d("div.stock_fields").show()}else{d("div.stock_fields").hide()}}).change();var e=d("#sale_price_dates_from, #sale_price_dates_to").datepicker({defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:true,showOn:"button",buttonImage:woocommerce_writepanel_params.calendar_image,buttonImageOnly:true,onSelect:function(j){var k=this.id=="sale_price_dates_from"?"minDate":"maxDate",g=d(this).data("datepicker"),h=d.datepicker.parseDate(g.settings.dateFormat||d.datepicker._defaults.dateFormat,j,g.settings);e.not(this).datepicker("option",k,h)}});d(".date-picker").datepicker({dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:true,showOn:"button",buttonImage:woocommerce_writepanel_params.calendar_image,buttonImageOnly:true});d("#attributes_list select.multiselect").multiselect({noneSelectedText:woocommerce_writepanel_params.select_terms,selectedList:4});var c=d("#attributes_list").children("tr").get();c.sort(function(h,g){var k=d(h).attr("rel");var j=d(g).attr("rel");return(kj)?1:0});d(c).each(function(g,h){d("#attributes_list").append(h)});function a(){d("table.woocommerce_attributes, table.woocommerce_variable_attributes").each(function(){if(d("tbody tr",this).size()==0){d(this).parent().hide()}else{d(this).parent().show()}})}a();function b(){d("#attributes_list tr").each(function(g,h){d(".attribute_position",h).val(parseInt(d(h).index("#attributes_list tr")))})}d("button.add_attribute").click(function(){var h=d("table.woocommerce_attributes tbody tr").size();var j=d("select.attribute_taxonomy").val();if(!j){var k=d("select#product-type").val();if(k!="variable"){enable_variation='style="display:none;"'}else{enable_variation=""}d("table.woocommerce_attributes tbody").append('')}else{var g=d("table.woocommerce_attributes tbody tr."+j);d("table.woocommerce_attributes tbody").append(d(g));d(g).show();b()}a()});d("button.hide_row").live("click",function(){var g=confirm("Remove this attribute?");if(g){d(this).parent().parent().find("select, input[type=text]").val("");d(this).parent().parent().hide();a()}return false});d("#attributes_list button.remove_row").live("click",function(){var g=confirm("Remove this attribute?");if(g){d(this).parent().parent().remove();a();b()}return false});d("table.woocommerce_attributes tbody").sortable({items:"tr",cursor:"move",axis:"y",scrollSensitivity:40,helper:function(h,g){g.children().each(function(){d(this).width(d(this).width())});return g},start:function(g,h){h.item.css("background-color","#f6f6f6")},stop:function(g,h){h.item.removeAttr("style");b()}});d(".multi_select_products button").live("click",function(){var n=d(this).parent().parent().parent().parent();var g=d(this);var j=g.parent().parent();if(j.is(".multi_select_products_target_upsell")||j.is(".multi_select_products_target_crosssell")){g.parent().remove()}else{if(g.is(".add_upsell")){var l=d(".multi_select_products_target_upsell",d(n));var m="upsell_ids[]"}else{var l=d(".multi_select_products_target_crosssell",d(n));var m="crosssell_ids[]"}var h=d("li[rel="+g.parent().attr("rel")+"]",l);if(d(h).size()>0){return false}var k=g.parent().clone();k.find("button:eq(0)").html("X");k.find("button:eq(1)").remove();k.find("input").val(g.parent().attr("rel"));k.find(".product_id").attr("name",m);k.appendTo(l)}});var f;d(".multi_select_products #product_search").bind("keyup click",function(){d(".multi_select_products_source").addClass("loading");d(".multi_select_products_source li:not(.product_search)").remove();if(f){f.abort()}var j=d(this).val();var g=this;var h=d(this).attr("rel");if(j.length<3){d(".multi_select_products_source").removeClass("loading");return}var k={name:h,search:encodeURI(j),action:"woocommerce_upsell_crosssell_search_products",security:woocommerce_writepanel_params.upsell_crosssell_search_products_nonce};f=d.ajax({url:woocommerce_writepanel_params.ajax_url,data:k,type:"POST",success:function(l){d(".multi_select_products_source").removeClass("loading");d(".multi_select_products_source li:not(.product_search)").remove();d(g).parent().parent().append(l)}})})}); \ No newline at end of file +jQuery(function(d){d("#upsell_product_data").bind("keypress",function(g){if(g.keyCode==13){return false}});d("ul.tabs").show();d("div.panel-wrap").each(function(){d("div.panel:not(div.panel:first)",this).hide()});d("ul.tabs a").click(function(){var g=d(this).closest("div.panel-wrap");d("ul.tabs li",g).removeClass("active");d(this).parent().addClass("active");d("div.panel",g).hide();d(d(this).attr("href")).show();return false});d("#order_items_list button.remove_row").live("click",function(){var g=confirm(woocommerce_writepanel_params.remove_item_notice);if(g){d(this).closest("tr.item").hide();d("input",d(this).closest("tr.item")).val("")}return false});d("button.calc_totals").live("click",function(){var p=confirm(woocommerce_writepanel_params.cart_total);if(p){var h=d("#order_items_list tr.item").size();var n=0;var o=d("input#_order_discount").val();var g=d("input#_order_shipping").val();var k=parseFloat(d("input#_order_shipping_tax").val());var l=0;var j=0;var m=0;if(!o){o=0}if(!g){g=0}if(!k){k=0}if(h>0){for(i=0;i0){taxRate=itemTax/100;itemTaxAmount=((itemCost*taxRate)*100);itemTaxAmount=itemTaxAmount.toFixed(2);totalItemTax=Math.round(itemTaxAmount)/100;totalItemTax=totalItemTax*itemQty}j=j+totalItemCost;l=l+totalItemTax}}n=j;m=parseFloat(n)+parseFloat(l)-parseFloat(o)+parseFloat(g)+parseFloat(k);if(m<0){m=0}d("input#_order_subtotal").val(n.toFixed(2));d("input#_order_tax").val(l.toFixed(2));d("input#_order_shipping_tax").val(k.toFixed(2));d("input#_order_total").val(m.toFixed(2))}return false});d("button.add_shop_order_item").click(function(){var j=d("select.add_item_id").val();if(j){d("table.woocommerce_order_items").block({message:null,overlayCSS:{background:"#fff url("+woocommerce_writepanel_params.plugin_url+"/assets/images/ajax-loader.gif) no-repeat center",opacity:0.6}});var g=d("table.woocommerce_order_items tbody tr.item").size();var h={action:"woocommerce_add_order_item",item_to_add:d("select.add_item_id").val(),index:g,security:woocommerce_writepanel_params.add_order_item_nonce};d.post(woocommerce_writepanel_params.ajax_url,h,function(k){d("table.woocommerce_order_items tbody#order_items_list").append(k);d("table.woocommerce_order_items").unblock();d("select.add_item_id").css("border-color","").val("");d(".tips").easyTooltip()})}else{d("select.add_item_id").css("border-color","red")}});d("button.add_meta").live("click",function(){var g=d(this).closest("tr.item").attr("rel");d(this).closest("table.meta").find(".meta_items").append('');return false});d("button.remove_meta").live("click",function(){var g=confirm("Remove this meta key?");if(g){d(this).closest("tr").remove()}return false});d("button.billing-same-as-shipping").live("click",function(){var g=confirm(woocommerce_writepanel_params.copy_billing);if(g){d("input#shipping_first_name").val(d("input#billing_first_name").val());d("input#shipping_last_name").val(d("input#billing_last_name").val());d("input#shipping_company").val(d("input#billing_company").val());d("input#shipping_address_1").val(d("input#billing_address_1").val());d("input#shipping_address_2").val(d("input#billing_address_2").val());d("input#shipping_city").val(d("input#billing_city").val());d("input#shipping_postcode").val(d("input#billing_postcode").val());d("input#shipping_country").val(d("input#billing_country").val());d("input#shipping_state").val(d("input#billing_state").val())}return false});d("select#product-type").change(function(){var g=d(this).val();d(".show_if_simple, .show_if_variable, .show_if_grouped").hide();if(g=="simple"){d(".show_if_simple").show()}else{if(g=="variable"){d(".show_if_variable").show()}else{if(g=="grouped"){d(".show_if_grouped").show();d("input#downloadable").removeAttr("checked").change()}}}d("ul.tabs li:visible").eq(0).find("a").click();d("input#manage_stock").change();d("body").trigger("woocommerce-product-type-change",g,d(this))}).change();d("input#downloadable").change(function(){d(".show_if_downloadable").hide();if(d("input#downloadable").is(":checked")){d(".show_if_downloadable").show()}if(d(".downloads_tab").is(".active")){d("ul.tabs li:visible").eq(0).find("a").click()}}).change();d("input#virtual").change(function(){d(".show_if_virtual").hide();if(d("input#virtual").is(":checked")){d(".show_if_virtual").show()}}).change();d("input#manage_stock").change(function(){if(d(this).is(":checked")){d("div.stock_fields").show()}else{d("div.stock_fields").hide()}}).change();var e=d("#sale_price_dates_from, #sale_price_dates_to").datepicker({defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:true,showOn:"button",buttonImage:woocommerce_writepanel_params.calendar_image,buttonImageOnly:true,onSelect:function(j){var k=this.id=="sale_price_dates_from"?"minDate":"maxDate",g=d(this).data("datepicker"),h=d.datepicker.parseDate(g.settings.dateFormat||d.datepicker._defaults.dateFormat,j,g.settings);e.not(this).datepicker("option",k,h)}});d(".date-picker").datepicker({dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:true,showOn:"button",buttonImage:woocommerce_writepanel_params.calendar_image,buttonImageOnly:true});d("#attributes_list select.multiselect").multiselect({noneSelectedText:woocommerce_writepanel_params.select_terms,selectedList:4});var c=d("#attributes_list").children("tr").get();c.sort(function(h,g){var k=d(h).attr("rel");var j=d(g).attr("rel");return(kj)?1:0});d(c).each(function(g,h){d("#attributes_list").append(h)});function a(){d("table.woocommerce_attributes, table.woocommerce_variable_attributes").each(function(){if(d("tbody tr",this).size()==0){d(this).parent().hide()}else{d(this).parent().show()}})}a();function b(){d("#attributes_list tr").each(function(g,h){d(".attribute_position",h).val(parseInt(d(h).index("#attributes_list tr")))})}d("button.add_attribute").click(function(){var h=d("table.woocommerce_attributes tbody tr").size();var j=d("select.attribute_taxonomy").val();if(!j){var k=d("select#product-type").val();if(k!="variable"){enable_variation='style="display:none;"'}else{enable_variation=""}d("table.woocommerce_attributes tbody").append('')}else{var g=d("table.woocommerce_attributes tbody tr."+j);d("table.woocommerce_attributes tbody").append(d(g));d(g).show();b()}a()});d("button.hide_row").live("click",function(){var g=confirm("Remove this attribute?");if(g){d(this).parent().parent().find("select, input[type=text]").val("");d(this).parent().parent().hide();a()}return false});d("#attributes_list button.remove_row").live("click",function(){var g=confirm("Remove this attribute?");if(g){d(this).parent().parent().remove();a();b()}return false});d("table.woocommerce_attributes tbody").sortable({items:"tr",cursor:"move",axis:"y",scrollSensitivity:40,helper:function(h,g){g.children().each(function(){d(this).width(d(this).width())});return g},start:function(g,h){h.item.css("background-color","#f6f6f6")},stop:function(g,h){h.item.removeAttr("style");b()}});d(".multi_select_products button").live("click",function(){var n=d(this).parent().parent().parent().parent();var g=d(this);var j=g.parent().parent();if(j.is(".multi_select_products_target_upsell")||j.is(".multi_select_products_target_crosssell")){g.parent().remove()}else{if(g.is(".add_upsell")){var l=d(".multi_select_products_target_upsell",d(n));var m="upsell_ids[]"}else{var l=d(".multi_select_products_target_crosssell",d(n));var m="crosssell_ids[]"}var h=d("li[rel="+g.parent().attr("rel")+"]",l);if(d(h).size()>0){return false}var k=g.parent().clone();k.find("button:eq(0)").html("×");k.find("button:eq(1)").remove();k.find("input").val(g.parent().attr("rel"));k.find(".product_id").attr("name",m);k.appendTo(l)}});var f;d(".multi_select_products #product_search").bind("keyup click",function(){d(".multi_select_products_source").addClass("loading");d(".multi_select_products_source li:not(.product_search)").remove();if(f){f.abort()}var j=d(this).val();var g=this;var h=d(this).attr("rel");if(j.length<3){d(".multi_select_products_source").removeClass("loading");return}var k={name:h,search:encodeURI(j),action:"woocommerce_upsell_crosssell_search_products",security:woocommerce_writepanel_params.upsell_crosssell_search_products_nonce};f=d.ajax({url:woocommerce_writepanel_params.ajax_url,data:k,type:"POST",success:function(l){d(".multi_select_products_source").removeClass("loading");d(".multi_select_products_source li:not(.product_search)").remove();d(g).parent().parent().append(l)}})})}); \ No newline at end of file diff --git a/classes/cart.class.php b/classes/cart.class.php index 282f62ed8c1..34f0d7aaf7b 100644 --- a/classes/cart.class.php +++ b/classes/cart.class.php @@ -12,12 +12,16 @@ */ class woocommerce_cart { + /* Public Variables */ + var $cart_contents; + var $applied_coupons; + var $cart_contents_total; var $cart_contents_total_ex_tax; var $cart_contents_weight; var $cart_contents_count; var $cart_contents_tax; - var $cart_contents; + var $total; var $subtotal; var $subtotal_ex_tax; @@ -25,43 +29,50 @@ class woocommerce_cart { var $discount_total; var $shipping_total; var $shipping_tax_total; - var $applied_coupons; - /** constructor */ + /** + * Constructor + */ function __construct() { add_action('init', array(&$this, 'init'), 1); // Get cart on init add_action('wp', array(&$this, 'calculate_totals'), 1); // Defer calculate totals so we can detect page } - function init () { + /** + * Loads the cart data from the session during WordPress init + */ + function init() { $this->applied_coupons = array(); $this->get_cart_from_session(); if ( isset($_SESSION['coupons']) ) $this->applied_coupons = $_SESSION['coupons']; } - /** Gets the cart data from the PHP session */ + /** + * Get the cart data from the PHP session + */ function get_cart_from_session() { - if ( isset($_SESSION['cart']) && is_array($_SESSION['cart']) ) : + if (isset($_SESSION['cart']) && is_array($_SESSION['cart'])) : $cart = $_SESSION['cart']; - foreach ($cart as $values) : + foreach ($cart as $key => $values) : - if ($values['variation_id']>0) : + if ($values['variation_id'] > 0) : $_product = &new woocommerce_product_variation($values['variation_id']); else : $_product = &new woocommerce_product($values['product_id']); endif; if ($_product->exists && $values['quantity']>0) : - - $this->cart_contents[] = array( + + // Put session data into array. Run through filter so other plugins can load their own session data + $this->cart_contents[$key] = apply_filters('woocommerce_get_cart_item_from_session', array( 'product_id' => $values['product_id'], 'variation_id' => $values['variation_id'], 'variation' => $values['variation'], 'quantity' => $values['quantity'], 'data' => $_product - ); + ), $values); endif; endforeach; @@ -73,7 +84,9 @@ class woocommerce_cart { if (!is_array($this->cart_contents)) $this->cart_contents = array(); } - /** sets the php session data for the cart and coupon */ + /** + * Sets the php session data for the cart and coupons + */ function set_session() { $cart = array(); @@ -88,9 +101,10 @@ class woocommerce_cart { $this->calculate_totals(); } - /** Empty the cart */ + /** + * Empty the cart data and destroy the session + */ function empty_cart() { - $this->cart_contents = array(); $this->total = 0; $this->cart_contents_total = 0; @@ -104,7 +118,6 @@ class woocommerce_cart { $this->subtotal_ex_tax = 0; $this->discount_total = 0; $this->shipping_total = 0; - unset($_SESSION['cart']); unset($_SESSION['coupons']); } @@ -112,29 +125,42 @@ class woocommerce_cart { /** * Check if product is in the cart and return cart item key * - * @param int $product_id - * @param int $variation_id optional variation id - * @param array $variation array of attributre values - * @return int|null + * Cart item key will be unique based on the item and its properties, such as variations */ - function find_product_in_cart($product_id, $variation_id, $variation = array()) { - - foreach ($this->cart_contents as $cart_item_key => $cart_item) : - - if (empty($variation_id) && $cart_item['product_id'] == $product_id) : - return $cart_item_key; - elseif ($cart_item['product_id'] == $product_id && $cart_item['variation_id'] == $variation_id) : - if($variation == $cart_item['variation']) : - return $cart_item_key; - endif; - endif; - - endforeach; - - return NULL; + function find_product_in_cart( $cart_id = false ) { + if ($cart_id !== false) foreach ($this->cart_contents as $cart_item_key => $cart_item) if ($cart_item_key == $cart_id) return $cart_item_key; } /** + * Generate a unique ID for the cart item being added + */ + function generate_cart_id( $product_id, $variation_id = '', $variation = '', $cart_item_data = '' ) { + + $id_parts = array( $product_id ); + + if ($variation_id) $id_parts[] = $variation_id; + + if (is_array($variation)) : + $variation_key = ''; + foreach ($variation as $key => $value) : + $variation_key .= trim($key) . trim($value); + endforeach; + $id_parts[] = $variation_key; + endif; + + if (is_array($cart_item_data)) : + $cart_item_data_key = ''; + foreach ($cart_item_data as $key => $value) : + if (is_array($value)) $value = http_build_query($value); + $cart_item_data_key .= trim($key) . trim($value); + endforeach; + $id_parts[] = $cart_item_data_key; + endif; + + return md5( implode('_', $id_parts) ); + } + + /** * Add a product to the cart * * @param string product_id contains the id of the product to add to the cart @@ -142,12 +168,19 @@ class woocommerce_cart { * @param int variation_id * @param array variation attribute values */ - function add_to_cart( $product_id, $quantity = 1, $variation = '', $variation_id = '' ) { + function add_to_cart( $product_id, $quantity = 1, $variation_id = '', $variation = '' ) { global $woocommerce; - if ($quantity < 1) $quantity = 1; + if ($quantity < 1) return false; - $found_cart_item_key = $this->find_product_in_cart($product_id, $variation_id, $variation); + // Load cart item data - may be added by other plugins + $cart_item_data = (array) apply_filters('woocommerce_add_cart_item_data', array(), $product_id); + + // Generate a ID based on product ID, variation ID, variation data, and other cart item data + $cart_id = $this->generate_cart_id( $product_id, $variation_id, $variation, $cart_item_data ); + + // See if this product and its options is already in the cart + $cart_item_key = $this->find_product_in_cart($cart_id); if ($variation_id>0) : $product_data = &new woocommerce_product_variation( $variation_id ); @@ -157,10 +190,10 @@ class woocommerce_cart { // Price set check if( $product_data->get_price() === '' ) : - $woocommerce->add_error( __('This product cannot be purchased - the price is not yet announced', 'woothemes') ); + $woocommerce->add_error( __('This product cannot be purchased - the price is not yet set', 'woothemes') ); return false; endif; - + // Stock check - only check if we're managing stock and backorders are not allowed if ( !$product_data->has_enough_stock( $quantity ) ) : $woocommerce->add_error( sprintf(__('You cannot add that amount to the cart since there is not enough stock. We have %s in stock.', 'woothemes'), $product_data->get_stock_quantity() )); @@ -169,41 +202,88 @@ class woocommerce_cart { $woocommerce->add_error( __('You cannot add that product to the cart since the product is out of stock.', 'woothemes') ); return false; endif; + + if ($cart_item_key) : - // Add it - if (is_numeric($found_cart_item_key)) : - - $quantity = $quantity + $this->cart_contents[$found_cart_item_key]['quantity']; + $quantity = $quantity + $this->cart_contents[$cart_item_key]['quantity']; // Stock check - this time accounting for whats already in-cart if ( !$product_data->has_enough_stock( $quantity ) ) : - $woocommerce->add_error( sprintf(__('You cannot add that amount to the cart since there is not enough stock. We have %s in stock and you already have %s in your cart.', 'woothemes'), $product_data->get_stock_quantity(), $this->cart_contents[$found_cart_item_key]['quantity'] )); + $woocommerce->add_error( sprintf(__('You cannot add that amount to the cart since there is not enough stock. We have %s in stock and you already have %s in your cart.', 'woothemes'), $product_data->get_stock_quantity(), $this->cart_contents[$cart_item_key]['quantity'] )); return false; elseif ( !$product_data->is_in_stock() ) : $woocommerce->add_error( __('You cannot add that product to the cart since the product is out of stock.', 'woothemes') ); return false; endif; - $this->cart_contents[$found_cart_item_key]['quantity'] = $quantity; - + $this->cart_contents[$cart_item_key]['quantity'] = $quantity; + else : - $cart_item_key = sizeof($this->cart_contents); - - $this->cart_contents[$cart_item_key] = array( + // Add item after merging with $cart_item_data - hook to allow plugins to modify cart item + $this->cart_contents[$cart_id] = apply_filters('woocommerce_add_cart_item', array_merge( $cart_item_data, array( 'product_id' => $product_id, 'variation_id' => $variation_id, 'variation' => $variation, 'quantity' => $quantity, 'data' => $product_data - ); - - endif; + ))); + endif; + $this->set_session(); return true; } + + /** + * Applies a coupon code + * + * @param string code The code to apply + * @return bool True if the coupon is applied, false if it does not exist or cannot be applied + */ + function add_discount( $coupon_code ) { + global $woocommerce; + + $the_coupon = &new woocommerce_coupon($coupon_code); + + if ($the_coupon->id) : + + // Check if applied + if ($woocommerce->cart->has_discount($coupon_code)) : + $woocommerce->add_error( __('Discount code already applied!', 'woothemes') ); + return false; + endif; + + // Check it can be used with cart + if (!$the_coupon->is_valid()) : + $woocommerce->add_error( __('Invalid coupon.', 'woothemes') ); + return false; + endif; + + // If its individual use then remove other coupons + if ($the_coupon->individual_use=='yes') : + $this->applied_coupons = array(); + endif; + + foreach ($this->applied_coupons as $code) : + $coupon = &new woocommerce_coupon($code); + if ($coupon->individual_use=='yes') : + $this->applied_coupons = array(); + endif; + endforeach; + + $this->applied_coupons[] = $coupon_code; + $this->set_session(); + $woocommerce->add_message( __('Discount code applied successfully.', 'woothemes') ); + return true; + + else : + $woocommerce->add_error( __('Coupon does not exist!', 'woothemes') ); + return false; + endif; + return false; + } /** * Set the quantity for an item in the cart @@ -211,123 +291,19 @@ class woocommerce_cart { * @param string cart_item_key contains the id of the cart item * @param string quantity contains the quantity of the item */ - function set_quantity( $cart_item, $quantity = 1 ) { + function set_quantity( $cart_item_key, $quantity = 1 ) { if ($quantity==0 || $quantity<0) : - unset($this->cart_contents[$cart_item]); + unset($this->cart_contents[$cart_item_key]); else : - $this->cart_contents[$cart_item]['quantity'] = $quantity; + $this->cart_contents[$cart_item_key]['quantity'] = $quantity; endif; $this->set_session(); } - /** - * Returns the contents of the cart - * - * @return array cart_contents + /** + * calculate totals for the items in the cart */ - function get_cart() { - return $this->cart_contents; - } - - /** - * Gets cross sells based on the items in the cart - * - * @return array cross_sells item ids of cross sells - */ - function get_cross_sells() { - $cross_sells = array(); - $in_cart = array(); - if (sizeof($this->cart_contents)>0) : foreach ($this->cart_contents as $cart_item_key => $values) : - if ($values['quantity']>0) : - $cross_sells = array_merge($values['data']->get_cross_sells(), $cross_sells); - $in_cart[] = $values['product_id']; - endif; - endforeach; endif; - $cross_sells = array_diff($cross_sells, $in_cart); - return $cross_sells; - } - - /** gets the url to the cart page */ - function get_cart_url() { - $cart_page_id = get_option('woocommerce_cart_page_id'); - if ($cart_page_id) return get_permalink($cart_page_id); - } - - /** gets the url to the checkout page */ - function get_checkout_url() { - $checkout_page_id = get_option('woocommerce_checkout_page_id'); - if ($checkout_page_id) : - if (is_ssl()) return str_replace('http:', 'https:', get_permalink($checkout_page_id)); - return get_permalink($checkout_page_id); - endif; - } - - /** gets the url to remove an item from the cart */ - function get_remove_url( $cart_item_key ) { - global $woocommerce; - $cart_page_id = get_option('woocommerce_cart_page_id'); - if ($cart_page_id) return $woocommerce->nonce_url( 'cart', add_query_arg('remove_item', $cart_item_key, get_permalink($cart_page_id))); - } - - /** looks through the cart to see if shipping is actually required */ - function needs_shipping() { - global $woocommerce; - - if (!$woocommerce->shipping->enabled) return false; - if (!is_array($this->cart_contents)) return false; - - $needs_shipping = false; - - foreach ($this->cart_contents as $cart_item_key => $values) : - $_product = $values['data']; - if ( $_product->needs_shipping() ) : - $needs_shipping = true; - endif; - endforeach; - - return $needs_shipping; - } - - /** Sees if we need a shipping address */ - function ship_to_billing_address_only() { - - $ship_to_billing_address_only = get_option('woocommerce_ship_to_billing_address_only'); - - if ($ship_to_billing_address_only=='yes') return true; - - return false; - } - - /** looks at the totals to see if payment is actually required */ - function needs_payment() { - if ( $this->total > 0 ) return true; - return false; - } - - /** looks through the cart to check each item is in stock */ - function check_cart_item_stock() { - $error = new WP_Error(); - foreach ($this->cart_contents as $cart_item_key => $values) : - $_product = $values['data']; - if ($_product->managing_stock()) : - if ($_product->is_in_stock() && $_product->has_enough_stock( $values['quantity'] )) : - // :) - else : - $error->add( 'out-of-stock', sprintf(__('Sorry, we do not have enough "%s" in stock to fulfill your order (%s in stock). Please edit your cart and try again. We apologise for any inconvenience caused.', 'woothemes'), $_product->get_title(), $_product->stock ) ); - return $error; - endif; - else : - if (!$_product->is_in_stock()) : - $error->add( 'out-of-stock', sprintf(__('Sorry, we do not have enough "%s" in stock to fulfill your order. Please edit your cart and try again. We apologise for any inconvenience caused.', 'woothemes'), $_product->get_title() ) ); - return $error; - endif; - endif; - endforeach; - return true; - } - - /** calculate totals for the items in the cart */ function calculate_totals() { global $woocommerce; @@ -347,7 +323,10 @@ class woocommerce_cart { $this->shipping_total = 0; if (sizeof($this->cart_contents)>0) : foreach ($this->cart_contents as $cart_item_key => $values) : + + // Get product from cart data $_product = $values['data']; + if ($_product->exists() && $values['quantity']>0) : $this->cart_contents_count = $this->cart_contents_count + $values['quantity']; @@ -512,30 +491,220 @@ class woocommerce_cart { if ($this->total < 0) $this->total = 0; } - /** gets the total (after calculation) */ + /** + *returns whether or not a discount has been applied + */ + function has_discount( $code ) { + if (in_array($code, $this->applied_coupons)) return true; + return false; + } + + /** + * looks through the cart to see if shipping is actually required + */ + function needs_shipping() { + global $woocommerce; + + if (!$woocommerce->shipping->enabled) return false; + if (!is_array($this->cart_contents)) return false; + + $needs_shipping = false; + + foreach ($this->cart_contents as $cart_item_key => $values) : + $_product = $values['data']; + if ( $_product->needs_shipping() ) : + $needs_shipping = true; + endif; + endforeach; + + return $needs_shipping; + } + + /** + * Sees if we need a shipping address + */ + function ship_to_billing_address_only() { + if (get_option('woocommerce_ship_to_billing_address_only')=='yes') return true; else return false; + } + + /** + * looks at the totals to see if payment is actually required + */ + function needs_payment() { + if ( $this->total > 0 ) return true; else return false; + } + + /** + * looks through the cart to check each item is in stock + */ + function check_cart_item_stock() { + $error = new WP_Error(); + foreach ($this->cart_contents as $cart_item_key => $values) : + $_product = $values['data']; + if ($_product->managing_stock()) : + if ($_product->is_in_stock() && $_product->has_enough_stock( $values['quantity'] )) : + // :) + else : + $error->add( 'out-of-stock', sprintf(__('Sorry, we do not have enough "%s" in stock to fulfill your order (%s in stock). Please edit your cart and try again. We apologise for any inconvenience caused.', 'woothemes'), $_product->get_title(), $_product->stock ) ); + return $error; + endif; + else : + if (!$_product->is_in_stock()) : + $error->add( 'out-of-stock', sprintf(__('Sorry, we do not have enough "%s" in stock to fulfill your order. Please edit your cart and try again. We apologise for any inconvenience caused.', 'woothemes'), $_product->get_title() ) ); + return $error; + endif; + endif; + endforeach; + return true; + } + + /** + * Gets and formats a list of cart item data + variations for display on the frontend + */ + function get_item_data( $cart_item, $flat = false ) { + global $woocommerce; + + if (!$flat) $return = '
    '; + + // Variation data + if($cart_item['data'] instanceof woocommerce_product_variation && is_array($cart_item['variation'])) : + + $variation_list = array(); + + foreach ($cart_item['variation'] as $name => $value) : + + if (!$value) continue; + + // If this is a term slug, get the term's nice name + if (taxonomy_exists(esc_attr(str_replace('attribute_', '', $name)))) : + $term = get_term_by('slug', $value, esc_attr(str_replace('attribute_', '', $name))); + if (!is_wp_error($term) && $term->name) : + $value = $term->name; + endif; + else : + $value = ucfirst($value); + endif; + + if ($flat) : + $variation_list[] = $woocommerce->attribute_label(str_replace('attribute_', '', $name)).': '.$value; + else : + $variation_list[] = '
    '.$woocommerce->attribute_label(str_replace('attribute_', '', $name)).':
    '.$value.'
    '; + endif; + + endforeach; + + if ($flat) : + $return .= implode(', ', $variation_list); + else : + $return .= implode('', $variation_list); + endif; + + endif; + + // Other data - returned as array with name/value values + $other_data = apply_filters('woocommerce_get_item_data', array(), $cart_item); + + if ($other_data && is_array($other_data) && sizeof($other_data)>0) : + + $data_list = array(); + + foreach ($other_data as $data) : + + if ($flat) : + $data_list[] = $data['name'].': '.$data['value']; + else : + $data_list[] = '
    '.$data['name'].':
    '.$data['value'].'
    '; + endif; + + endforeach; + + if ($flat) : + $return .= implode(', ', $data_list); + else : + $return .= implode('', $data_list); + endif; + + endif; + + if (!$flat) $return .= '
    '; + + return $return; + + } + + /** + * Gets cross sells based on the items in the cart + * + * @return array cross_sells item ids of cross sells + */ + function get_cross_sells() { + $cross_sells = array(); + $in_cart = array(); + if (sizeof($this->cart_contents)>0) : foreach ($this->cart_contents as $cart_item_key => $values) : + if ($values['quantity']>0) : + $cross_sells = array_merge($values['data']->get_cross_sells(), $cross_sells); + $in_cart[] = $values['product_id']; + endif; + endforeach; endif; + $cross_sells = array_diff($cross_sells, $in_cart); + return $cross_sells; + } + + /** gets the url to the cart page */ + function get_cart_url() { + $cart_page_id = get_option('woocommerce_cart_page_id'); + if ($cart_page_id) return get_permalink($cart_page_id); + } + + /** gets the url to the checkout page */ + function get_checkout_url() { + $checkout_page_id = get_option('woocommerce_checkout_page_id'); + if ($checkout_page_id) : + if (is_ssl()) return str_replace('http:', 'https:', get_permalink($checkout_page_id)); + return get_permalink($checkout_page_id); + endif; + } + + /** gets the url to remove an item from the cart */ + function get_remove_url( $cart_item_key ) { + global $woocommerce; + $cart_page_id = get_option('woocommerce_cart_page_id'); + if ($cart_page_id) return $woocommerce->nonce_url( 'cart', add_query_arg('remove_item', $cart_item_key, get_permalink($cart_page_id))); + } + + /** + * Returns the contents of the cart + */ + function get_cart() { + return $this->cart_contents; + } + + /** + * gets the total (after calculation) + */ function get_total() { return woocommerce_price($this->total); } - /** gets the cart contens total (after calculation) */ + /** + * gets the cart contens total (after calculation) + */ function get_cart_total() { return woocommerce_price($this->cart_contents_total); } - /** gets the sub total (after calculation) */ + /** + * gets the sub total (after calculation) + */ function get_cart_subtotal() { global $woocommerce; if (get_option('woocommerce_display_totals_tax')=='excluding' || ( defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT )) : if (get_option('woocommerce_prices_include_tax')=='yes') : - $return = woocommerce_price($this->subtotal - $this->tax_total); - else : - $return = woocommerce_price($this->subtotal); - endif; if ($this->tax_total>0) : @@ -546,13 +715,9 @@ class woocommerce_cart { else : if (get_option('woocommerce_prices_include_tax')=='yes') : - $return = woocommerce_price($this->subtotal); - else : - $return = woocommerce_price($this->subtotal + $this->tax_total); - endif; if ($this->tax_total>0) : @@ -564,14 +729,18 @@ class woocommerce_cart { } - /** gets the cart tax (after calculation) */ + /** + * gets the cart tax (after calculation) + */ function get_cart_tax() { $cart_total_tax = $this->tax_total + $this->shipping_tax_total; if ($cart_total_tax > 0) return woocommerce_price( $cart_total_tax ); return false; } - /** gets the shipping total (after calculation) */ + /** + * gets the shipping total (after calculation) + */ function get_cart_shipping_total() { global $woocommerce; @@ -602,83 +771,29 @@ class woocommerce_cart { endif; } - /** gets title of the chosen shipping method */ + /** + * gets title of the chosen shipping method + */ function get_cart_shipping_title() { global $woocommerce; if (isset($woocommerce->shipping->shipping_label)) : return __('via', 'woothemes') . ' ' . $woocommerce->shipping->shipping_label; endif; return false; - } + } /** - * Applies a coupon code - * - * @param string code The code to apply - * @return bool True if the coupon is applied, false if it does not exist or cannot be applied + * gets the total discount amount */ - function add_discount( $coupon_code ) { - global $woocommerce; - - $the_coupon = &new woocommerce_coupon($coupon_code); - - if ($the_coupon->id) : - - // Check if applied - if ($woocommerce->cart->has_discount($coupon_code)) : - $woocommerce->add_error( __('Discount code already applied!', 'woothemes') ); - return false; - endif; - - // Check it can be used with cart - if (!$the_coupon->is_valid()) : - $woocommerce->add_error( __('Invalid coupon.', 'woothemes') ); - return false; - endif; - - // If its individual use then remove other coupons - if ($the_coupon->individual_use=='yes') : - $this->applied_coupons = array(); - endif; - - foreach ($this->applied_coupons as $code) : - $coupon = &new woocommerce_coupon($code); - if ($coupon->individual_use=='yes') : - $this->applied_coupons = array(); - endif; - endforeach; - - $this->applied_coupons[] = $coupon_code; - $this->set_session(); - $woocommerce->add_message( __('Discount code applied successfully.', 'woothemes') ); - return true; - - else : - $woocommerce->add_error( __('Coupon does not exist!', 'woothemes') ); - return false; - endif; - return false; - - } - - /** returns whether or not a discount has been applied */ - function has_discount( $code ) { - if (in_array($code, $this->applied_coupons)) return true; - return false; - } - - /** gets the total discount amount */ function get_total_discount() { if ($this->discount_total) return woocommerce_price($this->discount_total); else return false; } - /** clears the cart/coupon data and re-calcs totals */ - function clear_cache() { - $this->cart_contents = array(); - $this->applied_coupons = array(); - unset( $_SESSION['cart'] ); - unset( $_SESSION['coupons'] ); - $this->calculate_totals(); + /** + * gets the array of applied coupon codes + */ + function get_applied_coupons() { + return (array) $this->applied_coupons; } } \ No newline at end of file diff --git a/classes/checkout.class.php b/classes/checkout.class.php index 5d2f9fbe286..f4017092623 100644 --- a/classes/checkout.class.php +++ b/classes/checkout.class.php @@ -365,7 +365,7 @@ class woocommerce_checkout { $woocommerce->verify_nonce('process_checkout'); - if (sizeof($woocommerce->cart->cart_contents)==0) : + if (sizeof($woocommerce->cart->get_cart())==0) : $woocommerce->add_error( sprintf(__('Sorry, your session has expired. Return to homepage →', 'woothemes'), home_url()) ); endif; @@ -644,7 +644,7 @@ class woocommerce_checkout { // Cart items $order_items = array(); - foreach ($woocommerce->cart->cart_contents as $cart_item_key => $values) : + foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) : $_product = $values['data']; @@ -765,7 +765,7 @@ class woocommerce_checkout { wp_set_object_terms( $order_id, 'pending', 'shop_order_status' ); // Discount code meta - if ($woocommerce->cart->applied_coupons) update_post_meta($order_id, 'coupons', implode(', ', $woocommerce->cart->applied_coupons)); + if ($applied_coupons = $woocommerce->cart->get_applied_coupons()) update_post_meta($order_id, 'coupons', implode(', ', $applied_coupons)); // Order is saved do_action('woocommerce_checkout_order_processed', $order_id, $this->posted); diff --git a/classes/coupons.class.php b/classes/coupons.class.php index c9d44a736a4..ec0deb79c9f 100644 --- a/classes/coupons.class.php +++ b/classes/coupons.class.php @@ -65,7 +65,7 @@ class woocommerce_coupon { // Product ids if (sizeof( $this->product_ids )>0) : $valid = false; - if (sizeof($woocommerce->cart->cart_contents)>0) : foreach ($woocommerce->cart->cart_contents as $cart_item_key => $cart_item) : + if (sizeof($woocommerce->cart->get_cart())>0) : foreach ($woocommerce->cart->get_cart() as $cart_item_key => $cart_item) : if (in_array($cart_item['product_id'], $this->product_ids) || in_array($cart_item['variation_id'], $this->product_ids)) : $valid = true; endif; @@ -76,7 +76,7 @@ class woocommerce_coupon { // Exclude product ids if (sizeof( $this->exclude_product_ids )>0) : $valid = true; - if (sizeof($woocommerce->cart->cart_contents)>0) : foreach ($woocommerce->cart->cart_contents as $cart_item_key => $cart_item) : + if (sizeof($woocommerce->cart->get_cart())>0) : foreach ($woocommerce->cart->get_cart() as $cart_item_key => $cart_item) : if (in_array($cart_item['product_id'], $this->exclude_product_ids) || in_array($cart_item['variation_id'], $this->exclude_product_ids)) : $valid = false; endif; diff --git a/classes/product.class.php b/classes/product.class.php index 7ff7c6ff215..d02d4d5512a 100644 --- a/classes/product.class.php +++ b/classes/product.class.php @@ -439,6 +439,13 @@ class woocommerce_product { if ($this->weight) return $this->weight; } + /** Adjust a products price dynamically */ + function adjust_price( $price ) { + if ($price>0) : + $this->price += $price; + endif; + } + /** Returns the product's price */ function get_price() { return $this->price; diff --git a/classes/shipping/shipping-flat_rate.php b/classes/shipping/shipping-flat_rate.php index 30f0b6d07f8..b31a878f5b2 100644 --- a/classes/shipping/shipping-flat_rate.php +++ b/classes/shipping/shipping-flat_rate.php @@ -52,7 +52,7 @@ class flat_rate extends woocommerce_shipping_method { endif; else : // Shipping per item - if (sizeof($woocommerce->cart->cart_contents)>0) : foreach ($woocommerce->cart->cart_contents as $item_id => $values) : + if (sizeof($woocommerce->cart->get_cart())>0) : foreach ($woocommerce->cart->get_cart() as $item_id => $values) : $_product = $values['data']; if ($_product->exists() && $values['quantity']>0) : diff --git a/classes/tax.class.php b/classes/tax.class.php index 0f23d904079..6c349ac49a0 100644 --- a/classes/tax.class.php +++ b/classes/tax.class.php @@ -188,7 +188,7 @@ class woocommerce_tax { $found_shipping_rates = array(); // Loop cart and find the highest tax band - if (sizeof($woocommerce->cart->cart_contents)>0) : foreach ($woocommerce->cart->cart_contents as $item) : + if (sizeof($woocommerce->cart->get_cart())>0) : foreach ($woocommerce->cart->get_cart() as $item) : if ($item['data']->tax_class) : diff --git a/shortcodes/shortcode-cart.php b/shortcodes/shortcode-cart.php index d7feccb4505..a09c22ff2fa 100644 --- a/shortcodes/shortcode-cart.php +++ b/shortcodes/shortcode-cart.php @@ -69,7 +69,7 @@ function woocommerce_cart( $atts ) { $woocommerce->show_messages(); - if (sizeof($woocommerce->cart->cart_contents)==0) : + if (sizeof($woocommerce->cart->get_cart())==0) : echo '

    '.__('Your cart is currently empty.', 'woothemes').'

    '; do_action('woocommerce_cart_is_empty'); echo '

    '.__('← Return To Shop', 'woothemes').'

    '; @@ -91,8 +91,8 @@ function woocommerce_cart( $atts ) { cart->cart_contents)>0) : - foreach ($woocommerce->cart->cart_contents as $cart_item_key => $values) : + if (sizeof($woocommerce->cart->get_cart())>0) : + foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) : $_product = $values['data']; if ($_product->exists() && $values['quantity']>0) : diff --git a/shortcodes/shortcode-checkout.php b/shortcodes/shortcode-checkout.php index 54de6933ea5..a1e48ed1aac 100644 --- a/shortcodes/shortcode-checkout.php +++ b/shortcodes/shortcode-checkout.php @@ -19,7 +19,7 @@ function woocommerce_checkout( $atts ) { if (!defined('WOOCOMMERCE_CHECKOUT')) define('WOOCOMMERCE_CHECKOUT', true); - if (sizeof($woocommerce->cart->cart_contents)==0) : + if (sizeof($woocommerce->cart->get_cart())==0) : wp_redirect(get_permalink(get_option('woocommerce_cart_page_id'))); exit; endif; diff --git a/templates/checkout/review_order.php b/templates/checkout/review_order.php index 0e63044e695..b2ec3ca9d6b 100755 --- a/templates/checkout/review_order.php +++ b/templates/checkout/review_order.php @@ -77,8 +77,8 @@ cart->cart_contents)>0) : - foreach ($woocommerce->cart->cart_contents as $item_id => $values) : + if (sizeof($woocommerce->cart->get_cart())>0) : + foreach ($woocommerce->cart->get_cart() as $item_id => $values) : $_product = $values['data']; if ($_product->exists() && $values['quantity']>0) : echo ' diff --git a/widgets/widget-cart.php b/widgets/widget-cart.php index 2648129e0eb..af23a525970 100644 --- a/widgets/widget-cart.php +++ b/widgets/widget-cart.php @@ -46,7 +46,7 @@ class WooCommerce_Widget_Cart extends WP_Widget { if ( $title ) echo $before_title . $title . $after_title; echo '
      '; - if (sizeof($woocommerce->cart->cart_contents)>0) : foreach ($woocommerce->cart->cart_contents as $cart_item_key => $cart_item) : + if (sizeof($woocommerce->cart->get_cart())>0) : foreach ($woocommerce->cart->get_cart() as $cart_item_key => $cart_item) : $_product = $cart_item['data']; if ($_product->exists() && $cart_item['quantity']>0) : echo '
    • '; @@ -56,9 +56,7 @@ class WooCommerce_Widget_Cart extends WP_Widget { echo apply_filters('woocommerce_cart_widget_product_title', $_product->get_title(), $_product).''; - if($_product instanceof woocommerce_product_variation && is_array($cart_item['variation'])) : - echo woocommerce_get_formatted_variation( $cart_item['variation'] ); - endif; + echo $woocommerce->cart->get_item_data( $cart_item ); echo '' .$cart_item['quantity'].' × '.woocommerce_price($_product->get_price()).'
    • '; endif; @@ -66,7 +64,7 @@ class WooCommerce_Widget_Cart extends WP_Widget { else: echo '
    • '.__('No products in the cart.', 'woothemes').'
    • '; endif; echo '
    '; - if (sizeof($woocommerce->cart->cart_contents)>0) : + if (sizeof($woocommerce->cart->get_cart())>0) : echo '

    '; if (get_option('js_prices_include_tax')=='yes') : diff --git a/woocommerce_actions.php b/woocommerce_actions.php index 1faf3c75ec4..5768c85d3cd 100644 --- a/woocommerce_actions.php +++ b/woocommerce_actions.php @@ -70,7 +70,7 @@ function woocommerce_ajax_update_order_review() { if (!defined('WOOCOMMERCE_CHECKOUT')) define('WOOCOMMERCE_CHECKOUT', true); - if (sizeof($woocommerce->cart->cart_contents)==0) : + if (sizeof($woocommerce->cart->get_cart())==0) : echo '

    '.__('Sorry, your session has expired.', 'woothemes').' '.__('Return to homepage →', 'woothemes').'

    '; die(); endif; @@ -130,7 +130,7 @@ add_action('woocommerce_new_order', 'woocommerce_increase_coupon_counts'); function woocommerce_increase_coupon_counts() { global $woocommerce; - if ($woocommerce->cart->applied_coupons) foreach ($woocommerce->cart->applied_coupons as $code) : + if ($applied_coupons = $woocommerce->cart->get_applied_coupons()) foreach ($applied_coupons as $code) : $coupon = &new woocommerce_coupon( $code ); $coupon->inc_usage_count(); endforeach; @@ -361,7 +361,7 @@ function woocommerce_update_cart_action() { global $woocommerce; // Remove from cart - if ( isset($_GET['remove_item']) && is_numeric($_GET['remove_item']) && $woocommerce->verify_nonce('cart', '_GET')) : + if ( isset($_GET['remove_item']) && $_GET['remove_item'] && $woocommerce->verify_nonce('cart', '_GET')) : $woocommerce->cart->set_quantity( $_GET['remove_item'], 0 ); @@ -377,8 +377,8 @@ function woocommerce_update_cart_action() { $cart_totals = $_POST['cart']; - if (sizeof($woocommerce->cart->cart_contents)>0) : - foreach ($woocommerce->cart->cart_contents as $cart_item_key => $values) : + if (sizeof($woocommerce->cart->get_cart())>0) : + foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) : if (isset($cart_totals[$cart_item_key]['qty'])) $woocommerce->cart->set_quantity( $cart_item_key, $cart_totals[$cart_item_key]['qty'] ); @@ -457,7 +457,7 @@ function woocommerce_add_to_cart_action( $url = false ) { if ($all_variations_set && $variation_id > 0) : // Add to cart - if ($woocommerce->cart->add_to_cart($product_id, $quantity, $variations, $variation_id)) : + if ($woocommerce->cart->add_to_cart($product_id, $quantity, $variation_id, $variations)) : if (get_option('woocommerce_cart_redirect_after_add')=='yes') : $woocommerce->add_message( __('Product successfully added to your cart.', 'woothemes') ); diff --git a/woocommerce_template_functions.php b/woocommerce_template_functions.php index 24faf01bd2f..0109f49da94 100644 --- a/woocommerce_template_functions.php +++ b/woocommerce_template_functions.php @@ -282,16 +282,24 @@ if (!function_exists('woocommerce_simple_add_to_cart')) { // Don't show cart if out of stock if (!$_product->is_in_stock()) return; - ?> + ?> + +
    + + is_virtual()) : ?>
    - + - + + +
    + + + +
    @@ -317,9 +327,16 @@ if (!function_exists('woocommerce_grouped_add_to_cart')) {
    + + + - + + +
    + + var product_variations = ; + +
    @@ -402,6 +421,9 @@ if (!function_exists('woocommerce_variable_add_to_cart')) {
    + + +
    - + + +
    + +