Automatic multisite cron using php5

Last modified: September 23, 2009 - 16:08

Create a new file preferably in the same directory as your drupal dir. Name it 'cronall.php' or something. Copy the following script into it. Then adjust the settings in the file, and visit the script with your webbrowser, to see if it is setup correctly.
Then create a cronjob for the cronall.php script, and you're done.

<?php
/**
* This script scans the sites directory, and uses a regular expression to extract the sitenames.
* It then uses this sitename to execute the cronjob for these sites.
* You then only have to create a cronjob for this script.
* In this way, you can create and delete sites on the fly, but all their cronjobs will be executed.
*/

/***********
* SETTINGS
**********/
//the location of the 'sites' directory relative to this script.
$sitesDir = '../drupal/sites';
/**
* A regular expression that matches the name of the directories in
* the 'sites' dir that you want to execute cronjobs for, with a
* backreference around the actual site name. (so we can exclude the
* domain part)
*
* If you don't know regular expressions you might want to brush up
* on them: <a href="http://www.regular-expressions.info/tutorial.html
" title="http://www.regular-expressions.info/tutorial.html
" rel="nofollow">http://www.regular-expressions.info/tutorial.html
</a> *
* Alternatively, you can just copy the name of one of the directories
* in the site dir, put a backslash \ in front of all dots . and replace
* the actual name of the site with ([a-zA-Z0-9_-])
*/
$siteNameRegExp = 'www\.example\.com\.([a-zA-Z0-9_-])';
//the url of the cron script, you should insert %s where the sitename should be inserted later.
$cronUrl = 'http://www.example.com/%s/cron.php';
//any other sites that you want to execute cronjobs for. Just comment this if you haven't got any.
$addedSites = array('drupal');
/***********
* END SETTINGS
**********/

error_reporting(E_ALL);
$sites = array();

$handle = opendir($sitesDir);
while (
$file = readdir($handle)) {
    if(
ereg($siteNameRegExp, $file)){
       
$sites[] = ereg_replace($siteNameRegExp, '\\1', $file);
    }
}
//default site
if(isset($addedSites) && is_array($addedSites)){
   
$sites = array_merge($sites, $addedSites);
}
foreach(
$sites as $site){
   
$cmd = 'wget --spider '.sprintf($cronUrl, $site);
    echo
'Executing command: '.$cmd.'<br>';
   
exec($cmd);
}

?>

Manual multisite cron

Carlos Miranda Levy - July 24, 2008 - 12:08

If you have many multisites, some not requiring cron.php or some even pointing to the same site (aliases), you may want to just define the list of sites to cron manually, below is a simplified version of the script that does this...

<?php
/**
* You only have to create a cronjob for this script.
* In this way, you can create and delete sites at will, but all their cronjobs will be executed.
*/

//cronUrl is the url of the cron script, you should insert %s where the sitename should be inserted later.
$cronUrl = 'http://%s/cron.php';
error_reporting(E_ALL);
$sites = array();
$sites[] = 'site1';
$sites[] = 'site2';
$sites[] = 'site3';
$sites[] = 'site4';
// add as many as needed, the value should be the root url you use to access each drupal site, ie. <a href="http://www.mysite1.com" title="www.mysite1.com" rel="nofollow">www.mysite1.com</a> or www.mysite.com/drupal

foreach($sites as $site){
   
$cmd = 'wget --spider '.sprintf($cronUrl, $site);
    echo
'Executing command: '.$cmd.'<br>';
   
exec($cmd);
}
?>

------
Con paciencia y calma,
sube un burro a una palma

Manual multisite cron via url argument

Carlos Miranda Levy - July 24, 2008 - 12:31

Not sure when you might need this, but this is another variation I tested while looking for a solution...

It is yet another simplified version of the script above, but this one allows you to pass the site as an argument in the url that calls the cron...

<?php
$drupal_sites_dir
= 'c:/xampp/htdocs/drupal/sites/';
/* something like '/home/account/public_html/sites/', '/home/account/public_html/drupal/sites/' or 'c:/xampp/htdocs/drupal/sites/' */

$default_site_domain = 'defaultsite.com';
/* site to use in case invalid argument is passed or no argument is passed */

/*
verify the validity of GET var page.
this prevents passing an invalid argument (a site that does not exist)
if not set, set to default site
*/

if(isset($HTTP_GET_VARS['sitetocron']))
{
    if (
file_exists($drupal_sites_dir.$HTTP_GET_VARS['sitetocron'])) {
      
$sitetocron = $HTTP_GET_VARS['sitetocron'];
    } else {
       
$sitetocron = $default_site_domain;
    }
}
else
{
$sitetocron = $default_site_domain;
}

$cronUrl = 'http://'.$sitetocron.'/cron.php';
error_reporting(E_ALL);

$cmd = 'wget --spider '.$cronUrl;
echo
'Executing command: '.$cmd.'<br>';
exec($cmd);
?>

------
Con paciencia y calma,
sube un burro a una palma

If you don't have Shell permission

mirsent - December 18, 2008 - 16:58

My shared hosting account doesn't allow me to execute shell scripts or command line programs like wget, curl etc.
However I can use PHP Curl. So, here's my version of cronall.php:

<?php
/**
* You only have to create a cronjob for this script.
* In this way, you can create and delete sites at will, but all their cronjobs will be executed.
*/

error_reporting(E_ALL);
$sites = array();
$sites[] = 'http://www.exampe.com';
$sites[] = 'http://www.example2.com';
// add as many as needed, the value should be the root url you use to access each drupal site

$ch = curl_init();

foreach(
$sites as $site){   
 
curl_setopt($ch, CURLOPT_URL, $site."/cron.php");
 
curl_exec($ch);
}

curl_close($ch);
?>

Cron with Python

davebv - December 12, 2008 - 15:43

I could not run neither wget, curl, lynx nor exec in php scripts, but I had python instead. Just in case you are interested (and because it is the only way I found I was able to run cron for multisite) I share a small python script.

import sys, urllib
def reporthook(*a): print a
for url in sys.argv[1:]:
     i = url.rfind('/')
     file = url[i+1:]
     print url, "->", file
     # urllib.urlretrieve(url, file, reporthook)
     urllib.urlopen(url)

so my cron entry will be:

/path/to/python wget.py url1/cron.php url2/cron.php

Easy multisite crontab ...?

lorraineflack - April 30, 2009 - 11:54

I am running 3 sites on one drupal code base.
The following crontab entry seems to work fine (no scripts necessary):

45 * * * * /usr/bin/wget -O - -q -t 1 http://www.site1.com/cron.php
46 * * * * /usr/bin/wget -O - -q -t 1 http://www.site2.com/cron.php
47 * * * * /usr/bin/wget -O - -q -t 1 http://www.site3.com/cron.php

ereg functions in PHP 5.3

tsunami7 - September 23, 2009 - 16:05

My reading of the PHP documentation indicates that the use of ereg and ereg_replace are deprecated in PHP 5.3, and should no longer be used. They recommend using preg_match() and preg_replace() instead.

Also my understanding of the original script here is that it doesn't deal with sites built as sub-domains, eg. http://site1.example.com/. I've attempted to create a more robust/maintenance free Multi-Site cron script, which is Step 10 of my blog post for setting up a Multi-Site development environment for OS X. Those interested can find it at:
http://blogs.martiangraphix.com/2009/09/building-a-drupal-development-en...

Hope this helps.

Michael
Martian Graphix, Inc

 
 

Drupal is a registered trademark of Dries Buytaert.