The goal of My Book It is to be highly automated so that it can run with minimal human interaction.  It needs to run in this manner as I do not have enough time for it to be a labour intensive job. So with that in mind I wanted to automate as much of the student counting, billing, creation etc. as possible.

The first task was student counts. This information will be stored in a manner that meets the following requirements

  • It has to be used to generate invoices for customers.
  • It has to hold enough information that it can be queried by a customer and maintain its integrity. (i.e. when a customer disputes the number of students on a bill,it needs to hold that information on record)
  • I don’t want to think about it.
  • I need to be able to check it to ensure it is working correctly. (i.e. an audit log of some kind)
  • It should only run once and should be smart enough to prevent double runs (i.e. it should only run once)

That is no small feat, I also want to be able to add maintenance tasks into the same system and they just work. This is what changed the way I performed the work from a collection of individual, self contained scripts to a maintenance framework that allows me to quickly add tasks as required.

To create the framework I created a generic PHP “master” page that checks to see if maintenance has already been run for the day, works out what day of the month it is and then checks if there are any tasks to be run on that day. It then adds a maintenance log entry and exits cleanly.

Each Subtask is then broken out into its own sub file which is included as required (I have stored these in a tasks sub folder for easy access). This prevents repeated code and will simplify updates as they are required.

Lets dive in and hopefully it may more more sense as it comes together.

Here is the main file.

<?php
	/********************************************************************
	*********************** Maintenance Scripts *************************
	*********************************************************************/
	
	##Variables
	//Action variable will be populated as maintenance tasks occur.
	$actions = ""; 
	
	##Database Connect - Subtask
	include_once("tasks/dbconf.php");
	
	##Check that maintenance has not already run
	$sql = "SELECT * FROM `master`.`maintenance_log` WHERE `date` = '" .date("Y-m-d") ."' ";
	$results = mysql_query($sql, $sitedb)
		or die("Error checking maintenance log.");
	
	##If maintenance has already run today, do not run it again
	if(mysql_num_rows($results) == 0) {
		##First maintenance run for the day. 
		$day = date("d"); //get the day of the month with a leading 0
		
		##Day Select
		switch($day) {
			case "01":
				##Student Count
				include_once("tasks/studentcount.php");
				##Monthly Billing
				include_once("tasks/monthlybilling.php");
				break;
			case "02":
				break;
			case "03":
				break;
			case "04":
				##Student Count
				include_once("tasks/studentcount.php");
				break;
			case "05":
				break;
			/* This repeats up until 31 (max days in any month */
		} //switch statement
		
		##Log this maintenance run into the log.
		include_once("tasks/logaction.php");
	} //if maintenance check	
?>

The main framework is pretty simple. Work out the day of the month and then run and scripts that are required.

If I need to run a task on more then one day (i.e. count how many students per site) then I add the task to a second day (In the script above the studentcount.php task is run on the 1st and 4th of each month). If I need to run more then one task per day, I just add a second task to the case (i.e. day 01 in the script above)

Now lets look at one of the subtasks. These files are very simple as they only need to perform a single action and then exit.

<?php
	##This file will add the maintenance log.
	//Check if the action is blank (i.e. no tasks run today)
	if($actions == "") {
		//If it is blank, record that no maintenance took place.
		$actions = "No Maintenance to complete";
	} //check check action
	
	//Add the record
	$sql = "INSERT INTO  `master`.`maintenance_log` (`id` ,`date` ,`action`) VALUES (NULL ,  '" .date("Y-m-d") ."',  '$actions' )";
	$results = mysql_query($sql, $sitedb)
		or die("Error adding maintenance log" .mysql_error());
?>

Now it is just a matter of scheduling it to run with Cron. The great thing about this system is that there is only one Cron entry.