%PDF-1.7 GIF89;
Server IP : 5.161.254.237 / Your IP : 216.73.216.30 Web Server : Apache System : Linux diamond.sialwebvps.com 4.18.0-553.8.1.el8_10.x86_64 #1 SMP Tue Jul 2 07:26:33 EDT 2024 x86_64 User : stellasp ( 1131) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /home/stellasp/public_html/application/libraries/ |
Upload File : |
<?php /* * Gocart Cart Library * Based on cart.php included with Codeigniter */ /* * Coupon Support * This cart accepts coupons, Two main types: - Whole order discount - Individual product discounts Discount Types: - percent of price - fixed discount Usage Restrictions (optional): - Number of uses - Product instance limit (ex. applying to up to x number of products per use) - Date range, expiration - Only one coupon can be applied to a prodct. No Doubling, etc. Coupon Discount Logic: - Validate usage limitation and expiration - Apply only one coupon to each individual item (up to the instance limit for each item) - Adhere to coupon instance restrictions by applying discount to x number of items - Maximize the savings for the customer by applying the best discount possible */ class go_cart { var $CI; // Cart properties and items will go in here // Modified from the original cart lib as follows: // _cart_contents[ (cart property indexes) ] = (property value) // _cart_contents[items] = (shopping cart products list) // This has to be in a single variable for easy session storage var $_cart_contents = array(); var $gift_cards_enabled = false; function __construct() { $this->CI =& get_instance(); $this->CI->load->model(array('Coupon_model' , 'Gift_card_model', 'Settings_model', 'Digital_Product_model')); // Load the saved session if ($this->CI->session->userdata('cart_contents') !== FALSE) { $this->_cart_contents = $this->CI->session->userdata('cart_contents'); } else { // Or init a new session $this->_init_properties(); } $gc_setting = $this->CI->Settings_model->get_settings('gift_cards'); if(@$gc_setting['enabled']==1) { $this->gift_cards_enabled = true; } //die(var_dump($this->_cart_contents)); } private function _init_properties($totals_only=false, $preserve_customer=false) { // shipping data $this->_cart_contents['order_insurable_value'] = 0; $this->_cart_contents['order_weight'] = 0; // This is the discount amount to subtract from the cart total when the order is finalized $this->_cart_contents['group_discount'] = 0; $this->_cart_contents['coupon_discount'] = 0; $this->_cart_contents['taxable_coupon_discount'] = 0; $this->_cart_contents['gift_card_balance'] = 0; $this->_cart_contents['gift_card_discount'] = 0; $this->_cart_contents['downloads'] = array(); // totals $this->_cart_contents['cart_subtotal'] = 0; $this->_cart_contents['cp_discounted_subtotal'] = 0; $this->_cart_contents['taxable_total'] = 0; // omits the price of digital products $this->_cart_contents['cart_total'] = 0; $this->_cart_contents['total_items'] = 0; $this->_cart_contents['total_quantities'] = 0; $this->_cart_contents['shipping_total'] = 0; // tax $this->_cart_contents['tax'] = 0; // We want to preserve the cart items and properties, but reset total values when recalculating if( ! $totals_only) { // product items will live in here $this->_cart_contents['items'] = array(); if(!$preserve_customer) { // customer data container $this->_cart_contents['customer'] = false; } // custom charges $this->_cart_contents['custom_charges'] = array(); // shipping details container $this->_cart_contents['shipping']['method'] = "No Shipping"; // defaults $this->_cart_contents['shipping']['price'] = 0.00; // This is the list of gift cards that are attached to the cart // to be applied toward a price reduction // (not to be confused with a gift card purchase) $this->_cart_contents['gc_list'] = array(); // This is the "pool" of coupons that the customer has entered // - products added after a coupon is attached to the cart will be factored into the discount logic // - not all coupons in the pool will be applied to a discount for the customer // - those that are not applied are ignored $this->_cart_contents['coupon_list'] = array(); // This is the list of coupons will be applied toward a price discount // we need to keep track of these so their usage can be updated once the order is confirmed to conform with usage limitations $this->_cart_contents['applied_coupons'] = array(); // Container for possible whole order level discount formulas // whole order coupons will be tracked and counted by indexing this array with the coupon code $this->_cart_contents['whole_order_discounts'] = array(); // If free shipping coupons are configured, we have to track and count which one is used $this->_cart_contents['free_shipping_coupon'] = false; // This is a flag to determine if we need to charge for shipping // Stays false if all products are non-shippable (downloads) $this->_cart_contents['requires_shipping'] = false; // Container for payment details $this->_cart_contents['payment'] = array(); } } /******************************************************* * * Private Methods * ********************************************************/ private function _insert($item) { // Was any cart data passed? No? Bah... if ( ! is_array($item) OR count($item) == 0) { return FALSE; } $cartkey = false; //is there an existing key? if(!empty($item['cartkey'])) { $cartkey = $item['cartkey']; } // now remove it whether or not it was empty unset($item['cartkey']); //record the quantity //$quantity = ($item['fixed_quantity']==0) ? $item['quantity'] : 1; $quantity = $item['quantity']; //remove quantity from the row ID hash this will enable us to add //the same item twice without having it appear twice due to quantity differences unset($item['quantity']); // Generate our row ID by the entire item array $newkey = md5(serialize($item)); //add quantity back in and we ceil it just in case someone is being silly submitting a decimal $item['quantity'] = ceil($quantity); //Add the Item Quantity to the Total $this->_cart_contents['total_quantities'] = $this->_cart_contents['total_quantities'] + $item['quantity']; //check to see if the item already exists in the cart //if it does, add the new quantity to the existing quantity //if it does not, add it as a new item //gotta do this differently to make sure the items stay in the same order if($cartkey) { $new_list = array(); foreach($this->_cart_contents['items'] as $key=>$i) { if($key == $cartkey) { //remove the old cart key (this is needed in order to fix coupons) $this->_remove($key); // replace the old item with the new item $new_list[$newkey] = $item; } else { $new_list[$key] = $i; } } $this->_cart_contents['items'] = $new_list; } else { //this is for non-edited products (except for quantity) if(isset($this->_cart_contents['items'][$newkey])) { $this->_cart_contents['items'][$newkey]['quantity'] = $this->_cart_contents['items'][$newkey]['quantity'] + 1; //make sure that fixed quantity items remain fixed quantity //if(!(bool)$item['fixed_quantity']) //{ //$this->_cart_contents['items'][$newkey]['quantity'] = $this->_cart_contents['items'][$newkey]['quantity'] + $item['quantity']; //} } else { // add our item to the items list $this->_cart_contents['items'][$newkey] = $item; } } // Run the product through the coupons list to check if there is a coupon which applies to it // cart contents item details and coupon data are automatically updated $this->_check_product_for_discount($newkey); // Woot! return TRUE; } private function _remove($cartkey) { if(!isset($this->_cart_contents['items'][$cartkey])) return false; // kill coupon association if(isset($this->_cart_contents['items'][$cartkey]['coupon_code'])) { unset($this->_cart_contents['applied_coupons'][$this->_cart_contents['items'][$cartkey]['coupon_code']][$cartkey]); // if there are no other discount lists for this coupon, remove it from the applied list altogether if(empty($this->_cart_contents['applied_coupons'][$this->_cart_contents['items'][$cartkey]['coupon_code']])) { unset($this->_cart_contents['applied_coupons'][$this->_cart_contents['items'][$cartkey]['coupon_code']]); } } //Update the Total Quantities $this->_cart_contents['total_quantities'] = $this->_cart_contents['total_quantities'] - $this->_cart_contents['items'][$cartkey]['quantity']; // Remove the item from our items list unset($this->_cart_contents['items'][$cartkey]); return true; } private function _update($cartkey, $quantity) { if(!isset($this->_cart_contents['items'][$cartkey])) { return false; } // Update the Total Quantity $quantitybeforeupdate = $this->_cart_contents['items'][$cartkey]['quantity']; // update cart, fixed quantity items restricted to 1 if($this->_cart_contents['items'][$cartkey]['fixed_quantity']==0) { $this->_cart_contents['items'][$cartkey]['quantity'] = ceil($quantity); } else { $this->_cart_contents['items'][$cartkey]['quantity'] = 1; } $this->_cart_contents['total_quantities'] = $this->_cart_contents['total_quantities'] + $this->_cart_contents['items'][$cartkey]['quantity'] - $quantitybeforeupdate; // Update associated coupon discount data if(isset($this->_cart_contents['items'][$cartkey]['coupon_code'])) { // see _apply_coupon_to_product method for explanation of what this array list is for $this->_cart_contents['applied_coupons'][$this->_cart_contents['items'][$cartkey]['coupon_code']][$cartkey] = array(); for($x=0;$x<$quantity;$x++) { $this->_cart_contents['applied_coupons'][$this->_cart_contents['items'][$cartkey]['coupon_code']][$cartkey][] = $this->_cart_contents['items'][$cartkey]['coupon_discount']; } } return true; } // This method is for applying existing coupons to NEW products private function _check_product_for_discount($cartkey) { // Loop through our coupon pool to see if any apply to the newly added product foreach($this->_cart_contents['coupon_list'] as $code=>$contents) { // does the current coupon apply to the product we are adding? if(in_array($this->_cart_contents['items'][$cartkey]['id'], $contents['product_list'])) { // try to apply the coupon $this->_apply_coupon_to_product($cartkey, $code); } } } // Applies a coupon to a product and calculates the discount amount private function _apply_coupon_to_product($cartkey, $coupon_code) { // calculate discount amount $price = (float) $this->_cart_contents['items'][$cartkey]['price']; if($this->_cart_contents['coupon_list'][$coupon_code]['reduction_type']=="percent") { //make sure we're removing the right percentage // $reduction_amount = 100 - $coupon['reduction_amount']; // $str = ' - ($subtotal * ('. $reduction_ammount .' /100))'; $reduction_amount = 100 - (float) $this->_cart_contents['coupon_list'][$coupon_code]['reduction_amount']; $discount = ($price * ($reduction_amount/100)); $discount_amount = abs($price-$discount); } else { $discount_amount = (float) $this->_cart_contents['coupon_list'][$coupon_code]['reduction_amount']; // Prevent fixed discounts from resulting a negative discount amount if($discount_amount > $this->_cart_contents['items'][$cartkey]['price']) { $discount_amount = $this->_cart_contents['items'][$cartkey]['price']; } } // Check for existing discount if(isset($this->_cart_contents['items'][$cartkey]['coupon_discount'] )) { // is the new discount a better deal? otherwise leave it as it is if($this->_cart_contents['items'][$cartkey]['coupon_discount'] < $discount_amount) { $old_code = $this->_cart_contents['items'][$cartkey]['coupon_code']; // replace previous value $this->_cart_contents['items'][$cartkey]['coupon_discount'] = $discount_amount; $this->_cart_contents['items'][$cartkey]['coupon_code'] = $coupon_code; // Un-apply the previously applied coupon by removing the old code placeholder from the cart item array unset($this->_cart_contents['applied_coupons'][$old_code][$cartkey]); // if there are no other discount lists for this coupon, remove it from the applied list altogether if(empty($this->_cart_contents['applied_coupons'][$old_code])) { unset($this->_cart_contents['applied_coupons'][$old_code]); } return true; } } else { // If no existing discount, just set it $this->_cart_contents['items'][$cartkey]['coupon_discount'] = $discount_amount; $this->_cart_contents['items'][$cartkey]['coupon_code'] = $coupon_code; // Construct a list containing product discount amounts resulting from all applied coupons // We have to index this by the cartkey, so it can be updated when the quantity is changed, sorted to siphon the biggest discounts, // conforming to instance limitation by only adding x number of item discounts to the final discount total // To start, it needs to look like: // applied_coupons[ coupon code index ][ product key index] = array list of discounts,repeated to product quantity for($x=0;$x<$this->_cart_contents['items'][$cartkey]['quantity'];$x++) { $this->_cart_contents['applied_coupons'][$coupon_code][$cartkey][] = $discount_amount; } return true; } return false; } private function _insert_coupon($coupon_code) { if(!$coupon_code) return false; $coupon = $this->CI->Coupon_model->get_coupon_by_code($coupon_code); // Is the code valid? if($coupon) { // Make sure they can't submit the same coupon more than once if(!isset($this->_cart_contents['coupon_list'][$coupon_code])) { $is_applied = false; // check validity if($this->CI->Coupon_model->is_valid($coupon)) { // add code to the coupon pool $this->_cart_contents['coupon_list'][$coupon_code] = $coupon; // apply coupon discount for free shipping, whole order discount, or product level if ($coupon['reduction_target'] =="shipping") { //$this->_cart_contents['requires_shipping'] = false; // Remember what code was used for free shipping $this->_cart_contents['free_shipping_coupon'] = $coupon_code; $is_applied = true; // is the coupon a whole-order discount coupon? } else if($coupon['whole_order_coupon']=="1") { // save a discount formula to be evaluated later // when determining the total order discount if($coupon['reduction_type'] == "fixed") { $str = $coupon['reduction_amount']; } else { //we need to swap percentages //ex 20% discount needs to return an 80% price $reduction_ammount = 100 - $coupon['reduction_amount']; $str = ' - ($subtotal * ('. $reduction_ammount .' /100))'; } $is_applied = true; // We want to keep an array, in case they have more than a single whole-order discount coupon // but we will only apply the one which yields the best discount $this->_cart_contents['whole_order_discounts'][$coupon_code] = $str; } else // Otherwise, this is a product level discount { // loop through our items and see if any of them can be discounted by this coupon foreach($this->_cart_contents['items'] as $key=>$item) { if(in_array($item['id'], $coupon['product_list'])) { // try to apply this coupon to the product if($this->_apply_coupon_to_product($key, $coupon['code'])) $is_applied = true; } } } if(!$is_applied) { // message coupon added but not applied return array('message'=>lang('coupon_not_apply')); } else { // message coupon applied return array('message'=>lang('coupon_applied')); } } else { // message coupon no longer valid return array('error'=>lang('coupon_invalid')); } } else { // message coupon already applied return array('error'=>lang('coupon_already_applied')); } } else { // invalid code error message return array('error'=>lang('invalid_coupon_code')); } } // Calculate the best possible discount within the product instance limitations for the whole cart // return the discount amount private function _calculate_coupon_discount() { $total_discount = 0; //keep tabs on how much is taxable $taxable_discount = 0; // Get the sum of the product-level coupons if( ! empty($this->_cart_contents['applied_coupons'])) { foreach($this->_cart_contents['applied_coupons'] as $code=>$discount_list) { // The discount list is an array of arrays, indexed by cart key // we need to prep this list for a final discount aggregation // by collapsing this into a singular array of all product discounts // from which we will calculate the total discount per coupon $collapsed = array(); $product_index = array(); $x = 0; // we will use this to cross-index what discounts belong to what product // so that we can separate taxable from non-taxable amounts foreach($discount_list as $key=>$item) { foreach($item as $discount) { $collapsed[$x] = $discount; $product_index[$x] = $key; $x++; } // because each product can only have one coupon associated // we can prep a total discount here for each item for later dealing with the amounts individually $this->_cart_contents['items'][$key]['total_coupon_discount'] = 0; } // sort the list, highest discount amounts on top rsort($collapsed); // either no limit or the limit is greater than the size of the list if($this->_cart_contents['coupon_list'][$code]['max_product_instances'] == 0 || count($collapsed)<=$this->_cart_contents['coupon_list'][$code]['max_product_instances']) { $maximum = count($collapsed); } else { $maximum = $this->_cart_contents['coupon_list'][$code]['max_product_instances']; } // Only calculate to the limit of instances for this coupon for($x=0;$x<$maximum;$x++) { $total_discount += $collapsed[$x]; // store the total discount in the item details, for future reference $this->_cart_contents['items'][$product_index[$x]]['total_coupon_discount'] += $collapsed[$x]; // taxable? if( $this->_cart_contents['items'][$product_index[$x]]['shippable'] == 1 ) { $taxable_discount += $collapsed[$x]; } } } } // Calculate whole order discount // If a customer has more than one whole order coupon and enters them, // we only want to use the one that results in the best discount (no doubling, etc) if(!empty($this->_cart_contents['whole_order_discounts'])) { $subtotal = $this->_cart_contents['cart_subtotal']; $temp = 0; foreach($this->_cart_contents['whole_order_discounts'] as $code=>$disc) { if(is_numeric($disc)) { $discount_amount = $disc; } else { eval('$discount_amount=$subtotal'.$disc.';'); } if($discount_amount > $temp) { $temp = $discount_amount; $this->_cart_contents['whole_order_discount_cp'] = $code; // track which code we use } } $total_discount = $temp; } $this->_cart_contents['cp_discounted_subtotal'] = $this->_cart_contents['cart_subtotal'] - $total_discount; $this->_cart_contents['coupon_discount'] = $total_discount; // this is the portion of the discount that applies to a taxable amount $this->_cart_contents['taxable_coupon_discount'] = $taxable_discount; } // Attach a Gift Card discount to the order private function _attach_gift_card($gc_code) { // enabled? if( ! $this->gift_cards_enabled) return; if ($gc_code) { if ( ! isset($this->_cart_contents['gc_list'][$gc_code]) ) { $gift_card = $this->CI->Gift_card_model->get_gift_card($gc_code); if($gift_card) { // valid code? if($this->CI->Gift_card_model->is_valid($gift_card)) { // Add to the cart list $this->_cart_contents['gc_list'][$gc_code]['balance'] = $this->CI->Gift_card_model->get_balance($gift_card); // update balance of all gift cards attached $this->_cart_contents['gift_card_balance'] += $this->_cart_contents['gc_list'][$gc_code]['balance']; // message coupon applied return array('message'=>lang('giftcard_balance_displayed')); } else { // invalid card (expired or zero balance) return array('error'=>lang('giftcard_zero_balance')); } } else { // invalid card code return array('error'=>lang('giftcard_not_exist')); } } else { // already applied return array('message'=>lang('giftcard_already_applied')); } } } private function _calculate_gift_card_discount() { // no cards are set in the cart if(empty($this->_cart_contents['gc_list'])) return; // calculate what will be taken from the card(s) foreach($this->_cart_contents['gc_list'] as &$card) { // If the card balance has more than enough to cover the total if($card['balance'] >= $this->_cart_contents['cart_total']) // cart total should be calculated already { // we don't want to change the card balance in the cart yet, so we just keep track of how much is taken from each one $card['amt_used'] = $this->_cart_contents['cart_total']; //for later tracking $this->_cart_contents['gift_card_discount'] = $this->_cart_contents['cart_total']; $this->_cart_contents['cart_total'] = 0; $this->_cart_contents['gift_card_balance'] += $card['balance'] - $card['amt_used']; // adds to a cart total balance (for all gc) // set payment placeholders, we will be skipping that in the checkout $this->_cart_contents['payment']['method'] = "Gift Card"; $this->_cart_contents['payment']['description'] = "Paid by Gift Card"; return; // complete discount acheived (total=0), stop procesing // Otherwise, discount up to the card balance } else { $card['amt_used'] = $card['balance']; $this->_cart_contents['gift_card_discount'] += $card['balance']; $this->_cart_contents['cart_total'] -= $card['balance']; } } } /** * Get Item * * Returns a specific item if it's there, otherwise returns false * * @access public * @return array */ function item($key) { if(!empty($this->_cart_contents['items'][$key])) { return $this->_cart_contents['items'][$key]; } else { return false; } } /** * Save the cart array to the session DB * * @access private * @return bool */ private function _save_cart($recalculate=true) { // Once in the check-out stage, we no longer need to keep recalculating totals // taxes and shipping will be added in later if($recalculate) { // Reset totals $this->_init_properties(true); // Lets add up the individual prices and set the cart sub-total $total = 0; $taxable = 0; $coupon_total = 0; $this->_cart_contents['requires_shipping'] = false; // Go back to default and redetermine if there is anything shippable foreach ($this->_cart_contents['items'] as $key => &$val) { // Apply any group discount if(isset($this->_cart_contents['customer']['group_discount_formula'])) { // calculate the discount amount eval('$this_price=$val["price"]'. $this->_cart_contents['customer']['group_discount_formula'] .';'); // add to the total group discount $this->_cart_contents['group_discount'] += ($val['price'] - $this_price) * $val['quantity']; } else { // or use the regular price $this_price = $val['price']; } // Deal with shippable if ( $val['shippable']== 1 ) { // shipping insurable value & weight $this->_cart_contents['order_insurable_value'] += $this_price; //$this->_cart_contents['order_weight'] += $val['weight']*$val['quantity']; $this->_cart_contents['order_weight'] += $val['quantity']; $this->_cart_contents['requires_shipping'] = true; } // charge tax? if($val['taxable'] == 1) { $taxable += ($this_price * $val['quantity']); } $total += ($this_price * $val['quantity']); // set product subtotal (NOT accounting for coupon discount yet) $val['subtotal'] = ($this_price * $val['quantity']); // Calculate the Total Quantities $this->_cart_contents['total_quantities'] += $val['quantity']; } // total products in the cart $this->_cart_contents['total_items'] = count($this->_cart_contents['items']); // Set the cart price totals ... $this->_cart_contents['cart_subtotal'] = $total; // Calculate / set total coupon discount amounts $this->_calculate_coupon_discount(); // set taxable subtotal $this->_cart_contents['taxable_total'] = $taxable - $this->_cart_contents['taxable_coupon_discount']; $this->_cart_contents['cart_total'] = $total - $this->_cart_contents['coupon_discount']; // $this->_cart_contents['group_discount']; // add any additional custom charges if(!empty($this->_cart_contents['custom_charges'])) { foreach($this->_cart_contents['custom_charges'] as $c) { $this->_cart_contents['cart_total'] += $c; } } // Compute taxes BEFORE shipping costs are added in? if(! $this->CI->config->item('tax_shipping')) { $this->_compute_tax(); } // Shipping costs if($this->_cart_contents['requires_shipping']) { $this->_cart_contents['cart_total'] += $this->_cart_contents['shipping']['price']; } else { // placeholders $this->_cart_contents['shipping']['method'] = "No Shipping"; $this->_cart_contents['shipping']['price'] = 0.00; } // Compute taxes AFTER shipping costs are added in ? if($this->CI->config->item('tax_shipping')) { $this->_compute_tax(); } // finally $this->_cart_contents['cart_total'] += $this->_cart_contents['tax']; // set any gift card reduction // updates totals accordingly if($this->gift_cards_enabled) { $this->_calculate_gift_card_discount(); } } // Save up $this->CI->session->set_userdata(array('cart_contents' => $this->_cart_contents)); // Woot! return TRUE; } private function _compute_tax() { $this->CI->load->model('Tax_model'); $this->_cart_contents['tax'] = $this->CI->Tax_model->get_tax_total(); } /******************************************************* * * Public Methods * ********************************************************/ /** * Double check that each item has enough in stock from the database * * @access public * @return bool */ function check_inventory() { $contents = $this->contents(); //this array merges any products that share the same product id $new_contents = array(); foreach($contents as $c) { // skip gift card products if($c['is_gc']) { continue; } //combine any product id's and tabulate their quantities if(array_key_exists($c['id'], $new_contents)) { $new_contents[$c['id']] = intval($new_contents[$c['id']])+intval($c['quantity']); } else { $new_contents[$c['id']] = $c['quantity']; } } $error = ''; $this->CI->load->model('Product_model'); foreach($new_contents as $product_id => $quantity) { $product = $this->CI->Product_model->get_product($product_id); //make sure we're tracking stock for this product if((bool)$product->track_stock) { if(intval($quantity) > intval($product->quantity)) { $error .= '<p>'.sprintf(lang('not_enough_stock'), $product->name, $product->quantity).'</p>'; } } } if(!empty($error)) { return $error; } else { return false; } } /** * Insert items into the cart and save it to the session table * * @access public * @param array * @return bool */ function insert($items = array()) { // Was any cart data passed? No? Bah... if ( ! is_array($items) OR count($items) == 0) { return FALSE; } // You can either insert a single product using a one-dimensional array, // or multiple products using a multi-dimensional one. The way we // determine the array type is by looking for a required array key named "id" // at the top level. If it's not found, we will assume it's a multi-dimensional array. $save_cart = FALSE; if (isset($items['id'])) { if ($this->_insert($items) == TRUE) { $save_cart = TRUE; } } else { foreach ($items as $val) { if (is_array($val) AND isset($val['id'])) { if ($this->_insert($val) == TRUE) { $save_cart = TRUE; } } } } // Save the cart data if the insert was successful if ($save_cart == TRUE) { $this->_save_cart(); return TRUE; } return FALSE; } function update_cart($qty_list=false, $coupon_code=false, $gc_code=false) { // We might not need to save the cart, if nothing changes $save_cart = false; $response = false; $error = ''; $message = ''; // insert any coupons that might be sent if($coupon_code) { $cp_status = $this->_insert_coupon($coupon_code); if(isset($cp_status['message'])) $save_cart = true; // collect message if(isset($cp_status['error'])) $error .= '<p>'. $cp_status['error'].'</p>'; if(isset($cp_status['message'])) $message .= '<p>'.$cp_status['message'].'</p>'; $response = true; } // attach any gift cards if($gc_code) { $gc_status = $this->_attach_gift_card($gc_code); if(isset($gc_status['message'])) $save_cart = true; // collect message if(isset($gc_status['error'])) $error .= '<p>'. $gc_status['error'].'</p>'; if(isset($gc_status['message'])) $message .= '<p>'.$gc_status['message'].'</p>'; $response = true; } // this message stuff could be cleaned up if($response) { $response = array(); $response['error'] = $error; $response['message'] = $message; } if($qty_list) { foreach($qty_list as $item_key=>$qty) { if(!is_numeric($qty)) continue; // ignore if there's garble in it //have to run an isset here due to an error in IE (presumeably due to self signed certificate error double loading) if(isset($this->_cart_contents['items'][$item_key]) && $this->_cart_contents['items'][$item_key]['quantity'] != $qty) { if((int)$qty>0) { // don't update the quantity of no_quantity items if(!isset($this->_cart_contents['items'][$item_key]['no_quantity'])) $this->_update($item_key, $qty); } else { $this->_remove($item_key); } $save_cart = true; } } } if($save_cart) { $this->_save_cart(); } return $response; } // save / get order download list function save_order_downloads($list) { $this->_cart_contents['downloads'] = $list; } function get_order_downloads() { return $this->_cart_contents['downloads']; } //save additional settings function set_additional_details($data) { $this->_cart_contents['additional_details'] = $data; $this->_save_cart(false); } function additional_details() { if(isset($this->_cart_contents['additional_details'])) { return $this->_cart_contents['additional_details']; } else { //return the array blank return array('referral'=>'' ,'shipping_notes'=>'' ); } } // set shipping details function set_shipping($method, $price) { if(!is_numeric($price)) return false; $this->_cart_contents['shipping'] = array('method'=>$method, 'price'=> (float) $price); //update cart - recalculate $this->_save_cart(); } //remove shipping details function clear_shipping() { $this->_cart_contents['shipping']['method'] = "No Shipping"; // defaults $this->_cart_contents['shipping']['price'] = 0.00; $this->_save_cart(); } function set_payment($module, $description) { $this->_cart_contents['payment'] = array('module'=>$module, 'description'=>$description); // save cart - no recalculation necessary $this->_save_cart(false); } // Use this to establish that a payment has been made (this is mostly for paypal) function set_payment_confirmed() { $this->_cart_contents['payment']['confirmed'] = true; // save cart - no recalculation necessary $this->_save_cart(false); } // This saves the confirmed order function save_order() { $this->CI->load->model('order_model'); $this->CI->load->model('Product_model'); //prepare our data for being inserted into the database $save = array(); // Is this a non shippable order? $none_shippable = true; foreach ($this->_cart_contents['items'] as $item) { if($item['shippable']==1) { $none_shippable = false; } } //default status comes from the config file if($none_shippable) { $save['status'] = $this->CI->config->item('nonship_status'); } else { $save['status'] = $this->CI->config->item('order_status'); } //if the id exists, then add it to the array $save array and remove it from the customer if(isset($this->_cart_contents['customer']['id']) && $this->_cart_contents['customer']['id'] != '') { $save['customer_id'] = $this->_cart_contents['customer']['id']; } $customer = $this->_cart_contents['customer']; $ship = $customer['ship_address']; $bill = $customer['bill_address']; $save['company'] = $customer['company']; $save['firstname'] = $customer['firstname']; $save['lastname'] = $customer['lastname']; $save['phone'] = $customer['phone']; $save['email'] = $customer['email']; $save['ship_company'] = $ship['company']; $save['ship_firstname'] = $ship['firstname']; $save['ship_lastname'] = $ship['lastname']; $save['ship_email'] = $ship['email']; $save['ship_phone'] = $ship['phone']; $save['ship_address1'] = $ship['address1']; $save['ship_address2'] = $ship['address2']; $save['ship_city'] = $ship['city']; $save['ship_zip'] = $ship['zip']; $save['ship_zone'] = 0;//$ship['zone']; $save['ship_zone_id'] = $ship['zone_id']; $save['ship_country'] = $ship['country']; $save['ship_country_id'] = $ship['country_id']; $save['bill_company'] = $bill['company']; $save['bill_firstname'] = $bill['firstname']; $save['bill_lastname'] = $bill['lastname']; $save['bill_email'] = $bill['email']; $save['bill_phone'] = $bill['phone']; $save['bill_address1'] = $bill['address1']; $save['bill_address2'] = $bill['address2']; $save['bill_city'] = $bill['city']; $save['bill_zip'] = $bill['zip']; $save['bill_zone'] = 0;//$bill['zone']; $save['bill_zone_id'] = $bill['zone_id']; $save['bill_country'] = $bill['country']; $save['bill_country_id'] = $bill['country_id']; //shipping information $save['shipping_method'] = $this->_cart_contents['shipping']['method']; $save['shipping'] = $this->_cart_contents['shipping']['price']; //I will add a shipping notes feature later //$data['shipping_notes'] = $this->_cart_contents['shipping_notes']; //add in the other charges $save['tax'] = $this->_cart_contents['tax']; //discounts $save['gift_card_discount'] = $this->_cart_contents['gift_card_discount']; $save['coupon_discount'] = $this->_cart_contents['coupon_discount']; $save['subtotal'] = $this->_cart_contents['cart_subtotal']; $save['total'] = $this->_cart_contents['cart_total']; $save['total_items'] = $this->_cart_contents['total_items']; $save['total_quantities'] = $this->_cart_contents['total_quantities']; //store the payment info //it's up to the payment method to remove any sensitive data from the array before this time if(!empty($this->_cart_contents['payment']['description'])) { $save['payment_info'] = $this->_cart_contents['payment']['description']; } else { //also set the description to '' so we don't get errors anywhere else. //we may want to review this later and see if there is a better way from having it even come to this. $this->_cart_contents['payment']['description'] = ''; $save['payment_info'] = ''; } //save additional details $details = $this->additional_details(); $save['referral'] = $details['referral']; $save['shipping_notes'] = $details['shipping_notes']; //ordered_on datetime stamp $save['ordered_on'] = date('Y-m-d H:i:s'); //contents this is the content section serialized //later on if we want to add out of stock counting here is where we will //decrement our stock $contents = array(); foreach ($this->_cart_contents['items'] as $item) { $contents[] = serialize($item); } // save the order content $order_id = $this->CI->order_model->save_order($save, $contents); // dont do anything else if the order failed to save if(!$order_id) return false; // Process any per-item operations foreach ($this->_cart_contents['items'] as $item) { // Process Gift Card purchase if($this->gift_cards_enabled && isset($item['gc_info'])) { $gc_data = array(); $gc_data['order_number'] = $order_id; $gc_data['beginning_amount'] = $item['price']; $gc_data['code'] = $item['code']; $gc_data= array_merge($gc_data, $item['gc_info']); $this->CI->Gift_card_model->save_card($gc_data); //send the recipient a message $this->CI->Gift_card_model->send_notification($gc_data); } // Process Downloadable Product $download_package = array(); if(!empty($item['file_list'])) { // compile a list of all the items that can be downloaded for this order $download_package[] = $item['file_list']; } if(!empty($download_package)) { // create the record, send the email $this->CI->Digital_Product_model->add_download_package($download_package, $order_id); } //deduct any quantities from the database if(!$item['is_gc']) { $product = $this->CI->Product_model->get_product($item['id']); $new_quantity = intval($product->quantity) - intval($item['quantity']); $product_quantity = array('id'=>$product->id, 'quantity'=>$new_quantity); $this->CI->Product_model->save($product_quantity); } } // update the balance of any gift cards used to purchase the order if($this->gift_cards_enabled && isset($this->_cart_contents['gc_list'])) { $this->CI->Gift_card_model->update_used_card_balances($this->_cart_contents['gc_list']); } // touch any used product coupons (increment usage) if(isset($this->_cart_contents['applied_coupons'])) { foreach($this->_cart_contents['applied_coupons'] as $code=>$content) $this->CI->Coupon_model->touch_coupon($code); } // touch free shipping coupon if($this->_cart_contents['free_shipping_coupon']) { $this->CI->Coupon_model->touch_coupon($this->_cart_contents['free_shipping_coupon']); } // touch whole order coupon if(isset($this->_cart_contents['whole_order_discount_cp'])) { $this->CI->Coupon_model->touch_coupon($this->_cart_contents['whole_order_discount_cp']); } return $order_id; } /** * Cart Items * * Returns the cart items list * * @access public * @return array */ function contents() { return $this->_cart_contents['items']; } /** * Retrieve Properties * * @access public * @return float */ function taxable_total() { return $this->_cart_contents['taxable_total']; } function total() { return $this->_cart_contents['cart_total']; } function subtotal() { return $this->_cart_contents['cart_subtotal']; } function group_discount() { return $this->_cart_contents['group_discount']; } function coupon_discount() { return $this->_cart_contents['coupon_discount']; } function discounted_subtotal() { return $this->_cart_contents['cp_discounted_subtotal']; } function gift_card_discount() { return $this->_cart_contents['gift_card_discount']; } function gift_card_balance() { return $this->_cart_contents['gift_card_balance']; } function order_insurable_value() { return $this->_cart_contents['order_insurable_value']; } function order_tax() { return $this->_cart_contents['tax']; } function tax_state() { return $this->_cart_contents['tax_state']; } function order_weight() { return $this->_cart_contents['order_weight']; } // return boolean function gift_cards_enabled() { return $this->gift_cards_enabled; } function requires_shipping() { return $this->_cart_contents['requires_shipping']; } function is_free_shipping() { if( ! $this->_cart_contents['free_shipping_coupon']) return false; else return true; // if the value isn't false, it must be set } // return array function payment_method() { return $this->_cart_contents['payment']; } function shipping_method() { return $this->_cart_contents['shipping']; } function shipping_cost() { return $this->_cart_contents['shipping']['price']; } function get_custom_charges() { return $this->_cart_contents['custom_charges']; } function customer() { if(!$this->_cart_contents['customer']) { return false; } else { return $this->_cart_contents['customer']; } } // Saves customer data in the cart function save_customer($data) { $this->_cart_contents['customer'] = $data; $this->_save_cart(); } // Add a custom charge to the cart function add_custom_charge($key, $price) { $this->_cart_contents['custom_charges'][$key] = $price; $this->_save_cart(); } function remove_custom_charge($key) { unset($this->_cart_contents['custom_charges'][$key]); $this->_save_cart(); } /** * Total Items * * Returns the total item count * * @access public * @return integer */ function total_items() { return $this->_cart_contents['total_items']; } /** * Total Number of Quantities in the Cart * * Returns the total Quantities count * * @access public * @return integer */ function total_quantities() { return $this->_cart_contents['total_quantities']; } /** * Destroy the cart * * Empties the cart * * * @access public * @return null */ function destroy($keep_customer_data=true) { // reset the cart values $this->_init_properties(false,$keep_customer_data); // save the updated cart to our session $this->_save_cart(false); } }