'Include of main fails'))); } header('Content-Type: application/json'); // Security check if (!$user->admin && !$user->hasRight('kundenkarte', 'admin')) { http_response_code(403); die(json_encode(array('error' => 'Access denied'))); } $action = GETPOST('action', 'aZ09'); // Directory for custom icons $iconDir = DOL_DATA_ROOT.'/kundenkarte/icons'; $iconUrl = DOL_URL_ROOT.'/document.php?modulepart=kundenkarte&file=icons/'; // Create directory if not exists if (!is_dir($iconDir)) { dol_mkdir($iconDir); } /** * List all custom icons */ if ($action == 'list') { $icons = array(); if (is_dir($iconDir)) { $files = scandir($iconDir); foreach ($files as $file) { if ($file == '.' || $file == '..') continue; $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); if (in_array($ext, array('png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'))) { $icons[] = array( 'filename' => $file, 'url' => $iconUrl.urlencode($file), 'name' => pathinfo($file, PATHINFO_FILENAME) ); } } } echo json_encode(array('success' => true, 'icons' => $icons)); exit; } /** * Upload a new icon */ if ($action == 'upload') { if (empty($_FILES['icon']) || $_FILES['icon']['error'] != 0) { http_response_code(400); die(json_encode(array('error' => 'No file uploaded or upload error'))); } $file = $_FILES['icon']; $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); // Check extension $allowedExt = array('png', 'jpg', 'jpeg', 'gif', 'svg', 'webp'); if (!in_array($ext, $allowedExt)) { http_response_code(400); die(json_encode(array('error' => 'Invalid file type. Allowed: '.implode(', ', $allowedExt)))); } // Check size (max 500KB) if ($file['size'] > 512000) { http_response_code(400); die(json_encode(array('error' => 'File too large. Max 500KB'))); } // Sanitize filename $filename = dol_sanitizeFileName($file['name']); $filename = preg_replace('/[^a-zA-Z0-9_\-\.]/', '_', $filename); // Check if file exists, add number if so $baseName = pathinfo($filename, PATHINFO_FILENAME); $counter = 1; while (file_exists($iconDir.'/'.$filename)) { $filename = $baseName.'_'.$counter.'.'.$ext; $counter++; } // Move file if (move_uploaded_file($file['tmp_name'], $iconDir.'/'.$filename)) { echo json_encode(array( 'success' => true, 'icon' => array( 'filename' => $filename, 'url' => $iconUrl.urlencode($filename), 'name' => pathinfo($filename, PATHINFO_FILENAME) ) )); } else { http_response_code(500); die(json_encode(array('error' => 'Failed to save file'))); } exit; } /** * Delete an icon */ if ($action == 'delete') { $filename = GETPOST('filename', 'alphanohtml'); if (empty($filename)) { http_response_code(400); die(json_encode(array('error' => 'No filename provided'))); } // Sanitize to prevent directory traversal $filename = basename($filename); $filepath = $iconDir.'/'.$filename; if (file_exists($filepath)) { if (unlink($filepath)) { echo json_encode(array('success' => true)); } else { http_response_code(500); die(json_encode(array('error' => 'Failed to delete file'))); } } else { http_response_code(404); die(json_encode(array('error' => 'File not found'))); } exit; } http_response_code(400); die(json_encode(array('error' => 'Invalid action')));