SugarCRM Logic Hook Order of Execution

When you have more than one logic hook, several local logic hooks, and several global logic hooks, you wonder in what order will all these logic hooks fire.

This is something I haven't come across in the SugarCRM documentation, so its worth an article here.  The order of firing turns out to be important, because you can run into conflicts between the logic hooks creating loops and bugs that may be difficult to find.  Let's take it a step at a time and start with local logic hooks.

Here's an example of having multiple local logic hooks, in this case located in "custom/modules/Accounts/logic_hooks.php."

logic_hooks.php

logic_hooks.php

In this logic_hooks.php file we find two before_save, two after_retrieve, and one process_record logic hook.  Which of these three events fires first is controlled by the event itself.  The before_save event fires right before you save a record to the database, the after_retrieve event fires after a record is returned from the database, and the process_record event fires when a record is being processes as part of a list view or subpanel.

In this case, five different pieces of custom code are programed to fire when one of those events is triggered by user interaction.  The interaction of the user with the system controls when a particular event fires.  The developer has control over which event to use with his code, and so the developer controls when each type of event fires, but what about the two before_save or two after_retrieve hooks, which fires first?

The developer controls this with the number in the array.  In the before_save hooks, in the array values, you'll see a number as the first entry in the array, this controls the order of firing for the two before_save hooks.  In this case, first (1) the "Updates Email Addrs" will fire and then (2) the "Logic Hook - Accounts Before Save." hook.

If you have global logic hooks, located in "custom/modules/logic_hooks.php," the logic_hooks.php file also may have multiple logic hooks.  These are set up the same way the local logic hooks are set up as described above.  So what's the problem?

Well, the question arises, if I have two local before_save logic hooks and two global before_save logic hooks, which one fires first?  Do you alternate between the number one's, and then go to the number two's?  This is important if the custom code in one hook may alter, or change, the result produced by running the custom code in another logic hook.

To answer these questions, I created a series of test logic hooks.  I created three local before_save logic hooks, numbered 1, 2, and 3; and three global before_save logic hooks, numbered 1, 2, and 3.  I took all the other logic hooks out of the file so there would be no conflict with different types of events.  I kept the numbers the same in the local and global file, so there would be no confusion about the numbers themselves controlling the overall execution, for example, 4, 5, and 6.

If the numbers alone controlled the sequence of events, then the developer would have to keep track of the number they were on for each event throughout the system, not good.  The only thing I did with the code itself was output a log entry saying what the hook was, whether it was local or global, and what number was firing.  See my article on "The SugarCRM Error Log," if you want to know how to set the error log output up.

Here are log entry results:

06/20/13 16:00:33 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the before_save local_hook #1 for Contact.

06/20/13 16:00:33 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the before_save local_hook #2 for Contact.

06/20/13 16:00:33 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the before_save local_hook #3 for Contact.

06/20/13 16:00:33 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the global before_save hook #1.

06/20/13 16:00:33 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the global before_save hook #2.

06/20/13 16:00:33 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the global before_save hook #3.

So take away number one is that all the local logic hooks fire first, and they fire in number order, and then the global logic hooks fire in number order.

As long as I had this experiment set up, I decided to mess around with it a little more. I wanted to double check that the hook numbers themselves controlled the execution order within the local, or global logic hook, and not the hooks placement in the logic_hooks file.  I switched the numbers, between the 1, and 2, in both the local and global hooks to see if the position listed in the logic hook file mattered, or indeed the numbers controlled the sequence.  I altered the log message to show what "should" happen, if the numbers were what controlled the sequence.

And I did one more thing.  I changed the last two of the before_save hooks to after_save hooks to show how the events themselves determine the sequence.

Here's the result:

06/20/13 15:52:44 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the before_save local_hook #2 in Contact module.  Should fire 1st.

06/20/13 15:52:44 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the before_save local_hook #1 in Contact module,  Should fire 2nd.

06/20/13 15:52:44 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the global before_save hook #3. Should fire 1st.

06/20/13 15:52:44 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the global before_save hook #2. Should fire 2nd.

06/20/13 15:52:44 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the local after_save hook #3 in Contact module.

06/20/13 15:52:44 [3488][57faf14d-9e12-11e2-b875-d4bed953f95d][FATAL] This is the global after_save hook #1. Fires last because after_save global.

These results show that the numbers do indeed control the sequence of a particular event, and not their place in the logic hook file, and  for a particular event the local fires then the global hook.

 

Comments are closed.