285 lines
8.5 KiB
PHP
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);
|