Os Vardefs são usados ​​para fornecer informações ao SuiteCRM sobre um determinado bean. Eles geralmente especificam os campos, relacionamentos e índices em um determinado módulo, bem como informações adicionais, como se ele é auditado, o nome da tabela, etc.

 

Definindo Vardefs

Módulo
Vardefs são inicialmente definidos em suas respectivas pastas de módulos. Para o módulo Contas, isso estará em modules / Accounts / vardefs.php. As informações são armazenadas em um array denominado $ dictionary, usando o nome do módulo como chave. Para contas, será $ dictionary [‘Conta’]. Vejamos os vardefs da conta (que foram editados para abreviar):

Exemplo 4.1: Vardefs da conta
$dictionary [‘Conta’] = array
(‘tabela’ => ‘contas’,
‘auditado’ => verdadeiro,
‘unified_search’ => true,
‘unified_search_default_enabled’ => verdadeiro, ‘duplicate_merge’ => true,
‘comment’ => ‘Contas são organizações ou entidades que …’, ‘campos’ => array (
// Cortado por brevidade. Veja a seção de campos. ), ‘índices’ => array (
// Cortado por brevidade. Veja a seção de índices. ), ‘relacionamentos’ => array (
// Cortado por brevidade. Veja a seção de relacionamento. ), // Isso ativa o bloqueio otimista para salvar a partir do EditView ‘optimistic_locking’ => true, );
VardefManager :: createVardef ( ‘Contas’,
‘Conta’,
array (‘padrão’, ‘atribuível’, ‘empresa’,)
);

 

Chaves
A seguir estão algumas das chaves que podem ser especificadas para os vardefs.
Os campos, índices e relacionamentos são abordados em suas próprias seções.

table
O nome da tabela do banco de dados para este módulo.

auditado
Se este módulo deve ou não ser auditado. Observe que auditado também deve ser definido no nível dos campos para um campo a ser auditado.

unified_search
Se este módulo pode ser pesquisado por meio da pesquisa global.

unified_search_default_enabled
Se este módulo pode ser pesquisado por meio da pesquisa global por padrão.

duplicate_merge
Se a funcionalidade de mesclagem duplicada está ou não habilitada para este módulo.
Comente Uma descrição deste módulo.

optimistic_locking
Se otimista deve ser habilitado para este módulo. O bloqueio otimista bloqueia edições simultâneas em um registro, assumindo que não haverá conflito.
Ao salvar, o último carimbo de data / hora modificado no registro será verificado.
Se for diferente, então ocorreu uma edição desde que este registro foi carregado.
Se for esse o caso, o usuário verá uma página mostrando as diferenças nas duas edições e será solicitado a escolher quais edições serão usadas.

 

 

Campos
O campo define o comportamento e os atributos de cada campo no módulo.

 

name
O nome do campo.

vname
O nome do rótulo do idioma a ser usado para este campo.

type
O tipo do campo. Veja a seção de tipos de campo.

isnull
Se valores nulos são permitidos.

len
Se o campo for do tipo string, o número máximo de caracteres permitidos.

options
Para campos enum, o rótulo de idioma para os valores suspensos para este campo.

dbtype
O tipo a ser usado pelo banco de dados para armazenar este campo. Isso não é necessário, pois o tipo apropriado geralmente é escolhido.

default
O valor padrão deste campo.
Para os campos de tipo date, datetime e datetimecombo, você deve usar display_default.

display_default
O valor padrão para os campos de tipo date, datetime e datetimecombo. Valores de amostra: -1 dia, hoje, +1 dia, +1 semana, próxima segunda-feira, primeiro dia do próximo mês, +1 mês, +1 ano.

massupdate
Se este campo deve ou não ser atualizável em massa.
Observe que alguns tipos de campo são sempre restritos a atualizações em massa.

rname
Apenas para campos relacionados. O nome do campo a ser obtido do módulo relacionado.

id_name
Apenas para campos relacionados. O campo neste bean que contém o id relacionado.

fonte A fonte deste campo. Pode ser definido como ‘não-db’ se o campo não estiver armazenado no banco de dados – por exemplo, para campos de link, campos preenchidos por ganchos lógicos ou por outros meios.

sort_on
Para campos concatenados (ou seja, campos de nome), o campo que deve ser usado para classificar.

Campos
Para campos concatenados (ou seja, campos de nome) uma matriz dos campos que devem ser concatenados.

db_concat_fields Para campos concatenados (ou seja, campos de nome) uma matriz dos campos que devem ser concatenados no banco de dados. Normalmente é o mesmo que campos.

unified_search
Verdadeiro se este campo deve ser pesquisável por meio da pesquisa global.

enable_range_search
Se a pesquisa de exibição de lista deve permitir uma pesquisa de intervalo deste campo.
Isso é usado para campos de data e numéricos.

estúdio
Se o campo deve ser exibido no estúdio.

auditado
Se as alterações neste campo devem ou não ser auditadas.

 

Tipos de campo
A seguir estão os tipos de campo comuns usados:

ID
Um campo de id.

name
Um campo de nome. Isso geralmente é uma concatenação de outros campos.

bool
Um campo booleano.

varchar Um campo de string de comprimento variável.

char
Um campo de caracteres.

text
Um campo de área de texto.

decimal
Um campo decimal.

date
Um campo de data.

datetime
Um campo de data e hora.

enum Um campo suspenso.

multienum Um campo suspenso que permite selecionar vários valores.

phone
Um campo de número de telefone.

call
Um link para outro módulo por meio de um relacionamento.

 

 

Índices
A matriz de índices permite definir quaisquer índices de banco de dados que devam estar presentes na tabela de banco de dados para este módulo. Vejamos um exemplo:

Exemplo 4.2: Exemplo de definição de índices
‘índices’ => array
( array ( ‘nome’ => ‘idx_mymod_id_del’,
‘tipo’ => ‘índice’,
‘campos’ => array (‘id’, ‘excluído’)),
array ( ‘nome’ => ‘idx_mymod_parent_id’,
‘tipo’ => ‘índice’,
‘campos’ => array (‘parent_id’)),
array ( ‘nome’ => ‘idx_mymod_parent_id’,
‘tipo’ => ‘único’,
‘campos’ => array (‘third_party_id’)),
),

Cada entrada da matriz deve ter, pelo menos, as seguintes entradas:

name
O nome do índice. Isso geralmente é usado pelo banco de dados para fazer referência ao índice. A maioria dos bancos de dados exige que sejam exclusivos.

type
O tipo de índice a ser criado. index irá simplesmente adicionar um índice nos campos, unique adicionará uma restrição exclusiva aos campos, primary adicionará os campos como uma chave primária.

field
Uma matriz dos campos a serem indexados. A ordem desta matriz será usada como a ordem dos campos no índice.

 

Relacionamentos
O Vardefs também especifica os relacionamentos dentro deste módulo. Aqui está um exemplo editado do módulo Contas:

Exemplo 4.3: Exemplo de definição de relacionamento

‘relacionamentos’ => array (
‘account_cases’ => array
(
‘lhs_module’ => ‘Contas’,
‘lhs_table’ => ‘contas’,
‘lhs_key’ => ‘id’,
‘rhs_module’ => ‘Casos’,
‘rhs_table’ => ‘casos’,
‘rhs_key’ => ‘account_id’,
‘relacionamento_tipo’ => ‘um para muitos’),
),

Aqui vemos a ligação entre contas e casos. Isso é especificado com as seguintes chaves:

lhs_module
O módulo do lado esquerdo deste relacionamento. Para um relacionamento de um para muitos, este será o lado “Um”.

lhs_table
A mesa para o módulo do lado esquerdo. Se você não tiver certeza, a tabela de um módulo pode ser encontrada em seu vardefs.

lhs_key
O campo a ser usado no lado esquerdo deste link. Nesse caso, é o id da conta.

rhs_module
O módulo do lado direito. Nesse caso, o lado “muitos” do relacionamento.

rhs_table
A mesa para o módulo do lado direito. Como afirmado anteriormente, você pode encontrar a tabela para um módulo em seu vardefs.

rhs_key
O campo a ser usado no lado direito. Neste caso, o campo account_id nos casos.

relantionship_type
O tipo de relacionamento – “um para muitos” ou “muitos para muitos”. Como este é um relacionamento de um para muitos, significa que um caso está relacionado a uma única conta, mas uma única conta pode ter vários casos.

Para muitos campos de relacionamento, as seguintes chaves também estão disponíveis:

join_table
O nome da tabela de junção para este relacionamento.

join_key_lhs
O nome do campo na tabela de junção para o lado esquerdo.

join_key_rhs
O nome do campo na tabela de junção do lado direito.

 

 

Modelos Vardef
Os modelos Vardef fornecem um atalho para definir vardefs comuns. Isso é feito chamando VardefManager :: createVardef e passando o nome do módulo, nome do objeto e um array de modelos a serem atribuídos. A seguir está um exemplo das contas vardefs:

Exemplo 4.4: modelo vardef de exemplo
VardefManager :: createVardef (

‘Contas’,
‘Conta’,
array (‘padrão’, ‘atribuível’, ‘empresa’,)
);

Neste exemplo, são usados ​​os modelos padrão, atribuível e da empresa. A seguir estão alguns dos modelos disponíveis:

basic
default
Adiciona os campos de base comuns, como id, nome, data_entrada, etc.

assignable
Adiciona os campos e relacionamentos necessários para atribuir um registro a um usuário.

person
Adiciona campos comuns aos registros de pessoas, como first_name, last_name, address, etc.

company
Adiciona campos comuns a empresas, como um menu suspenso do setor, endereço, etc.

 

 

Personalização de vardefs
Vardefs pode ser personalizado adicionando um arquivo em

Exemplo 4.5: localização vardef personalizada
custom / Extension / modules / /Ext/Vardefs/SomeFile.php

Este arquivo pode então ser usado para adicionar uma nova definição de campo ou personalizar uma existente, por exemplo, alterar um tipo de campo:

Exemplo 4.6: Exemplo substituindo um vardef existente
$dictionary [“TheModule”] [“fields”] [“some_field”] [‘type’] =’int’;

 

 

Frontend
Ao desenvolver algumas funcionalidades complexas de JavaScript, é muito útil ter definições de módulo vardefs ou dados personalizados na variável global SUGAR para que você possa lê-los em JavaScript.

Adicionar definições vardefs.php a uma visualização específica é muito simples:
class AccountsViewEdit extends ViewEdit
{
public function __construct()
{
parent::__construct();
$this->useForSubpanel = true;
$this->useModuleQuickCreateTemplate = true;
$data = $this->getVardefsData(‘Accounts’);
$this->addDomJS($data, ‘vardefs’);
}
}

Depois disso, você pode acessar as definições vardefs do JavaScript facilmente:

Mas também podemos adicionar outras informações relevantes à variável global SUGAR, como, por exemplo, dados do desenvolvedor:
class AccountsViewEdit extends ViewEdit
{
public function __construct()
{
parent::__construct();
$this->useForSubpanel = true;
$this->useModuleQuickCreateTemplate = true;
$data = $this->getVardefsData(‘Accounts’);
$this->addDomJS($data, ‘vardefs’);
‘country’ => ‘Argentina’,
$jose = array(
‘name’ => ‘Jose’, ‘footballTeam’ => ‘River Plate’,
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’);
}
}

 

Visualizações (Views)
SuiteCRM segue o padrão MVC (Model-View-Controller) e, como tal, tem o conceito de visualizações. As visualizações são responsáveis ​​por coletar e exibir dados. Existem várias visualizações padrão no SuiteCRM.
Esses incluem:

ListView
Exibe uma lista de registros e fornece links para EditViews e DetailViews desses registros. O ListView também permite algumas operações, como exclusão e atualização em massa de registros. Esta é (geralmente) a visualização padrão de um módulo.

DetailView
Exibe os detalhes de um único registro e também exibe subpainéis de registros relacionados.

EditView
O EditView permite editar os vários campos de um registro e fornece validação sobre esses valores.

Localização
As visualizações podem ser encontradas em modules / / views / ou, para visualizações customizadas, custom / modules / / views / e são nomeadas no seguinte formato: view. .php. Por exemplo, o Accounts DetailView pode ser encontrado em modules / Accounts / views / view.detail.php com uma versão customizada em custom / modules / Accounts / views / view.detail.php. A versão customizada é usada se existir. Caso contrário, a versão do módulo é usada. Finalmente, se nenhum deles existir, o padrão SuiteCRM é usado em include / MVC / View / views /.

 

 

Customizando
Para personalizar uma visão, primeiro precisamos criar o arquivo de visão apropriado. Isso irá variar dependendo do módulo que desejamos ter como alvo.

Módulo personalizado
Neste caso, podemos colocar o arquivo diretamente em nosso módulo. Crie um novo arquivo (se não existir) em modules / / views / view. .php. O conteúdo será semelhante a:

Exemplo 5.1: Visualização de um módulo personalizado
<? php

require_once ‘include / MVC / View / views / view. .php’;

if (! defined (‘sugarEntry’) ||! sugarEntry) die (‘Não é um ponto de entrada válido’);
classe View estende View
{

}

Um exemplo mais concreto seria para a visualização de detalhes de um módulo personalizado chamado ABC_Vehicles:

Exemplo 5.2: Visualização de detalhes para um módulo personalizado, ABC_Vehicles
<? php

require_once ‘include / MVC / View / views / view.detail.php’;

if (! defined (‘sugarEntry’) ||! sugarEntry) die (‘Não é um ponto de entrada válido’);
classe ABC_VehiclesViewDetail estende ViewDetail
{
}

 

 

Módulos pré-existentes
Para módulos preexistentes, você vai querer adicionar a visão a custom / modules / / views / view. .php.
O conteúdo deste arquivo irá variar dependendo se você deseja estender a visão existente (se houver) ou criar sua própria versão completamente.
Normalmente, é melhor estender a visualização existente, pois isso manterá uma lógica importante.
Observe a convenção de nomenclatura aqui.
Chamamos a classe de Custom View (por exemplo CustomAccountsViewDetail).
Aqui, não estendemos a visualização existente ou não existe tal visualização:

Exemplo 5.3: visualização personalizada para um módulo existente
<? php
if (! defined (‘sugarEntry’) ||! sugarEntry) die (‘Não é um ponto de entrada válido’);
require_once ‘include / MVC / View / views / view. .php’;
classe Custom View estende ViewDetail
{
}

Caso contrário, estendemos a visualização existente. Observe que estamos exigindo a vista existente:

Exemplo 5.4: Substituindo uma visão para um módulo existente
<? php
if (! defined (‘sugarEntry’) ||! sugarEntry) die (‘Não é um ponto de entrada válido’);
require_once ‘modules / / views / view. .php’;
class Custom View estende View
{
}

Por exemplo, substituindo a exibição de lista de contas:

Exemplo 5.5: Substituindo a visualização da lista de contas
<? php
if (! defined (‘sugarEntry’) ||! sugarEntry) die (‘Não é um ponto de entrada válido’);
require_once ‘modules / Accounts / views / view.list.php’;
classe CustomAccountsViewList estende AccountsViewList
{
}

 

 

Fazendo mudanças
Agora que temos uma visualização personalizada, o que podemos realmente fazer? As visualizações têm vários métodos que agora podemos substituir para alterar / adicionar comportamento.
Os mais comuns para substituir são:

preDisplay
Destina-se explicitamente a permitir que a lógica seja chamada antes que display () seja chamado. Isso pode ser usado para alterar argumentos para a exibição de lista ou para produzir qualquer coisa que apareça antes do código de exibição principal (como, por exemplo, adicionar JavaScript).

display
Realiza o trabalho real de exibição da visualização. Pode ser sobrescrito para alterar este comportamento ou para produzir qualquer coisa após a exibição principal. Normalmente, você deseja chamar parent :: display (); para garantir que o código de exibição seja executado (a menos, é claro, que você esteja adicionando sua própria lógica de exibição).

 

 

Personalização com modelos Smarty
Em vez de incluir arquivos HTML em PHP, você pode usar modelos Smarty para criar HTML complexo para visualizações personalizadas.
Digamos que você esteja adicionando um módulo personalizado chamado Store e tenha criado um arquivo em custom / modules / Store / views / view.store.php que usa HTML em HEREDOCs e Strings para criar uma página dinâmica:

<?php 
if (! defined ('sugarEntry') ||! sugarEntry) die ('Não é um ponto de entrada válido'); 
require_once ('include / MVC / View / SugarView.php'); 
classe StoreView estende SugarView 
  {     
   display de função pública ()     
    {         
     $storeName = $ store-> storeName;         
     $location = $ store-> location;         
     $products = $ store-> products;         
     $html = <<< "HTML" <h1> $ storeName </h1> <h2> Localização:          
     $location </h2> <ul> HTML;    
       foreach ($ products as $ id => $ product) {             
       $html. = "<li> $ product-> name: $ product-> price </li>";             
       }  
       $ html. = <<< "HTML"
</ul> 
HTML;         
     echo $ html;     
   } 
 }

Isso funciona, mas não é muito bom de se olhar e é difícil de manter e entender. Você está combinando sua lógica de back-end com o HTML de front-end, o que devemos tentar evitar ao máximo.

Em vez disso, podemos realizar a mesma coisa usando um template Smarty. Podemos alterar o arquivo custom / modules / Store / views / view.store.php para fornecer apenas as variáveis ​​para o template Smarty, ao invés de criar o próprio HTML.
<?php
if (!defined(‘sugarEntry’) || !sugarEntry) die(‘Not A Valid Entry Point’);
require_once(‘include/MVC/View/SugarView.php’);
class StoreView extends SugarView {
public function display()
{
$smarty = new Sugar_Smarty();
$smarty->assign(‘storeName’, $store->storeName);
$smarty->assign(‘location’, $store->location);
$smarty->assign(‘products’, $store->products);
$storePage = $smarty->fetch(‘custom/modules/Store/templates/store.tpl’); return $storePage;
}
}

E então criaremos um arquivo em custom / modules / Store / templates / store.tpl, que se parece com este:

<h1>{$storeName}</h1> 
<h2>Location: {$location}</h2> 
<ul>     
    {foreach name=productsIteration from=$products key=id item=product}          
    <li>{$product->name}: {$product->price}</li>     
    {/foreach} 
</ul>

Muito mais simples!

Você pode ler mais sobre os arquivos de modelo do Smarty e sua sintaxe na documentação do Smarty.