Guia rápido Passos iniciais para instalar o Framework
Guia rápido
A seguir, os passos mínimos para instalar e configurar uma aplicação no Adianti Framework. Este é um tutorial com recomendações genéricas, tanto para Linux, Windows, ou Mac. Para tutoriais específicos, siga estes link para Ubuntu Server e Windows.
Pacote Dominando o Adianti 7
Curso + Livro + Apps exemplo
Curso completo em Video Aulas (114 aulas).
Livro completo em PDF (463 páginas).
Códigos-fontes de Apps de Exemplo.
01
Instale o Apache
Instale e configure o Apache2
Configuração
Altere as configurações do Apache para ele ler os .htaccess presentes na estrutura de diretório do Framework, que protegem determinados diretórios do acesso indevido.

apache2.conf
AllowOverride All
02
Instale o PHP
Instale e configure o PHP
Módulos recomendados
soap, xml, curl, opcache, gd, sqlite3, mcrypt, mbstring
Configuração para desenvolvimento
Ajuste as configurações para habilitar log de erros, aumentar o limite de RAM, o tempo de execução, o tempo de sessão, e definir limites de upload, etc.

php.ini
error_log = /tmp/php_errors.log
log_errors = On
display_errors = On
memory_limit = 256M
max_execution_time = 120
error_reporting = E_ALL
file_uploads = On
post_max_size = 100M
upload_max_filesize = 100M
session.gc_maxlifetime = 14000
Configuração para produção
Quando a aplicação entrar em produção, desligue a exibição de erros.

php.ini
display_errors = Off
Configurações de segurança
As seguintes configurações são recomendações para segurança. Substitua CUSTOMSESSID por um nome específico.

php.ini
session.name = CUSTOMSESSID
session.use_only_cookies = 1
session.cookie_httponly = true
session.use_trans_sid = 0
session.entropy_file = /dev/urandom
session.entropy_length = 32
03
Template da aplicação
Faça download do Adianti Template, o gabarito funcional para construir aplicações no Adianti Framework com menus, permissões, logs, gestão de documentos, inbox, notificações, e outros.
Instalação
Descompacte o template conforme o seu sistema.
Ubuntu: /var/www/html/
Mac OS: /Library/WebServer/Documents/
Windows: C:\wamp64\www\

Será criada uma pasta template. Renomeie-a nome real de seu projeto:
mv template meu-projeto

Alterar em application.ini, o nome da aplicação, de template (default) para o nome real:

app/config/application.ini
application = meu-projeto
04
Banco de dados
Crie o banco de dados de sua aplicação, usando PostgreSQL, MySQL, SQLite, Oracle, Sql Server, ou Firebird.
Configuração
Configure o conector dentro da aplicação:
app/config/meu-projeto.ini

Cada banco de dados deve ser configurado na pasta app/config por um INI. Para usar um conector, você deve ter o driver correto habilitado no php.ini.

Obs: A propriedade "prep" habilita prepared statements para todas instruções geradas pelo framework.

A seguir um exemplo de um conector para SQLite:
host = ""
port = ""
name = "app/database/samples.db"
user = ""
pass = ""
type = "sqlite"
prep = "1"

A seguir um exemplo de um conector para PostgreSQL:
host = "192.168.1.102"
port = ""
name = "samples"
user = "postgres"
pass = "postgres"
type = "pgsql"
prep = "1"

A seguir um exemplo de um conector para MySQL:
host = "127.0.0.1"
port = ""
name = "tutor"
user = "root"
pass = "mysql"
type = "mysql"
prep = "1"
zone = "America/Sao_Paulo"
char = "utf8mb4"
Obs: Para usar com encoding iso, adicionar "char = ISO"

A seguir um exemplo de um conector para Oracle:
host = "192.168.1.103"
port = "1521"
name = "tutor"
user = "system"
pass = "12345678"
type = "oracle"
char = "AL32UTF8" ; alterar charset de conexão
flow = "1" ; garante atributos em lowercase
date = "YYYY-MM-DD" ; NLS_DATE_FORMAT
time = "YYYY-MM-DD HH24:MI:SS.FF" ; NLS_TIMESTAMP_FORMAT
nsep = ",." ; NLS_NUMERIC_CHARACTERS

A seguir um exemplo de um conector para Oracle com TNS:
user = "system" pass = "12345678" type = "oracle" tns = "(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.0.13)(PORT = 1521)) ) (CONNECT_DATA = (SERVICE_NAME = exemplos) ) )" prep = "1" flow = "1"

A seguir um exemplo de um conector para SQLServer:
host = 192.168.1.103
name = tutor
user = sa
pass = 12345678
type = mssql
prep = "1"
ntyp = "1"
opts = ";ENCRYPT=yes;trustServerCertificate=true"
Obs: O type mssql utiliza driver dblib (FreeTDS) para Linux e sqlsrv (Fornecido pela MS) para windows. Use também type=dblib ou type=sqlsrv para indicar o driver específico. "ntyp" é válido apenas para o driver "sqlsrv", habilita retorno de campos numéricos como tipos numéricos do PHP. A opção "opts" é necessária a partir do PHP8 em uso com o driver fornecido pela MS.


A seguir um exemplo de um conector para Firebird:
host = "192.168.0.103"
port = ""
name = "c:\teste2.fdb"
user = "sysdba"
pass = "masterkey"
type = "ibase"
05
Classe modelo
Crie classes que representam as tabelas do banco de dados.
Agora é o momento de criar as classes do modelo da aplicação. Uma classe modelo é filha de TRecord. Esta classe do framework fornece métodos básicos de persistência como store(), delete() e load() que manipulam um objeto na base de dados.

app/model/Person.class.php.
  1. <?php
  2. /**
  3.  * Fatura Active Record
  4.  * @author  <your-name-here>
  5.  */
  6. class Fatura extends TRecord
  7. {
  8.     const TABLENAME 'fatura';
  9.     const PRIMARYKEY'id';
  10.     const IDPOLICY =  'max'// {max, serial}
  11.     
  12.     
  13.     /**
  14.      * Constructor method
  15.      */
  16.     public function __construct($id NULL$callObjectLoad TRUE)
  17.     {
  18.         parent::__construct($id$callObjectLoad);
  19.         parent::addAttribute('cliente_id');
  20.         parent::addAttribute('dt_fatura');
  21.         parent::addAttribute('mes');
  22.         parent::addAttribute('ano');
  23.         parent::addAttribute('total');
  24.         parent::addAttribute('financeiro_gerado');
  25.         parent::addAttribute('ativo');
  26.     }
  27.     public function delete($id null)
  28.     {
  29.         $id = isset($id) ? $id $this->id;
  30.         
  31.         FaturaItem::where('fatura_id''='$this->id)->delete();
  32.         parent::delete($id);
  33.     }
  34.     
  35.     public function get_cliente()
  36.     {
  37.         return Pessoa::find($this->cliente_id);
  38.     }
  39. }

TABLENAME define o nome da tabela que a classe de modelo irá manipular.
PRIMARYKEY define o campo de chave primária. O framework não manipula chaves compostas.
IDPOLICY define a estratégia para geração de novos ID's. max+1 ou serial (deixa o campo de chave primária vazio e o banco de dados decide seu novo valor).

O método addAttribute() limita quais atributos deste objeto serão persistidos (gravados) na base de dados. Quaisquer atributos que não estejam no addAttribute() serão ignorados pelo mecanismo de persistência. Caso o addAttribute() não seja chamado nenhuma vez, todos atributos serão persistidos.
06
Classe controller
Criando páginas para formulários, listagens, e outros.
Agora é o momento de criar as páginas da aplicação. Para tal, podem ser usados componentes, templates, ou outras técnicas. No exemplo a seguir, estamos utilizando um controlador-padrão disponível no framework. O TStandardForm fornece uma abordagem padronizada para manipulação de formulários, que é explicada extensivamente no livro do Framework, onde também é abordada a construção manual de telas, e cada um dos componentes visuais para formulários.

As páginas controladoras de aplicação são salvas no diretório app/control. O controlador-padrão TStandardForm fornece métodos como setDatabase() e setActiveRecord() que definem o nome da base de dados (veja os arquivos INI) e a classe de Active Record que irá manipular os dados do formulário.

app/control/CidadeForm.class.php
  1. <?php
  2. /**
  3.  * ContaReceberForm
  4.  *
  5.  * @version    1.0
  6.  * @package    erphouse
  7.  * @subpackage control
  8.  * @author     Pablo Dall'Oglio
  9.  * @copyright  Copyright (c) 2006 Adianti Solutions Ltd. (http://www.adianti.com.br)
  10.  * @license    http://www.adianti.com.br/framework-license
  11.  */
  12. class ContaReceberForm extends TPage
  13. {
  14.     protected $form// form
  15.     
  16.     use Adianti\Base\AdiantiStandardFormTrait// Standard form methods
  17.     
  18.     /**
  19.      * Class constructor
  20.      * Creates the page and the registration form
  21.      */
  22.     function __construct()
  23.     {
  24.         parent::__construct();
  25.         
  26.         parent::setTargetContainer('adianti_right_panel');
  27.         
  28.         $this->setDatabase('erphouse');              // defines the database
  29.         $this->setActiveRecord('ContaReceber');     // defines the active record
  30.         
  31.         // creates the form
  32.         $this->form = new BootstrapFormBuilder('form_ContaReceber');
  33.         $this->form->setFormTitle('Conta a Receber');
  34.         $this->form->setClientValidation(true);
  35.         $this->form->setColumnClasses2, ['col-sm-5 col-lg-4''col-sm-7 col-lg-8'] );
  36.         // create the form fields
  37.         $id = new TEntry('id');
  38.         $dt_emissao = new TDate('dt_emissao');
  39.         $dt_vencimento = new TDate('dt_vencimento');
  40.         $dt_pagamento = new TDate('dt_pagamento');
  41.         $pessoa_id = new TDBUniqueSearch('pessoa_id''erphouse''Pessoa''id''nome_fantasia');
  42.         $valor = new TNumeric('valor'2',''.'true);
  43.         $obs = new TText('obs');
  44.         // add the fields
  45.         $this->form->addFields( [ new TLabel('Id') ], [ $id ] );
  46.         $this->form->addFields( [ new TLabel('Pessoa') ], [ $pessoa_id ] );
  47.         $this->form->addFields( [ new TLabel('Dt Emissao') ], [ $dt_emissao ] );
  48.         $this->form->addFields( [ new TLabel('Dt Vencimento') ], [ $dt_vencimento ] );
  49.         $this->form->addFields( [ new TLabel('Dt Pagamento') ], [ $dt_pagamento ] );
  50.         $this->form->addFields( [ new TLabel('Valor') ], [ $valor ] );
  51.         $this->form->addFields( [ new TLabel('Obs') ], [ $obs ] );
  52.         $dt_emissao->addValidation('Dt Emissao', new TRequiredValidator);
  53.         $dt_vencimento->addValidation('Dt Vencimento', new TRequiredValidator);
  54.         $pessoa_id->addValidation('Pessoa Id', new TRequiredValidator);
  55.         // set sizes
  56.         $id->setSize('100%');
  57.         $dt_emissao->setSize('100%');
  58.         $dt_vencimento->setSize('100%');
  59.         $dt_pagamento->setSize('100%');
  60.         $pessoa_id->setSize('100%');
  61.         $valor->setSize('100%');
  62.         $obs->setSize('100%');
  63.         $dt_emissao->setMask('dd/mm/yyyy');
  64.         $dt_vencimento->setMask('dd/mm/yyyy');
  65.         $dt_pagamento->setMask('dd/mm/yyyy');
  66.         $dt_emissao->setDatabaseMask('yyyy-mm-dd');
  67.         $dt_vencimento->setDatabaseMask('yyyy-mm-dd');
  68.         $dt_pagamento->setDatabaseMask('yyyy-mm-dd');
  69.         $pessoa_id->setMinLength(0);
  70.         
  71.         $dt_emissao->setValue(date('Y-m-d'));
  72.         $id->setEditable(FALSE);
  73.         
  74.         // create the form actions
  75.         $btn $this->form->addAction(_t('Save'), new TAction([$this'onSave']), 'fa:save');
  76.         $btn->class 'btn btn-sm btn-primary';
  77.         $this->form->addActionLink(_t('New'),  new TAction([$this'onEdit']), 'fa:eraser red');
  78.         $this->form->addHeaderActionLink_t('Close'), new TAction([$this'onClose']), 'fa:times red');
  79.         
  80.         // vertical box container
  81.         $container = new TVBox;
  82.         $container->style 'width: 100%';
  83.         // $container->add(new TXMLBreadCrumb('menu.xml', __CLASS__));
  84.         $container->add($this->form);
  85.         
  86.         parent::add($container);
  87.     }
  88.     
  89.     /**
  90.      * Save form data
  91.      * @param $param Request
  92.      */
  93.     public function onSave$param )
  94.     {
  95.         try
  96.         {
  97.             TTransaction::open('erphouse'); // open a transaction
  98.             
  99.             $this->form->validate(); // validate form data
  100.             $data $this->form->getData(); // get form data as array
  101.             
  102.             $object = new ContaReceber;  // create an empty object
  103.             $object->fromArray( (array) $data); // load the object with data
  104.             $object->mes TDateTime::convertToMask($object->dt_vencimento'yyyy-mm-dd''mm');
  105.             $object->ano TDateTime::convertToMask($object->dt_vencimento'yyyy-mm-dd''yyyy');
  106.             
  107.             if (empty($object->id))
  108.             {
  109.                 $object->ativo 'Y';
  110.             }
  111.             
  112.             $object->store(); // save the object
  113.             
  114.             // get the generated id
  115.             $data->id $object->id;
  116.             
  117.             $this->form->setData($data); // fill form data
  118.             TTransaction::close(); // close the transaction
  119.             
  120.             $pos_action = new TAction(['ContaReceberList''onReload'], ['register_state' => 'true']);
  121.                     
  122.             new TMessage('info'AdiantiCoreTranslator::translate('Record saved'), $pos_action);
  123.         }
  124.         catch (Exception $e// in case of exception
  125.         {
  126.             new TMessage('error'$e->getMessage()); // shows the exception error message
  127.             $this->form->setData$this->form->getData() ); // keep form data
  128.             TTransaction::rollback(); // undo all pending operations
  129.         }
  130.     }
  131.     /**
  132.      * Close side panel
  133.      */
  134.     public static function onClose($param)
  135.     {
  136.         TScript::create("Template.closeRightPanel()");
  137.     }
  138. }
07
Menu
O menu da aplicação é definido no arquivo menu.xml. Este arquivo deve ser construído contendo todas as opções possíveis. A aplicação lê o menu.xml e apresenta o menu para o usuário somente com as opções que ele possui permissão de acesso. Portanto, o arquivo menu.xml é filtrado em tempo de execução.
  1. <menu>
  2. <menuitem label='Cadastros'>
  3. <menu>
  4. <menuitem label='Básicos'>
  5. <menu>
  6. <menuitem label='Pessoas'>
  7. <icon>fa:users blue</icon>
  8. <action>PersonForm</action>
  9. </menuitem>
  10. </menu>
  11. </menuitem>
  12. </menu>
  13. </menuitem>
  14. </menu>
08
Permissões e login
Configurando permissões de acesso.
Acesso
Agora chegou o momento de rodar a aplicação e configurar as permissões de acesso. Para tal, abrimos o navegador e acessamos:
http://localhost/meu-projeto

Template
Configuração
1. Logar como "admin" senha "admin";
2. Cadastrar o programa a ser criado em: Administration -> Programs (Preencher Controller="CidadeForm");
3. Conceder a permissão do programa para um usuário ou grupo (Administration -> Users ou Administration -> Groups);
4. Efetuar logout e login novamente com o usuário que tenha permissão de acesso ao programa;