WooCommerce Rental Calculator

woocommerce

A Fully Bespoke Rental Price Calculator

WooCommerce is a hugely popular free plugin for WordPress which can provide an out-of-the-box, totally functional eShop with products of varying complexity, various shipping and payment methods, and a comprehensive checkout process. For a “standard” shop selling Products, ‘vanilla’ WooCommerce is amazing – it can get you up and running insanely fast, with little to none in the way of necessary development work. But when you want WooCommerce to do something it doesn’t do, it’s time to get down and dirty with some code. It should be noted that WooCommerce has a huge community producing and maintaining plugins which provide extra or changed functionality – for the most part, desired custom functionality can be achieved with one or two well-chosen plugins. But when plugins either cost too much, don’t meet your needs, or even overreach your needs and thus become a burden on the system, the only real option is to begin writing some bespoke code to produce your feature.

At Tidy Design, I do a lot of work with WordPress and WooCommerce, and more recently I’ve delved into pushing WooCommerce’s core functionality to produce a new shop for rental products. By default, the extent of WooCommerce’s options surrounding price is being able to set a sale price – but the requirements of this site included Products which have up to four price “brackets” which are used in a custom calculation on Product pages based on a customer’s input rental period. That’s quite a leap from WooCommerce’s default behaviour!

So let’s think of what exactly is required to get this working on a basic technical level:

1: Custom Product Data; the 4 price “brackets”. This must be configurable per-Product by administrators.
2: A “rental period” input on Product pages, representing the number of weeks the customer wants to rent the Product for.
3: A magic background calculator which can return a correct price for a given Product and rental period.
4: The ability to override the price for a Product in the cart, based on what was returned by the calculator.

Adding custom data to Products is a trivial two-stage (or in WordPress terms, a two-hook) process involving adding custom inputs to “edit Product” pages, and saving the values entered when the Administrator updates the post. I won’t cover that here because it’s a very “Googleable” subject – but in case you’re wondering, the first hook (adding custom inputs, specifically to the “Product Data” general tab) is

“woocommerce_product_options_general_product_data”

, and the second is

“woocommerce_process_product_meta”

– in which you’ll use WordPress’s built-in function “update_post_meta()” to write the values to the Product.

In the same way, adding a custom input to Product pages is trivial. The hook required depends on where you want the input to go. Mine is displayed above the normal Price output, so I used the hook

“woocommerce_single_product_summary”

to output some custom HTML.

The really interesting parts here are requirements three and four – the magic calculator, and overriding the WooCommerce price. Logically, the best option for the calculator was an AJAX function which is triggered by changes in the rental period input. WordPress has a hook-based method for adding AJAX functions that can be secured properly.

The below depicts a function which should receive a Product’s ID and the desired rental period, and return a calculated price.

function calculate_rental_price() {
		$price = 0;

		//get the product price data from the post
		$product_id = $_POST['rental_period'];
		$bracket_1 = floatval(get_post_meta($product_id, 'bracket_1', true)); //bracket 1 - for <1 week rentals
		$bracket_2 = floatval(get_post_meta($product_id, 'bracket_2', true)); //bracket 2 - for rental weeks 1 -> 4
		$bracket_2 = floatval(get_post_meta($product_id, 'bracket_3', true)); //bracket 3 - for rental weeks 5 + 6
		$bracket_4 = floatval(get_post_meta($product_id, 'bracket_4', true)); //bracket 4 - for rental weeks 7+

		$num_weeks = intval($_POST["num_weeks"]); //the input rental period

		if ($num_weeks === 0) {
			$price = $bracket_1;
		}
		else {
			for ($i = 1; $i < $num_weeks + 1; $i++) {
				if ($i <= 4) {
					$price += $bracket_2;
				}
				else if ($i <= 6) {
					$price += $bracket_3;
				}
				else if ($i >= 7) {
					$price += $bracket_4;
				}
			}
		}

		echo $price; //"return" the calculated price

		//write the calculated price to the PHP session
		session_start();
		$_SESSION['weeks'] = $num_weeks;
		$_SESSION['price'] = $price;

		die(); //exit
	}
	add_action('woocommerce_ajax_get_rental_price', 'calculate_rental_price');

So, at this stage, we have custom Product data depicting the various pricing brackets for different lengths of rental, we have a custom input on the Product page which allows a customer to request rental of any length in weeks, and we have a magic AJAX calculator which will return the correct price based on that input. The last stage is to tell WooCommerce “this is the price of the Product” when it is added to the cart.

By default, WooCommerce will take a Product’s regular or sale price as the price to display in the cart (and contribute to cart totals) – so we need a way to replace it. The first consideration might be to overwrite the regular and/or sale prices of the Product so that WooCommerce can just find the calculated price in the normal way. But consider what would happen here if two customers were ordering the same product at roughly the same time – which overwrite of the Product’s price would take precedence?

Luckily, when a Product is added to the cart in WooCommerce, a new “Cart Item” structure is created to represent it. This Cart Item is separate from the original Product object, and contains the price that will be displayed. We can overwrite this to any value we like – in our case, the calculated price.

But where does the calculated price come from? In the above AJAX function, I return the price to the page (where it is displayed by JavaScript where WooCommerce normally displays the price), but I also store it in the PHP session; a place to store variables which are relevant to the current user and which you want to “carry across” different pages.

It’s generally best practise to either not use the PHP session, or make its use as temporary as possible – so before I write the cart price of the product I transfer the values out of the session and into the cart item, utilising some custom array keys so as not to interfere with anything default.

This is achieved with the hook “woocommerce_add_cart_item_data” – which is run after the construction of a Cart Item, allowing the addition or modification of associated data.

	function transfer_rental_data_from_session_to_woocommerce_session($cart_item_data, $product_id) {
		session_start();
		$new_value = array();

		if (isset($_SESSION['weeks'])) {
			//write the value as text - "Three Day Express" for a 0-week rental period, and "x week(s)" for anything else.
			$option = $_SESSION['weeks'] == 0 ? 'Three Day Express' : ($_SESSION['weeks'] . ($_SESSION['weeks'] > 1 ? ' Weeks' : ' Week'));
			$new_value = array_merge($new_value, array('rental_period' => $option));
		}
		if (isset($_SESSION['price'])) {
			$option = $_SESSION['price'];
			$new_value = array_merge($new_value, array('custom_price' => $option));
		}

		//make sure to return the correct data - maintain the original cart item data, and only merge it with the new data if there is new data
		if (empty($new_value)) {
			return $cart_item_data;
		}
		else {
			if (empty($cart_item_data)) {
				return $new_value;
			}
			else {
				return array_merge($cart_item_data, $new_value);
			}
		}

		//get rid of the PHP session data - we don't need it any more
		session_unset();
		session_destroy();
	}
	add_filter('woocommerce_add_cart_item_data','transfer_rental_data_from_session_to_woocommerce_session', 1, 2);

So now, when a Product reaches the cart, its Cart Item has two new properties containing our custom data; ‘custom_price’ and ‘rental_period’. Data stored on the Cart Item allows for default WooCommerce functionality will continue to work – for example, the “undo” button after removing an item from the cart will restore the Cart Item, any custom data included. If the values were still hanging around in the PHP session, I’d have to do some clever logic to delete and recover it. As-is, no extra work is required to maintain the custom data.

Now for actually writing the cart price, using the hook “woocommerce_before_calculate_totals”.

	function overwrite_cart_price_for_rental_products($cart_object) {
		foreach ($cart_object->cart_contents as $cart_item_key => $cart_item) {
			if (array_key_exists('custom_price', $cart_item)) {
				$cart_item['data']->price = $cart_item['custom_price'];
			}
		}
	}
	add_action('woocommerce_before_calculate_totals', 'overwrite_cart_price_for_rental_products');

Quite simple, eh? All it does is take the previously-written custom price and copies it to the Cart Item’s price property. This is where WooCommerce looks to find the price to be displayed on the cart and to be considered in the cart totals.

So that’s it! All four technical requirements are met. We have our custom Product data, a rental period input on the Product page, a magic AJAX function and a mechanism for overwriting the cart price. In practice, this allows an Administrator to set up rental products which get cheaper the longer you rent them for, and it allows the customer to specify their desired rental period for every Product they order. Utilising the hook “woocommerce_cart_item_name”, I write out the rental period for each Product in the cart.

rental-period-cart

In essence, this is such a large functional change to WooCommerce that it could very well become its own plugin. I made careful considerations through all of the customisation (beyond what you see above) to ensure that only Products tagged as “Rental” adopt these changes, so this site can still set up and sell normal Products with set prices if desired.

The fact that I was able to implement this type of change goes to credit the incredible extensibility of WordPress and WooCommerce. Naturally, WooCommerce’s developers did not consider Products that work like these in their design process – but what they did do is make the system flexible enough that the remote developer has the opportunity to make them work.

It’s this extensibility and flexibility that have made me vow to never install a WooCommerce plugin. Anything that clients want is possible to achieve with a little bit of elbow grease and some well-placed hooks – though maybe one day I’ll produce my own set of plugins to re-use my custom functionality anywhere.

Happy customising!

Jonno

We Are Recruiting!

Attention all web designers / developers based in Portsmouth, we are looking to recruit a full-time individual to join Team Tidy!

tidy-design-portsmouth-naval-club

Our office is located at the Royal Naval Club in Old Portsmouth. Here we create bespoke websites for amazing clients.

Over the past couple of months our business has evolved, we therefore need someone enthusiastic and motivated to help us take Tidy Design to the next level – Does this sound like you?

If you are a competent web design / web developer with good knowledge of CSS, HTML, JS, jQuery, PHP and MySQL then we want to hear from you this summer – please send rosie@tidydesign.com your CV / cover letter / portfolio today!

A Six-Month Review

As Rosie deals with month-end, I can’t help but look at our office white board listing 30+ tasks for us to tackle in July 2016 – Yup, its going to be a busy few weeks!

website-designer-portsmouth-mike

This year (to-date) has been pretty interesting, highly productive and also challenging for us as a company. Overall Tidy Design is seeing a good level of growth however it is very important that we maintain a certain level of quality/support during these busier periods…

I guess we all have to grow with our business/brand; we are all responsible for its evolution and must react to planned or unplanned change…

All in all it has been a fantastic six months here at Tidy Design, a massive “thank you” must go out to our clients (old and new) for making this tidy adventure possible! Another big thanks must go to Blayne, Jonathan and Rosie – team tidy rocks!

The importance of Title and Meta tags

HTML documents are not all about text and content. While the bulk of an HTML document will denote the content seen on a webpage and how that content is displayed, some of the most key facets of these documents are not shown to the user in the conventional way – instead, these elements are shown to search engines and browsers.

web-designer-in-portsmouth

Two of the most important of these “hidden” elements are the <title> and <meta> tags. Both serve to improve the general usability of search engines, and attract new traffic by way of advertising a page and its content more accurately.

<title> tags – you guessed it – define the title of a page. This will be used both by the browser (to name the tab and window), and by the search engine (to name the Search Engine Results Page entry for the page). This is your user’s first contact point with your site and should be unique and descriptive to avoid being lost in the crowd.

A great example of a unique title tag could be:

title-tag-html

<meta> tags are a little more complex. They are designed to contain “information about the information” – character encodings, geographic locations, authors and many more fields can be defined with a meta tag. One of the most important pieces of meta information is a “meta description” which should be a short (150-160) character description of the page.

This description will appear as a snippet underneath the page’s title on the Result Page, and serves to bring more traffic to the page from users who will actually benefit from visiting your page.

A typical meta description for the About page defined above might take the following form:

meta-description-tag

Note that if a page lacks a meta description, the search engine will usually take the first content on the page for this field – this is almost never ideal, and can detract from the professional look, feel and usability of the site – usability starts at the Results Page, not at your actual site!

Jonathan

New Solent Fire Website

A few weeks ago Solent Fire contact us to discuss their website, it was pretty dated and required a complete re-design. Working with Solent Fire we put together a couple of design concepts, these soon evolved into the new website, please see below:

solent-fire-services

solent-fire-services-02

We hope you like the look and feel of SolentFire.co.uk, Tidy Design is delighted with the end result. We are now discussing the next phase of website development, please stay tuned…

solent-fire-services-03

Finally, it was great to receive such positive feedback from Solent Fire on this project, thank you so much for choosing Tidy Design.

A Recent Testimonial

Working with an array of different clients in different sectors is great, there is never a dull moment. Many thanks to Portsmouth NHS for their glowing testimonial; we look forward to working with you on future projects:

portsmouth-nhs-logo

“We asked Tidy Design to help us to develop an interactive, informative and user-friendly App to help expectant mothers choose where they would prefer to birth their baby. This is what they did. Mike and the team at Tidy Design were invaluable; their passion and expertise helped us achieve our vision.

The project was completed to an exceptional standard whilst maintaining timescales and financial targets. It was a pleasure working with Mike, Rosie and Blayne and we would not hesitate in recommending their services.”

gill-walton

Thanks again to Portsmouth NHS, here is a link to the project MyBirthplace.org

A Busy First Quarter!

Hard to believe the first quarter of 2016 is already over – a massive “thank you” must go out to all our clients, you have kept us very busy!

All in all it has been an eventful three months for Tidy Design; we have started to work with several new clients, we have seen lots of repeat business, we have been interviewing, growing as a company and working very hard to deliver a quality service day in day out…

my-birthplace-app

Doors certainly do open when you work hard; word of mouth is by far the best form of advertising (sorry Google) as this year has shown. From working with Portsmouth NHS two years ago we have now started to work with Wessex Strategic Clinical Networks, liaising with NHS trusts in Bournemouth, Dorchester, Hampshire, Isle of Wight, Poole and Southampton…

my-birthplace-itv

Yup, a busy first quarter!

4 Modern Website Layout Examples

Layouts have not changed an awful lot since the release of CSS3 and HTML5. The days of using tables to layout a website are long gone yet websites still feel table like. There are benefits of having an unorthodox layout. No matter your trade you will always have competitors and I bet a lot of those competitors have similar websites (table like). Will a user remember one hundred similar layouts or the one that was different?

Diamonds

CSS3 has really changed the way we can style elements on a page. Using transform we can alter the appearance of nearly any element. Giving us the power to create some really unique layouts. Rotating squares into diamonds is one of the more basic examples; nonetheless very unique compared to its square cousin.

diamond-layout

The layout I have created can be used in a number of ways. An e-commerce store may use the two side diamonds as links for either men or women. They could be used as image placeholders to accompany the text in the centre. Whatever you choose this is a sure fired way to ensure a memorable site.

Box Overlay

Overlaying boxes on a traditional looking website can really impact its appearance and break the mould. Using shadows you can effectively turn the content inside into high priority areas for your call to actions (cta). Users are more likely to scan those areas of the page before anywhere else. Overlapping the boundaries of the layout beneath can also add to the effect.

overlaying-blocks

This layout would be great for a personal blog, the longer box to the left can act as an effective side bar while the posts can be placed to the right. The featured post can occupy the top of the page, its image being inside of the overlaying square.

Masonry

There are a couple of ways to achieving this effect. The easiest is to use a Javascript grid layout library called Masonry, it sorts all of the boxes into optimal positions to prevent huge vertical spaces. As quoted from their website “sort of like a mason fitting stones into a wall”. This means you can have many different shapes and sizes all fitting nicely next to and beneath one another.

The sidebar is also a less common feature and takes up a fraction of the space compared to more traditional versions. Using icons and single words allows the sidebar to become less of a prominent feature but remaining just as useful.

masonry-layout

This layout again can be used for blogs but also for dashboards. The boxes can contain important information for the website owner such as statistics or quick actions etc.

Marginless

This final concept is the most traditional looking of them all but it still has its unique qualities. The majority of websites use CSS to include margin between their sections. A marginless layout throws that out of the window and uses padding instead to create its white space. If you can get the correct colours and images then these layouts can look amazing.

no-margin-layout

These types of sites are great if your trying to sell a single product or advertise your business online.

Hopefully by now you have a few ideas you can take away with you to start building some truly unique looking layouts. It does however take more then just a great layout to build a memorable website but its the foundation on which everything else will be placed. Have a favourite layout? let us know in the comments.

Blayne Phillips

Website Layouts

Website layouts can be one of the easiest but also one of the trickiest components of website design – it may take a few minutes to map out a website structure and design, it could take a few hours…

website-layouts

Each web design project is unique; this calls for a unique solution and approach to our clients requirements. Ok, there are several website layout guidelines we can all follow to create user-friendly layouts, these include; a good use of whitespace, obvious (and easy to follow) call to actions, consistent font styles, alignments, positioning and device compatibility…

If you would like to find out more then please do not hesitate to contact us, our office in Old Portsmouth is open weekdays, 9am to 5pm :)

Thank you for having us…

Yesterday evening we travelled up to London to attend an Eleven Magazine exhibition in association with The Architectural Review hosted by KPF;

Eleven Magazine

Top: Eleven Magazine // Bottom: London Snaps & Tidy Blayne

It was great to hear such positive feedback on the website, meet people from AR (The Architectural Review) and get a mention from Andrea (Eleven Magazine, Editor in Chief) when he did his speech.

If you are interested in architecture, design, travel or innovation then please check out the Eleven Magazine website, the stories and articles they post are very cool – keep up the good work!

Thanks again for having us, although we didn’t get to stay for the after party (maybe next time) we did have fun and meet some interesting people.