Managing .module file using hook_hook_info

Did you know? Using hook_hook_info, so we can reduce the size of loc in .module file and we can segregate  all the hooks in a single  custom module file.

Since all .module files get read and executed  for every Drupal menucallback execution, the size of the .module file directly impacts  performance. The .module file should always have just the necessary amount of code. hook_hook_info helps us to segregate & move all hook specific code to a separate file.

The Performance advantage is minimal when opcode caching is used. It still servers helps is managing code.

I am going to explain hook_hook_info with an example module (my_module.module). my_moudle.module uses  4 hooks (list below). 

Example :

Module name = my_module.module.

1) hook_node_insert

2) hook_node_delete

3) hook_comment_insert

4) hook_comment_delete

my_module.module file will have the below content:

function my_module_hook_info() { $hooks['node_insert'] = array( 'group' => 'node' ); $hooks['node_delete'] = array( 'group' => 'node' ); return $hooks; }

Create a separate inc file for all the groups. In our example we need two inc file one for ‘node’ and another for ‘comment’. The inc file should be in the format $module.$group.inc to be picked up by hook_hook_info(). In my example the inc files are:

1) my_module.node.inc

2) my_module.comment.inc

Inside my_module.node.inc declare :

function my_module_node_insert($node) { dpm($node); } function my_module_node_delete($node) { dpm($node); }

Inside my_module.comment.inc declare :

function my_module_comment_insert($comment) { dpm($comment); } function my_module_comment_delete($comment) { dpm($comment); }

When a Drupal hook is executed, Drupal triggers module_invoke_all. If your module uses a hook either directly in the module or by using  hook_hook_info(), the associated inc files will get invoked. The inc files also get triggered from module_invoke for the associated hook.

The sequence of functions executed,  how and where the inc files get included

For a specific hook, module_invoke_all is triggered, followed by module_implements. In module_implements the hook_info implementations are obtained from module_hook_info(). This is then parsed and the inc files are loaded in a loop. The below lines of code in the module_implements is what does these actions:

foreach ($list as $module) { $include_file = isset($hook_info[$hook]['group']) && module_load_include('inc', $module, $module . '.' . $hook_info[$hook]['group']); // Since module_hook() may needlessly try to load the include file again, // function_exists() is used directly here. if (function_exists($module . '_' . $hook)) { $implementations[$hook][$module] = $include_file ? $hook_info[$hook]['group'] : FALSE; } }

In my case, the above the line will include my_module.node.inc, my_module.comment.inc at runtime for the corresponding  hooks node and comment.

Use this feature to your advantage, reduce the size of your module files!

Example