Openbiz Best Practice

1. Work on Openbiz metadata files

Since openbiz-based applications heavily depends on metadata files, editing metadata files is as important as writing code during application development. In a  simple application, a web page includes a single data table that maps to a single database table. It is very easy to implement by configuring one BizDataObj, one BizForm and one BizView (this is covered by the simple tutorial). In case of building a complex application like CRM and school admin, database tables are related together by foreign keys, a page usually contains a driving form and multiple children forms which depends on the data of the driving form and one data object can be used in many places. Without careful design, managing metadata files becomes a tough job. This document is to discuss the best practice of managing your openbiz metadata files.

In order to discuss the topic on a concrete base, a commercial CRM database schema from sugarcrm is used here. In the schema, the relationship between accounts table and contacts table is many-to-many. The intersection table of their relationship is accounts_contacts.

accounts
id 
date_entered 
date_modified 
modified_user_id 
assigned_user_id 
created_by 
name 
parent_id 
account_type 
industry 
annual_revenue 
phone_fax 
billing_address_street 
billing_address_city 
billing_address_state 
billing_address_postalcode 
billing_address_country 
description 
rating 
phone_office 
phone_alternate 
email1 
email2 
website 
ownership 
employees 
sic_code 
ticker_symbol 
shipping_address_street 
shipping_address_city 
shipping_address_state 
shipping_address_postalcode
shipping_address_country 
deleted 
accounts_contacts
id 
contact_id 
account_id 
date_modified
deleted 
contacts
id 
deleted 
date_entered 
date_modified 
modified_user_id 
assigned_user_id 
created_by 
salutation 
first_name 
last_name 
lead_source 
title 
department 
reports_to_id 
birthdate 
do_not_call 
phone_home 
phone_mobile 
phone_work 
phone_other 
phone_fax 
email1 
email2 
assistant 
assistant_phone 
email_opt_out 
primary_address_street 
primary_address_city 
primary_address_state 
primary_address_postalcode
primary_address_country 
.... 
....
....

The requirement is to implement a contact page and and account page.

1.1 Preparation

Before starting editing the metadata files, we need to add database into openbiz eclipse plugin and openbiz application configurations. Metadata tree structure should be determined too.

1.2 Design the BizForm and BizDataObj objects

What are the objects in a view? 

A normal view with a little complexity may include a driving form and sub forms. A sub form may have a popup form to add a record into itself. Each form object has a corresponding data object behind it. We name the data object of the driving form as "main DO", the data object of a  sub form as "reference DO" because it must be one of the ObjReferences of the main DO. Then we call the data object of a popup form as "popup DO".

When a BizDataObj has joined fields (from other tables' columns), users should be able to select a record on a popup form to join it to the base form. This base form can either be driving form or sub form.

Openbiz objects hierarchy

Every database table should have a corresponding dataobj who has only fields mapping to its base table's columns. No join and object reference is in the dataobj. This dataobj is a slim dataobj that is the parent object of other fatter dataobj. If the parent dataobj includes all joins and object references, its children objects have them too. It'll hurt the performance. Other data objects (Main data object, Reference data object and Popup data object) inherit from the base data object.

A BizDataObj may be presented on UI with BizForms. Since different BizForms (even if they are based on same BizDataObj) usually have different UI layout which is rendered by smarty template, it might be easy to manage BizForms without inheritance. 

BizView is in fact a web page. Because web pages usually have different layout, inheritance is not well suitable for BizView.

Naming convention of openbiz objects

We need to have some naming convention of the objects so that we can tell the content of the objects from their names. Difference developers can different way to assigning names. In this article we uses prefix in the naming convention.

Data object (DO) DO prefix Example Form object Form prefix Example
base dataobj _DO _DOContacts      
main dataobj DO DOContacts driving form FM FMContacts
reference dataobj DORef DORefContacts sub form FMSub FMSubContacts
popup dataobj DOPop DOPopContacts popup form FMPop FMPopContacts

After knowing the objects in a view and objects hierarchy, applying the naming convention, finally we have objects chart drawn out as below.

1.3 Create Openbiz metadata files

Developers can recommended to use Openbiz Eclipse Plugin to compose Openbiz metadata files.

Openbiz eclipse plugin provides several different ways to help developers to create Openbiz metadata files.

Once the metadata file created, open it with Openbiz Metadata editor to edit it in eclipse. Please see the Openbiz eclipse plugin user manual for more details.

The the metadata file tree is shown as the following screenshot which is copied from eclipse Package Explorer view.

Other alternate metadata structure recommended by many other openbiz users separates BizDataObj, BizForm and BizView files under different directories. For example:

app_root/ 
---metadata/
------project/
------project/do   
(BizDataObj files)
------project/form 
(BizForm files)
------project/view 
(BizView files)

Change the Id generation algorithm for BizDataObj

By looking at the sugarcrm tables, you would find the id (primary key) column does not generated with native mysql algorithm. Now we need to extend genIdService (Openbiz plugin service) to use application specific ID generation algorithm.

- Create demoapp/bin/service/sugarIdService.php. Have a sugarIdService class extending from genIdService class and override GetNewID method.

include_once(OPENBIZ_HOME."/bin/service/genIdService.php");
 
class sugarIdService extends genIdService
{
   public function __construct() {}

   public function GetNewID($idGeneration, $conn, $dbtype, $table=null, $column=null)
   {
      if ($idGeneration == 'sugarId')
         return create_guid();	// this function is used in sugarcrm source code
      return parent::GetNewID($idGeneration, $conn, $dbtype, $table, $column);
   }
}

- Create demoapp/metadata/service/genIdService.xml that is the metadata file of Id Generation Service plugin. Assign the class as sugarIdService.

<?xml version="1.0" standalone="no"?>
<PluginService Name="genIdService" Package="service" Class="sugarIdService">
</PluginService>

- Assign BizDataObj's IdGeneration attribute as "sugarId". This attribute is used in GetNewId method of sugarIdService class.

1.4 Test views

To verify the your design works, open a browser and type in url 

http://localhost/demoapp/bin/controller.php?view=sugar.accounts.ViewAccounts 

http://localhost/demoapp/bin/controller.php?view=sugar.contacts.ViewContacts 

Verify the basic functionalities 

1.5 Refine the metadata files