Pages

Friday, June 30, 2017

SugarCRM: Customization Tips

One of the tasks we regularly perform within the Technical Account Management team at SugarCRM is review customizations, especially code level modifications. Two of the main objectives behind such reviews are:

Identify areas of opportunity (customizations that can be further refined or optimized)

Catalog potential pitfalls one may encounter were the instance upgraded

A challenge posed by such reviews is that any given instance can include customizations that touch a wide variety of the framework features and in different ways. Despite this, certain patterns emerge that point at common habits that require some level of attention and are applied while customizing Sugar. The more common behaviors are discussed in this post in hopes they will help you avoid some frustrations.1. Incomplete WHERE clauses. SugarQuery is the preferred mechanism for querying the Sugar database programmatically. However, executing an ad-hoc query is sometimes unavoidable. For such scenarios, always remember that Sugar performs soft deletes of its data. Thus, when attempting to interact with "active" records in the database, one must add the deleted = 0 condition to the WHERE clause, or run the risk of working with dirty data. This requirement spans across nearly all tables in the Sugar database, including the relationship tables such as accounts_contacts. Below is an example of its use:SELECT * FROM contacts WHERE first_name = 'Angel' AND deleted = 0;2. Using database platform specific features. Expanding on the previous point, the use of raw SQL queries is sometimes unavoidable. Should you find yourself in such a scenario, bear in mind the intended scope of your customization. If you intend for your customization to reach a large number of Sugar instances, avoid using database platform specific features as doing so will automatically cause your customization to only work on a single database platform. For example, should we rely on the database engine to generate a GUID for us, MySQL allows us to use the UUID(), whereas MS-SQL uses NEWID(). Herein is the value of generating such a value via PHP or JavaScript, instead of at the database level, given that leveraging the database engine to generate the value would effectively bind our customization to that database platform.

3. Overlooking time zones. A third example of ad-hoc SQL queries that can cause problems are those that overlook time zones. Sugar always stores date and time values as UTC. As a result, SQL queries that insert or read date time values must compensate for the difference between UTC and the local time zone. An example of a common error is using DATE() versus UTC_DATE() on MySQL or DATE() versus GMDATE() on PHP. 4. Including extraneous methods in custom controllers. The Sidecar framework allows us to extend default controllers that in turn can be used to introduce new JavaScript methods or override existing methods to modify the default logic. Quite often, custom controllers reference methods that do not fit either of that criteria. For example, a customization that extends an existing Sidecar controller might include code as follows:initialize: function(options){ this._super('initialize', [options]);},The above code is not necessary for two reasons: first, it does not alter the behavior of the default initialize() method provided by the parent controller we are extending, it merely invokes the parent controller version of the method; secondly, the parent controller will automatically invoke its default methods (including initialize), eliminating the need for us to explicitly invoke them in our extensions to that controller.From a functional standpoint, the above behavior is unlikely to cause problems with your customization, however, it does add noise and should be avoided.5. Hardcoding strings. The Sugar framework provides a facility for creating language extensions which in turn can be used to define strings one uses in a customization, e.g. a field label. These string definitions can be accessed programmatically via PHP and JavaScript, thus making them accessible throughout the entire Sugar application.Language extensions should always be used to define strings given they also make it simpler to localize a customization.