PHP File Manager
Editing File: Basket.php
<?php /* * Copyright (C) Wayne Purton-Smith - All Rights Reserved * Unauthorized copying of this file or removing this paragraph, via any medium is strictly prohibited * Proprietary and confidential * Written by Wayne Purton-Smith <waynepurtonsmith@hotmail.co.uk> February 2014 */ class Basket extends CI_Model { public $basket_id = 0; public $customer = 0; private $_in_stock_only = false; public $chargeable = true; public $total = 0; public $number_of_items = 0; public $delivery = 1; public $delivery_charges = NULL; public $charges = 0; public $gift_charges = 0; public $discount = 0; public $discount_type = NULL; public $discount_code = NULL; public $discount_code_type = NULL; public $vat = 0; public $delivery_costs = 0; public $total_before_charges = 0; public $total_before_discounts = 0; public $total_before_vat = 0; public $grand_total = 0; function __construct() { $this->checkBasketSession(); $this->resetTotals(); } public function checkBasketSession() { $this->basket_id = (($this->basket_id = (int) $this->basket_id) > 0) ? $this->basket_id : 0; if(!$this->basket_id) { if(!$this->input->is_cli_request() && ($basket_id = (int) $this->session->userdata('basket_id')) > 0) { $this->basket_id = $basket_id; } else { $this->createBasket(); } } else { $sql = "SELECT `b`.*, `dc`.`apply_type` AS `discount_code_type` FROM `basket` `b` LEFT OUTER JOIN `discount_codes` `dc` ON `b`.`discount_code` = `dc`.`code` AND `dc`.`is_deleted` = 0 WHERE `b`.`basket_id` = ? LIMIT 1"; $basket_info = $this->db->query($sql, array($this->basket_id))->row(); if(isset($basket_info->basket_id)) { $this->setCustomer($basket_info->ref_customer_id); $this->setChargeableMode($basket_info->chargeable); $this->setVat($basket_info->vat); $this->setDiscount($basket_info->discount); $this->setDiscountType($basket_info->discount_type); $this->setDiscountCode($basket_info->discount_code); $this->setDeliveryType($basket_info->delivery_type); $this->setDeliveryCharges($basket_info->delivery_charges); $this->setEstimatedDeliveryDate($basket_info->estimated_delivery); $this->discount_code_type = $basket_info->discount_code_type; } else { $this->createBasket(); } } } public function setBasketId($basket_id = 0) { if(($basket_id = (int) $basket_id) > 0) { $this->basket_id = $basket_id; } } public function createBasket() { $session_id = ($this->users->session_id) ? $this->users->session_id : md5(generate_unique_identifier(32)); $result = $this->db->query($this->db->insert_string('basket', array('session_id' => $session_id, 'date' => time()))); if($this->db->affected_rows($result) === 1) { $this->basket_id = $this->db->insert_id(); if(!$this->input->is_cli_request()) { $this->session->set_userdata('basket_id', $this->basket_id); } return $this->basket_id; } return false; } public function inStockOnly() { $this->_in_stock_only = true; return $this; } // TODO: Make arguments as singular as array so can be called with or without specific requirements public function addToBasket($item_id = 0, $quantity = 1, $extra_options = NULL, $gift_wrapped = false, $gift_wrap_cost = NULL, $gift_message = NULL, $override_cost = 0, $override_name = NULL, $data = NULL) { $this->checkBasketSession(); // getProducts($product_id = 0, $category_id = 0, $parent_product_id = 0, $filters = array(), $hide_invisible_products = false, $skip = 0, $limit = 30) if(($item_id = (int) $item_id) > 0 && ($product_info = $this->products->getProducts($item_id))) { if($this->_in_stock_only) { if(($stock_info = $this->stocks->getStock(NULL, $product_info->product_id))) { if($stock_info->level == $this->config->item(STOCK_OUT_OF_STOCK)) { return false; } } } $quantity = (($quantity = (int) $quantity) > 0) ? $quantity : 1; if(($minimum_order = (int) $product_info->minimum_order) && $quantity < $minimum_order) { $quantity = $minimum_order; } $cost = (($override_cost = (float) $override_cost) > 0) ? $override_cost : NULL; // Check if customer has agreed price if(!$cost && $this->customer) { if(($fixed_product = $this->customers->getFixedPrices($this->customer, $item_id))) { $cost = (float) $fixed_product->price; } } $sql_data['basket_id'] = $this->basket_id; $sql_data['item_id'] = $item_id; $sql_data['quantity'] = $quantity; $sql_data['cost'] = $cost; if(strlen(($override_name = trim($override_name)))) { $sql_data['override_name'] = $override_name; } $sql_data['gift_wrapped'] = (bool) $gift_wrapped; $sql_data['gift_wrap_cost'] = 0; if(strlen(trim($gift_wrap_cost)) > 0 && is_numeric($gift_wrap_cost)) { if(($gift_wrap_cost = (float) $gift_wrap_cost) > 0) { $sql_data['gift_wrap_cost'] = $gift_wrap_cost; } } else { // We'll use the default gift wrapping cost $sql_data['gift_wrap_cost'] = $product_info->gift_wrap_cost; } $sql_data['gift_message'] = nullify(format_whitespace($gift_message)); $sql_data['data'] = nullify($data); if(!isset($sql_data['override_name']) && ($existing_item_id = $this->basketItemExists($item_id))) { $basket_item_id = $existing_item_id; unset($sql_data['basket_id'], $sql_data['item_id']); $result = $this->db->query($this->db->update_string('basket_items', $sql_data, "basket_item_id = $existing_item_id")); //return ($result || $this->db->affected_rows($result)) ? $quantity : false; } else { $result = $this->db->query($this->db->insert_string('basket_items', $sql_data)); $basket_item_id = ($this->db->affected_rows($result)) ? $this->db->insert_id() : 0; //return ($this->db->affected_rows() === 1) ? $quantity : false; } if($basket_item_id <= 0) { return false; } $this->removeBasketItemOptions($basket_item_id); if(is_array($extra_options)) { foreach($extra_options as $i => $extra_id) { if(($extra_id = (int) $extra_id) > 0) { $this->saveBasketItemOption($basket_item_id, $extra_id); } } } return ($result || $this->db->affected_rows($result)) ? $quantity : false; } return false; } public function saveBasketItemOption($basket_item_id = 0, $extra_id = 0) { if(($basket_item_id = (int) $basket_item_id) > 0 && ($extra_id = (int) $extra_id) > 0) { $sql_data = array ( 'basket_id' => $this->basket_id, 'item_id' => $basket_item_id, 'extra_id' => $extra_id ); $this->db->query($this->db->insert_string('basket_item_options', $sql_data)); return ($this->db->affected_rows() === 1); } return false; } public function removeBasketItemOptions($basket_item_id = 0) { if($this->basket_id > 0 && ($basket_item_id = (int) $basket_item_id) > 0) { $this->db->query("DELETE FROM `basket_item_options` WHERE `item_id` = ? AND `basket_id` = ?", array($basket_item_id, $this->basket_id)); } } public function removeFromBasket($item_id = 0) { $this->checkBasketSession(); if(($item_id = (int) $item_id) > 0) { $this->db->query("DELETE FROM `basket_items` WHERE `basket_item_id` = ? AND `basket_id` = ? LIMIT 1", array($item_id, $this->basket_id)); return ($this->db->affected_rows() === 1); } return false; } public function basketItemExists($item_id = 0) { $this->checkBasketSession(); $sql = "SELECT `basket_item_id` FROM `basket_items` WHERE `item_id` = ? AND `basket_id` = ? LIMIT 1"; $result = $this->db->query($sql, array($item_id, $this->basket_id)); return ($result->num_rows() === 1) ? (int) $result->row('basket_item_id') : false; } public function getBasket($basket_id = 0, $include_photo_file = false) { $this->checkBasketSession(); $basket_id = (($basket_id = (int) $basket_id) > 0) ? $basket_id : $this->basket_id; $sql = "SELECT `bi`.*, IF(`bi`.`cost` IS NOT NULL, `bi`.`cost`, IF(`p2`.`cost` IS NOT NULL, (`r`.`cost` + `p2`.`cost`), `r`.`cost`)) AS `cost`, IF(`bi`.`cost` IS NOT NULL, 0, IF(`p2`.`cost` IS NOT NULL, `r`.`cost`, 0)) AS `option_cost`, IF(`bi`.`override_name` IS NOT NULL, `bi`.`override_name`, IF(`p2`.`name` IS NOT NULL, CONCAT(`p2`.`name`, ' (', `r`.`name`, ')'), `r`.`name`)) AS `name`, `bi`.`override_name`, `r`.`parent_id`, `r`.`identifier` FROM ( `basket_items` `bi` INNER JOIN `products` `r` ON `r`.`product_id` = `bi`.`item_id` LEFT OUTER JOIN ( SELECT `product_id`, `parent_id` AS `option_id`, `cost`, `name` FROM `products` WHERE `is_deleted` = 0 ) AS `p2` ON `p2`.`product_id` = `r`.`parent_id` ) WHERE `bi`.`basket_id` = ? GROUP BY `bi`.`basket_item_id` ORDER BY `bi`.`basket_item_id`"; $result = $this->db->query($sql, array($basket_id)); if($result->num_rows() > 0) { $rows = $result->result(); $result->free_result(); $items = array(); $this->setGiftCharges(0); foreach($rows as $row) { $item_data = array ( 'id' => (int) $row->item_id, 'parent' => (int) $row->parent_id, 'name' => $row->name, 'override_name' => $row->override_name, 'qty' => (int) $row->quantity, 'cost' => (float) $row->cost, 'extra_options' => $this->getBasketItemOptions($row->basket_item_id), 'gift_wrapped' => (bool) $row->gift_wrapped, 'gift_wrap_cost' => ($row->gift_wrapped) ? (float) $row->gift_wrap_cost : 0, 'gift_message' => $row->gift_message, 'data' => $row->data ); if($row->gift_wrapped) { //$this->setGiftCharges($this->setGiftCharges() + ($row->gift_wrap_cost * $row->quantity)); } if($include_photo_file) { if(file_exists('assets/uploads/products/' . $row->identifier . '.jpg')) { $item_data['photo'] = '/assets/uploads/products/' . $row->identifier . '.jpg'; $item_data['photo_thumb'] = preg_replace('/\.(\w+)$/', '_thumb.$1', $item_data['photo']); } else { $item_data['photo'] = $item_data['photo_thumb'] = '/assets/images/no-product-image.jpg'; } } $items[$row->basket_item_id] = (object) $item_data; } return $items; } return array(); } public function getBasketItemOptions($basket_item_id = 0) { if($this->basket_id > 0 && ($basket_item_id = (int) $basket_item_id) > 0) { $sql = "SELECT `io`.*, `pe`.`name` AS `option_name`, `pe`.`extra_charge` FROM `basket_item_options` `io` INNER JOIN `product_extras` `pe` ON `pe`.`extra_id` = `io`.`extra_id` WHERE `io`.`item_id` = ? AND `io`.`basket_id` = ? GROUP BY `io`.`option_id`"; $result = $this->db->query($sql, array($basket_item_id, $this->basket_id)); //echo $this->db->last_query(); if($result->num_rows()) { $rows = $result->result(); $result->free_result(); return $rows; } } return array(); } public function count($count_quantity = false) { $basket_items = $this->getBasket(); return array_sum(array_map(function($value) use ($count_quantity) { return ($count_quantity) ? $value->qty : 1; }, $basket_items)); } public function setChargeableMode($is_chargeable = true) { $this->chargeable = (bool) $is_chargeable; $this->storeBasketData('chargeable', $this->chargeable); } public function isChargeable() { return $this->chargeable; } public function setGiftCharges($amount = 0) { $this->gift_charges = (($amount = (float) $amount) >= 0) ? $amount : 0; $this->storeBasketData('gift_charges', $this->discount); } public function getGiftCharges() { $basket_items = $this->getBasket(); $charges = 0; foreach($basket_items as $item_info) { if($item_info->gift_wrapped) { $charges += ($item_info->gift_wrap_cost * $item_info->qty); } } return $charges; } public function setCustomer($customer_id = 0) { $this->customer = (($customer_id = (int) $customer_id) > 0) ? $customer_id : 0; $this->storeBasketData('ref_customer_id', $this->customer); } public function getCustomer() { return $this->customer; } public function setDeliveryType($delivery_type = NULL) { $this->delivery = (($delivery_type = (int) $delivery_type) > 0) ? $delivery_type : 0; $this->storeBasketData('delivery_type', $this->delivery); } public function getDeliveryType() { return $this->delivery; } public function getDeliveryInfo() { $result = $this->db->query("SELECT * FROM `delivery_types` WHERE `is_deleted` = 0 AND `delivery_id` = ? LIMIT 1", array($this->getDeliveryType())); $info = array ( 'id' => 1, 'default' => true, 'name' => NULL, 'per_item' => false, 'costs' => 0, 'days' => 0 ); if($result->num_rows()) { $delivery_info = $result->row(); $info['id'] = $delivery_info->delivery_id; $info['default'] = ($delivery_info->delivery_id == 1); $info['name'] = $delivery_info->label; $info['per_item'] = (bool) $delivery_info->per_item; $info['costs'] = (float) $delivery_info->costs; $info['days'] = (int) $delivery_info->delivery_days; } return (object) $info; } public function setEstimatedDeliveryDate($date = NULL) { $this->estimated_delivery_date = (is_numeric($date)) ? $date : NULL; $this->storeBasketData('estimated_delivery', $this->estimated_delivery_date); } public function getEstimatedDeliveryDate() { return $this->estimated_delivery_date; } public function calculateDeliveryCharges() { $delivery_info = $this->getDeliveryInfo(); if(($manual_charges = $this->getDeliveryCharges()) !== NULL) { return $manual_charges; } else { $delivery_cost = (float) $delivery_info->costs; if($delivery_info->per_item) { return ($delivery_cost > 0) ? ($delivery_cost * $this->count(true)) : 0; } return $delivery_cost; } } public function setDeliveryCharges($amount = 0) { $this->delivery_charges = (is_numeric($amount) && ($amount = (float) $amount) >= 0) ? $amount : NULL; $this->storeBasketData('delivery_charges', $this->delivery_charges); } public function getDeliveryCharges() { return $this->delivery_charges; } public function setDiscountType($discount_type = NULL) { $this->discount_type = (($discount_type = (int) $discount_type) > 0 && in_array($discount_type, array(DISCOUNT_PERCENTAGE, DISCOUNT_AMOUNT))) ? $discount_type : NULL; $this->storeBasketData('discount_type', $this->discount_type); } public function getDiscountType() { return $this->discount_type; } public function setDiscountCode($discount_code = NULL) { $this->discount_code = (is_string($discount_code)) ? strtoupper(remove_whitespace($discount_code)) : NULL; $this->storeBasketData('discount_code', $this->discount_code); } public function getDiscountCode() { return $this->discount_code; } public function setDiscount($amount = 0) { $this->discount = (is_numeric($amount) && ($amount = (float) $amount) >= 0) ? $amount : 0; $this->storeBasketData('discount', $this->discount); } public function getDiscount() { return $this->discount; } public function applyDiscountByCode($offer_code = NULL, &$discount_type = NULL, &$discount_amount = 0, &$delivery_charges = 0) { $this->load->model('offers'); if(($offer_code = remove_whitespace($offer_code)) != '' && ($discount_code_info = $this->offers->get(NULL, $offer_code))) { $discount_info = $this->offers->explainOffer($discount_code_info); if($discount_info->applies_to == 'SHIPPING') { if($discount_info->minimum_amount === NULL || $delivery_charges >= $discount_info->minimum_amount) { $delivery_charges -= calculate_discount($delivery_charges, $discount_info->amount, $discount_info->discount_type); } } elseif($discount_info->applies_to == 'ORDER') { if($discount_info->minimum_amount === NULL || $basket_before_discount >= $discount_info->minimum_amount) { $discount_type = $discount_info->discount_type; $discount_amount = $discount_info->amount; } } elseif($discount_info->applies_to == 'ITEMS') { $discount_type = $discount_info->discount_type; $discount_amount = 0; foreach($basket_items as $basket_item_info) { if($discount_info->minimum_amount === NULL || $basket_item_info->cost >= $discount_info->minimum_amount) { $item_discounted = calculate_discount($basket_item_info->cost, $discount_info->amount, $discount_info->discount_type); $discounted_diff = abs($basket_item_info->cost - $item_discounted); $discount_amount += $discounted_diff; } } } $this->setDiscountCode($offer_code); $this->setDiscountType($discount_type); $this->setDiscount($discount_amount); $this->setDeliveryCharges($delivery_charges); } } public function calculateDiscount($format = false) { $current_total = $this->total_before_discounts; if(($discount_amount = $this->getDiscount())) { switch($this->getDiscountType()) { case 1: return (($current_total / 100) * $discount_amount); break; case 2: return ($current_total - (($current_total - $discount_amount))); break; } } return 0; } public function setVat($amount = 0) { $this->vat = (($amount = (float) $amount) > 0) ? $amount : $this->common->vat; $this->storeBasketData('vat', $this->vat); } public function getVat() { return $this->vat; } public function setCharges($amount = 0) { $this->charges = (is_numeric($amount) && ($amount = (float) $amount) >= 0) ? $amount : 0; $this->storeBasketData('charges', $this->charges); } public function getCharges() { return $this->charges; } public function calculate($return_from = 'grand-total') { $this->checkBasketSession(); $this->resetTotals(); $basket_items = $this->getBasket(); $total_charges = 0; foreach($basket_items as $basket_item_id => $item_info) { $item_cost = ($item_info->cost * $item_info->qty); $this->total += $item_cost; $this->total_before_charges += $item_cost; if($this->isChargeable()) { // $total_charges += 0; } } $this->setCharges($total_charges); $this->total_before_discounts = $this->total_before_charges + $this->getCharges() + $this->getGiftCharges(); $this->total_before_vat = $this->total_before_discounts - $this->calculateDiscount(); $this->delivery_costs = $this->calculateDeliveryCharges(); // Including VAT $this->grand_total = ($this->total_before_vat + $this->delivery_costs); // Adds VAT on top //$this->grand_total = ($this->total_before_vat + calculate_vat($this->total_before_vat, $this->getVat())) + $this->delivery_costs; $return_types = array ( 'total' => $this->total, 'before-charges' => $this->total_before_charges, 'before-discounts' => $this->total_before_discounts, 'before-vat' => $this->total_before_vat, 'grand-total' => $this->grand_total ); return (isset($return_types[$return_from])) ? $return_types[$return_from] : $return_types['grand-total']; } public function resetTotals($full_reset = false) { if($full_reset) { $this->charges = 0; $this->gift_charges = 0; $this->discount = 0; $this->discount_type = NULL; $this->discount_code = NULL; $this->vat = $this->common->vat; } $this->total = 0; $this->total_before_charges = 0; $this->total_before_discounts = 0; $this->total_before_vat = 0; $this->grand_total = 0; $this->delivery = 1; $this->delivery_charges = NULL; $this->delivery_costs = 0; $this->estimated_delivery_date = NULL; } public function clearBasket() { $this->checkBasketSession(); $this->resetTotals(true); $this->db->query("DELETE FROM `basket` WHERE `basket_id` = ?", array($this->basket_id)); $this->db->query("DELETE FROM `basket_items` WHERE `basket_id` = ?", array($this->basket_id)); $this->db->query("DELETE FROM `basket_item_options` WHERE `basket_id` = ?", array($this->basket_id)); if(!$this->input->is_cli_request()) { $this->session->unset_userdata('basket_id'); } $this->basket_id = 0; return true; } private function storeBasketData($key = '', $data = NULL) { $this->db->query($this->db->update_string('basket', array($key => $data), "`basket_id` = " . $this->basket_id)); } }
Cancel