Files
territory-assigner/export_logs_pdf.php
2025-12-06 18:42:49 +01:00

285 lines
8.5 KiB
PHP

<?php
/**
* Export Log PDF
* Territory Manager
* Esporta i log delle attività in formato PDF
*/
require_once 'config.php';
require_once 'functions.php';
require_once 'db.php';
requireAdmin(); // Solo admin possono esportare i log
$db = getDB();
// Applica gli stessi filtri della pagina logs.php
$filters = [];
if (!empty($_GET['user_id'])) {
$filters['user_id'] = intval($_GET['user_id']);
}
if (!empty($_GET['action_type'])) {
$filters['action_type'] = $_GET['action_type'];
}
if (!empty($_GET['entity_type'])) {
$filters['entity_type'] = $_GET['entity_type'];
}
if (!empty($_GET['date_from'])) {
$filters['date_from'] = $_GET['date_from'];
}
if (!empty($_GET['date_to'])) {
$filters['date_to'] = $_GET['date_to'];
}
if (!empty($_GET['search'])) {
$filters['search'] = $_GET['search'];
}
// Ottieni tutti i log (senza limite di paginazione per l'export)
$where = [];
$params = [];
if (!empty($filters['user_id'])) {
$where[] = "user_id = ?";
$params[] = $filters['user_id'];
}
if (!empty($filters['action_type'])) {
$where[] = "action_type = ?";
$params[] = $filters['action_type'];
}
if (!empty($filters['entity_type'])) {
$where[] = "entity_type = ?";
$params[] = $filters['entity_type'];
}
if (!empty($filters['date_from'])) {
$where[] = "DATE(created_at) >= ?";
$params[] = $filters['date_from'];
}
if (!empty($filters['date_to'])) {
$where[] = "DATE(created_at) <= ?";
$params[] = $filters['date_to'];
}
if (!empty($filters['search'])) {
$where[] = "(action_description LIKE ? OR username LIKE ?)";
$search_term = '%' . $filters['search'] . '%';
$params[] = $search_term;
$params[] = $search_term;
}
$where_clause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';
$logs = $db->fetchAll(
"SELECT * FROM activity_logs
$where_clause
ORDER BY created_at DESC",
$params
);
// Classe semplice per generare PDF (HTML per stampa)
class LogPDF {
private $content = '';
public function addTitle($title) {
$this->content .= "<h1 style='color: #2c3e50; margin-bottom: 20px; text-align: center;'>$title</h1>";
}
public function addSubtitle($subtitle) {
$this->content .= "<h2 style='color: #34495e; margin: 20px 0 10px 0; font-size: 16px;'>$subtitle</h2>";
}
public function addText($text) {
$this->content .= "<p style='margin: 5px 0; color: #555;'>$text</p>";
}
public function addTable($headers, $rows) {
$this->content .= "<table style='width: 100%; border-collapse: collapse; margin: 20px 0; font-size: 11px;'>";
$this->content .= "<thead><tr style='background-color: #34495e; color: white;'>";
foreach ($headers as $header) {
$this->content .= "<th style='padding: 8px 6px; border: 1px solid #ddd; text-align: left; font-weight: bold;'>$header</th>";
}
$this->content .= "</tr></thead><tbody>";
$odd = true;
foreach ($rows as $row) {
$bgColor = $odd ? '#ffffff' : '#f8f9fa';
$this->content .= "<tr style='background-color: $bgColor;'>";
foreach ($row as $cell) {
$this->content .= "<td style='padding: 6px; border: 1px solid #ddd;'>$cell</td>";
}
$this->content .= "</tr>";
$odd = !$odd;
}
$this->content .= "</tbody></table>";
}
public function output($filename) {
header('Content-Type: text/html; charset=utf-8');
header('Content-Disposition: inline; filename="' . $filename . '.html"');
echo "<!DOCTYPE html>
<html lang='it'>
<head>
<meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>$filename</title>
<style>
* { box-sizing: border-box; }
body {
font-family: 'Segoe UI', Arial, sans-serif;
padding: 20px;
margin: 0;
background: white;
}
@media print {
body { padding: 10px; }
.no-print { display: none; }
table { page-break-inside: auto; }
tr { page-break-inside: avoid; page-break-after: auto; }
thead { display: table-header-group; }
}
@page {
size: A4 landscape;
margin: 1cm;
}
</style>
</head>
<body>";
echo "<div class='no-print' style='margin-bottom: 20px; text-align: center;'>";
echo "<button onclick='window.print()' style='padding: 10px 20px; background: #007bff; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 14px;'>Stampa / Salva come PDF</button>";
echo "<button onclick='window.close()' style='padding: 10px 20px; background: #6c757d; color: white; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; margin-left: 10px;'>Chiudi</button>";
echo "</div>";
echo $this->content;
echo "<div style='margin-top: 40px; text-align: center; color: #7f8c8d; font-size: 11px;'>";
echo "<p>Generato il " . date('d/m/Y H:i') . " da " . htmlspecialchars($_SESSION['username']) . " - " . APP_NAME . "</p>";
echo "</div>";
echo "</body></html>";
}
}
$pdf = new LogPDF();
// Titolo
$pdf->addTitle('Log Attività Sistema');
// Informazioni sul report
$info_text = "Report generato il " . date('d/m/Y H:i');
if (!empty($filters)) {
$info_text .= " - Filtri applicati: ";
$filter_parts = [];
if (!empty($filters['user_id'])) {
$user = $db->fetchOne("SELECT username FROM users WHERE id = ?", [$filters['user_id']]);
$filter_parts[] = "Utente: " . htmlspecialchars($user['username']);
}
if (!empty($filters['action_type'])) {
$filter_parts[] = "Azione: " . htmlspecialchars($filters['action_type']);
}
if (!empty($filters['entity_type'])) {
$filter_parts[] = "Entità: " . htmlspecialchars($filters['entity_type']);
}
if (!empty($filters['date_from'])) {
$filter_parts[] = "Dal: " . formatDate($filters['date_from']);
}
if (!empty($filters['date_to'])) {
$filter_parts[] = "Al: " . formatDate($filters['date_to']);
}
if (!empty($filters['search'])) {
$filter_parts[] = "Ricerca: " . htmlspecialchars($filters['search']);
}
$info_text .= implode(', ', $filter_parts);
}
$pdf->addText($info_text);
$pdf->addText("Totale log: " . count($logs));
// Prepara i dati per la tabella
$headers = ['Data/Ora', 'Utente', 'Azione', 'Descrizione', 'Entità', 'IP'];
$rows = [];
foreach ($logs as $log) {
$action_badge = strtoupper(htmlspecialchars($log['action_type']));
$entity_info = '-';
if ($log['entity_type']) {
$entity_info = htmlspecialchars($log['entity_type']);
if ($log['entity_id']) {
$entity_info .= ' #' . $log['entity_id'];
}
}
$rows[] = [
formatDateTime($log['created_at']),
htmlspecialchars($log['username']),
$action_badge,
htmlspecialchars($log['action_description']),
$entity_info,
htmlspecialchars($log['ip_address'])
];
}
$pdf->addTable($headers, $rows);
// Riepilogo per tipo di azione
$action_summary = $db->fetchAll(
"SELECT action_type, COUNT(*) as count
FROM activity_logs
$where_clause
GROUP BY action_type
ORDER BY count DESC",
$params
);
if (!empty($action_summary)) {
$pdf->addSubtitle('Riepilogo per Tipo di Azione');
$summary_headers = ['Tipo Azione', 'Numero Occorrenze'];
$summary_rows = [];
foreach ($action_summary as $summary) {
$summary_rows[] = [
strtoupper(htmlspecialchars($summary['action_type'])),
number_format($summary['count'])
];
}
$pdf->addTable($summary_headers, $summary_rows);
}
// Riepilogo per utente
$user_summary = $db->fetchAll(
"SELECT username, COUNT(*) as count
FROM activity_logs
$where_clause
GROUP BY username
ORDER BY count DESC",
$params
);
if (!empty($user_summary)) {
$pdf->addSubtitle('Riepilogo per Utente');
$user_headers = ['Utente', 'Numero Azioni'];
$user_rows = [];
foreach ($user_summary as $summary) {
$user_rows[] = [
htmlspecialchars($summary['username']),
number_format($summary['count'])
];
}
$pdf->addTable($user_headers, $user_rows);
}
// Output del PDF
$filename = 'log_attivita_' . date('Y-m-d_H-i-s');
$pdf->output($filename);
// Log dell'esportazione
logActivity('export', 'Esportazione log attività in PDF', 'logs', null);