false, 'files' => [], 'errors' => [] ]; function getUploadErrorMessage($errorCode) { switch ($errorCode) { case UPLOAD_ERR_INI_SIZE: return 'The uploaded file exceeds the upload_max_filesize directive in php.ini.'; case UPLOAD_ERR_FORM_SIZE: return 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.'; case UPLOAD_ERR_PARTIAL: return 'The uploaded file was only partially uploaded.'; case UPLOAD_ERR_NO_FILE: return 'No file was uploaded.'; case UPLOAD_ERR_NO_TMP_DIR: return 'Missing a temporary folder.'; case UPLOAD_ERR_CANT_WRITE: return 'Failed to write file to disk.'; case UPLOAD_ERR_EXTENSION: return 'A PHP extension stopped the file upload.'; default: return 'Unknown upload error.'; } } if (!isset($_FILES['photos'])) { $response['errors'][] = 'No files were sent. The key "photos" is missing from the request.'; echo json_encode($response); exit; } $upload_dir = __DIR__ . '/../assets/uploads/'; if (!is_dir($upload_dir)) { if (!mkdir($upload_dir, 0775, true)) { $response['errors'][] = 'Failed to create upload directory: ' . $upload_dir; echo json_encode($response); exit; } } if (!is_writable($upload_dir)) { $response['errors'][] = 'The upload directory is not writable: ' . $upload_dir; echo json_encode($response); exit; } $files = $_FILES['photos']; $file_count = count($files['name']); $successful_uploads = 0; try { $pdo = db(); $stmt = $pdo->prepare( 'INSERT INTO photos (filename, filepath, filesize) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE updated_at = CURRENT_TIMESTAMP' ); } catch (PDOException $e) { $response['errors'][] = 'Database connection failed: ' . $e->getMessage(); error_log('DB Connection Error: ' . $e->getMessage()); echo json_encode($response); exit; } for ($i = 0; $i < $file_count; $i++) { $errorCode = $files['error'][$i]; $filename = basename($files['name'][$i]); if ($errorCode !== UPLOAD_ERR_OK) { $response['errors'][] = "Error uploading '$filename': " . getUploadErrorMessage($errorCode); continue; } $filepath = $upload_dir . $filename; $relative_path = 'assets/uploads/' . $filename; if (!move_uploaded_file($files['tmp_name'][$i], $filepath)) { $response['errors'][] = "Failed to move uploaded file '$filename'. Check permissions and paths."; continue; } try { $stmt->execute([$filename, $relative_path, $files['size'][$i]]); $response['files'][] = [ 'filename' => $filename, 'filepath' => $relative_path ]; $successful_uploads++; } catch (PDOException $e) { $response['errors'][] = "Failed to save file '$filename' to database: " . $e->getMessage(); error_log("DB Insert Error for $filename: " . $e->getMessage()); // Optionally, delete the file if DB insert fails // unlink($filepath); } } if ($successful_uploads > 0) { $response['success'] = true; } if ($successful_uploads < $file_count) { $response['success'] = false; // Mark as failure if any file failed } echo json_encode($response);