Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / PHP

How to Enhance SuiteCRM REST API to Handle Case Updates Transactions

5.00/5 (1 vote)
25 Oct 2016CPOL6 min read 11.2K   59  
Tutorial about adding new API method to SuiteCRM APIs

Introduction

In recent months, I’ve designed and developed several Customer Portal projects for SuiteCRM. These applications are working based on SuiteCRM REST API. But there is a serious weakness in SuiteCRM API in response to all that we need.

So, as you know, the most important part of each common Customer Portal is a part that lets users put updates on their Tickets or Cases. But, unfortunately, there is no REST API method in SuiteCRM that allows developers to select the existing updates of a Case or Put new update for a case.

Using the Code

Ok, in this article, I will show you how to add two new APIs to SuiteCRM.

  1. To begin, you should understand the structure of SuiteCRM API service. SuiteCRM API has a core and several enhancements version. So, the latest version of SuiteCRM API is 4.2. For reviewing each version’s features, you can visit SugarCRM website.

    If you open the ‘service’ folder on this SuiteCRM root folder, then you will see the structure as follows:

    So, the folder that their name begins with ‘v’ is various versions of SuiteCRM APIs. This is very important to know that each version has all previous versions functionalities as also each extended classes from their last version.

  2. In each version folder, you will see this common structure:

    For creating and developing your own version of SuiteCRM API, you should change some code in all files. It’s very logical and practical that you extend your SuiteCRM API version from the latest version (v 4.1) of SuiteCRM API. So let's start.

  3. For creating your own service, clone the v4_1 folder and rename it to your version name. I rename it to fcc.
  4. So, rename the two files (SugarWebServiceImplv4_1.php, SugarWebServiceUtilv4_1.php) and replace v4_1 phrase to your version name. For example, I renamed them to SugarWebServiceImplfcc.php and SugarWebServiceUtilfcc.php. For your knowledge, the main codes of your extended version will be written in these two files.
  5. Now open the rest.php file. In the rest.php file, you should register and include all of your API version. So, it’s very easy and not complicated. As I mentioned below, my API name is fcc. So you can see the code of rest.php for fcc:
    PHP
    require_once('SugarWebServiceImplfcc.php');
    $webservice_class = 'SugarRestService';
    $webservice_path = 'service/core/SugarRestService.php';
    $webservice_impl_class = 'SugarWebServiceImplfcc';
    $registry_class = 'registry';
    $location = '/service/fcc/rest.php';
    $registry_path = 'service/fcc/registry.php';
    require_once('service/core/webservice.php');
    

    You should repeat this step for the soap.php file too.

  6. So, the next file we discuss is SugarWebServiceUtilfcc.php. The SugarWebServiceUtil[version name].php contains all utilities and helper functions that you use in the main API method. So, this file contains a class that is extended from one of the latest versions. As I mentioned, it’s better to extend from the latest version of SuiteCRM API service that is v4_1. So, the class structure will be such as follows:

    So, depending on your API functions needs, you can write your own functions in this class. Also, as you can see, you need to include the SugarWebServicecUtilv4_1.php in your script. It points to the version that you extend your API from.

    PHP
    require_once('service/v4_1/SugarWebServiceUtilv4_1.php');
    
    class SugarWebServiceUtilfcc extends SugarWebServiceUtilv4_1
    {
        // Your functiions
    }
    
  7. In this step, we start to write our own API method functions. The main API method and functions are written in the SugarWebServiceImpl[Version Name].php. So, we want to add two new API methods (I suppose you are familiar with SuiteCRM common functions);

    • set_case_update
    • get_case_updates

    At first, we write the prototypes of two new functions:

    PHP
    function get_case_updates($session, $module_name, $name_value_list) {
        // API code
    }
    And
    function set_case_update($session, $module_name, $name_value_list) {
        // API code
    }
    

    Both two new functions have the same parameters:

    • $session: The common parameter of all SuiteCRM API methods. This parameter contains the session Id that the login function returns and shows that the request has a sufficient credential.
    • $module_name: This parameter belongs to methods that are working for all modules such as get_entry_list, set_entry and … . It contains the name of the module that request has been done for its data. In our case, this parameter is not necessary because both methods are working on Case_Updates module. But I didn’t remove this parameter from the methods prototype.
    • $name_value_list: This parameter is an array that contains all sent data from the client such as queries, fields values, etc.

    So, we wrote the API methods prototypes successfully, now let’s start to write the methods.

  8. As it shows, the set_case_update method has the responsibility to insert or update a case_update on a case record. So, the method will look like:

    PHP
    $case_update = new AOP_Case_Updates();
    
    $GLOBALS['log']->info('Begin: SugarWebServiceImpl->set_case_update');
    
    if (!self::$helperObject->checkSessionAndModuleAccess
       ($session, 'invalid_session',
       "AOP_Case_Updates", 'read', 'no_access', $error)) {
        return;
    }
    
    foreach ($name_value_list as &$value) {
        $name = $value['name'];
        $case_update->$name = $value['value'];
    }
    
    $case_update->save();
    
    $GLOBALS['log']->info('End: SugarWebServiceImpl->set_case_update');
    return array('id'=> $case_update->id);
    

    At the first line, we create a new instance from AOP_Case_Update. As you know, in SuiteCRM for inserting or updating a new record, you just need to get a new instance from a module class. So, when you call the Save method, if the id field is empty, then a new record will be created and if the id has been filled, then the method updates a record that the id belongs to.

    The next code line just writes a new line in the SuiteCRM log file.

    PHP
    $GLOBALS['log']->info('Begin: SugarWebServiceImpl->set_case_update');
    

    The next condition statement is for checking the credentials and user access. If the session Id is empty or has a wrong value, then the method returns. In another case, if the user does not have sufficient access to the module, the methods return too. At the next statement, there is a foreach loop that loops through the $anem_value_list array and fills the $case_update parameters.

    And at the final statement, the save method of the case_update instance is called. As I said below, this method works based on the value of Id property. If the Id is empty, the method will add a new record and if the id property has a correct id value, the method will update that record.

    And the final line of the method returns the Id of the new or updated record. It’s a necessary part of all insert or update methods to return id value the code that calls it.

  9. The next method of this API is get_case_updates. This method gets a Case id and returns all of its case_updates. So the method is very easy:

    PHP
        function get_case_updates($session, $module_name, $name_value_list){
    
        $caseUpdateBean = BeanFactory::getBean('AOP_Case_Updates');
        $caseUpdate = $caseUpdateBean->get_full_list
                      ('date_entered desc',"case_id = '" .
                      $name_value_list[0]['value'] . "' ");
    
        $counter = 0;
    
        foreach ($caseUpdate as &$value) {
            $item = array();
            $i = 1;
            foreach ($value as $key => $val)
            {
                try
                {
                    if ($i < 22)
                    {
                        array_push($item, array
                        ("name" => $key, "value" => $val));
                    }
                }
                catch (Exception $e) {
    
                }
                $i++;
            }
            if ($counter == 0)
                $items = array($item);
            else
                array_push($items, $item);
    
            $counter++;
        }
    
        $result = array("count" => $i, "items" => $items);
    
        return array('entry_list'=> $result);
    }
    

    At the first line, we create a new instance of Case_Update. It has been done using the BeanFactory::getBean method. So, at the next line, we call the get_full_list method. This method gets two string parameters, sort order, and query statement and returns a list of the records that match the query.

    The loop at the next step fills a new array based on suitable return value that the client can handle it.

    And at the final line, the method returns the array to the client.

  10. Now, we wrote two new API methods. But these are inaccessible for the client. Because we should register these new methods as the rest methods. So, for doing this task, we should write some new code line in registry.php. This file has two methods for registering Functions and Types of the current API version. I have to mention that these new methods are very simple. There are some so complicated APIs that need new variable type and …

    So, I write a sample of how to register an API in registry.php:

    PHP
    $this->serviceClass->registerFunction(
                'set_case_update',
                array('session'=>'xsd:string', 'module_name'=>'xsd:string',
                      'name_value_list'=>'tns:name_value_list'),
                array('return'=>'tns:new_set_entry_result'));
    

Points of Interest

In this project, I enhanced the SuiteCRM API that helps me to extend 3rd party application for SuiteCRM. It's very important that you don't limit on SuiteCRM built in APIs and could create your own APIs.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)