Running php scripts that include relative paths with cron

I recently had a problem running a php script which had an include() in it using cron. It worked fine in normal testing, but not as a cron job.

The reason is that when browser testing the working diorectory is the script’s directory. Cron uses the php location as the working directory, so the relative paths won’t be the same.


Either use absolute paths or change the working directory.

Church Admin Plugin Update

I’ve just uploaded 0.32.8 of the Church Admin plugin to which should please our American cousins

  • Calendar date and time formats are controlled by WordPress global settings
  • PDF’s can now be generated in Letter, Legal and A4 sizes
  • Mailing labels allow for a range of Avery ® formats

It’ll be available through your WordPress Admin area or for download from in a few minutes!

The year planner

Why is it that most calendar software doesn’t use or give that most powerful of Church planning tools – the year planner? The answer is because a year to view would mean the text is too small.
So I’ve added an A4 pdf year planner to my WordPress church_admin plugin. It uses colour to show different events. Max one event worthy of year planner a day!

Now to add some more things to the planner!

Online Church Management

A website is a powerful tool for churches to advertise who they are, where they are and what they do. It’s also a great medium for Church administration. The Gateway Church uses WordPress to drive our website and I’ve written a powerful administration plugin to help manage Church life.

It contains an address book with bulk email and sms facilities to keep in touch with people. There’s a powerful rota with unlimited tasks, attendance tracking and graphs, visitor tracking and a great calendar that allows “nth day” recurring that Church leaders love – “the prayer meeting is on the fourth Sunday of the month”.
The back end is for logged in administrators to edit what is going on. Here are some back end screenshots
Firstly adding or editing address details

When communicating to everyone – lots of people look at emails daily, but everybody looks at an sms straight away!

If your website is on a “shared host”, chances are there are restriction on how many emails a website is allowed to send an hour, to stop sites become spammers. My plugin allows a non-technical user setup email queueing…

The calendar section has multiple categories with a neat colour picker…

And viewing, adding and editing of events…

Keeping track of visitor followup is important to see how people are settling in – and what you measure improves.

The plugin also has attendance graphs to help with future planning and to help spot seasonal high and low spots.
The monthly average shows seasonal dips…

The rolling average, smooths the seasonal dips out…

For us at The Gateway Church, you can see the classic Church Plant plateau, which we are working hard to burst out by being thoroughly outward looking.

The latest version is available at Enjoy

Facebook Application Development (friends invite, publish to wall)

The trouble with tutorials on Facebook Application development is that they go out of date so quickly. This one was written 14th Dec 2010. The Facebook developers wiki is pants too!
So here’s what I learnt the last few days.

I’m assuming you have registered your application to be on
and have the vital application id, application secret and application key.

The canvas is where your app shows within – choose Iframe in the “Facebook Integration” settings.
The application page will look something like this, but have values;-)

The canvas url is the directory on your server where your application is hosted.

So firstly you need your users to add your application. I do that with fbmain.php
Which requires facebook.php downloaded from the sdk area.

Then in index.php you can start coding…

The contains a call to the javascript sdk you may need.

and just closes the body and html

If you want to add a invite friends dialogue – this was a huge pain to google!!!


Just call that as require(“invite.php”) where you want the invite to go – the sizing javascript stops those horrible scrollbars on your iframe.

If you want to publish something on their status updates…

Now you have the basic building blocks for building your facebook app. Start coding! and stick it in index.php after the yoru app code goes here comment!

Have fun and try my app – 28% of us forget to get our MOT done on time, so my app will send you an email reminder a month before to get it booked in!

Using cron to send bulk email on a shared host

I’m running a conference booking system at and we need to send out lots of emails to delegates and potential delegates. Our host only allows 100 emails per hour from the website, so I needed to find a way of queueing them and sending in batches…

First a mysql db table…

I’ve not set up attachments yet, so that table continues everything else we need.

Here’s a function to queue messages

I tend to call it with some basic messaging

So that handles creating messages and storing them in the database queue.

Here’s my cronemail.php file

The code is well commented – make sure you replace the hashes!

You will also need the excellent phpmailer script

Now we need to set up our shared host to execute cronemail.php every hour!

Go to your CPANEL and click on cron jobs – on my version there is a standard link and an advanced link

I use standard!

Common settings gives you some common options – once an hour is what we want (although for testing once every five minutes would be less tedious)

The command to run took a bit longer to get right! A lot of blog posts get this bit wrong!!!

You need to find out your php path – most likely to be /usr/local/bin/php

Then you need the path to the script – best put in a non-public accessable area or in the document root if you must!


So now you can type

/usr/local/bin/php -f /home/(username)/public_html/cronemail.php

into the command to run field and press . The -f tells the php compiler to run the file. Don’t forget to change (username) to your username.

Hope it helps…
Here it is in a zip file with a tester script index.php –emailstuff. Don’t use index.php in a production environment as there is no form checking!

Checking table1 connects to table2

Duplicating data in a database table is a waste of space, so if table1 has some column information repeated frequently then transfer that to a second table and use an id to store in table1 – that’s called normalisation

As an example, I have a conference booking system where delegates where all booking in from one of 80 churches. So three tables to identify a ticket holder, ticket type and their church is a good plan…


ticket ticket_type church
forename ticket_description church_name
surname ticket_price church_town
church_id ticket_type_id church_country
ticket_type_id church_id

Because many of the churches were in the same country, I actually had a third table


And replaced church_country in the church table with country_id

That means that you can pull out data efficiently – how many delegates from each church

In that example COUNT() – counts how many records match the condition

CONCAT_WS is concatenate with separator – eg “The Gateway Church, King’s Lynn, United Kingdom”

GROUP BY ensures the data is grouped by individual Churches

and ORDER BY puts them in descending order

I could also tally by ticket type

Somehow the tallies of delegates grouped by church didn’t tally with delegates grouped by ticket type. What had gone wrong is that there was an error in church_id for a couple of tickets.

How to find the problem and the records that had bad church_id’s? How do you find out if ticket has a church_id that is not in the church table?

To make it transferable, here is the query using t1 and t2

Simple Browser Detection

I wanted a simple and fast PHP browser detector for a script recently. Most scripts are either very out of date or huge and look for every single browser possible.  Here’s a simple one that will return the major ones.

The trick was putting Chrome fairly near the start of the $browsers array or it gets missed!
Call browser_detect() which returns an array where
0=>Browser Name and version
1=>Browser Name