asdasd
This commit is contained in:
59
partials/landing/search.php
Normal file
59
partials/landing/search.php
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
$app = app();
|
||||||
|
$pdo = $app->pdo();
|
||||||
|
$q = trim((string)($_GET['q'] ?? ''));
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
if ($q !== '' && $pdo) {
|
||||||
|
$search = new \App\Search($pdo);
|
||||||
|
$results = $search->searchEvents($q, 100);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<main class="section">
|
||||||
|
<div class="container">
|
||||||
|
<p class="eyebrow">Suche</p>
|
||||||
|
<h1>Events finden</h1>
|
||||||
|
<form method="get" class="form-grid single" style="margin: 14px 0;">
|
||||||
|
<div class="stack gap-6">
|
||||||
|
<label class="label" for="q">Suchbegriff (Titel, Ort, Beschreibung)</label>
|
||||||
|
<input id="q" name="q" class="input" value="<?= htmlspecialchars($q, ENT_QUOTES) ?>" placeholder="z. B. Berlin oder Spielplatz">
|
||||||
|
</div>
|
||||||
|
<button class="btn" type="submit">Suchen</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php if ($q === ''): ?>
|
||||||
|
<p class="muted">Bitte gib einen Suchbegriff ein.</p>
|
||||||
|
<?php else: ?>
|
||||||
|
<h3 style="margin-top: 16px;"><?= count($results) ?> Ergebnis(se) für „<?= htmlspecialchars($q, ENT_QUOTES) ?>“</h3>
|
||||||
|
<?php if (!$results): ?>
|
||||||
|
<p class="muted">Keine passenden Events gefunden.</p>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="stack gap-12" style="margin-top: 12px;">
|
||||||
|
<?php foreach ($results as $ev): ?>
|
||||||
|
<article class="card">
|
||||||
|
<div class="event__body">
|
||||||
|
<div class="event__meta">
|
||||||
|
<span><?= htmlspecialchars($ev['starts_at'], ENT_QUOTES) ?></span>
|
||||||
|
<span>📍 <?= htmlspecialchars($ev['region'] ?: $ev['city'], ENT_QUOTES) ?></span>
|
||||||
|
<span><?= $ev['visibility'] === 'public' ? 'Öffentlich' : 'Mitglieder' ?></span>
|
||||||
|
<span class="badge"><?= ((int)$ev['allow_kids'] === 1) ? 'Mit Kindern' : 'Ohne Kinder' ?></span>
|
||||||
|
</div>
|
||||||
|
<h3><?= htmlspecialchars($ev['title'], ENT_QUOTES) ?></h3>
|
||||||
|
<p class="muted"><?= htmlspecialchars($ev['teaser_public'], ENT_QUOTES) ?></p>
|
||||||
|
<?php if (!empty($ev['location_label'])): ?>
|
||||||
|
<p class="muted small"><strong>Ort:</strong> <?= htmlspecialchars($ev['location_label'], ENT_QUOTES) ?></p>
|
||||||
|
<?php endif; ?>
|
||||||
|
<details>
|
||||||
|
<summary style="cursor:pointer;">Details anzeigen</summary>
|
||||||
|
<p><?= nl2br(htmlspecialchars($ev['description'], ENT_QUOTES)) ?></p>
|
||||||
|
</details>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
tpl('community/index', 'landing');
|
tpl('index', 'landing','community');
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
tpl('community/thread', 'landing');
|
tpl('thread', 'landing','community');
|
||||||
|
|||||||
@@ -1,75 +1,4 @@
|
|||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
$app = app();
|
tpl('search', 'landing');
|
||||||
$pdo = $app->pdo();
|
|
||||||
$q = trim((string)($_GET['q'] ?? ''));
|
|
||||||
$results = [];
|
|
||||||
|
|
||||||
if ($q !== '' && $pdo) {
|
|
||||||
$like = '%' . $q . '%';
|
|
||||||
$sql = 'SELECT id, title, teaser_public, description, city, region, starts_at, visibility, allow_kids, location_label
|
|
||||||
FROM events
|
|
||||||
WHERE starts_at >= NOW()
|
|
||||||
AND status != "cancelled"
|
|
||||||
AND (title LIKE :q1 OR teaser_public LIKE :q2 OR description LIKE :q3 OR city LIKE :q4 OR region LIKE :q5 OR zip LIKE :q6)
|
|
||||||
ORDER BY starts_at ASC
|
|
||||||
LIMIT 100';
|
|
||||||
$stmt = $pdo->prepare($sql);
|
|
||||||
$stmt->execute([
|
|
||||||
':q1' => $like,
|
|
||||||
':q2' => $like,
|
|
||||||
':q3' => $like,
|
|
||||||
':q4' => $like,
|
|
||||||
':q5' => $like,
|
|
||||||
':q6' => $like,
|
|
||||||
]);
|
|
||||||
$results = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
<main class="section">
|
|
||||||
<div class="container">
|
|
||||||
<p class="eyebrow">Suche</p>
|
|
||||||
<h1>Events finden</h1>
|
|
||||||
<form method="get" class="form-grid single" style="margin: 14px 0;">
|
|
||||||
<div class="stack gap-6">
|
|
||||||
<label class="label" for="q">Suchbegriff (Titel, Ort, Beschreibung)</label>
|
|
||||||
<input id="q" name="q" class="input" value="<?= htmlspecialchars($q, ENT_QUOTES) ?>" placeholder="z. B. Berlin oder Spielplatz">
|
|
||||||
</div>
|
|
||||||
<button class="btn" type="submit">Suchen</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<?php if ($q === ''): ?>
|
|
||||||
<p class="muted">Bitte gib einen Suchbegriff ein.</p>
|
|
||||||
<?php else: ?>
|
|
||||||
<h3 style="margin-top: 16px;"><?= count($results) ?> Ergebnis(se) für „<?= htmlspecialchars($q, ENT_QUOTES) ?>“</h3>
|
|
||||||
<?php if (!$results): ?>
|
|
||||||
<p class="muted">Keine passenden Events gefunden.</p>
|
|
||||||
<?php else: ?>
|
|
||||||
<div class="stack gap-12" style="margin-top: 12px;">
|
|
||||||
<?php foreach ($results as $ev): ?>
|
|
||||||
<article class="card">
|
|
||||||
<div class="event__body">
|
|
||||||
<div class="event__meta">
|
|
||||||
<span><?= htmlspecialchars($ev['starts_at'], ENT_QUOTES) ?></span>
|
|
||||||
<span>📍 <?= htmlspecialchars($ev['region'] ?: $ev['city'], ENT_QUOTES) ?></span>
|
|
||||||
<span><?= $ev['visibility'] === 'public' ? 'Öffentlich' : 'Mitglieder' ?></span>
|
|
||||||
<span class="badge"><?= ((int)$ev['allow_kids'] === 1) ? 'Mit Kindern' : 'Ohne Kinder' ?></span>
|
|
||||||
</div>
|
|
||||||
<h3><?= htmlspecialchars($ev['title'], ENT_QUOTES) ?></h3>
|
|
||||||
<p class="muted"><?= htmlspecialchars($ev['teaser_public'], ENT_QUOTES) ?></p>
|
|
||||||
<?php if (!empty($ev['location_label'])): ?>
|
|
||||||
<p class="muted small"><strong>Ort:</strong> <?= htmlspecialchars($ev['location_label'], ENT_QUOTES) ?></p>
|
|
||||||
<?php endif; ?>
|
|
||||||
<details>
|
|
||||||
<summary style="cursor:pointer;">Details anzeigen</summary>
|
|
||||||
<p><?= nl2br(htmlspecialchars($ev['description'], ENT_QUOTES)) ?></p>
|
|
||||||
</details>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
<?php endforeach; ?>
|
|
||||||
</div>
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php endif; ?>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|||||||
47
src/App/Search.php
Normal file
47
src/App/Search.php
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
final class Search
|
||||||
|
{
|
||||||
|
public function __construct(private ?\PDO $pdo) {}
|
||||||
|
|
||||||
|
public function searchEvents(string $query, int $limit = 100): array
|
||||||
|
{
|
||||||
|
if (!$this->pdo) return [];
|
||||||
|
|
||||||
|
$q = trim($query);
|
||||||
|
if ($q === '') return [];
|
||||||
|
|
||||||
|
$tokens = array_filter(preg_split('/\s+/', $q) ?: [], fn($t) => $t !== '');
|
||||||
|
if (!$tokens) {
|
||||||
|
$tokens = [$q];
|
||||||
|
}
|
||||||
|
|
||||||
|
$conditions = [];
|
||||||
|
$params = [];
|
||||||
|
$i = 0;
|
||||||
|
foreach ($tokens as $tok) {
|
||||||
|
$ph = ':kw' . $i++;
|
||||||
|
$conditions[] = "(title LIKE $ph OR teaser_public LIKE $ph OR description LIKE $ph OR city LIKE $ph OR region LIKE $ph OR zip LIKE $ph)";
|
||||||
|
$params[$ph] = '%' . $tok . '%';
|
||||||
|
}
|
||||||
|
$where = $conditions ? ('AND ' . implode(' AND ', $conditions)) : '';
|
||||||
|
|
||||||
|
$sql = "SELECT id, title, teaser_public, description, city, region, starts_at, visibility, allow_kids, location_label
|
||||||
|
FROM events
|
||||||
|
WHERE starts_at >= NOW()
|
||||||
|
AND status != 'cancelled'
|
||||||
|
$where
|
||||||
|
ORDER BY starts_at ASC
|
||||||
|
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) ?: [];
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user