Skip to content

Instantly share code, notes, and snippets.

@elivz
Created July 22, 2012 20:27
Show Gist options
  • Save elivz/3160987 to your computer and use it in GitHub Desktop.
Save elivz/3160987 to your computer and use it in GitHub Desktop.
Exp:resso Store discount extension
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Store Discount Extension
*
* @package ExpressionEngine
* @subpackage Addons
* @category Extension
* @author Eli Van Zoeren
* @link http://elivz.com
*/
class Store_discount_ext {
public $settings = array();
public $description = 'Apply quantity-based discounts to Exp:resso Store';
public $docs_url = 'http://elivz.com';
public $name = 'Store Discount';
public $settings_exist = 'n';
public $version = '1.0';
private $EE;
/**
* Constructor
*
* @param mixed Settings array or empty string if none exist.
*/
public function __construct($settings = '')
{
$this->EE =& get_instance();
$this->settings = $settings;
}
// ----------------------------------------------------------------------
/**
* Activate Extension
*
* This function enters the extension into the exp_extensions table
*
* @see http://codeigniter.com/user_guide/database/index.html for
* more information on the db class.
*
* @return void
*/
public function activate_extension()
{
// Setup custom settings in this array.
$this->settings = array();
// Add hooks
$data = array(
'class' => __CLASS__,
'method' => 'update_cart',
'hook' => 'store_cart_update_end',
'settings' => serialize($this->settings),
'priority' => 10,
'version' => $this->version,
'enabled' => 'y'
);
$this->EE->db->insert('extensions', $data);
}
// ----------------------------------------------------------------------
/**
* Disable Extension
*
* This method removes information from the exp_extensions table
*
* @return void
*/
function disable_extension()
{
$this->EE->db->where('class', __CLASS__);
$this->EE->db->delete('extensions');
}
// ----------------------------------------------------------------------
/**
* Update Extension
*
* This function performs any necessary db updates when the extension
* page is visited
*
* @return mixed void on update / false if none
*/
function update_extension($current = '')
{
if ($current == '' OR $current == $this->version)
{
return FALSE;
}
$this->EE->db->where('class', __CLASS__);
$this->EE->db->update(
'extensions',
array('version' => $this->version)
);
}
// ----------------------------------------------------------------------
/**
* Responds to the store_cart_update_end hook in Exp:resso Store
* to apply a discount to each product, as needed
*
* @return array of cart items
*/
function update_cart($cart_contents)
{
$this->EE->load->helper(array('store'));
// Get the number of products currently in the user's cart
$count = count($cart_contents['items']);
// Only apply the discount if there is more than one item
if ($count > 1)
{
// Take $10 off all but the first product
// This calculation can easily be adjusted as needed
$discount = ($count - 1) * 10;
// Add the quantity discount to any existing discount (promo code)
$cart_contents['order_discount_val'] += $discount;
// Make sure we don't end up with a negative total
if ($cart_contents['order_discount_val'] > $cart_contents['order_subtotal_val'])
{
$cart_contents['order_discount_val'] = $cart_contents['order_subtotal_val'];
}
$cart_contents['order_discount'] = store_format_currency($cart_contents['order_discount_val']);
// Update the cart total to reflect the new discount
$cart_contents['order_total_val'] = $cart_contents['order_subtotal_val'] - $cart_contents['order_discount_val'];
$cart_contents['order_total'] = store_format_currency($cart_contents['order_total_val']);
}
return $cart_contents;
}
}
/* End of file ext.store_discount.php */
/* Location: /system/expressionengine/third_party/store_discount/ext.store_discount.php */
@elivz
Copy link
Author

elivz commented Jul 26, 2012

Right... this is a starting point for developing your own discount extension. If you need a click-and-play interface for discounts, you'll probably need to wait until Exp:resso adds it to Store, or use a different e-commerce add-on (CartThrob has very flexible discounting, although at the expense of a more complex system all around).

@since1976
Copy link

Yeah I really should start learning as it will make things a lot easier.
Thanks for this extension Eli it will work as a great starting point. I will ask a mate of mine to have a look and show me how we can extend the code to what I need. I will gist the result when it is done.

Cheers
Dan

@amacneil
Copy link

Dan.. try something like this (untested, may be some slight errors):

foreach ($cart_contents['items'] as $item)
{
    if ($item['item_qty'] >= 3)
    {
         $cart_contents['order_discount_val'] += 10;
    }
}

then add the rest of the code from above:

        if ($cart_contents['order_discount_val'] > $cart_contents['order_total_val'])
            $cart_contents['order_discount_val'] = $cart_contents['order_total_val'];
        $cart_contents['order_discount'] = store_format_currency($cart_contents['order_discount_val']);

        // Update the cart total to reflect the new discount
        $cart_contents['order_total_val'] = $cart_contents['order_subtotal_val'] - $cart_contents['order_discount_val'];
        $cart_contents['order_total'] = store_format_currency($cart_contents['order_total_val']);

        return $cart_contents;

That should add a $10 discount for every item which has qty >= 3. Notice all the variables are exactly the same as what you use in the template (item_qty, order_total etc).

@since1976
Copy link

Works great thanks guys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment