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).

Leave a Comment

  • nonmaskable_developer

    how can i save a record field in database, for example i want to update a field of user and want to save record

  • Talma

    There is a visual data model that I can download?

    Like a Toad Data Modeler file, for example?