# Controladores — Diário Oficial

> _Atualizado para o **v6** (`update_diario_v5_to_v6`) em 2026-09-11. Alterações desta versão: `DIARIO_OFICIAL_ALTERACOES.md` e `plan/2026-09-11-diario-upgrade-backlog.md`._

## 1. `DiarioController` (CMS Principal)

**Arquivo:** `app/Http/Controllers/Prefecture/DiarioController.php`
**Rotas base:** `diario-oficial.*`

### Construtor

```php
public function __construct(IDiarioConfigRepository $repository_config)
{
    $this->middleware('check.route.permission')->except(['dados_diario', 'destroyAreas', 'generationStatus']);
    menuClicks('diario-oficial');
    $this->title = 'Diário Oficial';
    $this->table = app(Diario::class);
    $this->areas = app(DiarioArea::class);
    $this->subareas = app(DiarioSubArea::class);
    $this->repository = new DiarioOficialRepository();
    $this->diario_has_area = new DiarioHasAreas();
    $this->config_repository = $repository_config;
    $this->certificado = app(DiarioCertificado::class);
}
```

### Métodos Principais

| Método | Ação | View/Resposta |
|--------|------|---------------|
| `index()` | Listar diários | `view('...index', ['title' => 'Diário Oficial'])` |
| `create()` | Formulário de criação | `view('...create', ['areas', 'subareas', 'edicao', 'diarios', 'certificados', 'preinfo'])` |
| `store(DiarioOficialRequest)` | Salvar novo diário | Redireciona para edit; capa (se houver) e `dispatchGeneration` — **PDF não é gerado aqui** |
| `show($id, Request)` | Exibir/baixar PDF | `generatePDF($id, $force, true, ?download=1)`; `$force` é `true` quando `generation_status ∉ {completed, processing}` (regenera se desatualizado) |
| `edit($id)` | Formulário de edição | `view('...create', ['data' => $diario, ...])` |
| `update(DiarioOficialRequest, $id)` | Atualizar diário | Redireciona para index; `dispatchGeneration` + `activity()` (PDF gerado sob demanda) |
| `destroy($id)` | Excluir diário | `response()->json(...)` |
| `destroyAll(Request)` | Exclusão em lote | `response()->json(...)` |
| `publish($id)` | Publicar (4 olhos) | Exige `WORKFLOW_EM_REVISAO`, bloqueia o próprio elaborador; `status`, `permission_edit` |
| `toogle_status(Request)` | Ativar/Desativar | `response()->json(true/false)` respeitando segregação de funções |

### Métodos de Configuração

| Método | Rota | Ação |
|--------|------|------|
| `get_configuration()` | `GET diario/configuracoes` | View de configurações |
| `update_configuration(SaveConfigRequest)` | `PUT diario/configuracoes/update` | Salva config + upload header img |
| `delete_header_img($id)` | `DELETE diario/configuracoes/header-img/{id}` | Remove imagem de cabeçalho |

### Métodos de PDF / Geração

| Método | Rota | Ação |
|--------|------|------|
| `refresh_PDF($id)` | `GET /refresh-diario/{id}` | Regenera PDF + flash success |
| `refresh_PDF_preview($id, Request)` | `GET /refresh-diario-preview/{id}` | Marca `generation_status=processing`, zera `generation_progress`, gera síncrono e atualiza o status via **query update** (`completed`/`failed`) — responde JSON |
| `generationStatus($id)` | `GET /diario-generation-status/{id}` | JSON de polling: status, erro, progresso, `generation_started_at/completed_at` e `file_exists` |
| `loading()` | `GET /loading-diario-preview` | View de loading |

### Métodos de Capa / Publicação

| Método | Ação |
|--------|------|
| `attachCoverImage(Request, $diario)` (privado) | Grava em transação (rollback + log); comprime só raster limitando a altura a **1366px** (pula `webp/avif/gif/svg`) |
| `delete_cover_image($id)` | Remove o `Archive` da capa e zera `cover_image_id` (transação) |
| `publish($id)` | Aplica o princípio dos 4 olhos (revisor ≠ elaborador) |

### Métodos Auxiliares

| Método | Rota | Ação |
|--------|------|------|
| `dados_diario($id)` | `GET /ajax/dados-diario/{id}` | JSON com áreas e subáreas (GetDiarioResource) |
| `sort($id, SortRequest)` | `PUT /ajax/diario-oficial/{id}/sort` | Reordena áreas (position) |
| `destroyAreas($id)` | `DELETE /diario-area/{id}` | Remove área do diário |

---

## 2. `DiarioAreaController`

**Arquivo:** `app/Http/Controllers/Prefecture/DiarioAreaController.php`
**Rotas base:** `area.*`

Gerencia tanto as **Áreas** (categorias) quanto as **Matérias** (conteúdo do diário).

### Métodos

| Método | Uso |
|--------|-----|
| `index()` | Lista áreas (view) |
| `create()` | Formulário de nova área |
| `store(SaveAreaRequest)` | Se `request->name`: cria área. Se `request->conteudo`: cria matéria (DiarioHasAreas) |
| `show($id)` | JSON com dados do diário + áreas + permissões |
| `edit($id)` | Se `$id` contém 'modal': retorna JSON da matéria. Senão: form de área |
| `update(Request, $id)` | Se name: atualiza área. Senão: atualiza matéria |
| `destroy($id)` | Exclui área |
| `destroyAll(Request)` | Exclusão em lote |

**Processamento de Conteúdo:** O método `processContent($content)` percorre o HTML do Summernote, procurando imagens em base64 ou URLs externas, faz upload automático e compressão.

---

## 3. `DiarioSubAreaController`

**Arquivo:** `app/Http/Controllers/Prefecture/DiarioSubAreaController.php`
**Rotas base:** `subarea.*`

CRUD simples para Subáreas.

| Método | Uso |
|--------|-----|
| `index()` | Lista subáreas |
| `create()` | Formulário |
| `store(DiarioAreasRequest)` | Salva |
| `edit($id)` | Formulário de edição |
| `update(DiarioAreasRequest, $id)` | Atualiza |
| `destroy($id)` | Exclui |
| `destroyAll(Request)` | Exclusão em lote |

---

## 4. `DiarioCertificadosController`

**Arquivo:** `app/Http/Controllers/Prefecture/DiarioCertificadosController.php`
**Rotas base:** `certificado.*`

CRUD completo para certificados digitais (upload de arquivos .pfx, .p12, .crt + chaves).

No `store`, o certificado é validado: CRT gerado existe/não vazio, `openssl_x509_read` e presença de CN, além da leitura do PKCS12; em falha faz `forceDelete` + limpeza do diretório e registra log específico.

---

## 5. `DatatableController` (métodos Diario)

**Arquivo:** `app/Http/Controllers/Prefecture/DatatableController.php`

| Método | View/Fonte | Rota |
|--------|-----------|------|
| `get_diario_oficial()` | View `diario_oficial` | `/datatable/diario_oficial` |
| `get_areas_diario()` | View `areas_do_diario` | `/datatable/areas_diario` |
| `get_sub_areas_diario()` | View `sub_areas_do_diario` | `/datatable/sub_areas_diario` |

---

## 6. `Portal\DiarioController`

**Arquivo:** `app/Http/Controllers/Portal/DiarioController.php`

Controlador público para visualização de diários no portal.

| Método | Ação |
|--------|------|
| `index()` | Lista paginada (`orderBy('edicao','DESC')`) |
| `showPDF($id)` | Visualizador PDF com navegação entre edições; se o arquivo não existe, marca `generation_status=pending` e mostra tela de espera |
| `search(Request)` | Busca AJAX por termo (ILIKE em conteúdo, título, edição, autor, lei) |
| `fileInfo($id)` | Informações do PDF (tamanho, páginas) via AJAX |
| `auditoria($id)` | Trilha de auditoria pública (LGPD) via `getPublicAuditTrail` |
| `filtroGET(Request)` | Filtro em banco: datas (`data_inicial`/`data_final`), termo e **edição**; somente `status = true`; `orderBy('edicao','DESC')` |
