Summary: Record the last action for each user so that stale accounts can be detected
Version: 2007-03-25
Prerequisites: pmwiki-2.1.26 (may work with other versions), AuthUser (may work with UserAuth)
Status: stable
Maintainer: Lordmundi

Questions answered by this recipe

  • How can I detect stale accounts?
  • How can I tell the last time a user logged in?
  • How can I keep track of the last action performed by each user?


This recipe will record the last action of each user into a file so that stale accounts can be detected.


  1. Copy user_last_action.phpΔ to the cookbook directory
  2. add include_once("$FarmD/cookbook/user_last_action.php"); to config.php.
  3. Optionally, configure using configuration options below

NOTE: The recipe script must be included after scripts/authuser.php or scripts/author.php to have the {$AuthId} and {$Author} wiki variables properly defined.


Sets the page name to be used to record page actions. Make sure it contains some sort of variable to be replaced with the author name (defaults to Profiles.{$AuthId}-LastAction).
An array of usernames which the script will ignore (defaults to array('admin')). For example, in your config file, you could have the recipe "admin" and "guest" with the line:

$LastUserActionIgnoreUsers = array('admin', 'guest');
Format of string to be recorded. Defaults to:
' ACTION - [[TARGET]] on %Y-%m-%d %H:%M:%S from REMOTE_ADDR'

An alternative format that I use that puts the date in front (more easily sorted by date visually):
$LastUserActionLineFmt = ' %Y-%m-%d %H:%M:%S * {$AuthId} * ACTION [[TARGET]] from REMOTE_ADDR';

is the address of the user.
is the interaction he had with...
the page concerned.
<time variables>
as documented by php's strftime routine

Recommended Use

Since it is easier to just the (:include Profiles.<user>-LastAction:) markup, I didn't add custom markup to return the last action for a particular user.

The way I wanted to use this was to be able to generate a pagelist of user profile pages (on my wiki, every user is forced to have a profile page), and then next to each user, show their last action. Since the line recorded (at least with the default format) is a single line, the page can be included to show the last action string. I created a pagelist custom format to do this on my Site.LocalTemplates page. To learn more about pagelist custom formats, see PageLists.

I have the following pagelist template in Site.LocalTemplates (note the (:include :) command which pulls in the string from the -LastAction page):

(:if equal {<$Group}:)
(:table width="90%" :)
(:cell width=30% style="background:#e5e5ff;padding-left:5px" :)'''User'''
(:cell width=70% style="background:#e5e5ff;padding-left:5px" :)'''Last Action''' 
(:cellnr width=30% style="background:#eeeeff;padding-left:25px" :)[[{=$FullName}]] 
(:cell width=70% style="background:#eeeeff;padding-left:5px" :)(:include {=$FullName}-LastAction:)
(:if equal {>$Group}:)

And I invoke the list with the following markup (lists all Profile pages ignoring some specific ones):

(:pagelist group=Profiles name=-GroupFooter,-Profiles,-RecentChanges,-*-LastAction fmt=Site.LocalTemplates#userlist:)

This produces a list like this:


This recipe was originally intended to be a way to record the last login of each account, but it looked easier to just record the last action for each account which would achieve the same purpose (detect stale accounts).

Code was inspired by code in ActionLog and TotalCounter.

Also, this is my first recipe, so go easy on me and feel free to customize, add, subtract, whatever.

Release Notes

  • 2007-03-25: Updated to fix shutdown function dir weirdness that sometimes occues with apache. Now, the script is able to cope with "register_shutdown_function" sometimes changing directories beneath our feet. Also added a check to immediately return if user is not logged in.
  • 2007-03-20: First release.


See Discussion at UserLastAction-Talk

  • It would be nice if this recipe also added a page variable with the date alone in it. That way, the page variable could be accessed and things could be sorted (such as the pagelist above) on the date. Lordmundi
    I found a way to do this by using the new page text variables stuff in 2.2. Simply change your format string to include a hidden page text variable and then whatever you want after it... like this:
    $LastUserActionLineFmt = 
      '(:LastActionDate: %Y-%m-%d %H:%M:%S:) %Y-%m-%d %H:%M:%S * ACTION [[TARGET]] from REMOTE_ADDR';
    Then, to get out the data, just use the page text variable syntax, such as:
    Now that you have that, you can create a pagelist that sorts on that variable. See this page for more info on pmwiki's new page text variable stuff and how to use.
  • forceflow: I had some problems with this cookbook script since it kept interfering with pagelist cache. The disabling of file mod tracking in the current implementation does not work (presumably because you forgot to import $LastModFile as a global. See user_last_action_lastmodfix.phpΔ

See Also


User notes? : If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.