Merge branch 'main' of http://git.pb.bib.de/PBBFA23CIV/EIANotesApp
This commit is contained in:
commit
6cceae17d0
@ -36,4 +36,54 @@ class NotesController
|
|||||||
"note" => $note
|
"note" => $note
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function createNote()
|
||||||
|
{
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
// Process form submission
|
||||||
|
$note = $this->notesModel->createNote(
|
||||||
|
$_POST['title'],
|
||||||
|
$_POST['content'],
|
||||||
|
$_SESSION['user_id']
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($note) {
|
||||||
|
// Redirect to show notes page after successful creation
|
||||||
|
header('Location: ?controller=NotesController&page=showNotes');
|
||||||
|
exit();
|
||||||
|
} else {
|
||||||
|
// If creation failed, show error message and stay on the form
|
||||||
|
$this->view->setVars([
|
||||||
|
'error' => 'Failed to create note. Please try again.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editNote()
|
||||||
|
{
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
// Process form submission
|
||||||
|
$noteId = $_GET['id'];
|
||||||
|
$note = $this->notesModel->editNote($noteId, $_POST['title'], $_POST['content'], $_SESSION['user_id']);
|
||||||
|
|
||||||
|
if ($note) {
|
||||||
|
// Redirect to show notes page after successful creation
|
||||||
|
header('Location: ?controller=NotesController&page=showNotes');
|
||||||
|
exit();
|
||||||
|
} else {
|
||||||
|
// If creation failed, show error message and stay on the form
|
||||||
|
$this->view->setVars([
|
||||||
|
'error' => 'Failed to create note. Please try again.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteNote()
|
||||||
|
{
|
||||||
|
$noteId = $_GET['id'];
|
||||||
|
$this->notesModel->deleteNote($noteId, $_SESSION['user_id']);
|
||||||
|
header("Location: ?controller=NotesController&page=showNotes");
|
||||||
|
}
|
||||||
}
|
}
|
@ -61,4 +61,72 @@ class NotesModel extends Database
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createNote($title, $content, $userId) {
|
||||||
|
$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) VALUES (?, ?, ?)");
|
||||||
|
$stmt->execute([$userId, trim($title), $content]); // user_id is current session user
|
||||||
|
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, $userId, $title, $content) {
|
||||||
|
$pdo = $this->linkDB();
|
||||||
|
if (!$pdo) return ['success' => false, 'message' => 'Database error.'];
|
||||||
|
if (empty(trim($title))) return ['success' => false, 'message' => 'Title is required.'];
|
||||||
|
try {
|
||||||
|
if (isAdmin()) { // Admin can update any note, user_id for record not changed
|
||||||
|
$stmt = $pdo->prepare("UPDATE notes SET title = ?, content = ? WHERE id = ?");
|
||||||
|
$params = [trim($title), $content, $noteId];
|
||||||
|
} else { // User can only update their own note
|
||||||
|
$stmt = $pdo->prepare("UPDATE notes SET title = ?, content = ? WHERE id = ? AND user_id = ?");
|
||||||
|
$params = [trim($title), $content, $noteId, $userId];
|
||||||
|
}
|
||||||
|
$stmt->execute($params);
|
||||||
|
|
||||||
|
if ($stmt->rowCount() > 0) {
|
||||||
|
return ['success' => true, 'message' => 'Note updated successfully.'];
|
||||||
|
}
|
||||||
|
// Check if note exists if rowCount is 0
|
||||||
|
$checkStmt = isAdmin() ? $pdo->prepare("SELECT id FROM notes WHERE id=?") : $pdo->prepare("SELECT id FROM notes WHERE id=? AND user_id=?");
|
||||||
|
$checkParams = isAdmin() ? [$noteId] : [$noteId, $userId];
|
||||||
|
$checkStmt->execute($checkParams);
|
||||||
|
if ($checkStmt->fetch()) {
|
||||||
|
return ['success' => true, 'message' => 'No changes made to the note.']; // Or false if you prefer
|
||||||
|
}
|
||||||
|
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 (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.'];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
67
Views/Notes/createNote.phtml
Normal file
67
Views/Notes/createNote.phtml
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
use ppa\Model\NotesModel;
|
||||||
|
include dirname(__DIR__).'/header.phtml';
|
||||||
|
|
||||||
|
$parsedown = new Parsedown();
|
||||||
|
$parsedown->setSafeMode(true);
|
||||||
|
|
||||||
|
$this->notesModel = new \ppa\Model\NotesModel();
|
||||||
|
|
||||||
|
$isEditMode = false;
|
||||||
|
$note = null;
|
||||||
|
if ($isEditMode) {
|
||||||
|
$noteId = $_GET['id'] ?? 0;
|
||||||
|
$note = $this->notesModel->getNoteById($noteId, $_SESSION['user_id']);
|
||||||
|
if (!$note) {
|
||||||
|
echo "<div class='alert alert-danger'>Note not found or you don't have permission to edit it.</div>";
|
||||||
|
echo "<a href='?controller=Notes&page=showNotes&do=showNotes' class='button secondary'>Back to Dashboard</a>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLoggedIn() {
|
||||||
|
return isset($_SESSION['user_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAdmin() {
|
||||||
|
return false;// isLoggedIn() && isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
|
||||||
|
return htmlspecialchars((string)$data, $flags, $encoding);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<h2><?php echo $isEditMode ? 'Edit Note' . (isAdmin() && $note && $note['user_id'] != $_SESSION['user_id'] ? ' (Admin Edit - Owner: '.sanitize($note['owner_username']).')' : '') : 'Create New Note'; ?></h2>
|
||||||
|
<a href="?controller=Notes&page=showNotes&do=showNotes" class="button secondary">Cancel</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="drop-zone">Drag & drop a .txt or .md file here, or fill manually.</div>
|
||||||
|
|
||||||
|
<form id="note-form" method="POST">
|
||||||
|
<input type="hidden" name="action" value="<?php echo $isEditMode ? 'update_note' : 'create_note'; ?>">
|
||||||
|
<?php if ($isEditMode && $note): ?>
|
||||||
|
<input type="hidden" name="note_id" value="<?php echo sanitize($note['id']); ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="title">Title:</label>
|
||||||
|
<input type="text" id="title" name="title" value="<?php echo $isEditMode && $note ? sanitize($note['title']) : ''; ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="content">Content (Markdown supported):</label>
|
||||||
|
<textarea id="content" name="content" rows="10" required><?php echo $isEditMode && $note ? sanitize($note['content']) : ''; ?></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Live Markdown Preview:</label>
|
||||||
|
<div id="markdown-preview" class="markdown-preview">
|
||||||
|
<?php if($isEditMode && $note && !empty($note['content'])) echo $parsedown->text(sanitize($note['content'])); else echo "Start typing or drop a file to see preview..."; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-actions">
|
||||||
|
<button type="submit" class="button"><?php echo $isEditMode ? 'Update Note' : 'Create Note'; ?></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
67
Views/Notes/editNote.phtml
Normal file
67
Views/Notes/editNote.phtml
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
use ppa\Model\NotesModel;
|
||||||
|
include dirname(__DIR__).'/header.phtml';
|
||||||
|
|
||||||
|
$parsedown = new Parsedown();
|
||||||
|
$parsedown->setSafeMode(true);
|
||||||
|
|
||||||
|
$this->notesModel = new \ppa\Model\NotesModel();
|
||||||
|
|
||||||
|
$isEditMode = true;
|
||||||
|
$note = null;
|
||||||
|
if ($isEditMode) {
|
||||||
|
$noteId = $_GET['id'] ?? 0;
|
||||||
|
$note = $this->notesModel->getNoteById($noteId, $_SESSION['user_id']);
|
||||||
|
if (!$note) {
|
||||||
|
echo "<div class='alert alert-danger'>Note not found or you don't have permission to edit it.</div>";
|
||||||
|
echo "<a href='?controller=Notes&page=showNotes&do=showNotes' class='button secondary'>Back to Dashboard</a>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLoggedIn() {
|
||||||
|
return isset($_SESSION['user_id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAdmin() {
|
||||||
|
return false;// isLoggedIn() && isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
|
||||||
|
return htmlspecialchars((string)$data, $flags, $encoding);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="page-header">
|
||||||
|
<h2><?php echo $isEditMode ? 'Edit Note' . (isAdmin() && $note && $note['user_id'] != $_SESSION['user_id'] ? ' (Admin Edit - Owner: '.sanitize($note['owner_username']).')' : '') : 'Create New Note'; ?></h2>
|
||||||
|
<a href="?controller=Notes&page=showNotes&do=showNotes" class="button secondary">Cancel</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="drop-zone">Drag & drop a .txt or .md file here, or fill manually.</div>
|
||||||
|
|
||||||
|
<form id="note-form" method="POST">
|
||||||
|
<input type="hidden" name="action" value="<?php echo $isEditMode ? 'update_note' : 'create_note'; ?>">
|
||||||
|
<?php if ($isEditMode && $note): ?>
|
||||||
|
<input type="hidden" name="note_id" value="<?php echo sanitize($note['id']); ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="title">Title:</label>
|
||||||
|
<input type="text" id="title" name="title" value="<?php echo $isEditMode && $note ? sanitize($note['title']) : ''; ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="content">Content (Markdown supported):</label>
|
||||||
|
<textarea id="content" name="content" rows="10" required><?php echo $isEditMode && $note ? sanitize($note['content']) : ''; ?></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Live Markdown Preview:</label>
|
||||||
|
<div id="markdown-preview" class="markdown-preview">
|
||||||
|
<?php if($isEditMode && $note && !empty($note['content'])) echo $parsedown->text(sanitize($note['content'])); else echo "Start typing or drop a file to see preview..."; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-actions">
|
||||||
|
<button type="submit" class="button"><?php echo $isEditMode ? 'Update Note' : 'Create Note'; ?></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
@ -25,9 +25,9 @@ $parsedown->setSafeMode(true);
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="note-actions">
|
<div class="note-actions">
|
||||||
<a href="?controller=NotesController&page=showNotes" class="button">Back to Notes</a>
|
<a href="?controller=Notes&page=showNotes&do=showNotes" class="button">Back to Notes</a>
|
||||||
<?php if (isset($note['id'])): ?>
|
<?php if (isset($note['id'])): ?>
|
||||||
<a href="?controller=NotesController&page=editNote¬e_id=<?php echo (int)$note['id']; ?>" class="button">Edit Note</a>
|
<a href="?controller=Notes&do=editNote&id=<?php echo (int)$note['id']; ?>" class="button">Edit Note</a>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,7 +35,7 @@ $parsedown->setSafeMode(true);
|
|||||||
<div class="error-message">
|
<div class="error-message">
|
||||||
<h2>Note Not Found</h2>
|
<h2>Note Not Found</h2>
|
||||||
<p><?php echo htmlspecialchars($error ?? 'The requested note could not be found.'); ?></p>
|
<p><?php echo htmlspecialchars($error ?? 'The requested note could not be found.'); ?></p>
|
||||||
<a href="?controller=NotesController&page=showNotes" class="button">Back to Notes</a>
|
<a href="?controller=Notes&page=showNotes&do=showNotes" class="button">Back to Notes</a>
|
||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<?php include dirname(__DIR__).'/header.phtml'; ?>
|
<?php include dirname(__DIR__).'/header.phtml'; ?>
|
||||||
|
|
||||||
<h2>Notes</h2>
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<?php
|
<?php
|
||||||
$parsedown = new Parsedown();
|
$parsedown = new Parsedown();
|
||||||
@ -14,6 +12,7 @@
|
|||||||
function isAdmin() {
|
function isAdmin() {
|
||||||
return false;// isLoggedIn() && isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
|
return false;// isLoggedIn() && isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
|
||||||
}
|
}
|
||||||
|
|
||||||
function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
|
function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
|
||||||
return htmlspecialchars((string)$data, $flags, $encoding);
|
return htmlspecialchars((string)$data, $flags, $encoding);
|
||||||
}
|
}
|
||||||
@ -21,6 +20,11 @@
|
|||||||
$sortBy = $_GET['sort_by'] ?? 'updated_at';
|
$sortBy = $_GET['sort_by'] ?? 'updated_at';
|
||||||
$sortOrder = strtoupper($_GET['sort_order'] ?? 'DESC'); // Ensure uppercase for comparison
|
$sortOrder = strtoupper($_GET['sort_order'] ?? 'DESC'); // Ensure uppercase for comparison
|
||||||
?>
|
?>
|
||||||
|
<div class="page-header">
|
||||||
|
<h2><?php echo isAdmin() ? "All Users' Notes" : "My Notes"; ?></h2>
|
||||||
|
<a href="?controller=Notes&do=createNote" class="button">Create New Note</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table class="notes-table">
|
<table class="notes-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -51,7 +55,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td><?php echo date("d.m.Y H:i", strtotime($note['updated_at'])); ?></td>
|
<td><?php echo date("d.m.Y H:i", strtotime($note['updated_at'])); ?></td>
|
||||||
<td class="actions-cell">
|
<td class="actions-cell">
|
||||||
<a href="index.php?page=edit_note&id=<?php echo $note['id']; ?>" class="button">Edit</a>
|
<a href="?controller=Notes&do=editNote&id=<?php echo $note['id']; ?>" class="button">Edit</a>
|
||||||
<button class="button danger delete-note-btn" data-note-id="<?php echo $note['id']; ?>">Delete</button>
|
<button class="button danger delete-note-btn" data-note-id="<?php echo $note['id']; ?>">Delete</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<link href="CSS/style.css" rel="stylesheet" type="text/css" />
|
<link href="CSS/style.css" rel="stylesheet" type="text/css" />
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/2.1.0/showdown.min.js"></script>
|
||||||
<script src="JavaScript/script.js"></script>
|
<script src="JavaScript/script.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user