Sunday, April 5, 2015

How I Solved "Fatal error Class 'JModuleHelper' not found" Error in Joomla

Before I tell you how I solved this, let me give you these tips:
  1. JModuleHelper is a very commonly used module in the Joomla! framework. There is no one reason why an error relating to this module will be raised. It is very context-dependent.
  2. If you are using a template or template framework (I use RocketTheme's Gantry framework), switch to a built-in template before you let yourself get hauled down the path of wondering what's wrong in Gantry. Probably nothing.
So here's the context of my problem: I was calling JUser::save() and that was resulting in the "Fatal error Class 'JModuleHelper' not found" error. The error message was being raised inside the Gantry framework, so I figured that's where the problem was. However, following principal #2 above, I switched to a "stock" template and got the same result. To be clear: I did not see the same error, which seems to be because Gantry does a great job of reporting problems rather than ignoring them. But the result of the JUser::save() method was the same.

Next, I peppered the JUser::save() method with error_log() calls so I could find out where it was encountering the error. Turns out, it was having problems at the very end when it triggers the 'onUserAfterSave' event in various listeners.
I then grep-ed for all php files that register an interest in the 'onUserAfterSave' event and came up with a list of four plugins:
  1. plugins/user/profile/profile.php
  2. plugins/user/contactcreator/contactcreator.php
  3. plugins/user/joomla/joomla.php
  4. system/languagefilter/languagefilter.php
Again, using my paleolithic debugging approach, I put an error_log('entering profile') and error_log('leaving profile') statement in each plug in, changing the logged message to indicate which plugin was logging the message. Then when I called JUser::save(), I got the expected messages in my log file EXCEPT for the ones relating to contactcreator.php.

Ultimately, what it turned out to be was this: I was testing by adding a user, logging in with that user's credentials, deleting the user from the Joomla! Administrator interface, then adding the user again. ContactCreator is a plug in that came with my Joomla distribution and was enabled, probably by default, but I don't know that for certain. When ContactCreator is notified of the "onUserAfterSave" event, ContactCreator adds a record to the contact_details table, including inserting a value in an `alias` column of the database. The values in `alias` have to be unique.

When you delete a user using the Joomla! Administrator console, ContactCreator does NOT delete the contact_details record. I don't know who uses ContactCreator, but it has the ability to store a LOT of information about a user--information that you probably don't want to lose just because you deleted the user's record. So maybe this is good behavior.

The problem is that when you call JUser::save() again with the same person's NAME, ContactCreator creates a duplicate `alias`. Instead of updating the corresponding record in the contact_details table, it tries to INSERT and it fails due to the violation of unique constraint. That failure propogates up and, in my world, resulted in Gantry complaining that it could not find the JModuleHelper class. Once I disabled the ContactCreator plugin from the Joomla! Administrator console, my system worked perfectly.

I thought about modifying the plug in to do an "upsert" operation, but I don't care about this plug in and didn't want to get into a battle with Joomla! updates overwriting my changes. If you need this plugin and you are getting the same error I got, you'll need a more robust solution.

No comments:

Post a Comment