WebCron Documentation

WebCron is a separate, self-contained, but related product to Barebones CMS. It is an officially recognized product and therefore some kind soul in the support forums will help you if you need it.

WebCron is a web server cron (webcron) solution designed for programmers who need PHP code to run on a schedule on a web host or within the hosting environment of a web server. In essence, WebCron is 'cron' for websites that do not support cron nor provide shell accounts. However, this product is much more than just cron. WebCron is perhaps best summarized as a complete webcron solution that also provides a state-engine for performing lengthy atomic/linear and RPC-like operations. To that end, this product contains client and server components that talk to each other using compressed and encrypted data streams.

Be responsible with this product. Traditional cron jobs have free reign on the system and can consume as many resources as needed (CPU, RAM, etc). WebCron is restricted by the limitations of PHP and restrictions on the setup of your web host. You should be aware of your web host's limitations before using this product so that you do not get kicked off or banned from your web host. I am not responsible for what you do with this software.

This documentation covers everything you need to know about WebCron. There are very few similarities between WebCron and Barebones CMS other than WebCron leverages Admin Pack for managing unauthenticated scheduling and module configuration.

License

Like Barebones CMS, WebCron is dual-licensed under a MIT or LGPL license - your choice. The license and restrictions are identical to the Barebones CMS License.

WebCron as a whole isn't particularly well-suited for integration into other products. However, most of its functionality is encapsulated into reusable functions and classes, such as the CalendarEvent and WebMutex classes.

If you find WebCron useful, financial donations are sincerely appreciated and go towards future development efforts.

Download

WebCron 1.0RC14 is the fourteenth release candidate of WebCron.

Download webcron-1.0rc14.zip

If you find WebCron or a specific module useful, please donate toward future development efforts.

Authenticated vs. Unauthenticated

Authenticated execution and unauthenticated execution are two terms I came up with to describe the two execution paths within WebCron. Each execution path has pros and cons. For most tasks and most websites, the unauthenticated execution path is probably good enough.

Authenticated Execution Path

Pros:

Cons:

Most of these cons can be mitigated. If you don't like the idea of having a computer left on or requiring a working Internet connection for the times when the scheduled task runs, the unauthenticated execution path is probably a better solution.

The location of where WebCron is installed is sent in the clear over HTTP. There is no way around this with HTTP as it is how that protocol operates. The data itself is encrypted with AES, so at least part of the traffic is encrypted over HTTP. To secure all the traffic and communications to and from the server, use HTTPS.

If both the server and the client have the zlib extension enabled, compression of the data stream is enabled both ways after the initial session negotiation completes. Depending on the data being transferred, this can result in up to a 90% savings in bandwidth. The downside is that compression uses more CPU time.

There is no easy way around the limitations of the scheduling granularity of the task scheduler your OS uses. *NIX and Mac users have 'cron', which may or may not be capable of running tasks on a 'seconds' level of granularity and there are some other restrictions as to what cron can schedule. Windows users have the built-in Windows Task Scheduler available, which is sort of reliable but is also limited. Depending on your needs, you may find the built-in task scheduling solutions to be insufficient. Alternatives like 'launchd' for the *NIX folks (Mac users already have this) - and 'pycron' and other solutions exist for the Windows crowd.

The real purpose of using the authenticated execution path is to have two-way communications between the client (e.g. your computer) and server in a secure fashion. This inevitably means learning to write client and server modules for WebCron, which is more difficult than authoring a task for the Task Module. If all you want to do is execute Task Module tasks via authenticated execution, learning how to write a module is not necessary.

There is one official module that leverages authenticated execution: Site Backup. The Site Backup module offers full and incremental backups of files and MySQL databases complete with e-mail reports. See the WebCron Site Backup documentation for details.

Unauthenticated Execution Path

Pros:

Cons:

Each of the cons can be mitigated. If the website doesn't get enough visitors, there are several options available: Say something stupid on the website to get on Reddit/Digg/etc., edit the 'config.php' file's unauthenticated execution options and set lower values (the defaults are for medium-traffic sites), or replace with or add the authenticated execution path as part of the solution.

If a task is written improperly, it usually shows up right away when loading 'admin.php' (syntax error, etc.), or when using the "Run Task" feature inside the administration interface for the tasks in the Task Module.

On a high-traffic, bandwidth-sucking server, every request to the box counts. Putting an 'img' tag on the page will cause an extra request per page load. To mitigate this issue, use some Javascript to randomly document.write() the 'img' tag (e.g. 1 out of 5 requests). Or use the authenticated execution path.

The unauthenticated execution path does not offer client/server communication because it is designed to be server-only communications. If you need RPC-like execution, use the authenticated execution path.

Installation

Installation of WebCron is fairly straightforward. Like Barebones CMS, WebCron comes with an installer script that gets you up and running quickly. Unlike Barebones CMS, there is little need to secure the installer script itself. The installation procedure is as follows:

A number of these directions are simplifications of the Barebones CMS Installation documentation.

Due to the nature of WebCron, it is highly recommended that the directory that the files are uploaded to is given a random name. Naming the directory 'cron' or 'webcron' is a bad idea.

What follows in the rest of this section is the manual installation instructions for the authenticated client and the unauthenticated execution path for the Task Module. See the previous section on "Authenticated vs. Unauthenticated" to learn about the pros and cons of each solution.

Authenticated Installation - Client Setup

Setting up the client component requires PHP 5.2.x or later to be installed on an external computer. The client is a command-line application so that it can be connected to the OS' task scheduler. The installation of the client is as follows:

It is highly recommended that the server portion be installed over SSL and the client only communicate over SSL (HTTPS). Otherwise, a hacker could sniff traffic between the client and server and learn of the location of WebCron. Also, downloading 'config.php' should be done over a secure connection like SFTP as it contains encryption keys. The data sent from the client is encrypted with AES so that even if HTTP is used, the data itself being transmitted is secure.

If both the client and server have the zlib extension enabled, the data transferred both ways will be compressed. Depending on the data being transferred, this can result in up to a 90% savings in bandwidth.

Testing the client install.
Testing the client install.

Testing the installation from the command-line is fairly straightforward. You need PHP 5.2.x or later to be installed and on the path and then run a command from within the client directory similar to:

php index.php -v -wc_task=test.php

There are several default command-line options available, stored in the $wc_args global:

Each module can have its own command-line options. For example, the Task Module (wc_task) accepts a specific task to run on the server via the 'wc_task' option. And most command-line options can be repeated.

Also, notice that the letters of the options are d, m, and v. DMV - get it? (Har har.)

Unauthenticated Installation - Task Module Setup

The Task Module (wc_task) offers both an authenticated method of execution via the client for one-way communication only or through the unauthenticated 'task.php' file ('modules/wc_task/task.php'). Installing 'task.php' is fairly easy:

Naming the directory something benign-sounding could be misleading to hackers. It probably doesn't matter either way as long as the main WebCron directory is never published.

Example:

...
<img src="/cron/" width="1" height="1" />
...

The 'img' tag is usually simple but slightly awkward since developers generally expect to specify a file with a '.jpg', '.gif', or '.png' extension. If you really want to mislead and are running a server with 'mod_rewrite' enabled, you could try adding something similar to the following to a '.htaccess' file in the newly created directory:

RewriteEngine On
RewriteRule pink_ponies.gif index.php [L]

Then just point the 'img' tag at 'pink_ponies.gif' and mod_rewrite will translate it into 'index.php' and execute that file.

Upgrading

Like Barebones CMS, upgrading WebCron is easy - just upload the new files to the server and overwrite existing files. If you use the client components, overwrite those files as well.

Securing WebCron

There are a couple of different aspects to security in terms of WebCron. There are three points of entry into the system from most to least obvious:

What follows in this section is some discussion on each area of entry and how to address the security concerns regarding each one.

Securing 'admin.php'

Upon completing the installation, there is a link to "Start using WebCron" that goes to the administration interface - 'admin.php'. Upon clicking the link, a warning box appears at the top of the page that says that 'admin.php' is not secure. This is true since anyone who happens to stumble onto that URL can start messing with the configuration for WebCron.

There are two approaches to solving the security issue here: Delete the file or write a simple plugin. Deleting the file when it isn't needed makes it unavailable to hackers. But it is also inconvenient to upload and delete a file every time a change needs to be made and tested.

The other approach is to write a plugin. The file 'admin.php' is actually based on Admin Pack, so if you are familiar with the security in Admin Pack, this is similar. To make the warning go away and secure the site, create a file in the directory called 'admin_hook.php', tie it into your own login system, and then do whatever you need to do to set the value of $bb_usertoken. See the Admin Pack documentation for details on $bb_usertoken. Most 'admin_hook.php' files are only around 7 lines of code. Using this approach also makes it easy to upgrade WebCron in the future.

Securing 'index.php'

Theoretically, it is nearly impossible to hack the authenticated execution path once the client is set up. Transmitted data is encrypted with AES in CBC cipher mode with semi-random data surrounding the protected data being transferred. For the security conscious, the setup process can be secured by transferring all files over SFTP and conduct all client/server communications over SSL (HTTPS) - including the installation - to eliminate the possibility of network sniffers who might be monitoring the connection.

Due to the atomic/linear nature of 'index.php', if someone manages to locate the directory in which WebCron is installed, it is possible to perform a Denial of Service attack against 'index.php's unauthenticated execution route to prevent authenticated execution from taking place. Fortunately, this is fairly easy to detect as web server logs will have a record of the offender.

One way to secure 'index.php' is to write a plugin. Create a file in the directory where 'index.php' is located called 'index_hook.php'. Then do whatever you need to do to secure the environment. This is mostly used to restrict the authenticated execution path to specific IP addresses. Some programmers also like to give priority access to the authenticated execution path by denying unauthenticated execution path access when there is at least one authenticated execution path session. This is usually done with a lock file of sorts and deals with the aforementioned Denial of Service issue.

There are a number of settings in 'config.php' related to the security of this key file. See the "Configuration Options" section of this documentation for a detailed breakdown of each configuration option.

Securing the Task Module: 'task.php'

By default, the unauthenticated execution path for the Task Module - 'modules/wc_task/tasks.php' - is secure as-is since it depends on a copy of 'config.php' to be in the same directory as this file in order to do anything useful. Never place a copy of 'config.php' in the 'modules/wc_task' directory on the server.

The secure approach to using 'task.php' is to copy both it and 'config.php' to a directory outside of the WebCron root. For example, a directory called 'cron' or 'tasks'. Rename 'task.php' to 'index.php'. Then put a HTML 'img' tag that points at 'index.php' in either the site header or footer.

At this point, it becomes possible for a hacker to learn of the location of the WebCron installation if a task is improperly written and an unauthenticated execution schedule is added for it. Always try to test changes to tasks by using the "Run Task" feature for the task to mitigate this issue.

Creating Task Module Tasks

The Task Module is included with the default installation of WebCron. It resides in the 'modules/wc_task' directory and scans the 'modules/wc_task/tasks' directory for PHP files to locate tasks. Newly created tasks are disabled by default in the configuration and have to be activated from the administration interface before they can be used.

Creating a new task is easy. Here's an example:

<?php
	if (!defined("WC_FILE"))  exit();

	$g_wc_task_config["_f"] = "Task Name";
	$g_wc_task_config["_c"] = "wc_task_test";

	function wc_task_test()
	{
		global $g_wc_task_config;

		if (!isset($g_wc_task_config["count"]))  $g_wc_task_config["count"] = 0;

		$g_wc_task_config["count"]++;
	}
?>

Basically, each task declares its name, a function to call when the task is supposed to run, and then the actual function definition. Each task can store configuration and state information into the global $g_wc_task_config variable. This variable is loaded with current task information before loading the file and running the task. Variable names that start with an underscore '_' prefix in $g_wc_task_config are reserved for use by the Task Module:

The only options that should be modified by tasks are _m, _f, and _c. (MFC, get it? That was a lame Windows joke. Har har.)

$g_wc_task_config is always saved to the global 'settings.php' file. There is no special function to call to save the configuration for a single task.

My primary goal with this approach was to make it easy to create tasks. From my own perspective, requiring the code to be located inside a function is not ideal, but it isn't terrible either. This offers a fair trade-off for the ease-of-use in setting up the schedule for the task later on.

Once the task is ready, it can be activated, tested, and a schedule set up from within the administration interface.

Creating Modules

The process of creating a module is only necessary for setting up secure two-way communications between a client and server. WebCron offers an easy-to-use framework entirely written in PHP that makes it easy to send requests, receive responses, and manage a state-engine between calls.

A complete module typically consists of a server component and a client component.

Creating the Server Module

The process of creating a server module is similar to creating widgets in Barebones CMS. However, the server module needs to assume that there is limited time in which to perform whatever task it needs to perform and assume execution will be separated into multiple calls. The server module should be written such that the client will drive the server.

The server-side framework makes it easy to determine how much time is left for script execution so that PHP will not abort script execution prematurely and provide enough time for responding to the client. The client-side of the framework will attempt to communicate with the server up to three times to get a valid response before giving up. The server-side should be prepared to handle this condition as well as be prepared to handle any lengthy operations.

A good approach for handling lengthy operations is to have a precalculation step where the server-side determines roughly how much time it will take to complete the next operation, and, if there is not enough time, return an error. If the server is in the middle of a potentially lengthy operation, the error can request that the client retry the request but on the server side save the state in such a way that it can resume the operation when the client executes the same call. The WebCron client will automatically execute the same request if the server tells it to, which could result in an infinite loop in some rare cases. These approaches, however, make the server module robust and fairly easy to write.

Example:

<?php
	if (!defined("WC_FILE"))  exit();

	class TestServer extends WC_ModuleBase
	{
		public function Init()
		{
			if (!isset($wc_settings["TestServer"]["message"]))
			{
				$wc_settings["TestServer"]["message"] = "Pink Ponies";
			}

			return "Test Server Module";
		}

		public function Config()
		{
			global $wc_settings, $wc_menuopts;

			if (isset($_REQUEST["action2"]) && $_REQUEST["action2"] == "save_config")
			{
				$wc_settings["TestServer"]["message"] = $_REQUEST["message"];

				WC_ConfigRedirect("", array(), "success", "Successfully updated the configuration.");
			}
			else
			{
				$contentopts = array(
					"desc" => "Edit the configuration.",
					"nonce" => "action",
					"hidden" => array(
						"action" => $_REQUEST["action"],
						"module" => $_REQUEST["module"],
						"action2" => "save_config",
					),
					"fields" => array(
						array(
							"title" => "Message",
							"type" => "text",
							"name" => "message",
							"value" => $wc_settings["TestServer"]["message"],
							"desc" => "The message to return."
						)
					),
					"submit" => "Save",
					"focus" => false
				);

				BB_GeneratePage("Edit Configuration", $wc_menuopts, $contentopts);
			}
		}

		public function Process()
		{
			global $wc_settings, $wc_data, $wc_session, $wc_time_limit;

			if ($wc_time_limit < 20)
			{
				$response = array(
					"success" => false,
					"retry" => false,
					"error" => "Server configuration needs to be at least 20 seconds."
				);

				WC_SendResponse($response);
			}
			else if (WC_GetTimeLeft() < 15)
			{
				$response = array(
					"success" => false,
					"retry" => true,
					"error" => "Task needs more time to complete."
				);

				WC_SendResponse($response);
			}
			else
			{
				$response = array(
					"success" => true,
					"message" => (isset($wc_data["test_server_msg"]) ? $wc_data["test_server_msg"] : $wc_settings["TestServer"]["message"])
				);

				WC_SendResponse($response);
			}
		}

		public function ProcessUnauth()
		{
			global $wc_settings;
		}
	}
?>

Every server module must derive from and extend WC_ModuleBase. As a result, all member functions are optional. Most developers writing server modules usually exclude ProcessUnauth() since unauthenticated execution for server modules makes no sense given that the Task Module unauthenticated execution path generally suffices for most needs.

The server module's 'index.php' file must be in a directory named the same as the class name. The example above would be stored in 'modules/TestServer/index.php' on the server.

Creating the Client Module

The process of creating a client module is a lot simpler than the server module. Client modules are executed from the command-line interface (cli) mode of PHP. Each client module can have its own command-line arguments passed to it that are expanded and parsed in $wc_args.

Example:

<?php
	if ($wc_verbose)  echo "Running process...\n";
	$data = array();
	if (isset($wc_args["opts"]["testmsg"]))  $data["test_server_msg"] = $wc_args["opts"]["testmsg"];
	$result = WC_SendRequest($data);
	if (!$result["success"])  echo "Error:  Failed to get message.  Reason:  " . $result["error"] . "\n";
	else  echo "Message received:  " . $result["message"] . "\n";
?>

This example client connects with the example server module from the previous section (Creating the Server Module) and retrieves the message stored in the configuration or, if a 'testmsg' command-line option is used, sends and receives that message instead.

Client modules must be prepared to handle any and all error conditions. If the network connection suddenly goes out, the script should be prepared to handle it. If the server enters an error condition, the script should handle that too. Clients should check all responses for failure conditions and gracefully degrade.

Client modules must be named identically to their server counterparts and stored in similar directory and file structures. The example would be stored in 'modules/TestServer/index.php' on the client.

Note that WC_SendRequest() attempts each request three times before giving up. The server should be prepared to handle the condition where the same request is made multiple times by the client and respond with the same data each time.

Configuration Options

The configuration file 'config.php' contains the configuration for the server and client. The installer for the server makes sure enough information is available that the client works on most systems without issues. The configuration file is also used in conjunction with the Task Module unauthenticated execution path (task.php).

What follows in this section is a detailed description of each option.

USE_HTTPS

Type: Boolean [Constant]

Example: true

Forces the admin and client to use HTTPS to communicate with the server. The current SSL status is determined using WC_IsSSLRequest().

USE_MAXLOCK

Type: Boolean [Constant]

Example: true

When set to true, this sets the maximum time for a lock to be $wc_time_limit + 5 seconds. On a NFS or cloud computing resource, this should be set to false. See WebMutex::Lock() for details.

USE_JSON

Type: Boolean [Constant]

Example: false

When using the authenticated execution path, json_encode() and json_decode() are used for the transport medium instead of PHP serialize() and unserialize(). Should only be used if you understand the restrictions of JSON (strings and associative arrays only - no objects, integers, floats, etc). Typical use of this option is to create better interoperability between a client and server. For example, a client could be written in a different scripting language.

ENCRYPT_EXTRA

Type: Boolean [Constant]

Example: true

If the server sends extra data beyond the response packet (e.g. a file), this option can be used to decide if the data also needs to be encrypted or can be sent as plain-text. The default is 'true', but if the 'mcrypt' library is not available (the installer can determine availability), it may be desirable to set this to 'false' as the PHP implementation of AES is very slow.

AUTH_ALLOW

Type: Boolean [Constant]

Example: true

Allows authenticated execution of WebCron. Set this to 'false' to completely disable the authenticated execution path.

UNAUTH_ALLOW

Type: Boolean [Constant]

Example: true

Allows unauthenticated execution of WebCron. Set this to 'false' to completely disable the unauthenticated execution path.

UNAUTH_FREQ

Type: Integer [Constant]

Example: 5

Used by the Task Module to determine the frequency, in seconds, to check to see if tasks should run. The default is once every five seconds. Typically used in conjunction with UNAUTH_RAND.

UNAUTH_RAND

Type: Integer [Constant]

Example: 5

Used by the Task Module to determine the random chance that this PHP instance will check to see if tasks should run. The default is a one in five chance. Typically used in conjunction with UNAUTH_FREQ.

UNAUTH_BASE_TIMEZONE

Type: String [Constant]

Example: "UTC"

The timezone to use primarily for unauthenticated execution of task schedules and exceptions. Used by the Task Module to set the timezone before performing any date/time operations. Changing this will not alter existing task schedules or exceptions. See the complete list of recognized timezones for allowed values.

UNAUTH_BASE_WEEKDAY

Type: String [Constant]

Example: "Sun"

The English three-letter abbreviation of the starting weekday of the week. Used by the Task Module to set the starting weekday for new schedules. Changing this will not alter existing task schedules or exceptions.

ROOT_PATH

Type: String [Constant]

Example #1: "/usr/local/apache/htdocs/testcron"

Example #2: "C:/Website/testcron"

This is the absolute path to the root of the WebCron installation from the perspective of the web server. Do not add a trailing slash to the path.

ROOT_URL

Type: String [Constant]

Example: "/testcron"

This is the absolute URL to the root of the WebCron installation from the perspective of a web browser or the authenticated execution path for the client. Do not add a trailing slash to the URL. If WebCron is installed to the web root (not recommended), then this should be an empty string.

ROOT_HOST

Type: String [Constant]

Example: "http://barebonescms.com"

This is the host part of the URL the client uses to contact the server.

Supports 'http[s]://[username[:password]@]www.something.com[:port]'. The installer attempts to automatically determine this string.

SUPPORT_PATH

Type: String [Constant]

Example: "support"

This is the path to the 'support' subdirectory. Do not add a slash to the start or the end of the string.

MODULE_PATH

Type: String [Constant]

Example: "modules"

This is the path to the 'modules' subdirectory. Do not add a slash to the start or the end of the string.

BASE_RAND_SEED

Type: String [Constant]

This is a randomly generated secret seed of bytes, in hexadecimal format, that helps to keep WebCron secure.

BASE_RAND_SEED2

Type: String [Constant]

This is another randomly generated secret seed of bytes, in hexadecimal format, that helps to keep WebCron secure.

BASE_RAND_SEED3

Type: String [Constant]

This is another randomly generated secret seed of bytes, in hexadecimal format, that helps to keep WebCron secure.

PROXY_URL

Type: String [Constant]

Example: "https://localproxyserver/"

This is the host part of a URL the client uses to contact a proxy server to handle communication with the server specified by ROOT_HOST.

Supports 'http[s]://[username[:password]@]www.something.com[:port]'. Leave blank if no proxy server connection is required. Only supports BASIC authentication.

PROXY_CONNECT

Type: Boolean [Constant]

Example: false

When set to true, will attempt to establish a TCP/IP tunnel through the proxy server using the HTTP proxy CONNECT method. Usually used in conjunction with HTTPS connections.

CLIENT_ROOT_PATH

Type: String [Constant]

Example #1: "/home/user/testcron"

Example #2: "C:/Scripts/testcron"

This is the absolute path to the root of the WebCron client. Do not add a trailing slash to the path. Automatically defined by the client if it is not defined in 'config.php'.

CLIENT_SUPPORT_PATH

Type: String [Constant]

Example: "support"

This is the path to the 'support' subdirectory of the WebCron client. Do not add a slash to the start or the end of the string. Automatically defined by the client if it is not defined in 'config.php'.

CLIENT_MODULE_PATH

Type: String [Constant]

Example: "modules"

This is the path to the 'modules' subdirectory of the WebCron client. Do not add a slash to the start or the end of the string. Automatically defined by the client if it is not defined in 'config.php'.

Global and Reserved Variables - Server

The server has a number of global variables available to programmers writing server modules. All WebCron globals start with the prefix '$wc_'. This prefix is reserved exclusively for WebCron to prevent possible future conflicts. If you need to create globals, prefix the variable with '$g_[yourmodulename]' to help guarantee uniqueness and reduce potential conflicts.

What follows in this section is a detailed description of each global variable on the server-side.

$wc_start

Type: Double

The microsecond timestamp of roughly when the 'index.php' script started.

$wc_datasent

Type: Integer

The number of actual bytes sent to the client with WC_SendResponse(). This number is accurate even when compression is enabled. Server modules that send data outside of WC_SendResponse() calls should try to update this variable to keep the number of bytes sent as accurate as possible. It is highly recommended that no more than 10 megabytes be sent per request and the amount of data per WC_SendResponse() be limited to roughly one megabyte of uncompressed data. This set of restrictions allows the client to download, decrypt, and decompress the data stream while only consuming 30 to 40 megabytes of RAM per run.

$wc_time_limit

Type: Integer

Example: 30

The number of seconds the script has to execute code. This value may be different from the PHP configuration and actual execution time may vary slightly.

$wc_sessions

Type: Array

Stores the current authenticated sessions and variables associated with each session as an array of data. Current session information is stored in 'sessions.php' as PHP serialized and Base64 encoded data.

$wc_authenticated

Type: Boolean

Example: false

Set to true if the current request is using the authenticated execution path, false if using the unauthenticated execution path. Can be used by tasks to perform alternate actions.

$wc_session

Type: Boolean or String

Example: false

This is set to the value of a key in '$wc_sessions' if the current request is authenticated and the request contains a valid session key. A module may access session data for the current request using $wc_sessions[$wc_session]. Keys that have an underscore '_' prefix in $wc_sessions[$wc_session] are restricted for use by the WebCron client.

$wc_data

Type: Array

Only available if the current request is using the authenticated execution path. Contains a set of key/value pairs intended as request information for transport from the client module to the server module. Keys starting with a prefix of 'wc_' are restricted for use by the WebCron client.

$wc_mutex

Type: Object

Do not touch this variable. This maintains a lock file in the WebCron root that guarantees that the entire product is executing atomically. That is, only one instance of PHP is guaranteed to be executing the code that is running. The lock file is named 'webcron.lock' and will restrict access for a maximum of $wc_time_limit + 5 seconds.

$wc_settings

Type: Array

Stores the settings for each module. Each module gets its own array to store configuration data in. For example, the Task Module stores its data in $wc_settings["wc_task"]. Store temporary session data in $wc_sessions[$wc_session].

Global and Reserved Variables - Client

The client has a number of global variables available to programmers writing client modules. All WebCron globals start with the prefix '$wc_'. This prefix is reserved exclusively for WebCron to prevent possible future conflicts. If you need to create globals, prefix the variable with '$g_[yourmodulename]' to help guarantee uniqueness and reduce potential conflicts.

What follows in this section is a detailed description of each global variable on the client-side.

$wc_start

Type: Double

The microsecond timestamp of roughly when the 'index.php' script started.

$wc_args

Type: Array

Example:

# php index.php -m=wc_task -wc_task=test.php

array(3) {
  ["success"]=>
  bool(true)
  ["file"]=>
  string(9) "index.php"
  ["opts"]=>
  array(2) {
    ["module"]=>
    array(1) {
      [0]=>
      string(7) "wc_task"
    }
    ["wc_task"]=>
    array(1) {
      [0]=>
      string(8) "test.php"
    }
  }
}

This contains the parsed command-line arguments that were passed in.

$wc_debug

Type: Boolean

Example: false

When the '-d' or '-debug' option is specified on the command-line, this is assigned a value of true. This is false if the '-d' option is not used. Typically displays detailed information about each request to and from the server to diagnose problems with modules. When debugging is enabled, piping output to a file is recommended to make it easier to analyze the output in a text editor.

$wc_verbose

Type: Boolean or Integer

Example: false

When the '-v' or '-verbose' option is specified on the command-line, this is assigned the value of the number of times '-v' appears. This is false if the '-v' option is not used. Typically used to determine if more output should be displayed - typically for debugging purposes.

$wc_requests

Type: Integer

Example: 41

The number of times WC_SendRequest() is called. Displayed at the end of client execution when verbose mode is enabled.

$wc_datasent

Type: Integer

Example: 197892

The number of bytes sent to the server. Displayed at the end of client execution when verbose mode is enabled.

$wc_datarecv

Type: Integer

Example: 345463817

The number of bytes received from the server. Displayed at the end of client execution when verbose mode is enabled.

$wc_modules

Type: Array

This is an array of modules that may be loaded later on by the client. Depending on the '-m' or '-modules' option(s), this may be used to execute one or more modules.

$wc_module

Type: String

Example: "wc_task"

This contains the active module being processed by the client.

$wc_session

Type: Array

This contains the current session information for the active module. A client module may access the $wc_session["compress"] to determine if two-way compression is enabled for the current session. A client module may also access $wc_session["maxsize"] to determine the maximum number of bytes that may be sent to the server in a single request.

Global Functions - Server

The server component of WebCron has a number of useful functions available to programmers developing modules. WebCron-specific functions have the prefix 'WC_', which is reserved for use by WebCron. There should be no need to develop functions outside of the WC_ModuleBase-derived class created for each module. However, should such functions be needed, it is recommended that the function name be prefixed with '[modulename]_' to help guarantee uniqueness and reduce potential conflicts.

The baseline 'support/debug.php' and 'support/str_basics.php' global functions are always available to server-side modules, 'index_hook.php' plugins, and 'admin_hook.php' plugins. These functions are documented in the Barebones CMS Global Functions documentation.

When the administration interface is being used and the module's Config() function is called, the global functions of Admin Pack are also available.

See the "Extra Components" sections of this documentation for details on the CalendarEvent and WebMutex classes.

What follows in this section is a detailed description of each global function on the server-side not already mentioned.

WC_SetTimeLimit()

Parameters: None.

Returns: Nothing.

This function attempts to set $wc_time_limit for both 'index.php' and 'admin.php' to a reasonable limit of somewhere between 15 and 60 seconds. The ideal sweet-spot is around 30 seconds.

WC_SaveSessions()

Parameters: None.

Returns: A boolean of true if the 'sessions.php' was saved successfully, false otherwise.

This saves the '$wc_sessions' global variable to the 'sessions.php' file. Current session information is stored in 'sessions.php' as PHP serialized and Base64 encoded data.

WC_NewSession($module, $compress, $oldid = "")

Parameters:

Returns: A string containing a new session ID if successful, a boolean of false otherwise.

This function creates a new session for the authenticated execution path. The $oldid option is a leftover from a similar function for Barebones CMS and not used anywhere.

WC_RefreshSession($id)

Parameters:

Returns: The return value of WC_SaveSessions().

Sessions expire after 15 minutes of inactivity. This function keeps the session from expiring and is called automatically after every successful 'wc_process' call, which has the side-effect of saving changes to the session variables the server module may have modified.

WC_DeleteExpiredSessions()

Parameters: None.

Returns: A boolean of true if successful, false otherwise.

This function deletes expired sessions.

WC_EndSession($id)

Parameters:

Returns: The return value of WC_SaveSessions().

Deletes an active session and all variables associated with the session.

WC_GetModuleList()

Parameters: None.

Returns: An array containing the list of modules on the server.

This function retrieves the list of directories in the 'modules' subdirectory that contain 'index.php' files. These are assumed to be valid server modules.

WC_GetTimeLeft()

Parameters: None.

Returns: A double containing the number of seconds the script has left before PHP forcefully terminates execution.

This function returns zero when there is less than five seconds left, which allows for plenty of time to send a response to the server. If there are more than five seconds left, the time left is close to actual.

WC_SendResponse($data)

Parameters:

Returns: A boolean of true.

This function serializes the input array, compresses the data (if applicable), encrypts the data using AES_Packet::CreateDataPacket(), Base64 encodes the encrypted data, and outputs the result followed by a single newline.

For clients to function correctly, the input array must contain certain key/value pairs:

These key names are reserved for use by WebCron and required as part of sending a response to the authenticated client.

WC_SaveSettings()

Parameters: None.

Returns: A boolean of true if the 'settings.php' was saved successfully, false otherwise.

This saves the '$wc_settings' global variable to the 'settings.php' file. Current module configuration information is stored in 'settings.php' as PHP serialized and Base64 encoded data.

WC_GetDirectoryList($path)

Parameters:

Returns: An array of two arrays of subdirectories ("dirs") and files ("files") within the directory specified by $path.

This function retrieves a list of subdirectories and files within the specified directory and sorts them with natcasesort(). Subdirectories go into one array of the array that is returned and is called "dirs". Files go into another array and is called "files".

This function is a clone of BB_GetDirectoryList().

WC_PHPShorthandToBytes($val)

Parameters:

Returns: An integer containing the shorthand size in bytes.

This function is used primarily to determine how many bytes can be uploaded to the server.

Global Functions - Server Admin

The administrative interface contains a few functions that reduce development effort by simplifying things such as creating valid hyperlinks. The functions in this section don't fit anywhere else and are defined in 'admin.php'.

WC_CreateConfigURL($action2, $extra = array())

Parameters:

Returns: A string containing valid URL that can be used in a hyperlink or redirect.

This function wraps up the error-prone BB_CreateSecurityToken() function and returns a valid URL. This function is generally not called directly and is used by WC_CreateConfigLink() and WC_ConfigRedirect().

WC_CreateConfigLink($title, $action2, $extra = array(), ...)

Parameters:

Returns: A string containing a valid hyperlink including surrounding 'a' tags.

This function wraps up the error-prone BB_CreateSecurityToken() function and creates a valid link that usually used to load another configuration page.

WC_ConfigRedirect($action2, $extra = array(), $msgtype = "", ...)

Parameters:

Returns: Nothing.

This function outputs a header() containing a redirect. Note that this function does not call exit() or die(). The Config() function in every module is expected to fall through to completion so that settings are saved correctly.

Global Functions - Client

The client component of WebCron has a number of useful functions available to programmers developing modules. WebCron-specific functions have the prefix 'WC_', which is reserved for use by WebCron. When creating functions for client modules, it is recommended that the function name be prefixed with '[modulename]_' to help guarantee uniqueness and reduce potential conflicts.

The baseline 'support/debug.php' and 'support/str_basics.php' global functions are always available to client-side modules. These functions are documented in the Barebones CMS Global Functions documentation.

See the "Extra Components" portion of this documentation for details on the AES class and command-line parser. See the Barebones CMS Extra Components documentation for details on the HTTP functions.

What follows in this section is a detailed description of each global function on the client-side not already mentioned.

WC_SendRequest($data, $wc_action = "wc_process")

Parameters:

Returns: An array of information about the request and the response from the server.

This is the primary workhorse of a client module. It sends encrypted data and receives an encrypted response. However, from the client's perspective, the data is a PHP array of information being passed back and forth intact. This function abstracts away the details of communicating with the server.

Calls WC_ProcessResponse() to extract the first response from the server.

WC_ProcessResponse($data)

Parameters:

Returns: An array of data that was sent with WC_SendResponse().

This function decodes, decrypts, and unserializes data from the server back into a PHP array. This function may be called by client modules to process additional data sent by the server. The first response is automatically processed by WC_SendRequest(), which is usually good enough.

WC_GetModuleList()

Parameters: None.

Returns: An array containing the list of modules on the client.

This function retrieves the list of directories in the 'modules' subdirectory that contain 'index.php' files. These are assumed to be valid client modules.

WC_GetDirectoryList($path)

Parameters:

Returns: An array of two arrays of subdirectories ("dirs") and files ("files") within the directory specified by $path.

This function retrieves a list of subdirectories and files within the specified directory and sorts them with natcasesort(). Subdirectories go into one array of the array that is returned and is called "dirs". Files go into another array and is called "files".

This function is a clone of BB_GetDirectoryList().

Extra Component - CalendarEvent

The CalendarEvent class, located at 'support/calendar_event.php', is an encapsulated, reusable class that provides a versatile scheduling and calendaring interface. It can be used to generate a calendar of days for a given month and supports 'cron'-like scheduling of events. This class is very efficient at calculating a calendar, supports schedule exceptions, one-time and recurring events, and also supports serialization.

In theory, the class should work with PHP 5.x and later but only PHP 5.2.x and later is supported.

The Task Module server component of WebCron uses CalendarEvent extensively for unauthenticated execution path scheduling of tasks.

CalendarEvent::SetData($data = array())

Parameters:

Returns: Nothing.

Restores a class instance's values with the values in the array. The CalendarEvent constructor also accepts similar input. This function should only be called with the same data that GetData() returns.

CalendarEvent::GetData()

Parameters: None.

Returns: An array of data suitable for later use with SetData or the constructor of a new object.

This function returns the internal data structure as an array ready for serialization. Designed to be used in a later SetData() call.

CalendarEvent::SetTime($ts = false)

Parameters:

Returns: Nothing.

This function sets an internal current timestamp. Automatically set to the current time on class initialization. Used during processing so that dates and times don't potentially change and therefore mess up calculations.

CalendarEvent::SetTimezone($tz)

Parameters:

Returns: Nothing.

Sets the internal class timezone to the specified timezone. It is recommended that this function be called before any schedules or exceptions are added.

CalendarEvent::GetTimezone()

Parameters: None.

Returns: A string containing the internal class timezone.

Gets the internal class timezone.

CalendarEvent::SetStartWeekday($weekday)

Parameters:

Returns: A boolean of true if the starting weekday was successfully set, false otherwise.

Sets the internal starting weekday. The starting weekday affects the numeric value of the 'weekday' option and the 'weekrows' option of schedules. The default starting weekday is "Sun". It is recommended that this function be called before any schedules or exceptions are added.

CalendarEvent::AddSchedule($options, $replaceid = false)

Parameters:

Returns: An array with "success" set to a boolean of true plus other information if the schedule was successfully added, false otherwise.

This function is the primary scheduling workhorse of CalendarEvent. It parses, validates, and adds schedules to the internal data structures. The $options parameter accepts three different forms of input:

The alternate format is the official 'cron' format and must begin with the word cron.

The "months", "weekrows", "weekday", "days", "hours", "mins", and "secs" options support various common cron expressions for pattern matching:

Other rules that apply to each option:

There are a number of examples in the source code for this function.

CalendarEvent::GetSchedules()

Parameters: None.

Returns: An array of schedules.

Example result:

array(1) {
  [0]=>
  array(8) {
    ["origopts"]=>
    string(36) "Jul * N-Mon-Fri 4 0 0 0 2010-01-01 *"
    ["months"]=>
    string(3) "Jul"
    ["weekday"]=>
    string(9) "N-Mon-Fri"
    ["days"]=>
    string(1) "4"
    ["hours"]=>
    string(1) "0"
    ["mins"]=>
    string(1) "0"
    ["secs"]=>
    string(1) "0"
    ["startdate"]=>
    string(10) "2010-01-01"
  }
}

This function returns the internal array of schedules. Each array element is a key/value pair where the key is the schedule ID and the value is an array containing expanded options and the "origopts" key contains the original options passed to AddSchedule().

CalendarEvent::GetCachedSchedules()

Parameters: None.

Returns: An array of cached schedules or a boolean of false if RebuildCalendar() has not been called.

Example result:

array(1) {
  [0]=>
  array(8) {
    ["months"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(3) "Jul"
      ["prefixes"]=>
      array(0) {
      }
      ["orignoprefix"]=>
      string(3) "jul"
      ["expanded"]=>
      array(1) {
        [7]=>
        bool(true)
      }
    }
    ["weekrows"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(1) "*"
      ["prefixes"]=>
      array(0) {
      }
      ["orignoprefix"]=>
      string(1) "*"
      ["expanded"]=>
      array(6) {
        [1]=>
        bool(true)
        [2]=>
        bool(true)
        [3]=>
        bool(true)
        [4]=>
        bool(true)
        [5]=>
        bool(true)
        [6]=>
        bool(true)
      }
    }
    ["weekday"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(9) "N-Mon-Fri"
      ["prefixes"]=>
      array(1) {
        ["n-"]=>
        bool(true)
      }
      ["orignoprefix"]=>
      string(7) "mon-fri"
      ["expanded"]=>
      array(5) {
        [2]=>
        bool(true)
        [3]=>
        bool(true)
        [4]=>
        bool(true)
        [5]=>
        bool(true)
        [6]=>
        bool(true)
      }
    }
    ["days"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(1) "4"
      ["prefixes"]=>
      array(0) {
      }
      ["orignoprefix"]=>
      string(1) "4"
      ["expanded"]=>
      array(1) {
        [4]=>
        bool(true)
      }
    }
    ["startdate"]=>
    array(8) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(10) "2010-01-01"
      ["year"]=>
      int(2010)
      ["month"]=>
      int(1)
      ["day"]=>
      int(1)
      ["firstofmonth"]=>
      int(1262329200)
      ["daysinmonth"]=>
      string(2) "31"
      ["ts"]=>
      int(1262329200)
    }
    ["hours"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(1) "0"
      ["prefixes"]=>
      array(0) {
      }
      ["orignoprefix"]=>
      string(1) "0"
      ["expanded"]=>
      array(1) {
        [0]=>
        bool(true)
      }
    }
    ["mins"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(1) "0"
      ["prefixes"]=>
      array(0) {
      }
      ["orignoprefix"]=>
      string(1) "0"
      ["expanded"]=>
      array(1) {
        [0]=>
        bool(true)
      }
    }
    ["secs"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(1) "0"
      ["prefixes"]=>
      array(0) {
      }
      ["orignoprefix"]=>
      string(1) "0"
      ["expanded"]=>
      array(1) {
        [0]=>
        bool(true)
      }
    }
  }
}

This function returns the internal array of cached schedules. Each array element is a key/value pair where the key is the schedule ID and the value contains parsed options based on AddSchedule(). This array is used to rapidly generate calendars of schedules.

CalendarEvent::RemoveSchedule($id)

Parameters:

Returns: A boolean of true if the schedule was successfully removed, false otherwise.

This function removes a specific schedule by ID.

CalendarEvent::SetScheduleDuration($id, $duration)

Parameters:

Returns: A boolean of true if the duration was successfully set, false otherwise.

This function sets the duration of a schedule. It is up to the application to best determine how to use a schedule duration. CalendarEvent just offers this functionality as a convenient storage mechanism.

CalendarEvent::AddScheduleException($options)

Parameters:

Returns: An array with "success" set to a boolean of true plus other information if the schedule exception was successfully added, false otherwise.

This function creates a schedule exception for a specific date. A schedule exception replaces all schedules that run on a specific date with the schedule in the exception on a target date. The $options parameter accepts two different forms of input:

The "hours", "mins", and "secs" options support various common cron expressions for pattern matching:

Other rules that apply to each option:

Most of the time a schedule exception occurs on the same date, so both "srcdate" and "destdate" will typically be the same. The "destdate" is the date on which the schedule exception will take place, so it is possible to shift the exception to some other date - including dates that have already past.

CalendarEvent::GetScheduleExceptions()

Parameters: None.

Returns: An array of schedule exceptions.

Example result:

array(1) {
  ["2011-07-04"]=>
  array(6) {
    ["origopts"]=>
    string(27) "2011-07-04 2011-07-10 0 0 0"
    ["srcdate"]=>
    string(10) "2011-07-04"
    ["destdate"]=>
    string(10) "2011-07-10"
    ["hours"]=>
    string(1) "0"
    ["mins"]=>
    string(1) "0"
    ["secs"]=>
    string(1) "0"
  }
}

This function returns the internal array of schedules. Each array element is a key/value pair where the key is the schedule exception "srcdate" and the value is an array containing expanded options and the "origopts" key contains the original options passed to AddScheduleException().

CalendarEvent::GetCachedScheduleExceptions()

Parameters: None.

Returns: An array of cached schedule exceptions or a boolean of false if RebuildCalendar() has not been called.

Example result:

array(1) {
  ["2011-07-04"]=>
  array(4) {
    ["destdate"]=>
    array(8) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(10) "2011-07-10"
      ["year"]=>
      int(2011)
      ["month"]=>
      int(7)
      ["day"]=>
      int(10)
      ["firstofmonth"]=>
      int(1309500000)
      ["daysinmonth"]=>
      string(2) "31"
      ["ts"]=>
      int(1310277600)
    }
    ["hours"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(1) "0"
      ["prefixes"]=>
      array(0) {
      }
      ["orignoprefix"]=>
      string(1) "0"
      ["expanded"]=>
      array(1) {
        [0]=>
        bool(true)
      }
    }
    ["mins"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(1) "0"
      ["prefixes"]=>
      array(0) {
      }
      ["orignoprefix"]=>
      string(1) "0"
      ["expanded"]=>
      array(1) {
        [0]=>
        bool(true)
      }
    }
    ["secs"]=>
    array(5) {
      ["success"]=>
      bool(true)
      ["orig"]=>
      string(1) "0"
      ["prefixes"]=>
      array(0) {
      }
      ["orignoprefix"]=>
      string(1) "0"
      ["expanded"]=>
      array(1) {
        [0]=>
        bool(true)
      }
    }
  }
}

This function returns the internal array of cached schedule exceptions. Each array element is a key/value pair where the key is the schedule exception "srcdate" and the value contains parsed options based on AddScheduleException(). This array is used to rapidly generate calendars of schedules.

CalendarEvent::RemoveScheduleException($id)

Parameters:

Returns: A boolean of true if the schedule exception was successfully removed, false otherwise.

This function removes a specific schedule exception by "srcdate".

CalendarEvent::SetScheduleExceptionDuration($id, $duration)

Parameters:

Returns: A boolean of true if the duration was successfully set, false otherwise.

This function sets the duration of a schedule exception. It is up to the application to best determine how to use a schedule exception duration. CalendarEvent just offers this functionality as a convenient storage mechanism.

CalendarEvent::GetCalendar($year, $month, $sparse = false)

Parameters:

Returns: An array containing scheduling information for the given month.

Example result:

array(10) {
  ["success"]=>
  bool(true)
  ["year"]=>
  int(2011)
  ["month"]=>
  int(7)
  ["prevmonthnumdays"]=>
  string(2) "30"
  ["weekdays"]=>
  array(7) {
    ["sun"]=>
    int(1)
    ["mon"]=>
    int(2)
    ["tue"]=>
    int(3)
    ["wed"]=>
    int(4)
    ["thu"]=>
    int(5)
    ["fri"]=>
    int(6)
    ["sat"]=>
    int(7)
  }
  ["firstweekdaypos"]=>
  int(6)
  ["numdays"]=>
  string(2) "31"
  ["numweeks"]=>
  int(6)
  ["nextmonthweekdaypos"]=>
  int(2)
  ["calendar"]=>
  array(1) {
    [10]=>
    array(2) {
      ["type"]=>
      string(13) "destexception"
      ["exceptions"]=>
      array(1) {
        [0]=>
        string(10) "2011-07-04"
      }
    }
  }
}

Generates a calendar of days for a given month and IDs of schedules and schedule exceptions that run on those days. When $sparse is true, only days with schedules that run are included in the results. Additional information is included to easily generate a displayable calendar (e.g. HTML).

CalendarEvent::GetTimes($id)

Parameters:

Returns: An array with "success" set to a boolean of true plus other information if the schedule ID is valid, false otherwise.

Example result:

array(4) {
  ["success"]=>
  bool(true)
  ["hours"]=>
  array(1) {
    [0]=>
    bool(true)
  }
  ["mins"]=>
  array(1) {
    [0]=>
    bool(true)
  }
  ["secs"]=>
  array(1) {
    [0]=>
    bool(true)
  }
}

This function retrieves the expanded times (hours, mins, secs) used in the AddSchedule() call. Generally used by the class while rebuilding the calendar.

CalendarEvent::GetExceptionTimes($srcdate)

Parameters:

Returns: An array with "success" set to a boolean of true plus other information if the schedule exception $srcdate is valid, false otherwise.

This function retrieves the expanded times (hours, mins, secs) used in the AddScheduleException() call. Generally used by the class while rebuilding the calendar.

CalendarEvent::NextTrigger()

Parameters: None.

Returns: An array of information if the next trigger timestamp is less than 14 months away, a boolean of false otherwise.

This function determines the timestamp of the next trigger - the next timestamp a pattern matches - based on schedules and schedule exceptions. The best approach is to cache the result of this function. Then wait for the cached value to expire/pass, do whatever needs to be processed, and set the cached value to false. Then, if the cached result is false, create a CalendarEvent object to call NextTrigger() and save the result to the cache.

CalendarEvent::RebuildCalendar()

Parameters: None.

Returns: Nothing.

This function forces the internal calendar to rebuild and reset the next trigger timestamp. Call this function after making changes that affect schedules, exceptions, timezones, or the starting weekday. For example, adding a new schedule requires calling AddSchedule() and then RebuildCalendar(). Multiple changes can be made before calling this function.

CalendarEvent_TZSwitch::__construct($tz)

Parameters:

Returns: Nothing.

This class is useful for creating a new, temporary object that sets the timezone until the end of the current function scope, at which point the original timezone is restored.

Extra Component - WebMutex

The WebMutex class, located at 'support/web_mutex.php', is an encapsulated, reusable class that provides a cross-platform, cross-process, cross-thread, non-blocking, expire-capable, multi-lock capable, named mutex. It guarantees that the current web request is the only instance of PHP executing a specific piece of code or has access to a specific resource on the server it is running on. In a Cloud, as long as the file system is shared (e.g. NFS), WebMutex will even operate across all servers in the cloud/cluster (minus the lock expiration functionality). This class is, in theory, portable to any language and platform.

In theory, the class should work with PHP 5.x and later but only PHP 5.2.x and later is supported.

The server component of WebCron uses WebMutex extensively to guarantee single instance access to all resources.

WebMutex::_construct($name)

Parameters:

Returns: Nothing.

The constructor requires a named mutex name. WebMutex operates by using a real file on the file system. It is highly recommended that a full path be used. Note that the filename will have a '.lock' extension added automatically to all file operations.

WebMutex::Lock($block = true, $maxlock = false)

Parameters:

Returns: A boolean of true if the lock was successfully obtained, false otherwise.

This function attempts to obtain a lock on the mutex. This is also known as signaling. Locking is done by attempting to create a file that will only be created if it does not exist. Since the OS arbitrates file system access, the function is guaranteed to work everywhere and support non-blocking operations. The file that is created has a '.lock' file extension appended.

The $maxlock feature introduces a way to expire a lock. For instance, if a PHP script dies while it holds a lock, the file will not be deleted automatically. This option allows for a reasonable time to pass before the lock is deleted. When both $block and $maxlock are used, they should both be integers, the value for $block should be significantly smaller than $maxlock, and $maxlock should be larger than the maximum execution length of a PHP script. Do not use $maxlock on NFS or in a cloud environment unless you really know what you are doing.

If this function is called more than once on a mutex that has already been locked successfully, it will merely increment an internal counter.

WebMutex::Unlock()

Parameters: None.

Returns: A boolean of true if the mutex was successfully unlocked, false otherwise.

If the Lock() function was called more than once, this simply decreases the counter by one. Otherwise, the lock file is deleted. A mutex should remain locked only as long as it is needed. However, the destructor for WebMutex automatically unlocks the lock and frees up resources.

Extra Component - Command-line Parser

The command-line parser, located at 'support/cli.php' that comes with the client is a single, reusable function that is suitable for any command-line PHP script. It is up to each script to determine if the results are legitimate.

The client component of WebCron uses the command-line parser to parse the command-line into the global $wc_args and $wc_verbose variables.

ParseCommandLine($options)

Parameters:

Returns: An array containing the parsed command-line.

This function takes the current command-line options stored in $_SERVER["argv"] and parses them into an array of keys and values. The $options array may contain the following options:

The WebCron client uses the letter codes "m" and "v" to map to "module" and "verbose".

© CubicleSoft