File: /home/onlyfibr/public_html/cadastro/admin/configuracoes.php
<?php
// HABILITAR ERROS PARA DEBUG - REMOVER/COMENTAR EM PRODUÇÃO!
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// ---------------------------------------------------------
// 1. Verifica se o admin está logado
require_once 'includes/auth_check.php';
// Define o título desta página ANTES de incluir o header
$pageTitle = 'Configurações';
require_once '../includes/config/config.php'; // Necessário para $pdo e constantes
require_once '../includes/functions/functions.php'; // Pode ser necessário para alguma função auxiliar
// --- Processamento de Mensagens Flash ---
$mensagem_erro = $_SESSION['erro_dashboard'] ?? null;
$mensagem_sucesso = $_SESSION['sucesso_dashboard'] ?? null;
unset($_SESSION['erro_dashboard'], $_SESSION['sucesso_dashboard']);
// Geração de token CSRF
if (!isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$csrf_token = $_SESSION['csrf_token'];
// --- INÍCIO: Ler Configurações Atuais ---
$config_sistema = [
'enviar_api_ativo' => true, // Valor padrão
'timeout_api' => 30, // Valor padrão
'nome_empresa' => 'AdminProv', // Valor padrão
'logo_url' => '', // Valor padrão
'email_contato' => '', // Valor padrão
'mostrar_pendentes_home' => true, // Valor padrão
'tema_dashboard' => 'default', // Valor padrão
'modo_debug' => false, // Valor padrão
'tentativas_api' => 3, // Valor padrão
'exibir_menu_publica' => true, // Valor padrão
];
$config_lida_ok = false;
$erro_busca_db = '';
$warning = '';
if ($pdo) {
try {
// Busca configurações do sistema na tabela configuracoes
$stmt_cfg = $pdo->query("SELECT * FROM configuracoes WHERE id = 1 LIMIT 1");
$config_db = $stmt_cfg->fetch(PDO::FETCH_ASSOC);
if ($config_db !== false) {
// Atualiza as configurações com os valores do banco
$config_sistema['enviar_api_ativo'] = (bool) ($config_db['enviar_dados_api_sgp'] ?? true);
$config_sistema['timeout_api'] = (int) ($config_db['timeout_api'] ?? 30);
$config_sistema['nome_empresa'] = $config_db['nome_empresa'] ?? 'AdminProv';
$config_sistema['logo_url'] = $config_db['logo_url'] ?? '';
$config_sistema['email_contato'] = $config_db['email_contato'] ?? '';
$config_sistema['mostrar_pendentes_home'] = (bool) ($config_db['mostrar_pendentes_home'] ?? true);
$config_sistema['tema_dashboard'] = $config_db['tema_dashboard'] ?? 'default';
$config_sistema['modo_debug'] = (bool) ($config_db['modo_debug'] ?? false);
$config_sistema['tentativas_api'] = (int) ($config_db['tentativas_api'] ?? 3);
$config_sistema['exibir_menu_publica'] = (bool) ($config_db['exibir_menu_publica'] ?? true);
$config_lida_ok = true;
} else {
// Se a configuração não existe, pode criar uma padrão
$warning = "Aviso: Linha de configuração global não encontrada. Valores padrão serão exibidos.";
}
} catch (\PDOException $e) {
$erro_busca_db = "Erro ao ler configurações: " . $e->getMessage();
error_log("Erro busca configurações: " . $e->getMessage());
}
} else {
$erro_busca_db = "Erro crítico: Conexão com banco de dados falhou.";
}
// --- FIM: Ler Configurações Atuais ---
// --- Processamento do Formulário (POST Requests) ---
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['salvar_configuracoes'])) {
// Validação do token CSRF
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
$mensagem_erro = "Erro de segurança: token inválido. Por favor, tente novamente.";
} else {
// 1. Coleta e validação de dados
$novo_enviar_api = isset($_POST['enviar_api_status']) && $_POST['enviar_api_status'] === '1';
$novo_timeout_api = filter_input(INPUT_POST, 'timeout_api', FILTER_VALIDATE_INT, ['options' => ['min_range' => 5, 'max_range' => 120, 'default' => 30]]);
$novo_nome_empresa = trim($_POST['nome_empresa'] ?? '');
$novo_logo_url = filter_input(INPUT_POST, 'logo_url', FILTER_SANITIZE_URL);
$novo_email_contato = filter_input(INPUT_POST, 'email_contato', FILTER_VALIDATE_EMAIL);
$novo_mostrar_pendentes = isset($_POST['mostrar_pendentes_home']) && $_POST['mostrar_pendentes_home'] === '1';
$novo_tema_dashboard = filter_input(INPUT_POST, 'tema_dashboard', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$novo_modo_debug = isset($_POST['modo_debug']) && $_POST['modo_debug'] === '1';
$novo_tentativas_api = filter_input(INPUT_POST, 'tentativas_api', FILTER_VALIDATE_INT, ['options' => ['min_range' => 1, 'max_range' => 10, 'default' => 3]]);
$novo_exibir_menu_publica = isset($_POST['exibir_menu_publica']) && $_POST['exibir_menu_publica'] === '1';
// 2. Validações adicionais
$erros_validacao = [];
if (empty($novo_nome_empresa)) {
$erros_validacao[] = "Nome da empresa não pode ficar em branco.";
}
if (!empty($novo_email_contato) && !filter_var($novo_email_contato, FILTER_VALIDATE_EMAIL)) {
$erros_validacao[] = "Email de contato inválido.";
}
// 3. Se não houver erros de validação
if (empty($erros_validacao) && $pdo) {
try {
// Verifica se a linha de configuração já existe
$stmt_check = $pdo->query("SELECT id FROM configuracoes WHERE id = 1 LIMIT 1");
$config_exists = $stmt_check->fetchColumn();
if ($config_exists) {
// Atualiza configuração existente
$sql = "UPDATE configuracoes SET
enviar_dados_api_sgp = :enviar_api,
timeout_api = :timeout_api,
nome_empresa = :nome_empresa,
logo_url = :logo_url,
email_contato = :email_contato,
mostrar_pendentes_home = :mostrar_pendentes,
tema_dashboard = :tema_dashboard,
modo_debug = :modo_debug,
tentativas_api = :tentativas_api,
exibir_menu_publica = :exibir_menu_publica,
data_atualizacao = NOW()
WHERE id = 1";
} else {
// Insere nova configuração
$sql = "INSERT INTO configuracoes
(id, enviar_dados_api_sgp, timeout_api, nome_empresa, logo_url, email_contato,
mostrar_pendentes_home, tema_dashboard, modo_debug, tentativas_api,
exibir_menu_publica, data_atualizacao)
VALUES
(1, :enviar_api, :timeout_api, :nome_empresa, :logo_url, :email_contato,
:mostrar_pendentes, :tema_dashboard, :modo_debug, :tentativas_api,
:exibir_menu_publica, NOW())";
}
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':enviar_api', $novo_enviar_api, PDO::PARAM_BOOL);
$stmt->bindValue(':timeout_api', $novo_timeout_api, PDO::PARAM_INT);
$stmt->bindValue(':nome_empresa', $novo_nome_empresa, PDO::PARAM_STR);
$stmt->bindValue(':logo_url', $novo_logo_url ?: null, $novo_logo_url ? PDO::PARAM_STR : PDO::PARAM_NULL);
$stmt->bindValue(':email_contato', $novo_email_contato ?: null, $novo_email_contato ? PDO::PARAM_STR : PDO::PARAM_NULL);
$stmt->bindValue(':mostrar_pendentes', $novo_mostrar_pendentes, PDO::PARAM_BOOL);
$stmt->bindValue(':tema_dashboard', $novo_tema_dashboard, PDO::PARAM_STR);
$stmt->bindValue(':modo_debug', $novo_modo_debug, PDO::PARAM_BOOL);
$stmt->bindValue(':tentativas_api', $novo_tentativas_api, PDO::PARAM_INT);
$stmt->bindValue(':exibir_menu_publica', $novo_exibir_menu_publica, PDO::PARAM_BOOL);
if ($stmt->execute()) {
$_SESSION['sucesso_dashboard'] = "Configurações atualizadas com sucesso!";
// Atualiza os valores na sessão atual
$config_sistema['enviar_api_ativo'] = $novo_enviar_api;
$config_sistema['timeout_api'] = $novo_timeout_api;
$config_sistema['nome_empresa'] = $novo_nome_empresa;
$config_sistema['logo_url'] = $novo_logo_url;
$config_sistema['email_contato'] = $novo_email_contato;
$config_sistema['mostrar_pendentes_home'] = $novo_mostrar_pendentes;
$config_sistema['tema_dashboard'] = $novo_tema_dashboard;
$config_sistema['modo_debug'] = $novo_modo_debug;
$config_sistema['tentativas_api'] = $novo_tentativas_api;
$config_sistema['exibir_menu_publica'] = $novo_exibir_menu_publica;
// Redireciona para evitar reenvio do formulário
header("Location: " . htmlspecialchars($_SERVER['PHP_SELF']));
exit;
} else {
$mensagem_erro = "Erro ao executar atualização das configurações.";
}
} catch (\PDOException $e) {
error_log("Erro DB ao salvar configurações: " . $e->getMessage());
$mensagem_erro = "Erro ao salvar configurações no banco de dados. Código: " . $e->getCode();
}
} else if (!empty($erros_validacao)) {
$mensagem_erro = implode("<br>", $erros_validacao);
}
}
}
// Lista de temas disponíveis
$temas_disponiveis = [
'default' => 'Padrão (Azul escuro)',
'light' => 'Claro',
'dark' => 'Escuro',
'colorful' => 'Colorido',
'minimal' => 'Minimalista'
];
// Obter os menus dinamicamente do banco de dados
$menus = carregarMenus($pdo, $usuario_permissoes ?? ['admin']);
// Incluir o header
include_once 'includes/header.php';
?>
<div class="container">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h1>Configurações do Sistema</h1>
<p class="text-muted">Personalize as opções do sistema de acordo com suas necessidades</p>
</div>
<div>
<a href="index.php" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Voltar para Dashboard
</a>
</div>
</div>
<?php if ($erro_busca_db): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<?php echo htmlspecialchars($erro_busca_db); ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if ($mensagem_erro): ?>
<div class="alert alert-danger alert-dismissible fade show" role="alert">
<?php echo $mensagem_erro; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if ($mensagem_sucesso): ?>
<div class="alert alert-success alert-dismissible fade show" role="alert">
<?php echo $mensagem_sucesso; ?>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
<?php endif; ?>
<?php if (!$config_lida_ok && !empty($warning)): ?>
<div class="alert alert-warning">
<?php echo $warning; ?>
</div>
<?php endif; ?>
<!-- Formulário de Configurações -->
<div class="card">
<div class="card-header bg-primary text-white">
<h5 class="mb-0"><i class="fas fa-cogs me-2"></i>Configurações Gerais</h5>
</div>
<div class="card-body">
<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" class="needs-validation" novalidate>
<input type="hidden" name="salvar_configuracoes" value="1">
<input type="hidden" name="csrf_token" value="<?php echo $csrf_token; ?>">
<div class="row mb-4">
<div class="col-lg-6">
<h5 class="border-bottom pb-2">Configurações da Empresa</h5>
<div class="mb-3">
<label for="nome_empresa" class="form-label">Nome da Empresa</label>
<input type="text" class="form-control" id="nome_empresa" name="nome_empresa"
value="<?php echo htmlspecialchars($config_sistema['nome_empresa']); ?>" required>
<div class="invalid-feedback">
Por favor, informe o nome da empresa.
</div>
</div>
<div class="mb-3">
<label for="logo_url" class="form-label">URL da Logo</label>
<input type="url" class="form-control" id="logo_url" name="logo_url"
value="<?php echo htmlspecialchars($config_sistema['logo_url']); ?>"
placeholder="https://exemplo.com/logo.png">
<div class="form-text">Deixe em branco para usar a logo padrão.</div>
</div>
<div class="mb-3">
<label for="email_contato" class="form-label">E-mail de Contato</label>
<input type="email" class="form-control" id="email_contato" name="email_contato"
value="<?php echo htmlspecialchars($config_sistema['email_contato']); ?>"
placeholder="contato@empresa.com">
</div>
</div>
<div class="col-lg-6">
<h5 class="border-bottom pb-2">Aparência</h5>
<div class="mb-3">
<label for="tema_dashboard" class="form-label">Tema do Dashboard</label>
<select class="form-select" id="tema_dashboard" name="tema_dashboard">
<?php foreach ($temas_disponiveis as $value => $label): ?>
<option value="<?php echo htmlspecialchars($value); ?>"
<?php echo ($config_sistema['tema_dashboard'] === $value) ? 'selected' : ''; ?>>
<?php echo htmlspecialchars($label); ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="mb-3 form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch"
id="mostrar_pendentes_home" name="mostrar_pendentes_home" value="1"
<?php echo $config_sistema['mostrar_pendentes_home'] ? 'checked' : ''; ?>>
<label class="form-check-label" for="mostrar_pendentes_home">
Mostrar Pendentes na Página Inicial
</label>
</div>
<div class="mb-3 form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch"
id="exibir_menu_publica" name="exibir_menu_publica" value="1"
<?php echo $config_sistema['exibir_menu_publica'] ? 'checked' : ''; ?>>
<label class="form-check-label" for="exibir_menu_publica">
Exibir Menu na Área Pública
</label>
</div>
</div>
</div>
<div class="row mb-4">
<div class="col-lg-6">
<h5 class="border-bottom pb-2">Configurações da API</h5>
<div class="mb-3 form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch"
id="enviar_api_status" name="enviar_api_status" value="1"
<?php echo $config_sistema['enviar_api_ativo'] ? 'checked' : ''; ?>>
<label class="form-check-label" for="enviar_api_status">
Enviar dados para API SGP
</label>
<div id="enviarApiHelp" class="form-text">
Se desativado, os dados serão salvos localmente e precisarão ser processados manualmente depois.
</div>
</div>
<div class="mb-3">
<label for="timeout_api" class="form-label">Timeout da API (segundos)</label>
<input type="number" class="form-control" id="timeout_api" name="timeout_api"
value="<?php echo htmlspecialchars($config_sistema['timeout_api']); ?>"
min="5" max="120" required>
</div>
<div class="mb-3">
<label for="tentativas_api" class="form-label">Número de Tentativas</label>
<input type="number" class="form-control" id="tentativas_api" name="tentativas_api"
value="<?php echo htmlspecialchars($config_sistema['tentativas_api']); ?>"
min="1" max="10" required>
<div class="form-text">
Número de vezes que o sistema tentará enviar para a API antes de desistir.
</div>
</div>
</div>
<div class="col-lg-6">
<h5 class="border-bottom pb-2">Configurações Avançadas</h5>
<div class="mb-3 form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch"
id="modo_debug" name="modo_debug" value="1"
<?php echo $config_sistema['modo_debug'] ? 'checked' : ''; ?>>
<label class="form-check-label" for="modo_debug">
Modo Debug
</label>
<div id="modoDebugHelp" class="form-text text-warning">
Atenção: Ative apenas em ambiente de desenvolvimento ou para solução de problemas.
</div>
</div>
<div class="mt-4 p-3 bg-light rounded">
<h6><i class="fas fa-info-circle me-2"></i>Informações do Sistema</h6>
<div class="row">
<div class="col-md-6">
<p class="mb-1"><strong>Versão do PHP:</strong> <?php echo phpversion(); ?></p>
<p class="mb-1"><strong>Servidor:</strong> <?php echo $_SERVER['SERVER_SOFTWARE'] ?? 'Desconhecido'; ?></p>
</div>
<div class="col-md-6">
<p class="mb-1"><strong>Versão do Sistema:</strong> 2.0</p>
<p class="mb-1"><strong>Última Atualização:</strong> <?php echo date('d/m/Y'); ?></p>
</div>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-end border-top pt-3">
<button type="reset" class="btn btn-outline-secondary me-2">
<i class="fas fa-undo me-2"></i>Restaurar Padrões
</button>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-2"></i>Salvar Configurações
</button>
</div>
</form>
</div>
</div>
<!-- Seção de Backup e Restauração -->
<div class="card mt-4">
<div class="card-header bg-secondary text-white">
<h5 class="mb-0"><i class="fas fa-database me-2"></i>Backup e Restauração</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6>Fazer Backup do Sistema</h6>
<p>Crie um backup completo do banco de dados para restauração futura.</p>
<button type="button" class="btn btn-outline-primary" id="btnGerarBackup">
<i class="fas fa-download me-2"></i>Gerar Backup
</button>
</div>
<div class="col-md-6">
<h6>Restaurar Backup</h6>
<p>Restaure o sistema a partir de um arquivo de backup anterior.</p>
<form id="formRestaurarBackup" class="d-flex align-items-center">
<input type="file" class="form-control me-2" id="arquivoBackup" accept=".sql,.zip">
<button type="button" class="btn btn-outline-warning" id="btnRestaurarBackup" disabled>
<i class="fas fa-upload me-2"></i>Restaurar
</button>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
// Validação do formulário
(function() {
'use strict';
// Fetch all forms we want to apply validation to
var forms = document.querySelectorAll('.needs-validation');
// Loop e previne submissão se houver campos inválidos
Array.prototype.slice.call(forms).forEach(function(form) {
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
})();
// Habilitar/desabilitar botão de restauração quando arquivo for selecionado
document.getElementById('arquivoBackup').addEventListener('change', function() {
document.getElementById('btnRestaurarBackup').disabled = !this.files.length;
});
// Simulação de backup/restauração (apenas alerta)
document.getElementById('btnGerarBackup').addEventListener('click', function() {
alert('Esta função geraria um backup do banco de dados.\nPara implementação real, você precisaria executar um script de backup no servidor.');
});
document.getElementById('btnRestaurarBackup').addEventListener('click', function() {
if (confirm('ATENÇÃO: Restaurar um backup irá sobrescrever todos os dados atuais.\nTem certeza que deseja continuar?')) {
alert('Esta função restauraria o backup no servidor.\nPara implementação real, você precisaria executar um script de restauração.');
}
});
</script>
<?php
// Incluir o footer
include_once 'includes/footer.php';
?>