From 6303da2633210fa5ca8ee52f3f5e9d0a5396d72f Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Tue, 30 Dec 2025 01:09:15 +0100 Subject: [PATCH] asdasd --- partials/landing/community/index.php | 125 ++++++++++++++++ partials/landing/community/thread.php | 82 ++++++++++ public/page/community.php | 206 +------------------------- public/page/community_thread.php | 93 +----------- src/App/Community.php | 120 +++++++++++++++ 5 files changed, 329 insertions(+), 297 deletions(-) create mode 100644 partials/landing/community/index.php create mode 100644 partials/landing/community/thread.php create mode 100644 src/App/Community.php diff --git a/partials/landing/community/index.php b/partials/landing/community/index.php new file mode 100644 index 0000000..4683300 --- /dev/null +++ b/partials/landing/community/index.php @@ -0,0 +1,125 @@ +pdo(); +$userId = $_SESSION['user_id'] ?? null; +$error = ''; +$search = trim((string)($_GET['q'] ?? '')); + +$communityCfg = require __DIR__ . '/../../../config/community.php'; +$community = $pdo ? new \App\Community($pdo, $communityCfg) : null; + +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'thread_create') { + if (!$userId) { + $error = 'Bitte einloggen, um Fragen zu stellen.'; + } elseif ($community) { + $title = trim((string)($_POST['title'] ?? '')); + $body = trim((string)($_POST['body'] ?? '')); + if ($title === '' || $body === '') { + $error = 'Titel und Text sind erforderlich.'; + } else { + $community->createThread((int)$userId, $title, $body); + redirect('/community'); + } + } +} + +$threads = $community ? ($search !== '' ? $community->searchThreads($search, 50) : $community->listThreads(50)) : []; +?> +
+
+

Community

+

Forum

+ +
+ + +
+
+
+ + +
+ +
+ + + + Login für neue Frage + +
+ +
+ + computePoints((int)$t['uid']) : 0.0; + $lvl = $community ? $community->membershipLevel($pts) : ['label'=>'','icon'=>'']; + ?> +
+
+
+ + + ( Punkte) + Beiträge: + Antworten: +
+

+

200 ? '…' : '' ?>

+
+
+ + +

Keine Treffer.

+ +
+
+
+ + + + + + diff --git a/partials/landing/community/thread.php b/partials/landing/community/thread.php new file mode 100644 index 0000000..98d5a16 --- /dev/null +++ b/partials/landing/community/thread.php @@ -0,0 +1,82 @@ +pdo(); +$userId = $_SESSION['user_id'] ?? null; +$error = ''; +$threadId = (int)($_GET['id'] ?? 0); + +$communityCfg = require __DIR__ . '/../../../config/community.php'; +$community = $pdo ? new \App\Community($pdo, $communityCfg) : null; + +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'reply') { + if (!$userId) { + $error = 'Bitte einloggen, um zu antworten.'; + } elseif ($community) { + $body = trim((string)($_POST['body'] ?? '')); + if ($body === '') { + $error = 'Antwort darf nicht leer sein.'; + } else { + $community->createPost((int)$userId, $threadId, $body); + redirect('/community_thread?id=' . $threadId); + } + } +} + +$thread = $community ? $community->getThread($threadId) : null; +$posts = $community ? $community->listPosts($threadId) : []; + +if (!$thread) { + http_response_code(404); + echo "

Thread nicht gefunden.

"; + return; +} +?> +
+
+

Community

+

+

Von ·

+
+
+

+
+
+ +

Antworten ()

+
+ +
+
+
+ + +
+

+
+
+ + +

Noch keine Antworten.

+ +
+ + +
+ + + +
+ +
+ + +
+ +
+ +

Bitte einloggen, um zu antworten.

+ +
+
diff --git a/public/page/community.php b/public/page/community.php index 2c40502..e85cf33 100644 --- a/public/page/community.php +++ b/public/page/community.php @@ -1,208 +1,4 @@ pdo(); -$userId = $_SESSION['user_id'] ?? null; -$error = ''; - -if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'thread_create') { - if (!$userId) { - $error = 'Bitte einloggen, um Fragen zu stellen.'; - } elseif ($pdo) { - $title = trim((string)($_POST['title'] ?? '')); - $body = trim((string)($_POST['body'] ?? '')); - if ($title === '' || $body === '') { - $error = 'Titel und Text sind erforderlich.'; - } else { - $pdo->prepare('CREATE TABLE IF NOT EXISTS forum_threads ( - id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, - user_id BIGINT UNSIGNED NOT NULL, - title VARCHAR(200) NOT NULL, - body TEXT NOT NULL, - created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci')->execute(); - $pdo->prepare('INSERT INTO forum_threads (user_id, title, body) VALUES (:uid, :title, :body)') - ->execute(['uid' => $userId, 'title' => $title, 'body' => $body]); - header('Location: /community'); - exit; - } - } -} - -$threads = []; -$configCommunity = require __DIR__ . '/../../config/community.php'; -$pointsCfg = $configCommunity['points'] ?? []; -$levelsCfg = $configCommunity['levels'] ?? []; -$search = trim((string)($_GET['q'] ?? '')); -if ($pdo) { - $pdo->prepare('CREATE TABLE IF NOT EXISTS forum_posts ( - id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, - thread_id BIGINT UNSIGNED NOT NULL, - user_id BIGINT UNSIGNED NOT NULL, - body TEXT NOT NULL, - created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - INDEX idx_thread (thread_id) - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci')->execute(); - - $conditions = []; - $params = []; - if ($search !== '') { - $tokens = preg_split('/\\s+/', $search); - $i = 0; - foreach ($tokens as $tok) { - $tok = trim($tok); - if ($tok === '') continue; - $ph1 = 't' . $i . '_title'; - $ph2 = 't' . $i . '_body'; - $i++; - $conditions[] = "(ft.title LIKE :$ph1 OR ft.body LIKE :$ph2)"; - $params[$ph1] = '%' . $tok . '%'; - $params[$ph2] = '%' . $tok . '%'; - } - } - $whereSearch = $conditions ? ('AND ' . implode(' AND ', $conditions)) : ''; - - $sql = "SELECT ft.id, ft.title, ft.body, ft.created_at, - u.id as uid, u.created_at as user_created, - p.display_name, - (SELECT COUNT(*) FROM forum_posts fp WHERE fp.thread_id = ft.id) AS answers, - (SELECT COUNT(*) FROM forum_posts fp2 WHERE fp2.user_id = u.id) + - (SELECT COUNT(*) FROM forum_threads ft2 WHERE ft2.user_id = u.id) AS user_posts - FROM forum_threads ft - JOIN users u ON u.id = ft.user_id - LEFT JOIN user_profiles p ON p.user_id = u.id - WHERE 1=1 $whereSearch - ORDER BY ft.created_at DESC - LIMIT 50"; - $stmt = $pdo->prepare($sql); - $stmt->execute($params); - $threads = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: []; -} - -function compute_points(array $row, \PDO $pdo, array $pointsCfg): float { - $uid = (int)$row['uid']; - $threads = (int)($row['user_posts'] ?? 0); - $answers = (int)($row['answers'] ?? 0); - $eventCreated = (int)$pdo->query("SELECT COUNT(*) FROM events WHERE created_by = {$uid}")->fetchColumn(); - $eventParticipants = (float)$pdo->query("SELECT COUNT(*) FROM event_participants WHERE user_id = {$uid}")->fetchColumn(); - $invites = 0; - return $threads * ($pointsCfg['forum_question'] ?? 0.5) - + $answers * ($pointsCfg['forum_answer'] ?? 1.0) - + $eventCreated * ($pointsCfg['event_create'] ?? 1.0) - + $eventParticipants * ($pointsCfg['event_participation'] ?? 0.1) - + $invites * ($pointsCfg['invite'] ?? 0.5); -} - -function membership_level(float $points, array $levels): array { - usort($levels, fn($a,$b) => ($b['min'] ?? 0) <=> ($a['min'] ?? 0)); - foreach ($levels as $lvl) { - if ($points >= (float)($lvl['min'] ?? 0)) { - return [ - 'label' => $lvl['label'] ?? 'New Daddy', - 'icon' => $lvl['icon'] ?? '', - ]; - } - } - $fallback = $levels ? $levels[count($levels)-1] : ['label' => 'New Daddy','icon' => '']; - return ['label' => $fallback['label'], 'icon' => $fallback['icon'] ?? '']; -} -?> -
-
-

Community

-

Forum

- -
- - -
-
-
- - -
- -
- - - - Login für neue Frage - -
- -
- - -
-
-
- - - ( Punkte) - Beiträge: - Antworten: -
-

-

200 ? '…' : '' ?>

-
-
- - -

Noch keine Fragen gestellt.

- -
-
-
- - - - - - +tpl('community/index', 'landing'); diff --git a/public/page/community_thread.php b/public/page/community_thread.php index cc245cf..aa4ab03 100644 --- a/public/page/community_thread.php +++ b/public/page/community_thread.php @@ -1,95 +1,4 @@ pdo(); -$userId = $_SESSION['user_id'] ?? null; -$id = (int)($_GET['id'] ?? 0); -$error = ''; - -if (!$id) { - http_response_code(404); - exit('

Thread nicht gefunden.

'); -} - -if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'reply') { - if (!$userId) { - $error = 'Bitte einloggen, um zu antworten.'; - } elseif ($pdo) { - $body = trim((string)($_POST['body'] ?? '')); - if ($body === '') { - $error = 'Antwort darf nicht leer sein.'; - } else { - $pdo->prepare('INSERT INTO forum_posts (thread_id, user_id, body) VALUES (:tid, :uid, :body)') - ->execute(['tid' => $id, 'uid' => $userId, 'body' => $body]); - header('Location: /community_thread?id=' . $id); - exit; - } - } -} - -$thread = null; -$posts = []; -if ($pdo) { - $stmt = $pdo->prepare('SELECT ft.*, p.display_name FROM forum_threads ft LEFT JOIN user_profiles p ON p.user_id = ft.user_id WHERE ft.id = :id'); - $stmt->execute(['id' => $id]); - $thread = $stmt->fetch(PDO::FETCH_ASSOC); - if ($thread) { - $stmt = $pdo->prepare('SELECT fp.*, p.display_name FROM forum_posts fp LEFT JOIN user_profiles p ON p.user_id = fp.user_id WHERE fp.thread_id = :id ORDER BY fp.created_at ASC'); - $stmt->execute(['id' => $id]); - $posts = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: []; - } -} - -if (!$thread) { - http_response_code(404); - exit('

Thread nicht gefunden.

'); -} -?> -
-
-

Community

-

-

Von ·

-
-
-

-
-
- -

Antworten ()

-
- -
-
-
- - -
-

-
-
- - -

Noch keine Antworten.

- -
- - -
- - - -
- -
- - -
- -
- -

Bitte einloggen, um zu antworten.

- -
-
+tpl('community/thread', 'landing'); diff --git a/src/App/Community.php b/src/App/Community.php new file mode 100644 index 0000000..51c1a17 --- /dev/null +++ b/src/App/Community.php @@ -0,0 +1,120 @@ +pdo->prepare('INSERT INTO forum_threads (user_id, title, body) VALUES (:uid, :title, :body)'); + $stmt->execute([ + ':uid' => $userId, + ':title' => trim($title), + ':body' => trim($body), + ]); + } + + public function createPost(int $userId, int $threadId, string $body): void + { + $stmt = $this->pdo->prepare('INSERT INTO forum_posts (thread_id, user_id, body) VALUES (:tid, :uid, :body)'); + $stmt->execute([ + ':tid' => $threadId, + ':uid' => $userId, + ':body' => trim($body), + ]); + } + + public function searchThreads(string $query, int $limit = 50): array + { + $conditions = []; + $params = []; + $tokens = array_filter(preg_split('/\s+/', trim($query)) ?: [], fn($t) => $t !== ''); + $i = 0; + foreach ($tokens as $tok) { + $ph1 = ':t' . $i . 'a'; + $ph2 = ':t' . $i . 'b'; + $conditions[] = "(ft.title LIKE $ph1 OR ft.body LIKE $ph2)"; + $params[$ph1] = '%' . $tok . '%'; + $params[$ph2] = '%' . $tok . '%'; + $i++; + } + $where = $conditions ? ('AND ' . implode(' AND ', $conditions)) : ''; + + $sql = "SELECT ft.id, ft.title, ft.body, ft.created_at, + u.id as uid, u.created_at as user_created, + p.display_name, + (SELECT COUNT(*) FROM forum_posts fp WHERE fp.thread_id = ft.id) AS answers, + (SELECT COUNT(*) FROM forum_posts fp2 WHERE fp2.user_id = u.id) + + (SELECT COUNT(*) FROM forum_threads ft2 WHERE ft2.user_id = u.id) AS user_posts + FROM forum_threads ft + JOIN users u ON u.id = ft.user_id + LEFT JOIN user_profiles p ON p.user_id = u.id + WHERE 1=1 $where + ORDER BY ft.created_at DESC + LIMIT :lim"; + $stmt = $this->pdo->prepare($sql); + foreach ($params as $k => $v) { + $stmt->bindValue($k, $v, \PDO::PARAM_STR); + } + $stmt->bindValue(':lim', $limit, \PDO::PARAM_INT); + $stmt->execute(); + return $stmt->fetchAll(\PDO::FETCH_ASSOC) ?: []; + } + + public function listThreads(int $limit = 50): array + { + return $this->searchThreads('', $limit); + } + + public function getThread(int $id): ?array + { + $stmt = $this->pdo->prepare('SELECT ft.*, p.display_name FROM forum_threads ft LEFT JOIN user_profiles p ON p.user_id = ft.user_id WHERE ft.id = :id'); + $stmt->execute([':id' => $id]); + $row = $stmt->fetch(\PDO::FETCH_ASSOC); + return $row ?: null; + } + + public function listPosts(int $threadId): array + { + $stmt = $this->pdo->prepare('SELECT fp.*, p.display_name FROM forum_posts fp LEFT JOIN user_profiles p ON p.user_id = fp.user_id WHERE fp.thread_id = :id ORDER BY fp.created_at ASC'); + $stmt->execute([':id' => $threadId]); + return $stmt->fetchAll(\PDO::FETCH_ASSOC) ?: []; + } + + public function computePoints(int $userId): float + { + $pointsCfg = $this->config['points'] ?? []; + $eventCreated = (int)$this->pdo->query("SELECT COUNT(*) FROM events WHERE created_by = {$userId}")->fetchColumn(); + $eventParticipants = (float)$this->pdo->query("SELECT COUNT(*) FROM event_participants WHERE user_id = {$userId}")->fetchColumn(); + $threadCount = (int)$this->pdo->query("SELECT COUNT(*) FROM forum_threads WHERE user_id = {$userId}")->fetchColumn(); + $answerCount = (int)$this->pdo->query("SELECT COUNT(*) FROM forum_posts WHERE user_id = {$userId}")->fetchColumn(); + $invites = 0; + + return $threadCount * ($pointsCfg['forum_question'] ?? 0.5) + + $answerCount * ($pointsCfg['forum_answer'] ?? 1.0) + + $eventCreated * ($pointsCfg['event_create'] ?? 1.0) + + $eventParticipants * ($pointsCfg['event_participation'] ?? 0.1) + + $invites * ($pointsCfg['invite'] ?? 0.5); + } + + public function membershipLevel(float $points): array + { + $levels = $this->config['levels'] ?? []; + usort($levels, fn($a,$b) => ($b['min'] ?? 0) <=> ($a['min'] ?? 0)); + foreach ($levels as $lvl) { + if ($points >= (float)($lvl['min'] ?? 0)) { + return [ + 'label' => $lvl['label'] ?? 'New Daddy', + 'icon' => $lvl['icon'] ?? '', + ]; + } + } + $fallback = $levels ? $levels[count($levels)-1] : ['label' => 'New Daddy','icon' => '']; + return ['label' => $fallback['label'], 'icon' => $fallback['icon'] ?? '']; + } +}