WooCommerce Appointments Enhanced with an Availability Calendar

WordPress WooCommerce Appointments

WooCommerce Appointments is a commercial  booking plugin that allows you to setup appointments with WooCommerce. It has full integration into Google calendar to track appointments of your staff.

Staff availability can be set globally or via each staff members profile. While this is nice, I was looking for an option to actually handle availability via another Google Calendar as well. That was a must have feature for a current project.

What do you do, if that feature is not available yet ? You poke the code!

The magic entry point for the staff availability is the user meta “_wc_appointment_availability“, which is made available through includes/class-wc-product-appointment-staff.php.

A couple of weeks ago I asked support for a simple filter hook to alter the availability on demand from the outside.

The development team added the feature in one of the latest releases, making wc_appointments_staff_availability the entry point for my custom availability changes.

The filter hook

  1. add_filter( 'wc_appointments_staff_availability', 'availability_callback', 10, 3 );
  2.  
  3. function availability_callback($availability, $staff){
  4. // Your changes here
  5. return $availability;
  6. }

Getting the data

You can either pull Google Calendar Events directly through the Google Calendar API or use the available iCal export option. In this quick example I will use the private calendar iCal export file.

The availability calendar

Lets setup a quick clean calendar, called “Availability”. So simple and catchy :)

  1. Create a new calendar
  2. Create some test events. WooCommerce Appointments supports multiple availability rules, but I am focusing on the time:range option and recurring events for this example. I might be extending on this a bit more in the future ! So for this example:  Friday, timeframe 10:00 – 16:00 and repeating four times.
  3. Go into settings and get the link to the privat ical export file

Parse iCal data

For this example I am using the PHP ICS Parser, but any other parser will do.  Install it via composer: composer require johngrogg/ics-parser.

Lets create a quick little plugin to get us going and save it to /wp-content/plugins/CustomAvailability/smile.php

  1. <?php
  2. use ICal\ICal;
  3.  
  4. /*
  5. Plugin Name: WooCommerce Appointments - Custom Availability
  6. Plugin URI: https://portalzine.de
  7. Description: Attach additional Google Calendar for staff availability
  8. Version: 1.0
  9. Author: portalZINE NMN
  10. Author URI: https://portalzine.de
  11. */
  12.  
  13.  
  14. require_once(PATH_TO_VENDOR_DIR."vendor/autoload.php");
  15.  
  16. class StaffCustomAvailability{
  17.  
  18. function __construct() {
  19.   add_filter( 'wc_appointments_staff_availability', array($this, 'staffAvailability'), 10, 3 );
  20.  }
  21.  
  22. function staffAvailability($availability, $staff){
  23. // Your changes here
  24. return $availability;
  25. }
  26.  
  27. }
  28.  
  29. $StaffCustomAvailability = new StaffCustomAvailability();
  30.  

 

Set the availability

Its time to get the data into the system. I am only pulling and altering the availability for one single user in this example, the user with the USERID “3”. This should provide you with a good starting point.

  1. function staffAvailability($availability, $staff){
  2.  
  3. // $staff holds the complete user data
  4. // $availability is the current set of rules
  5.  
  6. // Only altering availability for  USERID 3
  7.  
  8. if($staff->data->ID == 3){
  9.      $newSet = array();  
  10.   try {
  11.     // add the private ics file here
  12.     $ical = new ICal('URL TO PRIVATE ICS FILE', array(
  13.         'defaultSpan'                 => 2,     // Default value
  14.         'defaultTimeZone'             => 'Europe/Berlin',
  15.         'defaultWeekStart'            => 'MO',  // Default value
  16.         'disableCharacterReplacement' => false, // Default value
  17.         'skipRecurrence'              => false, // Default value
  18.         'useTimeZoneWithRRules'       => false, // Default value
  19.     ));
  20.  
  21.      } catch (\Exception $e) {
  22.     die($e);
  23. }
  24.  
  25.    $forceTimeZone = true;
  26.        
  27.    $events = $ical->sortEventsWithOrder($ical->events());
  28.     // looping through all events
  29.    foreach ($events as $event) {
  30.         // Get Start and end date / time information
  31.         $dtstart = $ical->iCalDateToDateTime($event->dtstart_array[3], $forceTimeZone);
  32.         $dtend = $ical->iCalDateToDateTime($event->dtend_array[3], $forceTimeZone);
  33.        
  34.         // Define new time:range rule
  35.         // Adding one rule per day
  36.        // Added Friday to the calendar + event recurring  4 times, which results in 4 new rules for staff member 3
  37.         $newSet[] =  array(            
  38.             'type' => "time:range",// rule type used for this example
  39.             'appointable' => "yes",
  40.             '[priority' => 10,
  41.             'from' => $dtstart->format('H:i'), // start time 10:00
  42.             'to' => $dtend->format('H:i'), // end time 16:00
  43.             'from_date' => $dtstart->format('Y-m-d'), // start date -  Friday
  44.             'to_date' => $dtend->format('Y-m-d') // end date - Friday
  45.                        );
  46.             $availability = $newSet;
  47.           }
  48.      
  49.      
  50.     }
  51. return $availability;
  52. }

The example pulls and parses the ics file on every load, use a transient or REDIS to store data and only refresh in certain intervals.

Hope this gets you started! I build a simple interface around it, with a lot of more rule options. This makes the setup for each staff member a brise. Now each of them can setup a calendar easily and provide  me with the ics link  :) WooCommerce Appointments rocks …

Enjoy coding ….

 

Alex

I am a full-stack developer. I love programming,  design and know my way around server architecture as well.  I would never feel complete, with one of these missing. I have a broad range of interests, that’s why I constantly dive into new technologies and expand my knowledge where ever required. Technologies are evolving fast and I enjoy using the latest. Apart from that, I am a peace loving guy who tries to have people around him that think the same.  I truly believe in the principle: “If you help someone, someone will help you, when you need it."

View Comments

  • Hi Alex,

    Great tips and thanks.

    One Question. How to show Auto-select First Available Day on product loop at shop page?

    Take a look here

    Thanks in Advance

    • Hi,
      you are better off asking that question to their support. I would have to check their latest documentation or parse the code to find a workaround, which there always is ;) .

      Cheers
      Alex

Recent Posts

Particle Network Animations in Javascript

What are particle animations? Particle network animations in JavaScript typically involve creating visual representations of… Read More

5 days ago

B&B / Hotel Booking Solutions for WordPress | 2024

BOOKING SOLUTIONS 202x This is my take on a subset of booking, appointment, PMS or… Read More

1 month ago

WordPress Cron + WP-CLI + Ntfy

THE GOAL Create a system cron for WordPress, that is accessible and can be easily… Read More

3 months ago

2024 is here and now :)

2024, what's cooking? Slowly getting into the 2024 spirit. 3 projects coming to a close… Read More

4 months ago

2023 ends and whats next !

Short look back at 2023 This has been a busy and interesting year. I am… Read More

4 months ago

cubicFUSION Grid Tweaker – Elementor Grid made easy.

Elementor Pro provides grid containers as an experimental feature. The options provided are limited, when… Read More

5 months ago