Compare commits
15 Commits
652bcc5474
...
bugs
| Author | SHA1 | Date | |
|---|---|---|---|
| c22853d802 | |||
| 4abc5f4167 | |||
| 9f4343cc53 | |||
| a5998cffca | |||
| 153a612ad6 | |||
| 437da98add | |||
| a4b0dfe7ec | |||
| 3a819d6ed2 | |||
| 4f4ad9599d | |||
| d9da018ac2 | |||
| 2148ba75f3 | |||
| c4ffc1c797 | |||
| 96f38ce72e | |||
| b81f0c9e5c | |||
| f8aed4283e |
Generated
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="dataSourceStorageLocal" created-in="IU-261.25134.95">
|
||||
<component name="dataSourceStorageLocal" created-in="IU-253.32098.101">
|
||||
<data-source name="articles" uuid="315cb5c9-2b0f-435b-b602-59823b160908">
|
||||
<database-info product="SQLite" version="3.51.1" jdbc-version="4.2" driver-name="SQLite JDBC" driver-version="3.51.1.0" dbms="SQLITE" exact-version="3.51.1" exact-driver-version="3.51">
|
||||
<identifier-quote-string>"</identifier-quote-string>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<?php
|
||||
include_once 'php/controller/profile-controller.php';
|
||||
|
||||
$user = $user ?? null;
|
||||
$isEditMode = (isset($_GET["edit"]) && $_GET["edit"] === "1") || !empty($error);
|
||||
|
||||
+40
-2
@@ -5,6 +5,30 @@ $repliesByParent = [];
|
||||
$articleObj = null;
|
||||
|
||||
include_once 'php/controller/showArticle-controller.php';
|
||||
require_once 'php/model/UserManager.php';
|
||||
|
||||
$userManager = UserManager::getInstance();
|
||||
|
||||
/**
|
||||
* Liefert den vollständigen Namen zu einer gespeicherten E-Mail-Adresse.
|
||||
* Falls kein Benutzer gefunden wird, wird die E-Mail als Ersatz angezeigt.
|
||||
*/
|
||||
function getCommentAuthorName($email, $userManager)
|
||||
{
|
||||
$email = trim($email);
|
||||
$user = $userManager->findUser($email);
|
||||
|
||||
if ($user === null) {
|
||||
return $email;
|
||||
}
|
||||
|
||||
$vorname = trim($user["vorname"] ?? "");
|
||||
$nachname = trim($user["nachname"] ?? "");
|
||||
|
||||
$fullName = trim($vorname . " " . $nachname);
|
||||
|
||||
return $fullName !== "" ? $fullName : $email;
|
||||
}
|
||||
/*
|
||||
* Ermittelt, ob ohne JavaScript auf einen Kommentar
|
||||
* geantwortet werden soll.
|
||||
@@ -178,7 +202,14 @@ if ($replyAuthor === null) {
|
||||
|
||||
<p>
|
||||
<strong>
|
||||
<?php echo htmlspecialchars($comment->getAuthor()); ?>
|
||||
<?php
|
||||
echo htmlspecialchars(
|
||||
getCommentAuthorName(
|
||||
$comment->getAuthor(),
|
||||
$userManager
|
||||
)
|
||||
);
|
||||
?>
|
||||
</strong>
|
||||
|
||||
<span>
|
||||
@@ -313,7 +344,14 @@ if ($replyAuthor === null) {
|
||||
|
||||
<p>
|
||||
<strong>
|
||||
<?php echo htmlspecialchars($reply->getAuthor()); ?>
|
||||
<?php
|
||||
echo htmlspecialchars(
|
||||
getCommentAuthorName(
|
||||
$reply->getAuthor(),
|
||||
$userManager
|
||||
)
|
||||
);
|
||||
?>
|
||||
</strong>
|
||||
|
||||
<span>
|
||||
|
||||
+194
-5
@@ -154,21 +154,32 @@ h1 {
|
||||
|
||||
.button {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
padding: 14px;
|
||||
background-color: #2563eb;
|
||||
color: white;
|
||||
border: none;
|
||||
border: 2px solid transparent;
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s, transform 0.2s, box-shadow 0.2s;
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease,
|
||||
border-color 0.2s ease;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background-color: #1e40af;
|
||||
border-color: #93c5fd;
|
||||
transform: translateY(-3px) scale(1.01);
|
||||
box-shadow: 0 8px 18px rgba(37, 99, 235, 0.35);
|
||||
}
|
||||
|
||||
.button:active {
|
||||
background-color: #1d4ed8;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 10px rgba(0,0,0,0.15);
|
||||
transform: translateY(1px) scale(0.99);
|
||||
box-shadow: 0 2px 5px rgba(37, 99, 235, 0.25);
|
||||
}
|
||||
|
||||
.register-link {
|
||||
@@ -225,4 +236,182 @@ h1 {
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* Deutlichere Klickreaktion für Kategorien */
|
||||
.category-link:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Sichtbare Tastatur-Markierung */
|
||||
.button:focus-visible,
|
||||
.category-link:focus-visible,
|
||||
.article-link a:focus-visible,
|
||||
.register-link a:focus-visible {
|
||||
outline: 3px solid #fbbf24;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
/* Kommentarbereich */
|
||||
|
||||
#comments-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
#comments-list > div,
|
||||
.comment {
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #dbe3ec;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease,
|
||||
border-color 0.2s ease;
|
||||
}
|
||||
|
||||
#comments-list > div:hover,
|
||||
.comment:hover {
|
||||
transform: translateY(-3px);
|
||||
border-color: #93c5fd;
|
||||
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
|
||||
#comments-list textarea,
|
||||
#comment-content {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 14px;
|
||||
border: 1px solid #cbd5e1;
|
||||
border-radius: 8px;
|
||||
font-size: 1rem;
|
||||
resize: vertical;
|
||||
transition:
|
||||
border-color 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
#comments-list textarea:focus,
|
||||
#comment-content:focus {
|
||||
outline: none;
|
||||
border-color: #2563eb;
|
||||
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.18);
|
||||
}
|
||||
|
||||
#comments-list a {
|
||||
color: #2563eb;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
transition:
|
||||
color 0.2s ease,
|
||||
background-color 0.2s ease;
|
||||
}
|
||||
|
||||
#comments-list a:hover {
|
||||
color: #1e40af;
|
||||
background-color: #dbeafe;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#comments-list button {
|
||||
cursor: pointer;
|
||||
}
|
||||
.delete-comment-button {
|
||||
display: inline-block;
|
||||
background: #ffffff;
|
||||
color: #dc2626;
|
||||
border: 2px solid #dc2626;
|
||||
border-radius: 8px;
|
||||
padding: 10px 18px;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition:
|
||||
background-color 0.25s ease,
|
||||
color 0.25s ease,
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.delete-comment-button:hover {
|
||||
background: #dc2626;
|
||||
color: #ffffff;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 6px 14px rgba(220,38,38,0.25);
|
||||
}
|
||||
|
||||
.delete-comment-button:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: none;
|
||||
}
|
||||
.delete-comment-form {
|
||||
margin-top: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
/* Button zum Öffnen der Kommentarbearbeitung */
|
||||
.edit-comment-button {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
padding: 10px 18px;
|
||||
background-color: #2563eb;
|
||||
color: #ffffff;
|
||||
border: 2px solid #2563eb;
|
||||
border-radius: 8px;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
border-color 0.2s ease,
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
/* Entfernt das normale Dreieck in einigen Browsern */
|
||||
.edit-comment-button::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Eigenes Symbol vor dem Text */
|
||||
.edit-comment-button::before {
|
||||
content: "✏ ";
|
||||
}
|
||||
|
||||
.edit-comment-button:hover {
|
||||
background-color: #1e40af;
|
||||
border-color: #1e40af;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 5px 12px rgba(37, 99, 235, 0.3);
|
||||
}
|
||||
|
||||
.edit-comment-button:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.edit-comment-button:focus-visible {
|
||||
outline: 3px solid #fbbf24;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
/* Abstand zwischen Bearbeiten und Löschen */
|
||||
.edit-comment-details {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
/* Geöffneter Bearbeitungsbereich */
|
||||
.edit-comment-details[open] .edit-comment-button {
|
||||
margin-bottom: 12px;
|
||||
background-color: #1e40af;
|
||||
}
|
||||
|
||||
/* Geändertes Symbol, wenn der Bereich geöffnet ist */
|
||||
.edit-comment-details[open] .edit-comment-button::before {
|
||||
content: "▲ ";
|
||||
}
|
||||
+86
-2
@@ -248,7 +248,7 @@ CSS für die navbar
|
||||
z-index: 1000;
|
||||
transition: left 0.3s ease;
|
||||
padding: 2rem 1rem;
|
||||
box-shadow: 2px 0 10px rgba(0,0,0,0.5);
|
||||
box-shadow: 2px 0 10px rgba(0, 0, 0, 0.5);
|
||||
overflow-y: auto;
|
||||
|
||||
/* Genug Abstand oben rechts, damit Links nicht hinter dem X liegen */
|
||||
@@ -328,5 +328,89 @@ CSS für die navbar
|
||||
padding: 0.8rem 1rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
/* Deutlichere Hover-Effekte für die Navigation */
|
||||
|
||||
}
|
||||
.nav__dropdown-toggle,
|
||||
.nav__link {
|
||||
border-radius: 6px;
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
color 0.2s ease,
|
||||
transform 0.2s ease;
|
||||
}
|
||||
|
||||
.nav__dropdown-toggle:hover,
|
||||
.nav__link:hover {
|
||||
background-color: #ffffff;
|
||||
color: #1d4ed8;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Sichtbare Reaktion beim Anklicken */
|
||||
.nav__dropdown-toggle:active,
|
||||
.nav__link:active {
|
||||
transform: translateY(1px);
|
||||
}
|
||||
|
||||
/* Deutlichere Effekte für Anmelden, Registrieren usw. */
|
||||
.nav__button {
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
color 0.2s ease,
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.nav__button:hover {
|
||||
background-color: #2563eb;
|
||||
color: #ffffff;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.nav__button:active {
|
||||
transform: translateY(1px);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* Deutlichere Hervorhebung der Einträge im Dropdown-Menü */
|
||||
.nav__dropdown-menu a {
|
||||
display: block;
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
color 0.2s ease,
|
||||
padding-left 0.2s ease;
|
||||
}
|
||||
|
||||
.nav__dropdown-menu a:hover {
|
||||
background-color: #dbeafe;
|
||||
color: #1d4ed8;
|
||||
padding-left: 1.4rem;
|
||||
}
|
||||
|
||||
/* Effekt für den Suchbutton */
|
||||
.nav__search-button {
|
||||
transition:
|
||||
background-color 0.2s ease,
|
||||
color 0.2s ease,
|
||||
transform 0.2s ease;
|
||||
}
|
||||
|
||||
.nav__search-button:hover {
|
||||
background-color: #2563eb;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.nav__search-button:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
/* Sichtbare Markierung bei Tastaturbedienung */
|
||||
.nav a:focus-visible,
|
||||
.nav button:focus-visible,
|
||||
.nav input:focus-visible,
|
||||
.nav label:focus-visible {
|
||||
outline: 3px solid #fbbf24;
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ if (session_status() === PHP_SESSION_NONE) {
|
||||
}
|
||||
|
||||
require_once "../model/CommentManager.php";
|
||||
require_once "../model/UserManager.php";
|
||||
require_once "../model/ArticleManager.php";
|
||||
require_once "../../includes/csrf.php";
|
||||
|
||||
@@ -211,13 +212,29 @@ try {
|
||||
$parentCommentId
|
||||
);
|
||||
|
||||
$userManager = UserManager::getInstance();
|
||||
$user = $userManager->findUser($_SESSION["user_email"]);
|
||||
|
||||
$authorName = $_SESSION["user_email"];
|
||||
|
||||
if ($user !== null) {
|
||||
$vorname = trim($user["vorname"] ?? "");
|
||||
$nachname = trim($user["nachname"] ?? "");
|
||||
|
||||
$fullName = trim($vorname . " " . $nachname);
|
||||
|
||||
if ($fullName !== "") {
|
||||
$authorName = $fullName;
|
||||
}
|
||||
}
|
||||
|
||||
sendCommentResponse(
|
||||
true,
|
||||
"Der Kommentar wurde erfolgreich gespeichert.",
|
||||
$articleId,
|
||||
[
|
||||
"commentId" => $commentId,
|
||||
"author" => $_SESSION["user_email"],
|
||||
"author" => $authorName,
|
||||
"content" => $content,
|
||||
"created" => date("Y-m-d H:i:s"),
|
||||
"parentCommentId" => $parentCommentId
|
||||
|
||||
@@ -20,6 +20,8 @@ if ($pfad === "login") {
|
||||
include_once "php/controller/confirm-register-controller.php";
|
||||
} elseif ($pfad === "confirm-password") {
|
||||
include_once "php/controller/confirm-password-controller.php";
|
||||
} elseif ($pfad === "profile") {
|
||||
include_once "php/controller/profile-controller.php";
|
||||
} elseif ($pfad === "updateComment") {
|
||||
include_once "php/controller/updateComment-controller.php";
|
||||
} elseif($pfad === "deleteComment") {
|
||||
|
||||
@@ -76,10 +76,6 @@ class DatabaseArticleManager implements ArticleManagerDAO {
|
||||
return intval($db->lastInsertId());
|
||||
|
||||
} catch (PDOException $e) {
|
||||
// NEU: Die rohe PDO-Fehlermeldung wird nicht mehr direkt in die
|
||||
// eigene Exception übernommen (Kapselung), sondern durch eine
|
||||
// generische, sprechende Meldung ersetzt - analog zu den übrigen
|
||||
// Methoden dieser Klasse und zu DatabaseUserManager.
|
||||
throw new InternalServerErrorException("internal_error");
|
||||
}
|
||||
}
|
||||
@@ -284,10 +280,10 @@ class DatabaseArticleManager implements ArticleManagerDAO {
|
||||
$db = $this->getConnection();
|
||||
|
||||
$sql = "SELECT id, title, content, author, category, tags, created
|
||||
FROM articles
|
||||
WHERE title LIKE :keyword
|
||||
OR content LIKE :keyword
|
||||
OR tags LIKE :keyword";
|
||||
FROM articles
|
||||
WHERE title LIKE :keyword
|
||||
OR content LIKE :keyword
|
||||
OR tags LIKE :keyword;";
|
||||
|
||||
$command = $db->prepare($sql);
|
||||
|
||||
@@ -302,10 +298,11 @@ class DatabaseArticleManager implements ArticleManagerDAO {
|
||||
$filteredArticles = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$likes = $this->getLikesForArticle(intval($row['id']));
|
||||
$articleId = intval($row['id']);
|
||||
$likes = $this->getLikesForArticle($articleId);
|
||||
|
||||
$filteredArticles[] = new Article(
|
||||
intval($row['id']),
|
||||
$articleId,
|
||||
$row['title'] ?? '',
|
||||
$row['content'] ?? '',
|
||||
$row['author'] ?? '',
|
||||
|
||||
Reference in New Issue
Block a user