Controlling execution order of Drupal modules
So lately, this had become a ‘stuff that breaks at work’ blog, but I fear that if I don’t document these, they’ll likely bite me again. And, if the solutions help someone else, then that’s great.
Our team recently launched a large website in Drupal that uses many home-grown modules. I discovered that with certain modules, the execution order is very important; especially authentication modules. We’d developed a module that interacts with the University’s single sign-on service and automatically creates or loads a Drupal user.
Order matters
Everything worked perfectly in testing except 403 handling. Specifically, when an unauthenticated user encounters a page that requires authentication or a certain role (via the privacy by role module), the user would expect to be routed to the single sign-on form, authenticate, and then be returned to the resource they originally requested. This wasn’t happening. The user would click a protected link, login, and then encounter the default 403 page: ‘Access Denied.’ The giveaway was that if you refreshed the page, the protected page would appear. After hours of debugging, I discovered that it was indeed the execution order. Our authentication module was being executed after the node load.
System.weight
Some Googling revealed the nearly undocumented ‘weight’ column in the system table. This column allows you to control the order/priority in which modules are executed. Most module will default to 0. To increase the priority, decrease the weight; to decrease the priority, increase the weight. With 90% of our modules at 0, and, assuming that we’d always want authentication to run first (even before the Node module), we set its weight to -1. This caused the authentication to fire before the node load and successfully load the requested page.
2 comments
Hi,
I just ran into the ‘Utility’ module (http://drupal.org/project/util) which allows you to modify the weight of modules via an admin interface.
Hey there, I wanted to give my example from today. Your post gave me the idea that my problem could be module execution order and it was! I was having to hide the image_attach form for a particular role and ran into the problem of multiple hook_form_alter()’s in different modules (in particular image_attach.module). My new hook_form_alter() was in my ‘article.module’ and was being squashed by image_attach.module so I moved the form function to my ‘item.module’ and it worked b/c it was firing after image_attach. Thanks! -Jordan
Comment on this post