linkDB(); $erg = array(); // Whitelist of allowed sort columns $allowedSortColumns = ['id', 'title', 'owner_username', 'updated_at', 'priority']; $allowedSortOrders = ['ASC', 'DESC']; $sortBy = in_array($sortBy, $allowedSortColumns) ? $sortBy : 'updated_at'; $sortOrder = in_array(strtoupper($sortOrder), $allowedSortOrders) ? strtoupper($sortOrder) : 'DESC'; try { if ($isAdmin) { $sql = "SELECT n.id, n.title, n.content, n.created_at, n.updated_at, u.username AS owner_username, p.name AS priority FROM notes n JOIN priority p ON n.priority = p.id JOIN users u ON n.user_id = u.id ORDER BY {$sortBy} {$sortOrder}"; $stmt = $pdo->prepare($sql); $stmt->execute(); } else { $sql = "SELECT n.id, n.title, n.content, n.created_at, n.updated_at, p.name AS priority FROM notes n JOIN priority p ON n.priority = p.id WHERE user_id = :userid ORDER BY {$sortBy} {$sortOrder}"; $stmt = $pdo->prepare($sql); $stmt->execute(['userid' => $userid]); } $erg = $stmt->fetchAll(\PDO::FETCH_ASSOC); return $erg; } catch (PDOException $e) { error_log("Database Error in selectNotesForUser: " . $e->getMessage()); return false; } } function getNoteById($noteId) { $pdo = $this->linkDB(); if (!$pdo) return null; try { if ($_SESSION['role'] === 'admin') { // Admin can fetch any note $stmt = $pdo->prepare("SELECT n.*, u.username as owner_username FROM notes n JOIN users u ON n.user_id = u.id WHERE n.id = ?"); $stmt->execute([$noteId]); } else { // Regular user can only fetch their own notes $stmt = $pdo->prepare("SELECT * FROM notes WHERE id = ? AND user_id = ?"); $stmt->execute([$noteId, $_SESSION['user_id']]); } return $stmt->fetch(); } catch (PDOException $e) { error_log("Get Note Error: " . $e->getMessage()); return null; } } function createNote($title, $content, $userId, $priority) { $pdo = $this->linkDB(); if (!$pdo) return ['success' => false, 'message' => 'Database error.']; if (empty(trim($title))) return ['success' => false, 'message' => 'Title is required.']; try { $stmt = $pdo->prepare("INSERT INTO notes (user_id, title, content, priority) VALUES (?, ?, ?, ?)"); $stmt->execute([$userId, trim($title), $content, $priority]); // user_id is current session user $noteId = $pdo->lastInsertId(); $uploadResult = $this->uploadFiles($noteId); if (!$uploadResult['success']) { return $uploadResult; } return ['success' => true, 'message' => 'Note created successfully.']; } catch (PDOException $e) { error_log("Create Note Error: " . $e->getMessage()); return ['success' => false, 'message' => 'Failed to create note.']; } } function editNote($noteId, $title, $content, $userId, $priority) { $pdo = $this->linkDB(); if (!$pdo) return ['success' => false, 'message' => 'Database error.']; if (empty(trim($title))) return ['success' => false, 'message' => 'Title is required.']; try { if ($this->isAdmin()) { // Admin can update any note, user_id for record not changed $stmt = $pdo->prepare("UPDATE notes SET title = ?, content = ?, priority = ? WHERE id = ?"); $params = [trim($title), $content, $priority, $noteId]; } else { // User can only update their own note $stmt = $pdo->prepare("UPDATE notes SET title = ?, content = ?, priority = ? WHERE id = ? AND user_id = ?"); $params = [trim($title), $content, $priority, $noteId, $userId]; } $stmt->execute($params); $uploadResult = $this->uploadFiles($noteId); if (!$uploadResult['success']) { return $uploadResult; } if ($stmt->rowCount() > 0) { return ['success' => true, 'message' => 'Note updated successfully.']; } // Check if note exists if rowCount is 0 $checkStmt = $this->isAdmin() ? $pdo->prepare("SELECT id FROM notes WHERE id=?") : $pdo->prepare("SELECT id FROM notes WHERE id=? AND user_id=?"); $checkParams = $this->isAdmin() ? [$noteId] : [$noteId, $userId]; $checkStmt->execute($checkParams); if ($checkStmt->fetch()) { return ['success' => true, 'message' => 'No changes made to the note.']; } return ['success' => false, 'message' => 'Note not found or permission denied.']; } catch (PDOException $e) { error_log("Update Note Error: " . $e->getMessage()); return ['success' => false, 'message' => 'Failed to update note.']; } } function deleteNote($noteId, $userId) { $pdo = $this->linkDB(); if (!$pdo) return ['success' => false, 'message' => 'Database error.']; try { if ($this->isAdmin()) { // Admin can delete any note $stmt = $pdo->prepare("DELETE FROM notes WHERE id = ?"); $params = [$noteId]; } else { // User can only delete their own note $stmt = $pdo->prepare("DELETE FROM notes WHERE id = ? AND user_id = ?"); $params = [$noteId, $userId]; } $stmt->execute($params); if ($stmt->rowCount() > 0) { return ['success' => true, 'message' => 'Note deleted successfully.']; } return ['success' => false, 'message' => 'Note not found or permission denied.']; } catch (PDOException $e) { error_log("Delete Note Error: " . $e->getMessage()); return ['success' => false, 'message' => 'Failed to delete note.']; } } function getUploadedFiles($noteId) { $pdo = $this->linkDB(); if (!$pdo) return []; try { $stmt = $pdo->prepare("SELECT * FROM files WHERE note_id = ?"); $stmt->execute([$noteId]); return $stmt->fetchAll(\PDO::FETCH_ASSOC); } catch (PDOException $e) { error_log("Get Uploaded Files Error: " . $e->getMessage()); return []; } } function getFileCount() { $pdo = $this->linkDB(); if (!$pdo) return 0; try { $stmt = $pdo->prepare("SELECT COUNT(*) FROM files"); $stmt->execute(); return $stmt->fetchColumn(); } catch (PDOException $e) { error_log("Get Files Count Error: " . $e->getMessage()); return 0; } } function getNoteCount() { $pdo = $this->linkDB(); if (!$pdo) return 0; try { $stmt = $pdo->prepare("SELECT COUNT(*) FROM notes"); $stmt->execute(); return $stmt->fetchColumn(); } catch (PDOException $e) { error_log("Get Notes Count Error: " . $e->getMessage()); return 0; } } function isLoggedIn() { return isset($_SESSION['user_id']); } function isAdmin() { return $this->isLoggedIn() && isset($_SESSION['role']) && $_SESSION['role'] === 'admin'; } public function uploadFiles($noteId) { $pdo = $this->linkDB(); if (!$pdo) return ['success' => false, 'message' => 'Database error.']; $uploadDir = $_SERVER['DOCUMENT_ROOT'] . '/EIANotesApp/Uploads/'; $uploadedFileNames = []; if (isset($_FILES['attachments']) && !empty($_FILES['attachments']['name'][0])) { $files = $_FILES['attachments']; foreach ($files['name'] as $key => $name) { if ($files['error'][$key] === UPLOAD_ERR_OK) { $tmpName = $files['tmp_name'][$key]; $safeFilename = basename($name); $uniqueFilename = time() . '-' . preg_replace('/[^A-Za-z0-9.\-]/', '_', $safeFilename); $destination = $uploadDir . $uniqueFilename; if (move_uploaded_file($tmpName, $destination)) { $uploadedFileNames[] = $uniqueFilename; $stmt = $pdo->prepare("INSERT INTO files (note_id, original_filename, stored_filename, file_type, file_size, uploaded_at) VALUES (?, ?, ?, ?, ?, ?)"); $stmt->execute([$noteId, $safeFilename, $uniqueFilename, $files['type'][$key], $files['size'][$key], date('Y-m-d H:i:s')]); } else { $errmsg = "Error: Could not move uploaded file '$safeFilename'."; } } else { $errmsg = "Error uploading file '$name'. Error code: " . $files['error'][$key]; } } } if (isset($errmsg)) { return ['success' => false, 'message' => $errmsg]; } return ['success' => true, 'message' => 'Files uploaded successfully.', 'fileNames' => $uploadedFileNames]; } }