blob: 6a107752caf2aabef7a593a2223bd88d3bcbb22a [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
Rick Ellis98783322009-02-17 02:29:44 +00002/**
3 * CodeIgniter
4 *
Andrey Andreevfe9309d2015-01-09 17:48:58 +02005 * An open source application development framework for PHP
Rick Ellis98783322009-02-17 02:29:44 +00006 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +02007 * This content is released under the MIT License (MIT)
Andrey Andreevbb248832011-12-21 16:42:51 +02008 *
Instructor, BCIT0e59db62019-01-01 08:34:36 -08009 * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
Andrey Andreevbb248832011-12-21 16:42:51 +020010 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020011 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights
14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 * copies of the Software, and to permit persons to whom the Software is
16 * furnished to do so, subject to the following conditions:
Derek Jonesf4a4bd82011-10-20 12:18:42 -050017 *
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020018 * The above copyright notice and this permission notice shall be included in
19 * all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * THE SOFTWARE.
28 *
29 * @package CodeIgniter
30 * @author EllisLab Dev Team
Andrey Andreev1924e872016-01-11 12:55:34 +020031 * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
Instructor, BCIT0e59db62019-01-01 08:34:36 -080032 * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (http://bcit.ca/)
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020033 * @license http://opensource.org/licenses/MIT MIT License
Andrey Andreevbd202c92016-01-11 12:50:18 +020034 * @link https://codeigniter.com
Andrey Andreevbdb96ca2014-10-28 00:13:31 +020035 * @since Version 1.0.0
Rick Ellis98783322009-02-17 02:29:44 +000036 * @filesource
37 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020038defined('BASEPATH') OR exit('No direct script access allowed');
Rick Ellis98783322009-02-17 02:29:44 +000039
Rick Ellis98783322009-02-17 02:29:44 +000040/**
41 * Shopping Cart Class
42 *
43 * @package CodeIgniter
44 * @subpackage Libraries
45 * @category Shopping Cart
Derek Jonesf4a4bd82011-10-20 12:18:42 -050046 * @author EllisLab Dev Team
Andrey Andreevbd202c92016-01-11 12:50:18 +020047 * @link https://codeigniter.com/user_guide/libraries/cart.html
Andrey Andreev21c3c222014-12-04 12:10:00 +020048 * @deprecated 3.0.0 This class is too specific for CI.
Rick Ellis98783322009-02-17 02:29:44 +000049 */
50class CI_Cart {
51
Timothy Warren86611db2012-04-27 10:06:25 -040052 /**
53 * These are the regular expression rules that we use to validate the product ID and product name
54 * alpha-numeric, dashes, underscores, or periods
Andrey Andreev56454792012-05-17 14:32:19 +030055 *
Timothy Warren86611db2012-04-27 10:06:25 -040056 * @var string
57 */
Andrey Andreevfe9309d2015-01-09 17:48:58 +020058 public $product_id_rules = '\.a-z0-9_-';
Andrey Andreev56454792012-05-17 14:32:19 +030059
Timothy Warren86611db2012-04-27 10:06:25 -040060 /**
61 * These are the regular expression rules that we use to validate the product ID and product name
62 * alpha-numeric, dashes, underscores, colons or periods
63 *
64 * @var string
65 */
Andrey Andreevfe9309d2015-01-09 17:48:58 +020066 public $product_name_rules = '\w \-\.\:';
Andrey Andreev56454792012-05-17 14:32:19 +030067
Timothy Warren86611db2012-04-27 10:06:25 -040068 /**
69 * only allow safe product names
70 *
71 * @var bool
72 */
Andrey Andreevfe9309d2015-01-09 17:48:58 +020073 public $product_name_safe = TRUE;
Barry Mienydd671972010-10-04 16:33:58 +020074
Timothy Warren86611db2012-04-27 10:06:25 -040075 // --------------------------------------------------------------------------
Andrey Andreev56454792012-05-17 14:32:19 +030076
Timothy Warren86611db2012-04-27 10:06:25 -040077 /**
78 * Reference to CodeIgniter instance
79 *
80 * @var object
81 */
Andrey Andreev6f042cc2012-03-26 14:58:33 +030082 protected $CI;
Andrey Andreev56454792012-05-17 14:32:19 +030083
Timothy Warren86611db2012-04-27 10:06:25 -040084 /**
85 * Contents of the cart
86 *
87 * @var array
88 */
Andrey Andreevfe9309d2015-01-09 17:48:58 +020089 protected $_cart_contents = array();
Rick Ellis98783322009-02-17 02:29:44 +000090
91 /**
92 * Shopping Class Constructor
93 *
94 * The constructor loads the Session class, used to store the shopping cart contents.
Timothy Warren86611db2012-04-27 10:06:25 -040095 *
96 * @param array
Andrey Andreev56454792012-05-17 14:32:19 +030097 * @return void
Barry Mienydd671972010-10-04 16:33:58 +020098 */
Greg Akera9263282010-11-10 15:26:43 -060099 public function __construct($params = array())
Barry Mienydd671972010-10-04 16:33:58 +0200100 {
Rick Ellis98783322009-02-17 02:29:44 +0000101 // Set the super object to a local variable for use later
102 $this->CI =& get_instance();
Barry Mienydd671972010-10-04 16:33:58 +0200103
Derek Jones37f4b9c2011-07-01 17:56:50 -0500104 // Are any config settings being passed manually? If so, set them
Andrey Andreevbb248832011-12-21 16:42:51 +0200105 $config = is_array($params) ? $params : array();
Barry Mienydd671972010-10-04 16:33:58 +0200106
Rick Ellis98783322009-02-17 02:29:44 +0000107 // Load the Sessions class
Edwin Awedc9afa2013-01-25 16:12:20 +0800108 $this->CI->load->driver('session', $config);
Barry Mienydd671972010-10-04 16:33:58 +0200109
Andrey Andreevbb248832011-12-21 16:42:51 +0200110 // Grab the shopping cart array from the session table
111 $this->_cart_contents = $this->CI->session->userdata('cart_contents');
Ivan Tcholakov29453cd2012-11-23 13:54:28 +0200112 if ($this->_cart_contents === NULL)
Rick Ellis98783322009-02-17 02:29:44 +0000113 {
114 // No cart exists so we'll set some base values
Andrey Andreevbb248832011-12-21 16:42:51 +0200115 $this->_cart_contents = array('cart_total' => 0, 'total_items' => 0);
Rick Ellis98783322009-02-17 02:29:44 +0000116 }
Barry Mienydd671972010-10-04 16:33:58 +0200117
Andrey Andreev90726b82015-01-20 12:39:22 +0200118 log_message('info', 'Cart Class Initialized');
Rick Ellis98783322009-02-17 02:29:44 +0000119 }
120
121 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200122
Rick Ellis98783322009-02-17 02:29:44 +0000123 /**
124 * Insert items into the cart and save it to the session table
125 *
Rick Ellis98783322009-02-17 02:29:44 +0000126 * @param array
127 * @return bool
128 */
Andrey Andreevbb248832011-12-21 16:42:51 +0200129 public function insert($items = array())
Rick Ellis98783322009-02-17 02:29:44 +0000130 {
131 // Was any cart data passed? No? Bah...
Andrey Andreevbb248832011-12-21 16:42:51 +0200132 if ( ! is_array($items) OR count($items) === 0)
Rick Ellis98783322009-02-17 02:29:44 +0000133 {
134 log_message('error', 'The insert method must be passed an array containing data.');
135 return FALSE;
136 }
Barry Mienydd671972010-10-04 16:33:58 +0200137
138 // You can either insert a single product using a one-dimensional array,
Rick Ellis98783322009-02-17 02:29:44 +0000139 // or multiple products using a multi-dimensional one. The way we
140 // determine the array type is by looking for a required array key named "id"
141 // at the top level. If it's not found, we will assume it's a multi-dimensional array.
Barry Mienydd671972010-10-04 16:33:58 +0200142
143 $save_cart = FALSE;
Rick Ellis98783322009-02-17 02:29:44 +0000144 if (isset($items['id']))
Barry Mienydd671972010-10-04 16:33:58 +0200145 {
Phil Sturgeon90910512011-07-20 10:07:40 -0600146 if (($rowid = $this->_insert($items)))
Rick Ellis98783322009-02-17 02:29:44 +0000147 {
148 $save_cart = TRUE;
149 }
150 }
151 else
152 {
153 foreach ($items as $val)
154 {
Andrey Andreev6f042cc2012-03-26 14:58:33 +0300155 if (is_array($val) && isset($val['id']))
Rick Ellis98783322009-02-17 02:29:44 +0000156 {
Phil Sturgeon90910512011-07-20 10:07:40 -0600157 if ($this->_insert($val))
Rick Ellis98783322009-02-17 02:29:44 +0000158 {
159 $save_cart = TRUE;
160 }
Barry Mienydd671972010-10-04 16:33:58 +0200161 }
Rick Ellis98783322009-02-17 02:29:44 +0000162 }
163 }
164
165 // Save the cart data if the insert was successful
Andrey Andreevbb248832011-12-21 16:42:51 +0200166 if ($save_cart === TRUE)
Rick Ellis98783322009-02-17 02:29:44 +0000167 {
168 $this->_save_cart();
Phil Sturgeon90910512011-07-20 10:07:40 -0600169 return isset($rowid) ? $rowid : TRUE;
Rick Ellis98783322009-02-17 02:29:44 +0000170 }
171
172 return FALSE;
173 }
174
175 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200176
Rick Ellis98783322009-02-17 02:29:44 +0000177 /**
178 * Insert
179 *
Rick Ellis98783322009-02-17 02:29:44 +0000180 * @param array
181 * @return bool
182 */
Andrey Andreev74476e12012-03-26 15:03:40 +0300183 protected function _insert($items = array())
Rick Ellis98783322009-02-17 02:29:44 +0000184 {
185 // Was any cart data passed? No? Bah...
Andrey Andreevbb248832011-12-21 16:42:51 +0200186 if ( ! is_array($items) OR count($items) === 0)
Rick Ellis98783322009-02-17 02:29:44 +0000187 {
188 log_message('error', 'The insert method must be passed an array containing data.');
189 return FALSE;
190 }
Barry Mienydd671972010-10-04 16:33:58 +0200191
Rick Ellis98783322009-02-17 02:29:44 +0000192 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200193
Derek Jones37f4b9c2011-07-01 17:56:50 -0500194 // Does the $items array contain an id, quantity, price, and name? These are required
Andrey Andreev56454792012-05-17 14:32:19 +0300195 if ( ! isset($items['id'], $items['qty'], $items['price'], $items['name']))
Rick Ellis98783322009-02-17 02:29:44 +0000196 {
197 log_message('error', 'The cart array must contain a product ID, quantity, price, and name.');
198 return FALSE;
199 }
200
201 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200202
Andrey Andreevbb248832011-12-21 16:42:51 +0200203 // Prep the quantity. It can only be a number. Duh... also trim any leading zeros
Andrey Andreev17779d62011-12-22 13:21:08 +0200204 $items['qty'] = (float) $items['qty'];
Rick Ellis98783322009-02-17 02:29:44 +0000205
206 // If the quantity is zero or blank there's nothing for us to do
Andrey Andreev1a9b7e02012-11-01 16:23:47 +0200207 if ($items['qty'] == 0)
Rick Ellis98783322009-02-17 02:29:44 +0000208 {
209 return FALSE;
210 }
Barry Mienydd671972010-10-04 16:33:58 +0200211
Rick Ellis98783322009-02-17 02:29:44 +0000212 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200213
Rick Ellis98783322009-02-17 02:29:44 +0000214 // Validate the product ID. It can only be alpha-numeric, dashes, underscores or periods
215 // Not totally sure we should impose this rule, but it seems prudent to standardize IDs.
216 // Note: These can be user-specified by setting the $this->product_id_rules variable.
Andrey Andreevbb248832011-12-21 16:42:51 +0200217 if ( ! preg_match('/^['.$this->product_id_rules.']+$/i', $items['id']))
Rick Ellis98783322009-02-17 02:29:44 +0000218 {
Derek Jones37f4b9c2011-07-01 17:56:50 -0500219 log_message('error', 'Invalid product ID. The product ID can only contain alpha-numeric characters, dashes, and underscores');
Rick Ellis98783322009-02-17 02:29:44 +0000220 return FALSE;
221 }
222
223 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200224
Rick Ellis98783322009-02-17 02:29:44 +0000225 // Validate the product name. It can only be alpha-numeric, dashes, underscores, colons or periods.
226 // Note: These can be user-specified by setting the $this->product_name_rules variable.
Louis Racicot025b6462013-03-07 09:32:16 -0500227 if ($this->product_name_safe && ! preg_match('/^['.$this->product_name_rules.']+$/i'.(UTF8_ENABLED ? 'u' : ''), $items['name']))
Rick Ellis98783322009-02-17 02:29:44 +0000228 {
Andrew Seymour3dd66632011-12-13 15:50:52 +0000229 log_message('error', 'An invalid name was submitted as the product name: '.$items['name'].' The name can only contain alpha-numeric characters, dashes, underscores, colons, and spaces');
230 return FALSE;
Rick Ellis98783322009-02-17 02:29:44 +0000231 }
232
233 // --------------------------------------------------------------------
234
Andrey Andreevbb248832011-12-21 16:42:51 +0200235 // Prep the price. Remove leading zeros and anything that isn't a number or decimal point.
Andrey Andreev17779d62011-12-22 13:21:08 +0200236 $items['price'] = (float) $items['price'];
Barry Mienydd671972010-10-04 16:33:58 +0200237
Rick Ellis98783322009-02-17 02:29:44 +0000238 // We now need to create a unique identifier for the item being inserted into the cart.
Barry Mienydd671972010-10-04 16:33:58 +0200239 // Every time something is added to the cart it is stored in the master cart array.
240 // Each row in the cart array, however, must have a unique index that identifies not only
241 // a particular product, but makes it possible to store identical products with different options.
242 // For example, what if someone buys two identical t-shirts (same product ID), but in
Derek Jones37f4b9c2011-07-01 17:56:50 -0500243 // different sizes? The product ID (and other attributes, like the name) will be identical for
Rick Ellis98783322009-02-17 02:29:44 +0000244 // both sizes because it's the same shirt. The only difference will be the size.
245 // Internally, we need to treat identical submissions, but with different options, as a unique product.
246 // Our solution is to convert the options array to a string and MD5 it along with the product ID.
247 // This becomes the unique "row ID"
Andrey Andreev6f042cc2012-03-26 14:58:33 +0300248 if (isset($items['options']) && count($items['options']) > 0)
Rick Ellis98783322009-02-17 02:29:44 +0000249 {
ThallisPHPf074dff2012-05-03 16:01:46 -0300250 $rowid = md5($items['id'].serialize($items['options']));
Rick Ellis98783322009-02-17 02:29:44 +0000251 }
252 else
253 {
254 // No options were submitted so we simply MD5 the product ID.
255 // Technically, we don't need to MD5 the ID in this case, but it makes
256 // sense to standardize the format of array indexes for both conditions
257 $rowid = md5($items['id']);
Barry Mienydd671972010-10-04 16:33:58 +0200258 }
Rick Ellis98783322009-02-17 02:29:44 +0000259
260 // --------------------------------------------------------------------
261
262 // Now that we have our unique "row ID", we'll add our cart items to the master array
Andrew Seymour2e5bda32011-12-13 11:40:15 +0000263 // grab quantity if it's already there and add it on
Andrey Andreevbb248832011-12-21 16:42:51 +0200264 $old_quantity = isset($this->_cart_contents[$rowid]['qty']) ? (int) $this->_cart_contents[$rowid]['qty'] : 0;
Barry Mienydd671972010-10-04 16:33:58 +0200265
Andrey Andreevbb248832011-12-21 16:42:51 +0200266 // Re-create the entry, just to make sure our index contains only the data from this submission
267 $items['rowid'] = $rowid;
268 $items['qty'] += $old_quantity;
269 $this->_cart_contents[$rowid] = $items;
Barry Mienydd671972010-10-04 16:33:58 +0200270
Phil Sturgeon90910512011-07-20 10:07:40 -0600271 return $rowid;
Rick Ellis98783322009-02-17 02:29:44 +0000272 }
273
274 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200275
Rick Ellis98783322009-02-17 02:29:44 +0000276 /**
277 * Update the cart
278 *
Barry Mienydd671972010-10-04 16:33:58 +0200279 * This function permits the quantity of a given item to be changed.
Rick Ellis98783322009-02-17 02:29:44 +0000280 * Typically it is called from the "view cart" page if a user makes
281 * changes to the quantity before checkout. That array must contain the
282 * product ID and quantity for each item.
283 *
Rick Ellis98783322009-02-17 02:29:44 +0000284 * @param array
Rick Ellis98783322009-02-17 02:29:44 +0000285 * @return bool
286 */
Andrey Andreevbb248832011-12-21 16:42:51 +0200287 public function update($items = array())
Rick Ellis98783322009-02-17 02:29:44 +0000288 {
289 // Was any cart data passed?
Andrey Andreevbb248832011-12-21 16:42:51 +0200290 if ( ! is_array($items) OR count($items) === 0)
Rick Ellis98783322009-02-17 02:29:44 +0000291 {
292 return FALSE;
293 }
Barry Mienydd671972010-10-04 16:33:58 +0200294
295 // You can either update a single product using a one-dimensional array,
Derek Jones37f4b9c2011-07-01 17:56:50 -0500296 // or multiple products using a multi-dimensional one. The way we
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200297 // determine the array type is by looking for a required array key named "rowid".
Rick Ellis98783322009-02-17 02:29:44 +0000298 // If it's not found we assume it's a multi-dimensional array
299 $save_cart = FALSE;
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200300 if (isset($items['rowid']))
Rick Ellis98783322009-02-17 02:29:44 +0000301 {
Andrey Andreevbb248832011-12-21 16:42:51 +0200302 if ($this->_update($items) === TRUE)
Rick Ellis98783322009-02-17 02:29:44 +0000303 {
304 $save_cart = TRUE;
305 }
306 }
307 else
308 {
309 foreach ($items as $val)
310 {
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200311 if (is_array($val) && isset($val['rowid']))
Rick Ellis98783322009-02-17 02:29:44 +0000312 {
Andrey Andreevbb248832011-12-21 16:42:51 +0200313 if ($this->_update($val) === TRUE)
Rick Ellis98783322009-02-17 02:29:44 +0000314 {
315 $save_cart = TRUE;
316 }
Barry Mienydd671972010-10-04 16:33:58 +0200317 }
Rick Ellis98783322009-02-17 02:29:44 +0000318 }
319 }
320
321 // Save the cart data if the insert was successful
Andrey Andreevbb248832011-12-21 16:42:51 +0200322 if ($save_cart === TRUE)
Rick Ellis98783322009-02-17 02:29:44 +0000323 {
324 $this->_save_cart();
325 return TRUE;
326 }
327
328 return FALSE;
329 }
330
331 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200332
Rick Ellis98783322009-02-17 02:29:44 +0000333 /**
334 * Update the cart
335 *
Ahmad Anbar7d16de62014-02-13 01:45:27 +0200336 * This function permits changing item properties.
Rick Ellis98783322009-02-17 02:29:44 +0000337 * Typically it is called from the "view cart" page if a user makes
338 * changes to the quantity before checkout. That array must contain the
Ahmad Anbarda2bdf22014-02-13 12:59:18 +0200339 * rowid and quantity for each item.
Rick Ellis98783322009-02-17 02:29:44 +0000340 *
Rick Ellis98783322009-02-17 02:29:44 +0000341 * @param array
342 * @return bool
Barry Mienydd671972010-10-04 16:33:58 +0200343 */
Andrey Andreev6f042cc2012-03-26 14:58:33 +0300344 protected function _update($items = array())
Rick Ellis98783322009-02-17 02:29:44 +0000345 {
346 // Without these array indexes there is nothing we can do
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200347 if ( ! isset($items['rowid'], $this->_cart_contents[$items['rowid']]))
Rick Ellis98783322009-02-17 02:29:44 +0000348 {
349 return FALSE;
350 }
Barry Mienydd671972010-10-04 16:33:58 +0200351
Rick Ellis98783322009-02-17 02:29:44 +0000352 // Prep the quantity
Ahmad Anbar2702a3b2014-03-14 16:53:44 +0200353 if (isset($items['qty']))
Rick Ellis98783322009-02-17 02:29:44 +0000354 {
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200355 $items['qty'] = (float) $items['qty'];
356 // Is the quantity zero? If so we will remove the item from the cart.
357 // If the quantity is greater than zero we are updating
358 if ($items['qty'] == 0)
359 {
360 unset($this->_cart_contents[$items['rowid']]);
Ahmad Anbar9af07462014-03-14 15:33:18 +0200361 return TRUE;
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200362 }
Andrey Andreevdb3e49d2014-03-17 11:04:55 +0200363 }
364
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200365 // find updatable keys
366 $keys = array_intersect(array_keys($this->_cart_contents[$items['rowid']]), array_keys($items));
367 // if a price was passed, make sure it contains valid data
368 if (isset($items['price']))
Rick Ellis98783322009-02-17 02:29:44 +0000369 {
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200370 $items['price'] = (float) $items['price'];
Rick Ellis98783322009-02-17 02:29:44 +0000371 }
Barry Mienydd671972010-10-04 16:33:58 +0200372
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200373 // product id & name shouldn't be changed
374 foreach (array_diff($keys, array('id', 'name')) as $key)
375 {
376 $this->_cart_contents[$items['rowid']][$key] = $items[$key];
Andrey Andreevdb3e49d2014-03-17 11:04:55 +0200377 }
Ahmad Anbar4321cb02014-03-14 15:21:13 +0200378
Rick Ellis98783322009-02-17 02:29:44 +0000379 return TRUE;
380 }
381
382 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200383
Rick Ellis98783322009-02-17 02:29:44 +0000384 /**
385 * Save the cart array to the session DB
386 *
Rick Ellis98783322009-02-17 02:29:44 +0000387 * @return bool
388 */
Andrey Andreev6f042cc2012-03-26 14:58:33 +0300389 protected function _save_cart()
Rick Ellis98783322009-02-17 02:29:44 +0000390 {
vlakoff35672462013-02-15 01:36:04 +0100391 // Let's add up the individual prices and set the cart sub-total
Andrey Andreevbb248832011-12-21 16:42:51 +0200392 $this->_cart_contents['total_items'] = $this->_cart_contents['cart_total'] = 0;
Rick Ellis98783322009-02-17 02:29:44 +0000393 foreach ($this->_cart_contents as $key => $val)
394 {
395 // We make sure the array contains the proper indexes
Andrey Andreev56454792012-05-17 14:32:19 +0300396 if ( ! is_array($val) OR ! isset($val['price'], $val['qty']))
Rick Ellis98783322009-02-17 02:29:44 +0000397 {
398 continue;
399 }
400
Andrey Andreevbb248832011-12-21 16:42:51 +0200401 $this->_cart_contents['cart_total'] += ($val['price'] * $val['qty']);
402 $this->_cart_contents['total_items'] += $val['qty'];
Rick Ellisdf39d512009-02-24 22:29:37 +0000403 $this->_cart_contents[$key]['subtotal'] = ($this->_cart_contents[$key]['price'] * $this->_cart_contents[$key]['qty']);
Rick Ellis98783322009-02-17 02:29:44 +0000404 }
405
Andrey Andreev56454792012-05-17 14:32:19 +0300406 // Is our cart empty? If so we delete it from the session
Rick Ellis98783322009-02-17 02:29:44 +0000407 if (count($this->_cart_contents) <= 2)
408 {
409 $this->CI->session->unset_userdata('cart_contents');
Barry Mienydd671972010-10-04 16:33:58 +0200410
Rick Ellis98783322009-02-17 02:29:44 +0000411 // Nothing more to do... coffee time!
412 return FALSE;
413 }
414
415 // If we made it this far it means that our cart has data.
416 // Let's pass it to the Session class so it can be stored
417 $this->CI->session->set_userdata(array('cart_contents' => $this->_cart_contents));
418
Andrey Andreev17779d62011-12-22 13:21:08 +0200419 // Woot!
Barry Mienydd671972010-10-04 16:33:58 +0200420 return TRUE;
Rick Ellis98783322009-02-17 02:29:44 +0000421 }
422
423 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200424
Rick Ellis98783322009-02-17 02:29:44 +0000425 /**
426 * Cart Total
427 *
Andrey Andreev6f042cc2012-03-26 14:58:33 +0300428 * @return int
Rick Ellis98783322009-02-17 02:29:44 +0000429 */
Andrey Andreevbb248832011-12-21 16:42:51 +0200430 public function total()
Rick Ellis98783322009-02-17 02:29:44 +0000431 {
Rick Ellisdf39d512009-02-24 22:29:37 +0000432 return $this->_cart_contents['cart_total'];
Rick Ellis98783322009-02-17 02:29:44 +0000433 }
Andrey Andreevbb248832011-12-21 16:42:51 +0200434
Andrew Seymourf75ec112011-12-14 09:36:39 +0000435 // --------------------------------------------------------------------
Andrey Andreevbb248832011-12-21 16:42:51 +0200436
Andrew Seymourf75ec112011-12-14 09:36:39 +0000437 /**
438 * Remove Item
439 *
440 * Removes an item from the cart
441 *
Timothy Warren86611db2012-04-27 10:06:25 -0400442 * @param int
Andrey Andreev6f042cc2012-03-26 14:58:33 +0300443 * @return bool
Andrew Seymourf75ec112011-12-14 09:36:39 +0000444 */
445 public function remove($rowid)
446 {
Andrey Andreevbb248832011-12-21 16:42:51 +0200447 // unset & save
Andrew Seymourf75ec112011-12-14 09:36:39 +0000448 unset($this->_cart_contents[$rowid]);
Andrew Seymourf75ec112011-12-14 09:36:39 +0000449 $this->_save_cart();
Andrey Andreevbb248832011-12-21 16:42:51 +0200450 return TRUE;
Andrew Seymourf75ec112011-12-14 09:36:39 +0000451 }
Andrey Andreevbb248832011-12-21 16:42:51 +0200452
Rick Ellis98783322009-02-17 02:29:44 +0000453 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200454
Rick Ellis98783322009-02-17 02:29:44 +0000455 /**
456 * Total Items
457 *
458 * Returns the total item count
459 *
Andrey Andreev6f042cc2012-03-26 14:58:33 +0300460 * @return int
Rick Ellis98783322009-02-17 02:29:44 +0000461 */
Andrey Andreevbb248832011-12-21 16:42:51 +0200462 public function total_items()
Rick Ellis98783322009-02-17 02:29:44 +0000463 {
464 return $this->_cart_contents['total_items'];
465 }
466
467 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200468
Rick Ellis98783322009-02-17 02:29:44 +0000469 /**
470 * Cart Contents
471 *
472 * Returns the entire cart array
473 *
Timothy Warren86611db2012-04-27 10:06:25 -0400474 * @param bool
Rick Ellis98783322009-02-17 02:29:44 +0000475 * @return array
476 */
Andrey Andreevbb248832011-12-21 16:42:51 +0200477 public function contents($newest_first = FALSE)
Rick Ellis98783322009-02-17 02:29:44 +0000478 {
Andrew Seymourde2e96a2011-12-13 16:44:59 +0000479 // do we want the newest first?
Andrey Andreevbb248832011-12-21 16:42:51 +0200480 $cart = ($newest_first) ? array_reverse($this->_cart_contents) : $this->_cart_contents;
Barry Mienydd671972010-10-04 16:33:58 +0200481
Rick Ellis98783322009-02-17 02:29:44 +0000482 // Remove these so they don't create a problem when showing the cart table
483 unset($cart['total_items']);
484 unset($cart['cart_total']);
Barry Mienydd671972010-10-04 16:33:58 +0200485
Rick Ellis98783322009-02-17 02:29:44 +0000486 return $cart;
487 }
488
489 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200490
Rick Ellis98783322009-02-17 02:29:44 +0000491 /**
Andrey Andreevcdeee662012-10-25 17:29:52 +0300492 * Get cart item
493 *
494 * Returns the details of a specific item in the cart
495 *
496 * @param string $row_id
497 * @return array
498 */
499 public function get_item($row_id)
500 {
501 return (in_array($row_id, array('total_items', 'cart_total'), TRUE) OR ! isset($this->_cart_contents[$row_id]))
502 ? FALSE
503 : $this->_cart_contents[$row_id];
504 }
505
506 // --------------------------------------------------------------------
507
508 /**
Rick Ellis98783322009-02-17 02:29:44 +0000509 * Has options
510 *
511 * Returns TRUE if the rowid passed to this function correlates to an item
512 * that has options associated with it.
513 *
Andrey Andreevcdeee662012-10-25 17:29:52 +0300514 * @param string $row_id = ''
Andrey Andreevbb248832011-12-21 16:42:51 +0200515 * @return bool
Rick Ellis98783322009-02-17 02:29:44 +0000516 */
Andrey Andreevcdeee662012-10-25 17:29:52 +0300517 public function has_options($row_id = '')
Rick Ellis98783322009-02-17 02:29:44 +0000518 {
Andrey Andreevcdeee662012-10-25 17:29:52 +0300519 return (isset($this->_cart_contents[$row_id]['options']) && count($this->_cart_contents[$row_id]['options']) !== 0);
Rick Ellis98783322009-02-17 02:29:44 +0000520 }
521
522 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200523
Rick Ellis98783322009-02-17 02:29:44 +0000524 /**
525 * Product options
526 *
527 * Returns the an array of options, for a particular product row ID
528 *
Andrey Andreevcdeee662012-10-25 17:29:52 +0300529 * @param string $row_id = ''
Rick Ellis98783322009-02-17 02:29:44 +0000530 * @return array
531 */
Andrey Andreevcdeee662012-10-25 17:29:52 +0300532 public function product_options($row_id = '')
Rick Ellis98783322009-02-17 02:29:44 +0000533 {
Andrey Andreevcdeee662012-10-25 17:29:52 +0300534 return isset($this->_cart_contents[$row_id]['options']) ? $this->_cart_contents[$row_id]['options'] : array();
Rick Ellis98783322009-02-17 02:29:44 +0000535 }
Rick Ellisdf39d512009-02-24 22:29:37 +0000536
537 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200538
Rick Ellisdf39d512009-02-24 22:29:37 +0000539 /**
540 * Format Number
541 *
542 * Returns the supplied number with commas and a decimal point.
543 *
Andrey Andreev6f042cc2012-03-26 14:58:33 +0300544 * @param float
Andrey Andreevbb248832011-12-21 16:42:51 +0200545 * @return string
Rick Ellisdf39d512009-02-24 22:29:37 +0000546 */
Andrey Andreevbb248832011-12-21 16:42:51 +0200547 public function format_number($n = '')
Rick Ellisdf39d512009-02-24 22:29:37 +0000548 {
Alex Bilbied261b1e2012-06-02 11:12:16 +0100549 return ($n === '') ? '' : number_format( (float) $n, 2, '.', ',');
Rick Ellisdf39d512009-02-24 22:29:37 +0000550 }
Barry Mienydd671972010-10-04 16:33:58 +0200551
Rick Ellis98783322009-02-17 02:29:44 +0000552 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200553
Rick Ellis98783322009-02-17 02:29:44 +0000554 /**
555 * Destroy the cart
556 *
557 * Empties the cart and kills the session
558 *
Andrey Andreevbb248832011-12-21 16:42:51 +0200559 * @return void
Rick Ellis98783322009-02-17 02:29:44 +0000560 */
Andrey Andreevbb248832011-12-21 16:42:51 +0200561 public function destroy()
Rick Ellis98783322009-02-17 02:29:44 +0000562 {
Andrey Andreevbb248832011-12-21 16:42:51 +0200563 $this->_cart_contents = array('cart_total' => 0, 'total_items' => 0);
Rick Ellis9c86ce52009-02-17 19:54:14 +0000564 $this->CI->session->unset_userdata('cart_contents');
Rick Ellis98783322009-02-17 02:29:44 +0000565 }
566
Rick Ellis98783322009-02-17 02:29:44 +0000567}