How to Define Model’s Metadata
Zurmo uses RedBeanPHP ORM system to abstract access to the database. Because Zurmo is using the Yii framework, we had to completely rewrite the Yii Active Record, with RedBeanModel, and its related classes to have all the functionality we needed.
To archive database abstraction, we must define some model fields, relations, validation rules, and so on, therefore RedBeanModel has a static function getDefaultMetadata which should be extended by all model classes. This function will return model metadata.
Below is sample code from the getDefaultMetadata function in AccountModel:
public static function getDefaultMetadata()
{
$metadata = parent::getDefaultMetadata();
$metadata[__CLASS__] = array(
'members' => array(
'annualRevenue',
'description',
'employees',
'name',
'officePhone',
'officeFax',
'website',
),
'relations' => array(
'account' => array(RedBeanModel::HAS_MANY_BELONGS_TO, 'Account'),
'accounts' => array(RedBeanModel::HAS_MANY, 'Account'),
'billingAddress' => array(RedBeanModel::HAS_ONE, 'Address', RedBeanModel::OWNED),
'contacts' => array(RedBeanModel::HAS_MANY, 'Contact'),
'industry' => array(RedBeanModel::HAS_ONE, 'OwnedCustomField', RedBeanModel::OWNED),
'opportunities' => array(RedBeanModel::HAS_MANY, 'Opportunity'),
'primaryEmail' => array(RedBeanModel::HAS_ONE, 'Email', RedBeanModel::OWNED),
'secondaryEmail' => array(RedBeanModel::HAS_ONE, 'Email', RedBeanModel::OWNED),
'shippingAddress' => array(RedBeanModel::HAS_ONE, 'Address', RedBeanModel::OWNED),
'type' => array(RedBeanModel::HAS_ONE, 'OwnedCustomField', RedBeanModel::OWNED),
),
'rules' => array(
array('annualRevenue', 'type', 'type' => 'float'),
array('description', 'type', 'type' => 'string'),
array('employees', 'type', 'type' => 'integer'),
array('name', 'required'),
array('name', 'type', 'type' => 'string'),
array('name', 'length', 'min' => 3, 'max' => 64),
array('officePhone', 'type', 'type' => 'string'),
array('officePhone', 'length', 'min' => 1, 'max' => 14),
array('officeFax', 'type', 'type' => 'string'),
array('officeFax', 'length', 'min' => 1, 'max' => 14),
array('website', 'url'),
),
'elements' => array(
'account' => 'Account',
'billingAddress' => 'Address',
'description' => 'TextArea',
'officePhone' => 'Phone',
'officeFax' => 'Phone',
'primaryEmail' => 'EmailAddressInformation',
'secondaryEmail' => 'EmailAddressInformation',
'shippingAddress' => 'Address',
),
'customFields' => array(
'industry' => 'Industries',
'type' => 'AccountTypes',
),
'defaultSortAttribute' => 'name',
'rollupRelations' => array(
'accounts' => array('contacts', 'opportunities'),
'contacts',
'opportunities'
),
'noAudit' => array(
'annualRevenue',
'description',
'employees',
'website',
),
);
return $metadata;
}
members define a list of model properties (fields in database)
relations define a list of model relationships with other models
rules define validation rules
elements define model elements
customFields define custom fields
rollupRelations define rollup relationships, for example between Accounts and Contacts
defaultSortAttribute – default sorting attribute
noAudit – list of fields whose changes will not be tracked
noExport – defines a list of fields that will not be exported
noExport – defines a list of fields that will not be exported via API
When a user adds new fields to an existing model, or deletes or edits an existing one via the Designer tool, those settings are saved in the database (check GlobalMetadata class, or globalmetadata table, after you have edited some fields via the Designer tool).
Sometimes you might need to refresh data in the database, ie after changing model default metadata. You can do that by accessing a url on your web server, and appending ??resolveCustomData=1 string to url (for example if we consider that Zurmo CRM in installed under http://www.zurmo.org/app, this url would look like: http://www.zurmo.org/app/index.php?resolveCustomData=1).