319 lines
No EOL
14 KiB
PHP
319 lines
No EOL
14 KiB
PHP
<?php
|
|
if (!defined('SVRJS_MOD_DIRECTORY')) die;
|
|
|
|
$errorMessage = null;
|
|
$reviewSubmitted = false;
|
|
$reviewDeleted = false;
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
|
if (!isset($_POST['_csrf']) || $_POST['_csrf'] != $_SESSION['csrf']) {
|
|
$errorMessage = "Potential CSRF attack detected.";
|
|
} elseif (!isset($_POST['action'])) {
|
|
$errorMessage = "No action specified.";
|
|
} elseif ($_POST['action'] == "submit") {
|
|
if (!isset($_POST['rating'], $_POST['review']) || !$_POST['rating'] || !$_POST['review']) {
|
|
$errorMessage = "You need to input rating and review.";
|
|
} elseif (!filter_var($_POST['rating'], FILTER_VALIDATE_INT)) {
|
|
$errorMessage = "Invalid rating.";
|
|
} else {
|
|
$rating = intval($_POST['rating']);
|
|
if ($rating < 1 || $rating > 5) {
|
|
$errorMessage = "Invalid rating.";
|
|
} else {
|
|
$statement = $connection->prepare("REPLACE INTO reviews (
|
|
`mod`,
|
|
user,
|
|
rating,
|
|
review
|
|
) VALUES (
|
|
?,
|
|
?,
|
|
?,
|
|
?
|
|
);");
|
|
|
|
if (!$statement) {
|
|
$errorMessage = "An unexpected error occurred while submitting the review.";
|
|
} else {
|
|
$statement->bind_param('iiis', $modData['id'], $_SESSION['user'], $rating, $_POST['review']);
|
|
if (!$statement->execute()) {
|
|
$errorMessage = "An unexpected error occurred while submitting the review.";
|
|
} else {
|
|
$reviewSubmitted = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} elseif ($_POST['action'] == "delete") {
|
|
$statement = $connection->prepare("DELETE FROM reviews WHERE `mod` = ? AND user = ?");
|
|
|
|
if (!$statement) {
|
|
$errorMessage = "An unexpected error occurred while deleting the review.";
|
|
} else {
|
|
$statement->bind_param('ii', $modData['id'], $_SESSION['user']);
|
|
if (!$statement->execute()) {
|
|
$errorMessage = "An unexpected error occurred while deleting the review.";
|
|
} else {
|
|
$reviewDeleted = true;
|
|
}
|
|
}
|
|
} else {
|
|
$errorMessage = "Unknown action specified.";
|
|
}
|
|
}
|
|
|
|
if ($reviewSubmitted) {
|
|
$pageTitle = "Review submitted";
|
|
$pageDescription = "Your review has been submitted.";
|
|
} elseif ($reviewDeleted) {
|
|
$pageTitle = "Review deleted";
|
|
$pageDescription = "Your review has been deleted.";
|
|
} else {
|
|
$pageTitle = 'Reviews for "' . $modData['name'] . '" mod';
|
|
$pageDescription = 'See reviews for the "' . $modData['name'] . '" mod on SVR.JS Mods directory.';
|
|
$pageImage = (isset($modData['image_ext']) && $modData['image_ext'] ? 'mods/' . urlencode(str_replace(['/', '\\'], '', $modData['slug'])) . '.' . urlencode(str_replace(['/', '\\'], '', $modData['image_ext'])) : 'mod-missing.png');
|
|
}
|
|
include 'header.php';
|
|
?>
|
|
<main class="content">
|
|
<?php if ($reviewSubmitted) { ?>
|
|
<h1>Review submitted</h1>
|
|
<p>Your review has been submitted.</p>
|
|
<p><a href="<?php echo htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'reviews/' . urlencode($modData['slug'])); ?>" class="btn">Return to mod reviews</a></p>
|
|
<?php } elseif ($reviewDeleted) { ?>
|
|
<h1>Review deleted</h1>
|
|
<p>Your review has been deleted.</p>
|
|
<p><a href="<?php echo htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'reviews/' . urlencode($modData['slug'])); ?>" class="btn">Return to mod reviews</a></p>
|
|
<?php } else { ?>
|
|
<h1>Reviews for “<?php echo htmlspecialchars($modData['name']) ?>” mod</h1>
|
|
<p><a href="<?php echo htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'mod/' . urlencode($modData['slug'])); ?>">Return to the mod page</a></p>
|
|
<?php if ($errorMessage) echo '<p class="form-error">' . htmlspecialchars($errorMessage) . '</p>'; ?>
|
|
<?php
|
|
if ($modData['rating']) {
|
|
$stars = round($modData['rating']);
|
|
|
|
echo '<p class="rating">';
|
|
|
|
echo '<span class="rating-rating">' . htmlspecialchars(number_format($modData['rating'], 2)) . '</span>';
|
|
|
|
echo '<span class="rating-stars">';
|
|
|
|
for ($i = 0; $i < $stars; $i++) {
|
|
echo '<span class="rating-star rating-star-higlighted">★</span>';
|
|
}
|
|
|
|
for ($i = $stars; $i < 5; $i++) {
|
|
echo '<span class="rating-star">★</span>';
|
|
}
|
|
|
|
echo '</span></p>';
|
|
}
|
|
?>
|
|
<p><strong>Reviews</strong>: <?php echo htmlspecialchars(number_format($modData['reviews'], 0)); ?></p>
|
|
<h2>Submit a review</h2>
|
|
<?php if (!isset($_SESSION['user'])) { ?>
|
|
<p>You need to be logged in to submit a review on this mod.</p>
|
|
<?php } elseif ($_SESSION['user'] == $modData['user_id']) { ?>
|
|
<p>As a mod publisher, you cannot submit a review on this mod.</p>
|
|
<?php } else { ?>
|
|
<?php
|
|
$userReview = null;
|
|
$statement = $connection->prepare('SELECT rating, review FROM reviews WHERE `mod` = ? AND user = ?;');
|
|
if ($statement) {
|
|
$statement->bind_param('ii', $modData['id'], $_SESSION['user']);
|
|
$statement->execute();
|
|
$result = $statement->get_result();
|
|
if ($result) {
|
|
$userReview = $result->fetch_assoc();
|
|
}
|
|
$statement->close();
|
|
}
|
|
?>
|
|
<form action="<?php echo htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'reviews/' . urlencode($modData['slug'])) ?>" method="post" class="form">
|
|
<div class="form-block-checkbox">
|
|
<span>Rating:</span>
|
|
<span class="rating-select">
|
|
<input type="radio" name="rating" id="rate-5" value="5" required <?php echo $userReview && $userReview['rating'] == 5 ? 'checked' : ''; ?>>
|
|
<label for="rate-5" title="5 stars">★</label>
|
|
<input type="radio" name="rating" id="rate-4" value="4" required <?php echo $userReview && $userReview['rating'] == 4 ? 'checked' : ''; ?>>
|
|
<label for="rate-4" title="4 stars">★</label>
|
|
<input type="radio" name="rating" id="rate-3" value="3" required <?php echo $userReview && $userReview['rating'] == 3 ? 'checked' : ''; ?>>
|
|
<label for="rate-3" title="3 stars">★</label>
|
|
<input type="radio" name="rating" id="rate-2" value="2" required <?php echo $userReview && $userReview['rating'] == 2 ? 'checked' : ''; ?>>
|
|
<label for="rate-2" title="2 stars">★</label>
|
|
<input type="radio" name="rating" id="rate-1" value="1" required <?php echo $userReview && $userReview['rating'] == 1 ? 'checked' : ''; ?>>
|
|
<label for="rate-1" title="1 star">★</label>
|
|
</span>
|
|
</div>
|
|
<div class="form-block">
|
|
<label for="review">Review:</label>
|
|
<textarea name="review" id="review" maxlength="1000" required><?php echo $userReview && $userReview['review'] ? htmlspecialchars($userReview['review']) : ''; ?></textarea>
|
|
</div>
|
|
<div class="form-block">
|
|
<input type="submit" value="<?php echo $userReview ? 'Edit review' : 'Submit review' ?>">
|
|
</div>
|
|
<input type="hidden" name="_csrf" value="<?php echo htmlspecialchars($_SESSION['csrf']) ?>">
|
|
<input type="hidden" name="action" value="submit">
|
|
</form>
|
|
<?php if ($userReview) { ?>
|
|
<h2>Delete your review</h2>
|
|
<form action="<?php echo htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'reviews/' . urlencode($modData['slug'])) ?>" method="post" class="form">
|
|
<div class="form-block">
|
|
<input type="submit" value="Delete review">
|
|
</div>
|
|
<input type="hidden" name="_csrf" value="<?php echo htmlspecialchars($_SESSION['csrf']) ?>">
|
|
<input type="hidden" name="action" value="delete">
|
|
</form>
|
|
<?php } ?>
|
|
<?php } ?>
|
|
<h2>Reviews</h2>
|
|
<?php
|
|
$countStatement = $connection->prepare('SELECT COUNT(reviews.id) AS count
|
|
FROM reviews
|
|
JOIN (
|
|
SELECT mods.id AS id, mods.is_removed AS is_removed, mods.name AS name, mods.slug AS slug FROM mods
|
|
JOIN users ON users.id = mods.user AND users.is_verified = 1 AND users.is_deleted = 0 AND users.is_suspended = 0
|
|
) AS mods ON mods.id = reviews.mod
|
|
JOIN users ON users.id = reviews.user
|
|
WHERE mods.id = ?
|
|
AND mods.is_removed = 0
|
|
AND users.is_suspended = 0
|
|
AND users.is_deleted = 0
|
|
AND users.is_verified = 1;');
|
|
if (!$countStatement) {
|
|
echo "<p>An unexpected error occurred while fetching reviews.</p>";
|
|
} else {
|
|
$countStatement->bind_param('i', $modData['id']);
|
|
$countStatement->execute();
|
|
|
|
$countResult = $countStatement->get_result();
|
|
|
|
if (!$countResult) {
|
|
echo "<p>An unexpected error occurred while fetching reviews.</p>";
|
|
$countStatement->close();
|
|
} else {
|
|
$countRow = $countResult->fetch_assoc();
|
|
$countStatement->close();
|
|
if (!$countRow) {
|
|
echo "<p>An unexpected error occurred while fetching reviews.</p>";
|
|
} else {
|
|
$modCount = $countRow['count'];
|
|
$totalPages = ceil($modCount / PAGE_MODS);
|
|
$statement = $connection->prepare('SELECT
|
|
reviews.id AS id,
|
|
reviews.rating AS rating,
|
|
reviews.review AS review,
|
|
mods.name AS mod_name,
|
|
mods.slug AS mod_slug,
|
|
users.username AS user,
|
|
users.id AS user_id
|
|
FROM reviews
|
|
JOIN (
|
|
SELECT mods.id AS id, mods.is_removed AS is_removed, mods.name AS name, mods.slug AS slug FROM mods
|
|
JOIN users ON users.id = mods.user AND users.is_verified = 1 AND users.is_deleted = 0 AND users.is_suspended = 0
|
|
) AS mods ON mods.id = reviews.mod
|
|
JOIN users ON users.id = reviews.user
|
|
WHERE mods.id = ?
|
|
AND mods.is_removed = 0
|
|
AND users.is_suspended = 0
|
|
AND users.is_deleted = 0
|
|
AND users.is_verified = 1
|
|
ORDER BY reviews.id DESC
|
|
LIMIT ?,?;');
|
|
if (!$statement) {
|
|
echo "<p>An unexpected error occurred while fetching reviews.</p>";
|
|
} else {
|
|
$pageNumber = isset($_GET['page']) && filter_var($_GET['page'], FILTER_VALIDATE_INT) ? intval($_GET['page']) : 1;
|
|
$firstNumber = PAGE_REVIEWS * ($pageNumber - 1);
|
|
$pageReviews = PAGE_REVIEWS;
|
|
$statement->bind_param('iii', $modData['id'], $firstNumber, $pageReviews);
|
|
$statement->execute();
|
|
|
|
$result = $statement->get_result();
|
|
|
|
if (!$result) {
|
|
echo "<p>An unexpected error occurred while fetching reviews.</p>";
|
|
$statement->close();
|
|
} else {
|
|
$reviewsPresent = false;
|
|
while ($review = $result->fetch_assoc()) {
|
|
$reviewsPresent = true;
|
|
echo '<div class="review"><div class="review-header">';
|
|
|
|
$stars = round($review['rating']);
|
|
|
|
echo '<span class="rating-stars">';
|
|
|
|
for ($i = 0; $i < $stars; $i++) {
|
|
echo '<span class="rating-star rating-star-higlighted">★</span>';
|
|
}
|
|
|
|
for ($i = $stars; $i < 5; $i++) {
|
|
echo '<span class="rating-star">★</span>';
|
|
}
|
|
|
|
echo ' | by <a href="' . htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'user/' . urlencode($review['user'])) . '">' . htmlspecialchars($review['user']) . '</a> | on <a href="' . htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'mod/' . urlencode($review['mod_slug'])) . '">' . htmlspecialchars($review['mod_name']) . '</a></div><p>' . str_replace(["\r\n", "\n", "\r"], '<br/>', htmlspecialchars($review['review'])) . '</div>';
|
|
}
|
|
if (!$reviewsPresent) {
|
|
echo '<p>No reviews.</p>';
|
|
}
|
|
$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 . '/') . 'reviews/' . urlencode($modData['slug']) . '?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 . '/') . 'reviews/' . urlencode($modData['slug']) . '?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 . '/') . 'reviews/' . urlencode($modData['slug']) . '?page=' . urlencode(strval($pageNumber + 1))) . '">›</a>';
|
|
echo '</div>';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
?>
|
|
<?php } ?>
|
|
</main>
|
|
<?php
|
|
include 'footer.php';
|
|
|
|
if ($reviewSubmitted) {
|
|
$username = null;
|
|
if (isset($_SESSION['user'])) {
|
|
$usernameStatement = $connection->prepare('SELECT username FROM users WHERE id = ?;');
|
|
if ($usernameStatement) {
|
|
$usernameStatement->bind_param('i', $_SESSION['user']);
|
|
$usernameStatement->execute();
|
|
$usernameResult = $usernameStatement->get_result();
|
|
if ($usernameResult) {
|
|
$usernameRow = $usernameResult->fetch_assoc();
|
|
if ($usernameRow) {
|
|
$username = $usernameRow['username'];
|
|
}
|
|
}
|
|
$usernameStatement->close();
|
|
}
|
|
}
|
|
|
|
sendEmail(
|
|
[[
|
|
"name" => $modData['user'],
|
|
"address" => $modData['user_email']
|
|
]],
|
|
($username ? $username : 'Someone') . ' has left a review on your mod',
|
|
($username ? $username : 'Someone') . " has left you a " . intval($_POST['rating']) . "-star review on your \"" . $modData['name'] . "\" mod. The contents of the review are below:\n\n" . $_POST['review']
|
|
);
|
|
}
|
|
?>
|