Invoking MODX System Events

Firing MODX System Events in your own code


In my previous article, we looked at MODX system events, how they're fired, how plugins are executed, and how to make sure an event has fired. In this one, we'll look at invoking (firing) system events yourself in your own code.


MODX logo

Firing System Events

As we saw in my previous article, MODX system events are fired with $modx->invokeEvent('EventName', $parameters). It's almost always better to call a MODX processor to perform your action and let it invoke the appropriate events. There may be cases, though, where you want to fire an event yourself. The first step is to look at the code of the processor, found under the core/model/modx/processors/ directory or consult the reference here, to see what parameters the processor is expecting to get (sometimes there are none).


A Concrete Example

Imagine that you're working on a small part of a very large web site. Your job is to create code that blocks individual users based on bad behavior. You might track bad language or suspicious links used in forum posts, banned or spoofed IP addresses, etc. Using some algorithm, your code ultimately blocks the miscreant user by simply changing the active field of the modUser object for the current user from 1 to 0, so the user can no longer log in.

Suppose that there's already a system in place to send users an email explaining their new status when they're deactivated in the MODX Manager. The email gets sent by a plugin attached to the OnUserDeactivate event. If your code looks like this (you already have the user's ID):

$user = $modx->getObject('modUser', $userId);
$user->set('active', 0);
$user->save();

the email will never get sent.

To fix this, you need just need to fire the OnUserDeactivate event yourself. Since there is also an OnBeforeUserDeactivate event fired when a user is deactivated in the Manager, you should fire that as well.

You could do this by calling the security/user/update processor, which would fire the events for you, but it's cumbersome. That processor does a lot of things you don't need (like handling the user profile), and it requires properties that you don't really need to send to accomplish your goal. At this writing, there's no security/user/deactivate processor, so it's a lot easier and more efficient to just fire the appropriate events yourself.


Expected Parameters

If you look at the code that runs when a user is deactivated in the manager, you'll see that both events expect these parameters:

  • 'id' — The ID of the user
  • 'user' — The user object (passed by reference)
  • 'mode' — modSystemEvent::MODE_UPD for single users, 'multiple' for multiple users

Your New Code

$user = $modx->getObject('modUser', $userId);

$params = array(
    'id' => $id,
    'user' => &$user,
    'mode' => modSystemEvent::MODE_UPD,
);

$user->set('active', 0);

$modx->invokeEvent('OnBeforeUserDeactivate', $params);

if ($user->save() === false) {
     $modx->log(modX::LOG_LEVEL_ERROR,$this->modx->lexicon('user_err_save'));
} else {
    $modx->invokeEvent('OnUserDeactivate', $params);
}

Now, the email gets sent, and any other plugins (current or future) attached to either event will also execute as they should.

For security, you might also want to make sure that the current user has permission to save a user object with code like this at the top (but below where you initialize the $user variable):

if (! $user->hasPermission('save_user')) {
   /* Handle permission failure */
}

Earlier in your code, you might also want to make sure the user object exists and handle the error if it doesn't.

If your code is in a method inside a class, you'll probably want to set a $modx class variable to the modX object and replace $modx with $this->modx in the code above.


Wrapping Up

You can fire any MODX system event by just setting the expected parameters and calling $modx->invokeEvent(). Now that you understand the process, you may even want to create your own system events so you can invoke them in your code. We'll look at how to do that in the next article.



Looking for high-quality, MODX-friendly hosting? As of May 2016, Bob's Guides is hosted at A2 hosting. (More information in the box below.)



Comments (0)


Please login to comment.

  (Login)