[eluser]snoo[/eluser]
Hi all,
Due to my items setup configuration, which is to list every possible attribute for an item as an individual item, I need to let my cart->update() accept new options and prices. Essentially, cart->update() becomes remove, then add new item to cart. Also added sorting so I can maintain the cart item order. So I tried to extend the cart library. Everything is working fine, but this is the first time I write extension, please let me know if I'm doing this right. Following in my code, thanks much for any input!
Code:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class MY_Cart extends CI_Cart {
function __construct(){
parent::__construct();
// accept () and * in item name
$this->product_name_rules = '\*\(\)\-_ a-z0-9';
}
function _update($items = array())
{
// Without these array indexes there is nothing we can do
if ( ! isset($items['qty']) OR ! isset($items['rowid']) OR ! isset($this->_cart_contents[$items['rowid']]))
{
return FALSE;
}
// create new rowid
if (isset($items['options']) AND count($items['options']) > 0)
{
$rowid = md5($items['id'].implode('', $items['options']));
}
else
{
// No options were submitted so we simply MD5 the product ID.
// Technically, we don't need to MD5 the ID in this case, but it makes
// sense to standardize the format of array indexes for both conditions
if(isset($items['id']))
{
$rowid = md5($items['id']);
}
}
if(isset($rowid))
{
// save current cart item
$current_cart_item = $this->_cart_contents[$items['rowid']];
// save current order
$current_order = $this->_preserve_cart_order($this->_cart_contents);
// remove current cart with old rowid
unset($this->_cart_contents[$items['rowid']]);
// create new array with new rowid
$this->_cart_contents[$rowid] = $current_cart_item;
// return order key with old rowid
$order_key = array_search($items['rowid'], $current_order);
// replace old rowid with new rowid in order array
$current_order[$order_key] = $rowid;
// reorder cart
$this->_cart_contents = $this->_restore_cart_order($this->_cart_contents, $current_order);
}
else
{
$rowid = $items['rowid'];
}
if(isset($items['price'])){
// Prep the price. Remove anything that isn't a number or decimal point.
$items['price'] = trim(preg_replace('/([^0-9\.])/i', '', $items['price']));
// Trim any leading zeros
$items['price'] = trim(preg_replace('/(^[0]+)/i', '', $items['price']));
// Is the price a valid number?
if ( ! is_numeric($items['price']))
{
log_message('error', 'An invalid price was submitted for product ID: '.$items['id']);
return FALSE;
}
else
{
$this->_cart_contents[$rowid]['price'] = $items['price'];
}
}
// Prep the quantity
$items['qty'] = preg_replace('/([^0-9])/i', '', $items['qty']);
// Is the quantity a number?
if ( ! is_numeric($items['qty']))
{
return FALSE;
}
// Is the new quantity different than what is already saved in the cart?
// If it's the same there's nothing to do
if ($this->_cart_contents[$rowid]['qty'] == $items['qty'])
{
return FALSE;
}
// Is the quantity zero? If so we will remove the item from the cart.
// If the quantity is greater than zero we are updating
if ($items['qty'] == 0)
{
unset($this->_cart_contents[$rowid]);
}
else
{
$this->_cart_contents[$rowid]['qty'] = $items['qty'];
}
return TRUE;
}
function _preserve_cart_order($cart)
{
$cart_order = array();
foreach($cart as $key=>$index)
{
$cart_order[] = $key;
}
return $cart_order;
}
function _restore_cart_order($cart,$cart_order)
{
$ordered = array();
foreach($cart_order as $key)
{
if(array_key_exists($key,$cart))
{
$ordered[$key] = $cart[$key];
unset($cart[$key]);
}
}
return $ordered + $cart;
}
}