Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

The cart

The cart is the list of products a visitor is going to buy. In code it is the object $this->cart, available on the storefront. Through it an extension finds out what is in the cart and how much it costs, and can add or remove products.

Where it lives

WhatWhere
The classsystem/library/cart/cart.php
The dataTable oc_cart, one row per position
The cart pageindex.php?route=checkout/cart

A position is tied to the session of a guest or to the customer, so after login the cart is kept.

Reading the cart

// extension/acme_hello/catalog/controller/module/acme_hello.php, in index()
$data['cart_count'] = $this->cart->countProducts();
$data['cart_total'] = $this->currency->format($this->cart->getTotal(), $this->session->data['currency']);

Print both variables in the module template. Add a product to the cart on the storefront and reload the home page — the module shows the number of items and their sum.

Positions

foreach ($this->cart->getProducts() as $product) {
    $data['items'][] = [
        'name' => $product['name'],
        'quantity' => $product['quantity'],
        'total' => $this->currency->format($product['total'], $this->session->data['currency']),
    ];
}

Each position is an array: cart_id, product_id, quantity, the price for one unit price and for the whole position total, the chosen options. The price already takes into account options, discounts and special offers. The exact set of keys differs between releases 4.0 and 4.1 — print the array once with $this->log->write(print_r($product, true)) and look at it in the error log.

Methods

MethodWhat it does
add($productId, $quantity, $option)Adds a product
update($cartId, $quantity)Changes the quantity of a position
remove($cartId)Removes a position
clear()Empties the cart
getProducts()Positions with prices and options
countProducts()Total number of items
getSubTotal()Sum without tax
getTotal()Sum with tax
getWeight()Total weight
hasProducts()Whether the cart is not empty
hasShipping()Whether any product needs delivery
hasStock()Whether everything is in stock

update() and remove() take the id of the position cart_id, not the id of the product: the same product with different options is two positions.

Adding from code

$this->cart->add(42, 2);

Two units of the product 42 appear in the cart. The third argument is the chosen options — an array where the key is the id of the product option and the value is the id of the chosen value.

Adding from a form

A button «Add to cart» in your template does not need your own controller. The form is sent to the core route, which checks the minimum quantity, the required options and the stock:

<form action="{{ add_to_cart }}" method="post" data-oc-toggle="ajax" data-oc-load="{{ cart }}" data-oc-target="#cart">
  <input type="hidden" name="product_id" value="42">
  <input type="hidden" name="quantity" value="1">
  <button type="submit" class="btn btn-primary">{{ button_cart }}</button>
</form>

add_to_cart is the link to checkout/cart.add, and cart is the link to common/cart.info — the block in the header that is reloaded after adding. Product forms in the core templates are built the same way.

Common mistake

$this->cart->add() is called directly for a product with required options or a minimum quantity. The library does not check anything: the position gets into the cart, and the error appears only at checkout. From code add only products you know for sure, and for a button on a page use the core route checkout/cart.add.

Thanks for reading!

Donate to the site — we work hard for you.