Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c2b7462307 | |||
| cdbf81878b | |||
| 68ec6dedd7 | |||
| 12782463d7 | |||
| 21a935edf3 | |||
| 3d65f79d2c | |||
| ed31210e3a | |||
| 5030caa029 | |||
| 4a87152531 | |||
| 1401c3afe7 | |||
| d5a3f4298f | |||
| b4a5c9c020 | |||
| 6d6f1f31b0 | |||
| cafffba921 | |||
| 8fa758d825 |
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-261.24374.151">
|
||||
<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>
|
||||
|
||||
@@ -16,18 +16,21 @@
|
||||
|
||||
## Bekannte Fehler und Mängel
|
||||
- Bitte auf die gesetzten TODO's achten. Wenn Inhalte fehlen, sind sie i.d.R. als TODO kommentiert.
|
||||
- Die Suchseite und Kategorieseite packen momentan alle passenden Beiträge untereinander. Später sollen zunächst 10
|
||||
Ergebnisse auf einer Seite angezeigt werden.
|
||||
- Die Kategorieseite listet momentan alle passenden Beiträge untereinander. Später sollen mit einem Paginator die neusten
|
||||
Beiträge nacheinander aufgelistet werden (ähnlich wie bei der Suche, wenn nach Fach gefiltert wird).
|
||||
- Wenn ein Bild aus einem Beitrag entfernt wird, dann wird noch nicht die Datei im Pfad /uploads gelöscht.
|
||||
- id in showArticle-controller.php und updateArticle-controller.php wird nicht als gültige numerische ID geprüft.
|
||||
- sort in search-results-controller.php wird nicht gegen erlaubte Werte validiert.
|
||||
- Bilder im Beitragseditor sollen zukünftig eine Bildunterschrift bekommen und größenverstellbar sein.
|
||||
- Die Elemente eines Contents im Beitrag werden momentan stumpf untereinander aufgelistet. Soll später
|
||||
sich responisve auch nebeneinander orientieren usw.
|
||||
|
||||
## Besonderheiten des Projektes
|
||||
- Es wurde ein einfacher Beitrags-Editor erstellt. Mit diesem können Beiträge erstellt oder bearbeitet werden.
|
||||
Es handelt es sich um eine einfache Version. Später sollen z.B. Bilder und die Positionierung der Elemente folgen.
|
||||
- Es sind drei Dummy-Beiträge für den Nutzer max.mustermann hinterlegt.
|
||||
- Die Such-Seite umfasst eine Such- und Sortierfunktion. Jedoch fehlt noch eine
|
||||
Filterfunktion (z.B. nur Mathe anzeigen).
|
||||
- Es wurde AJAX verwendet, um asynchrone Erstellung von Kommentaren zu implementieren. Es ermöglicht dem Nutzer, einen
|
||||
Kommentar abzusenden, ohne dass die gesamte Webseite neu geladen werden muss.
|
||||
- Mit JavaScript werden auch clientseitig die Kommentare visuell hinzugefügt und die Kommentarbäume aufgebaut.
|
||||
- JavaScript wird verwendet, um im erweitertem Beitragseditor clientseitig einzelne Content-Boxen erstellen und löschen
|
||||
zu können.
|
||||
- JavaScript wird ebenfalls verwendet, um in die Suchergebnisse clientseitig zu sortieren.
|
||||
|
||||
## Sonstiges
|
||||
- Das Datenschema befindet sich unter /planung/Datenschema.pdf
|
||||
+31
-56
@@ -27,8 +27,7 @@ if ($currentPage < 1) {
|
||||
$offset = ($currentPage - 1) * $limit;
|
||||
|
||||
// Nur die Ergebnisse für die aktuelle Seite ausschneiden
|
||||
//$results = array_slice($all_results, $offset, $limit);
|
||||
$results = $all_results;
|
||||
$results = array_slice($all_results, $offset, $limit);
|
||||
$resultCount = count($results);
|
||||
|
||||
?>
|
||||
@@ -45,11 +44,12 @@ $resultCount = count($results);
|
||||
<!-- Links: Seitenleiste für Filter und Suche -->
|
||||
<aside class="s-res-sidebar">
|
||||
|
||||
<form action="php/controller/search-results-controller.php" method="GET" id="search-form-id" class="s-res-sidebar-form">
|
||||
<!-- Sortierfuntion Box und Such Box-->
|
||||
<form id="search-form-id" action="php/controller/search-results-controller.php" method="GET" class="s-res-sidebar-form">
|
||||
<!-- Dieses Feld hält die aktuelle Seitenzahl für den Submit bereit -->
|
||||
<input type="hidden" name="page" id="s-res-page-input" value="<?php echo $currentPage; ?>">
|
||||
|
||||
<input type="hidden" id="s-res-page-input" name="page" value="<?php echo $_GET['page'] ?? 1; ?>">
|
||||
|
||||
<div class="s-res-sidebar-box">
|
||||
<div class="s-res-sidebar-box">
|
||||
<h3 class="s-res-sidebar-title">Suche anpassen</h3>
|
||||
<input type="search" id="site-search" name="q" placeholder="Suchen..." class="nav__search" value="<?php echo htmlspecialchars($query); ?>" maxlength="50" required>
|
||||
<button type="submit" class="nav__search-button">Suchen</button>
|
||||
@@ -60,57 +60,25 @@ $resultCount = count($results);
|
||||
<?php $currentSort = $_SESSION['search_sort'] ?? 'alphabet'; ?>
|
||||
<div class="s-res-filter-group">
|
||||
<label class="s-res-filter-option">
|
||||
<input type="radio" name="sort" value="alphabet" class="sort-radio" <?php echo $currentSort === 'alphabet' ? 'checked' : ''; ?>>
|
||||
<input type="radio" name="sort" value="alphabet" <?php echo $currentSort === 'alphabet' ? 'checked' : ''; ?> onchange="this.form.submit()">
|
||||
<span>Alphabetisch</span>
|
||||
</label>
|
||||
<!-- Noch disabled, da likes noch nicht implementiert-->
|
||||
<label class="s-res-filter-option">
|
||||
<input type="radio" name="sort" value="likes" class="sort-radio" <?php echo $currentSort === 'likes' ? 'checked' : ''; ?>>
|
||||
<input type="radio" name="sort" value="likes" <?php echo $currentSort === 'likes' ? 'checked' : ''; ?> onchange="this.form.submit()">
|
||||
<span>Beliebtheit (Likes)</span>
|
||||
</label>
|
||||
<label class="s-res-filter-option">
|
||||
<input type="radio" name="sort" value="newest" class="sort-radio" <?php echo $currentSort === 'newest' ? 'checked' : ''; ?>>
|
||||
<input type="radio" name="sort" value="newest" <?php echo $currentSort === 'newest' ? 'checked' : ''; ?> onchange="this.form.submit()">
|
||||
<span>Neueste Beiträge</span>
|
||||
</label>
|
||||
<label class="s-res-filter-option">
|
||||
<input type="radio" name="sort" value="oldest" class="sort-radio" <?php echo $currentSort === 'oldest' ? 'checked' : ''; ?>>
|
||||
<input type="radio" name="sort" value="oldest" <?php echo $currentSort === 'oldest' ? 'checked' : ''; ?> onchange="this.form.submit()">
|
||||
<span>Älteste Beiträge</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="s-res-sidebar-box">
|
||||
<h3 class="s-res-sidebar-title">Kategorie filtern</h3>
|
||||
<select id="category-filter" class="s-res-limit-select" style="width: 100%; padding: 8px; border-radius: 6px; border: 1px solid #cbd5e1;">
|
||||
<option value="all">Alle Kategorien</option>
|
||||
<option value="Deutsch">Deutsch</option>
|
||||
<option value="Englisch">Englisch</option>
|
||||
<option value="Franzoesisch">Französisch</option>
|
||||
<option value="Latein">Latein</option>
|
||||
<option value="Literatur">Literatur</option>
|
||||
<option value="Mathematik">Mathematik</option>
|
||||
<option value="Biologie">Biologie</option>
|
||||
<option value="Informatik">Informatik</option>
|
||||
<option value="Chemie">Chemie</option>
|
||||
<option value="Physik">Physik</option>
|
||||
<option value="Astronomie">Astronomie</option>
|
||||
<option value="Geschichte">Geschichte</option>
|
||||
<option value="Erdkunde">Erdkunde</option>
|
||||
<option value="Sozialkunde">Sozialkunde</option>
|
||||
<option value="Wirtschaftskunde">Wirtschaftskunde</option>
|
||||
<option value="Religion">Religion</option>
|
||||
<option value="Ethikunterricht">Ethikunterricht</option>
|
||||
<option value="Philosophie">Philosophie</option>
|
||||
<option value="Psychologie">Psychologie</option>
|
||||
<option value="Kunst">Kunst</option>
|
||||
<option value="Musik">Musik</option>
|
||||
<option value="Theater">Theater</option>
|
||||
<option value="Technik">Technik</option>
|
||||
<option value="Werken">Werken</option>
|
||||
<option value="Hauswirtschaft">Hauswirtschaft</option>
|
||||
<option value="Sport">Sport</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</aside>
|
||||
@@ -127,11 +95,8 @@ $resultCount = count($results);
|
||||
<?php
|
||||
if (!empty($results)): ?>
|
||||
|
||||
<?php foreach ($results as $item):
|
||||
// Anzahl der Likes ermitteln (falls es ein Array ist, zählen; falls Zahl, direkt nutzen)
|
||||
$likesCount = isset($item['likes']) && is_array($item['likes']) ? count($item['likes']) : ($item['likes'] ?? 0);
|
||||
?>
|
||||
<div class="s-res-item" data-likes="<?php echo $likesCount; ?>" data-category="<?php echo strtolower($item['category'] ?? ''); ?>">
|
||||
<?php foreach ($results as $item): ?>
|
||||
<div class="s-res-item">
|
||||
<div class="s-res-content">
|
||||
<h2 class="s-res-item-title">
|
||||
<a href="index.php?pfad=showArticle&id=<?php echo $item['id']; ?>" class="s-res-link">
|
||||
@@ -142,9 +107,10 @@ $resultCount = count($results);
|
||||
<p class="s-res-author">Von: <span class="s-res-author-name"><?php echo htmlspecialchars($item['author']); ?></span></p>
|
||||
|
||||
<span class="s-res-likes">
|
||||
❤️ <?php echo $likesCount; ?>
|
||||
❤️ <?php echo isset($item['likes']) && is_array($item['likes']) ? count($item['likes']) : 0; ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="s-res-arrow">→</div>
|
||||
</div>
|
||||
@@ -154,8 +120,8 @@ $resultCount = count($results);
|
||||
elseif (isset($_SESSION["search_query"]) && $_SESSION["search_query"] !== "" && $resultCount === 0): ?>
|
||||
<p>Keine Beiträge zu diesem Suchbegriff gefunden.</p>
|
||||
<?php
|
||||
elseif (isset($_SESSION["message"]) && $_SESSION["message"] == "invalid_search_query"): ?>
|
||||
<p>Unzulässige Suchanfrage</p>
|
||||
elseif (isset($_SESSION["message"]) && $_SESSION["message"] == "missing_parameters"): ?>
|
||||
<p>Bitte überprüfe deine Sucheingabe und versuche es erneut!</p>
|
||||
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
@@ -177,11 +143,20 @@ $resultCount = count($results);
|
||||
</div>
|
||||
|
||||
<div class="s-res-page-navigation">
|
||||
<button type="button" class="s-res-page-btn" id="prev-page-btn" data-page="0">«</button>
|
||||
|
||||
<span id="dynamic-page-numbers"></span>
|
||||
|
||||
<button type="button" class="s-res-page-btn" id="next-page-btn" data-page="2">»</button>
|
||||
<button type="button" class="s-res-page-btn" data-page="<?php echo $currentPage - 1; ?>" <?php echo $currentPage <= 1 ? 'disabled' : ''; ?>>
|
||||
«
|
||||
</button>
|
||||
<!-- Dynamische Seitenzahlen -->
|
||||
<?php for ($i = 1; $i <= $totalPages; $i++): ?>
|
||||
<button type="button"
|
||||
class="s-res-page-btn <?php echo $i === $currentPage ? 's-res-page-btn-active' : ''; ?>"
|
||||
data-page="<?php echo $i; ?>">
|
||||
<?php echo $i; ?>
|
||||
</button>
|
||||
<?php endfor; ?>
|
||||
<button type="button" class="s-res-page-btn" data-page="<?php echo $currentPage + 1; ?>" <?php echo $currentPage >= $totalPages ? 'disabled' : ''; ?>>
|
||||
»
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -78,6 +78,11 @@
|
||||
Das Bild konnte nicht hochgeladen werden. Bitte versuche es erneut oder verwende ein anderes Bildformat.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($_SESSION["message"]) && $_SESSION["message"] == "database_error"): ?>
|
||||
<p class="alert-message is-error">
|
||||
Es ist ein Datenbankfehler aufgetreten. Bitte versuche es erneut.
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php
|
||||
unset($_SESSION["message"]);
|
||||
?>
|
||||
|
||||
@@ -3,6 +3,7 @@ if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
ob_start();
|
||||
include_once("php/controller/index.php");
|
||||
|
||||
$pfad = $_GET["pfad"] ?? "home";
|
||||
|
||||
@@ -53,10 +54,8 @@ if ($pfad === "deleteAccount") {
|
||||
<link rel="stylesheet" href="css/message.css">
|
||||
|
||||
<script src="js/paginator.js" async></script>
|
||||
<script src="js/sorter.js" async></script>
|
||||
<script src="js/comments.js" defer></script>
|
||||
<script src="js/editor.js" async></script>
|
||||
<script src="js/filter.js" async></script>
|
||||
|
||||
<title>EduForge</title>
|
||||
</head>
|
||||
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
let currentClientPage = 1;
|
||||
const itemsPerPage = 10;
|
||||
|
||||
function initFilter() {
|
||||
const filterSelect = document.getElementById('category-filter');
|
||||
const listContainer = document.querySelector('.s-res-list');
|
||||
|
||||
if (!filterSelect || !listContainer) return;
|
||||
|
||||
updateVisibility();
|
||||
|
||||
filterSelect.addEventListener('change', function() {
|
||||
currentClientPage = 1;
|
||||
updateVisibility();
|
||||
});
|
||||
|
||||
const navigationContainer = document.querySelector('.s-res-page-navigation');
|
||||
if (navigationContainer) {
|
||||
navigationContainer.addEventListener('click', function(e) {
|
||||
const button = e.target.closest('.s-res-page-btn');
|
||||
if (!button || button.disabled) return;
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
const targetPage = button.getAttribute('data-page');
|
||||
if (targetPage) {
|
||||
currentClientPage = parseInt(targetPage, 10);
|
||||
updateVisibility();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateVisibility() {
|
||||
const filterSelect = document.getElementById('category-filter');
|
||||
const listContainer = document.querySelector('.s-res-list');
|
||||
const selectedCategory = filterSelect.value.toLowerCase().trim();
|
||||
const cards = listContainer.querySelectorAll('.s-res-item');
|
||||
|
||||
let visibleCards = [];
|
||||
cards.forEach(card => {
|
||||
const cardCategory = (card.getAttribute('data-category') || '').toLowerCase().trim();
|
||||
if (selectedCategory === 'all' || cardCategory.includes(selectedCategory) || selectedCategory.includes(cardCategory)) {
|
||||
visibleCards.push(card);
|
||||
} else {
|
||||
card.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
const totalVisible = visibleCards.length;
|
||||
const totalPages = Math.max(1, Math.ceil(totalVisible / itemsPerPage));
|
||||
|
||||
if (currentClientPage < 1) currentClientPage = 1;
|
||||
if (currentClientPage > totalPages) currentClientPage = totalPages;
|
||||
|
||||
const startOffset = (currentClientPage - 1) * itemsPerPage;
|
||||
const endOffset = startOffset + itemsPerPage;
|
||||
|
||||
visibleCards.forEach((card, index) => {
|
||||
if (index >= startOffset && index < endOffset) {
|
||||
card.style.display = 'flex';
|
||||
} else {
|
||||
card.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
updatePaginatorUI(currentClientPage, totalPages);
|
||||
}
|
||||
|
||||
function updatePaginatorUI(currentPage, totalPages) {
|
||||
const prevBtn = document.getElementById('prev-page-btn');
|
||||
const nextBtn = document.getElementById('next-page-btn');
|
||||
const numbersContainer = document.getElementById('dynamic-page-numbers');
|
||||
|
||||
if (!prevBtn || !nextBtn || !numbersContainer) return;
|
||||
|
||||
prevBtn.setAttribute('data-page', currentPage - 1);
|
||||
prevBtn.disabled = (currentPage <= 1);
|
||||
|
||||
nextBtn.setAttribute('data-page', currentPage + 1);
|
||||
nextBtn.disabled = (currentPage >= totalPages);
|
||||
|
||||
let buttonsHTML = '';
|
||||
for (let i = 1; i <= totalPages; i++) {
|
||||
const activeClass = (i === currentPage) ? 's-res-page-btn-active' : '';
|
||||
buttonsHTML += `<button type="button" class="s-res-page-btn ${activeClass}" data-page="${i}">${i}</button> `;
|
||||
}
|
||||
numbersContainer.innerHTML = buttonsHTML;
|
||||
}
|
||||
|
||||
// Hilfsfunktion für Math.ceil in JS
|
||||
function ceil(val) { return Math.ceil(val); }
|
||||
|
||||
// ist das DOM bereits vollständig aufgebaut?
|
||||
if (document.readyState === 'loading') {
|
||||
// Falls noch geladen wird, auf das Event warten
|
||||
document.addEventListener('DOMContentLoaded', initFilter);
|
||||
} else {
|
||||
// Falls das HTML bereits komplett da ist, sofort ausführen
|
||||
initFilter();
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
|
||||
function initSorter() {
|
||||
const listContainer = document.querySelector('.s-res-list');
|
||||
const sortRadios = document.querySelectorAll('.sort-radio');
|
||||
|
||||
// wenn keine liste vorhanden, abbrechen
|
||||
if (!listContainer || sortRadios.length === 0) return;
|
||||
|
||||
sortRadios.forEach(radio => {
|
||||
radio.addEventListener('change', function() {
|
||||
const cards = Array.from(listContainer.querySelectorAll('.s-res-item'));
|
||||
const sortValue = this.value;
|
||||
|
||||
cards.sort((a, b) => {
|
||||
if (sortValue === 'likes') {
|
||||
const likesA = parseInt(a.getAttribute('data-likes') || '0', 10);
|
||||
const likesB = parseInt(b.getAttribute('data-likes') || '0', 10);
|
||||
return likesB - likesA;
|
||||
}
|
||||
else if (sortValue === 'alphabet') {
|
||||
// alphabetische sortierung
|
||||
const titleA = a.querySelector('.s-res-link').textContent.trim().toLowerCase();
|
||||
const titleB = b.querySelector('.s-res-link').textContent.trim().toLowerCase();
|
||||
return titleA.localeCompare(titleB);
|
||||
}
|
||||
else if (sortValue === 'newest' || sortValue === 'oldest') {
|
||||
// hoehere ID wird als neuer gesehen
|
||||
const urlA = a.querySelector('.s-res-link').getAttribute('href');
|
||||
const urlB = b.querySelector('.s-res-link').getAttribute('href');
|
||||
|
||||
const idA = parseInt(urlA.match(/id=(\d+)/)[1], 10);
|
||||
const idB = parseInt(urlB.match(/id=(\d+)/)[1], 10);
|
||||
|
||||
return sortValue === 'newest' ? idB - idA : idA - idB;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
listContainer.innerHTML = '';
|
||||
cards.forEach(card => listContainer.appendChild(card));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ist das DOM bereits vollständig aufgebaut?
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initSorter);
|
||||
} else {
|
||||
initSorter();
|
||||
}
|
||||
@@ -5,15 +5,14 @@ if (session_status() === PHP_SESSION_NONE) {
|
||||
require_once '../model/LocalArticleManager.php';
|
||||
require_once '../model/ArticleManager.php';
|
||||
require_once '../model/Article.php';
|
||||
require_once '../validator/search-validator.php';
|
||||
|
||||
if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["q"])) {
|
||||
|
||||
$search = trim($_GET["q"]);
|
||||
if (!searchQueryValidator($search)) {
|
||||
if (empty($search)) {
|
||||
$_SESSION["search_results"] = [];
|
||||
$_SESSION["search_query"] = "";
|
||||
$_SESSION["message"] = "invalid_search_query";
|
||||
$_SESSION["message"] = "missing_parameters";
|
||||
} else {
|
||||
try {
|
||||
|
||||
@@ -71,9 +70,6 @@ if ($_SERVER["REQUEST_METHOD"] === "GET" && isset($_GET["q"])) {
|
||||
|
||||
$sort = $_GET['sort'] ?? 'alphabet';
|
||||
$limit = isset($_GET['limit']) ? (int)$_GET['limit'] : 10;
|
||||
if (!searchLimitValidator($limit)) {
|
||||
$limit = 10;
|
||||
}
|
||||
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
|
||||
header("Location: ../../index.php?pfad=search-results&q=" . urlencode($search) . "&sort=" . urlencode($sort) . "&limit=" . $limit . "&page=" . $page);
|
||||
exit();
|
||||
|
||||
@@ -8,7 +8,7 @@ require_once '../model/ArticleManager.php';
|
||||
require_once '../model/Article.php';
|
||||
require_once '../validator/article-validator.php';
|
||||
|
||||
if (!isset($_SESSION["user"])) {
|
||||
if (!isset($_SESSION["user_email"])) {
|
||||
header("Location: index.php?pfad=login");
|
||||
exit();
|
||||
}
|
||||
@@ -16,7 +16,7 @@ if (!isset($_SESSION["user"])) {
|
||||
if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$_SESSION["old_title"] = $_POST["title"] ?? '';
|
||||
$_SESSION["old_content"] = $_POST["content"] ?? '';
|
||||
$_SESSION["old_category"] = $_POST["category"] ?? ''; // TODO: die Kategorie im Dropdown setzen, wenn der Editor erneut geöffnet wird.
|
||||
$_SESSION["old_category"] = $_POST["category"] ?? '';
|
||||
$_SESSION["old_tags"] = $_POST["tags"] ?? '';
|
||||
|
||||
if (isset($_GET["id"]) && !empty($_GET["id"])) {
|
||||
@@ -30,7 +30,7 @@ if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
try {
|
||||
$articleManager = ArticleManager::getInstance();
|
||||
$article = $articleManager->getArticle($id);
|
||||
if ($article->getAuthor() != $_SESSION["user"]->getUsername()) {
|
||||
if ($article->getAuthor() != $_SESSION["user_email"]) {
|
||||
$_SESSION["message"] = "unauthorized_access";
|
||||
header("location: ../../index.php");
|
||||
exit();
|
||||
|
||||
@@ -18,152 +18,9 @@ class ArticleManager
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
$articleManager = DatabaseArticleManager::getInstance(); // Hier kann zwischen dem lokalen und datenbankbasiertem ArticleManager gewechselt werden.
|
||||
|
||||
// 100 fiktionale Fachbeiträge:
|
||||
$dummyArticles = [
|
||||
// --- INFORMATIK & MATHE (1-20) ---
|
||||
1 => ["Satz des Pythagoras", "Der Satz des Pythagoras beschreibt das Verhältnis der Seitenlängen in einem rechtwinkligen Dreieck.", "mathe", "Dreiecke, Geometrie"],
|
||||
2 => ["Tunneleffekt", "Der Tunneleffekt beschreibt das quantenmechanische Phänomen, dass Teilchen Barrieren überwinden können.", "physik", "Quantenphysik, Energie"],
|
||||
3 => ["Datenschutz vs Datensicherheit", "Datenschutz schützt Personen, während Datensicherheit Systeme vor unbefugten Zugriffen schützt.", "informatik", "Daten, DSGVO"],
|
||||
4 => ["Einführung in Algorithmen", "Ein Algorithmus ist eine präzise Handlungsanweisung zur Lösung eines vordefinierten Problems.", "informatik", "Code, Logik"],
|
||||
5 => ["Primzahlen im Detail", "Primzahlen sind natürliche Zahlen, die nur durch eins und sich selbst ohne Rest teilbar sind.", "mathe", "Zahlentheorie"],
|
||||
6 => ["Lineare Algebra", "Vektoren und Matrizen bilden das Fundament für moderne Computergrafik und 3D-Engines.", "mathe", "Matrizen, Vektoren"],
|
||||
7 => ["Objektorientierte Programmierung", "Die OOP nutzt Klassen und Objekte, um reale Strukturen im Quellcode abzubilden.", "informatik", "OOP, Klassen"],
|
||||
8 => ["Grundlagen von HTML und CSS", "HTML strukturiert den Inhalt einer Webseite, während CSS für das optische Design zuständig ist.", "informatik", "Web, Frontend"],
|
||||
9 => ["Die Relativitätstheorie", "Einsteins Theorie revolutionierte unser Verständnis von Raum, Zeit und Gravitation massiv.", "physik", "Einstein, Gravitation"],
|
||||
10 => ["Datenbanken und SQL", "Strukturierte Abfragesprachen erlauben das effiziente Speichern und Abrufen großer Datenmengen.", "informatik", "SQL, Datenbank"],
|
||||
11 => ["Wahrscheinlichkeitsrechnung", "Die Stochastik befasst sich mit der mathematischen Analyse von Zufallsexperimenten.", "mathe", "Zufall, Stochastik"],
|
||||
12 => ["Quantencomputing", "Künftige Quantencomputer nutzen Qubits, um komplexe Berechnungen in Rekordzeit zu lösen.", "informatik", "Hardware, Zukunft"],
|
||||
13 => ["Die Fibonacci-Folge", "Diese Zahlenreihe beschreibt mathematische Wachstumsmuster, die oft in der Natur vorkommen.", "mathe", "Zahlen, Natur"],
|
||||
14 => ["Thermodynamik", "Die Hauptsätze der Thermodynamik regeln den Energieaustausch und die Entropie in Systemen.", "physik", "Energie, Wärme"],
|
||||
15 => ["Cybersecurity Grundlagen", "Die Absicherung von Netzwerken erfordert Firewalls, Verschlüsselung und regelmäßige Audits.", "informatik", "Sicherheit, Hacker"],
|
||||
16 => ["Kryptographie", "Asymmetrische Verschlüsselungsverfahren sichern heutzutage den gesamten Datenverkehr im Web.", "informatik", "Krypto, Security"],
|
||||
17 => ["Analysis und Ableitungen", "Die Differentialrechnung untersucht die lokalen Änderungsraten von mathematischen Funktionen.", "mathe", "Analysis, Funktionen"],
|
||||
18 => ["Schwarze Löcher", "Diese Regionen im Raum besitzen eine so starke Gravitation, dass selbst Licht nicht entkommt.", "physik", "Astronomie, Kosmos"],
|
||||
19 => ["Git Versionsverwaltung", "Git erlaubt Entwicklern das parallele Arbeiten an Code-Projekten ohne Datenverlust.", "informatik", "Git, DevOps"],
|
||||
20 => ["Künstliche Intelligenz", "Neuronale Netze versuchen das menschliche Gehirn für maschinelles Lernen nachzubilden.", "informatik", "KI, Software"],
|
||||
return DatabaseArticleManager::getInstance(); // Hier kann zwischen dem lokalen und datenbankbasiertem ArticleManager gewechselt werden.
|
||||
|
||||
// --- CHEMIE & BIOLOGIE (21-40) ---
|
||||
21 => ["Das Periodensystem", "Die Elemente sind nach ihrer Ordnungszahl und chemischen Eigenschaften geordnet.", "chemie", "Elemente, Moleküle"],
|
||||
22 => ["Photosynthese", "Pflanzen wandeln mithilfe von Sonnenlicht Kohlendioxid und Wasser in Glukose und Sauerstoff um.", "biologie", "Pflanzen, Energie"],
|
||||
23 => ["Aufbau einer Zelle", "Die Zelle ist die kleinste lebende Einheit aller Organismen mit spezialisierten Organellen.", "biologie", "Zellen, Biologie"],
|
||||
24 => ["Säuren und Basen", "Der pH-Wert misst die Konzentration von Wasserstoff-Ionen in einer wässrigen Lösung.", "chemie", "Labor, pH-Wert"],
|
||||
25 => ["Die DNA-Struktur", "Die Doppelhelix enthält den genetischen Bauplan für die Entwicklung aller Lebewesen.", "biologie", "Genetik, Erbgut"],
|
||||
26 => ["Chemische Bindungen", "Kovalente Bindungen entstehen durch das Teilen von Elektronenpaaren zwischen Atomen.", "chemie", "Atome, Bindung"],
|
||||
27 => ["Das Immunsystem", "Weiße Blutkörperchen und Antikörper schützen den menschlichen Körper vor Krankheitserregern.", "biologie", "Gesundheit, Abwehr"],
|
||||
28 => ["Katalysatoren", "Katalysatoren beschleunigen chemische Reaktionen, ohne dabei selbst verbraucht zu werden.", "chemie", "Reaktion, Chemie"],
|
||||
29 => ["Ökosystem Wald", "Das Zusammenspiel von Flora, Fauna und Klima bildet ein hochsensibles ökologisches System.", "biologie", "Natur, Wald"],
|
||||
30 => ["Die Mendelschen Regeln", "Diese Grundgesetze der Vererbung beschreiben, wie Merkmale an Nachkommen weitergegeben werden.", "biologie", "Genetik, Erbung"],
|
||||
31 => ["Zustandsformen der Materie", "Fest, flüssig und gasförmig sind die klassischen Aggregatzustände von Stoffen.", "chemie", "Physik, Materie"],
|
||||
32 => ["Evolutionstheorie", "Charles Darwin begründete die Theorie der natürlichen Auslese und Anpassung von Arten.", "biologie", "Darwin, Evolution"],
|
||||
33 => ["Organische Chemie", "Die Chemie der Kohlenstoffverbindungen bildet die Basis für alles bekannte Leben.", "chemie", "Kohlenstoff, Chemie"],
|
||||
34 => ["Das menschliche Gehirn", "Milliarden von Neuronen kommunizieren über Synapsen, um Reize und Gedanken zu verarbeiten.", "biologie", "Neurologie, Nerven"],
|
||||
35 => ["Der Wasserkreislauf", "Verdunstung, Kondensation und Niederschlag halten das Wasser auf der Erde in Bewegung.", "geographie", "Wasser, Klima"],
|
||||
36 => ["Aggregatzustände von Wasser", "Wasser zeigt ungewöhnliche Eigenschaften wie die Dichteanomalie beim Gefrieren.", "chemie", "Wasser, Eis"],
|
||||
37 => ["Blutkreislauf des Menschen", "Das Herz pumpt sauerstoffreiches Blut durch Arterien in alle Organe des Körpers.", "biologie", "Herz, Medizin"],
|
||||
38 => ["Das Ohmsche Gesetz", "Es beschreibt den direkten Zusammenhang zwischen Spannung, Stromstärke und Widerstand.", "physik", "Strom, Elektronik"],
|
||||
39 => ["Plattentektonik", "Die Bewegung der Kontinentalplatten führt zu Erdbeben, Vulkanismus und Gebirgsbildung.", "geographie", "Erde, Geologie"],
|
||||
40 => ["Proteine und Enzyme", "Enzyme wirken als Biokatalysatoren und steuern fast alle Stoffwechselprozesse.", "biologie", "Biochemie, Enzyme"],
|
||||
|
||||
// --- GESCHICHTE & WIRTSCHAFT (41-60) ---
|
||||
41 => ["Das Römische Reich", "Vom Stadtstaat zum Weltreich prägte Rom die Rechts- und Kulturgeschichte Europas.", "geschichte", "Antike, Rom"],
|
||||
42 => ["Die Französische Revolution", "Freiheit, Gleichheit, Brüderlichkeit beendeten 1789 die absolute Monarchie in Frankreich.", "geschichte", "Europa, Politik"],
|
||||
43 => ["Inflation erklärt", "Inflation bezeichnet die kontinuierliche Geldentwertung und den Kaufkraftverlust.", "wirtschaft", "Geld, Finanzen"],
|
||||
44 => ["Die Industrielle Revolution", "Die Erfindung der Dampfmaschine veränderte die Produktion und die Gesellschaft tiefgreifend.", "geschichte", "Industrie, Arbeit"],
|
||||
45 => ["Angebot und Nachfrage", "Dieses fundamentale Marktgesetz bestimmt den Preis von Gütern in einer freien Wirtschaft.", "wirtschaft", "Markt, Preise"],
|
||||
46 => ["Der Buchdruck", "Johannes Gutenbergs Erfindung revolutionierte die Verbreitung von Wissen im Mittelalter.", "geschichte", "Medien, Wissen"],
|
||||
47 => ["Die Entdeckung Amerikas", "Kolumbus' Seereise im Jahr 1492 leitete das Zeitalter der Kolonialisierung ein.", "geschichte", "Entdeckung, Seefahrt"],
|
||||
48 => ["Kryptowährungen", "Bitcoin nutzt Blockchain-Technologie, um dezentralen digitalen Werttransfer zu erlauben.", "wirtschaft", "Blockchain, Finanzen"],
|
||||
49 => ["Das antike Griechenland", "Die Wiege der Demokratie und Philosophie brachte Denker wie Sokrates und Platon hervor.", "geschichte", "Antike, Philosophie"],
|
||||
50 => ["Globalisierung", "Die weltweite Verflechtung in Wirtschaft, Kultur und Politik bringt Chancen und Risiken.", "wirtschaft", "Weltwirtschaft, Handel"],
|
||||
51 => ["Der Dreißigjährige Krieg", "Ein religiöser und politischer Konflikt verwüstete zwischen 1618 und 1648 Mitteleuropa.", "geschichte", "Krieg, Europa"],
|
||||
52 => ["Die Weimarer Republik", "Die erste deutsche Demokratie scheiterte an wirtschaftlichen und politischen Krisen.", "geschichte", "Deutschland, Weimar"],
|
||||
53 => ["Aktien und Börse", "Unternehmen beschaffen sich Kapital durch die Ausgabe von Anteilen an Investoren.", "wirtschaft", "Aktien, Investieren"],
|
||||
54 => ["Das alte Ägypten", "Pharaonen, Pyramiden und Hieroglyphen zeugen von einer hochentwickelten Hochkultur am Nil.", "geschichte", "Ägypten, Antike"],
|
||||
55 => ["Der Kalte Krieg", "Das Wettrüsten zwischen USA und UdSSR prägte die globale Politik der Nachkriegszeit.", "geschichte", "Ost-West, Politik"],
|
||||
56 => ["Zentralbanken und Leitzins", "Durch Zinsänderungen steuern Notenbanken die Geldmenge und bekämpfen Inflation.", "wirtschaft", "Zinsen, Geldpolitik"],
|
||||
57 => ["Die Seidenstraße", "Das historische Netzwerk von Handelsrouten verband über Jahrhunderte Asien und Europa.", "geschichte", "Handel, Asien"],
|
||||
58 => ["Das Mittelalter", "Ritter, Burgen und das Feudalsystem prägten diese tausendjährige Epoche Europas.", "geschichte", "Mittelalter, Feudalismus"],
|
||||
59 => ["Planwirtschaft vs Marktwirtschaft", "Zentrale staatliche Steuerung steht dem freien Spiel der Marktkräfte gegenüber.", "wirtschaft", "Systeme, Wirtschaft"],
|
||||
60 => ["Die Berliner Mauer", "Ihr Bau 1961 zementierte die Teilung Deutschlands, ihr Fall 1989 beendete sie.", "geschichte", "DDR, Wiedervereinigung"],
|
||||
|
||||
// --- ANWENDUNGEN & WEITERE THEMEN (61-100) ---
|
||||
61 => ["Cloud Computing", "Das Auslagern von Rechenleistung in das Internet spart lokale IT-Infrastruktur ein.", "informatik", "Cloud, Web"],
|
||||
62 => ["Responsive Webdesign", "Moderne Webseiten passen ihr Layout dynamisch an Smartphones und Desktops an.", "informatik", "Design, CSS"],
|
||||
63 => ["Der Treibhauseffekt", "Gase in der Atmosphäre verhindern das Entweichen von Wärme ins Weltall.", "physik", "Klima, Umwelt"],
|
||||
64 => ["Mechanik und Kräfte", "Die Newtonschen Axiome beschreiben, wie Kräfte auf Körper wirken und sie bewegen.", "physik", "Newton, Kraft"],
|
||||
65 => ["Die Mendelschen Gesetze", "Die Vererbung von Genen folgt klaren statistischen Wahrscheinlichkeiten.", "biologie", "Genetik, Erbsen"],
|
||||
66 => ["Lichtgeschwindigkeit", "Im Vakuum bewegt sich Licht mit knapp 300.000 Kilometern pro Sekunde.", "physik", "Licht, Relativität"],
|
||||
67 => ["Die Funktion von APIs", "Programmierschnittstellen erlauben den Datenaustausch zwischen verschiedenen Systemen.", "informatik", "API, Schnittstelle"],
|
||||
68 => ["Der Goldstandard", "Ein historischen Währungssystem, bei dem Geld durch echtes Gold gedeckt war.", "wirtschaft", "Gold, Währung"],
|
||||
69 => ["Der Wiener Kongress", "1815 ordneten die europäischen Mächte die Landkarte nach den Napoleonischen Kriegen neu.", "geschichte", "Europa, Diplomatie"],
|
||||
70 => ["Integrierte Schaltkreise", "Mikrochips enthalten Millionen Transistoren auf kleinstem Raum für Logikschaltungen.", "informatik", "Hardware, Chips"],
|
||||
71 => ["Die Magellan-Expedition", "Die erste erfolgreiche Weltumsegelung bewies praktisch die Kugelgestalt der Erde.", "geschichte", "Seefahrt, Erde"],
|
||||
72 => ["Das Internet der Dinge", "Alltagsgegenstände werden vernetzt, um smarte Automatisierungen zu ermöglichen.", "informatik", "IoT, SmartHome"],
|
||||
73 => ["Halbwertszeit", "Die Zeitspanne, in der sich die Hälfte der instabilen Atome radioaktiv abbaut.", "physik", "Atomphysik, Strahlung"],
|
||||
74 => ["Elektromagnetismus", "Die Verknüpfung von elektrischen Strömen und magnetischen Feldern treibt Motoren an.", "physik", "Strom, Magnet"],
|
||||
75 => ["Das Ökosystem Meer", "Ozeane regulieren das Weltklima und bieten Lebensraum für unzählige Arten.", "biologie", "Meer, Ökologie"],
|
||||
76 => ["Einführung in Docker", "Containerisierung isoliert Anwendungen samt Abhängigkeiten für stabilen Betrieb.", "informatik", "Docker, DevOps"],
|
||||
77 => ["Das Römische Recht", "Viele moderne europäische Gesetzbücher basieren auf antiken römischen Rechtsprinzipien.", "geschichte", "Recht, Gesetz"],
|
||||
78 => ["Verhaltensbiologie", "Untersuchung von angeborenen und erlernten Verhaltensweisen bei Mensch und Tier.", "biologie", "Verhalten, Tiere"],
|
||||
79 => ["Verschlüsselung im Alltag", "HTTPS schützt Passwörter und Zahlungsdaten beim Surfen vor dem Mitlesen.", "informatik", "Web, HTTPS"],
|
||||
80 => ["Die Magna Carta", "1215 schränkte dieses Dokument die absolute Macht des englischen Königs ein.", "geschichte", "England, Verfassung"],
|
||||
81 => ["Marktversagen", "Wenn der freie Markt Ressourcen unvollständig verteilt, muss der Staat eingreifen.", "wirtschaft", "Markt, Staat"],
|
||||
82 => ["Optische Linsen", "Konvexe und konkave Linsen brechen Licht für Brillen, Mikroskope und Kameras.", "physik", "Optik, Licht"],
|
||||
83 => ["Die Entstehung der Erde", "Vor rund 4,5 Milliarden Jahren ballte sich kosmischer Staub zu unserem Planeten.", "geographie", "Erde, Kosmos"],
|
||||
84 => ["Grundlagen von JavaScript", "Diese Skriptsprache macht statische Webseiten interaktiv und dynamisch nutzbar.", "informatik", "JS, Webentwicklung"],
|
||||
85 => ["Die industrielle Landwirtschaft", "Moderne Techniken sichern Welternährung, belasten jedoch oft die Umwelt.", "biologie", "Landwirtschaft, Umwelt"],
|
||||
86 => ["Das Schwarze Jahr 1929", "Der New Yorker Börsencrash löste die verheerende Weltwirtschaftskrise aus.", "geschichte", "Krise, Finanzen"],
|
||||
87 => ["Die Evolution des Menschen", "Der Stammbaum des Homo Sapiens entwickelte sich über Millionen Jahre in Afrika.", "biologie", "Mensch, Evolution"],
|
||||
88 => ["Einführung in Linux", "Das Open-Source-Betriebssystem bildet das Rückgrat moderner Server-Infrastrukturen.", "informatik", "Linux, OS"],
|
||||
89 => ["Der Urknall", "Die Urknalltheorie beschreibt den Beginn des Universums aus einer Singularität.", "physik", "Astronomie, Urknall"],
|
||||
90 => ["Das Periodensystem der Elemente", "Dmitri Mendelejew ordnete Elemente logisch nach ihren Atommassen.", "chemie", "Periodensystem, Chemie"],
|
||||
91 => ["Die Hanse", "Ein mächtiger mittelalterlicher Bund von Kaufleuten dominierte den Nordseehandel.", "geschichte", "Handel, Mittelalter"],
|
||||
92 => ["Wirtschaftswachstum", "Die Steigerung des Bruttoinlandsprodukts gilt oft als Indikator für Wohlstand.", "wirtschaft", "BIP, Finanzen"],
|
||||
93 => ["Neuronale Netze", "Diese Strukturen lernen durch mathematische Gewichtung aus riesigen Datenmengen.", "informatik", "KI, Mathematik"],
|
||||
94 => ["Der Erste Weltkrieg", "Der globale Konflikt von 1914 bis 1918 zerstörte das alte europäische Machtgefüge.", "geschichte", "Europa, Krieg"],
|
||||
95 => ["Das Gehirn und Hormone", "Botenstoffe steuern Gefühle, Schlafzyklen und Reaktionen des Körpers.", "biologie", "Medizin, Hormone"],
|
||||
96 => ["SQL Joins erklärt", "Joins verknüpfen Daten aus mehreren Tabellen über gemeinsame Schlüssel.", "informatik", "SQL, Datenbanken"],
|
||||
97 => ["Wellen-Teilchen-Dualismus", "Quantenobjekte zeigen je nach Messaufbau Eigenschaften von Wellen oder Teilchen.", "physik", "Quanten, Licht"],
|
||||
98 => ["Der Absolutismus", "Der Sonnenkönig Ludwig XIV. verkörperte die unbeschränkte Herrschaft des Monarchen.", "geschichte", "Frankreich, Monarchie"],
|
||||
99 => ["Die Funktion von Routern", "Netzwerkgeräte leiten Datenpakete über IP-Adressen an den richtigen Empfänger.", "informatik", "Netzwerk, Internet"],
|
||||
100 => ["Die Entstehung des Geldes", "Vom Tauschhandel über Naturalgeld bis hin zu modernen digitalen Fiat-Währungen.", "wirtschaft", "Geld, Geschichte"]
|
||||
];
|
||||
|
||||
// 10 Dummy-User:
|
||||
$authors = [
|
||||
'max.mustermann@web.de', 'erika.mustermann@web.de', 'john.doe@gmail.com',
|
||||
'jane.doe@gmail.com', 'anna.schmidt@gmx.de', 'thomas.mueller@gmx.de',
|
||||
'sabine.fischer@outlook.com', 'michael.weber@outlook.com', 'julia.wagner@t-online.de',
|
||||
'stefan.becker@t-online.de'
|
||||
];
|
||||
|
||||
foreach ($dummyArticles as $id => $data) {
|
||||
// Falls der Artikel mit der ID noch nicht existiert, lege ihn an
|
||||
if ($articleManager->getArticle($id) == null) {
|
||||
// Verteilt die 10 Autoren gleichmäßig (ID 1 -> Autor 1, ID 10 -> Autor 10, ID 11 -> Autor 1)
|
||||
$authorEmail = $authors[($id - 1) % 10];
|
||||
|
||||
$blockStructure = [
|
||||
[
|
||||
'type' => 'text',
|
||||
'value' => $data[1] // Der originale Text aus dem Dummy-Array
|
||||
]
|
||||
];
|
||||
$jsonContent = json_encode($blockStructure, JSON_UNESCAPED_UNICODE);
|
||||
|
||||
$articleManager->addArticle(
|
||||
$data[0], // Titel
|
||||
$jsonContent, // Inhalt
|
||||
$authorEmail, // Rotierende Autoren-E-Mail
|
||||
$data[2], // Kategorie
|
||||
$data[3] // Tags
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $articleManager;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
require_once 'DatabaseInitializer.php';
|
||||
require_once 'ArticleManagerDAO.php';
|
||||
require_once 'Article.php';
|
||||
/**
|
||||
@@ -9,60 +10,35 @@ require_once 'Article.php';
|
||||
class DatabaseArticleManager implements ArticleManagerDAO {
|
||||
|
||||
private static $instance = null;
|
||||
private $dbPath;
|
||||
|
||||
/**
|
||||
* Konstruktor
|
||||
*
|
||||
* Erstellt die Datenbankverbindung und die Tabelle articles.
|
||||
* @throws InternalServerErrorException
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
if (!file_exists(__DIR__ . '/../../db/articles.db')) {
|
||||
try {
|
||||
|
||||
$db = $this->getConnection();
|
||||
|
||||
// Tabelle für Beiträge
|
||||
$db->exec("
|
||||
CREATE TABLE articles (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT,
|
||||
content TEXT,
|
||||
author TEXT,
|
||||
category TEXT,
|
||||
tags TEXT,
|
||||
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);");
|
||||
|
||||
// Tabelle für Likes
|
||||
$db->exec("
|
||||
CREATE TABLE likes (
|
||||
article_id INTEGER,
|
||||
user_id TEXT,
|
||||
PRIMARY KEY (article_id, user_id),
|
||||
FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE
|
||||
);");
|
||||
unset($db);
|
||||
} catch (PDOException $e) {
|
||||
throw new InternalServerErrorException($e->getMessage());
|
||||
}
|
||||
}
|
||||
$this->dbPath = __DIR__ . '/../../db/eduforgeDB.db';
|
||||
DatabaseInitializer::initialize($this->dbPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Baut die Verbindung zur Datenbank auf.
|
||||
* @throws InternalServerErrorException
|
||||
*
|
||||
* @return PDO Datenbankverbindung
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function getConnection()
|
||||
{
|
||||
try {
|
||||
$user = 'root';
|
||||
$pw = null;
|
||||
$dsn = 'sqlite:' . __DIR__ . '/../../db/articles.db';
|
||||
return new PDO($dsn, $user, $pw);
|
||||
$db = new PDO('sqlite:' . $this->dbPath, null, null);
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->exec('PRAGMA foreign_keys = ON;');
|
||||
return $db;
|
||||
} catch (PDOException $e) {
|
||||
throw new InternalServerErrorException($e->getMessage());
|
||||
throw new RuntimeException("internal_error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'DatabaseInitializer.php';
|
||||
require_once "CommentManagerDAO.php";
|
||||
require_once "Comment.php";
|
||||
|
||||
@@ -12,43 +12,15 @@ require_once "Comment.php";
|
||||
class DatabaseCommentManager implements CommentManagerDAO
|
||||
{
|
||||
private static $instance = null;
|
||||
private $dbPath;
|
||||
|
||||
/**
|
||||
* Erstellt die Kommentartabelle, falls diese noch nicht existiert.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
try {
|
||||
$db = $this->getConnection();
|
||||
|
||||
$db->exec("
|
||||
CREATE TABLE IF NOT EXISTS comments (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
article_id INTEGER NOT NULL,
|
||||
parent_comment_id INTEGER NULL,
|
||||
author TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
");
|
||||
|
||||
$columns = $db->query("PRAGMA table_info(comments);")->fetchAll(PDO::FETCH_ASSOC);
|
||||
$hasParentColumn = false;
|
||||
|
||||
foreach ($columns as $column) {
|
||||
if ($column["name"] === "parent_comment_id") {
|
||||
$hasParentColumn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasParentColumn) {
|
||||
$db->exec("ALTER TABLE comments ADD COLUMN parent_comment_id INTEGER NULL;");
|
||||
}
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException("internal_error");
|
||||
}
|
||||
$this->dbPath = __DIR__ . '/../../db/eduforgeDB.db';
|
||||
DatabaseInitializer::initialize($this->dbPath);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,13 +31,10 @@ class DatabaseCommentManager implements CommentManagerDAO
|
||||
private function getConnection()
|
||||
{
|
||||
try {
|
||||
$dsn = 'sqlite:' . __DIR__ . '/../../db/comments.db';
|
||||
|
||||
$db = new PDO($dsn, null, null);
|
||||
$db = new PDO('sqlite:' . $this->dbPath, null, null);
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$db->exec('PRAGMA foreign_keys = ON;');
|
||||
return $db;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException("internal_error");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
/**
|
||||
* Diese Klasse legt einmalig beim allerersten Start in der exakt korrekten Reihenfolge die Tabellen an
|
||||
*
|
||||
* @author Niklas Ortmann
|
||||
*/
|
||||
class DatabaseInitializer {
|
||||
public static function initialize($dbPath) {
|
||||
if (!file_exists($dbPath)) {
|
||||
try {
|
||||
$db = new PDO('sqlite:' . $dbPath);
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
$db->exec('PRAGMA foreign_keys = ON;');
|
||||
|
||||
$db->exec("
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
email TEXT PRIMARY KEY,
|
||||
vorname TEXT NOT NULL,
|
||||
nachname TEXT NOT NULL,
|
||||
password TEXT NOT NULL
|
||||
);
|
||||
");
|
||||
|
||||
$db->exec("
|
||||
CREATE TABLE IF NOT EXISTS articles (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT,
|
||||
content TEXT,
|
||||
author TEXT,
|
||||
category TEXT,
|
||||
tags TEXT,
|
||||
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (author) REFERENCES users(email) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
);
|
||||
");
|
||||
|
||||
$db->exec("
|
||||
CREATE TABLE IF NOT EXISTS likes (
|
||||
article_id INTEGER,
|
||||
user_id TEXT,
|
||||
PRIMARY KEY (article_id, user_id),
|
||||
FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (user_id) REFERENCES users(email) ON DELETE CASCADE
|
||||
);
|
||||
");
|
||||
|
||||
$db->exec("
|
||||
CREATE TABLE IF NOT EXISTS comments (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
article_id INTEGER NOT NULL,
|
||||
parent_comment_id INTEGER NULL,
|
||||
author TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (article_id) REFERENCES articles(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (author) REFERENCES users(email) ON DELETE CASCADE,
|
||||
FOREIGN KEY (parent_comment_id) REFERENCES comments(id) ON DELETE CASCADE
|
||||
);
|
||||
");
|
||||
|
||||
$initializer = new self();
|
||||
$availableEmails = $initializer->seedDummyUsers($db);
|
||||
$initializer->seedDummyArticles($db, $availableEmails);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException("internal-error");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt die Dummy-Benutzer in der Datenbank.
|
||||
*
|
||||
* @param PDO $db Die aktive Datenbankverbindung
|
||||
* @return array Liste der erfolgreich angelegten E-Mail-Adressen
|
||||
*/
|
||||
private function seedDummyUsers(PDO $db): array {
|
||||
$dummyUsers = [
|
||||
['email' => 'max.mustermann@web.de', 'vorname' => 'Max', 'nachname' => 'Mustermann'],
|
||||
['email' => 'erika.mustermann@web.de', 'vorname' => 'Erika', 'nachname' => 'Mustermann'],
|
||||
['email' => 'john.doe@gmail.com', 'vorname' => 'John', 'nachname' => 'Doe'],
|
||||
['email' => 'jane.doe@gmail.com', 'vorname' => 'Jane', 'nachname' => 'Doe'],
|
||||
['email' => 'anna.schmidt@gmx.de', 'vorname' => 'Anna', 'nachname' => 'Schmidt'],
|
||||
['email' => 'thomas.mueller@gmx.de', 'vorname' => 'Thomas', 'nachname' => 'Müller'],
|
||||
['email' => 'sabine.fischer@outlook.com', 'vorname' => 'Sabine', 'nachname' => 'Fischer'],
|
||||
['email' => 'michael.weber@outlook.com', 'vorname' => 'Michael', 'nachname' => 'Weber'],
|
||||
['email' => 'julia.wagner@t-online.de', 'vorname' => 'Julia', 'nachname' => 'Wagner'],
|
||||
['email' => 'stefan.becker@t-online.de', 'vorname' => 'Stefan', 'nachname' => 'Becker']
|
||||
];
|
||||
|
||||
$passwordHash = password_hash("test12345", PASSWORD_DEFAULT);
|
||||
$userInsertStmt = $db->prepare("INSERT INTO users (email, vorname, nachname, password) VALUES (:email, :vorname, :nachname, :password);");
|
||||
|
||||
$availableEmails = [];
|
||||
foreach ($dummyUsers as $user) {
|
||||
$userInsertStmt->execute([
|
||||
':email' => $user['email'],
|
||||
':vorname' => $user['vorname'],
|
||||
':nachname' => $user['nachname'],
|
||||
':password' => $passwordHash
|
||||
]);
|
||||
$availableEmails[] = $user['email'];
|
||||
}
|
||||
|
||||
return $availableEmails;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt die 100 Fachbeiträge in der Datenbank.
|
||||
*
|
||||
* @param PDO $db Die aktive Datenbankverbindung
|
||||
* @param array $availableEmails Pool für die Foreign-Key-Zuweisung des Autors
|
||||
* @return void
|
||||
*/
|
||||
private function seedDummyArticles(PDO $db, array $availableEmails): void
|
||||
{
|
||||
$dummyArticles = [
|
||||
// --- INFORMATIK & MATHE (1-20) ---
|
||||
1 => ["Satz des Pythagoras", "Der Satz des Pythagoras beschreibt das Verhältnis der Seitenlängen in einem rechtwinkligen Dreieck.", "mathe", "Dreiecke, Geometrie"],
|
||||
2 => ["Tunneleffekt", "Der Tunneleffekt beschreibt das quantenmechanische Phänomen, dass Teilchen Barrieren überwinden können.", "physik", "Quantenphysik, Energie"],
|
||||
3 => ["Datenschutz vs Datensicherheit", "Datenschutz schützt Personen, während Datensicherheit Systeme vor unbefugten Zugriffen schützt.", "informatik", "Daten, DSGVO"],
|
||||
4 => ["Einführung in Algorithmen", "Ein Algorithmus ist eine präzise Handlungsanweisung zur Lösung eines vordefinierten Problems.", "informatik", "Code, Logik"],
|
||||
5 => ["Primzahlen im Detail", "Primzahlen sind natürliche Zahlen, die nur durch eins und sich selbst ohne Rest teilbar sind.", "mathe", "Zahlentheorie"],
|
||||
6 => ["Lineare Algebra", "Vektoren und Matrizen bilden das Fundament für moderne Computergrafik und 3D-Engines.", "mathe", "Matrizen, Vektoren"],
|
||||
7 => ["Objektorientierte Programmierung", "Die OOP nutzt Klassen und Objekte, um reale Strukturen im Quellcode abzubilden.", "informatik", "OOP, Klassen"],
|
||||
8 => ["Grundlagen von HTML und CSS", "HTML strukturiert den Inhalt einer Webseite, während CSS für das optische Design zuständig ist.", "informatik", "Web, Frontend"],
|
||||
9 => ["Die Relativitätstheorie", "Einsteins Theorie revolutionierte unser Verständnis von Raum, Zeit und Gravitation massiv.", "physik", "Einstein, Gravitation"],
|
||||
10 => ["Datenbanken und SQL", "Strukturierte Abfragesprachen erlauben das effiziente Speichern und Abrufen großer Datenmengen.", "informatik", "SQL, Datenbank"],
|
||||
11 => ["Wahrscheinlichkeitsrechnung", "Die Stochastik befasst sich mit der mathematischen Analyse von Zufallsexperimenten.", "mathe", "Zufall, Stochastik"],
|
||||
12 => ["Quantencomputing", "Künftige Quantencomputer nutzen Qubits, um komplexe Berechnungen in Rekordzeit zu lösen.", "informatik", "Hardware, Zukunft"],
|
||||
13 => ["Die Fibonacci-Folge", "Diese Zahlenreihe beschreibt mathematische Wachstumsmuster, die oft in der Natur vorkommen.", "mathe", "Zahlen, Natur"],
|
||||
14 => ["Thermodynamik", "Die Hauptsätze der Thermodynamik regeln den Energieaustausch und die Entropie in Systemen.", "physik", "Energie, Wärme"],
|
||||
15 => ["Cybersecurity Grundlagen", "Die Absicherung von Netzwerken erfordert Firewalls, Verschlüsselung und regelmäßige Audits.", "informatik", "Sicherheit, Hacker"],
|
||||
16 => ["Kryptographie", "Asymmetrische Verschlüsselungsverfahren sichern heutzutage den gesamten Datenverkehr im Web.", "informatik", "Krypto, Security"],
|
||||
17 => ["Analysis und Ableitungen", "Die Differentialrechnung untersucht die lokalen Änderungsraten von mathematischen Funktionen.", "mathe", "Analysis, Funktionen"],
|
||||
18 => ["Schwarze Löcher", "Diese Regionen im Raum besitzen eine so starke Gravitation, dass selbst Licht nicht entkommt.", "physik", "Astronomie, Kosmos"],
|
||||
19 => ["Git Versionsverwaltung", "Git erlaubt Entwicklern das parallele Arbeiten an Code-Projekten ohne Datenverlust.", "informatik", "Git, DevOps"],
|
||||
20 => ["Künstliche Intelligenz", "Neuronale Netze versuchen das menschliche Gehirn für maschinelles Lernen nachzubilden.", "informatik", "KI, Software"],
|
||||
|
||||
// --- CHEMIE & BIOLOGIE (21-40) ---
|
||||
21 => ["Das Periodensystem", "Die Elemente sind nach ihrer Ordnungszahl und chemischen Eigenschaften geordnet.", "chemie", "Elemente, Moleküle"],
|
||||
22 => ["Photosynthese", "Pflanzen wandeln mithilfe von Sonnenlicht Kohlendioxid und Wasser in Glukose und Sauerstoff um.", "biologie", "Pflanzen, Energie"],
|
||||
23 => ["Aufbau einer Zelle", "Die Zelle ist die kleinste lebende Einheit aller Organismen mit spezialisierten Organellen.", "biologie", "Zellen, Biologie"],
|
||||
24 => ["Säuren und Basen", "Der pH-Wert misst die Konzentration von Wasserstoff-Ionen in einer wässrigen Lösung.", "chemie", "Labor, pH-Wert"],
|
||||
25 => ["Die DNA-Struktur", "Die Doppelhelix enthält den genetischen Bauplan für die Entwicklung aller Lebewesen.", "biologie", "Genetik, Erbgut"],
|
||||
26 => ["Chemische Bindungen", "Kovalente Bindungen entstehen durch das Teilen von Elektronenpaaren zwischen Atomen.", "chemie", "Atome, Bindung"],
|
||||
27 => ["Das Immunsystem", "Weiße Blutkörperchen und Antikörper schützen den menschlichen Körper vor Krankheitserregern.", "biologie", "Gesundheit, Abwehr"],
|
||||
28 => ["Katalysatoren", "Katalysatoren beschleunigen chemische Reaktionen, ohne dabei selbst verbraucht zu werden.", "chemie", "Reaktion, Chemie"],
|
||||
29 => ["Ökosystem Wald", "Das Zusammenspiel von Flora, Fauna und Klima bildet ein hochsensibles ökologisches System.", "biologie", "Natur, Wald"],
|
||||
30 => ["Die Mendelschen Regeln", "Diese Grundgesetze der Vererbung beschreiben, wie Merkmale an Nachkommen weitergegeben werden.", "biologie", "Genetik, Erbung"],
|
||||
31 => ["Zustandsformen der Materie", "Fest, flüssig und gasförmig sind die klassischen Aggregatzustände von Stoffen.", "chemie", "Physik, Materie"],
|
||||
32 => ["Evolutionstheorie", "Charles Darwin begründete die Theorie der natürlichen Auslese und Anpassung von Arten.", "biologie", "Darwin, Evolution"],
|
||||
33 => ["Organische Chemie", "Die Chemie der Kohlenstoffverbindungen bildet die Basis für alles bekannte Leben.", "chemie", "Kohlenstoff, Chemie"],
|
||||
34 => ["Das menschliche Gehirn", "Milliarden von Neuronen kommunizieren über Synapsen, um Reize und Gedanken zu verarbeiten.", "biologie", "Neurologie, Nerven"],
|
||||
35 => ["Der Wasserkreislauf", "Verdunstung, Kondensation und Niederschlag halten das Wasser auf der Erde in Bewegung.", "geographie", "Wasser, Klima"],
|
||||
36 => ["Aggregatzustände von Wasser", "Wasser zeigt ungewöhnliche Eigenschaften wie die Dichteanomalie beim Gefrieren.", "chemie", "Wasser, Eis"],
|
||||
37 => ["Blutkreislauf des Menschen", "Das Herz pumpt sauerstoffreiches Blut durch Arterien in alle Organe des Körpers.", "biologie", "Herz, Medizin"],
|
||||
38 => ["Das Ohmsche Gesetz", "Es beschreibt den direkten Zusammenhang zwischen Spannung, Stromstärke und Widerstand.", "physik", "Strom, Elektronik"],
|
||||
39 => ["Plattentektonik", "Die Bewegung der Kontinentalplatten führt zu Erdbeben, Vulkanismus und Gebirgsbildung.", "geographie", "Erde, Geologie"],
|
||||
40 => ["Proteine und Enzyme", "Enzyme wirken als Biokatalysatoren und steuern fast alle Stoffwechselprozesse.", "biologie", "Biochemie, Enzyme"],
|
||||
|
||||
// --- GESCHICHTE & WIRTSCHAFT (41-60) ---
|
||||
41 => ["Das Römische Reich", "Vom Stadtstaat zum Weltreich prägte Rom die Rechts- und Kulturgeschichte Europas.", "geschichte", "Antike, Rom"],
|
||||
42 => ["Die Französische Revolution", "Freiheit, Gleichheit, Brüderlichkeit beendeten 1789 die absolute Monarchie in Frankreich.", "geschichte", "Europa, Politik"],
|
||||
43 => ["Inflation erklärt", "Inflation bezeichnet die kontinuierliche Geldentwertung und den Kaufkraftverlust.", "wirtschaft", "Geld, Finanzen"],
|
||||
44 => ["Die Industrielle Revolution", "Die Erfindung der Dampfmaschine veränderte die Produktion und die Gesellschaft tiefgreifend.", "geschichte", "Industrie, Arbeit"],
|
||||
45 => ["Angebot und Nachfrage", "Dieses fundamentale Marktgesetz bestimmt den Preis von Gütern in einer freien Wirtschaft.", "wirtschaft", "Markt, Preise"],
|
||||
46 => ["Der Buchdruck", "Johannes Gutenbergs Erfindung revolutionierte die Verbreitung von Wissen im Mittelalter.", "geschichte", "Medien, Wissen"],
|
||||
47 => ["Die Entdeckung Amerikas", "Kolumbus' Seereise im Jahr 1492 leitete das Zeitalter der Kolonialisierung ein.", "geschichte", "Entdeckung, Seefahrt"],
|
||||
48 => ["Kryptowährungen", "Bitcoin nutzt Blockchain-Technologie, um dezentralen digitalen Werttransfer zu erlauben.", "wirtschaft", "Blockchain, Finanzen"],
|
||||
49 => ["Das antike Griechenland", "Die Wiege der Demokratie und Philosophie brachte Denker wie Sokrates und Platon hervor.", "geschichte", "Antike, Philosophie"],
|
||||
50 => ["Globalisierung", "Die weltweite Verflechtung in Wirtschaft, Kultur und Politik bringt Chancen und Risiken.", "wirtschaft", "Weltwirtschaft, Handel"],
|
||||
51 => ["Der Dreißigjährige Krieg", "Ein religiöser und politischer Konflikt verwüstete zwischen 1618 und 1648 Mitteleuropa.", "geschichte", "Krieg, Europa"],
|
||||
52 => ["Die Weimarer Republik", "Die erste deutsche Demokratie scheiterte an wirtschaftlichen und politischen Krisen.", "geschichte", "Deutschland, Weimar"],
|
||||
53 => ["Aktien und Börse", "Unternehmen beschaffen sich Kapital durch die Ausgabe von Anteilen an Investoren.", "wirtschaft", "Aktien, Investieren"],
|
||||
54 => ["Das alte Ägypten", "Pharaonen, Pyramiden und Hieroglyphen zeugen von einer hochentwickelten Hochkultur am Nil.", "geschichte", "Ägypten, Antike"],
|
||||
55 => ["Der Kalte Krieg", "Das Wettrüsten zwischen USA und UdSSR prägte die globale Politik der Nachkriegszeit.", "geschichte", "Ost-West, Politik"],
|
||||
56 => ["Zentralbanken und Leitzins", "Durch Zinsänderungen steuern Notenbanken die Geldmenge und bekämpfen Inflation.", "wirtschaft", "Zinsen, Geldpolitik"],
|
||||
57 => ["Die Seidenstraße", "Das historische Netzwerk von Handelsrouten verband über Jahrhunderte Asien und Europa.", "geschichte", "Handel, Asien"],
|
||||
58 => ["Das Mittelalter", "Ritter, Burgen und das Feudalsystem prägten diese tausendjährige Epoche Europas.", "geschichte", "Mittelalter, Feudalismus"],
|
||||
59 => ["Planwirtschaft vs Marktwirtschaft", "Zentrale staatliche Steuerung steht dem freien Spiel der Marktkräfte gegenüber.", "wirtschaft", "Systeme, Wirtschaft"],
|
||||
60 => ["Die Berliner Mauer", "Ihr Bau 1961 zementierte die Teilung Deutschlands, ihr Fall 1989 beendete sie.", "geschichte", "DDR, Wiedervereinigung"],
|
||||
|
||||
// --- ANWENDUNGEN & WEITERE THEMEN (61-100) ---
|
||||
61 => ["Cloud Computing", "Das Auslagern von Rechenleistung in das Internet spart lokale IT-Infrastruktur ein.", "informatik", "Cloud, Web"],
|
||||
62 => ["Responsive Webdesign", "Moderne Webseiten passen ihr Layout dynamisch an Smartphones und Desktops an.", "informatik", "Design, CSS"],
|
||||
63 => ["Der Treibhauseffekt", "Gase in der Atmosphäre verhindern das Entweichen von Wärme ins Weltall.", "physik", "Klima, Umwelt"],
|
||||
64 => ["Mechanik und Kräfte", "Die Newtonschen Axiome beschreiben, wie Kräfte auf Körper wirken und sie bewegen.", "physik", "Newton, Kraft"],
|
||||
65 => ["Die Mendelschen Gesetze", "Die Vererbung von Genen folgt klaren statistischen Wahrscheinlichkeiten.", "biologie", "Genetik, Erbsen"],
|
||||
66 => ["Lichtgeschwindigkeit", "Im Vakuum bewegt sich Licht mit knapp 300.000 Kilometern pro Sekunde.", "physik", "Licht, Relativität"],
|
||||
67 => ["Die Funktion von APIs", "Programmierschnittstellen erlauben den Datenaustausch zwischen verschiedenen Systemen.", "informatik", "API, Schnittstelle"],
|
||||
68 => ["Der Goldstandard", "Ein historischen Währungssystem, bei dem Geld durch echtes Gold gedeckt war.", "wirtschaft", "Gold, Währung"],
|
||||
69 => ["Der Wiener Kongress", "1815 ordneten die europäischen Mächte die Landkarte nach den Napoleonischen Kriegen neu.", "geschichte", "Europa, Diplomatie"],
|
||||
70 => ["Integrierte Schaltkreise", "Mikrochips enthalten Millionen Transistoren auf kleinstem Raum für Logikschaltungen.", "informatik", "Hardware, Chips"],
|
||||
71 => ["Die Magellan-Expedition", "Die erste erfolgreiche Weltumsegelung bewies praktisch die Kugelgestalt der Erde.", "geschichte", "Seefahrt, Erde"],
|
||||
72 => ["Das Internet der Dinge", "Alltagsgegenstände werden vernetzt, um smarte Automatisierungen zu ermöglichen.", "informatik", "IoT, SmartHome"],
|
||||
73 => ["Halbwertszeit", "Die Zeitspanne, in der sich die Hälfte der instabilen Atome radioaktiv abbaut.", "physik", "Atomphysik, Strahlung"],
|
||||
74 => ["Elektromagnetismus", "Die Verknüpfung von elektrischen Strömen und magnetischen Feldern treibt Motoren an.", "physik", "Strom, Magnet"],
|
||||
75 => ["Das Ökosystem Meer", "Ozeane regulieren das Weltklima und bieten Lebensraum für unzählige Arten.", "biologie", "Meer, Ökologie"],
|
||||
76 => ["Einführung in Docker", "Containerisierung isoliert Anwendungen samt Abhängigkeiten für stabilen Betrieb.", "informatik", "Docker, DevOps"],
|
||||
77 => ["Das Römische Recht", "Viele moderne europäische Gesetzbücher basieren auf antiken römischen Rechtsprinzipien.", "geschichte", "Recht, Gesetz"],
|
||||
78 => ["Verhaltensbiologie", "Untersuchung von angeborenen und erlernten Verhaltensweisen bei Mensch und Tier.", "biologie", "Verhalten, Tiere"],
|
||||
79 => ["Verschlüsselung im Alltag", "HTTPS schützt Passwörter und Zahlungsdaten beim Surfen vor dem Mitlesen.", "informatik", "Web, HTTPS"],
|
||||
80 => ["Die Magna Carta", "1215 schränkte dieses Dokument die absolute Macht des englischen Königs ein.", "geschichte", "England, Verfassung"],
|
||||
81 => ["Marktversagen", "Wenn der freie Markt Ressourcen unvollständig verteilt, muss der Staat eingreifen.", "wirtschaft", "Markt, Staat"],
|
||||
82 => ["Optische Linsen", "Konvexe und konkave Linsen brechen Licht für Brillen, Mikroskope und Kameras.", "physik", "Optik, Licht"],
|
||||
83 => ["Die Entstehung der Erde", "Vor rund 4,5 Milliarden Jahren ballte sich kosmischer Staub zu unserem Planeten.", "geographie", "Erde, Kosmos"],
|
||||
84 => ["Grundlagen von JavaScript", "Diese Skriptsprache macht statische Webseiten interaktiv und dynamisch nutzbar.", "informatik", "JS, Webentwicklung"],
|
||||
85 => ["Die industrielle Landwirtschaft", "Moderne Techniken sichern Welternährung, belasten jedoch oft die Umwelt.", "biologie", "Landwirtschaft, Umwelt"],
|
||||
86 => ["Das Schwarze Jahr 1929", "Der New Yorker Börsencrash löste die verheerende Weltwirtschaftskrise aus.", "geschichte", "Krise, Finanzen"],
|
||||
87 => ["Die Evolution des Menschen", "Der Stammbaum des Homo Sapiens entwickelte sich über Millionen Jahre in Afrika.", "biologie", "Mensch, Evolution"],
|
||||
88 => ["Einführung in Linux", "Das Open-Source-Betriebssystem bildet das Rückgrat moderner Server-Infrastrukturen.", "informatik", "Linux, OS"],
|
||||
89 => ["Der Urknall", "Die Urknalltheorie beschreibt den Beginn des Universums aus einer Singularität.", "physik", "Astronomie, Urknall"],
|
||||
90 => ["Das Periodensystem der Elemente", "Dmitri Mendelejew ordnete Elemente logisch nach ihren Atommassen.", "chemie", "Periodensystem, Chemie"],
|
||||
91 => ["Die Hanse", "Ein mächtiger mittelalterlicher Bund von Kaufleuten dominierte den Nordseehandel.", "geschichte", "Handel, Mittelalter"],
|
||||
92 => ["Wirtschaftswachstum", "Die Steigerung des Bruttoinlandsprodukts gilt oft als Indikator für Wohlstand.", "wirtschaft", "BIP, Finanzen"],
|
||||
93 => ["Neuronale Netze", "Diese Strukturen lernen durch mathematische Gewichtung aus riesigen Datenmengen.", "informatik", "KI, Mathematik"],
|
||||
94 => ["Der Erste Weltkrieg", "Der globale Konflikt von 1914 bis 1918 zerstörte das alte europäische Machtgefüge.", "geschichte", "Europa, Krieg"],
|
||||
95 => ["Das Gehirn und Hormone", "Botenstoffe steuern Gefühle, Schlafzyklen und Reaktionen des Körpers.", "biologie", "Medizin, Hormone"],
|
||||
96 => ["SQL Joins erklärt", "Joins verknüpfen Daten aus mehreren Tabellen über gemeinsame Schlüssel.", "informatik", "SQL, Datenbanken"],
|
||||
97 => ["Wellen-Teilchen-Dualismus", "Quantenobjekte zeigen je nach Messaufbau Eigenschaften von Wellen oder Teilchen.", "physik", "Quanten, Licht"],
|
||||
98 => ["Der Absolutismus", "Der Sonnenkönig Ludwig XIV. verkörperte die unbeschränkte Herrschaft des Monarchen.", "geschichte", "Frankreich, Monarchie"],
|
||||
99 => ["Die Funktion von Routern", "Netzwerkgeräte leiten Datenpakete über IP-Adressen an den richtigen Empfänger.", "informatik", "Netzwerk, Internet"],
|
||||
100 => ["Die Entstehung des Geldes", "Vom Tauschhandel über Naturalgeld bis hin zu modernen digitalen Fiat-Währungen.", "wirtschaft", "Geld, Geschichte"]
|
||||
|
||||
];
|
||||
$articleInsertStmt = $db->prepare("
|
||||
INSERT INTO articles (title, content, author, category, tags)
|
||||
VALUES (:title, :content, :author, :category, :tags);");
|
||||
|
||||
foreach ($dummyArticles as $article) {
|
||||
// Bestimmt per Zufall einen Autor aus dem Pool der gültigen E-Mails
|
||||
$randomAuthor = $availableEmails[array_rand($availableEmails)];
|
||||
|
||||
$articleInsertStmt->execute([
|
||||
':title' => $article[0],
|
||||
':content' => $article[1],
|
||||
':author' => $randomAuthor,
|
||||
':category' => $article[2],
|
||||
':tags' => $article[3]
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'DatabaseInitializer.php';
|
||||
require_once "UserManagerDAO.php";
|
||||
|
||||
/**
|
||||
@@ -11,6 +11,7 @@ require_once "UserManagerDAO.php";
|
||||
class DatabaseUserManager implements UserManagerDAO {
|
||||
|
||||
private static $instance = null;
|
||||
private $dbPath;
|
||||
|
||||
/**
|
||||
* Konstruktor.
|
||||
@@ -22,23 +23,8 @@ class DatabaseUserManager implements UserManagerDAO {
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
try {
|
||||
$db = $this->getConnection();
|
||||
|
||||
$db->exec("
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
email TEXT PRIMARY KEY,
|
||||
vorname TEXT NOT NULL,
|
||||
nachname TEXT NOT NULL,
|
||||
password TEXT NOT NULL
|
||||
);
|
||||
");
|
||||
|
||||
unset($db);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException("Benutzerdatenbank konnte nicht erstellt werden.");
|
||||
}
|
||||
$this->dbPath = __DIR__ . '/../../db/eduforgeDB.db';
|
||||
DatabaseInitializer::initialize($this->dbPath);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,15 +37,12 @@ class DatabaseUserManager implements UserManagerDAO {
|
||||
private function getConnection()
|
||||
{
|
||||
try {
|
||||
$dsn = 'sqlite:' . __DIR__ . '/../../db/users.db';
|
||||
|
||||
$db = new PDO($dsn, null, null);
|
||||
$db = new PDO('sqlite:' . $this->dbPath, null, null);
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$db->exec('PRAGMA foreign_keys = ON;');
|
||||
return $db;
|
||||
|
||||
} catch (PDOException $e) {
|
||||
throw new RuntimeException("Verbindung zur Benutzerdatenbank fehlgeschlagen.");
|
||||
throw new RuntimeException("internal_error");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,38 +12,8 @@ require_once "DatabaseUserManager.php";
|
||||
class UserManager {
|
||||
|
||||
public static function getInstance() {
|
||||
$userManager = DatabaseUserManager::getInstance();
|
||||
|
||||
/*
|
||||
* Dummy-User anlegen, falls sie noch nicht existieren.
|
||||
* Passwort für alle User: test12345
|
||||
*/
|
||||
$dummyUsers = [
|
||||
['email' => 'max.mustermann@web.de', 'vorname' => 'Max', 'nachname' => 'Mustermann'],
|
||||
['email' => 'erika.mustermann@web.de', 'vorname' => 'Erika', 'nachname' => 'Mustermann'],
|
||||
['email' => 'john.doe@gmail.com', 'vorname' => 'John', 'nachname' => 'Doe'],
|
||||
['email' => 'jane.doe@gmail.com', 'vorname' => 'Jane', 'nachname' => 'Doe'],
|
||||
['email' => 'anna.schmidt@gmx.de', 'vorname' => 'Anna', 'nachname' => 'Schmidt'],
|
||||
['email' => 'thomas.mueller@gmx.de', 'vorname' => 'Thomas', 'nachname' => 'Müller'],
|
||||
['email' => 'sabine.fischer@outlook.com', 'vorname' => 'Sabine', 'nachname' => 'Fischer'],
|
||||
['email' => 'michael.weber@outlook.com', 'vorname' => 'Michael', 'nachname' => 'Weber'],
|
||||
['email' => 'julia.wagner@t-online.de', 'vorname' => 'Julia', 'nachname' => 'Wagner'],
|
||||
['email' => 'stefan.becker@t-online.de', 'vorname' => 'Stefan', 'nachname' => 'Becker']
|
||||
];
|
||||
return DatabaseUserManager::getInstance();
|
||||
|
||||
$passwordHash = password_hash("test12345", PASSWORD_DEFAULT);
|
||||
|
||||
foreach ($dummyUsers as $user) {
|
||||
if ($userManager->findUser($user['email']) == null) {
|
||||
$userManager->addUser(
|
||||
$user['email'],
|
||||
$user['vorname'],
|
||||
$user['nachname'],
|
||||
$passwordHash
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $userManager;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Prüft, ob eine Suchanfrage gültig ist.
|
||||
*
|
||||
* Erlaubt werden Buchstaben, Zahlen, Umlaute, typische Satzzeichen und Leerzeichen.
|
||||
* Die Länge muss zwischen 1 und 50 Zeichen liegen.
|
||||
*
|
||||
* @param string $query Zu prüfender Suchbegriff
|
||||
*
|
||||
* @return bool true wenn die Suche gültig ist, sonst false
|
||||
*/
|
||||
function searchQueryValidator($query)
|
||||
{
|
||||
$query = trim($query);
|
||||
|
||||
// Mindestens 1 Zeichen, maximal 50 Zeichen
|
||||
$length = mb_strlen($query);
|
||||
if ($length < 1 || $length > 50) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Erlaubt Buchstaben (inkl. Umlaut/ß), Zahlen, Leerzeichen sowie ?, !, ., -, _
|
||||
$searchPattern = '/^[a-zA-Z0-9äöüÄÖÜß\s?!.,\-_]+$/u';
|
||||
|
||||
return preg_match($searchPattern, $query) === 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prüft, ob das gewählte Treffer-Limit erlaubt ist.
|
||||
*
|
||||
* @param int|string $limit Das zu prüfende Limit
|
||||
*
|
||||
* @return bool true wenn das Limit 10, 20, 50 oder 100 ist, sonst false
|
||||
*/
|
||||
function searchLimitValidator($limit)
|
||||
{
|
||||
$allowedLimits = [10, 20, 50, 100];
|
||||
return in_array((int)$limit, $allowedLimits, true);
|
||||
}
|
||||
Reference in New Issue
Block a user