# Filesystem System - Framework OfficeGest

> **Nível**: Básico a Avançado  
> **Pré-requisitos**: Conhecimento básico de PHP e manipulação de arquivos  
> **Tempo de leitura**: ~10 minutos

---

## 📋 Índice

1. [Introdução](#introdução)
2. [Recuperar e Guardar Ficheiros](#recuperar-e-guardar-ficheiros)
3. [Gestão de Diretórios](#gestão-de-diretórios)
4. [Operações de I/O Seguras](#operações-de-io-seguras)
5. [Streams e Downloads](#streams-e-downloads)
6. [Facade File](#facade-file)
7. [Exemplos Práticos](#exemplos-práticos)

---

## Introdução

O OfficeGest possui uma camada de abstração poderosa para gestão de ficheiros, localizada em `Modules/Common/Filesystem/`. Esta camada oferece métodos seguros, normalizados e fáceis de usar para interagir com o sistema de ficheiros do servidor.

A forma mais comum de interagir é através da Facade `File` (`Og\Modules\Common\Facades\File`).

---

## Recuperar e Guardar Ficheiros

### `File::get($path)`

O método `get` é usado para recuperar o conteúdo de um ficheiro.

```php
use Og\Modules\Common\Facades\File;

try {
    $conteudo = File::get('/caminho/para/arquivo.txt');
} catch (\Exception $e) {
    // O ficheiro não existe
}
```

> **Nota:** Diferente do `file_get_contents` nativo do PHP, este método lança uma excepção explicita se o ficheiro não existir.

### `File::put($path, $contents, $permissions = 0644)`

O método `put` grava conteúdo num ficheiro. **Uma grande vantagem** deste método é que ele cria automaticamente todos os diretórios pai necessários se eles não existirem.

```php
// Cria automaticamente a pasta 'logs/2024/01/' se não existir
File::put('logs/2024/01/erro.log', 'Conteúdo do log');

// Também pode definir permissões específicas (Padrão: 0644)
File::put('scripts/executavel.sh', '#!/bin/bash...', 0755);
```

### `File::delete($path)`

Remove um ficheiro do sistema.

```php
if (File::delete('temp/arquivo_antigo.tmp')) {
    // Ficheiro removido com sucesso
}
```

### `File::fileExists($path)`

Verifica se um ficheiro (ou diretório) existe.

```php
if (File::fileExists('config/settings.json')) {
    // ...
}
```

### `File::copy($from, $to)` e `File::move($from, $to)`

Copia ou move ficheiros, criando diretórios de destino automaticamente se necessário.

```php
// Copia template para destino final, criando pastas se necessário
File::copy('stubs/controller.stub', 'Modules/Sales/Controllers/NewController.php');

// Move (Renomeia)
File::move('temp/upload_123.jpg', 'public/images/profile.jpg');
```

---

## Gestão de Diretórios

### `File::ensureDirectoryExists($path)`

Garante que um diretório existe. Se não existir, ele é criado (com permissão 0755).

```php
File::ensureDirectoryExists('storage/uploads/2024');
```

### `File::makeDirectory($path, $mode = 0755, $recursive = false)`

Cria um diretório com controle total sobre permissões e recursividade.

```php
// Cria estrutura complexa recursivamente
File::makeDirectory('storage/a/b/c', 0755, true);
```

---

## Streams e Downloads

Para lidar com ficheiros grandes ou downloads eficientes, o sistema oferece métodos otimizados que evitam carregar tudo para a memória RAM.

### `File::writeStream($stream, $path)`

Escreve um *resource stream* php diretamente para um ficheiro no disco. Ideal para salvar uploads grandes ou dados vindos de APIs externas.

```php
$stream = fopen('php://temp', 'r+');
fwrite($stream, 'Dados grandes...');
rewind($stream);

File::writeStream($stream, 'storage/big_file.dat');
```

### `File::streamDownload($filename, $stream, $mimeType)`

Inicia um download para o browser do utilizador a partir de um stream, sem carregar o ficheiro todo em memória.

```php
public function export()
{
    $stream = fopen('php://memory', 'r+');
    fputcsv($stream, ['ID', 'Nome', 'Email']);
    // ... escrever mais linhas ...
    rewind($stream);

    // O browser iniciará o download de 'export.csv'
    File::streamDownload('export.csv', $stream, 'text/csv');
}
```

---

## Facade File

A Facade `Og\Modules\Common\Facades\File` é a interface estática para a classe `Og\Modules\Common\Filesystem\Filesystem`.

| Método | Retorno | Descrição |
| :--- | :--- | :--- |
| `get($path)` | `string` | Retorna conteúdo do ficheiro. |
| `put($path, $content)` | `bool` | Grava conteúdo (cria dirs auto). |
| `delete($path)` | `bool` | Apaga ficheiro. |
| `fileExists($path)` | `bool` | Verifica existência. |
| `copy($from, $to)` | `bool` | Copia ficheiro. |
| `move($from, $to)` | `bool` | Move ficheiro. |
| `ensureDirectoryExists($path)` | `void` | Cria diretório se não existir. |
| `getRequire($path)` | `mixed` | Faz `require_once` do ficheiro. |

---

## Exemplos Práticos

### 1. Sistema de Cache de Rotas (Leitura e Escrita JSON)

Extraído de `Modules/Common/Routing/RouteCache.php`. Mostra como ler e escrever JSON de forma segura.

```php
use Og\Modules\Common\Facades\File;

// SALVAR CACHE
public function saveRouteCache(array $routes): void
{
    // Grava e subscreve o ficheiro de cache
    File::put('bootstrap/cache/routes.json', json_encode($routes));
}

// LER CACHE
public function loadRouteCache(): array
{
    if (!File::fileExists('bootstrap/cache/routes.json')) {
        return [];
    }

    $content = File::get('bootstrap/cache/routes.json');
    return json_decode($content, true);
}
```

### 2. Geração de Código (Stubs)

Extraído de `Modules/Common/CLI/Commands/MakeActionCommand.php`. Mostra a criação de ficheiros PHP baseados em templates (stubs).

```php
use Og\Modules\Common\Facades\File;

public function handle()
{
    $name = 'NewAction';
    $path = "Modules/Actions/{$name}.php";

    // 1. Verificar se já existe para não sobrescrever acidentalmente
    if (File::fileExists($path)) {
        throw new \Exception("Action já existe!");
    }

    // 2. Garantir que a pasta do módulo existe
    File::ensureDirectoryExists(dirname($path));

    // 3. Ler o template
    $stub = File::get(__DIR__.'/stubs/action.stub');

    // 4. Substituir placeholders
    $code = str_replace('{{class}}', $name, $stub);

    // 5. Gravar o novo ficheiro
    File::put($path, $code);
}
```

### 3. QueueMaster Crash Recovery (Escrita Atómica)

Extraído de `Modules/QueueMaster/Services/QueueMasterIntegration.php`. Salva o estado do sistema em caso de falha crítica.

```php
public function saveCrashDump(array $errorData): void
{
    $json = json_encode($errorData, JSON_PRETTY_PRINT);
    
    // O método put encarrega-se de criar a pasta 'storage/crash_dumps/' se
    // ela ainda não existir, prevenindo erros de "Directory not found".
    File::put('storage/crash_dumps/' . date('Y-m-d_H-i-s') . '.json', $json);
}
```