By Clay Li on Friday, 23 March 2018
Category: Feature

Calem Integration 3: Custom Triggers

Calem Enterprise comes with integration capabilities including:

Custom triggers are discussed in this blog. They can be used to perform business logic required in customers' businesses. For instance, a customer likes to display vendor contract information in purchase orders. The requirement is that if a vendor has a contract with the customer, the contract's start date should be listed. Here are the steps to implement the feature with the help of customer triggers in Calem:


The screenshot of the error message raised by the custom trigger:

The screenshot with two custom fields added in PO: 

The PO creation form is customized to have the two custom fields: "Has Contract?" and "Contract Date".


Customers need to white list their IPs with Calem for access to their Cloud services to experiment and deploy custom triggers. Programming skills of PHP are required to develop custom triggers. There are plenty of triggers shipped in Calem Enterprise in plain PHP scripts. They can be used as examples.

The following triggers are supported in Calem:

Trigger Type Trigger is Fired When
​Before Insert ​Before a record is inserted
​After Insert​After a record is inserted
​Before Update2​Before a record is updated.
BeforeUpdate2 includes custom fields (see example below).
​After Update​After a record is updated
​Before Delete​Before a record is deleted
​After Delete​After a record is deleted

Triggers are seeded in Calem for many tables. Customers can add custom triggers which are fired after the seeded triggers.

Customer triggers are configured in your server configuration file at Calem_Home/server/conf/calem.custom.php. For instance, the following defines a custom trigger for purchase order table:

$_CALEM_dist['dbo_conf']['cm_po']='CmPoDbo_Ct';

Here are the rules about the custom triggers:

Here is the sample trigger source code:

CmPoDbo_Ct.php
1     
2    /** 
3     *  Copyright (c) 2006-Present 
4     *  CalemEAM Inc. All Rights Reserved. 
5     *  The contents of this file are confidential and proprietary information of CalemEAM Inc. 
6     *  You shall use the file only in accordance with the terms of the CalemEAM Software License Agreement. 
7     */ 
8     
9    //Checking basic initialization 
10   if (!defined('_CALEM_DIR_')) die("Access denied at ".__FILE__); 
11    
12   require_once _CALEM_DIR_ . 'server/core/database/CmDbo.php'; 
13    
14   class CmPoDbo_Ct extends CmDbo { 
15    
16      // before insert 
17      // $baseTable base table name 
18      // $baseData an array of key/value data to be inserted 
19      // $customTable custom table name 
20      // $customData an array of custom key/value data 
21      public function beforeInsert($baseTable, $baseData, $customTable, $customData) { 
22         //Throw an exception if PO is closed. 
23         $hasContract= ($customData ? $customData['has_contract'] : null); 
24         $contractDate = ($customData ? $customData['contract_date'] : null); 
25         if ($hasContract && !$contractDate) { 
26            $this->onSvrExceptionByMsg('A valid contract date is required.'); 
27         } 
28         //You can update $baseData by filling more info 
29         return $baseData; 
30      } 
31    
32      // after insert 
33      // $id the record id for created record 
34      // $baseTable base table name 
35      // $baseData an array of key/value data inserted 
36      // $customTable custom table name 
37      // $customData an array of custom key/value data 
38      // $batch batch process 
39      // $sync offline sync 
40      public function onDataInserted($id, $baseTable, $baseData, $customTable, $customData, $batch=false, $sync=false) { 
41         //You may update other related tables after data is inserted. 
42      } 
43    
44      // before update 
45      // $baseTable base table name 
46      // $baseCurrent an array of current record key/value data 
47      // $baseUpdate an array of key/value data updated 
48      public function beforeUpdate2($baseTable, $baseCurrent, $baseUpdate, $customTable, $customCurrent, $customUpdate) { 
49         // You may add/update fields to be updated if needed. 
50         $hasContract=$this->getValueByUpd('has_contract', $customUpdate, $customCurrent); 
51         $contractDate=$this->getValueByUpd('contract_date', $customUpdate, $customCurrent); 
52         if ($hasContract && !$contractDate) { 
53            $this->onSvrExceptionByMsg('A valid contract date is required.'); 
54         } 
55         return $baseUpdate; 
56      } 
57    
58      // after update 
59      // $baseTable base table name 
60      // $baseCurrent an array of current record data 
61      // $baseUpdate an array of fields to be updated 
62      // $customTable custom table name 
63      // $customCurrent an array of current record data 
64      // $customUpdate an array of custom key/value data to be updated 
65      // $batch batch process 
66      // $sync offline sync 
67      public function onDataUpdated($baseTable, $baseCurrent, $baseUpdate, $customTable, $customCurrent, $customUpdate, $batch=false, $sync=false) { 
68         //You may update other related tables after data is updated. 
69      } 
70       
71      // before delete 
72      public function beforeDelete() { 
73         //Load the data row for use in post deletion 
74         $this->loadRecord(); 
75      } 
76       
77      // after delete 
78      // @table the table name 
79      // @id the id of the record deleted 
80      // $batch batch process 
81      // $sync offline sync 
82      public function onDataDeleted($table, $id, $batch=false, $sync=false) { 
83         //You may reference the deleted row as "$this->row" and process it. 
84      } 
85    
86   } 
87   

Additional resources