Logging Actions in your ExpressionEngine Add-ons

2 comments

Written on March 1st by Erik Reagan

Logging Actions in your ExpressionEngine Add-ons

I've recently given some thought to a piece of EE that I have never had a great need for. Control Panel logging. Out of the box, ExpressionEngine logs certain actions that are performed in the CP saving the Site ID, Member, IP Address of that member, date/time and the action performed. This can be very useful when trying to figure out when something happened and who may have done it. It can also help see how many people might be logging in under the same account from various locations (IPs). This is all great but quite limited considering the number of actions for which this occurs.

Developers: Throughout this article the word "action" is not referring to the exp_actions table which is used in tandem with Modules. It is simply referring to "an act that is performed" in the Control Panel.

General Notice: This article is considering EE 1.6.x features only. While the same functionality may be possible in EE 2.x, I have not tested it. When I do test it in 2.x I will update any code/verbiage necessary.

What is logged?

Without extending ExpressionEngine at all, the following actions are logged:

  • A member logs in
  • A member logs out
  • A SuperAdmin logs in as another member
  • Member group settings are changed
  • A new member profile is created
  • A member profile field is deleted
  • A member's email address is updated
  • A member's username/password is updated
  • A weblog/channel's preferences are updated
  • A weblog/channel gets deleted
  • A category field gets deleted
  • A category group is created, updated or deleted
  • A status group is created, updated or deleted
  • A field group is created, updated or deleted
  • A custom field is deleted
  • An upload preference is deleted

As you see from the list above, the primary function of the Control Panel Log is to record more administrative actions to the log. That's a useful thing to have if you need to track down who may have performed an administrative action. However, what if you need to know who last saved a certain weblog/channel entry or who posted the last entry? What about logging actions on your custom Extensions or Modules? This is certainly doable with some simple code so let's take a look now.

Logging your own actions

In order to log actions you first need to load the Logger class in ExpressionEngine. This class is located in system/cp/cp.log.php and contains functions for logging and clearing three logs: the CP log (what we are talking about), the Search Term log and the Throttle log. Today we are just looking at a single function, log_action(). The function only takes a single parameter and will only be executed on a logged in member. This isn't something that should necessarily be used in your templates (though it is technically possible).

The rest of the article will be in the context of your add-on so open up an extension or module you've written or just test this out in a template for the time being. I advise you only to this in a test environment until your comfortable and always backup your database when trying something new.

To load the class we will first double check to make sure the class doesn't already exist (always good practice) then use PHP's require() function followed by creating a new log object. That looks like this:

<?php

if( ! class_exists('Logger') )
{
   
// PATH_CP is the system path to your cp class files and EXT is
   // the file extension. Both are constants set by EE
   
require PATH_CP 'cp.log' EXT;
}

// I tend to use all caps to stay consistent with EE's approach to
// naming objects 
$LOG = new Logger;

?> 

Now that we have the Logger class loaded into our add-on we just need to log an action. This part is as easy as it gets. As I mentioned earlier, the log_item() function only takes one parameter which is either the string message or an array of messages that you send it. Just to do a quick test let's throw a random string in there.

<?php

if( ! class_exists('Logger') )
{
   
// PATH_CP is the system path to your cp class files and EXT
   // is the file extension. Both are constants set by EE
   
require PATH_CP 'cp.log' EXT;
}

// I tend to use all caps to stay consistent with EE's approach to
// naming objects 
$LOG = new Logger;

// Log a test string
$LOG->log_action("Testing new CP log item");

?> 

Our results

Loading the extension/module you're testing this with will execute the logging so now go view your CP Log located under Admin → Utilities → View Control Panel Log. You should now see the new item logged like in the image below. See, that wasn't so hard was it?

Logged item screenshot

You can turn your message string into an array and produce multiple lines of text if you'd like. Consider the following example:

<?php

if( ! class_exists('Logger') )
{
   
// PATH_CP is the system path to your cp class files and EXT
   // is the file extension. Both are constants set by EE
   
require PATH_CP 'cp.log' EXT;
}

// I tend to use all caps to stay consistent with EE's approach to
// naming objects 
$LOG = new Logger;

// Log a test array producing multiple lines of text
$LOG->log_action(array("This is line 1 of my message","This is line 2 of my message"));

?> 
Logged item screenshot 2

That would produce a logged item like the one seen in the picture to the right. You can create as many lines as you want/need using an array instead of a string. This can be particularly helpful if you want a message that is more than just a few words long which includes more specifics of an action.

So how can I use this?

I'm glad you asked! You can use this just about anywhere you might need inside of your Module or Extension. Let's take my Redirect Helper Lite module and use it as an example. If a user has permission to use that module they can create, modify and delete redirect rules for their website. Say I want to add a log record every time a redirect rule is created, modified or deleted. I simply add something like this to each method performing those specific actions:

<?php

// I'm excluding any additional code that would be in or around my method

// Log record of user updating the redirect entry using a variable
// available within my method
$LOG->log_action("Redirect Helper Lite: '".$fields['redirect_name']."' was modified");

?> 

This will record the name of the redirect entry (based on the form results, not relevant to our topic). Reloading our Log should show the new action as seen in the image below.

Logged item from Redirect Helper Lite screenshot

Go forth, Big Brother

As you can see, you can log actions provided it is either your custom module or you tap into an existing Hook in the system. It's pretty powerful but there's no need to go crazy. With this knowledge combined with an understanding of the available hooks in the system, you can extend the usefulness of the Control Panel Log.

Enjoy!

Comments

Awesome work, I was just about to write this same functionality myself. :)

Nathan Pitman on Mar 18th at 10:07 am

This kicks ass. Thanks.

Rob Sanchez on Mar 30th at 4:48 pm

Your Words of Wisdom

Remember me       Notify me of follow-up comments