# 📁 Regra de Armazenamento de Arquivos e Uploads (51_UPLOADS_STORAGE.md) ## ❗ Regra Fundamental **Nenhum módulo do SysCMS deve gravar arquivos diretamente no diretório `public/`.** Todos os uploads, arquivos gerados pelo sistema ou mídias de usuários devem ser obrigatoriamente armazenados no diretório `storage/uploads/{nome-do-modulo}/`. --- ## 🏗️ Estrutura de Armazenamento (Padrão Único e Definitivo) - **Localização Física**: `storage/uploads/{nome-do-modulo}/` - **URL de Acesso**: `url('storage/uploads/{nome-do-modulo}/' ~ nome_arquivo)` - **Funciona em**: Windows e Linux (Docker) - **OBRIGATÓRIO**: Subpastas por módulo (ex: `storage/uploads/erpcarriers/`, `storage/uploads/blog/`) - **PROIBIDO**: Uso de Links Simbólicos (Symlinks), Junctions ou Atalhos. - **Este padrão é definitivo e imutável** - NUNCA deve ser alterado --- ## 🌐 Acesso via Web Os arquivos em `storage/uploads/{nome-do-modulo}/` são acessíveis via rota do sistema. ### Geração de URLs Para acessar um arquivo via navegador, utilize o helper `url()` apontando para `storage/uploads/{nome-do-modulo}/`: - **Correto**: `url('storage/uploads/blog/imagem.jpg')` - **Incorreto**: `url('public/uploads/imagem.jpg')` - **Incorreto**: `url('storage/imagem.jpg')` (sem módulo) --- ## 🛠️ Implementação no Código (PHP) ### 1. Definindo o Diretório de Upload Sempre utilize caminhos absolutos baseados na raiz do projeto e inclua o nome do módulo: ```php $moduleName = 'erpcarriers'; // Exemplo $uploadDir = dirname(__DIR__, 4) . '/storage/uploads/' . $moduleName . '/'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0755, true); } ``` ### 2. Salvando o Caminho no Banco de Dados Grave apenas o nome do arquivo: - **BD**: `imagem.jpg` - **NÃO**: `blog/imagem.jpg` (redundante se a pasta for padrão) ### 3. Exibindo no Frontend (Twig) ```twig ... ``` --- ## 🛡️ Segurança e Manutenção 1. **Proteção de Diretório**: O diretório `storage/` contém um arquivo `.htaccess` que impede a execução de scripts PHP, garantindo que arquivos maliciosos enviados por upload não sejam executados. 2. **Limpeza**: Ao remover um registro que possui arquivos associados, o arquivo físico deve ser removido utilizando `unlink()`. 3. **Nomes de Arquivos**: Use nomes únicos (ex: `TRA` + random_bytes + timestamp + extensão) para evitar conflitos. --- ## ⚠️ Importante Este padrão está definido como definitivo e imutável no [DECISIONS.md](../../DECISIONS.md). Em caso de dúvida, consulte sempre o DECISIONS.md antes de implementar funcionalidades de upload.