303 lines
9.5 KiB
PHP
Executable File
303 lines
9.5 KiB
PHP
Executable File
<?php
|
|
|
|
// upload.php - Version für AJAX
|
|
|
|
$ini_array = parse_ini_file("config.ini", true);
|
|
$baseURL = $ini_array['base']['URL'];
|
|
|
|
session_start();
|
|
if(! isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] === false){
|
|
header("location: " .$baseURL ."/redirecttologin.php");
|
|
}
|
|
|
|
date_default_timezone_set('Europe/Berlin');
|
|
|
|
// CORS-Headers für AJAX-Requests (falls nötig)
|
|
header('Access-Control-Allow-Origin: *');
|
|
header('Access-Control-Allow-Methods: POST');
|
|
header('Access-Control-Allow-Headers: Content-Type');
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
// Fehlerbehandlung für bessere AJAX-Antworten
|
|
set_error_handler('custom_error_handler');
|
|
set_exception_handler('custom_exception_handler');
|
|
|
|
// Konfiguration
|
|
$max_file_size = 10 * 1024 * 1024; // 10MB
|
|
$allowed_types = array('application/pdf');
|
|
$upload_dir = '../uploads/';
|
|
|
|
// Upload-Ordner erstellen
|
|
if (!is_dir($upload_dir)) {
|
|
if (!mkdir($upload_dir, 0755, true)) {
|
|
send_json_response(false, 'Upload-Ordner konnte nicht erstellt werden.');
|
|
}
|
|
}
|
|
|
|
// Globale Variablen
|
|
$uploaded_files = array();
|
|
$errors = array();
|
|
$start_time = microtime(true);
|
|
|
|
// Hauptverarbeitung
|
|
try {
|
|
process_ajax_upload();
|
|
} catch (Exception $e) {
|
|
send_json_response(false, 'Server-Fehler: ' . $e->getMessage());
|
|
}
|
|
|
|
// ==================== FUNKTIONEN ====================
|
|
|
|
function process_ajax_upload() {
|
|
global $uploaded_files, $errors;
|
|
|
|
// Prüfe HTTP-Methode
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
send_json_response(false, 'Nur POST-Requests erlaubt.');
|
|
}
|
|
|
|
// Prüfe ob Dateien gesendet wurden
|
|
if (empty($_FILES)) {
|
|
send_json_response(false, 'Keine Dateien empfangen.');
|
|
}
|
|
|
|
// Memory Limit erhöhen für große Uploads
|
|
ini_set('memory_limit', '256M');
|
|
|
|
// Alle Dateien verarbeiten
|
|
foreach ($_FILES as $file_key => $file) {
|
|
if ($file['error'] === UPLOAD_ERR_OK) {
|
|
process_single_file($file_key, $file);
|
|
} else if ($file['error'] !== UPLOAD_ERR_NO_FILE) {
|
|
$errors[] = get_upload_error_message($file['error']) . " (Datei: $file_key)";
|
|
}
|
|
}
|
|
|
|
// Antwort senden
|
|
|
|
send_upload_response();
|
|
}
|
|
|
|
function process_single_file($file_key, $file) {
|
|
global $uploaded_files, $errors, $max_file_size, $allowed_types, $upload_dir;
|
|
|
|
$file_number = str_replace('pdf_file_', '', $file_key);
|
|
$document_type = get_post_value('doc_type_' . $file_number);
|
|
|
|
// Detaillierte Validierung
|
|
$validation_result = validate_uploaded_file($file, $file_number, $document_type);
|
|
if (!$validation_result['valid']) {
|
|
$errors = array_merge($errors, $validation_result['errors']);
|
|
return;
|
|
}
|
|
|
|
// Eindeutigen Dateinamen generieren
|
|
$safe_filename = create_unique_filename($file['name'], $file_number);
|
|
$target_path = $upload_dir . $safe_filename;
|
|
|
|
// Datei verschieben mit Fehlerbehandlung
|
|
if (move_uploaded_file($file['tmp_name'], $target_path)) {
|
|
$file_info = array(
|
|
'original_name' => $file['name'],
|
|
'saved_name' => $safe_filename,
|
|
'document_type' => $document_type,
|
|
'file_number' => intval($file_number),
|
|
'size' => $file['size'],
|
|
'path' => $target_path,
|
|
'upload_time' => date('Y-m-d H:i:s'),
|
|
'mime_type' => $file['type']
|
|
);
|
|
|
|
$uploaded_files[] = $file_info;
|
|
|
|
// Logging
|
|
log_upload_activity($file_info);
|
|
|
|
// Optional: Datei-Metadaten in Datenbank speichern
|
|
// save_file_to_database($file_info);
|
|
|
|
} else {
|
|
$errors[] = "Datei $file_number konnte nicht gespeichert werden (Berechtigung prüfen)";
|
|
}
|
|
}
|
|
|
|
function validate_uploaded_file($file, $file_number, $document_type) {
|
|
global $max_file_size, $allowed_types;
|
|
|
|
$validation_errors = array();
|
|
/* foreach($file as $key => $ele){
|
|
$validation_errors[] = $key .": " .$ele ."<br>";
|
|
}
|
|
*/
|
|
|
|
// PDF-Datei Passwort geschützt?
|
|
$command = "pdfinfo " . $file['tmp_name'] . " 2>&1";
|
|
$output = shell_exec($command);
|
|
// $validation_errors[] = "pdfinfo: " .$output;
|
|
|
|
if (strpos($output, 'Incorrect password') !== false ||
|
|
strpos($output, 'Command Line Error') !== false) {
|
|
$validation_errors[] = "Datei '" .$file['name'] ."' ist mit einem Passwort geschützt. Verarbeitung nicht möglich.";
|
|
}
|
|
|
|
|
|
// Dokumentenart prüfen
|
|
if (empty($document_type)) {
|
|
$validation_errors[] = "Dokumentenart für Datei $file_number fehlt";
|
|
}
|
|
|
|
// Dateigröße prüfen
|
|
if ($file['size'] > $max_file_size) {
|
|
$max_mb = round($max_file_size / (1024 * 1024 * 10));
|
|
$file_mb = round($file['size'] / (1024 * 1024 * 10), 2);
|
|
$validation_errors[] = "Datei $file_number zu groß: {$file_mb}MB (max. {$max_mb}MB)";
|
|
}
|
|
|
|
// MIME-Type prüfen
|
|
if (!in_array($file['type'], $allowed_types)) {
|
|
$validation_errors[] = "Datei $file_number hat ungültigen MIME-Type: {$file['type']}";
|
|
}
|
|
|
|
// Dateiendung prüfen
|
|
$file_extension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
|
if ($file_extension !== 'pdf') {
|
|
$validation_errors[] = "Datei $file_number hat keine .pdf Endung";
|
|
}
|
|
|
|
// Dateiinhalt zusätzlich prüfen (PDF-Header)
|
|
if (!is_valid_pdf_file($file['tmp_name'])) {
|
|
$validation_errors[] = "Datei $file_number ist keine gültige PDF-Datei";
|
|
}
|
|
|
|
return array(
|
|
'valid' => empty($validation_errors),
|
|
'errors' => $validation_errors
|
|
);
|
|
}
|
|
|
|
function is_valid_pdf_file($file_path) {
|
|
// PDF-Header prüfen
|
|
$handle = fopen($file_path, 'rb');
|
|
if (!$handle) return false;
|
|
|
|
$header = fread($handle, 4);
|
|
fclose($handle);
|
|
|
|
return $header === '%PDF';
|
|
}
|
|
|
|
function create_unique_filename($original_name, $file_number) {
|
|
$name_info = pathinfo($original_name);
|
|
$base_name = preg_replace('/[^a-zA-Z0-9._-]/', '_', $name_info['filename']);
|
|
$extension = $name_info['extension'];
|
|
|
|
// Zeitstempel und zusätzliche Eindeutigkeit
|
|
$timestamp = date('YmdHis');
|
|
$random = substr(md5(uniqid(rand(), true)), 0, 6);
|
|
|
|
return $base_name . '_' . $timestamp . '_' . $file_number . '_' . $random . '.' . $extension;
|
|
}
|
|
|
|
function log_upload_activity($file_info) {
|
|
$log_entry = array(
|
|
'timestamp' => $file_info['upload_time'],
|
|
'original_name' => $file_info['original_name'],
|
|
'saved_name' => $file_info['saved_name'],
|
|
'document_type' => $file_info['document_type'],
|
|
'size' => $file_info['size'],
|
|
'ip_address' => get_client_ip()
|
|
);
|
|
|
|
$log_file = '../uploads/upload_log.json';
|
|
|
|
// Bestehende Logs laden
|
|
$existing_logs = array();
|
|
if (file_exists($log_file)) {
|
|
$existing_logs = json_decode(file_get_contents($log_file), true) ?: array();
|
|
}
|
|
|
|
// Neuen Eintrag hinzufügen
|
|
$existing_logs[] = $log_entry;
|
|
|
|
// Logs speichern
|
|
file_put_contents($log_file, json_encode($existing_logs, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
|
}
|
|
|
|
function get_client_ip() {
|
|
$ip_keys = array('HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP', 'HTTP_CLIENT_IP', 'REMOTE_ADDR');
|
|
|
|
foreach ($ip_keys as $key) {
|
|
if (!empty($_SERVER[$key])) {
|
|
$ip = $_SERVER[$key];
|
|
if (strpos($ip, ',') !== false) {
|
|
$ip = trim(explode(',', $ip)[0]);
|
|
}
|
|
if (filter_var($ip, FILTER_VALIDATE_IP)) {
|
|
return $ip;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 'unknown';
|
|
}
|
|
|
|
function get_post_value($key) {
|
|
return isset($_POST[$key]) ? trim($_POST[$key]) : '';
|
|
}
|
|
|
|
function get_upload_error_message($error_code) {
|
|
$messages = array(
|
|
UPLOAD_ERR_INI_SIZE => 'Datei überschreitet upload_max_filesize',
|
|
UPLOAD_ERR_FORM_SIZE => 'Datei überschreitet MAX_FILE_SIZE',
|
|
UPLOAD_ERR_PARTIAL => 'Datei wurde nur teilweise hochgeladen',
|
|
UPLOAD_ERR_NO_FILE => 'Keine Datei hochgeladen',
|
|
UPLOAD_ERR_NO_TMP_DIR => 'Temporärer Ordner fehlt',
|
|
UPLOAD_ERR_CANT_WRITE => 'Fehler beim Schreiben',
|
|
UPLOAD_ERR_EXTENSION => 'Upload durch Extension blockiert'
|
|
);
|
|
|
|
return isset($messages[$error_code]) ? $messages[$error_code] : "Unbekannter Fehler ($error_code)";
|
|
}
|
|
|
|
function send_upload_response() {
|
|
global $uploaded_files, $errors, $start_time;
|
|
|
|
$execution_time = round(microtime(true) - $start_time, 2);
|
|
|
|
$response = array(
|
|
'success' => empty($errors),
|
|
'message' => empty($errors)
|
|
? count($uploaded_files) . ' Datei(en) erfolgreich hochgeladen'
|
|
// : 'Upload mit ' . count($errors) . ' Fehler(n) abgeschlossen',
|
|
: '',
|
|
'files' => $uploaded_files,
|
|
'errors' => $errors,
|
|
'execution_time' => $execution_time . 's',
|
|
'timestamp' => date('Y-m-d H:i:s')
|
|
);
|
|
|
|
send_json_response($response['success'], $response['message'], $response);
|
|
}
|
|
|
|
function send_json_response($success, $message, $additional_data = array()) {
|
|
$response = array_merge(array(
|
|
'success' => $success,
|
|
'message' => $message,
|
|
'timestamp' => date('Y-m-d H:i:s')
|
|
), $additional_data);
|
|
|
|
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
|
exit;
|
|
}
|
|
|
|
function custom_error_handler($severity, $message, $file, $line) {
|
|
if (!(error_reporting() & $severity)) return;
|
|
|
|
send_json_response(false, "PHP Fehler: $message in $file:$line");
|
|
}
|
|
|
|
function custom_exception_handler($exception) {
|
|
send_json_response(false, "Exception: " . $exception->getMessage());
|
|
}
|
|
?>
|