2024-12-27 15:05:54 +01:00
|
|
|
<?php
|
|
|
|
$searchQuery = isset($_GET['q']) && $_GET['q'] ? $_GET['q'] : "";
|
|
|
|
if (!defined('SVRJS_MOD_DIRECTORY')) die;
|
2024-12-27 16:22:53 +01:00
|
|
|
$pageTitle = $searchQuery ? "$searchQuery - Search" : "Search";
|
2024-12-27 15:05:54 +01:00
|
|
|
$pageDescription = "Search for SVR.JS mods";
|
|
|
|
include 'header.php';
|
|
|
|
?>
|
|
|
|
<main class="content">
|
|
|
|
<h1>Search</h1>
|
|
|
|
<form action="<?php echo htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'search') ?>" method="get" class="search-form">
|
|
|
|
<input type="text" name="q" placeholder="Search for SVR.JS mods..." <?php if ($searchQuery) echo 'value="' . htmlspecialchars($searchQuery) . '" '; ?>>
|
|
|
|
<input type="submit" value="Search">
|
|
|
|
</form>
|
|
|
|
<?php
|
|
|
|
if (trim($searchQuery)) {
|
|
|
|
$queryLike = '%' . str_replace(array('!', '%', '_', '['), array('!!', '!%', '!_', '!['), $searchQuery) . '%';
|
|
|
|
$countStatement = $connection->prepare('SELECT COUNT(mods.id) AS count
|
|
|
|
FROM mods
|
|
|
|
JOIN users ON users.id = mods.user
|
|
|
|
WHERE mods.is_removed = 0
|
|
|
|
AND users.is_suspended = 0
|
|
|
|
AND users.is_deleted = 0
|
|
|
|
AND users.is_verified = 1
|
|
|
|
AND (
|
|
|
|
MATCH (mods.name, mods.description) AGAINST (? IN NATURAL LANGUAGE MODE)
|
|
|
|
OR mods.name LIKE ?
|
|
|
|
OR mods.description LIKE ?
|
|
|
|
);');
|
|
|
|
if (!$countStatement) {
|
|
|
|
echo "<p>An unexpected error occurred while fetching mods.</p>";
|
|
|
|
} else {
|
|
|
|
$countStatement->bind_param('sss', $searchQuery, $queryLike, $queryLike);
|
|
|
|
$countStatement->execute();
|
|
|
|
|
|
|
|
$countResult = $countStatement->get_result();
|
|
|
|
|
|
|
|
if (!$countResult) {
|
|
|
|
echo "<p>An unexpected error occurred while fetching mods.</p>";
|
|
|
|
$countStatement->close();
|
|
|
|
} else {
|
|
|
|
$countRow = $countResult->fetch_assoc();
|
|
|
|
$countStatement->close();
|
|
|
|
if (!$countRow) {
|
|
|
|
echo "<p>An unexpected error occurred while fetching mods.</p>";
|
|
|
|
} else {
|
|
|
|
$modCount = $countRow['count'];
|
|
|
|
$totalPages = ceil($modCount / PAGE_MODS);
|
|
|
|
$statement = $connection->prepare('SELECT
|
|
|
|
mods.id AS id,
|
|
|
|
mods.name AS name,
|
|
|
|
mods.slug AS slug,
|
|
|
|
mods.description AS description,
|
|
|
|
mods.image_ext AS image_ext,
|
|
|
|
mods.is_paid AS is_paid,
|
|
|
|
categories.name AS category,
|
|
|
|
categories.slug AS category_slug,
|
|
|
|
users.username AS user,
|
|
|
|
users.id AS user_id,
|
|
|
|
AVG(reviews.rating) AS rating,
|
|
|
|
COUNT(reviews.id) AS reviews,
|
|
|
|
MATCH (mods.name, mods.description) AGAINST (? IN NATURAL LANGUAGE MODE) AS score
|
|
|
|
FROM mods
|
|
|
|
LEFT JOIN categories ON categories.id = mods.category
|
|
|
|
LEFT JOIN (
|
|
|
|
SELECT
|
|
|
|
reviews.rating AS rating,
|
|
|
|
reviews.id AS id,
|
|
|
|
reviews.mod AS `mod`
|
|
|
|
FROM reviews
|
|
|
|
JOIN users ON users.id = reviews.user AND users.is_verified = 1 AND users.is_deleted = 0 AND users.is_suspended = 0
|
|
|
|
) AS reviews ON reviews.mod = mods.id
|
|
|
|
JOIN users ON users.id = mods.user
|
|
|
|
WHERE mods.is_removed = 0
|
|
|
|
AND users.is_suspended = 0
|
|
|
|
AND users.is_deleted = 0
|
|
|
|
AND users.is_verified = 1
|
|
|
|
GROUP BY mods.id
|
|
|
|
HAVING (
|
|
|
|
score > 0
|
|
|
|
OR mods.name LIKE ?
|
|
|
|
OR mods.description LIKE ?
|
|
|
|
)
|
|
|
|
ORDER BY score DESC,
|
|
|
|
IFNULL(rating, 0) DESC,
|
|
|
|
reviews DESC
|
|
|
|
LIMIT ?,?;');
|
|
|
|
if (!$statement) {
|
|
|
|
echo "<p>An unexpected error occurred while fetching mods.</p>";
|
|
|
|
} else {
|
|
|
|
$pageNumber = isset($_GET['page']) && filter_var($_GET['page'], FILTER_VALIDATE_INT) ? intval($_GET['page']) : 1;
|
|
|
|
$firstNumber = PAGE_MODS * ($pageNumber - 1);
|
|
|
|
$pageMods = PAGE_MODS;
|
|
|
|
$statement->bind_param('sssii', $searchQuery, $queryLike, $queryLike, $firstNumber, $pageMods);
|
|
|
|
$statement->execute();
|
|
|
|
|
|
|
|
$result = $statement->get_result();
|
|
|
|
|
|
|
|
if (!$result) {
|
|
|
|
echo "<p>An unexpected error occurred while fetching mods.</p>";
|
|
|
|
$statement->close();
|
|
|
|
} else {
|
|
|
|
$modsPresent = false;
|
|
|
|
while ($mod = $result->fetch_assoc()) {
|
|
|
|
if (!$modsPresent) {
|
|
|
|
echo '<div class="mods">';
|
|
|
|
}
|
|
|
|
$modsPresent = true;
|
|
|
|
echo '<div class="mods-mod-container">
|
|
|
|
<div class="mods-mod-card">
|
|
|
|
<a href="' . htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'mod/' . urlencode($mod['slug'])) . '"><img src="' . htmlspecialchars(APP_ROOT . 'img/' . (isset($mod['image_ext']) && $mod['image_ext'] ? 'mods/' . urlencode(str_replace(['/', '\\'], '', $mod['slug'])) . '.' . urlencode(str_replace(['/', '\\'], '', $mod['image_ext'])) : 'mod-missing.png')) . '" alt="' . htmlspecialchars($mod['name']) . ' cover image"></a>
|
|
|
|
<div class="mods-mod-card-contents">
|
|
|
|
<h2><a href="' . htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'mod/' . urlencode($mod['slug'])) . '">' . htmlspecialchars($mod['name']) . '</a></h2>
|
|
|
|
<p>' . (isset($mod['description']) && $mod['description'] ? str_replace(["\r\n", "\n", "\r"], '<br/>', htmlspecialchars(shortenDescription($mod['description']))) : "<i>No description</i>") . '</p>
|
|
|
|
<div class="mods-mod-card-bottom">
|
|
|
|
<p class="mods-mod-card-publisher">Publisher: <a href="' . htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'user/' . urlencode($mod['user'])) . '">' . htmlspecialchars($mod['user']) . '</a>' . (isset($_SESSION['user']) && $_SESSION['user'] == $mod['user_id'] ? ' | <a href="' . htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'edit-mod/' . urlencode($mod['slug'])) . '">Edit mod</a>' : '') . '</p>
|
|
|
|
' . ($mod['rating'] ? '<span class="badge">' . htmlspecialchars(number_format($mod['rating'], 2)) . ' ★</span>' : '') . '
|
|
|
|
<span class="badge">' . ($mod['is_paid'] ? 'Paid' : 'Gratis') . '</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>';
|
|
|
|
}
|
|
|
|
if ($modsPresent) {
|
|
|
|
echo '</div>';
|
|
|
|
} else {
|
|
|
|
echo '<p>No mods found matching the <b>“' . htmlspecialchars($searchQuery) . '”</b> query.</p>
|
|
|
|
<ul>
|
|
|
|
<li>Check your search query for misspellings</li>
|
|
|
|
<li>Try using different keywords</li>
|
|
|
|
<li>Try replacing some keywords with more general ones</li>
|
|
|
|
</ul>';
|
|
|
|
}
|
|
|
|
$statement->close();
|
|
|
|
if ($totalPages > 1) {
|
|
|
|
$begPage = $pageNumber - 2;
|
|
|
|
$endPage = $pageNumber + 2;
|
|
|
|
if ($endPage > $totalPages) {
|
|
|
|
$begPage -= $endPage - $totalPages;
|
|
|
|
$endPage = $totalPages;
|
|
|
|
}
|
|
|
|
if ($begPage < 1) {
|
|
|
|
$endPage += 1 - $begPage;
|
|
|
|
$begPage = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
echo '<div class="pagination">';
|
|
|
|
echo $pageNumber <= 1 ? '<span>‹</span>' : '<a href="' . htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'search' . ($searchQuery ? '?q=' . urlencode($searchQuery) . '&' : '?') . 'page=' . urlencode(strval($pageNumber - 1))) . '">‹</a>';
|
|
|
|
for ($i = 0; $i < ($totalPages > 5 ? 5 : $totalPages); $i++) {
|
|
|
|
echo $pageNumber == $begPage + $i ? '<span>' . htmlspecialchars(strval($begPage + $i)) . '</span>' : '<a href="' . htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'search' . ($searchQuery ? '?q=' . urlencode($searchQuery) . '&' : '?') . 'page=' . urlencode(strval($begPage + $i))) . '">' . htmlspecialchars(strval($begPage + $i)) . '</a>';
|
|
|
|
}
|
|
|
|
echo $pageNumber >= $totalPages ? '<span>›</span>' : '<a href="' . htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'search' . ($searchQuery ? '?q=' . urlencode($searchQuery) . '&' : '?') . 'page=' . urlencode(strval($pageNumber + 1))) . '">›</a>';
|
|
|
|
echo '</div>';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
?>
|
|
|
|
</main>
|
|
|
|
<?php
|
|
|
|
include 'footer.php';
|
|
|
|
?>
|