<?php
// modules/log-izleme.php
session_start();
require_once '../config/db.php';
require_once '../config/functions.php';
// Sadece ROOT yetkisine sahip kişi görebilir.
// Güvenlik gereği diğer yöneticilere kapalıdır.
yetkiKontrol(['root']);
include '../includes/header.php';
include '../includes/menu.php';
// --- FİLTRELEME PARAMETRELERİ ---
$where = "WHERE 1=1";
$params = [];
// 1. İşlem Tipi Filtresi
if (!empty($_GET['islem_tipi'])) {
$where .= " AND l.islem_tipi = :tip";
$params[':tip'] = guvenlik($_GET['islem_tipi']); // XSS koruması eklendi
}
// 2. Kullanıcı Filtresi
if (!empty($_GET['kullanici_adi'])) {
$where .= " AND k.kullanici_adi LIKE :kadi";
$params[':kadi'] = '%' . guvenlik($_GET['kullanici_adi']) . '%'; // XSS koruması eklendi
}
// 3. Tarih Aralığı
if (!empty($_GET['baslangic']) && !empty($_GET['bitis'])) {
$where .= " AND l.tarih BETWEEN :bas AND :bit";
$params[':bas'] = guvenlik($_GET['baslangic']) . " 00:00:00"; // XSS koruması eklendi
$params[':bit'] = guvenlik($_GET['bitis']) . " 23:59:59"; // XSS koruması eklendi
}
// --- SAYFALAMA MANTIĞI ---
$sayfa = isset($_GET['sayfa']) ? (int)$_GET['sayfa'] : 1;
$limit = 50; // Sayfa başı kayıt sayısı
$offset = ($sayfa - 1) * $limit;
// Toplam kayıt sayısını bul
$sql_count = "SELECT COUNT(*) FROM sistem_loglari l LEFT JOIN kullanicilar k ON l.kullanici_id = k.id $where";
$stmt_count = $pdo->prepare($sql_count);
$stmt_count->execute($params);
$toplam_kayit = $stmt_count->fetchColumn();
$toplam_sayfa = ceil($toplam_kayit / $limit);
// Verileri Çek
$sql = "SELECT l.*, k.kullanici_adi, k.ad, k.soyad
FROM sistem_loglari l
LEFT JOIN kullanicilar k ON l.kullanici_id = k.id
$where
ORDER BY l.id DESC
LIMIT $limit OFFSET $offset";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$loglar = $stmt->fetchAll();
?>
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-3">
<h3><i class="fas fa-shield-alt text-danger"></i> Sistem Güvenlik Logları</h3>
<span class="badge bg-secondary">Toplam Kayıt: <?php echo $toplam_kayit; ?></span>
</div>
<div class="card-box p-3 mb-4 bg-light border">
<form method="GET" class="row g-3">
<div class="col-md-2">
<label class="form-label small fw-bold">İşlem Tipi</label>
<select name="islem_tipi" class="form-select form-select-sm">
<option value="">Tümü</option>
<option value="giris" <?php echo ($_GET['islem_tipi'] ?? '') == 'giris' ? 'selected' : ''; ?>>Giriş</option>
<option value="guvenlik_uyarisi" <?php echo ($_GET['islem_tipi'] ?? '') == 'guvenlik_uyarisi' ? 'selected' : ''; ?>>Güvenlik Uyarısı</option>
<option value="ekleme" <?php echo ($_GET['islem_tipi'] ?? '') == 'ekleme' ? 'selected' : ''; ?>>Ekleme</option>
<option value="guncelleme" <?php echo ($_GET['islem_tipi'] ?? '') == 'guncelleme' ? 'selected' : ''; ?>>Güncelleme</option>
<option value="silme" <?php echo ($_GET['islem_tipi'] ?? '') == 'silme' ? 'selected' : ''; ?>>Silme</option>
<option value="onay" <?php echo ($_GET['islem_tipi'] ?? '') == 'onay' ? 'selected' : ''; ?>>Onay</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label small fw-bold">Kullanıcı Adı</label>
<input type="text" name="kullanici_adi" class="form-control form-control-sm" placeholder="Ara..." value="<?php echo guvenlik($_GET['kullanici_adi'] ?? ''); ?>">
</div>
<div class="col-md-3">
<label class="form-label small fw-bold">Başlangıç</label>
<input type="date" name="baslangic" class="form-control form-control-sm" value="<?php echo guvenlik($_GET['baslangic'] ?? ''); ?>">
</div>
<div class="col-md-3">
<label class="form-label small fw-bold">Bitiş</label>
<input type="date" name="bitis" class="form-control form-control-sm" value="<?php echo guvenlik($_GET['bitis'] ?? ''); ?>">
</div>
<div class="col-md-2 d-flex align-items-end">
<button type="submit" class="btn btn-primary btn-sm w-100 me-2"><i class="fas fa-filter"></i> Filtrele</button>
<a href="log-izleme.php" class="btn btn-secondary btn-sm"><i class="fas fa-sync"></i></a>
</div>
</form>
</div>
<div class="card-box p-0 overflow-hidden">
<div class="table-responsive">
<table class="table table-hover table-striped mb-0 table-sm" style="font-size: 0.9rem;">
<thead class="table-dark">
<tr>
<th width="50">#ID</th>
<th>Zaman</th>
<th>Kullanıcı</th>
<th>İşlem Tipi</th>
<th>Açıklama</th>
<th>IP / Cihaz</th>
<th width="50">Detay</th>
</tr>
</thead>
<tbody>
<?php foreach ($loglar as $log):
// İşlem tipine göre renk belirleme
$badge_color = 'secondary';
if($log['islem_tipi'] == 'guvenlik_uyarisi') $badge_color = 'danger';
elseif($log['islem_tipi'] == 'giris') $badge_color = 'success';
elseif($log['islem_tipi'] == 'guncelleme') $badge_color = 'warning text-dark';
elseif($log['islem_tipi'] == 'silme') $badge_color = 'danger';
elseif($log['islem_tipi'] == 'onay') $badge_color = 'info text-dark';
?>
<tr>
<td><?php echo $log['id']; ?></td>
<td><?php echo date('d.m.Y H:i:s', strtotime($log['tarih'])); ?></td>
<td>
<?php if($log['kullanici_id'] == 0): ?>
<span class="text-danger fw-bold">SİSTEM / BİLİNMEYEN</span>
<?php else: ?>
<strong><?php echo guvenlik($log['kullanici_adi']); ?></strong><br>
<small class="text-muted"><?php echo guvenlik($log['ad']) . ' ' . guvenlik($log['soyad']); ?></small>
<?php endif; ?>
</td>
<td><span class="badge bg-<?php echo $badge_color; ?>"><?php echo strtoupper(guvenlik($log['islem_tipi'])); ?></span></td>
<td><?php echo guvenlik($log['aciklama']); ?></td>
<td>
<small class="d-block"><?php echo guvenlik($log['ip_adresi']); ?></small>
<small class="text-muted" style="font-size: 0.7rem;" title="<?php echo guvenlik($log['cihaz_bilgisi']); ?>">
<?php
// User Agent'ı kısalt
$ua = $log['cihaz_bilgisi'];
if(strpos($ua, 'Windows')) echo 'Windows PC';
elseif(strpos($ua, 'Android')) echo 'Android';
elseif(strpos($ua, 'iPhone')) echo 'iPhone';
else echo 'Diğer';
?>
</small>
</td>
<td>
<?php if(!empty($log['eski_veri']) || !empty($log['yeni_veri'])): ?>
<button type="button" class="btn btn-sm btn-outline-dark detay-btn"
data-bs-toggle="modal" data-bs-target="#logDetayModal"
data-eski='<?php echo guvenlik($log['eski_veri']); ?>'
data-yeni='<?php echo guvenlik($log['yeni_veri']); ?>'>
<i class="fas fa-eye"></i>
</button>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php if(empty($loglar)): ?>
<tr><td colspan="7" class="text-center p-4">Kriterlere uygun kayıt bulunamadı.</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php if($toplam_sayfa > 1): ?>
<div class="p-3 border-top">
<nav>
<ul class="pagination justify-content-center mb-0">
<li class="page-item <?php echo ($sayfa <= 1) ? 'disabled' : ''; ?>">
<a class="page-link" href="?sayfa=<?php echo $sayfa-1; ?>&islem_tipi=<?php echo $_GET['islem_tipi'] ?? ''; ?>">« Önceki</a>
</li>
<?php for($s=1; $s<=$toplam_sayfa; $s++):
// Çok fazla sayfa varsa hepsini gösterme (Basit mantık)
if ($s == 1 || $s == $toplam_sayfa || ($s >= $sayfa-2 && $s <= $sayfa+2)):
?>
<li class="page-item <?php echo ($sayfa == $s) ? 'active' : ''; ?>">
<a class="page-link" href="?sayfa=<?php echo $s; ?>&islem_tipi=<?php echo $_GET['islem_tipi'] ?? ''; ?>"><?php echo $s; ?></a>
</li>
<?php elseif($s == $sayfa-3 || $s == $sayfa+3): ?>
<li class="page-item disabled"><a class="page-link">...</a></li>
<?php endif; endfor; ?>
<li class="page-item <?php echo ($sayfa >= $toplam_sayfa) ? 'disabled' : ''; ?>">
<a class="page-link" href="?sayfa=<?php echo $sayfa+1; ?>&islem_tipi=<?php echo $_GET['islem_tipi'] ?? ''; ?>">Sonraki »</a>
</li>
</ul>
</nav>
</div>
<?php endif; ?>
</div>
</div>
<div class="modal fade" id="logDetayModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Değişiklik Detayları</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-6 border-end">
<h6 class="text-danger border-bottom pb-2">Eski Veri</h6>
<pre id="eskiVeriIcerik" class="bg-light p-2 small text-muted" style="white-space: pre-wrap;"></pre>
</div>
<div class="col-md-6">
<h6 class="text-success border-bottom pb-2">Yeni Veri</h6>
<pre id="yeniVeriIcerik" class="bg-light p-2 small text-muted" style="white-space: pre-wrap;"></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
// Modal açıldığında verileri içine doldur
document.addEventListener('DOMContentLoaded', function() {
const detayBtns = document.querySelectorAll('.detay-btn');
const eskiDiv = document.getElementById('eskiVeriIcerik');
const yeniDiv = document.getElementById('yeniVeriIcerik');
detayBtns.forEach(btn => {
btn.addEventListener('click', function() {
// PHP'den gelen JSON string verilerini al
let eski = this.getAttribute('data-eski');
let yeni = this.getAttribute('data-yeni');
// JSON'ı güzel formatla (Pretty Print)
try {
if(eski) eski = JSON.stringify(JSON.parse(eski), null, 2);
if(yeni) yeni = JSON.stringify(JSON.parse(yeni), null, 2);
} catch(e) {
// JSON bozuksa olduğu gibi bas
}
eskiDiv.textContent = eski || "Veri yok.";
yeniDiv.textContent = yeni || "Veri yok.";
});
});
});
</script>
<?php include '../includes/footer.php'; ?>