105 lines
3.4 KiB
PHP
105 lines
3.4 KiB
PHP
<?php
|
|
/**
|
|
* Hilfsfunktionen rund um die Suchergebnisse.
|
|
*
|
|
* Werden sowohl von content/search-results.php (No-JS-Rendering)
|
|
* als auch von php/controller/search-results-data.php (JSON für
|
|
* die JS-Hydration) genutzt, damit Sortier-/Filterlogik nur an
|
|
* einer Stelle gepflegt werden muss
|
|
*/
|
|
|
|
function getLikeCount($item): int
|
|
{
|
|
if (isset($item['likes']) && is_array($item['likes'])) {
|
|
return count($item['likes']);
|
|
}
|
|
return (int)($item['likes'] ?? 0);
|
|
}
|
|
|
|
/**
|
|
* Sortiert die Ergebnisse
|
|
*/
|
|
function sortSearchResults(array $results, string $sortStyle): array
|
|
{
|
|
switch ($sortStyle) {
|
|
case 'likes':
|
|
usort($results, function ($a, $b) {
|
|
return getLikeCount($b) <=> getLikeCount($a);
|
|
});
|
|
break;
|
|
case 'newest':
|
|
usort($results, function ($a, $b) {
|
|
return strcmp($b['creationDate'] ?? '', $a['creationDate'] ?? '');
|
|
});
|
|
break;
|
|
case 'oldest':
|
|
usort($results, function ($a, $b) {
|
|
return strcmp($a['creationDate'] ?? '', $b['creationDate'] ?? '');
|
|
});
|
|
break;
|
|
case 'alphabet':
|
|
default:
|
|
usort($results, function ($a, $b) {
|
|
return strcasecmp($a['title'] ?? '', $b['title'] ?? '');
|
|
});
|
|
break;
|
|
}
|
|
return $results;
|
|
}
|
|
|
|
/**
|
|
* Filtert die Ergebnisse ('all' = kein Filter).
|
|
*/
|
|
function filterSearchResultsByCategory(array $results, string $category): array
|
|
{
|
|
$category = strtolower(trim($category));
|
|
if ($category === '' || $category === 'all') {
|
|
return $results;
|
|
}
|
|
return array_values(array_filter($results, function ($item) use ($category) {
|
|
return strtolower($item['category'] ?? '') === $category;
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Baut eine Such-Ergebnis-URL für einen bestimmten Seitenwechsel (No-JS-Pagination).
|
|
*/
|
|
function buildSearchResultsUrl(int $page, string $query, string $sort, string $category, int $limit): string
|
|
{
|
|
return "index.php?pfad=search-results"
|
|
. "&q=" . urlencode($query)
|
|
. "&sort=" . urlencode($sort)
|
|
. "&category=" . urlencode($category)
|
|
. "&limit=" . $limit
|
|
. "&page=" . $page;
|
|
}
|
|
|
|
/**
|
|
* Rendert eine rein serverseitige Pagination (echte <a>-Links) für den No-JS-Fall:
|
|
*/
|
|
function renderNoJsPagination(int $currentPage, int $totalPages, string $query, string $sort, string $category, int $limit): string
|
|
{
|
|
$html = '';
|
|
|
|
if ($currentPage > 1) {
|
|
$html .= '<a class="s-res-page-btn" href="' . htmlspecialchars(buildSearchResultsUrl($currentPage - 1, $query, $sort, $category, $limit)) . '">«</a> ';
|
|
} else {
|
|
$html .= '<span class="s-res-page-btn" aria-disabled="true">«</span> ';
|
|
}
|
|
|
|
for ($i = 1; $i <= $totalPages; $i++) {
|
|
if ($i === $currentPage) {
|
|
$html .= '<span class="s-res-page-btn s-res-page-btn-active">' . $i . '</span> ';
|
|
} else {
|
|
$html .= '<a class="s-res-page-btn" href="' . htmlspecialchars(buildSearchResultsUrl($i, $query, $sort, $category, $limit)) . '">' . $i . '</a> ';
|
|
}
|
|
}
|
|
|
|
if ($currentPage < $totalPages) {
|
|
$html .= '<a class="s-res-page-btn" href="' . htmlspecialchars(buildSearchResultsUrl($currentPage + 1, $query, $sort, $category, $limit)) . '">»</a>';
|
|
} else {
|
|
$html .= '<span class="s-res-page-btn" aria-disabled="true">»</span>';
|
|
}
|
|
|
|
return $html;
|
|
} |