Versioning

For many content types within the Continuum CMS it is possible to view historic versions of a particular piece of content and rollback to a selected version. This is achieved using the generic versioning functionality.

A content version is stored in a database table - the name of the table, apart from being meaningful, does not matter (by convention though, the name of the table should end with “Versions”, e.g. JaduNewsVersions) - with the following fields:

  • id – the unique ID for the record
  • objectID - refers to the ID of the content from its native table
  • category - the name of the table in which the object resides
  • content - a serialized PHP object which forms the content of the version
  • modDate - the date on which the version was stored
  • liveVersion - whether the version record is the one that is live; only one version record with a particular id should be live at any one time

Each time a piece of content that uses the versioning system is saved a check is made to determine whether the content has changed. If the content has changed then a new record in the relevant table is created. The liveVersion field for the newly added field is set to 0 when it is created and is set to 1 after the content has been approved. This allows the live content to remain unchanged while at the same time allowing the content to be edited and reviewed before being made. The web site should only display content which has a liveVersion value of 1.

Generally, all content is stored in a table with a name appropriate for the content, for example news records are stored in a table named JaduNews. If news items are to be versioned then the version records would be stored in a separate table, possibly named JaduNewsVersions. The most up to date record of the content is always available in the JaduNews table and at appropriate times, for example when content is changed or approved, a new version record is created in the JaduNewsVersions table.

Version objects for different types of content can be stored in the same versions table. This is useful in such cases as when content does not change so often and to minimise the number of version tables required, for example the version records for terms and conditions data (from JaduTerms) and for organisation location information (from JaduLocation) can both be stored in JaduVersions. The category field in a versions table is used to distinguish between different types of content stored in the same versions table.

The Versioning API

The core code for versioning is located in the JaduVersions.php script. This script contains a number of methods and functions that are useful when dealing with versioning of content.

The Versions Class

The Versions class is used to store a number of serialized version objects that are associated with a particular content item. The constructor takes the name of a type of content (usually the name of the table the content comes from), the ID of the content to get versions of, and the table to get the version records from. Thus, all versions of a particular item of content can be retrieved as follows:

$versions = new Versions('JaduNews', '13', 'JaduNewsVersions');

This will instantiate a new Versions object and retrieve from the database all news versions for the news record with an ID of 13. Note that the category name JaduNews is completely incidental, but for the sake of clarity the name of the table from which the version records derive is often used. In the example above the versions records would be obtained from the JaduNewsVersions table. The newly instantiated object contains the following attributes:

  • category
  • objectID
  • table
  • objects
  • liveVersion

The category, table and objectID attributes should be self-explanatory: they are the same as the parameters passed to the Versions constructor. The objects attribute is an array of instances of the object contained within the content field of the versions table. For example, if the content field of the JaduNewsVersions table contains serialized versions of instances of the News class then the objects array will contains those (unserialized) instances. The key of the array is the id of the record. Finally, the liveVersion attribute contains the ID of the record which is currently live.

There are two functions of the Versions class worthy of note: addVersion and setLatestVersionCurrent.

The addVersion function is used to add a record to a versions table. The function takes care of serializing the object. The following code shows how a new version object is created.

$versions = new Versions('JaduNews', '13', 'JaduNewsVersions');
$news = new News();
$news->title = "My new news record":
$versions->addVersion($news, 'JaduNewsVersions');

The version record added in this code will have the liveVersion field set to 0, meaning that it should not be used on the web site. At such a time when the content has been approved to be made live, the liveVersion field can be set to 1. This can be achieved using the setLatestVersionCurrent function, as follows:

$versions = new Versions('JaduNews', '13', 'JaduNewsVersions');
$versions->setLatestVersionCurrent();

The content class, in this instance named CustomThing, should extend VersionObject, which is a base class for all version-able content.

include_once('JaduVersions.php');
class CustomThing extends VersionObject {}

Also, so that duplicate versions are not created when no changes have been made, the method getHTMLDescription() should be added. This is used to compare two versions and check for changes. It is also used to generate the output in “Track Changes” lightboxes, hence it returns a HTML string.

function getHTMLDescription()
{
    return
    <<<EOD
    <table width="100%" cellpadding="4" cellspacing="1">
    <tr>
    <td bgcolor="#cccccc" width="20%" valign="top">Name</td>
    <td bgcolor="#999999" width="80%">$this->name</td>
    </tr>
    </table>
    EOD;
}

To store the versions you will need to create a separate Versions table. This can use the following schema, only the table name will need changing:

CREATE TABLE `CustomThingVersionsTable` (
    `id` int(11) NOT NULL auto_increment,
    `objectID` int(10) NOT NULL default '-1',
    `category` varchar(50) NOT NULL default '',
    `object` text NOT NULL,
    `modDate` datetime NOT NULL default '0000-00-00 00:00:00',
    `liveVersion` tinyint(4) NOT NULL default '0',
    PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Now we need to ensure new versions are created when the content is updated. Add the following code before you execute the UPDATE query:

$versions = new Versions('CustomThingTable', $id);
$versions->addVersion(getCustomThing($id));

Similarly when content is deleted you will need to delete the versions of that content.

$versions = new Versions('CustomThingTable', $id);
$versions->deleteAllVersions();

results matching ""

    No results matching ""