<?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.
yetkiKontrol(['root']);
// --- YARDIMCI FONKSİYON: ETKİLENEN PERSONELİ BUL ---
function etkilenenPersonelBul($pdo, $tablo, $id) {
if (!$id || !$tablo) return null;
try {
$sql = "";
if ($tablo == 'kullanicilar') {
$sql = "SELECT id, ad, soyad FROM kullanicilar WHERE id = ?";
} elseif ($tablo == 'calisma_donemleri') {
$sql = "SELECT k.id, k.ad, k.soyad FROM calisma_donemleri d JOIN kullanicilar k ON d.calisan_id = k.id WHERE d.id = ?";
} elseif (in_array($tablo, ['izin_talepleri', 'mesai_hareketleri', 'avans_hareketleri', 'maas_gecmisi'])) {
$sql = "SELECT k.id, k.ad, k.soyad FROM $tablo t JOIN kullanicilar k ON t.calisan_id = k.id WHERE t.id = ?";
}
if ($sql) {
$stmt = $pdo->prepare($sql);
$stmt->execute([$id]);
$res = $stmt->fetch(PDO::FETCH_ASSOC);
if ($res) {
return "<span class='text-primary fw-bold'><i class='fas fa-user-tag'></i> {$res['ad']} {$res['soyad']} (ID: {$res['id']})</span>";
}
}
return "<span class='text-muted fst-italic'>(Kayıt silinmiş veya bulunamadı)</span>";
} catch (Exception $e) {
return "<span class='text-danger'>Hata</span>";
}
}
// --- FİLTRELEME PARAMETRELERİ ---
$where = "WHERE 1=1";
$params = [];
if (!empty($_GET['islem_tipi'])) {
$where .= " AND l.islem_tipi = :tip";
$params[':tip'] = $_GET['islem_tipi'];
}
if (!empty($_GET['tablo_adi'])) {
$where .= " AND l.tablo_adi = :tbl";
$params[':tbl'] = $_GET['tablo_adi'];
}
if (!empty($_GET['kullanici_adi'])) {
$where .= " AND k.kullanici_adi LIKE :kadi";
$params[':kadi'] = '%' . $_GET['kullanici_adi'] . '%';
}
if (!empty($_GET['baslangic'])) {
$where .= " AND l.tarih >= :bas";
$params[':bas'] = $_GET['baslangic'] . " 00:00:00";
}
if (!empty($_GET['bitis'])) {
$where .= " AND l.tarih <= :bit";
$params[':bit'] = $_GET['bitis'] . " 23:59:59";
}
// --- EXCEL ÇIKTISI ---
if (isset($_GET['format']) && $_GET['format'] == 'excel') {
$filename = "Sistem_Loglari_" . date('Y-m-d_H-i') . ".xls";
header("Content-Type: application/vnd.ms-excel; charset=utf-8");
header("Content-Disposition: attachment; filename=$filename");
echo "\xEF\xBB\xBF";
$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";
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$tum_loglar = $stmt->fetchAll();
?>
<table border="1">
<thead>
<tr style="background-color:#ccc;">
<th>Log ID</th><th>Tarih</th><th>İşlemi Yapan</th><th>İşlem Tipi</th><th>Modül/Tablo</th><th>Açıklama & Etkilenen Personel</th><th>IP Adresi</th>
</tr>
</thead>
<tbody>
<?php foreach($tum_loglar as $log):
$etkilenen = strip_tags(etkilenenPersonelBul($pdo, $log['tablo_adi'], $log['kayit_id']));
?>
<tr>
<td><?php echo $log['id']; ?></td>
<td><?php echo $log['tarih']; ?></td>
<td><?php echo $log['kullanici_adi'] . ' (' . $log['ad'] . ' ' . $log['soyad'] . ')'; ?></td>
<td><?php echo $log['islem_tipi']; ?></td>
<td><?php echo $log['tablo_adi']; ?></td>
<td><?php echo $log['aciklama'] . " - " . $etkilenen; ?></td>
<td><?php echo $log['ip_adresi']; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php
exit;
}
include '../includes/header.php';
include '../includes/menu.php';
// --- SAYFALAMA ---
$sayfa = isset($_GET['sayfa']) ? (int)$_GET['sayfa'] : 1;
$limit = 50;
$offset = ($sayfa - 1) * $limit;
// Toplam Sayı
$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();
// URL Oluşturucu
function urlOlustur($sayfa_no) {
$q = $_GET;
$q['sayfa'] = $sayfa_no;
return '?' . http_build_query($q);
}
?>
<style>
@media print {
body * { visibility: hidden; }
#printableArea, #printableArea * { visibility: visible; }
#printableArea { position: absolute; left: 0; top: 0; width: 100%; }
.no-print { display: none !important; }
.card-box { border: none !important; box-shadow: none !important; }
.table { font-size: 10px !important; }
.badge { border: 1px solid #000; color: #000 !important; background: none !important; }
}
.json-pre { max-height: 300px; overflow-y: auto; font-size: 0.75rem; background-color: #2d2d2d; color: #f8f8f2; padding: 10px; border-radius: 5px; }
.badge-info { background-color: #17a2b8; }
.badge-danger { background-color: #dc3545; }
.badge-success { background-color: #28a745; }
.badge-warning { background-color: #ffc107; }
.badge-primary { background-color: #007bff; }
.badge-secondary { background-color: #6c757d; }
</style>
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3><i class="fas fa-history text-primary"></i> Sistem Log İzleme</h3>
<div class="d-flex gap-2 no-print">
<a href="?format=excel" class="btn btn-sm btn-success"><i class="fas fa-file-excel"></i> Excel</a>
</div>
</div>
<div class="card shadow-sm border-0">
<div class="card-body">
<!-- FİLTRE FORMU -->
<form method="GET" id="filterForm" class="row g-2 mb-4">
<div class="col-md-2">
<label class="form-label small">İşlem Tipi</label>
<select name="islem_tipi" class="form-select form-select-sm">
<option value="">Tümü</option>
<option value="ekleme" <?= ($_GET['islem_tipi']??'') == 'ekleme' ? 'selected' : '' ?>>Ekleme</option>
<option value="guncelleme" <?= ($_GET['islem_tipi']??'') == 'guncelleme' ? 'selected' : '' ?>>Güncelleme</option>
<option value="silme" <?= ($_GET['islem_tipi']??'') == 'silme' ? 'selected' : '' ?>>Silme</option>
<option value="işe_alim" <?= ($_GET['islem_tipi']??'') == 'işe_alim' ? 'selected' : '' ?>>İşe Alım</option>
<option value="isten_cikarma" <?= ($_GET['islem_tipi']??'') == 'isten_cikarma' ? 'selected' : '' ?>>İşten Çıkarma</option>
<option value="maas_guncelleme" <?= ($_GET['islem_tipi']??'') == 'maas_guncelleme' ? 'selected' : '' ?>>Maaş Güncelleme</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label small">Modül/Tablo</label>
<select name="tablo_adi" class="form-select form-select-sm">
<option value="">Tümü</option>
<option value="kullanicilar" <?= ($_GET['tablo_adi']??'') == 'kullanicilar' ? 'selected' : '' ?>>Personel</option>
<option value="calisma_donemleri" <?= ($_GET['tablo_adi']??'') == 'calisma_donemleri' ? 'selected' : '' ?>>Çalışma Dönemleri</option>
<option value="izin_talepleri" <?= ($_GET['tablo_adi']??'') == 'izin_talepleri' ? 'selected' : '' ?>>İzin Talepleri</option>
<option value="mesai_hareketleri" <?= ($_GET['tablo_adi']??'') == 'mesai_hareketleri' ? 'selected' : '' ?>>Mesai</option>
<option value="maas_gecmisi" <?= ($_GET['tablo_adi']??'') == 'maas_gecmisi' ? 'selected' : '' ?>>Maaş Geçmişi</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label small">İşlemi Yapan</label>
<input type="text" name="kullanici_adi" class="form-control form-control-sm" placeholder="Kullanıcı adı" value="<?= $_GET['kullanici_adi']??'' ?>">
</div>
<div class="col-md-2">
<label class="form-label small">Başlangıç</label>
<input type="date" name="baslangic" class="form-control form-control-sm" value="<?= $_GET['baslangic']??'' ?>">
</div>
<div class="col-md-2">
<label class="form-label small">Bitiş</label>
<input type="date" name="bitis" class="form-control form-control-sm" value="<?= $_GET['bitis']??'' ?>">
</div>
<div class="col-md-2 d-flex align-items-end gap-1">
<button type="submit" class="btn btn-primary btn-sm flex-grow-1">Filtrele</button>
<a href="log-izleme.php" class="btn btn-secondary btn-sm">Temizle</a>
</div>
<input type="hidden" name="format" id="exportFormat" value="">
</form>
<!-- TABLO -->
<div class="table-responsive">
<table class="table table-hover table-sm align-middle">
<thead class="table-light">
<tr>
<th>ID</th>
<th>Tarih</th>
<th>İşlemi Yapan</th>
<th>İşlem Tipi</th>
<th>Modül/Tablo</th>
<th>Açıklama</th>
<th>Etkilenen</th>
<th>IP</th>
<th>Detay</th>
</tr>
</thead>
<tbody>
<?php if(empty($loglar)): ?>
<tr><td colspan="9" class="text-center p-4 text-muted">Kayıt bulunamadı.</td></tr>
<?php else: ?>
<?php foreach($loglar as $log):
$tip_badge = match($log['islem_tipi']) {
'ekleme' => 'badge-success',
'guncelleme' => 'badge-info',
'silme' => 'badge-danger',
'işe_alim' => 'badge-success',
'isten_cikarma' => 'badge-danger',
'maas_guncelleme' => 'badge-warning',
default => 'badge-secondary'
};
$etkilenen = etkilenenPersonelBul($pdo, $log['tablo_adi'], $log['kayit_id']);
?>
<tr>
<td><?= $log['id'] ?></td>
<td><?= date('d.m.Y H:i', strtotime($log['tarih'])) ?></td>
<td><?= htmlspecialchars($log['kullanici_adi'] ?? 'Sistem') ?>
<?php if($log['ad'] && $log['soyad']): ?>
<small class="text-muted">(<?= $log['ad'] . ' ' . $log['soyad'] ?>)</small>
<?php endif; ?>
</td>
<td><span class="badge <?= $tip_badge ?>"><?= $log['islem_tipi'] ?></span></td>
<td><?= htmlspecialchars($log['tablo_adi'] ?? '-') ?></td>
<td><?= htmlspecialchars($log['aciklama']) ?></td>
<td><?= $etkilenen ?></td>
<td><?= htmlspecialchars($log['ip_adresi'] ?? '-') ?></td>
<td>
<?php if($log['eski_veri'] || $log['yeni_veri']): ?>
<button class="btn btn-sm btn-outline-info detay-btn"
data-bs-toggle="modal" data-bs-target="#logDetayModal"
data-eski='<?= htmlspecialchars($log['eski_veri'] ?? '') ?>'
data-yeni='<?= htmlspecialchars($log['yeni_veri'] ?? '') ?>'>
<i class="fas fa-eye"></i>
</button>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
<!-- SAYFALAMA -->
<?php if($toplam_sayfa > 1): ?>
<nav aria-label="Sayfalama" class="mt-3 no-print">
<ul class="pagination pagination-sm justify-content-center">
<li class="page-item <?= ($sayfa <= 1) ? 'disabled' : '' ?>">
<a class="page-link" href="<?= urlOlustur($sayfa-1) ?>">«</a>
</li>
<?php for($s=1; $s<=$toplam_sayfa; $s++):
if ($s == 1 || $s == $toplam_sayfa || ($s >= $sayfa-2 && $s <= $sayfa+2)): ?>
<li class="page-item <?= ($sayfa == $s) ? 'active' : '' ?>">
<a class="page-link" href="<?= urlOlustur($s) ?>"><?= $s ?></a>
</li>
<?php elseif($s == $sayfa-3 || $s == $sayfa+3): ?>
<li class="page-item disabled"><span class="page-link">...</span></li>
<?php endif;
endfor; ?>
<li class="page-item <?= ($sayfa >= $toplam_sayfa) ? 'disabled' : '' ?>">
<a class="page-link" href="<?= urlOlustur($sayfa+1) ?>">»</a>
</li>
</ul>
</nav>
<?php endif; ?>
</div>
</div>
</div>
<!-- MODAL -->
<div class="modal fade" id="logDetayModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header bg-dark text-white">
<h5 class="modal-title">Veri Değişiklik Detayı</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body bg-light">
<div class="row g-3">
<div class="col-md-6">
<div class="card border-danger h-100">
<div class="card-header bg-danger text-white py-2">Eski Veri</div>
<div class="card-body p-0">
<pre id="eskiVeriIcerik" class="json-pre mb-0"></pre>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card border-success h-100">
<div class="card-header bg-success text-white py-2">Yeni Veri</div>
<div class="card-body p-0">
<pre id="yeniVeriIcerik" class="json-pre mb-0"></pre>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Kapat</button>
</div>
</div>
</div>
</div>
<script>
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() {
let eski = this.getAttribute('data-eski');
let yeni = this.getAttribute('data-yeni');
try {
if(eski) eski = JSON.stringify(JSON.parse(eski), null, 2);
if(yeni) yeni = JSON.stringify(JSON.parse(yeni), null, 2);
} catch(e) {}
eskiDiv.textContent = eski || "Veri yok / Değişiklik yok.";
yeniDiv.textContent = yeni || "Veri yok.";
});
});
});
</script>
<?php include '../includes/footer.php'; ?>