Dealing with User Role IDs in Features

February 6, 2014
blog author



Anyone who uses Features to deploy code to different development environments has probably encountered this issue at one point or another: Your feature works fine on your local environment, but once deployed, just refuses to work. There are a few things you could look for, and one of those is user role IDs.

As of this writing (Drupal 7), user roles have no machine names, rather, they are identified by role IDs. The issue here is that the same role ID could mean different roles on different environments. So if your feature export includes user role IDs, once they are imported on a different environtment, if you're lucky, the feature will just not work because there are no such role IDs. If you're really unlucky, then you might end up associating the feature with the wrong role, such as giving administrative power to someone you shouldn't.

Two common modules that export user roles by their IDs are Views and Rules.  Fortunately for us, they do provide a way to alter their values before importing through: hook_views_default_views_alter() and hook_default_rules_configuration_alter(). In these hooks, you can set the role ID values to the appropriate role IDs of the local environment. This is not a perfection solution because you are, essentially, hardcoding your logic (role) in your code. If for any reason, you decide to change the roles in your Views/Rules (from the UI) and re-deploy again, you need to go back to your code and update it with the corresponding roles. Otherwise, it will override whatever changes you made.

That was two modules out of the thousands of modules that Drupal has. That's great, but what about the rest of the modules that don't provide a way for us to modify their exports?

For modules that store their configurations in Drupal's variable table, Strongarm provides a way to export those settings into features. However, you're still running into the issue of roles being exported by their IDs, rather than role names. A simple patch to the strongarm module allows you to hook into the export (hook_strongarm_export_value_alter()) and import (hook_strongarm_import_value_alter()) processes of strongarm. One way to do this is in hook_strongarm_export_value_alter(), convert role IDs into role names. Then in hook_strongarm_import_value_alter(), convert role names back to role IDs. The great thing about this is that you're not hardcoding anything. Any changes from the development environment will be captured by hook_strongarm_export_value_alter() automatically, and hook_strongarm_import_value_alter() will just convert it back when you deploy it.

So until Drupal has a way of persisting user role identifers across environments, *_alter() away.