@extends('layouts.docs') @section('title', 'Utilities - OG Framework') @section('body')
@include('docs.partials.sidebar')
Voltar para Documentação

Ferramentas

Sistema de Utilities

Colecção de classes auxiliares especializadas que fornecem funcionalidades transversais essenciais: performance, debugging, configuração, e integração com sistemas legacy.

{{-- Introduction --}}

Visão Geral

O OfficeGest acumulou ao longo dos anos uma variedade de classes auxiliares que resolvem problemas específicos. Organizámo-las em categorias para facilitar a descoberta e reutilização.

Esta página apresenta as mais importantes. Não precisas de as memorizar todas — quando precisares de resolver um problema específico, provavelmente já existe uma utility para isso.

{{-- Benchmark --}}

Benchmark (Performance)

A classe Benchmark é essencial para identificar bottlenecks de performance. Se tens um endpoint lento mas não sabes porquê, usa o Benchmark para medir diferentes partes do código e descobrir onde está o problema.

Medir Tempo de Execução

O método value() executa uma closure, mede o tempo, e devolve o resultado junto com a duração.

use Og\Modules\Common\Utils\Benchmark;

// Medir uma operação específica
[$result, $time] = Benchmark::value(function() {
    return $this->heavyCalculation();
});

echo "Cálculo demorou {$time}ms";
echo $result;

Comparar Implementações

Quando tens duas formas de fazer algo e queres saber qual é mais rápida, usa compare().

$comparison = Benchmark::compare([
    function() { return array_map(...); },      // Método 1
    function() { return foreach + array; },      // Método 2
], iterations: 1000);

// Resultado mostra qual é mais rápida e por quanto
{{-- SqlProfiler --}}

SqlProfiler

O SqlProfiler é mais especializado que o Benchmark — foca-se exclusivamente em queries SQL. Regista todas as queries executadas, o seu tempo, e pode até identificar problemas comuns como N+1 queries.

Inicializar e Analisar

use Og\Modules\Common\Utils\SqlProfiler;

// Iniciar profiling no início do request
SqlProfiler::init([
    'log_threshold_ms' => 100,    // Logar queries > 100ms
    'explain_queries' => true,    // Executar EXPLAIN em queries lentas
    'backtrace_enabled' => true,  // Guardar stacktrace de cada query
]);

// No final do request, analisar
$report = SqlProfiler::getReport();
$slowQueries = SqlProfiler::getSlowestQueries(10);

// Identificar N+1
$duplicates = SqlProfiler::getDuplicateQueries();
{{-- Config --}}

Config

A classe Config é o repositório central de configurações. Carrega ficheiros PHP de uma directoria, faz merge de tudo, e fornece acesso via notação "dot" (app.debug, database.host).

Em produção, as configurações são cacheadas num único ficheiro para evitar carregar dezenas de ficheiros em cada request.

// Acesso via helper global
$debug = config('app.debug', false);
$dbHost = config('database.connections.mysql.host');

// Ou via classe directamente
$config = new Config('/path/to/config', '/path/to/cache.php');
$value = $config->get('app.name');

// Forçar rebuild do cache (após deploy, por exemplo)
$config->reload(force: true);
{{-- URL --}}

URL Builder

A classe URL fornece uma API fluente para construir URLs de forma segura. Trata automaticamente de encoding, query strings, e fragmentos.

use Og\Modules\Common\Utils\URL;

$url = (new URL())
    ->scheme('https')
    ->host('api.officegest.com')
    ->path('/v1/invoices')
    ->query(['status' => 'pending', 'page' => 2])
    ->fragment('results');

echo $url; // https://api.officegest.com/v1/invoices?status=pending&page=2#results

// Ou parsear uma URL existente
$url = URL::parse('https://exemplo.com/path?foo=bar');
echo $url->host();  // exemplo.com
echo $url->query('foo');  // bar
{{-- ProcessChain --}}

ProcessChain

O ProcessChain implementa o padrão Chain of Responsibility para processar dados através de uma sequência de passos. Cada passo pode transformar os dados ou interromper a cadeia se algo falhar.

Exemplo: Pipeline de Importação

use Og\Modules\Common\Utils\ProcessChain;

$result = (new ProcessChain())
    ->step(fn($data) => $this->validate($data))     // 1. Validar
    ->step(fn($data) => $this->normalize($data))    // 2. Normalizar
    ->step(fn($data) => $this->enrich($data))       // 3. Enriquecer
    ->step(fn($data) => $this->persist($data))      // 4. Guardar
    ->then(
        fn($result) => $this->notifySuccess($result),
        $inputData
    )
    ->catch(fn($error) => $this->logError($error)); // Se qualquer passo falhar

Se qualquer passo lançar uma excepção, a cadeia é interrompida e o handler catch() é chamado.

{{-- Navigation --}}
@include('docs.partials.toc', ['sections' => [ 'introducao' => 'Visão Geral', 'benchmark' => 'Benchmark', 'sql' => 'SqlProfiler', 'config' => 'Config', 'url' => 'URL Builder', 'processchain' => 'ProcessChain', ]])
@endsection