The method used here was inspired by a MODX forum post from Michelle84. The idea is that you might have time-sensitive resources that should be unpublis
hed after a certain amount of time.
MODX resources can be scheduled for “unpublication” using the Unpublish Date on the Create/Edit Resource panel, but it’s a pain to have to set this for every resource you create, and it’s easy to forget. The unpublish date is stored in the unpub_date
field of the resource, and it’s actually pretty easy to create a plugin to set it automatically. In this article we’ll see a couple of ways to do it.
The Approach
In Michelle84’s example, the resource was intended to be unpublished one year after its publication. In a plugin connected to OnDocFormSave
, it’s easy to check the publishedon
field, add a year to that time, and save the new value in the unpub_date
field.
It’s important to remember that MODX stores date fields as unix timestamps, but converts them from human-readable dates when saving them and converts them to human readable dates when you retrieve them. In other words, if you want to set a date field in code, you need to send a human-readable date. And if you ask MODX for a date field value with get()
, you’ll get a human-readable date.
In addition, if you want to do arithmetic or comparisons between date values, you almost always want them in the form of timestamps. A timestamp, by the way, is just a big number expressing the number of seconds since midnight on Thursday, 1 January 1970.
The PHP strtotime()
function converts human-readable dates to timestamps.
The PHP strftime()
function converts timestamps to human-readable dates
The Code
Because of the flexibility and intelligence of PHP’s strtotime()
function, you can specify the time interval in fairly plain language:
[code language=”php”]
$publishedOn = $resource->get(‘publishedon’);
if (empty($publishedOn)) {
return ”;
}
$t = strtotime(‘+1 year’, $publishedOn);
$dateString = $strftime(‘Y-m-d’, $t);
$resource->set(‘unpub_date’, $dateString));
$resource->save();
return ”;
[/code]
In the first four lines of the code above, we get the value of the resource’s publishedon
field and return without doing anything if it’s empty. If set, the publication date will be in the form of a human-readable date. In the fifth line, we set $t
to a timestamp, one year beyond the publishedon date. In the sixth line, we convert that timestamp to a human-readable date string. In the seventh line we use that date string to set the unpub_date
field. Finally, in the last line, we save the resource.
In line 5, we could easily change the interval using '+6 months'
, '+1 week'
, '+2 days'
, etc.
To make it easy to follow, the code above is unnecessarily lengthy. In fact, we could do it in fewer lines like this:
[code language=”php”]
$publishedOn = $resource->get(‘publishedon’);
if (empty($publishedOn)) {
return ”;
}
$resource->set(‘unpub_date’, $strftime(‘Y-m-d’, strtotime(‘+1 year’, $publishedon’)));
$resource->save();
return ”;
[/code]
A Faster Alternative
Another way to approach the problem takes advantage of the fact that when you connect the plugin to OnDocPublished
rather than OnDocFormSave
, the publication date is the current time. Using this method also means that the plugin will no longer run every time any resource is saved. Since strtotime()
uses the current time by default, you can skip getting the publishedon
field altogether and do something like this:
[code language=”php”]
$t = strtotime(‘+1 year’);
$resource->set(‘unpub_date’, $strftime(‘Y-m-d’, $t));
$resource->save();
return ”;
[/code]
Or the shorter version
[code language=”php”]
$resource->set(‘unpub_date’, $strftime(‘Y-m-d’, strtotime(‘+1 year’)));
$resource->save();
return ”;
[/code]
This code doesn’t need to check the publishedon
field, because it can assume that the resource is being published at the current time. Be aware that if the resource is unpublished, then published again, the Unpublish Date will be reset to a year from the current time. Note also that with this version, if the user manually sets an Unpublish Date, it will be ignored. To avoid that, we could do it like this:
[code language=”php”]
if (empty($resource->get(‘unpub_date’)) {
$resource->set(‘unpub_date’, $strftime(‘Y-m-d’, strtotime(‘+1 year’)));
$resource->save();
}
return ”;
[/code]
In the code above, if the unpub_date
field is already set to something, the plugin does nothing.
Creating the Plugin
In the Elements Tree, right-click on the “Plugins” folder and select “New Plugin.” Use the name AutoUnpub
for the plugin and paste in one of the code versions above. On the Plugin’s System Events tab, put a check next to either OnDocFormSave
or OnDocPublished
, depending on which version of the code you’re using.
Final Concerns
There are some possible issues with attaching the plugin to either OnDocFormSave
or OnDocPublished
. There are various ways a resource can be published, and not all of them will necessarily trigger the event that the plugin is attached to. If, for example, your plugin is connected to OnDocFormSave
and the resource is saved as unpublished. The plugin will not set the unpub_date
field. If the resources is later published, the plugin won’t act unless the OnDocFormSave
event is triggered. This will happen if you save it in the Manager or publish it through NewsPublisher in the front end, but may not happen if you bulk publish documents with an Extra like Batcher.
Similarly, if you attach the plugin to OnDocPublished
, it may not execute if you publish one or more documents through the Batcher extra or a resource is published by code in another snippet or plugin.
In either case, it will be easy to tell if the plugin has executed. Just load the resource in the Create/Edit Resource panel and see if the Unpublish Date is set.
Coming Up
In the next article, we’ll look at why you should never use the id
field of the User Profile to retrieve a user’s Profile.
For more information on how to use MODX to create a web site, see my web site Bob’s Guides, or
better yet, buy my book: MODX: The Official Guide.
Looking for quality MODX Web Hosting? Look no further than Arvixe Web Hosting!