# Redes Sociais — Rotas e Controladores

## 1. Rotas públicas (portal)

**Não existe rota pública para redes sociais.** A busca em `v6/routes/web.php` não retorna nenhuma
ocorrência de `rede-social` ou `redes-sociais`. O módulo aparece apenas dentro do cabeçalho e do
rodapé das demais páginas do portal, o que significa:

- não há página `/redes-sociais`;
- não há breadcrumb para redes sociais;
- não há entrada na API `v1` (`v6/routes/api.php`) para redes sociais.

## 2. Rotas do CMS (`/cms`)

| Método | URI | Nome | Controller@ação | Observação |
|---|---|---|---|---|
| get | `/cms/conteudos/{slug}` | `listar-conteudo` | `Prefecture\ContentController@genericIndex` | `slug = rede-social` -> listagem |
| get | `/cms/conteudos/cadastrar/{slug}` | `cadastrar-conteudo` | `Prefecture\ContentController@genericCreate` | formulário de criação |
| get | `/cms/conteudos/editar/{slug}/{id}` | `editar-conteudo` | `Prefecture\ContentController@genericEdit` | formulário de edição |
| resource | `/cms/conteudo` | `conteudo.*` | `Prefecture\ContentController` | `store`, `update`, `destroy` |
| post | `/cms/conteudo/deleteAll` | `ajax.generic.content.deleteAll` | `Prefecture\ContentController@genericDeleteAll` | exclusão em lote |
| get | `/cms/datatable/redes_sociais` | `redes_sociais` | `Prefecture\DatatableController@get_redes_sociais` | fonte da tabela |
| post | `/cms/ajust-banners` | `ajust.banners` | `Prefecture\ContentController@ajustOrder` | reordenação por drag-and-drop |
| post | `/cms/set-status` | `set.status` | `Prefecture\ContentController@setStatus` | alterna ativo/inativo |

Trechos reais (`v6/routes/basepro.php`):

```php
Route::post('ajust-banners', 'Prefecture\ContentController@ajustOrder')->name('ajust.banners');
Route::post('set-status', 'Prefecture\ContentController@setStatus')->name('set.status');
```

```php
Route::get('/redes_sociais', 'Prefecture\DatatableController@get_redes_sociais')->name('redes_sociais');
```

> A rota `set-status` fica no grupo de AJAX (`v6/routes/basepro.php:347`) e recebe `contents_id`.
> A rota `ajust.banners` é genérica: o nome é herdado de banners, mas é usada também por redes
> sociais (e por outros módulos com ordenação).

## 3. Controladores

### 3.1 `Prefecture\ContentController`

Arquivo: `v6/app/Http/Controllers/Prefecture/ContentController.php`

| Método | Linha | Comportamento no módulo |
|---|---|---|
| `genericIndex($slug)` | 91-119 | `rede-social` -> `returnIndex('Redes Sociais', $slug)` (linha 102) |
| `genericGenerate($slug,$id)` | 163-239 | `rede-social` -> `returnData('Redes Sociais', $slug, 'rede', [], $id)` (linha 173) |
| `returnData($title,$slug,$self,$extra,$id)` | 275-312 | injeta `position` (linhas 305-308) e a coleção `rede` (linha 301) |
| `store(ContentRequest)` | 616 | grava `contents`; cria o registro em `links` quando há `link` (linhas 717-733) |
| `update(ContentRequest,$id)` | 937 | atualiza `contents` e sincroniza o `links` (linhas 1067-1110) |
| `ajustOrder(Request)` | — | reordena os itens conforme a lista enviada pelo sortable |
| `setStatus(Request)` | 1548 | alterna `contents.status` |

Trecho real do `store` para o link (`v6/app/Http/Controllers/Prefecture/ContentController.php:717-733`):

```php
$blank = $request->has('isBlank') ? 1 : 0;
if (isset($request->link) && !empty($request->link)) {
    $videoLink = $this->sanitizeLink(normalizeVideoLink($request->get('link')));

    $linksCreate = [
        'contents_id' => $content->id,
        'name' => $request->get('title'),
        'title' => $request->get('title'),
        'link' => $videoLink,
        'alt' => $request->get('title'),
        'isBlank' => $blank
    ];
    $links = Link::create($linksCreate); //INSERE LINK UNICO. EX: YOUTUBE
```

### 3.2 `Prefecture\DatatableController@get_redes_sociais`

Arquivo: `v6/app/Http/Controllers/Prefecture/DatatableController.php:240-244`

```php
public function get_redes_sociais()
{
    $rede_social = DB::table("rede_social")->get();
    return DataTables::of($this->struct_views($rede_social, 'rede-social'))->make(true);
}
```

## 4. Form Request e validação

`v6/app/Http/Requests/ContentRequest.php:182-191`:

```php
case 'rede-social':
    $rules = [
        "title" => "required|max:120",
        "category_contents_id" => "required|numeric",
        "icon" => "required",
        "link" => "required|max:2999",
        "order" => "required"
    ];

    break;
```

| Campo | Regra | Observação |
|---|---|---|
| `title` | `required|max:120` | nome da rede |
| `category_contents_id` | `required|numeric` | hidden no formulário |
| `icon` | `required` | classe CSS do ícone |
| `link` | `required|max:2999` | gravada na tabela `links` |
| `order` | `required` | numérico (o input usa `tipo => number`) |

Campos **sem** regra: `status` e `isBlank`. O `status` é tratado como booleano no `update`
(`$dataForm['status'] = isset($dataForm['status'])`) e no `store` vem como `$request->get('status')`;
`isBlank` vira `1`/`0` via `$request->has('isBlank')`.

## 5. API Resources e presenters

- Não há API Resource para redes sociais.
- O presenter `ContentPresenter::socialNetworkLink()` (linha 140) normaliza o URL:

```php
public function socialNetworkLink()
{
    if (substr($this->linksUnique->link, 0, 4) != "http") {
        return "http://{$this->linksUnique->link}";
    }

    return $this->linksUnique->link;
}
```

- As views do cabeçalho/rodapé **não** usam o presenter: replicam a mesma lógica inline
  (`if (substr($rede->linksUnique->link, 0, 4) != 'http') { $http = 'http://'; }`).

## 6. Permissões exigidas

| Permissão (seed) | Uso real no código |
|---|---|
| `redes-sociais.create` | o seed a define, mas a view verifica `has_access(['rede-social.create'])` |
| `redes-sociais.edit` | `struct_views($data, 'rede-social')` avalia `rede-social.edit` |
| `redes-sociais.delete` | idem (`rede-social.delete`) |
| `redes-sociais.restore` / `redes-sociais.inactivate` | colunas `active`/`inactivate` do DataTable |

Divergência real entre o slug das permissões (`redes-sociais.*`) e o slug avaliado no código
(`rede-social.*`). Ver `08-GAPS-E-DIVIDAS.md`.

O botão “Informações da Instituição” da listagem aponta para `/cms/configuracoes/editar/configuracoes`
e não exige permissão específica; as demais ações usam o middleware `check.route.permission`
aplicado no construtor de `ContentController` e o `check.logged` do grupo `/cms`.
