The shopping cart object allows you to create a custom class to configure the cart. If you are happy with the defaults used by the shopping cart object you do not require such a class. Certain configurations can also be applied by page handlers used to add items to the cart rather than using a dedicated cart configuration class. Nevertheless, if you have several page handers to manage different card items it is cleaner to code the configurations in a dedicated class in order to reduce code redundancy and improve efficiency.

Changing the Cart Language or Terminology

If you wish to change the textual content of the shopping cart you should create a translation specification under the name cart. To do so, start by launching the translation model then use the command "example cart" to pull in the definitions expected by the cart object. If you are translating these into a different language you might want to do so under the system pseudo site so that your translations can be used by any site.

Defining a Cart Configuration Class

Cart config classes are created using the php_class model and must be named cart_config. If such a class is present in the current site's class folder it will be called automatically when the cart object is first created. If this class defines a set_site method this method will be called first passing it the current site object. Next, the configure_cart method will be called and it will be passed a reference to the cart object. To create this class you can launch the php_class model and use the command "example cart_config" to load sample code that shows all possible settings. 

In the following sections we describe the various configuration options that can be set within the configure_cart method. For all options, the actual method that is called is set_{option}.

checkout_link

Call the set_checkout_link method If you wish to change the appearance of the checkout button or the name of the checkout page. Normally you would pass the output from a dollar function such as $image_link or $link_buttons to this function.  Here we show how the default checkout link is configured:

$checkout_button = array('orientation' => 'h', 'size' => 'medium', 'color' => 'green', 'button_style' => 'filed', 'pageid' => array('checkout'));
$checkout_link = $this->site->dollar_function('link_buttons',$checkout_button);

Suppose you wanted to use an image as your checkout link, you could define an image that assigns the *page property to refer to your checkout page. Then you could use the $imagelink fimction to generate your checkout link as follows:

function configure_cart($cart) {
	$checkout_button = $this->site->dollar_function('imagelink','checkout-button')
	$cart->set_checkout_link($checkout_button);
}

In the following examples we don't show that the calls are within the context of the configure_cart method however this is where the cart object's methods would normally be called.

remove_link

To rebuild the default remove link your code would look something like the following:

$remove_button = '<input type="submit" name="remove" class="tiny red button auto filed" '.
  'onclick="this.form.button_pressed.value = this.name;" value="&#x2718;" '.
  'title="Select the items to be removed and click here to remove them from the cart" />';
$cart->set_remove_link($remove_button);

Note that the link or button must be named remove and it must submit the form. It must also assign the form field named button_pressed the value remove when the button is pressed.

currency_code

Use this method to set the desired cart currency. You can set this to any of the currency values defined within the specification named currency_formats defined within system. This is a specification of type php_array_data.

Here we show how you would set the cart currency to Euros:

  $cart->set_currency_code('EUR');

If the currency you wish to use is not defined within the supplied list of currency formats you have three options.

1. Override the currency_formats by Creating a Local Version

You can create a local copy of the currency_formats class by following these steps:

  1. Edit the php_array_data model.
  2. Use the command "example currency_formats" to load some sample currencies.
  3. Change the currency definition rows to the ones you want your cart to support.
  4. Stow the definition as currency_formats.

Your custom currency_formats will now take precedence over those defined in system.

2. Pass Your Currency Definition to the set_currency Method  

Here we show an example of passing the currency settings in parameter two of the set_currency method.

// Configure the Indonesian rupiah
$rupiah = array (
    'decimals' => 0,
    'symbol_before' => 'Rp',
    'separator_before' => '',
    'thousands' => ',',
    'decimal' => '',
    'separator_after' => '',
    'symbol_after' => '');
  $cart->set_currency_code('IDR',$rupiah);

3. Update the currency_formats Definied in System

You are free to add new currencies to the supplied currency definitions in system. Be aware that if you upgrade to a new version of GenHelm it will be necessary to ensure that any customizations you make to the framework are reapplied.

Setting the Currency Later

Sometimes you may not know the currency of your cart at the time the cart is configured. For example you may designate the currency later in the checkout process once you know where the customer's order will be shipped. In such a case, you can pick a default currency when configuring your cart and change it later once the currency can be established.

Handling Currency Locales

Some currency representations differ depending on the user's locale. For example, in the Canadian province of  Qu├ębec, one thousand dollars would be shown as "1.000,00 $" whereas in the other Canadian provinces this would be rendered as "$1,000.00". If you want to offer this level of specificity you will need to ascertain the user's location or currency preference and set the site object's locale accordingly.  For example:

if ($_SESSION['billing_province'] == 'QC') {
  $this->site->set_locale('fr-CA');
}
else {
  $this->site->set_locale('en-CA');
}
$cart->set_currency_code('CAD');

valid_currencies

If you want to allow the user to change the desired currency as part of the cart functionality, call the set_valid_currencies method of the cart object as shown here:

$cart->set_valid_currencies(array('USD'=>'US Dollars','CAD'=>'Canadian Dollars'));

This will cause a currency selection field to appear in the cart next to the total value as we see in the sample screen below.

Cart with currency selector

When using this method, the currency codes provided must be defined within the currency_formats definition. If your cart supports multiple currencies, the price returned by the get_price method should reflect the price in the current currency (as indicated by the item's currency_code property). Whenever the currency is changed, the cart will invoke the set_currency_code method of all cart items to update the currency_code to the newly selected currency.  After setting the currency, the cart will call the get_price method for each item in order to get the price which reflects the current currency setting.

The cart item object is responsible for determining how to perform any required currency conversion. In the code sample below, you can see that the item object uses $boc_fx in the initialize method to obtain the USD/CAD conversion rate from the previous day. The initialize method is called only once when the item_object is first created, this call occurs after setting the currency_code in case this is needed as part of the initialization processing.

In the example, the get_price method is overridden from what is in the base class so that it can set a price which reflects the current currency code. 

function initialize() {
	// Establish a USD/CAD conversion rate .75% above the previous days Bank of Canada  rate
	$this->conversion_rate = floatval($this->site->dollar_function('boc_fx','USD','CAD',.75));
}

function get_price() {
	if ($this->currency_code == 'USD') {
		return $this->price;
	}
	else {
		return round($this->price * $this->conversion_rate,2);
	}
}

show_currency

This option allows you to show the name of the currency. This can be shown in the summary area above the cart, at the bottom of the cart or in both locations. In this example we show the currency within the cart area.

$cart->set_show_currency('cart');

Use value "summary" to show the currency only in the summary area, use "always" to show the currency in both locations or "no" to not show the currency at all.

show_currency_symbol

Most currencies use special symbols either before or after the amount to indicate that the number reflects a currency value. This option can be set to one of the following values:

noDon't show the currency for any of the amounts.
always Show the currency for all of the item and total amounts.
totalOnly show the currency on the total amount.

Here we set this option to show the symbol for all amounts:

$cart->set_show_currency_symbol('always');

show_all_item_properties

This option is only set to true during debugging. This causes the cart to show some hidden item properties, such as the item type, weight and cost, that are not normally shown.

include_total_above_cart

By default, a cart summary is shown above the cart area. If you don't want this, set this option to false.

cart_icon

This can be used to change the shopping cart icon that is used in the summary area and when the $cart(total,page_name) option is used. 

notify_item_of_removal

Sometimes you may need to take certain action when the user removes an item from their cart. For example, you may have temporarily held an item in inventory when the user added the item to their cart. When they decide to remove the item you may want to release this hold. To handle this sort of requirement you must define a before_removal method in your item object(s). When notify_item_of_removal is set to true your item objects will be instantiated before they are removed from the cart and the before_removal method will be called. This method is passed the cart item number being removed.

Overriding Item Behavior

Recall that, when adding items to a cart, one of the properties of an item is its type. This type value can be referenced to adjust the behavior of items of a certain type. Behavior is adjusted by calling the following method of the cart object:

$cart->set_item_behavior($type_value,$behavior_array);

The second parameter is a keyed array that may define one or more of the following keys:

single

This is a boolean value that defaults to false. For certain types of items it does not make sense to have several instances in the cart. For example, let's say you only sell one type of product however the customer has the option of adding an extended warranty for the product to their cart. You could prevent several extended warrantees from being added to the cart by setting the value of the single behavior to true.

hide_zero

This is a boolean value. When set to true an item will not appear in the cart if its price is zero.  By default items will be shown in the cart even if their price is zero provided the quantity is non-zero.

removable

This is a boolean value that defaults to true. Sometimes you want to programmatically add items to the cart which you don't want the user to be allowed to remove. For example, if you have calculated shipping charges for an item to be purchased and added this to the cart, you don't want the user to be allowed to delete these charges.

include_item_in_count

Recall that the cart can include a summary gadget which indicates how many items are in the cart. This behavior setting determines how many items will be added to the item total for items of the specified type. For example, if a hardware store sells a customer a hammer and 30 nails, should this be shown as 31 items or 2 items?  Similarly, if shipping charges are added to the cart, should this be considered as an item? Let's review the various values that this behavior can be set to:

'quantity'

This is the default setting. The full quantity ordered for items of the specified type will contribute to the item total.

'quantity_if_charged'

This is similar to 'quantity' except nothing will be added to the item total for items whose price is zero.

1

Only 1 will be added to the item total regardless of the number of items ordered.

'1_if_charged'

This is similar to 1 except nothing will be added to the item total for items whose price is zero. 

false

With this setting, the item will not contribute to the item total.

Behavior Example

Here we use the behavior settings to hide free shipping as a cart item and to not include shipping in the item total (even when it is not free).

function configure_cart($cart) {
	$behavior['single'] = true;  // Only allow 1 item of this type in the cart
	$behavior['hide_zero'] = true;  // Don't show the item if qty or price is zero
	$behavior['include_in_item_count'] = false;  // Don't count in item total.
	$behavior['removable'] = false;  // Don't allow shipping charges to be removed by the user.
	$cart->set_item_behavior('shipping',$behavior);
}

Reconfiguring the Cart

By default, the cart_config class will only be called once, at the time the cart is first loaded. This can make it difficult to test and alter your cart_config class without restarting your session. To make this easier you can add cart_config=1 to the query string of your cart page. If this is the only query string item you will use ?cart_config=1. If there are other items already in the query string you will add &cart_config=1.

Using the Cart Without the $cart Function

We have described how you can add the $cart function to your page to allow users to interact with the cart. It is also possible to simply add items programmatically. Here we show how you can:

  1. Instantiate and configure the cart
  2. Ask the cart to create an item object
  3. Set the properties of the item
  4. Commit the item to the cart
// Instantiate the cart
$cart = $this->site->create_object('cart','',true);
// Configure the cart to support a single item of type license
$cart->set_currency_code($currency);
$cart->set_show_currency('always');
$behavior['single'] = true;  // Only allow 1 item of this type in the cart
$behavior['include_in_item_count'] = 1;  // Count as 1 item
$behavior['removable'] = false;  // Don't allow lisense count to be removed
$cart->set_item_behavior('license',$behavior);
// Have the cart instanciate an item handler (class) named product_license and return the object
$license_obj = $cart->create_pending_object('product_license','genhelm-license','license');
// Use the quantity field to reflect the number of developers to be licensed
$license_obj->set_quantity($developers);
// Commit the item to the cart
$cart->commit_pending_object();