Vardefs

What are Vardefs

The Vardefs are used to supply information to SuiteCRM about a particular bean. These generally specify the fields, relationships and indexes in a given module as well as additional information such as whether it is audited, the table name etc.

Defining Vardefs

Module

Vardefs are initially defined in their respective modules folder. For the Accounts module this will be in modules/Accounts/vardefs.php. The information is stored in an array named $dictionary using the module name as the key. For Accounts this will be $dictionary['Account']. Let’s look at the Account vardefs (which have been edited for brevity):

Example 4.1: Account Vardefs
$dictionary['Account'] =
array(
  'table' => 'accounts',
  'audited'=>true,
  'unified_search' => true,
  'unified_search_default_enabled' => true,
  'duplicate_merge'=>true,
  'comment' => 'Accounts are organizations or entities that ...',
  'fields' => array (
   //Snipped for brevity. See the fields section.
  ),
  'indices' => array (
   //Snipped for brevity. See the indices section.
  ),
  'relationships' => array (
   //Snipped for brevity. See the relationship section.
  ),
   //This enables optimistic locking for Saves From EditView
  'optimistic_locking'=>true,
);

VardefManager::createVardef(
  'Accounts',
  'Account',
  array('default', 'assignable','company',)
);

Keys

The following are some of the keys that can be specified for the vardefs. Fields, indices and relationships are covered in their own sections.

table

The database table name for this module.

audited

Whether or not this module should be audited. Note that audited must also be set at the fields level for a field to be audited.

unified_search

Whether this module can be searchable via the global search.

unified_search_default_enabled

Whether this module is searchable via the global search by default.

duplicate_merge

Whether or not duplicate merging functionality is enabled for this module.

comment

A description of this module.

optimistic_locking

Whether optimistic should be enabled for this module. Optimistic locking locks concurrent edits on a record by assuming that there will be no conflict. On save the last modified timestamp on the record will be checked. If it is different then an edit has occurred since this record was loaded. If this is the case then the user will be prompted with a page showing the differences in the two edits and asked to choose which edits are to be used.

Fields

The field defines the behaviour and attributes of each field in the module.

name

The name of the field.

vname

The name of the language label to be used for this field.

type

The type of the field. See the field types section.

isnull

Whether null values are allowed

len

If the field is a string type, the max number of characters allowed.

options

For enum fields the language label for the dropdown values for this field

dbtype

The type to be used by the database to store this field. This is not required as the appropriate type is usually chosen.

default

The default value of this field. For date, datetime and datetimecombo type fields you should use display_default instead.

display_default

The default value for date, datetime and datetimecombo type fields. Sample Values: -1 day, today, +1 day, +1 week, next monday, first day of the next month, +1 month, +1 year .

massupdate

Whether or not this field should be mass updatable. Note that some field types are always restricted from mass updates.

rname

For related fields only. The name of the field to be taken from the related module.

id_name

For related fields only. The field in this bean which contains the related id.

source

The source of this field. Can be set to ‘non-db’ if the field is not stored in the database - for example for link fields, fields populated by logic hooks or by other means.

sort_on

For concatenated fields (i.e. name fields) the field which should be used to sort.

fields

For concatenated fields (i.e. name fields) an array of the fields which should be concatenated.

db_concat_fields

For concatenated fields (i.e. name fields) an array of the fields which should be concatenated in the database. Usually this is the same as fields.

unified_search

True if this field should be searchable via the global search.

enable_range_search

Whether the list view search should allow a range search of this field. This is used for date and numeric fields.

studio

Whether the field should display in studio.

audited

Whether or not changes to this field should be audited.

Field types

The following are common field types used:

id

An id field.

name

A name field. This is usually a concatenation of other fields.

bool

A boolean field.

varchar

A variable length string field.

char

A character field.

text

A text area field.

decimal

A decimal field.

date

A date field.

datetime

A date and time field.

enum

A dropdown field.

multienum

A dropdown field that allows selecting multiple values.

phone

A phone number field.

link

A link to another module via a relationship.

relate

A related bean field.

Indices

The indices array allows defining any database indexes that should be in place on the database table for this module. Let’s look at an example:

Example 4.2: Example indices definition
'indices' => array (
  array(
     'name' =>'idx_mymod_id_del',
     'type' =>'index',
     'fields'=>array('id', 'deleted')),
  array(
     'name' =>'idx_mymod_parent_id',
     'type' =>'index',
     'fields'=>array( 'parent_id')),
  array(
     'name' =>'idx_mymod_parent_id',
     'type' =>'unique',
     'fields'=>array( 'third_party_id')),
  ),

Each array entry should have, at least, the following entries:

name

The name of the index. This is usually used by the database to reference the index. Most databases require that these are unique.

type

The type of the index to create. index will simply add an index on the fields, unique will add a unique constraint on the fields, primary will add the fields as a primary key.

fields

An array of the fields to be indexed. The order of this array will be used as the order of the fields in the index.

At the moment it is not possible to add indexes to custom fields.

Relationships

The Vardefs also specify the relationships within this module. Here’s an edited example from the Accounts module:

Example 4.3: Example relationships definition
'relationships' => array (
  'account_cases' => array(
      'lhs_module'=> 'Accounts',
      'lhs_table'=> 'accounts',
      'lhs_key' => 'id',
      'rhs_module'=> 'Cases',
      'rhs_table'=> 'cases',
      'rhs_key' => 'account_id',
      'relationship_type' => 'one-to-many'),
),

Here we see the link between accounts and cases. This is specified with the following keys:

lhs_module

The module on the left hand side of this relationship. For a one to many relationship this will be the “One” side.

lhs_table

The table for the left hand side module. If you are unsure the table for a module can be found in it’s vardefs.

lhs_key

The field to use for the left hand side of this link. In this case it is the id of the account.

rhs_module

The right hand side module. In this case the “many” side of the relationship.

rhs_table

The table for the right hand side module. As stated previously you can find the table for a module can be found in it’s vardefs.

rhs_key

The field to use on the right hand side. In this case the account_id field on cases.

relationship_type

The type of relationship - “one-to-many” or “many-to-many”. Since this is a one to many relationship it means a case is related to a single account but a single account can have multiple cases.

For many to many relationship fields the following keys are also available:

join_table

The name of the join table for this relationship.

join_key_lhs

The name of the field on the join table for the left hand side.

join_key_rhs

The name of the field on the join table for the right hand side.

Vardef templates

Vardef templates provide a shortcut for defining common vardefs. This is done by calling VardefManager::createVardef and passing the module name, object name and an array of templates to be assigned. The following is an example from the accounts vardefs:

Example 4.4: Example vardef template
VardefManager::createVardef(
      'Accounts',
      'Account',
      array('default', 'assignable','company',)
      );

In this example the default, assignable and company templates are used. The following are some of the available templates:

basic
default

Adds the common base fields such as id, name, date_entered, etc.

assignable

Adds the fields and relationships necessary to assign a record to a user.

person

Adds fields common to people records such as first_name, last_name, address, etc.

company

Adds fields common to companies such as an industry dropdown, address, etc.

Customising vardefs

Vardefs can be customised by adding a file into

Example 4.5: Custom vardef location
custom/Extension/modules/<TheModule>/Ext/Vardefs/SomeFile.php

This file can then be used to add a new field definition or customise an existing one e.g changing a field type:

Example 4.6: Example overriding an existing vardef
$dictionary["TheModule"]["fields"]["some_field"]['type'] = 'int';

Frontend

This section applies only to SuiteCRM versions 7.11 and newer.

When developing some complex JavaScript functionality is very useful to have module vardefs definitions or custom data in the SUGAR global variable so you can read it from JavaScript.

Adding vardefs.php definitions to a specific view is very simple:

class AccountsViewEdit extends ViewEdit
{
    public function __construct()
    {
        parent::__construct();
        $this->useForSubpanel = true;
        $this->useModuleQuickCreateTemplate = true;
        $data = $this->getVardefsData('Accounts');
        $this->addDomJS($data, 'vardefs');
    }
}

After that, you can access vardefs definitions from JavaScript easily

vardefs

But we can also add other relevant information to the SUGAR global variable, like for example developer’s data ;-)

class AccountsViewEdit extends ViewEdit
{
    public function __construct()
    {
        parent::__construct();
        $this->useForSubpanel = true;
        $this->useModuleQuickCreateTemplate = true;
        $data = $this->getVardefsData('Accounts');
        $this->addDomJS($data, 'vardefs');

        $jose = array(
            'name' => 'Jose',
            'country' => 'Argentina',
            'footballTeam' => 'River Plate',
            'footballTeamLastTitles' => array(
                'Copa Sudamericana 2014',
                'Copa Libertadores de América 2015',
                'Copa Suruga Bank 2015',
                'Recopa Sudamericana 2015',
                'Recopa Sudamericana 2016',
                'Copa Libertadores de América 2018',
            ),
        );
        $this->addDomJS(array($jose), 'developerData');
    }
}

developerData

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.