Pages

Tuesday, October 11, 2011

SugarCRM Logic Hooks: Unintended Loops


There is something intriguing about working with logic hooks. Through their use, one can accomplish quite a bit given that the only real limitation is our ability to write PHP code. 

For example, we can use a logic hook to modify a value on a record that is being saved. We can also use it to connect to a web service and process data whenever a record is retrieved in SugarCRM. In addition, we can leverage the SugarCRM framework and add records in other modules, such as automatically adding a call upon the creation of a new Lead record.

Our possibilities are virtually endless, but at the same time, this power can sometimes present some odd problems that are difficult to troubleshoot or resolve. 

One such matter relates to the duplication of data, usually the result of what appears to be an unintended loop within the code executed by the logic hook. On the surface, this sounds simple enough to troubleshoot, but looks can be deceiving.

Lets take a look a code snippet which we will assume is being executed by our logic hook:

class LogicHookTest {
        function addContact(&$bean, $event, $arguments)
        {
             //Grab contact ID value stored in custom field on current record
             $contact_id = $bean->contact_id_c;         

             require_once('modules/Contacts/Contact.php');
             $contact = new Contact();

             //Retrieve Contact record with matching ID value
             $contact->retrieve($contact_id); 
             //Set value on Contact's custom field 
             $contact->custom_field_c = 'New Value';  
             $contact->save();
        }
}

To elaborate, the code is grabbing a value from the contact_id_c field of the record currently being accessed in SugarCRM and assigning it to the $contact_id variable. For the purposes of the example we will assume the record being accessed is in a custom module.

Next, the code instantiates a Contact object and uses that same $contact_id value to retrieve the record with the matching ID value from the Contacts module. Lastly, a custom field named custom_field_c is modified on that Contact record and then saved. 

In summary, the logic hook retrieves a record from the Contacts module and modifies a field on that record, without us actually needing to be in the Contacts module.

Assuming the referenced custom fields existed, the above code would work. However, this may not always yield the desired results, which leads us into the problem at the heart of this post.