258 lines
12 KiB
PHP
258 lines
12 KiB
PHP
|
<?php
|
||
|
if (!defined('SVRJS_MOD_DIRECTORY')) die;
|
||
|
|
||
|
$errorMessage = null;
|
||
|
$modSubmitted = false;
|
||
|
$slug = null;
|
||
|
|
||
|
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||
|
if (!isset($_POST['_csrf']) || $_POST['_csrf'] != $_SESSION['csrf']) {
|
||
|
$errorMessage = "Potential CSRF attack detected.";
|
||
|
} elseif (!isset($_POST['name'], $_POST['category'], $_POST['link']) || !$_POST['name'] || !$_POST['category'] || !$_POST['link']) {
|
||
|
$errorMessage = "You need to input name, category and download page URL.";
|
||
|
} elseif (!filter_var($_POST['link'], FILTER_VALIDATE_URL) || !preg_match('/^https?:\\/\\//', $_POST['link'])) {
|
||
|
$errorMessage = "Invalid download page URL.";
|
||
|
} elseif (isset($_POST['docslink']) && $_POST['docslink'] && (!filter_var($_POST['docslink'], FILTER_VALIDATE_URL) || !preg_match('/^https?:\\/\\//', $_POST['docslink']))) {
|
||
|
$errorMessage = "Invalid documentation URL.";
|
||
|
} elseif (!filter_var($_POST['category'], FILTER_VALIDATE_INT)) {
|
||
|
$errorMessage = "Invalid category.";
|
||
|
} else {
|
||
|
$categoryID = intval($_POST['category']);
|
||
|
$statement = $connection->prepare("SELECT id FROM categories WHERE id = ?");
|
||
|
if (!$statement) {
|
||
|
$errorMessage = "An unexpected error occurred while submitting the mod.";
|
||
|
} else {
|
||
|
$statement->bind_param('i', $categoryID);
|
||
|
$statement->execute();
|
||
|
$result = $statement->get_result();
|
||
|
if (!$result) {
|
||
|
$errorMessage = "An unexpected error occurred while submitting the mod.";
|
||
|
$statement->close();
|
||
|
} else {
|
||
|
$isCategoryPresent = boolval($result->fetch_assoc());
|
||
|
$statement->close();
|
||
|
if (!$isCategoryPresent) {
|
||
|
$errorMessage = "The selected category doesn't exist.";
|
||
|
} else {
|
||
|
$slugError = false;
|
||
|
$tempSlug = null;
|
||
|
$tempSlugCount = 1;
|
||
|
while (is_null($slug)) {
|
||
|
if (!$tempSlug) {
|
||
|
$tempSlug = strtolower($_POST['name']);
|
||
|
$tempSlug = preg_replace('/[^a-zA-Z0-9]+/', '-', $tempSlug);
|
||
|
$tempSlug = preg_replace('/^-+/', '', $tempSlug);
|
||
|
$tempSlug = preg_replace('/-+$/', '', $tempSlug);
|
||
|
}
|
||
|
|
||
|
$statement = $connection->prepare("SELECT slug FROM mods WHERE slug = ? UNION SELECT slug FROM mods_pending WHERE slug = ?");
|
||
|
if (!$statement) {
|
||
|
$slugError = true;
|
||
|
$errorMessage = "An unexpected error occurred while submitting the mod.";
|
||
|
break;
|
||
|
} else {
|
||
|
$tempSlug2 = $tempSlug . ($tempSlugCount > 1 ? '-' . strval($tempSlugCount) : '');
|
||
|
$statement->bind_param('ss', $tempSlug2, $tempSlug2);
|
||
|
$statement->execute();
|
||
|
$slugExistsResult = $statement->get_result();
|
||
|
if (!$slugExistsResult) {
|
||
|
$slugError = true;
|
||
|
$errorMessage = "An unexpected error occurred while submitting the mod.";
|
||
|
$statement->close();
|
||
|
break;
|
||
|
} else {
|
||
|
$slugExists = boolval($slugExistsResult->fetch_assoc());
|
||
|
$statement->close();
|
||
|
if (!$slugExists) {
|
||
|
$slug = $tempSlug2;
|
||
|
} else {
|
||
|
$tempSlugCount++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!$slugError) {
|
||
|
$fileError = false;
|
||
|
$fileExtension = null;
|
||
|
$modPendingUploadDirectory = APP_FSROOT . '/img/mods_pending';
|
||
|
$modUploadDirectory = APP_FSROOT . '/img/mods';
|
||
|
if (isset($_FILES['cover']) && $_FILES['cover']['error'] != UPLOAD_ERR_NO_FILE) {
|
||
|
if ($_FILES['cover']['error'] != UPLOAD_ERR_OK) {
|
||
|
$fileError = true;
|
||
|
$errorMessage = "An unexpected error occurred while uploading the cover image.";
|
||
|
} else {
|
||
|
$fileTmpPath = $_FILES['cover']['tmp_name'];
|
||
|
$fileName = $_FILES['cover']['name'];
|
||
|
$fileSize = $_FILES['cover']['size'];
|
||
|
$fileType = $_FILES['cover']['type'];
|
||
|
$fileExtension = pathinfo($fileName, PATHINFO_EXTENSION);
|
||
|
|
||
|
if ($fileSize > IMAGE_MAX_SIZE) {
|
||
|
$fileError = true;
|
||
|
$errorMessage = "The cover image is too large. Maximum cover image size: " . formatFileSize(IMAGE_MAX_SIZE);
|
||
|
} elseif (!in_array($fileExtension, IMAGE_EXTENSIONS_ALLOWED, true)) {
|
||
|
$fileError = true;
|
||
|
$errorMessage = "Invalid cover image extension.";
|
||
|
} else {
|
||
|
$imageType = exif_imagetype($fileTmpPath);
|
||
|
if (!$imageType || ($fileType && image_type_to_mime_type($imageType) != $fileType)) {
|
||
|
$fileError = true;
|
||
|
$errorMessage = "The cover image is either corrupted or of wrong type.";
|
||
|
} else {
|
||
|
if (!file_exists($modPendingUploadDirectory) && !mkdir($modPendingUploadDirectory, 0777, true)) {
|
||
|
$fileError = true;
|
||
|
$errorMessage = "An unexpected error occurred while uploading the cover image.";
|
||
|
}
|
||
|
if (!$fileError) {
|
||
|
$uploadedCoverImagePathname = $modPendingUploadDirectory . '/' . str_replace(['/', '\\'], '', $modDataToEdit['slug']) . '.' . $fileExtension;
|
||
|
if (!move_uploaded_file($fileTmpPath, $uploadedCoverImagePathname)) {
|
||
|
$fileError = true;
|
||
|
$errorMessage = "An unexpected error occurred while uploading the cover image.";
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (!$fileError) {
|
||
|
$statement = $connection->prepare("INSERT INTO mods_pending (
|
||
|
name,
|
||
|
slug,
|
||
|
description,
|
||
|
category,
|
||
|
link,
|
||
|
docs_link,
|
||
|
user,
|
||
|
image_ext,
|
||
|
is_paid,
|
||
|
is_rejected
|
||
|
) VALUES (
|
||
|
?,
|
||
|
?,
|
||
|
?,
|
||
|
?,
|
||
|
?,
|
||
|
?,
|
||
|
?,
|
||
|
?,
|
||
|
?,
|
||
|
0
|
||
|
)");
|
||
|
|
||
|
if (!$statement) {
|
||
|
$errorMessage = "An unexpected error occurred while submitting the mod.";
|
||
|
} else {
|
||
|
$modName = $_POST['name'];
|
||
|
$modSlug = $slug;
|
||
|
$modDescription = isset($_POST['description']) && $_POST['description'] ? $_POST['description'] : null;
|
||
|
$modCategory = $categoryID;
|
||
|
$modLink = $_POST['link'];
|
||
|
$modDocsLink = isset($_POST['docslink']) && $_POST['docslink'] ? $_POST['docslink'] : null;
|
||
|
$modUser = $_SESSION['user'];
|
||
|
$modImageExt = $fileExtension;
|
||
|
$modIsPaid = isset($_POST['paid']) ? 1 : 0;
|
||
|
$statement->bind_param('sssissisi', $modName, $modSlug, $modDescription, $modCategory, $modLink, $modDocsLink, $modUser, $modImageExt, $modIsPaid);
|
||
|
if (!$statement->execute()) {
|
||
|
$errorMessage = "An unexpected error occurred while submitting the mod.";
|
||
|
$statement->close();
|
||
|
} else {
|
||
|
$modSubmitted = true;
|
||
|
$statement->close();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!$modSubmitted) {
|
||
|
$pageTitle = "Submit mod";
|
||
|
$pageDescription = "Submit the SVR.JS mod in SVR.JS Mods directory.";
|
||
|
} else {
|
||
|
$pageTitle = "Mod submitted";
|
||
|
$pageDescription = "The submitted mod is now awaiting moderators' approval.";
|
||
|
}
|
||
|
include 'header.php';
|
||
|
?>
|
||
|
<main class="content">
|
||
|
<?php if ($modSubmitted) { ?>
|
||
|
<h1>Mod submitted</h1>
|
||
|
<p>The submitted mod is now awaiting moderators' approval.</p>
|
||
|
<p><a href="<?php echo htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'pending-mods'); ?>" class="btn">View pending mods</a></p>
|
||
|
<?php } else { ?>
|
||
|
<h1>Submit mod</h1>
|
||
|
<form action="<?php echo htmlspecialchars((URL_REWRITTEN ? APP_ROOT : APP_ROOT . APP_FILENAME . '/') . 'submit') ?>" method="post" class="form" enctype="multipart/form-data">
|
||
|
<div class="form-block">
|
||
|
<label for="name">Mod name:</label>
|
||
|
<input type="text" id="name" name="name" required maxlength="255">
|
||
|
</div>
|
||
|
<div class="form-block">
|
||
|
<label for="cover">Cover image:</label>
|
||
|
<input type="file" id="cover" name="cover" accept="<?php echo htmlspecialchars(implode(',', array_map(
|
||
|
function ($extension) {
|
||
|
return '.' . $extension;
|
||
|
},
|
||
|
IMAGE_EXTENSIONS_ALLOWED
|
||
|
))) ?>">
|
||
|
<p>Allowed file extensions for the cover image: <strong><?php echo htmlspecialchars(implode(', ', array_map(
|
||
|
function ($extension) {
|
||
|
return '.' . $extension;
|
||
|
},
|
||
|
IMAGE_EXTENSIONS_ALLOWED
|
||
|
))) ?></strong></p>
|
||
|
</div>
|
||
|
<div class="form-block">
|
||
|
<label for="category">Category:</label>
|
||
|
<select id="category" name="category" required>
|
||
|
<?php
|
||
|
$result = $connection->query('SELECT id, name FROM categories');
|
||
|
if ($result) {
|
||
|
while ($row = $result->fetch_assoc()) {
|
||
|
echo '<option value="' . htmlspecialchars(strval($row['id'])) . '">' . htmlspecialchars($row['name']) . '</option>';
|
||
|
}
|
||
|
}
|
||
|
?>
|
||
|
</select>
|
||
|
</div>
|
||
|
<div class="form-block">
|
||
|
<label for="description">Mod description:</label>
|
||
|
<textarea name="description" id="description" maxlength="10000"></textarea>
|
||
|
</div>
|
||
|
<div class="form-block">
|
||
|
<label for="link">Download page URL:</label>
|
||
|
<input type="url" id="link" name="link" required maxlength="255">
|
||
|
</div>
|
||
|
<div class="form-block">
|
||
|
<label for="docslink">Documentation URL:</label>
|
||
|
<input type="url" id="docslink" name="docslink" maxlength="255">
|
||
|
</div>
|
||
|
<div class="form-block-checkbox">
|
||
|
<input type="checkbox" name="paid" id="paid">
|
||
|
<label for="paid">Paid?</label>
|
||
|
</div>
|
||
|
|
||
|
<?php if ($errorMessage) echo '<p class="form-error">' . htmlspecialchars($errorMessage) . '</p>'; ?>
|
||
|
<div class="form-block">
|
||
|
<input type="submit" value="Submit mod">
|
||
|
</div>
|
||
|
<input type="hidden" name="_csrf" value="<?php echo htmlspecialchars($_SESSION['csrf']) ?>">
|
||
|
</form>
|
||
|
<?php } ?>
|
||
|
</main>
|
||
|
<?php
|
||
|
include 'footer.php';
|
||
|
|
||
|
if ($modSubmitted) {
|
||
|
$moderatorResult = $connection->query("SELECT email AS address, username AS name FROM users WHERE is_moderator = 1;");
|
||
|
if ($moderatorResult) {
|
||
|
$moderators = [];
|
||
|
while ($moderator = $moderatorResult->fetch_assoc()) {
|
||
|
array_push($moderators, $moderator);
|
||
|
}
|
||
|
sendEmail($moderators, 'A mod has been submitted that requires approval', "A mod has been submitted that requires approval:\n\nMod name: " . str_replace(["\r\n", "\r", "\n"], '', $_POST['name']) . "\nSlug: " . $slug . "\n\nPlease review the mod and approve or reject it.");
|
||
|
}
|
||
|
}
|
||
|
?>
|