Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

The cart

The cart is the WC()->cart object of the WC_Cart class. It keeps items in the visitor's session and recalculates the total on every change. The cart exists only on site pages: it is absent in the admin panel and in background jobs.

Where to write the code

Create the includes/cart.php file and include it in acme-shop.php.

Reading the cart

// wp-content/plugins/acme-shop/includes/cart.php
add_action('wp_footer', function () {
    if (!WC()->cart || WC()->cart->is_empty()) {
        return;
    }
 
    printf(
        '<p class="acme-cart-line">Items in the cart: %d, subtotal %s</p>',
        WC()->cart->get_cart_contents_count(),
        wc_price(WC()->cart->get_subtotal())
    );
});

The wp_footer hook fires at the end of every site page. Put the mug into the cart — the line Items in the cart: 1, subtotal €9.90 appears at the bottom of any page.

Items

get_cart() returns an array of items. The array key is a string unique to the item:

// wp-content/plugins/acme-shop/includes/cart.php
add_action('wp_footer', function () {
    if (!WC()->cart) {
        return;
    }
 
    foreach (WC()->cart->get_cart() as $key => $item) {
        $product = $item['data'];
 
        printf(
            '<p>%s × %d = %s</p>',
            esc_html($product->get_name()),
            $item['quantity'],
            wc_price($item['line_total'])
        );
    }
});
Item fieldWhat it holds
dataThe WC_Product object
product_idThe product ID
variation_idThe variation ID or 0
quantityThe quantity
line_totalThe line total after discounts

Cart methods

MethodWhat it does
add_to_cart($productId, $qty)Adds a product, returns the item key or false
remove_cart_item($key)Removes an item
set_quantity($key, $qty)Changes the quantity
empty_cart()Empties the cart
get_cart_contents_count()The number of product units
get_subtotal()The products total without shipping
get_total('edit')The total as a number
is_empty()Whether the cart is empty

Adding in code

The ready-made link /?add-to-cart=12 puts product 12 into the cart with no code. A set of several products is added by hand:

// wp-content/plugins/acme-shop/includes/cart.php
add_action('template_redirect', function () {
    if (!isset($_GET['acme_kit'])) {
        return;
    }
 
    WC()->cart->add_to_cart(12, 2);
    WC()->cart->add_to_cart(18, 2);
 
    wp_safe_redirect(wc_get_cart_url());
    exit;
});

Open the address /?acme_kit=1: two mugs and two plates go into the cart and the cart page opens. A variation is added with a third argument, its ID: add_to_cart(15, 1, 87).

Removing

foreach (WC()->cart->get_cart() as $key => $item) {
    if ($item['product_id'] === 18) {
        WC()->cart->remove_cart_item($key);
    }
}

Items are removed by the item key, not by the product ID: one product can sit in the cart as several items.

Validation on adding

// wp-content/plugins/acme-shop/includes/cart.php
add_filter('woocommerce_add_to_cart_validation', function (bool $passed, int $productId, int $quantity): bool {
    if ($quantity > 5) {
        wc_add_notice('No more than five of one product at a time.', 'error');
 
        return false;
    }
 
    return $passed;
}, 10, 3);

Enter a quantity of 6 on a product page and press Add to cart: the product is not added and a red message appears at the top of the page. wc_add_notice() shows a message to the customer; the types are success, error, notice.

Common mistake

WC()->cart is accessed in an admin hook or a background job, and the result is a call to a member function on null error. The cart is created only for a site visitor. If a hook can fire anywhere, start the function with the check if (!WC()->cart) return;.

Thanks for reading!

Donate to the site — we work hard for you.