This commit is contained in:
David Kalemi 2025-07-07 14:39:42 +02:00
commit bb9424232c
8 changed files with 147 additions and 10 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
uploads

View File

@ -79,15 +79,15 @@ class NotesController
$_SESSION['user_id'], $_SESSION['user_id'],
$_POST['priority'] $_POST['priority']
); );
if ($note) { if ($note) {
// Redirect to show notes page after successful creation // Redirect to show notes page after successful update
header('Location: ?controller=Notes&page=showNotes&do=showNotes'); header('Location: ?controller=Notes&page=showNotes&do=showNotes');
exit(); exit();
} else { } else {
// If creation failed, show error message and stay on the form // If update failed, show error message and stay on the form
$this->view->setVars([ $this->view->setVars([
'error' => 'Failed to create note. Please try again.' 'error' => 'Failed to update note. Please try again.'
]); ]);
} }
} }

View File

@ -71,6 +71,11 @@ class NotesModel extends Database
try { try {
$stmt = $pdo->prepare("INSERT INTO notes (user_id, title, content, priority) VALUES (?, ?, ?, ?)"); $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 $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.']; return ['success' => true, 'message' => 'Note created successfully.'];
} catch (PDOException $e) { } catch (PDOException $e) {
error_log("Create Note Error: " . $e->getMessage()); error_log("Create Note Error: " . $e->getMessage());
@ -91,6 +96,11 @@ class NotesModel extends Database
$params = [trim($title), $content, $priority, $noteId, $userId]; $params = [trim($title), $content, $priority, $noteId, $userId];
} }
$stmt->execute($params); $stmt->execute($params);
$uploadResult = $this->uploadFiles($noteId);
if (!$uploadResult['success']) {
return $uploadResult;
}
if ($stmt->rowCount() > 0) { if ($stmt->rowCount() > 0) {
return ['success' => true, 'message' => 'Note updated successfully.']; return ['success' => true, 'message' => 'Note updated successfully.'];
@ -132,6 +142,32 @@ class NotesModel extends Database
} }
} }
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() { function getNoteCount() {
$pdo = $this->linkDB(); $pdo = $this->linkDB();
if (!$pdo) return 0; if (!$pdo) return 0;
@ -152,4 +188,40 @@ class NotesModel extends Database
function isAdmin() { function isAdmin() {
return $this->isLoggedIn() && isset($_SESSION['role']) && $_SESSION['role'] === 'admin'; 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];
}
} }

View File

@ -2,6 +2,16 @@
use ppa\Model\NotesModel; use ppa\Model\NotesModel;
include dirname(__DIR__).'/header.phtml'; include dirname(__DIR__).'/header.phtml';
//// Test write permissions
//// This is the directory we will upload files to.
//$uploadDir = $_SERVER['DOCUMENT_ROOT'] . '/EIANotesApp/Uploads/';
//if (!file_exists($uploadDir)) {
// mkdir($uploadDir, 0777, true);
//}
//$testFile = $uploadDir . 'test_write.txt';
//$testContent = 'Test write operation at ' . date('Y-m-d H:i:s');
//$writeResult = file_put_contents($testFile, $testContent);
$parsedown = new Parsedown(); $parsedown = new Parsedown();
$parsedown->setSafeMode(true); $parsedown->setSafeMode(true);
@ -26,12 +36,16 @@ function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
<div class="page-header"> <div class="page-header">
<h2>Create New Note</h2> <h2>Create New Note</h2>
<a href="?controller=Notes&page=showNotes&do=showNotes" class="button secondary">Cancel</a> <a href="?controller=Notes&page=showNotes&do=showNotes" class="button secondary">Cancel</a>
</div> </div>
<label class="error-message"><?php if (isset($errmsg)):?>
<?php echo $errmsg;?>
<?php endif; ?></label>
<div id="drop-zone">Drag & drop a .txt or .md file here, or fill manually.</div> <div id="drop-zone">Drag & drop a .txt or .md file here, or fill manually.</div>
<form id="note-form" method="POST"> <form id="note-form" method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="create_note"> <input type="hidden" name="action" value="create_note">
<div class="form-group"> <div class="form-group">
<label for="title">Title:</label> <label for="title">Title:</label>
@ -55,6 +69,12 @@ function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
<option value="3">HIGH</option> <option value="3">HIGH</option>
</select> </select>
</div> </div>
<div class="form-group">
<label for="attachments">Attach Files:</label>
<input type="file" id="attachments" name="attachments[]" multiple>
</div>
<div class="form-actions"> <div class="form-actions">
<button type="submit" class="button">Create Note</button> <button type="submit" class="button">Create Note</button>
</div> </div>
@ -62,4 +82,4 @@ function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
<input type="hidden" name="do" value="createNote"> <input type="hidden" name="do" value="createNote">
</form> </form>
</div> </div>

View File

@ -15,6 +15,8 @@ if (!$note) {
echo "<a href='?controller=Notes&page=showNotes&do=showNotes' class='button secondary'>Back to Dashboard</a>"; echo "<a href='?controller=Notes&page=showNotes&do=showNotes' class='button secondary'>Back to Dashboard</a>";
} }
$files = $this->notesModel->getUploadedFiles($noteId);
function isLoggedIn() { function isLoggedIn() {
return isset($_SESSION['user_id']); return isset($_SESSION['user_id']);
} }
@ -37,7 +39,7 @@ function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
<div id="drop-zone">Drag & drop a .txt or .md file here, or fill manually.</div> <div id="drop-zone">Drag & drop a .txt or .md file here, or fill manually.</div>
<form id="note-form" method="POST"> <form id="note-form" method="POST" enctype="multipart/form-data">
<input type="hidden" name="action" value="update_note"> <input type="hidden" name="action" value="update_note">
<input type="hidden" name="note_id" value="<?php echo sanitize($note['id']); ?>"> <input type="hidden" name="note_id" value="<?php echo sanitize($note['id']); ?>">
<div class="form-group"> <div class="form-group">
@ -62,11 +64,26 @@ function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
<option value="3">HIGH</option> <option value="3">HIGH</option>
</select> </select>
</div> </div>
<div class="form-group">
<label for="attachments">Attach additional Files:</label>
<input type="file" id="attachments" name="attachments[]" multiple>
</div>
<?php if($files && count($files) > 0): ?>
<div class="form-group">
<label>Files currently attached:</label>
<ul>
<?php foreach($files as $file): ?>
<li>
<a href="/EIANotesApp/Uploads/<?php echo $file['stored_filename']; ?>" download target="_blank"><?php echo htmlspecialchars($file['original_filename']); ?></a>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<div class="form-actions"> <div class="form-actions">
<button type="submit" class="button">Update Note</button> <button type="submit" class="button">Update Note</button>
</div> </div>
<input type="hidden" name="controller" value="Notes"> <input type="hidden" name="controller" value="Notes">
<input type="hidden" name="do" value="editNote"> <input type="hidden" name="do" value="editNote">
</form> </form>
</div> </div>

View File

@ -3,6 +3,9 @@
<?php <?php
$parsedown = new Parsedown(); $parsedown = new Parsedown();
$parsedown->setSafeMode(true); $parsedown->setSafeMode(true);
$this->notesModel = new \ppa\Model\NotesModel();
$files = $this->notesModel->getUploadedFiles($note['id']);
?> ?>
<div class="container"> <div class="container">
@ -24,6 +27,19 @@ $parsedown->setSafeMode(true);
<?php echo $parsedown->text($note['content'] ?? ''); ?> <?php echo $parsedown->text($note['content'] ?? ''); ?>
</div> </div>
<div class="note-files">
<?php if (isset($files) && count($files) > 0): ?>
<h3>Attached Files:</h3>
<ul>
<?php foreach ($files as $file): ?>
<li>
<a href="/EIANotesApp/Uploads/<?php echo $file['stored_filename']; ?>" download target="_blank"><?php echo htmlspecialchars($file['original_filename']); ?></a>
</li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
</div>
<div class="note-actions"> <div class="note-actions">
<a href="?controller=Notes&page=showNotes&do=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'])): ?>

View File

@ -25,6 +25,10 @@
<a href="?controller=Notes&do=createNote" class="button">Create New Note</a> <a href="?controller=Notes&do=createNote" class="button">Create New Note</a>
</div> </div>
<?php if (isset($errmsg)): ?>
<label class="error-message"><?php echo $errmsg; ?></label>
<?php endif; ?>
<table class="notes-table"> <table class="notes-table">
<thead> <thead>
<tr> <tr>

View File

@ -26,7 +26,14 @@ $this->userModel = new \ppa\Model\UserModel();
echo $this->userModel->getUserCount(); echo $this->userModel->getUserCount();
?> ?>
Users Users
</b> </b><br>
<b style="font-size: 20px; margin: 20px">
<?php
echo $this->notesModel->getFileCount();
?>
Files
</b><br>
<?php include dirname(__DIR__).'/footer.phtml'; ?> <?php include dirname(__DIR__).'/footer.phtml'; ?>