Sticky Post

Changing the WooCommerce Shopping Cart Expiration Time

Buy the WooCommerce Cart Expiration Plugin here

WooCommerce defaults to a 48 hour expiration time for all user’s carts. After this time, a user’s cart is deleted and the user will have to restock their basket with the same items before continuing to shop.

The default expiry time can be changed by using the wc_session_expiring and wc_session_expiration filters in your site’s functions.php. This is fine if your expiry time is at 12 hour intervals as the WordPress cron system only runs the session clean up twice daily and you also have to consider if you really want to hardcode cart expiry in your website’s code?

There is a plugin that takes care of all of these problems

  1. Gives you control of the cart expiration time directly from the WooCommerce system settings page
  2. It changes the WooCommerce session clean up to an hourly period to allow cart expiration times of greater or less than 12 hour intervals
  3. It is fully supported on multisite installations of WordPress and WooCommerce

You can purchase the woocommerce cart expiry time changing plugin here

Buying the plugin rather than making the changes to the WooCommerce system yourself gives you the following benefits:

  1. When the plugin is updated and new features are added you will receive an email update along
  2. Using the plugin to control the cart expiration instead of changing the code yourself means you can update WooCommerce without undoing your changes.
  3. You have the benefit of being part of a community of users actively using and providing feedback on improvements to the developers of the plugin.

Dynamic multi-select fields in Twill CMS

Twill is a really promising headless CMS built by Area17. The product was release in March 2018. Unfortunately the online docs are somewhat lacking so implementing new features can be a struggle. There is a semi-active Spectrum chat for the project .

I wanted to implement dynamic multi-select fields in the CMS and after a lot of poking about l, I succeeded. So that my time doesn’t go wasted, I’ve documented the steps to add a dynamic multi-select field here.

This example shows how to add a “Sectors” multi-select field to an Article model.


You will need a new model, repository and controller for the Sectors.

php artisan twill:module Sectors

Your App/Models/Sector model should look like this:

namespace App\Models;

use A17\Twill\Models\Model;

class Sector extends Model {

   protected $fillable = [

   public $checkboxes = [

Your Article model will need a relationship reference to the Sector model. Add this to your Article model.

public function sectors() {
return $this->belongsToMany('App\Models\Sector');

The ArticleRepository repository needs the addition of some logic to save the multi-select fields on saving the model.

Add the afterSave method with a call to sync the sectors.

public function afterSave($object, $fields)
$object->sectors()->sync($fields['sectors'] ?? []);
parent::afterSave($object, $fields);


Customise the sectors migration generated by the artisan twill command


use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateSectorsTables extends Migration {
   public function up() {
      Schema::create( 'sectors', function ( Blueprint $table ) {
         createDefaultTableFields( $table );
         $table->string( 'title', 200 )->nullable();
      } );

   public function down() {
      Schema::dropIfExists( 'sectors' );

You will need to create a table in your DB for the article -> sector relationship.

artisan make:migration create_sector_article_table

My migration looks like this

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;

class CreateSectorsTables extends Migration {
   public function up() {
      Schema::create( 'sectors', function ( Blueprint $table ) {
         createDefaultTableFields( $table );
         $table->string( 'title', 200 )->nullable();
      } );

   public function down() {
      Schema::dropIfExists( 'sectors' );


Add a route for the sectors to the routes/admin.php file. You will probably want to add a section to the CMS to allow creation of new sectors from the CMS but this is outside of the scope of this article.


Form fields

And finally add the field to the CMS in articles/form.blade.php 🙂

    $sectors = array();
@foreach(\App\Models\Sector::all(['id','title']) as $sector)
        $sectors[] =
        'value' => $sector->id,
        'label' => $sector->title

@formField('multi_select', [
'name' => 'sectors',
'label' => 'Sectors',
'options' => $sectors,

WP Migrate CLI and MAMP

WP Migrate is a great tool well worth the slightly steep investment. The time and effort saved from a one click deployment huge. WP Migrate CLI takes this to another level with the ability to push an entire deployment from the command line.

If you’re running MAMP locally wp-cli may be using a different version of PHP than MAMP resulting in DB errors such as

wp-cli error establishing a database connection

This can be fixed by setting your bash/sh/git/[insert your shell] PHP version to use the same as is used by MAMP.

Add this to your ~/*.rc config file followed by source ~/*.rc to update your PHP binary path

PHP_VERSION=$(ls /Applications/MAMP/bin/php/ | sort -n | tail -1)
export PATH=/Applications/MAMP/bin/php/${PHP_VERSION}/bin:$PATH

Bish bash bosh, simple, repeatable, less error prone deployments are yours!

Compiling Andreas Antonopoulos’ Mastering Bitcoin book from source code

Andreas Antonopoulos’ Mastering Bitcoin book is available as an open source project on Github.

It can be compiled from source code pretty easily using asciidoc. Here’s how to do this using OS X

  1. Install asciidoc. I use homebrew:
    “brew install asciidoc”
  2. Clone the git repo:
    “git clone”
  3. cd to the cloned repo
  4. and compile the book with:
    “asciidoc -b html5 -a icons -a toc2 book.asciidoc”
  5. This will give you the book as a html file located in the new file book.html in the root of the repo director

    Mastering bitcoin compiled to HTML




Tracking page views in angulartics2

Angulartics2 is a great package for vendor agnostic tracking in Angular apps. When using the package with Google Analytics, page view tracking is wired up automatically using the Angular  routing module.


The angulartics2 documentation does not include information on how to send page views using the module however it is pretty simple to do, just inject the Angulartics2 and Angular common Location modules into your module’s constructor like so:

import { Angulartics2 } from 'angulartics2';
import {Location} from '@angular/common';

 private location: Location,
 public angulartics2: Angulartics2,

and you can now track page views manually using the following method:{ path: '/your-path/' + issue.slug, location: location });

Fix for “/dev/vmmon not found, display cannot be initialized” in VMWare Fusion

When attempting to run any of my VMWare Fusion virtual machines on mac macOS (OS X) I was getting the “/dev/vmmon not found, display cannot be initialized, internal error” error every time I try and start a virtual machine.

I tried reinstalling, upgrading and downgrading VMWare Fusion all to no avail.

The Fix for the dev/vmmon not found error

The problem is caused by having both VirtualBox and VMWare fusion installed on the same machine. Run the Sun provided uninstallation script, mirrored here to  uninstall VirtualBox. This allows you to run your VMWare Fusion Virtual Machines without the “/dev/vmmon not found…” error.

Reinstalling VirtualBox after this install doesn’t seem to cause this error again, though a reboot might change things there in which case I will update this post.

Allow users to select and copy text in Ionic 2 apps

In Ionic 2, the selection and thus copying of text is disabled by default. Enabling selecting and copying of content inside an Ionic 2 app is pretty simple. Here’s how

First, add this class to your app.scss file

Now you can add the “selectable” class to individual elements in the app or to ionic elements using the ngClass attribute. This will allow your users to select and copy text from within your Ionic 2 app  ?

Selecting and copying text in an Ionic 2 app

Selecting and copying text in an Ionic 2 app

Logging with angular2-logger in Ionic 2 apps

As far as I am aware Ionic 2 does not yet have any decent logging options. But as Ionic 2 uses AngularJS 2, we can make use of the angular2-logger module

Angular2-logger is a Log4j inspired logger for Angular 2 apps allowing you to set your desired log level (OFF, WARN, ERROR, LOG, DEBUG etc)

I’ve found it best to implement the angular2-logger as a provider in Ionic 2 apps and inject it into  your classes rather than instantiating a new instance of the logger for each component in your app.

Once you have the npm module installed, create a LoggerService provider in your app with the following ionic command:

ionic g provider LoggerService

then add the following code to the generated logger-service.ts file

I’m configuring my log level using a config class but you can change the code above to use your own preferred method.

Now you can inject the LoggerService into your component’s like so

And then log messages in your components like this

And add the following references and providers to your app.component.ts file

Now say goodbye to your console.log naffness for good 🙂