Skip to content
← All writing

Episode 7 – WordPress Plugin Development with WooCommerce

The cart notice

Now the second feature. Above the cart we print:

Spend $12.00 more and get FREE shipping!

Step 1. Make the file

cd "/Users/sejim/Local Sites/simple-boards/app/public/wp-content/plugins/order-boost"
touch includes/class-orb-shipping-notice.php

Step 2. Type the class

<?php
/**
 * The free shipping notice on the cart page.
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class ORB_Shipping_Notice {

	public function __construct() {
		add_action( 'woocommerce_before_cart', array( $this, 'render_notice' ) );
	}
}

woocommerce_before_cart rings one time, at the top of the cart page, before the table of items.

Step 3. Type the method

Add this inside the class:

	public function render_notice() {

		if ( 'yes' !== get_option( 'orb_notice_enabled', 'yes' ) ) {
			return;
		}

		$threshold = (float) get_option( 'orb_threshold', 50 );
		$subtotal  = (float) WC()->cart->get_subtotal() - (float) WC()->cart->get_discount_total();
		$remaining = $threshold - $subtotal;

		if ( $remaining > 0 ) {
			wc_print_notice(
				sprintf( 'Spend %s more and get FREE shipping!', wc_price( $remaining ) ),
				'notice'
			);
		} else {
			wc_print_notice( 'Nice! You qualify for FREE shipping.', 'success' );
		}
	}

WC() is WooCommerce itself, in one object. WC()->cart is the cart of the person on the page right now.

get_subtotal() is the price of the items, before shipping and before tax.

get_discount_total() is what the coupons took off. We remove it, because a person with a 20 dollar coupon has not really spent 50.

(float) on both. The values arrive as text in some setups. Maths on text gives strange results.

wc_price() turns 12 into $12.00. It uses the shop currency, the symbol position, and the decimal settings. Never format money by hand.

wc_print_notice() prints a message in the WooCommerce style box. The second value is the type. Use notice for grey, success for green, error for red.

Step 4. Load it

In order-boost.php:

require_once ORB_DIR . 'includes/class-orb-shipping-notice.php';

And inside orb_init:

	new ORB_Shipping_Notice();

Step 5. Test

  1. Add one cheap product to the cart.
  2. Open the cart page.

You see the grey box: Spend $38.00 more and get FREE shipping!

Now add more products until the subtotal passes 50. Reload. The box turns green.

Change the threshold in WooCommerce > Order Boost to 10 and save. Reload the cart. The maths follows your setting.

Step 6. Do not nag the wrong people

If the customer already chose free shipping, our message is noise. Add this after the first check:

		$chosen_methods = WC()->session ? WC()->session->get( 'chosen_shipping_methods' ) : null;
		$chosen         = ( is_array( $chosen_methods ) && ! empty( $chosen_methods ) ) ? $chosen_methods[0] : '';

		if ( false !== strpos( (string) $chosen, 'free_shipping' ) ) {
			return;
		}

The session is the customer’s short term memory on your shop. It holds the cart, the chosen shipping, and the notices. It lives for that one visitor.

Note WC()->session ?. On some pages the session does not exist yet, and asking it a question would be fatal. We check first, the same way we checked $product in Episode 5.

The trap you must know

Your cart page is either the old shortcode [woocommerce_cart], or the new Cart block.

woocommerce_before_cart only rings on the shortcode version. On the block, it never rings. Your notice does not show, and there is no error.

This is one of the most common WooCommerce tickets today. The plugin works on your test site and shows nothing on theirs. The difference is one page.

How to check on any site:

  1. Open Pages and edit the Cart page.
  2. Look for a block called Cart, or for the text [woocommerce_cart].

If it is the block, that plugin needs different code. That is not our job today, but you must be able to name the cause.

Break it on purpose

Set the threshold to a word:

abc

Save, then reload the cart. The message says Spend $0.00 more, and the green box never comes.

(float) 'abc' is 0. No warning, no error. Just a silly message on a live shop.

That is a hole in our save code. We accept any text in that box. In the next episode we will meet the cost of holes like this, and a harder one in the sales counter.

Next episode: the “sold this week” counter. A real database query, and the cache that makes it fast.


Leave a response