Молниеносная разработка модулей для SugarCRM

SugarCRM сложно назвать лаконичной системой

Чтобы объявить простое текстовое поле, нужно указать восемь параметров. Чтобы создать простую связь между объектами, нужно объявить четыре таких поля. Чтобы появилось на странице модуля и на форме поиска, нужно обойти ещё файлов десять.

Стандартный инструмент для подобных доработок — Студия — отлично подходит для небольших правок. Однако, добавить с её помощью, скажем, полсотни полей — задача не самая простая.

Автоматизируем рутину

Чтобы уменьшить количество кода, необходмого для создания полей, мы написали велосипед генератор метаданных.

В его основе лежит идея convention over configuration, столь любимая рубистами: указывать как можно меньше параметров, по возможности используя значения по умолчанию.

Минимальная информация, нужная генератору для создания поля, это его тип, название в базе данных и перевод на русский язык:

array('varchar', 'name', 'Имя')

Этого достаточно, чтобы сгенерировать метаданные для полей, строки локализации, разметку для страниц модуля, субпанелей и формы поиска:

===Vardefs===

'name' => array(
    'name' => 'name',
    'type' => 'varchar',
    'vname' => 'LBL_NAME',
    'len' => '255',
    'audited' => false,
    'importable' => 'true',
    'massupdate' => false,
    'required' => false,
    'unified_search' => false,
),


===ModStrings===

'LBL_NAME' => 'Название',


===EditViewDefs===

array(
    array(
        'name' => 'name',
    ),
),


===DetailViewDefs===

array(
    array(
        'name' => 'name',
    ),
),


===ListViewDefs===

'NAME' => array(
    'width' => '10',
    'label' => 'LBL_NAME',
    'default' => true,
),


===SubpanelDefs===

'name' => array(
    'width' => '10%',
    'vname' => 'LBL_NAME',
),


===SearchFields===

'name' => array(
    'query_type' => 'default',
),


===SearchDefs===

array(
    'name' => 'name',
),


===Properties===

public $name;

Индивидуальный подход

При создании метаданных необходимо учитывать типы полей. Например, для поля типа enum

array('enum', 'status', 'Статус'),

генератор создаст список значений:

$dictionary['Contact']['fields']['status'] = array(
    'name' => 'status',
    'type' => 'enum',
    'vname' => 'LBL_STATUS',
    'len' => '100',
    'options' => 'contacts_status_list',
    'audited' => false,
    'importable' => 'true',
    'massupdate' => false,
    'required' => false,
    'unified_search' => false,
);


===ModStrings===

$mod_strings['LBL_STATUS'] = 'Статус';


===AppStrings===

$app_list_strings['contacts_status_list'] = array(
    '' => '',
    'option_1' => 'Option 1',
);

Для создания связи между достаточно указать тип поля (relate), сторону связи (right), а также название поля (Работодатель) и название модуля (Accounts):

array('relate', 'right', 'Работодатель', 'Accounts')

На выходе получим все необходимые поля и связь:

===Vardefs===

$dictionary['Contact']['fields']['account_id'] = array(
    'name' => 'account_id',
    'type' => 'id',
    'vname' => 'LBL_ACCOUNT_ID',
    'audited' => false,
    'importable' => 'true',
    'massupdate' => false,
    'required' => false,
    'unified_search' => false,
);
$dictionary['Contact']['fields']['account_name'] = array(
    'name' => 'account_name',
    'type' => 'relate',
    'vname' => 'LBL_ACCOUNT_NAME',
    'rname' => 'name',
    'id_name' => 'account_id',
    'link' => 'account_link',
    'module' => 'Accounts',
    'table' => 'accounts',
    'source' => 'non-db',
    'len' => '255',
    'audited' => false,
    'importable' => 'true',
    'isnull' => 'true',
    'join_name' => 'accounts',
    'massupdate' => false,
    'required' => false,
    'unified_search' => false,
);
$dictionary['Contact']['fields']['account_link'] = array(
    'name' => 'account_link',
    'type' => 'link',
    'vname' => 'LBL_ACCOUNT_LINK',
    'source' => 'non-db',
    'audited' => false,
    'importable' => 'false',
    'massupdate' => false,
    'relationship' => 'account_contacts',
    'required' => false,
    'side' => 'right',
    'unified_search' => false,
);
$dictionary['Account']['fields']['contacts'] = array(
    'name' => 'contacts',
    'type' => 'link',
    'vname' => 'LBL_CONTACTS',
    'module' => 'Contacts',
    'source' => 'non-db',
    'audited' => false,
    'bean_name' => 'Contact',
    'importable' => 'false',
    'massupdate' => false,
    'relationship' => 'account_contacts',
    'required' => false,
    'side' => 'left',
    'unified_search' => false,
);


===Relationships===

$dictionary['Account']['relationships']['account_contacts'] = array(
    'lhs_key' => 'id',
    'lhs_module' => 'Accounts',
    'lhs_table' => 'accounts',
    'relationship_type' => 'one-to-many',
    'rhs_key' => 'account_id',
    'rhs_module' => 'Contacts',
    'rhs_table' => 'contacts',
);

Резюме

Теперь мы тратим на разработку модулей в четыре раза меньше времени, чем раньше.

В ближайших планах — вторая версия генератора, с созданием файлов, управлением через консоль и конфигурацией в формате yaml.


© 2013 Ведисофт
Москва: +7 (499) 703-04-23
Екатеринбург: +7 (343) 236-60-96
Почта: info_at_vedisoft_dot_info