# Sistema de Bootstrap do OfficeGest - Documentação Técnica Completa

> **Público-alvo**: Desenvolvedor recém-contratados e equipa técnica
>
> **Objetivo**: Documentar detalhadamente todos os fluxos de inicialização do sistema OfficeGest

## Índice

1. [Visão Geral](#visão-geral)
2. [Pontos de Entrada do Sistema](#pontos-de-entrada-do-sistema)
3. [Análise Detalhada dos Bootstrappers](#análise-detalhada-dos-bootstrappers)
4. [Fluxos de Inicialização](#fluxos-de-inicialização)
5. [Container de Injeção de Dependência](#container-de-injeção-de-dependência)
6. [Análise Método por Método](#análise-método-por-método)
7. [Troubleshooting](#troubleshooting)

---

## Visão Geral

O OfficeGest utiliza um sistema híbrido de bootstrap que suporta múltiplos pontos de entrada:

- **Web (HTTP)**: Através de `index.php` e `.htaccess`
- **AJAX**: Através de `AjaxServer.php`
- **CLI**: Através do comando `./og`
- **Cron Jobs**: Através de `cron.php`
- **Downloads**: Através de `download.php`
- **Uploads**: Através de `upload.php`
- **Imagens**: Através de `loadImage.php`

Cada ponto de entrada tem um fluxo específico mas partilha componentes comuns através do sistema de bootstrap modular.

---

## Pontos de Entrada do Sistema

### 1. Web HTTP - index.php

**Finalidade**: Controlador frontal principal para todas as requisições web

**Fluxo**:
```php
define('INDEXTOP', 1);
const PANELS_LIST = ['mecanicos', 'tpvtouch', 'tpvretalho', 'padhotel', 'pedidos', 'fmms', 'fams'];

require(__DIR__ . '/_files/init.php');  // Bootstrap legacy

$hooks->execute('init_1');              // Hook fase 1
$hooks->execute('init_2');              // Hook fase 2

// Sistema de autenticação e sessões
// Sistema de mod_rewrite e roteamento
// Carregamento de views
```

**Características**:
- **INDEXTOP = 1**: Identifica que a requisição veio do índice principal
- **PANELS_LIST**: Define painéis especiais que não seguem roteamento normal
- **Sistema de Hooks**: Permite extensibilidade através de plugins
- **Roteamento Híbrido**: Combina sistema moderno com legacy

### 2. AJAX - AjaxServer.php

**Finalidade**: Processamento de requisições AJAX com inicialização otimizada

**Fluxo**:
```php
define('INDEXTOP', 1);
define("DEFERRED_INIT", true);           // Otimização: adia inicialização
require(__DIR__ . '/_files/init.php');

// Extração de action da URL ou parâmetro
$action = /* lógica de extração */;

$OG_Init->init_2();                      // Completa inicialização apenas quando necessário
$ajax_server = new AjaxServer($action);
$ajax_server->$action();                 // Execução dinâmica de método
```

**Características**:
- **DEFERRED_INIT = true**: Otimização que adia `init_2()` até ser necessário
- **Dynamic Method Calling**: Executa métodos baseado na URL
- **Session Validation**: Automática exceto para endpoints públicos
- **Performance Optimized**: Carrega apenas o necessário

### 3. CLI - og (executável)

**Finalidade**: Interface de linha de comando para operações do sistema

**Fluxo**:
```php
#!/usr/bin/env php
if (php_sapi_name() !== 'cli') {
    exit('OG deve ser executado via CLI');
}

require __DIR__ . '/vendor/autoload.php';
ErrorHandler::register();                           // Registo estático do error handler

// Carregamento de .env
$envPath = __DIR__ . '/.env';
if (file_exists($envPath)) {
    \Dotenv\Dotenv::createImmutable(__DIR__)->safeLoad();
}

$allowedCommandsWhenNotHttp = ['queue', 'cache', 'route', 'make'];

// Para comandos simples sem contexto HTTP
if(empty($argv[1]) || (!empty($argv) && arrayContains($allowedCommandsWhenNotHttp, $argv[1]) && empty(getenv('HTTP_HOST')))) {
    $container = Container::getInstance();
    $container->boot();
    $container->make(CLIApplication::class)->run();
    exit;
}

// Para comandos que precisam de contexto HTTP
if (empty(getenv('HTTP_HOST'))) {
    throw new Exception('HTTP_HOST is not defined');
}

$app = require_once rootPath('bootstrap.php');
$app->make(CliBootstrapper::class)->ensureDatabaseConnection();  // Garante conexão BD
$app->make(CliBootstrapper::class)->boot();                       // Fase de boot
$app->make(CliBootstrapper::class)->end();                        // Carrega módulos e addons
$app->make(CLIApplication::class)->run();
```

**Características**:
- **SAPI Validation**: Garante execução apenas via CLI
- **Conditional HTTP_HOST**: Alguns comandos precisam de contexto web
- **Command Auto-Discovery**: Encontra comandos automaticamente em Modules/
- **Symfony Console**: Baseado no framework de comandos do Symfony

### 4. Cron Jobs - cron.php

**Finalidade**: Execução de tarefas agendadas com sistema de scheduling próprio

**Fluxo**:
```php
define('INDEXTOP', 1);
define("CRON_RUN", true);
define('ROOT_DIR', realpath(__DIR__));

// Segurança: apenas localhost ou IPs autorizados
if (isset($_SERVER['REMOTE_ADDR']) && !in_array($_SERVER['REMOTE_ADDR'], ['127.0.0.1', gethostbyname('office.guisoft.net')])) {
    die('No access');
}

// Configurações para execução prolongada
@ini_set("max_execution_time", 0);
@ini_set("memory_limit", '-1');
@set_time_limit(0);

// Argumentos: company_id, HTTP_HOST, data_execução_opcional
$company_id = (isset($argv[1]) && is_numeric($argv[1])) ? $argv[1] : 1;
$upload = (isset($argv[2]) && !empty($argv[2])) ? '/_uploads/' . $argv[2] . '/' : '/upload/';

// Sistema de limpeza no shutdown
register_shutdown_function($clean_after_exit);

// Carrega configuração baseada no contexto
if (isset($argv[2]) && !empty($argv[2])) {
    $_SERVER['HTTP_HOST'] = $argv[2];
    require_once(__DIR__ . '/_files/init.php');
}

// Sistema de scheduling cron-like
// Leitura de cron.csv e execução de jobs
```

**Características**:
- **Security First**: Apenas IPs autorizados podem executar
- **Memory & Time Unlimited**: Configurado para execução prolongada
- **Multi-tenant**: Suporta múltiplas empresas via company_id
- **Custom Cron Format**: Sistema próprio de scheduling baseado em CSV
- **Notification Integration**: Notificações via Mattermost para debugging
- **Error Handling**: Captura e reporta erros de execução

### 5. Downloads - download.php

**Finalidade**: Servir arquivos de forma segura com controlo de acesso

**Fluxo**:
```php
define('INDEXTOP', 1);
define("DEFERRED_INIT", true);
require(__DIR__ . '/_files/init.php');

if (isset($_REQUEST['i'])) {
    $OG_Init->init_2();

    // Busca informações do arquivo na base de dados
    $file = $db->select(['Num','FileName','ShowName','Localizacao','FileType'])
               ->where('Num', base64_decode($_REQUEST['i']))
               ->get(TABLE_ATTACHMENTS)
               ->row();

    // Validações de segurança e servir arquivo
}
```

**Características**:
- **Database-Driven**: Arquivos referenciados na base de dados
- **Base64 Security**: IDs codificados para evitar acesso direto
- **MIME Type Detection**: Detecção automática do tipo de arquivo
- **Access Control**: Integrado com sistema de permissões

### 6. Uploads - upload.php

**Finalidade**: Servir arquivos uploadados (imagens, documentos) com transformações

**Fluxo**:
```php
define('INDEXTOP', 1);
require(__DIR__ . '/_files/init.php');

$url = Funcs::explode_verify_array('/', urldecode($_SERVER['REQUEST_URI']));

// Detecção de modificadores (watermark, avatar)
$watermark = (strtolower(end($url)) === "watermark" /* ... */);
$avatar = (strtolower(end($url)) === "avatar" /* ... */);

// Processamento e servir arquivo
```

**Características**:
- **Image Processing**: Suporte a watermarks e avatars
- **Path Parsing**: Análise inteligente de URLs para transformações
- **File Serving**: Servir arquivos com headers corretos

### 7. Images - loadImage.php

**Finalidade**: Carregar imagens de diferentes fontes (base de dados, filesystem)

**Fluxo**:
```php
define('INDEXTOP', 1);
require(__DIR__.'/_files/init.php');

$params = unserialize(base64_decode(strrev($_REQUEST['i'])));

switch (strtolower($params['action'])) {
    case 'getcodartigo':
        // Carregar imagem de artigo da base de dados
    case 'getimage':
        // Carregar imagem raw
    case 'loadupload':
        // Carregar de arquivo upload
}
```

**Características**:
- **Multiple Sources**: Base de dados, filesystem, URLs
- **Serialized Parameters**: Parâmetros codificados e serializados
- **MIME Detection**: Detecção automática de tipos de imagem

---

## Análise Detalhada dos Bootstrappers

### Hierarquia de Classes

```
Bootstrap (classe abstrata)
├── ApplicationBootstrapper (para requisições HTTP/Web)
└── CliBootstrapper (para linha de comando)
```

### Classe Base: Bootstrap

A classe `Bootstrap` contém toda a lógica comum de inicialização que é partilhada entre contextos web e CLI.

#### Propriedades Importantes

```php
protected array $reservedVariables = []; // Variáveis protegidas do sistema
protected array $dangerVars = [];        // Variáveis perigosas que devem ser removidas
```

### ApplicationBootstrapper vs CliBootstrapper

| Aspecto | ApplicationBootstrapper                               | CliBootstrapper |
|---------|-------------------------------------------------------|-----------------|
| **Contexto** | HTTP/Web                                              | Linha de comando |
| **Sanitização** | Sanitiza $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE | Não aplica sanitização HTTP |
| **Sessões** | Gere sessões web                                      | Não usa sessões |
| **Inicialização** | init_1() + init_2()                                   | constructor + boot() + end() |
| **Base de Dados** | Conecta em init_2()                                   | ensureDatabaseConnection() |
| **Performance** | Duas fases para otimização                            | Três métodos separados |
| **Control de Estado** | Sem flags                                            | Flags isBooted, isDatabaseConnected, isLoaded |
| **Security** | Multiple layers                                       | Minimal |

---

## Fluxos de Inicialização

### 1. Bootstrap HTTP Completo (index.php)

```
1. .htaccess processa requisição
2. index.php define INDEXTOP=1
3. require _files/init.php
   ├── define ROOT_DIR
   ├── require vendor/autoload.php (Composer)
   ├── $app = require bootstrap.php (Container DI)
   ├── ob_start() + session_start()
   ├── $OG_Init = ApplicationBootstrapper
   ├── $OG_Init->loadConfigFile()
   ├── $OG_Init->loadCustomerSession()
   ├── Sentry initialization
   └── $OG_Init->init_1()
4. $hooks->execute('init_1')
5. $hooks->execute('init_2')
6. Sistema de autenticação
7. Mod rewrite parsing
8. $OG_Init->init_2() (se não DEFERRED)
9. Roteamento e views
10. Footer e cleanup
```

### 2. Bootstrap CLI (./og command)

```
1. Shebang #!/usr/bin/env php
2. SAPI validation
3. require vendor/autoload.php
4. ErrorHandler::register() (estático)
5. Carregamento .env com Dotenv
6. Define allowedCommandsWhenNotHttp
7. Se comando simples (sem contexto HTTP):
   ├── Container::getInstance()
   ├── $container->boot()
   └── CLIApplication->run()
8. Se comando complexo:
   ├── Valida HTTP_HOST
   ├── require bootstrap.php (Container DI + CliBootstrapper constructor)
   ├── CliBootstrapper->ensureDatabaseConnection()
   ├── CliBootstrapper->boot()
   ├── CliBootstrapper->end()
   └── CLIApplication->run()
```

### 3. Bootstrap AJAX (ajaxserver/*)

```
1. .htaccess redirect para AjaxServer.php
2. define INDEXTOP=1, DEFERRED_INIT=true
3. require _files/init.php (sem init_2)
4. Action parsing (URL ou parâmetro)
5. $OG_Init->init_2() (apenas quando necessário)
6. new AjaxServer($action)
7. Validation (exceto endpoints públicos)
8. Dynamic method execution
```

### 4. Bootstrap Cron (cron.php)

```
1. define INDEXTOP=1, CRON_RUN=true
2. Security check (IP whitelist)
3. Performance settings (unlimited memory/time)
4. Arguments parsing (company_id, HTTP_HOST)
5. register_shutdown_function()
6. Conditional require _files/init.php
7. Cron scheduling system
8. Job execution com error handling
9. Notification system
```

---

## Container de Injeção de Dependência

### bootstrap.php - Ponto Central

```php
use Dotenv\Dotenv;
use Og\Modules\Common\Container\Container;
use Og\Modules\Common\Error\ErrorHandler;
use Og\Modules\Common\Legacy\Bootstrap\ApplicationBootstrapper;
use Og\Modules\Common\Legacy\Bootstrap\CliBootstrapper;

// 1. Error Handler - registo estático
ErrorHandler::register();

// 2. Carregamento de variáveis de ambiente (.env)
$envPath = rootPath('.env');
if (file_exists($envPath)) {
    Dotenv::createImmutable(rootPath())->safeLoad();
}

// 3. Container DI
$container = Container::getInstance();

// 4. Verificação adicional de .env (fallback)
if (empty($_ENV) && empty(getenv('APP_ENV'))) {
    $envPath = rootPath('.env');
    if (file_exists($envPath)) {
        Dotenv::createImmutable(rootPath())->safeLoad();
    }
}

// 5. HTTP_HOST environment setup
if (empty($_SERVER['HTTP_HOST']) && !empty(getenv('HTTP_HOST'))) {
    $_SERVER['HTTP_HOST'] = getenv('HTTP_HOST');
}

// 6. Context-aware bootstrapper selection
if (isCli()) {
    $container->make(CliBootstrapper::class);
} else {
    $container->make(ApplicationBootstrapper::class);
}

// 7. Boot do container (carrega service providers)
$container->boot();

return $container;
```

### Container Features

O container é baseado no Laravel Container mas com extensões específicas:

```php
class Container
{
    private static ?Container $instance = null;
    private LaravelContainer $container;
    private ServiceProviderManager $providerManager;
    private bool $booted = false;

    // Service Providers registrados automaticamente:
    // - CacheServiceProvider (Redis/File cache)
    // - QueueServiceProvider (RabbitMQ/Redis queues)
    // - RoutingServiceProvider (Rotas modernas)
    // - ViewServiceProvider (Template system)
    // - ValidationServiceProvider (Validação)
    // - NotificationServiceProvider (Notificações)
    // - HttpClientServiceProvider (HTTP client)
    // - RedisServiceProvider (Redis connections)
    // - GlobalServiceProvider (Legacy globals)
}
```

---

## Análise Método por Método

### ApplicationBootstrapper::init_1()

**Finalidade**: Primeira fase da inicialização - segurança, configuração básica

**Ordem de Execução e Razões**:

```php
public function init_1(): void
{
    // 1. INÍCIO - Medição de performance
    $this->time_init_start = hrtime(true);

    // 2. SEGURANÇA - Sanitização de inputs (CRÍTICO - deve ser primeiro)
    $_GET = $this->sanitizeInputVars($_GET);
    $_POST = $this->sanitizeInputVars($_POST);
    $_REQUEST = $this->sanitizeInputVars($_REQUEST);
    $_SERVER = $this->sanitizeInputVars($_SERVER);
    $_COOKIE = $this->sanitizeInputVars($_COOKIE);

    // 3. SEGURANÇA - Limpeza de variáveis perigosas
    $this->cleanDangerVars();

    // 4. BRANDING - Carregamento de rebranding (precisa ser antes da config)
    $this->loadRebrandig();

    // 5. CONFIGURAÇÃO - Verificação de constantes fase 1
    $this->checkDefinedVars(1);

    // 6. CORE FILES - Carregamento de arquivos essenciais
    $this->loadRequiredFiles();

    // 7. CONFIGURAÇÃO PRINCIPAL - Carregamento e validação de config.php
    if (!$this->load_config()) {
        // ERRO CRÍTICO - para execução
        echo 'Erro de configuração...';
        Funcs::flush();
        die();
    }

    // 8. PHP SETTINGS - Configurações do PHP (após config.php)
    $this->set_php_settings();

    // 9. SEGURANÇA - Segunda limpeza (após configurações)
    $this->cleanDangerVars();

    // 10. CONFIGURAÇÃO - Verificação de constantes fase 2
    $this->checkDefinedVars(2);

    // 11. AUTOLOADER - Registro do autoloader legacy
    spl_autoload_register([$this, "autoloadClass"]);

    // 12. CLEANUP - Limpeza final de variáveis
    $this->cleanVariables();
}
```

**Por que esta ordem?**

1. **Sanitização primeiro**: Protege contra ataques antes de qualquer processamento
2. **Rebranding antes de config**: Permite personalização de mensagens de erro
3. **Config antes de PHP settings**: PHP settings podem depender de valores de configuração
4. **Autoloader por último**: Garante que todas as classes estão disponíveis para carregamento

### ApplicationBootstrapper::init_2()

**Finalidade**: Segunda fase - base de dados, módulos, sistema completo

```php
public function init_2()
{
    // 1. BASE DE DADOS - Conexão (CRÍTICO - tudo depende disto)
    if (!$this->databaseConnect() || (defined('MAINTENANCE') && MAINTENANCE === 1)) {
        require_once(VIEWS_DIR . "maintenance.php");
        die();
    }

    // 2. REDIS - Inicialização do cache (após BD para configurações)
    $this->initialize_redis();

    // 3. MÓDULOS ESSENCIAIS - Carregamento de módulos críticos
    $this->loadRequiredModules();

    // 4. IDIOMA - Sistema de localização
    $this->loadLanguage();

    // 5. CONFIGURAÇÃO - Verificação fase 3 (após BD)
    $this->checkDefinedVars(3);

    // 6. MÓDULOS - Carregamento de todos os módulos
    $this->loadModules();

    // 7. ADDONS - Carregamento de plugins
    $this->load_addons();

    // 8. CONFIGURAÇÃO - Verificação de configurações obrigatórias
    $this->verifyRequiredConfs();

    // 9. WEBHOOKS - Sistema de hooks externos
    $this->load_WebHooks();

    // 10. UPGRADE - Verificação de atualizações
    $this->needUpgrade();

    // 11. DIRETÓRIOS - Criação de diretórios necessários
    $this->check_upload_dir();
}
```

**Por que esta ordem?**

1. **Base de dados primeiro**: Tudo depende da conectividade
2. **Redis após BD**: Configurações de Redis podem estar na BD
3. **Módulos essenciais antes dos opcionais**: Dependências
4. **Idioma após módulos**: Módulos podem ter traduções próprias
5. **Upgrade no final**: Pode redirecionar e interromper fluxo

### CliBootstrapper - Arquitetura em Fases

**Finalidade**: Inicialização modular para CLI com controle de estado através de métodos separados

#### Constructor (Inicialização básica)

```php
public function __construct()
{
    // 1. CONTAINER - Instância do container DI
    $this->container = Container::getInstance();

    // 2. ROOT_DIR - Definição se necessário
    if (!defined('ROOT_DIR')) {
        define('ROOT_DIR', rootPath());
    }

    // 3. VALIDAÇÃO CLI - Sai se não for CLI
    if (!isCli()) {
        return;
    }

    // 4. CONFIG FILE - Carregamento de arquivo configuração (com require)
    $this->configFile(true);

    // 5. CUSTOMER SESSION - Sessão do cliente (multi-tenant)
    $this->customerSession();

    // 6. REBRANDING - Carregamento de personalização
    $this->loadRebrandig();
}
```

#### Método boot() (Configurações e Autoloader)

```php
public function boot(): void
{
    if ($this->isBooted) {  // Flag para evitar re-execução
        return;
    }
    // 1. CONFIGURAÇÃO - Fase 1 de constantes
    $this->checkDefinedVars(1);

    // 2. REQUIRED FILES - Arquivos essenciais
    $this->loadRequiredFiles();

    // 3. PHP SETTINGS - Configurações do PHP
    $this->set_php_settings();

    // 4. CONFIGURAÇÃO - Fase 2 de constantes
    $this->checkDefinedVars(2);

    // 5. AUTOLOADER - Registro autoloader
    spl_autoload_register([$this, "autoloadClass"]);

    $this->isBooted = true;
}
```

#### Método ensureDatabaseConnection() (Conexão BD)

```php
public function ensureDatabaseConnection(): void
{
    if ($this->isDatabaseConnected) {  // Flag para evitar reconexão
        return;
    }
    $this->databaseConnect();
    $this->isDatabaseConnected = true;
}
```

#### Método end() (Módulos e Addons)

```php
public function end(): void
{
    if ($this->isLoaded) {  // Flag para evitar re-carregamento
        return;
    }
    // 1. MÓDULOS ESSENCIAIS - Carregamento de módulos críticos
    $this->loadRequiredModules();

    // 2. LANGUAGE - Sistema de idiomas
    $this->language($_COOKIE['lang'] ?? 'pt', 'l');

    // 3. MÓDULOS - Todos os módulos
    $this->loadModules();

    // 4. ADDONS - Plugins
    $this->load_addons();

    // 5. CRITICAL MODULES - Módulos críticos (debug only)
    $this->loadCriticalModules();

    $this->isLoaded = true;
}
```

**Por que arquitetura em fases?**
- **Controle de Estado**: Flags (`isBooted`, `isDatabaseConnected`, `isLoaded`) evitam re-execução
- **Flexibilidade**: Permite chamar apenas os métodos necessários dependendo do comando
- **Comandos Simples**: Alguns comandos não precisam de BD ou módulos completos
- **Comandos Complexos**: Podem chamar todos os métodos para contexto completo

---

## Métodos da Classe Bootstrap (Partilhados)

### checkDefinedVars($level)

**Finalidade**: Define constantes do sistema em 3 fases

```php
protected function checkDefinedVars($level): void
{
    $defined = [
        1 => [ // FASE 1: Paths básicos (antes da configuração)
            'WEBSITE_NAME' => 'OfficeGest',
            'FILES_DIR'    => rootPath('/_files/'),
            'LOGS_DIR'     => /* path dinâmico */,
            'VIEWS_DIR'    => rootPath('/_views/'),
            'LANG_DIR'     => rootPath('/_lang/'),
            'FORMS_DIR'    => rootPath('/_forms/'),
            'ADDONS_DIR'   => rootPath('/addons/'),
            'UPLOAD_DIR'   => /* path dinâmico */,
        ],
        2 => [ // FASE 2: Configurações do sistema (após config.php)
            'DEBUG'          => 0,
            'WEBSITE_URL'    => /* gerado dinamicamente */,
            'COOKIE_DOMAIN'  => '',
            'DB_SERVER'      => '',
            'LICENSE_KEY'    => '',
            // ... outras configurações de BD e sistema
        ],
        3 => [ // FASE 3: APIs e serviços externos (após BD)
            'ONLINESERVICESAPI'     => /* da configuração ou default */,
            'MAISVALORAPI'          => /* da configuração ou default */,
            'ELASTICSEARCH_HOST'    => '10.30.100.240',
            // ... outras APIs
        ],
    ];
}
```

**Por que 3 fases?**
- **Fase 1**: Paths básicos necessários para encontrar arquivos
- **Fase 2**: Após carregar config.php - configurações específicas
- **Fase 3**: Após BD - configurações que podem vir da base de dados

### sanitizeInputVars($arr)

**Finalidade**: Sanitização recursiva de arrays de input

```php
private function sanitizeInputVars($arr): array|string
{
    $cleandata = [];
    if (is_array($arr)) {
        foreach ($arr as $key => $val) {
            // Validação de chave: apenas alfanuméricos, _, -, ., espaço, !=
            if (ctype_alnum(replace(["_", "-", ".", " ", "!="], "", $key))) {
                if (is_array($val)) {
                    // Recursão para arrays aninhados
                    $cleandata[$key] = $this->sanitizeInputVars($val);
                } else {
                    $cleandata[$key] = $val; // Mantém valor original

                    // Remove magic quotes se existirem (legacy PHP)
                    if (ini_get('magic_quotes_sybase') &&
                        (strtolower(ini_get('magic_quotes_sybase')) != "off")) {
                        $cleandata[$key] = stripslashes($cleandata[$key]);
                    }
                }
            }
            // Se chave inválida, não inclui no array limpo
        }
    } else {
        // Para strings simples
        $cleandata = htmlspecialchars($arr);
        if ((function_exists("get_magic_quotes_gpc") && get_magic_quotes_gpc()) ||
            (ini_get('magic_quotes_sybase') &&
             (strtolower(ini_get('magic_quotes_sybase')) != "off"))) {
            $cleandata = stripslashes($cleandata);
        }
    }
    return $cleandata;
}
```

**Estratégia de segurança**:
- **Key Validation**: Apenas chaves "seguras" são aceites
- **Recursive**: Funciona com arrays multi-dimensionais
- **Magic Quotes**: Compatibilidade com versões legacy do PHP
- **htmlspecialchars**: Para strings simples

### databaseConnect($var = "db")

**Finalidade**: Estabelece conexão com base de dados

```php
public function databaseConnect(string $var = "db")
{
    if (isCli()) {
        $startTime = microtime(true); // Timing para CLI
    }

    try {
        // Resolve database service do container DI
        $$var = app()->makeWith('database', ['dbParamName' => $var]);

        if (isCli() && isset($startTime)) {
            $duration = round((microtime(true) - $startTime) * 1000, 2);
            // Log timing information
        }

    } catch (Throwable $e) {
        // CRITICAL notification (sempre envia)
        if (isCli()) {
            CliNotifier::databaseFailed($e->getMessage());
        }
        throw $e; // Re-throw para parar execução
    }

    // Define views baseadas na plataforma de BD
    if (!defined('VIEW_DUMPDOCUMENTS')) {
        define('VIEW_DUMPDOCUMENTS',
               (in_array($$var->platform(), ['mysql', 'mysqli']))
               ? 'dumpdocumentstable' : 'dumpdocuments');
    }
    // ... outras views

    return $$var->conn_id;
}
```

**Estratégias implementadas**:
- **DI Container**: Usa container para resolver dependências
- **Performance Monitoring**: Mede tempo de conexão no CLI
- **Error Notification**: Notifica falhas críticas
- **Platform Detection**: Views diferentes por tipo de BD
- **Global Variable**: Mantém compatibilidade legacy com $db

### loadRequiredModules()

**Finalidade**: Carrega módulos essenciais do sistema via container DI

```php
protected function loadRequiredModules(): void
{
    global $a, $u, $s, $print, $mail, $cmsg, $empresa, $restclient, $attachments, $m, $ogTheme;

    $m = [];

    // Resolve serviços do container DI
    $a = app('app');                    // Aplicação principal
    $u = app('user');                   // Utilizador
    $s = app('session');                // Sessão
    $m['tabelasdeapoio'] = app('support-tables'); // Tabelas de apoio
    $print = app('printer');            // Impressão
    $mail = app('email');               // Email
    $cmsg = app('message-center');      // Centro de mensagens
    $empresa = $a->ShadowHorizonBlaze(); // Dados da empresa
    $restclient = app('rest-client');   // Cliente REST
    $attachments = app('attachments');  // Anexos

    // Sistema de temas (Beta feature)
    $ogTheme = 'light';
    if ($a->getParam('BETA') == 1 && isset($_COOKIE['ogTheme'])) {
        $ogTheme = $_COOKIE['ogTheme'];
        if ($ogTheme == 'system') {
            $ogTheme = isset($_COOKIE['prefersDarkScheme']) ? 'dark' : 'light';
        }
    }
}
```

**Por que "required"?**
- **Dependency Chain**: Outros módulos dependem destes
- **Global Compatibility**: Mantém variáveis globais para código legacy
- **DI Integration**: Usa container moderno mas expõe via globais
- **Theme System**: Configura tema visual baseado nas preferências

### loadModules()

**Finalidade**: Carrega todos os módulos do sistema baseado na licença

```php
protected function loadModules(): void
{
    global $a, $m;

    // Combina módulos essenciais com os licenciados
    $modules = array_merge(
        ['Entidades', 'financeiros', 'gdpr'], // Sempre disponíveis
        $a->getModules()                      // Da licença
    );

    foreach ($modules as $module) {
        $name = strtolower($module);
        if (class_exists($module)) {
            $m[$name] = new $module();        // Instancia classe
        }
    }
}
```

**Sistema de módulos**:
- **License-Based**: Módulos baseados na licença do cliente
- **Essential Modules**: Alguns módulos são sempre carregados
- **Dynamic Loading**: Classes carregadas dinamicamente
- **Global Registry**: Armazenado em $m global para acesso legacy

### set_php_settings()

**Finalidade**: Configura settings do PHP para o ambiente OfficeGest

```php
public function set_php_settings(): void
{
    // Performance settings
    @ini_set('max_execution_time', 900);     // 15 minutos
    @ini_set('memory_limit', defined('MEMORY_LIMIT') ? MEMORY_LIMIT : '1024M');
    @ini_set('date.timezone', defined('TIMEZONE') ? TIMEZONE : 'Europe/Lisbon');

    // Session settings
    if (@ini_get("session.gc_maxlifetime") < 18000) {
        @ini_set('session.gc_maxlifetime', 18000); // 5 horas
    }

    // Debug vs Production
    if (defined('DEBUG') && DEBUG) {
        error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
        ini_set('display_errors', '1');
        ini_set('display_startup_errors', '1');
    } else {
        error_reporting(0);
        ini_set('display_errors', '0');
    }

    // SSL Redirect
    if (!isCli() && defined('IS_SSL') && IS_SSL == true &&
        ($_SERVER["REQUEST_URI"] == "/" || $_SERVER["REQUEST_URI"] == "/login") &&
        $this->getServerPort() == 80) {
        header("Location: https://" . $_SERVER['SERVER_NAME']);
        die('<h2><a href="https://' . $_SERVER['SERVER_NAME'] . '">https://' . $_SERVER['SERVER_NAME'] . '</a></h2>');
    }

    // HTTP Auth header parsing
    if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) && !empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
        [$_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']] =
            Funcs::explode_verify_array(':', base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 6)), 2);
    }
}
```

**Configurações importantes**:
- **Memory & Time**: Configurado para aplicações web pesadas
- **Timezone**: Padrão português mas configurável
- **Session Lifetime**: 5 horas de inatividade
- **SSL Enforcement**: Redirect automático quando configurado
- **HTTP Auth**: Suporte para autenticação HTTP

---

## Sistema de Roteamento

### Roteamento Híbrido no index.php

O sistema combina roteamento moderno com legacy:

```php
// 1. Roteamento moderno (Container DI)
$routerCollector = app('router-collector');
[$parsedUri, $method] = $routerCollector->getParsedUri();
$routeExists = $routerCollector->routeExists($parsedUri, $method);

if ($routeExists) {
    \Og\Modules\Common\Facades\Route::run();  // Sistema moderno
} elseif ($category == "dsa") {
    require_once(VIEWS_DIR . "dsa.php");     // Sistema especial
} elseif (isset($category)) {
    // 2. Roteamento legacy (switch/case gigante)
    switch ($category) {
        case 'entidades':
            if (isset($user) && $u->IsLogged() && $u->checkPriv("entidades")) {
                $useraction = $modrewrite[1];
                if (!isset($useraction) || $useraction == "") {
                    $useraction = "clientes";  // Default
                }
                if (file_exists(VIEWS_DIR . "entidades/" . $useraction . ".php")) {
                    if ($u->checkPriv("entidades:" . $useraction)) {
                        $l->load("entidades/" . $useraction);
                        require_once(VIEWS_DIR . "entidades/" . $useraction . ".php");
                    } else {
                        require_once(VIEWS_DIR . "error_noaccess.php");
                    }
                } else {
                    require_once(VIEWS_DIR . "error_404.php");
                }
            } else {
                require_once(VIEWS_DIR . "error_noaccess.php");
            }
            break;
        // ... dezenas de outros cases
    }
}
```

**Sistema de 3 camadas**:
1. **Rotas Modernas**: Definidas no sistema de módulos
2. **DSA (Do Some Action)**: Sistema especial para ações específicas
3. **Legacy Switch**: Baseado na primeira parte da URL

**Características do roteamento legacy**:
- **Permission-Based**: Cada rota verifica permissões
- **Module-Based**: Organized por módulos funcionais
- **Default Actions**: Cada módulo tem uma ação padrão
- **File-Based**: Views são arquivos PHP físicos
- **Error Handling**: 404 e no-access padronizados

---

## Sistema de Variáveis Globais Legacy

Para compatibilidade, o sistema expõe variáveis globais essenciais:

```php
// Disponíveis após bootstrap completo
global $a, $u, $m, $db, $s, $hooks, $l;

$a    // Aplicação principal (Aplication class)
$u    // Utilizador logado (User class)
$m    // Módulos disponíveis (array associativo)
$db   // Conexão base de dados (DB class)
$s    // Sessão (Session class)
$hooks // Sistema de hooks (Hooks class)
$l    // Language system (Language class)
```

### Exemplos de Uso Comum

```php
// Verificar permissões
if ($u->checkPriv('stocks:artigos')) {
    // User tem permissão para módulo stocks, ação artigos
}

// Acesso à base de dados
$products = $db->fetchAll("SELECT * FROM artigos WHERE active = 'T'");

// Executar hooks para extensibilidade
$hooks->execute('before_save_product', $productData);

// Obter parâmetro de configuração
$companyName = $a->getParam('NomeEmpresa');

// Sistema de traduções
echo $l->r('welcome_message'); // Retorna tradução de 'welcome_message'
```

---

## Troubleshooting e Problemas Comuns

### 1. Erro: "Configuration file error"

**Sintomas**: Sistema não inicia, mensagem de erro de configuração

**Causas possíveis**:
- `config.php` não existe em `_files/` ou `_configs/{HOST}/`
- `config.php` tem erros de sintaxe PHP
- Constante `LICENSE_KEY` não está definida

**Solução**:
```bash
# Verificar se arquivo existe
ls -la _files/config.php
ls -la _configs/$(hostname)/config.php

# Verificar sintaxe PHP
php -l _files/config.php

# Verificar constantes obrigatórias
grep "LICENSE_KEY" _files/config.php
```

### 2. Erro: "Invalid Session" no AJAX

**Sintomas**: Requests AJAX retornam "Invalid Session"

**Causas possíveis**:
- Sessão PHP expirada
- Cookies bloqueados
- Domínio de cookie mal configurado
- CSRF token inválido

**Solução**:
```php
// Verificar configuração de sessão
echo "Session ID: " . session_id();
echo "Cookie Domain: " . ini_get('session.cookie_domain');

// Debug sessão
var_dump($_SESSION);
var_dump($_COOKIE);

// Verificar endpoints que não requerem sessão
$ignValidate = ['login', 'login_panel', 'smsAuthLogin', 'newsslides', 'DevNull', 'ping', 'oauthconnector'];
```

### 3. Erro: "HTTP_HOST is not defined" no CLI

**Sintomas**: Comandos CLI falham com erro de HTTP_HOST

**Causas**: Comando precisa de contexto HTTP mas variável não está definida

**Solução**:
```bash
# Definir HTTP_HOST antes do comando
export HTTP_HOST=meudominio.com
./og comando:executar

# Ou inline
HTTP_HOST=meudominio.com ./og comando:executar

# Para comandos que não precisam de HTTP_HOST
./og queue:work  # OK, está na lista allowedCommandsWhenNotHttp
./og cache:clear # OK, está na lista allowedCommandsWhenNotHttp
```

### 4. Container não resolve dependências

**Sintomas**: Erro "Class X cannot be resolved"

**Causas possíveis**:
- Service Provider não registrado
- Binding incorreto
- Circular dependency

**Debug**:
```php
// Verificar se service está registrado
$services = app()->getBindings();
var_dump(array_keys($services));

// Verificar Service Providers carregados
$providers = Container::getInstance()->getLoadedProviders();
var_dump($providers);

// Resolver manualmente para debug
try {
    $service = app()->make(ProblematicService::class);
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
    echo "Trace: " . $e->getTraceAsString();
}
```

### 5. Performance Issues no Bootstrap

**Sintomas**: Aplicação demora muito a carregar

**Debug e otimização**:
```php
// Medir tempo de bootstrap (já implementado)
if (isset($OG_Init)) {
    $duration = ($OG_Init->time_init_end - $OG_Init->time_init_start) / 1000000;
    echo "Bootstrap time: {$duration}ms";
}

// Usar DEFERRED_INIT quando possível
define("DEFERRED_INIT", true);

// Verificar conexões de base de dados
$startTime = microtime(true);
$db->query("SELECT 1");
$dbTime = (microtime(true) - $startTime) * 1000;
echo "DB Connection time: {$dbTime}ms";

// Verificar Redis
$startTime = microtime(true);
$redis->ping();
$redisTime = (microtime(true) - $startTime) * 1000;
echo "Redis time: {$redisTime}ms";
```

### 6. Cron Jobs não executam

**Sintomas**: Tarefas agendadas não são executadas

**Debug**:
```bash
# Verificar se cron.php é executável
chmod +x cron.php

# Testar execução manual
php cron.php 1 meudominio.com

# Verificar se cron.csv existe e tem conteúdo
ls -la _uploads/meudominio.com/1/cron.csv
cat _uploads/meudominio.com/1/cron.csv

# Verificar logs de cron
tail -f _logs/meudominio.com/cronjob.log

# Verificar se jobs estão no formato correto do CSV
# Formato: minute,hour,day,month,weekday,path,module,addon,description,id_report
```

### 7. Módulos não carregam

**Sintomas**: Funcionalidade de módulo não está disponível

**Debug**:
```php
// Verificar módulos licenciados
global $a;
$modules = $a->getModules();
var_dump($modules);

// Verificar se classe do módulo existe
$module = 'Stocks';
if (class_exists($module)) {
    echo "Classe {$module} existe";
} else {
    echo "Classe {$module} NÃO existe";
}

// Verificar se módulo foi instanciado
global $m;
var_dump(array_keys($m));

// Verificar licença
var_dump($a->lic);
```

---

## Comandos de Diagnóstico

### CLI Commands para Debug

```bash
# Listar todos os comandos disponíveis
./og list

# Verificar configuração do sistema
./og config:show

# Testar conectividade de base de dados
./og database:test

# Limpar caches
./og cache:clear

# Verificar rotas registradas
./og route:list

# Status das filas
./og queue:status

# Informações do sistema
./og system:info

# Verificar saúde do sistema
./og health:check
```

### Logs Importantes

```bash
# Logs principais por localização
_logs/{HTTP_HOST}/error.log       # Erros PHP gerais
_logs/{HTTP_HOST}/cronjob.log     # Execução de cron jobs
_logs/{HTTP_HOST}/debug.log       # Debug messages
_logs/{HTTP_HOST}/license.log     # Verificações de licença
_logs/{HTTP_HOST}/database.log    # Queries e erros de BD

# Logs do servidor web
/var/log/apache2/error.log        # Apache errors
/var/log/nginx/error.log          # Nginx errors
```

---

## Notas Finais para Developers

### Best Practices

1. **Use o Container DI**: Para novos developments, sempre usar `app()->make()`
2. **Respeite as fases de init**: Não aceda a serviços antes de estarem disponíveis
3. **DEFERRED_INIT para performance**: Use quando aplicável
4. **Error handling**: Sempre capture e trate exceções
5. **Logging**: Use `Funcs::log()` para debug
6. **Permissions**: Sempre verificar `$u->checkPriv()` antes de operações

### Arquitetura Evolutiva

O sistema está numa transição arquitetural:

- **Legacy** (\_files/, \_ajax/): Sistema antigo mas funcional
- **Modern** (Modules/): Nova arquitetura com DI, PSR-4, etc.
- **Hybrid**: Os dois sistemas coexistem e interoperam

### Contribuição

Para adicionar novas funcionalidades:

1. **Preferencialmente**: Usar arquitetura moderna em `Modules/`
2. **Service Providers**: Registrar novos serviços adequadamente
3. **Commands**: CLI commands em `*Command.php`
4. **Routes**: Usar sistema de rotas moderno quando possível
5. **Testes**: Adicionar testes para nova funcionalidade

---

*Esta documentação é viva e deve ser atualizada conforme o sistema evolui. Qualquer alteração significativa no bootstrap deve ser refletida aqui.*
