Compare commits
51 Commits
75742157b7
...
main
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5ef5de9b98 | ||
![]() |
92e162283e | ||
![]() |
26fb9b54b6 | ||
![]() |
b4fcc4892c | ||
![]() |
58e0f1eafd | ||
![]() |
9bca8fd1d1 | ||
bb9424232c | |||
e8766ecc26 | |||
![]() |
c5ebde8b20 | ||
![]() |
4ae6971b9c | ||
![]() |
0799db48f0 | ||
![]() |
9db4d93ce3 | ||
![]() |
aabd6288fe | ||
![]() |
48f1fb8923 | ||
ce59837500 | |||
3c9d90ebb8 | |||
![]() |
871ffe01d0 | ||
36ea386e04 | |||
31fff91725 | |||
![]() |
b92f7c1054 | ||
![]() |
6dbca7cbd4 | ||
![]() |
ba9ec6b430 | ||
63899ffa8f | |||
5c381740ff | |||
![]() |
fc17a1a312 | ||
5eb3e30114 | |||
ab757adfbd | |||
![]() |
95b7634901 | ||
![]() |
5a63cc66c5 | ||
1a5a069844 | |||
![]() |
24c8f38c4d | ||
![]() |
1e9705aa13 | ||
![]() |
df103f9b86 | ||
![]() |
5741783dbe | ||
6cceae17d0 | |||
3d4e1532c7 | |||
![]() |
80cb9f2818 | ||
![]() |
bcde6649b5 | ||
![]() |
e54a8f241e | ||
![]() |
21aa81dbd3 | ||
![]() |
7d1d48199a | ||
![]() |
d21da71585 | ||
ba55304182 | |||
032029ce7f | |||
ff1234d561 | |||
9a4626e854 | |||
![]() |
b06536baf6 | ||
![]() |
a4d6aeea18 | ||
![]() |
a2fd5f011b | ||
97137da6b9 | |||
246f0c9e5a |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
uploads
|
@@ -19,10 +19,39 @@ body {
|
||||
}
|
||||
|
||||
.top-bar h1 {
|
||||
margin: 0;
|
||||
margin: 0 30px 0 0;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.top-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.top-nav ul {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.top-nav li {
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.top-nav li a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -309,4 +338,19 @@ button.danger {
|
||||
font-size: 0.8em;
|
||||
color: #6A5ACD;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.style_low {
|
||||
background-color: darkseagreen;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.style_mid {
|
||||
background-color: moccasin;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.style_high {
|
||||
background-color: lightcoral;
|
||||
font-weight: bold;
|
||||
}
|
@@ -18,6 +18,12 @@ class NotesController
|
||||
|
||||
public function showNotes()
|
||||
{
|
||||
# Redirect zum Login wenn kein User eingeloggt ist
|
||||
if(!Isset($_SESSION['role']))
|
||||
{
|
||||
header("Location: ?controller=User&do=showUserLoginForm");
|
||||
}
|
||||
|
||||
$sortBy = $_GET['sort_by'] ?? 'updated_at';
|
||||
$sortOrder = strtoupper($_GET['sort_order'] ?? 'DESC');
|
||||
$isAdmin = $_SESSION['role'] === 'admin';
|
||||
@@ -28,4 +34,108 @@ class NotesController
|
||||
]);
|
||||
}
|
||||
|
||||
public function showNoteDetails()
|
||||
{
|
||||
$noteId = $_GET['id'];
|
||||
$note = $this->notesModel->getNoteById($noteId);
|
||||
$this->view->setVars([
|
||||
"note" => $note
|
||||
]);
|
||||
}
|
||||
|
||||
public function createNote()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// Process form submission
|
||||
$note = $this->notesModel->createNote(
|
||||
$_POST['title'],
|
||||
$_POST['content'],
|
||||
$_SESSION['user_id'],
|
||||
$_POST['priority']
|
||||
);
|
||||
|
||||
if ($note) {
|
||||
// Redirect to show notes page after successful creation
|
||||
header('Location: ?controller=Notes&page=showNotes&do=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'],
|
||||
$_POST['priority']
|
||||
);
|
||||
|
||||
if ($note) {
|
||||
// Redirect to show notes page after successful update
|
||||
header('Location: ?controller=Notes&page=showNotes&do=showNotes');
|
||||
exit();
|
||||
} else {
|
||||
// If update failed, show error message and stay on the form
|
||||
$this->view->setVars([
|
||||
'error' => 'Failed to update note. Please try again.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteNote()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['note_id'])) {
|
||||
$noteId = $_POST['note_id'];
|
||||
$this->notesModel->deleteNote($noteId, $_SESSION['user_id']);
|
||||
}
|
||||
|
||||
header("Location: ?controller=Notes&page=showNotes&do=showNotes");
|
||||
exit();
|
||||
}
|
||||
|
||||
public function fileManager()
|
||||
{
|
||||
# Redirect zum Login wenn kein User eingeloggt ist
|
||||
if(!Isset($_SESSION['role']))
|
||||
{
|
||||
header("Location: ?controller=User&do=showUserLoginForm");
|
||||
}
|
||||
# Redirect zum Welcome wenn kein User kein Admin ist
|
||||
if(!Isset($_SESSION['role']) || $_SESSION['role'] !== 'admin')
|
||||
{
|
||||
header("Location: ?controller=Welcome&do=showWelcome");
|
||||
}
|
||||
|
||||
$sortBy = $_GET['sort_by'] ?? 'uploaded_at';
|
||||
$sortOrder = strtoupper($_GET['sort_order'] ?? 'DESC');
|
||||
$isAdmin = $_SESSION['role'] === 'admin';
|
||||
$userid = $_SESSION['user_id'];
|
||||
|
||||
$files = $this->notesModel->selectFiles($userid, true, $sortBy, $sortOrder);
|
||||
$this->view->setVars([
|
||||
"files" => $files
|
||||
]);
|
||||
}
|
||||
|
||||
public function deleteFile()
|
||||
{
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['file_id'])) {
|
||||
$fileId = $_POST['file_id'];
|
||||
$this->notesModel->deleteFile($fileId, $_SESSION['user_id']);
|
||||
}
|
||||
|
||||
header("Location: ?controller=Notes&do=fileManager");
|
||||
exit();
|
||||
}
|
||||
}
|
@@ -19,14 +19,58 @@ class UserController
|
||||
|
||||
public function loginUser()
|
||||
{
|
||||
echo "test";
|
||||
//verifyLogin($_POST['username'] ?? '', $_POST['password'] ?? '')
|
||||
$erg = array();
|
||||
$erg = $this->userModel->loginUser($this->sanitize($_POST["username"]), $this->sanitize($_POST["password"]) );
|
||||
if ($erg["success"] == true) {
|
||||
header("Location: ?controller=Welcome&do=showWelcome");
|
||||
exit();
|
||||
|
||||
}
|
||||
else {
|
||||
$this->view->setDoMethodName("showUserLoginForm");
|
||||
$this->showUserLoginForm();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function logoutUser()
|
||||
{
|
||||
$this->userModel->logoutUser();
|
||||
header("Location: ?controller=User&do=showUserLoginForm");
|
||||
exit();
|
||||
}
|
||||
|
||||
public function registerUser()
|
||||
{
|
||||
$erg = array();
|
||||
$erg = $this->userModel->registerUser($this->sanitize($_POST["username"]), $this->sanitize($_POST["password"]) );
|
||||
if ($erg["success"] == true) {
|
||||
header("Location: ?controller=User&do=showUserLoginForm");
|
||||
exit();
|
||||
}
|
||||
else {
|
||||
$this->view->setDoMethodName("showUserRegisterForm");
|
||||
|
||||
$message = $this->sanitize($erg['message']);
|
||||
echo "<script type='text/javascript'>alert(\"$message\");</script>";
|
||||
$this->view->setVars([
|
||||
"errmsg" => $message
|
||||
]);
|
||||
$this->showUserRegisterForm();
|
||||
}
|
||||
}
|
||||
|
||||
public function showUserLoginForm()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function showUserRegisterForm()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
|
||||
return htmlspecialchars((string)$data, $flags, $encoding);
|
||||
}
|
||||
}
|
@@ -2,13 +2,11 @@
|
||||
|
||||
namespace ppa\Controller;
|
||||
|
||||
/**
|
||||
* Description of Welcome
|
||||
*
|
||||
* @author reich
|
||||
*/
|
||||
class WelcomeController
|
||||
{
|
||||
private $notesModel;
|
||||
private $view;
|
||||
|
||||
public function setView(\ppa\Library\View $view)
|
||||
{
|
||||
$this->view = $view;
|
||||
@@ -16,5 +14,8 @@ class WelcomeController
|
||||
|
||||
function showWelcome()
|
||||
{
|
||||
if ($this->notesModel === null) {
|
||||
$this->notesModel = new \ppa\Model\NotesModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,3 @@
|
||||
// public/script.js
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// --- Password Strength Checker for Registration ---
|
||||
const passwordInput = document.getElementById('password');
|
||||
@@ -58,60 +57,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
if(passwordInput.value) passwordInput.dispatchEvent(new Event('input'));
|
||||
}
|
||||
|
||||
// --- Delete Note Confirmation and AJAX ---
|
||||
document.querySelectorAll('.delete-note-btn').forEach(button => {
|
||||
button.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
if (confirm('Are you sure you want to delete this note?')) {
|
||||
const noteId = this.dataset.noteId;
|
||||
|
||||
// Create a temporary form to submit for delete
|
||||
const tempForm = document.createElement('form');
|
||||
tempForm.method = 'POST';
|
||||
tempForm.style.display = 'none';
|
||||
|
||||
const actionInput = document.createElement('input');
|
||||
actionInput.type = 'hidden';
|
||||
actionInput.name = 'action';
|
||||
actionInput.value = 'delete_note';
|
||||
tempForm.appendChild(actionInput);
|
||||
|
||||
const noteIdInput = document.createElement('input');
|
||||
noteIdInput.type = 'hidden';
|
||||
noteIdInput.name = 'note_id';
|
||||
noteIdInput.value = noteId;
|
||||
tempForm.appendChild(noteIdInput);
|
||||
|
||||
document.body.appendChild(tempForm); // Form must be in DOM to submit
|
||||
|
||||
// Use handleAjaxForm for consistency
|
||||
const formData = new FormData(tempForm);
|
||||
fetch('index.php', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
displayMessage(data.message, data.success ? 'success' : 'danger');
|
||||
if (data.success) {
|
||||
// Refresh page or remove row dynamically for better UX
|
||||
// For simplicity, reload. A more advanced way is to find and remove table row.
|
||||
setTimeout(() => { window.location.reload(); }, 1000);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
displayMessage('An error occurred during deletion.', 'danger');
|
||||
})
|
||||
.finally(() => {
|
||||
document.body.removeChild(tempForm); // Clean up
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// --- Drag and Drop File Upload ---
|
||||
// ... (no changes from previous, ensure it's present)
|
||||
const dropZone = document.getElementById('drop-zone');
|
||||
const noteTitleInput = document.getElementById('title');
|
||||
const noteContentInput = document.getElementById('content');
|
||||
|
@@ -12,7 +12,7 @@ class NotesModel extends Database
|
||||
$erg = array();
|
||||
|
||||
// Whitelist of allowed sort columns
|
||||
$allowedSortColumns = ['id', 'title', 'owner_username', 'updated_at'];
|
||||
$allowedSortColumns = ['id', 'title', 'owner_username', 'updated_at', 'priority'];
|
||||
$allowedSortOrders = ['ASC', 'DESC'];
|
||||
|
||||
$sortBy = in_array($sortBy, $allowedSortColumns) ? $sortBy : 'updated_at';
|
||||
@@ -20,15 +20,17 @@ class NotesModel extends Database
|
||||
|
||||
try {
|
||||
if ($isAdmin) {
|
||||
$sql = "SELECT n.*, u.username AS owner_username
|
||||
$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 users u ON n.user_id = u.id
|
||||
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 id, title, content, created_at, updated_at
|
||||
FROM notes
|
||||
$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);
|
||||
@@ -43,4 +45,252 @@ class NotesModel extends Database
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public function selectFiles($userid, $isAdmin = false, $sortBy = 'updated_at', $sortOrder = 'DESC')
|
||||
{
|
||||
$pdo = $this->linkDB();
|
||||
$erg = array();
|
||||
|
||||
// Whitelist of allowed sort columns
|
||||
$allowedSortColumns = ['id', 'original_filename', 'stored_filename', 'note_id', 'owner_username', 'uploaded_at', 'file_size'];
|
||||
$allowedSortOrders = ['ASC', 'DESC'];
|
||||
|
||||
$sortBy = in_array($sortBy, $allowedSortColumns) ? $sortBy : 'uploaded_at';
|
||||
$sortOrder = in_array(strtoupper($sortOrder), $allowedSortOrders) ? strtoupper($sortOrder) : 'DESC';
|
||||
|
||||
try {
|
||||
if ($isAdmin) {
|
||||
$sql = "SELECT f.*, n.title AS note_title, u.username AS owner_username
|
||||
FROM files f
|
||||
JOIN notes n ON f.note_id = n.id
|
||||
JOIN users u ON n.user_id = u.id
|
||||
ORDER BY {$sortBy} {$sortOrder}";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$erg = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
return $erg;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
error_log("Database Error in selectFiles: " . $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 = __DIR__ . '/../Uploads/';
|
||||
$uploadedFileNames = [];
|
||||
|
||||
if (!file_exists($uploadDir)) {
|
||||
mkdir($uploadDir, 0777, true);
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
public function deleteFile($fileId, $userId) {
|
||||
$pdo = $this->linkDB();
|
||||
if (!$pdo) return ['success' => false, 'message' => 'Database error.'];
|
||||
try {
|
||||
// Delete the local file
|
||||
$stmt = $pdo->prepare("SELECT stored_filename FROM files WHERE id = ?");
|
||||
$stmt->execute([$fileId]);
|
||||
$file = $stmt->fetch();
|
||||
if ($file) {
|
||||
$filePath = __DIR__ . '/../Uploads/' . $file['stored_filename'];
|
||||
if (file_exists($filePath)) {
|
||||
unlink($filePath);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->isAdmin()) { // Admin can delete any file
|
||||
$stmt = $pdo->prepare("DELETE FROM files WHERE id = ?");
|
||||
$params = [$fileId];
|
||||
} else { // User can only delete their own files
|
||||
$stmt = $pdo->prepare("DELETE FROM files WHERE id = ? AND note_id IN (SELECT id FROM notes WHERE user_id = ?)");
|
||||
$params = [$fileId, $userId];
|
||||
}
|
||||
$stmt->execute($params);
|
||||
|
||||
if ($stmt->rowCount() > 0) {
|
||||
return ['success' => true, 'message' => 'File deleted successfully.'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'File not found or permission denied.'];
|
||||
} catch (PDOException $e) {
|
||||
error_log("Delete File Error: " . $e->getMessage());
|
||||
return ['success' => false, 'message' => 'Failed to delete file.'];
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,12 +2,12 @@
|
||||
|
||||
namespace ppa\Model;
|
||||
use ppa\Model\ParticipantModel;
|
||||
use ppb\Library\Msg;
|
||||
//use ppb\Library\Msg;
|
||||
use PDOException;
|
||||
|
||||
class UserModel extends Database
|
||||
{
|
||||
function verifyLogin($pdo, $username, $password)
|
||||
public function loginUser($username, $password)
|
||||
{
|
||||
$pdo = $this->linkDB();
|
||||
if (!$pdo) return ['success' => false, 'message' => 'Database connection error.'];
|
||||
@@ -20,7 +20,7 @@ class UserModel extends Database
|
||||
$_SESSION['user_id'] = $user['id'];
|
||||
$_SESSION['username'] = $user['username'];
|
||||
$_SESSION['role'] = $user['role']; // Store role
|
||||
return ['success' => true, 'message' => 'Login successful!', 'redirect' => showNotes()];
|
||||
return ['success' => true, 'message' => 'Login successful!'];
|
||||
}
|
||||
return ['success' => false, 'message' => 'Invalid username or password.'];
|
||||
} catch (PDOException $e) {
|
||||
@@ -28,4 +28,58 @@ class UserModel extends Database
|
||||
return ['success' => false, 'message' => 'An error occurred during login.'];
|
||||
}
|
||||
}
|
||||
|
||||
function logoutUser()
|
||||
{
|
||||
session_unset();
|
||||
session_destroy();
|
||||
return ['success' => true, 'message' => 'Logged out successfully.'];
|
||||
}
|
||||
|
||||
|
||||
function registerUser($username, $password) {
|
||||
$pdo = $this->linkDB();
|
||||
if (!$pdo) return ['success' => false, 'message' => 'Database connection error.'];
|
||||
$errors = [];
|
||||
if (empty($username)) $errors[] = "Username is required.";
|
||||
if (empty($password)) $errors[] = "Password is required.";
|
||||
if (strlen($password) < 8) $errors[] = "Password must be at least 8 characters.";
|
||||
if (!preg_match('/[A-Z]/', $password)) $errors[] = "Password needs an uppercase letter.";
|
||||
if (!preg_match('/[a-z]/', $password)) $errors[] = "Password needs a lowercase letter.";
|
||||
if (!preg_match('/[0-9]/', $password)) $errors[] = "Password needs a number.";
|
||||
if (!preg_match('/[^A-Za-z0-9]/', $password)) $errors[] = "Password needs a special character.";
|
||||
|
||||
if (!empty($errors)) {
|
||||
return ['success' => false, 'message' => implode("\\n", $errors)];
|
||||
}
|
||||
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?");
|
||||
$stmt->execute([$username]);
|
||||
if ($stmt->fetch()) {
|
||||
return ['success' => false, 'message' => 'Username already taken.'];
|
||||
}
|
||||
|
||||
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
||||
$stmt = $pdo->prepare("INSERT INTO users (username, password) VALUES (?, ?)"); // Role defaults to 'user'
|
||||
$stmt->execute([$username, $hashedPassword]);
|
||||
return ['success' => true, 'message' => 'Registration successful! Please login.'];
|
||||
} catch (PDOException $e) {
|
||||
error_log("Registration Error: " . $e->getMessage());
|
||||
return ['success' => false, 'message' => 'An error occurred during registration.'];
|
||||
}
|
||||
}
|
||||
|
||||
function getUserCount() {
|
||||
$pdo = $this->linkDB();
|
||||
if (!$pdo) return 0;
|
||||
try {
|
||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM users");
|
||||
$stmt->execute();
|
||||
return $stmt->fetchColumn();
|
||||
} catch (PDOException $e) {
|
||||
error_log("Get User Count Error: " . $e->getMessage());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
85
Views/Notes/createNote.phtml
Normal file
85
Views/Notes/createNote.phtml
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
use ppa\Model\NotesModel;
|
||||
include dirname(__DIR__).'/header.phtml';
|
||||
|
||||
//// Test write permissions
|
||||
//// This is the directory we will upload files to.
|
||||
//$uploadDir = __DIR__ . '/../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->setSafeMode(true);
|
||||
|
||||
$this->notesModel = new \ppa\Model\NotesModel();
|
||||
|
||||
$note = null;
|
||||
|
||||
function isLoggedIn() {
|
||||
return isset($_SESSION['user_id']);
|
||||
}
|
||||
|
||||
function isAdmin() {
|
||||
return 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>Create New Note</h2>
|
||||
<a href="?controller=Notes&page=showNotes&do=showNotes" class="button secondary">Cancel</a>
|
||||
</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>
|
||||
|
||||
<form id="note-form" method="POST" enctype="multipart/form-data">
|
||||
<input type="hidden" name="action" value="create_note">
|
||||
<div class="form-group">
|
||||
<label for="title">Title:</label>
|
||||
<input type="text" id="title" name="title" value="" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="content">Content (Markdown supported):</label>
|
||||
<textarea id="content" name="content" rows="10" required></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Live Markdown Preview:</label>
|
||||
<div id="markdown-preview" class="markdown-preview">
|
||||
Start typing or drop a file to see preview...
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Priorität:</label>
|
||||
<select name="priority" id="priority">
|
||||
<option value="1">LOW</option>
|
||||
<option value="2">MID</option>
|
||||
<option value="3">HIGH</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="attachments">Attach Files:</label>
|
||||
<input type="file" id="attachments" name="attachments[]" multiple>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="button">Create Note</button>
|
||||
</div>
|
||||
<input type="hidden" name="controller" value="Notes">
|
||||
<input type="hidden" name="do" value="createNote">
|
||||
</form>
|
||||
|
||||
</div>
|
89
Views/Notes/editNote.phtml
Normal file
89
Views/Notes/editNote.phtml
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
use ppa\Model\NotesModel;
|
||||
include dirname(__DIR__).'/header.phtml';
|
||||
|
||||
$parsedown = new Parsedown();
|
||||
$parsedown->setSafeMode(true);
|
||||
|
||||
$this->notesModel = new \ppa\Model\NotesModel();
|
||||
|
||||
$note = null;
|
||||
$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>";
|
||||
}
|
||||
|
||||
$files = $this->notesModel->getUploadedFiles($noteId);
|
||||
|
||||
function isLoggedIn() {
|
||||
return isset($_SESSION['user_id']);
|
||||
}
|
||||
|
||||
function isAdmin() {
|
||||
return 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 'Edit Note' . (isAdmin() && $note && $note['user_id'] != $_SESSION['user_id'] ? ' (Admin Edit - Owner: '.sanitize($note['owner_username']).')' : '') ?></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" enctype="multipart/form-data">
|
||||
<input type="hidden" name="action" value="update_note">
|
||||
<input type="hidden" name="note_id" value="<?php echo sanitize($note['id']); ?>">
|
||||
<div class="form-group">
|
||||
<label for="title">Title:</label>
|
||||
<input type="text" id="title" name="title" value="<?php echo $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 $note ? sanitize($note['content']) : ''; ?></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Live Markdown Preview:</label>
|
||||
<div id="markdown-preview" class="markdown-preview">
|
||||
<?php if($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-group">
|
||||
<label>Priorität:</label>
|
||||
<select name="priority" id="priority">
|
||||
<option value="1">LOW</option>
|
||||
<option value="2">MID</option>
|
||||
<option value="3">HIGH</option>
|
||||
</select>
|
||||
</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="<?php echo substr($_SERVER['PHP_SELF'], 0, -9).'Uploads/'.$file['stored_filename']; ?>" download target="_blank"><?php echo htmlspecialchars($file['original_filename']); ?></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="button">Update Note</button>
|
||||
</div>
|
||||
<input type="hidden" name="controller" value="Notes">
|
||||
<input type="hidden" name="do" value="editNote">
|
||||
</form>
|
||||
</div>
|
64
Views/Notes/fileManager.phtml
Normal file
64
Views/Notes/fileManager.phtml
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php include dirname(__DIR__).'/header.phtml'; ?>
|
||||
|
||||
<div class="container">
|
||||
<?php
|
||||
function isLoggedIn() {
|
||||
return isset($_SESSION['user_id']);
|
||||
}
|
||||
|
||||
function isAdmin() {
|
||||
return isLoggedIn() && isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
|
||||
}
|
||||
|
||||
function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
|
||||
return htmlspecialchars((string)$data, $flags, $encoding);
|
||||
}
|
||||
|
||||
$sortBy = $_GET['sort_by'] ?? 'uploaded_at';
|
||||
$sortOrder = strtoupper($_GET['sort_order'] ?? 'DESC'); // Ensure uppercase for comparison
|
||||
?>
|
||||
<div class="page-header">
|
||||
<h2>All Users' Files</h2>
|
||||
</div>
|
||||
|
||||
<?php if (isset($errmsg)): ?>
|
||||
<label class="error-message"><?php echo $errmsg; ?></label>
|
||||
<?php endif; ?>
|
||||
|
||||
<table class="notes-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-sort="id">File ID <span class="sort-icon"><?php if($sortBy === 'id') echo $sortOrder === 'ASC' ? '▲' : '▼'; ?></span></th>
|
||||
<th data-sort="original_filename">Original File Name <span class="sort-icon"><?php if($sortBy === 'original_filename') echo $sortOrder === 'ASC' ? '▲' : '▼'; ?></span></th>
|
||||
<th data-sort="stored_filename">Stored File Name <span class="sort-icon"><?php if($sortBy === 'stored_filename') echo $sortOrder === 'ASC' ? '▲' : '▼'; ?></span></th>
|
||||
<th data-sort="note_id">Note ID <span class="sort-icon"><?php if($sortBy === 'note_id') echo $sortOrder === 'ASC' ? '▲' : '▼'; ?></span></th>
|
||||
<th data-sort="owner_username">Owner <span class="sort-icon"><?php if($sortBy === 'owner_username') echo $sortOrder === 'ASC' ? '▲' : '▼'; ?></span></th>
|
||||
<th data-sort="uploaded_at">Uploaded At <span class="sort-icon"><?php if($sortBy === 'uploaded_at') echo $sortOrder === 'ASC' ? '▲' : '▼'; ?></span></th>
|
||||
<th data-sort="file_size">File Size <span class="sort-icon"><?php if($sortBy === 'file_size') echo $sortOrder === 'ASC' ? '▲' : '▼'; ?></span></th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($files as $file): ?>
|
||||
<tr>
|
||||
<td><?php echo sanitize($file['id']); ?></td>
|
||||
<td><a href="<?php echo substr($_SERVER['PHP_SELF'], 0, -9).'Uploads/'.$file['stored_filename']; ?>"><?php echo sanitize($file['stored_filename']); ?></a></td>
|
||||
<td><?php echo sanitize($file['stored_filename']); ?></td>
|
||||
<td><?php echo sanitize($file['note_id']); ?></td>
|
||||
<td><?php echo sanitize($file['owner_username']); ?></td>
|
||||
<td><?php echo date("d.m.Y H:i", strtotime($file['uploaded_at'])); ?></td>
|
||||
<td><?php echo round(sanitize($file['file_size']) / 1024, 2) . ' KB'; ?></td>
|
||||
<td class="actions-cell">
|
||||
<form method="POST" action="?controller=Notes&do=deleteFile" onsubmit="return confirm('Are you sure you want to delete this file?');" style="display: inline;">
|
||||
<input type="hidden" name="file_id" value="<?php echo $file['id']; ?>">
|
||||
<button type="submit" class="button danger">Delete</button>
|
||||
<input type="hidden" name="controller" value="Notes">
|
||||
<input type="hidden" name="do" value="deleteFile">
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php include dirname(__DIR__).'/footer.phtml'; ?>
|
59
Views/Notes/showNoteDetails.phtml
Normal file
59
Views/Notes/showNoteDetails.phtml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php include dirname(__DIR__).'/header.phtml'; ?>
|
||||
|
||||
<?php
|
||||
$parsedown = new Parsedown();
|
||||
$parsedown->setSafeMode(true);
|
||||
|
||||
$this->notesModel = new \ppa\Model\NotesModel();
|
||||
$files = $this->notesModel->getUploadedFiles($note['id']);
|
||||
?>
|
||||
|
||||
<div class="container">
|
||||
<?php if (isset($note) && $note): ?>
|
||||
<div class="note-details">
|
||||
<div class="note-header">
|
||||
<h2><?php echo htmlspecialchars($note['title'] ?? ''); ?></h2>
|
||||
<div class="note-meta">
|
||||
<?php if (($isAdmin ?? false) && isset($note['owner_username'])): ?>
|
||||
<span class="note-owner">Owner: <?php echo htmlspecialchars($note['owner_username']); ?></span>
|
||||
<?php endif; ?>
|
||||
<span class="note-date">
|
||||
Last updated: <?php echo isset($note['updated_at']) ? date("d.m.Y H:i", strtotime($note['updated_at'])) : 'N/A'; ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="note-content">
|
||||
<?php echo $parsedown->text($note['content'] ?? ''); ?>
|
||||
</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="<?php echo substr($_SERVER['PHP_SELF'], 0, -9).'Uploads/'.$file['stored_filename']; ?>" download target="_blank"><?php echo htmlspecialchars($file['original_filename']); ?></a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="note-actions">
|
||||
<a href="?controller=Notes&page=showNotes&do=showNotes" class="button">Back to Notes</a>
|
||||
<?php if (isset($note['id'])): ?>
|
||||
<a href="?controller=Notes&do=editNote&id=<?php echo (int)$note['id']; ?>" class="button">Edit Note</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="error-message">
|
||||
<h2>Note Not Found</h2>
|
||||
<p><?php echo htmlspecialchars($error ?? 'The requested note could not be found.'); ?></p>
|
||||
<a href="?controller=Notes&page=showNotes&do=showNotes" class="button">Back to Notes</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php include dirname(__DIR__).'/footer.phtml'; ?>
|
@@ -1,7 +1,5 @@
|
||||
<?php include dirname(__DIR__).'/header.phtml'; ?>
|
||||
|
||||
<h2>Notes</h2>
|
||||
|
||||
<div class="container">
|
||||
<?php
|
||||
$parsedown = new Parsedown();
|
||||
@@ -12,8 +10,9 @@
|
||||
}
|
||||
|
||||
function isAdmin() {
|
||||
return false;// isLoggedIn() && isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
|
||||
return isLoggedIn() && isset($_SESSION['role']) && $_SESSION['role'] === 'admin';
|
||||
}
|
||||
|
||||
function sanitize($data, $flags = ENT_QUOTES, $encoding = 'UTF-8') {
|
||||
return htmlspecialchars((string)$data, $flags, $encoding);
|
||||
}
|
||||
@@ -21,6 +20,15 @@
|
||||
$sortBy = $_GET['sort_by'] ?? 'updated_at';
|
||||
$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>
|
||||
|
||||
<?php if (isset($errmsg)): ?>
|
||||
<label class="error-message"><?php echo $errmsg; ?></label>
|
||||
<?php endif; ?>
|
||||
|
||||
<table class="notes-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -31,6 +39,7 @@
|
||||
<?php endif; ?>
|
||||
<th>Content (Preview)</th>
|
||||
<th data-sort="updated_at">Last Edited <span class="sort-icon"><?php if($sortBy === 'updated_at') echo $sortOrder === 'ASC' ? '▲' : '▼'; ?></span></th>
|
||||
<th data-sort="priority">Priority<span class="sort-icon"><?php if($sortBy === 'priority') echo $sortOrder === 'ASC' ? '▲' : '▼'; ?></span></th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -38,7 +47,7 @@
|
||||
<?php foreach ($notes as $note): ?>
|
||||
<tr>
|
||||
<td><?php echo sanitize($note['id']); ?></td>
|
||||
<td><a href="index.php?page=view_note&id=<?php echo $note['id']; ?>"><?php echo sanitize($note['title']); ?></a></td>
|
||||
<td><a href="?controller=Notes&do=showNoteDetails&id=<?php echo $note['id']; ?>"><?php echo sanitize($note['title']); ?></a></td>
|
||||
<?php if (isAdmin()): ?>
|
||||
<td><?php echo sanitize($note['owner_username']); ?></td>
|
||||
<?php endif; ?>
|
||||
@@ -50,9 +59,21 @@
|
||||
?>
|
||||
</td>
|
||||
<td><?php echo date("d.m.Y H:i", strtotime($note['updated_at'])); ?></td>
|
||||
<?php
|
||||
if($note['priority'] === 'LOW') echo ('<td class="style_low";>');
|
||||
elseif($note['priority'] === 'MID') echo ('<td class="style_mid";>');
|
||||
elseif($note['priority'] === 'HIGH') echo ('<td class="style_high";>');
|
||||
echo sanitize($note['priority']);
|
||||
echo ('</td>')
|
||||
?>
|
||||
<td class="actions-cell">
|
||||
<a href="index.php?page=edit_note&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>
|
||||
<a href="?controller=Notes&do=editNote&id=<?php echo $note['id']; ?>" class="button">Edit</a>
|
||||
<form method="POST" action="?controller=Notes&do=deleteNote" onsubmit="return confirm('Are you sure you want to delete this note?');" style="display: inline;">
|
||||
<input type="hidden" name="note_id" value="<?php echo $note['id']; ?>">
|
||||
<button type="submit" class="button danger">Delete</button>
|
||||
<input type="hidden" name="controller" value="Notes">
|
||||
<input type="hidden" name="do" value="deleteNote">
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
@@ -1,5 +1,4 @@
|
||||
<?php include dirname(__DIR__).'/header.phtml'; ?>
|
||||
<script src="JavaScript/script.js"></script>
|
||||
<?php include dirname(__DIR__).'/header.phtml'; ?>
|
||||
<div class="form-container">
|
||||
<h2>Login</h2>
|
||||
<form id="login-form" method="POST">
|
||||
@@ -13,10 +12,15 @@
|
||||
<input type="password" id="password" name="password" required>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
|
||||
<button type="submit" href="?controller=User&do=loginUser">Login</button>
|
||||
<p style="margin-top:15px; text-align:center;">Don't have an account? <a href="index.php?page=register">Register here</a></p>
|
||||
</div>
|
||||
<button type="submit">Login</button>
|
||||
<label><?php if (isset($errmsg)):?>
|
||||
<?php echo $errmsg;?>
|
||||
<?php endif; ?>
|
||||
</label>
|
||||
<p style="margin-top:15px; text-align:center;">Don't have an account? <a href="?controller=User&do=showUserRegisterForm">Register here</a></p>
|
||||
</div>
|
||||
<input type="hidden" name="controller" value="User">
|
||||
<input type="hidden" name="do" value="loginUser">
|
||||
</form>
|
||||
</div>
|
||||
<?php include dirname(__DIR__).'/footer.phtml'; ?>
|
28
Views/User/showUserRegisterForm.phtml
Normal file
28
Views/User/showUserRegisterForm.phtml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php include dirname(__DIR__).'/header.phtml'; ?>
|
||||
<div class="form-container">
|
||||
<h2>Register</h2>
|
||||
<form id="register-form" method="POST">
|
||||
<input type="hidden" name="action" value="register">
|
||||
<div class="form-group">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" id="username" name="username" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Password:</label>
|
||||
<input type="password" id="password" name="password" required>
|
||||
<div class="password-strength-meter"><div id="strength-bar"></div></div>
|
||||
<div id="password-strength"><ul></ul></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="confirm_password">Confirm Password:</label>
|
||||
<input type="password" id="confirm_password" name="confirm_password" required>
|
||||
</div>
|
||||
<div class="form-actions">
|
||||
<button type="submit" >Register</button>
|
||||
<p style="margin-top:15px; text-align:center;">Already have an account? <a href="?controller=User&do=showUserLoginForm">Login here</a></p>
|
||||
</div>
|
||||
<input type="hidden" name="controller" value="User">
|
||||
<input type="hidden" name="do" value="registerUser">
|
||||
</form>
|
||||
</div>
|
||||
<?php include dirname(__DIR__).'/footer.phtml'; ?>
|
@@ -1,6 +1,39 @@
|
||||
<?php include dirname(__DIR__).'/header.phtml'; ?>
|
||||
<?php
|
||||
use ppa\Model\NotesModel;
|
||||
include dirname(__DIR__).'/header.phtml';
|
||||
|
||||
$parsedown = new Parsedown();
|
||||
$parsedown->setSafeMode(true);
|
||||
|
||||
$this->notesModel = new \ppa\Model\NotesModel();
|
||||
$this->userModel = new \ppa\Model\UserModel();
|
||||
?>
|
||||
|
||||
<h2>Welcome in out Notes App!</h2>
|
||||
|
||||
<p>To start, simply select an option in the navigation bar.</p>
|
||||
|
||||
<h2>Notes App statistics</h2>
|
||||
<b style="font-size: 20px; margin: 20px">
|
||||
<?php
|
||||
echo $this->notesModel->getNoteCount();
|
||||
?>
|
||||
Notes
|
||||
</b><br>
|
||||
|
||||
<b style="font-size: 20px; margin: 20px">
|
||||
<?php
|
||||
echo $this->userModel->getUserCount();
|
||||
?>
|
||||
Users
|
||||
</b><br>
|
||||
|
||||
<b style="font-size: 20px; margin: 20px">
|
||||
<?php
|
||||
echo $this->notesModel->getFileCount();
|
||||
?>
|
||||
Files
|
||||
</b><br>
|
||||
|
||||
<h2>Baustelle</h2>
|
||||
|
||||
<?php include dirname(__DIR__).'/footer.phtml'; ?>
|
||||
|
||||
|
@@ -5,22 +5,40 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<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>
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="wrapper">
|
||||
<div class="button">
|
||||
<a href="?controller=User&do=showUserLoginForm">Anmelden</a>
|
||||
<header class="top-bar">
|
||||
<h1>Notes App <?php if(isset($_SESSION['role']) && $_SESSION['role'] === 'admin') echo "<span style='font-size:0.7em; color:#ffdd57;'>(Admin Panel)</span>"; ?></h1>
|
||||
|
||||
<nav class="top-nav">
|
||||
<ul>
|
||||
<li><a href="?controller=Welcome&do=showWelcome">Welcome!</a></li>
|
||||
<li><a href="?controller=Notes&do=showNotes">Notes</a></li>
|
||||
<?php if (isset($_SESSION['role']) && $_SESSION['role'] === 'admin'): ?>
|
||||
<li><a href="?controller=Notes&do=fileManager">File Manager</a></li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<?php if (isset($_SESSION['user_id'])): ?>
|
||||
<div class="user-info">
|
||||
<span>Welcome, <?php echo htmlspecialchars($_SESSION['username'], ENT_QUOTES, 'UTF-8'); ?>!</span>
|
||||
<form id="logout-form" method="POST" style="display: inline;">
|
||||
<a class="icon-button" href="?controller=User&do=logoutUser">→</a>
|
||||
</form>
|
||||
</div>
|
||||
<h1>Notes<span>.de</span></h1>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="user-info">
|
||||
<?php if (!isset($_SESSION['user_id'])): ?>
|
||||
<a href="?controller=User&do=showUserLoginForm">Login</a>
|
||||
<?php endif; ?>
|
||||
<?php if (!isset($_SESSION['user_id'])): ?>
|
||||
<a href="?controller=User&do=showUserRegisterForm">Register</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
<nav>
|
||||
<ul>
|
||||
<li><a href="?controller=Welcome&do=showWelcome">Willkommen</a></li>
|
||||
<li><a href="?controller=Notes&do=showNotes">Notizen</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="wrapper">
|
||||
<main>
|
Reference in New Issue
Block a user