Let the platform do the work

Controller

Overview

The basic actions of a module.

Controllers

The main controller, named SugarController, addresses the basic actions of a module from EditView and DetailView to saving a record. Each module can override this SugarController by adding a controller.php file into its directory. This file extends the SugarController, and the naming convention for the class is: <module>Controller

Inside the controller, you define an action method. The naming convention for the method is: action_<action name>

There are more fine-grained control mechanisms that a developer can use to override the controller processing. For example, if a developer wanted to create a new save action, there are three places where they could possibly override.

  • action_save: This is the broadest specification and gives the user full control over the save process.
  • pre_save: A user could override the population of parameters from the form.
  • post_save: This is where the view is being set up. At this point, the developer could set a redirect URL, do some post-save processing, or set a different view.

Upgrade-Safe Implementation

You can also add a custom Controller that extends the module's Controller if such a Controller already exists. For example, if you want to extend the Controller for a module, you should check if that module already has a module-specific controller. If so, you extend from that controller class. Otherwise, you extend from SugarController class. In both cases, you should place the custom controller class file in ./custom/modules/<module>/Controller.php instead of the module directory. Doing so makes your customization upgrade-safe.

File Structure

  • ./include/MVC/Controller/SugarController.php
  • ./include/MVC/Controller/ControllerFactory.php
  • ./modules/<module>/Controller.php
  • ./custom/modules/<module>/controller.php

Implementation

If the module does not contain a controller.php file in ./modules/<module>/, you will create the following file:

./custom/modules/<module>/controller.php

class <module>Controller extends SugarController
{
    function action_<action>()
    {
        $this->view = '<action lowercase>';
    }
}

If the module does contain a controller.php file, you will need to extend it by doing the following:

./custom/modules/<module>/controller.php

require_once 'modules/<module>/controller.php';

class Custom<module>Controller extends <module>Controller
{
    function action_<action>()
    {
        $this->view = '<action lowercase>';
    }
}

Note: When creating or moving files you will need to rebuild the file map.

More information on rebuilding the file map can be found in the SugarAutoLoader.

Mapping Actions to Files

You can choose not to provide a custom action method as defined above, and instead, specify your mappings of actions to files in $action_file_map. Take a look at ./include/MVC/Controller/action_file_map.php as an example:

$action_file_map['subpanelviewer'] = 'include/SubPanel/SubPanelViewer.php';
$action_file_map['save2'] = 'include/generic/Save2.php';
$action_file_map['deleterelationship'] = 'include/generic/DeleteRelationship.php';
$action_file_map['import'] = 'modules/Import/index.php';

Here the developer has the opportunity to map an action to a file. For example, Sugar uses a generic sub-panel file for handling subpanel actions. You can see above that there is an entry mapping the action 'subpanelviewer' to ./include/SubPanel/SubPanelViewer.php.

The base SugarController class loads the action mappings in the following path sequence:

  • ./include/MVC/Controller
  • ./modules/<module>
  • ./custom/modules/<module>
  • ./custom/include/MVC/Controller

Each one loads and overrides the previous definition if in conflict. You can drop a new action_file_map in the later path sequence that extends or overrides the mappings defined in the previous one.

Upgrade-Safe Implementation

If you want to add custom action_file_map.php to an existing module that came with the SugarCRM release, you should place the file at ./custom/modules/<module>/action_file_map.php

File Structure

  • ./include/MVC/Controller/action_file_map.php
  • ./modules/<module>/action_file_map.php
  • ./custom/modules/<module>/action_file_map.php

Implementation

$action_file_map['soapRetrieve'] = 'custom/SoapRetrieve/soap.php';

Classic Support (Not Recommended)

Classic support allows you to have files that represent actions within your module. Essentially, you can drop in a PHP file into your module and have that be handled as an action. This is not recommended, but is considered acceptable for backward compatibility. The better practice is to take advantage of the action_<action> structure.

File Structure

  • ./modules/<module>/<action>.php

Controller Flow Overview

For example, if a request comes in for DetailView the controller will handle the request as follows:

  1. Start in index.php and load the SugarApplication instance.
  2. SugarApplication instantiates the SugarControllerFactory.
  3. SugarControllerFactory loads the appropriate Controller.
  4. SugarControllerFactory checks for ./custom/modules/<module>/Controller.php.
    1. If not found, check for ./modules/<module>/Controller.php.
    2. If not found, load SugarController.php.
  5. Calls on the appropriate action.
    1. Look for ./custom/modules/<module>/<action>.php. If found and ./custom/modules/<module>/views/view.<action>.php is not found, use this view.
    2. If not found check for modules/<module>/<action>.php. If found and ./modules/<module>/views/view.<action>.php is not found, then use the ./modules/<module>/<action>.php action.
    3. If not found, check for the method action_<action> in the controller.
    4. If not found, check for an action_file_mapping.
    5. If not found, report error "Action is not defined".