Let the platform do the work

Logic Hooks

Overview

The Logic Hook framework allows you to append actions to system events such as when creating, editing, and deleting records.

Hook Definitions

A logic hook definition file defines the various actions to execute when an event is triggered. It is important to note that there are various ways to implement a logic hook. The following sections describe the different ways to implement a logic hook and when to use each.

Methodologies

Logic hook definitions can pertain to a specific module or to the entire application. Either way, you must decide if the logic hook definition will be implemented as an extension of or directly to the module or application. The following sections explain the difference between these methodologies.

Module Extension Hooks

Module extension hooks are located in ./custom/Extension/modules/<module>/Ext/LogicHooks/ and allow a developer to define hook actions that will be executed for the specified events in a given module. Extensions are best used when creating customizations that may be installed in various environments. They help prevent conflicting edits that occur when modifying ./custom/modules/<module>/logic_hooks.php. More information can be found in the Logic Hooks extension section.

Module Hooks

Module hooks are located in ./custom/modules/<module>/logic_hooks.php and allow a developer to define hook actions that will be executed for the specified events in a given module. This path can be used for private development, however, it is not recommended for use with distributed modules and plugins. For distributed code, please refer to using module extensions.

Application Extension Hooks

Application extension hooks are located in ./custom/Extension/application/Ext/LogicHooks/ and allow a developer to define hook actions that will be executed for all specified application-level events using the extension framework. More information can be found in the Logic Hooks extension section.

Application Hooks

Application hooks are located in ./custom/modules/logic_hooks.php and allow a developer to define hook actions that will be executed for the specified events in all modules. This path can be used for private development, however, it is not recommended for use with distributed modules and plugins. For distributed code, please refer to using application extensions.

Definition Properties

All logic hooks must have a $hook_version and $hook_array variable defined. The following sections cover each required variable.

hook_version

All logic hook definitions will define a $hook_version. This determines the version of the logic hook framework. Currently, the only supported hook version is 1.

  $hook_version = 1;

hook_array

The logic hook definition will also contain a $hook_array. This defines the specific action to execute. The hook array will be defined as follows:

Name Type Description
event_name String The name of the event to append the action to
process_index Integer The order of action execution
description String A short description of the hook action
file_path String The path to the logic hook file in the ./custom/ directory, or null if using namespaces
class_name String The name of the logic hook action class including any namespaces
method_name String The name of the logic hook action method

Your definition should resemble the code block below:

  <?php

    $hook_version = 1;

    $hook_array['<event_name>'][] = array(
        <process_index>, //Integer
        '<description>', //String
        '<file_path>', //String or null if using namespaces
        '<class_name>', //String
        '<method_name>', //String
    );

Hook Method

The hook action class can be located anywhere you choose. We recommended grouping the hooks with the module they are associated with in the ./custom/ directory. You can create a hook action method either with a namespace or without.

Namespaced Hooks

As of 7.7, developers can create namespaced logic hooks. When using namespaces, the file path in ./custom/ will be automatically built out when using the corresponding namespace. The filename defining the class must match the class name exactly to allow the autoloader to find the class definition.

Namespace File Path
Sugarcrm\Sugarcrm\custom ./custom/
Sugarcrm\Sugarcrm\custom ./custom/src/
Sugarcrm\Sugarcrm\custom\any\path ./custom/any/path/
Sugarcrm\Sugarcrm\custom\any\path ./custom/src/any/path/

./custom/Extension/modules/Accounts/Ext/LogicHooks/<file>.php

  <?php

    $hook_array['before_save'][] = array(
        1,
        'Hook description',
        null,
        'Sugarcrm\\Sugarcrm\\custom\\modules\\Accounts\\className',
        'methodName'
    );
?>

./custom/modules/Accounts/className.php

  <?php

namespace Sugarcrm\Sugarcrm\custom\modules\Accounts;

    class className
    {
        function methodName($bean, $event, $arguments)
        {
            //logic
        }
    }
?>

The logic hook method signature may contain different arguments depending on the hook event you have selected.

Hooks without Namespaces

./custom/Extension/modules/Accounts/Ext/LogicHooks/<file>.php

  <?php

    $hook_array['before_save'][] = array(
        1,
        'Hook description',
        'custom/modules/Accounts/customLogicHook.php',
        'className',
        'methodName'
    );
?>

./custom/modules/Accounts/customLogicHook.php

  <?php

    class className
    {
        function methodName($bean, $event, $arguments)
        {
            //logic
        }
    }
?>

The logic hook method signature may contain different arguments depending on the hook event you have selected.

Considerations

When using logic hooks, keep in mind the following best practices:

  • As of PHP 5.3, objects are automatically passed by reference. When creating logic hook signatures, do not append the ampersand (&) to the $bean variable. Doing this will cause unexpected behavior.
  • There is no hook that fires specifically for the ListView, DetailView or EditView events. Instead, use either the process_record or after_retrieve logic hooks.
  • In order to compare new values with previous values, use fetched_row to determine whether a change has occurred:
    if ($bean->fetched_row['{field}'] != $bean->{field})
    {
        //logic
    }
  • Make sure that the permissions on the logic_hooks.php file and the class file that it references are readable by the web server. Otherwise, Sugar will not read the files and your business logic extensions will not work. For example, *nix developers who are extending the Tasks logic should use the following command for the logic_hooks file and the same command for the class file that will be called:
    chmod +r ./custom/modules/Tasks/logic_hooks.php
  • Make sure that the entire ./custom/ directory is writable by the web server or else the logic hooks code will not work properly.