refactor error messages and add response code

This commit is contained in:
Spine
2025-03-18 05:50:23 +00:00
parent f6b5b7a983
commit 31f5909642
366 changed files with 1368 additions and 1118 deletions

View File

@@ -117,7 +117,7 @@ abstract class Collector extends Base {
'44' => $sql .= "t.Format = 'AAC' AND t.Encoding = 'q5.5'",
'45' => $sql .= "t.Format = 'AAC' AND t.Encoding = 'q5'",
'46' => $sql .= "t.Format = 'AAC' AND t.Encoding = '192'",
default => error('Unknown collector selector'),
default => Error400::error('Unknown collector selector'),
};
$sql .= " THEN $Priority ";
}

View File

@@ -146,7 +146,7 @@ class Debug {
);
}
public function saveError(\Exception $e): int {
public function saveError(\Error|\Exception $e): int {
return $this->saveCase(
$e->getMessage() . "\n"
. str_replace(SERVER_ROOT . '/', '', $e->getTraceAsString())

28
app/Error.php Normal file
View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Gazelle;
abstract class Error extends Base {
public static function error(string $message = ''): never {
echo static::payload($message);
exit;
}
public static function payload(string $message): string {
header("{$_SERVER['SERVER_PROTOCOL']} " . static::errorCode() . ' ' . static::errorLabel());
return static::$twig->render('error.twig', [
'code' => static::errorCode(),
'label' => static::errorLabel(),
'description' => static::errorDescription(),
'message' => $message,
]);
}
abstract public static function errorCode(): int;
abstract public static function errorLabel(): string;
abstract public static function errorDescription(): string;
}

19
app/Error400.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Gazelle;
class Error400 extends Error {
public static function errorCode(): int {
return 400;
}
public static function errorLabel(): string {
return 'Bad Request';
}
public static function errorDescription(): string {
return 'A parameter in the page request is missing or has an incorrect value. If you copy-pasted the page, make sure it is correct.';
}
}

32
app/Error403.php Normal file
View File

@@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace Gazelle;
class Error403 extends Error {
public static function error(string $message = ''): never {
$who = static::$requestContext->viewer()->label();
$ipaddr = static::$requestContext->viewer()->ipaddr();
$geoip = new Util\GeoIP(new Util\Curl());
Util\Irc::sendMessage(
IRC_CHAN_STATUS,
"$who ($ipaddr [{$geoip->countryISO($ipaddr)}]) on {$_SERVER['REQUEST_METHOD']} {$_SERVER['REQUEST_URI']}"
. (!empty($_SERVER['HTTP_REFERER']) ? " from {$_SERVER['HTTP_REFERER']}" : '')
. (!empty($message) ? " message '$message'" : '')
);
parent::error($message);
}
public static function errorCode(): int {
return 403;
}
public static function errorLabel(): string {
return 'Forbidden';
}
public static function errorDescription(): string {
return "You cannot view something you are not allowed to view.";
}
}

19
app/Error404.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Gazelle;
class Error404 extends Error {
public static function errorCode(): int {
return 404;
}
public static function errorLabel(): string {
return 'Not Found';
}
public static function errorDescription(): string {
return 'The requested page does not exist, or if it did once, it no longer exists.';
}
}

19
app/Error429.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Gazelle;
class Error429 extends Error {
public static function errorCode(): int {
return 429;
}
public static function errorLabel(): string {
return 'Too Many Requests';
}
public static function errorDescription(): string {
return 'You tried to do something too frequently. Slow down and try again later.';
}
}

19
app/Error500.php Normal file
View File

@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);
namespace Gazelle;
class Error500 extends Error {
public static function errorCode(): int {
return 500;
}
public static function errorLabel(): string {
return 'Server Error';
}
public static function errorDescription(): string {
return "This one's on us, it looks like you tripped over a bug in the code.";
}
}

View File

@@ -2,6 +2,8 @@
namespace Gazelle\Manager;
use Gazelle\Error400;
class Comment extends \Gazelle\BaseManager {
final public const CATALOG = '%s_comments_%d_cat_%d';
@@ -11,7 +13,7 @@ class Comment extends \Gazelle\BaseManager {
'collages' => \Gazelle\Comment\Collage::class,
'requests' => \Gazelle\Comment\Request::class,
'torrents' => \Gazelle\Comment\Torrent::class,
default => error("no comments for " . display_str($page)),
default => Error400::error("no comments for " . html_escape($page)),
};
}

View File

@@ -4,6 +4,7 @@
namespace Gazelle\Search;
use Gazelle\Enum\LeechType;
use Gazelle\Error500;
class Torrent {
final protected const TAGS_ANY = 0;
@@ -199,7 +200,7 @@ class Torrent {
$ErrMsg,
86_400,
);
error('-1');
Error500::error();
}
$this->Page = $searchMany ? $Page : min($Page, SPHINX_MAX_MATCHES / $PageSize); /** @phpstan-ignore-line sphinx must die */

View File

@@ -1,11 +1,6 @@
<?php
// phpcs:disable PSR1.Files.SideEffects.FoundWithSymbols
// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
if (!extension_loaded('mysqli')) {
error('Mysqli Extension not loaded.');
}
class Sphinxql extends mysqli {
private static $Connections = [];
private $Ident;
@@ -101,7 +96,7 @@ class Sphinxql extends mysqli {
echo '<pre>' . display_str($error) . '</pre>';
die();
} else {
error('-1');
Gazelle\Error500::error($message);
}
}
}

View File

@@ -1,6 +1,8 @@
<?php
// phpcs:disable PSR1.Files.SideEffects.FoundWithSymbols
namespace Gazelle;
use Gazelle\Util\Crypto;
use Gazelle\Util\Time;
@@ -18,7 +20,7 @@ if (
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
$context = new Gazelle\BaseRequestContext(
$context = new BaseRequestContext(
$_SERVER['SCRIPT_NAME'],
$_SERVER['REMOTE_ADDR'],
$_SERVER['HTTP_USER_AGENT'] ?? '[no-useragent]',
@@ -41,8 +43,8 @@ if (
$SessionID = false;
$Viewer = null;
$ipv4Man = new Gazelle\Manager\IPv4();
$userMan = new Gazelle\Manager\User();
$ipv4Man = new Manager\IPv4();
$userMan = new Manager\User();
$forceLogout = function (): never {
setcookie('session', '', [
@@ -84,7 +86,7 @@ if (!empty($_SERVER['HTTP_AUTHORIZATION']) && $module === 'ajax') {
$Viewer->logoutEverywhere();
$forceLogout();
}
$session = new Gazelle\User\Session($Viewer);
$session = new User\Session($Viewer);
if (!$session->valid($SessionID)) {
$Viewer->logout($SessionID);
$forceLogout();
@@ -139,16 +141,16 @@ if ($Viewer) {
// To proxify images (or not), or e.g. not render the name of a thread
// for a user who may lack the privileges to see it in the first place.
\Text::setViewer($Viewer);
\Gazelle\Util\Twig::setViewer($Viewer);
Util\Twig::setViewer($Viewer);
$context->setViewer($Viewer);
}
unset($forceLogout);
$Debug->mark('load page');
if (DEBUG_MODE || ($Viewer && $Viewer->permitted('site_debug'))) {
$Twig->addExtension(new Twig\Extension\DebugExtension());
if (DEBUG_MODE || $Viewer?->permitted('site_debug')) {
$Twig->addExtension(new \Twig\Extension\DebugExtension());
}
Gazelle\Base::setRequestContext($context);
Base::setRequestContext($context);
// for sections/tools/development/process_info.php
$Cache->cache_value('php_' . getmypid(), [
@@ -181,30 +183,25 @@ header('Cache-Control: no-cache, must-revalidate, post-check=0, pre-check=0');
header('Pragma: no-cache');
$file = realpath(__DIR__ . "/sections/{$module}/index.php");
if (!$file || !preg_match('/^[a-z][a-z0-9_]+$/', $module)) {
error($Viewer ? 403 : 404);
if ($file === false) {
Error400::error();
}
try {
include_once $file;
} catch (Gazelle\DB\MysqlException $e) {
Gazelle\DB::DB()->rollback(); // if there was an ongoing transaction, abort it
if (DEBUG_MODE || (isset($Viewer) && $Viewer->permitted('site_debug'))) {
echo $Twig->render('error-db.twig', [
'message' => $e->getMessage(),
'trace' => str_replace(SERVER_ROOT . '/', '', $e->getTraceAsString()),
]);
} else {
$id = $Debug->saveError($e);
error("That is not supposed to happen, please create a thread in the Bugs forum explaining what you were doing and referencing Error ID $id");
} catch (\Error | \Exception $e) {
// if there was an ongoing transaction, abort it
if ($e::class === DB\MysqlException::class) {
DB::DB()->rollback();
}
$id = $Debug->saveError($e);
$message = DEBUG_MODE || $Viewer?->permitted('site_debug')
? ($e->getMessage() . " (case $id)")
: "That is not supposed to happen, you can a thread in the Bugs forum explaining what you were doing and referencing Error ID $id";
Error500::error($message);
} finally {
$Debug->mark('send to user');
if (!is_null($Viewer)) {
$Debug->profile($Viewer, $module);
}
} catch (\Exception $e) {
$Debug->saveError($e);
}
// 5. Finish up
$Debug->mark('send to user');
if (!is_null($Viewer)) {
$Debug->profile($Viewer, $module);
}

View File

@@ -343,7 +343,7 @@ function authKey(): string {
* Make sure $_GET['auth'] is the same as the user's authorization key
* Should be used for any user action that relies solely on GET.
*/
function authorize(bool $Ajax = false): void {
function authorize(bool $ajax = false): void {
global $Viewer;
foreach (['auth', 'authkey'] as $auth) {
if (isset($_REQUEST[$auth]) && $Viewer->auth() === $_REQUEST[$auth]) {
@@ -354,7 +354,13 @@ function authorize(bool $Ajax = false): void {
"{$Viewer->username()} authorize failed on {$_SERVER['REQUEST_URI']}"
. (!empty($_SERVER['HTTP_REFERER']) ? " coming from " . $_SERVER['HTTP_REFERER'] : "")
);
error('Invalid authorization key. Go back, refresh, and try again.', $Ajax);
if ($ajax) {
json_die('Invalid authorization key. Go back, refresh, and try again.');
} else {
Gazelle\Error400::error(
'Invalid authorization key. Go back, refresh, and try again.'
);
}
}
function parse_user_agent(string $useragent): array {
@@ -411,25 +417,6 @@ function parse_user_agent(string $useragent): array {
return $browserUserAgent;
}
/**
* Display a critical error and kills the page.
*
* $Error Error type. Automatically supported:
* 403, 404, 0 (invalid input), -1 (invalid request)
* If you use your own string for Error, it becomes the error description.
* $NoHTML If true, the header/footer won't be shown, just the description.
* $Log If true, the user is given a link to search $Log in the site log.
*/
// phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
function error(int|string $Error, bool $NoHTML = false, bool $Log = false): never {
global $Debug, $Viewer, $Twig;
include_once __DIR__ . '/../sections/error/index.php';
if (isset($Viewer)) {
$Debug->profile($Viewer, $Viewer->requestContext()->module());
}
exit;
}
// phpcs:enable Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
/**
@@ -460,11 +447,11 @@ function json_error(int|string $code): never {
exit;
}
function json_or_error(mixed $JsonError, mixed $Error = null, bool $NoHTML = false): never {
function json_or_error(mixed $JsonError, mixed $Error = null): never {
if (defined('AJAX')) {
json_error($JsonError);
} else {
error($Error ?? $JsonError, $NoHTML);
Gazelle\Error400::error($Error ?? $JsonError);
}
}

View File

@@ -0,0 +1,151 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class AdminPrivileges extends AbstractMigration {
public function up(): void {
$this->getQueryBuilder('update') /** @phpstan-ignore-line need more magic */
->update('permissions')
->set('`Values`',
serialize([
'admin_add_log' => 1,
'admin_advanced_user_search' => 1,
'admin_audit_edit' => 1,
'admin_audit_view' => 1,
'admin_bp_history' => 1,
'admin_clear_cache' => 1,
'admin_create_users' => 1,
'admin_dnu' => 1,
'admin_donor_log' => 1,
'admin_fl_history' => 1,
'admin_freeleech' => 1,
'admin_global_notification' => 1,
'admin_login_watch' => 1,
'admin_manage_applicants' => 1,
'admin_manage_blog' => 1,
'admin_manage_contest' => 1,
'admin_manage_fls' => 1,
'admin_manage_forums' => 1,
'admin_manage_invite_source' => 1,
'admin_manage_ipbans' => 1,
'admin_manage_navigation' => 1,
'admin_manage_news' => 1,
'admin_manage_payments' => 1,
'admin_manage_permissions' => 1,
'admin_manage_polls' => 1,
'admin_manage_referrals' => 1,
'admin_manage_stylesheets' => 1,
'admin_manage_user_fls' => 1,
'admin_manage_wiki' => 1,
'admin_periodic_task_manage' => 1,
'admin_periodic_task_view' => 1,
'admin_rate_limit_manage' => 1,
'admin_rate_limit_view' => 1,
'admin_recovery' => 1,
'admin_reports' => 1,
'admin_schedule' => 1,
'admin_site_debug' => 1,
'admin_staffpm_stats' => 1,
'admin_tracker' => 1,
'admin_view_notifications' => 1,
'admin_view_payments' => 1,
'admin_view_referrals' => 1,
'admin_whitelist' => 1,
'artist_edit_vanityhouse' => 1,
'can_use_tor' => 1,
'edit_unknowns' => 1,
'forums_polls_create' => 1,
'forums_polls_moderate' => 1,
'site_admin_forums' => 1,
'site_admin_requests' => 1,
'site_advanced_search' => 1,
'site_advanced_top10' => 1,
'site_album_votes' => 1,
'site_analysis' => 1,
'site_archive_ajax' => 1,
'site_can_invite_always' => 1,
'site_collages_create' => 1,
'site_collages_delete' => 1,
'site_collages_manage' => 1,
'site_collages_personal' => 1,
'site_collages_recover' => 1,
'site_collages_renamepersonal' => 1,
'site_collages_subscribe' => 1,
'site_database_specifics' => 1,
'site_debug' => 1,
'site_delete_artist' => 1,
'site_delete_tag' => 1,
'site_disable_ip_history' => 1,
'site_edit_lineage' => 1,
'site_edit_requests' => 1,
'site_edit_wiki' => 1,
'site_forum_autosub' => 1,
'site_forum_post_delete' => 1,
'site_make_bookmarks' => 1,
'site_moderate_forums' => 1,
'site_moderate_requests' => 1,
'site_search_many' => 1,
'site_send_unlimited_invites' => 1,
'site_submit_requests' => 1,
'site_tag_aliases_read' => 1,
'site_top10' => 1,
'site_torrents_notify' => 1,
'site_unlimit_ajax' => 1,
'site_upload' => 1,
'site_user_stats' => 1,
'site_view_flow' => 1,
'site_view_full_log' => 1,
'site_view_torrent_snatchlist' => 1,
'site_vote' => 1,
'torrents_add_artist' => 1,
'torrents_delete' => 1,
'torrents_delete_fast' => 1,
'torrents_edit' => 1,
'torrents_edit_vanityhouse' => 1,
'torrents_freeleech' => 1,
'users_auto_reports' => 1,
'users_delete_users' => 1,
'users_disable_any' => 1,
'users_disable_posts' => 1,
'users_disable_users' => 1,
'users_edit_avatars' => 1,
'users_edit_invites' => 1,
'users_edit_own_ratio' => 1,
'users_edit_password' => 1,
'users_edit_profiles' => 1,
'users_edit_ratio' => 1,
'users_edit_reset_keys' => 1,
'users_edit_titles' => 1,
'users_edit_usernames' => 1,
'users_give_donor' => 1,
'users_invite_notes' => 1,
'users_linked_users' => 1,
'users_logout' => 1,
'users_make_invisible' => 1,
'users_mod' => 1,
'users_override_paranoia' => 1,
'users_promote_below' => 1,
'users_promote_to' => 1,
'users_reset_own_keys' => 1,
'users_view_email' => 1,
'users_view_friends' => 1,
'users_view_invites' => 1,
'users_view_ips' => 1,
'users_view_keys' => 1,
'users_view_seedleech' => 1,
'users_view_uploaded' => 1,
'users_warn' => 1,
'view_last_seen' => 1,
'zip_downloader' => 1,
])
)
->where(['Level' => 1000])
->execute();
}
public function down(): void {
// no-op
}
}

View File

@@ -230,46 +230,6 @@ parameters:
count: 1
path: ../sections/better/better.php
-
message: "#^Function Gazelle\\\\notify invoked with 2 parameters, 3 required\\.$#"
count: 1
path: ../sections/error/404.php
-
message: "#^Function Gazelle\\\\notify invoked with 2 parameters, 3 required\\.$#"
count: 1
path: ../sections/error/413.php
-
message: "#^Function Gazelle\\\\notify invoked with 2 parameters, 3 required\\.$#"
count: 1
path: ../sections/error/504.php
-
message: "#^Function Gazelle\\\\notify\\(\\) has no return type specified\\.$#"
count: 1
path: ../sections/error/index.php
-
message: "#^Function Gazelle\\\\notify\\(\\) has parameter \\$Channel with no type specified\\.$#"
count: 1
path: ../sections/error/index.php
-
message: "#^Function Gazelle\\\\notify\\(\\) has parameter \\$Message with no type specified\\.$#"
count: 1
path: ../sections/error/index.php
-
message: "#^Function Gazelle\\\\notify\\(\\) has parameter \\$Viewer with no type specified\\.$#"
count: 1
path: ../sections/error/index.php
-
message: "#^Variable \\$Error might not be defined\\.$#"
count: 1
path: ../sections/error/index.php
-
message: "#^Variable \\$info might not be defined\\.$#"
count: 1

View File

@@ -67,10 +67,10 @@ if (!$Action || !isset($Viewer)) {
}
$UserID = $Viewer->id();
if (!empty($_SERVER['CONTENT_TYPE']) && str_starts_with($_SERVER['CONTENT_TYPE'], 'application/json')) {
if (str_starts_with($_SERVER['CONTENT_TYPE'] ?? '', 'application/json')) {
$input = file_get_contents('php://input');
if ($input === false) {
error("json decode failure");
json_error("json decode failure");
}
$_POST = json_decode($input, true);
}

View File

@@ -6,12 +6,7 @@ namespace Gazelle;
authorize(true);
print
json_encode(
[
'status' => 'success',
'response' => [
'loadAverage' => sys_getloadavg()
]
]
);
print json_encode([
'status' => 'success',
'response' => ['loadAverage' => sys_getloadavg()]
]);

View File

@@ -11,7 +11,7 @@ if (isset($_FILES['log']) && is_uploaded_file($_FILES['log']['tmp_name'])) {
$fileTmp = tempnam(TMPDIR, 'log_');
if ($fileTmp === false) {
// This will only happen if the directory that TMPDIR points to disappears
error('Failed to persist the log file.');
json_error('Failed to persist the log file.');
}
file_put_contents($fileTmp, $_POST["pastelog"]);
$file = [

View File

@@ -7,7 +7,7 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_admin_forums')) {
error(403);
Error403::error();
}
$postId = (int)($_GET['postid'] ?? 0);

View File

@@ -58,7 +58,7 @@ switch ($type) {
case 'bookmarks':
$Title = 'Your bookmarked requests';
if (is_null($user)) {
error("No user id given");
json_die("No user id given");
}
$search->setBookmarker($user);
$BookmarkView = true;
@@ -99,7 +99,7 @@ if (isset($_GET['requestor'])) {
if ($requestor) {
$search->setRequestor($requestor);
} else {
error(404);
json_die('requestor not found');
}
}

View File

@@ -8,7 +8,7 @@ namespace Gazelle;
authorize();
if ($Viewer->disableTagging() || !$Viewer->permitted('site_delete_tag')) {
error(403);
Error403::error();
}
$tagMan = new Manager\Tag();
$tgMan = new Manager\TGroup();
@@ -16,7 +16,7 @@ $tgMan = new Manager\TGroup();
$tag = $tagMan->findById((int)$_GET['tagid']);
$tgroup = $tgMan->findById((int)$_GET['groupid']);
if (is_null($tgroup) || is_null($tag)) {
error(404);
Error404::error();
}
$tagName = $tag->name();

View File

@@ -13,7 +13,7 @@ if ($Viewer->permitted('admin_manage_applicants')) {
/** @var \Gazelle\User $Viewer phpstan is dense */
if (!array_filter($appRoleMan->publishedList(), fn($r) => $r->isStaffViewer($Viewer))) {
// a user is being naughty
error(403);
Error403::error();
}
// Staff who can see specific roles cannot see the admin page
header('Location: apply.php?action=view');

View File

@@ -7,12 +7,12 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('admin_manage_applicants')) {
error(403);
Error403::error();
}
$role = (new Manager\ApplicantRole())->findById((int)($_GET['id'] ?? 0));
if (is_null($role)) {
error(404);
Error404::error();
}
if (isset($_POST['auth'])) {

View File

@@ -10,10 +10,10 @@ $appMan = new Manager\Applicant();
if (isset($_REQUEST['id'])) {
$app = $appMan->findById((int)$_GET['id']);
if (is_null($app)) {
error(404);
Error404::error();
}
if (!$app->isViewable($Viewer)) {
error(403);
Error403::error();
}
if (!empty($_POST['note_reply'])) {

View File

@@ -7,28 +7,28 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('torrents_edit')) {
error(403);
Error403::error();
}
authorize();
$redirectId = (int)$_POST['redirect'];
$newName = Artist::sanitize($_POST['name']);
if (empty($newName)) {
error('The specified name is empty.');
Error400::error('The specified name is empty.');
}
$artMan = new Manager\Artist();
$artist = $artMan->findById((int)$_POST['artistid']);
if (is_null($artist)) {
error(404);
Error404::error();
} elseif ($artist->isLocked() && !$Viewer->permitted('users_mod')) {
error('This artist is locked.');
Error400::error('This artist is locked.');
}
$otherArtist = $artMan->findByName($newName);
if ($otherArtist) {
if ($otherArtist->id() === $artist->id()) {
error("This artist already has the specified alias.");
Error400::error("This artist already has the specified alias.");
}
echo $Twig->render('artist/error-alias.twig', [
'alias' => $newName,
@@ -41,10 +41,10 @@ $redirArtist = null;
if ($redirectId) {
$redirArtist = $artMan->findByAliasId($redirectId);
if (is_null($redirArtist)) {
error("No alias found for desired redirect.");
Error400::error("No alias found for desired redirect.");
}
if ($artist->id() !== $redirArtist->id()) {
error("Cannot redirect to the alias of a different artist.");
Error400::error("Cannot redirect to the alias of a different artist.");
}
}

View File

@@ -15,7 +15,7 @@ if (is_null($artist)) {
if (defined('AJAX')) {
json_die('failure', 'no such artist');
} else {
error(404);
Error404::error('no such artist');
}
}
$other = $artistMan->findByName(trim($_POST['artistname'] ?? ''));
@@ -25,7 +25,7 @@ if (is_null($other)) {
if (defined('AJAX')) {
json_die('failure', 'no such similar artist name');
} else {
error('Unknown similar artist name.');
Error404::error('Unknown similar artist name.');
}
}
}

View File

@@ -14,7 +14,7 @@ $artist = $revisionId
? $artistMan->findByIdAndRevision((int)($_GET['id'] ?? 0), $revisionId)
: $artistMan->findById((int)($_GET['id'] ?? 0));
if (is_null($artist)) {
error(404);
Error404::error();
}
$artist->loadArtistRole();
$artistId = $artist->id();

View File

@@ -7,28 +7,28 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('torrents_edit')) {
error(403);
Error403::error();
}
authorize();
$artMan = new Manager\Artist();
$artist = $artMan->findById((int)($_POST['artistid'] ?? 0));
if (is_null($artist)) {
error('Please select a valid artist to change.');
Error400::error('Please select a valid artist to change.');
} elseif ($artist->isLocked() && !$Viewer->permitted('users_mod')) {
error('This artist is locked.');
Error400::error('This artist is locked.');
}
$new = $artMan->findById((int)($_POST['newartistid'] ?? 0));
if (is_null($new)) {
$new = $artMan->findByName($_POST['newartistname'] ?? '');
if (is_null($new)) {
error('Please enter a valid artist ID number or a valid artist name.');
Error404::error('Please enter a valid artist ID number or a valid artist name.');
}
}
if ($artist->id() == $new->id()) {
error('You cannot merge an artist with itself.');
Error400::error('You cannot merge an artist with itself.');
}
$redirect = (bool)$_POST['redirect'];

View File

@@ -7,13 +7,13 @@ declare(strict_types=1);
namespace Gazelle;
if (!($Viewer->permitted('site_delete_artist') && $Viewer->permitted('torrents_delete'))) {
error(403);
Error403::error();
}
authorize();
$artist = (new Manager\Artist())->findById((int)($_GET['artistid'] ?? 0));
if (is_null($artist)) {
error(404);
Error404::error();
}
$tgMan = new Manager\TGroup();

View File

@@ -7,7 +7,7 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('torrents_edit')) {
error(403);
Error403::error();
}
authorize();
@@ -15,16 +15,16 @@ $artMan = new Manager\Artist();
$aliasId = (int)$_GET['aliasid'];
$artist = $artMan->findByAliasId($aliasId);
if (is_null($artist)) {
error(404);
Error404::error();
} elseif ($artist->isLocked() && !$Viewer->permitted('users_mod')) {
error('This artist is locked.');
Error400::error('This artist is locked.');
}
if ($artist->primaryAliasId() === $aliasId) {
error("You cannot delete the primary alias.");
Error400::error("You cannot delete the primary alias.");
}
if (!empty($artist->aliasInfo()[$aliasId]['alias'])) {
error("This alias has redirecting aliases attached.");
Error400::error("This alias has redirecting aliases attached.");
}
$tgroupList = $artMan->tgroupList($aliasId, new Manager\TGroup());

View File

@@ -8,14 +8,14 @@ namespace Gazelle;
authorize();
if (!$Viewer->permitted('site_delete_tag')) {
error(403);
Error403::error();
}
$artistMan = new Manager\Artist();
$artist = $artistMan->findById((int)($_GET['artistid'] ?? 0));
$similar = $artistMan->findById((int)($_GET['similarid'] ?? 0));
if (is_null($artist) || is_null($similar)) {
error(404);
Error404::error();
}
$artist->similar()->removeSimilar($similar, $Viewer);

View File

@@ -6,19 +6,19 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('zip_downloader')) {
error(403);
Error403::error();
}
if (!isset($_REQUEST['preference']) || count($_REQUEST['list']) === 0) {
error('No artist collector preference specified');
Error400::error('No artist collector preference specified');
}
$artist = (new Manager\Artist())->findById((int)($_REQUEST['artistid'] ?? 0));
if (is_null($artist)) {
error(404);
Error404::error();
}
$collector = new Collector\Artist($Viewer, new Manager\Torrent(), $artist, (int)$_REQUEST['preference']);
if (!$collector->prepare($_REQUEST['list'])) {
error("Nothing to gather, choose some encodings and media!");
Error400::error("Nothing to gather, choose some encodings and media!");
}
$Viewer->modifyOption('Collector', [implode(':', $_REQUEST['list']), $_REQUEST['preference']]);

View File

@@ -7,13 +7,15 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('torrents_edit')) {
error(403);
Error403::error();
}
$artist = (new Manager\Artist())->findById((int)$_GET['artistid']);
if (is_null($artist)) {
$id = html_escape($_GET['artistid']); // might not be a number
error("Cannot find an artist with the ID $id: See the <a href=\"log.php?search=Artist+$id\">site log</a>.");
Error400::error(
"Cannot find an artist with the ID $id: See the <a href=\"log.php?search=Artist+$id\">site log</a>."
);
}
echo $Twig->render('artist/edit.twig', [

View File

@@ -6,21 +6,21 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_edit_wiki')) {
error(403);
Error403::error();
}
authorize();
$artist = (new Manager\Artist())->findById((int)$_POST['artistid']);
if (is_null($artist)) {
error(404);
Error404::error();
}
if (($_GET['action'] ?? '') === 'revert') { // if we're reverting to a previous revision
authorize();
$revisionId = (int)$_GET['revisionid'];
if (!$revisionId) {
error('No revision given to revert');
Error400::error('No revision given to revert');
}
$artist->revertRevision($revisionId, $Viewer);
header("Location: " . $artist->location());
@@ -36,11 +36,11 @@ $image = trim($_POST['image']);
if ($image != $artist->image()) {
if (!empty($image)) {
if (!preg_match(IMAGE_REGEXP, $image)) {
error(display_str($image) . " does not look like a valid image url");
Error400::error(html_escape($image) . " does not look like a valid image url");
}
$banned = (new Util\ImageProxy($Viewer))->badHost($image);
if ($banned) {
error("Please rehost images from $banned elsewhere.");
Error400::error("Please rehost images from $banned elsewhere.");
}
}
$artist->setField('image', $image);

View File

@@ -8,7 +8,7 @@ namespace Gazelle;
$artist = (new Manager\Artist())->findById((int)($_GET['artistid'] ?? 0));
if (is_null($artist)) {
error(404);
Error404::error();
}
echo $Twig->render('artist/request-edit.twig', [

View File

@@ -8,7 +8,7 @@ namespace Gazelle;
$artist = (new Manager\Artist())->findById((int)($_POST['artistid'] ?? 0));
if (is_null($artist)) {
error(404);
Error404::error();
}
authorize();

View File

@@ -8,7 +8,7 @@ namespace Gazelle;
$artistMan = new Manager\Artist();
$artist = $artistMan->findById((int)$_GET['artistid']);
if (is_null($artist)) {
error(404);
Error404::error();
}
echo $Twig->render('revision.twig', ['object' => $artist]);

View File

@@ -14,7 +14,7 @@ if (!empty($_POST['action'])) {
'rename' => include_once 'rename.php',
'edit' => include_once 'edit_handle.php',
'takeeditrequest' => include_once 'edit_request_handle.php',
default => error('Missing artist POST action'),
default => Error400::error('Missing artist POST action'),
};
} elseif (!empty($_GET['action'])) {
match ($_GET['action']) {
@@ -30,7 +30,7 @@ if (!empty($_POST['action'])) {
'notifyremove' => include_once 'notify_remove.php',
'revert' => include_once 'edit_handle.php',
'vote_similar' => include_once 'vote_similar.php',
default => error('Missing artist action'),
default => Error400::error('Missing artist action'),
};
} else {
if (!empty($_GET['id'])) {

View File

@@ -6,13 +6,13 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_torrents_notify')) {
error(403);
Error403::error();
}
authorize();
$artist = (new Manager\Artist())->findById((int)$_GET['artistid']);
if (is_null($artist)) {
error(404);
Error404::error();
}
$Viewer->addArtistNotification($artist);

View File

@@ -6,13 +6,13 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_torrents_notify')) {
error(403);
Error403::error();
}
authorize();
$artist = (new Manager\Artist())->findById((int)$_GET['artistid']);
if (is_null($artist)) {
error(404);
Error404::error();
}
$Viewer->removeArtistNotification($artist);

View File

@@ -6,7 +6,7 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('torrents_edit')) {
error(403);
Error403::error();
}
authorize();
@@ -14,25 +14,27 @@ authorize();
$artistMan = new Manager\Artist();
$artist = $artistMan->findById((int)($_POST['artistid'] ?? 0));
if (is_null($artist) || empty($_POST['aliasid'])) {
error(404);
Error404::error();
} elseif ($artist->isLocked() && !$Viewer->permitted('users_mod')) {
error('This artist is locked.');
Error400::error('This artist is locked.');
}
$aliasId = (int)$_POST['aliasid'];
$newName = Artist::sanitize($_POST['name']);
if (empty($newName)) {
error('No new name given.');
Error400::error('No new name given.');
} elseif (!isset($artist->aliasList()[$aliasId])) {
error('Could not find existing alias ID');
Error400::error('Could not find existing alias ID');
} elseif ($artist->aliasList()[$aliasId]['name'] === $newName) {
error('The new name is identical to the old name."');
Error400::error('The new name is identical to the old name."');
}
$oldName = $artist->aliasList()[$aliasId]['name'];
$otherArtist = $artistMan->findByName($newName);
if (!is_null($otherArtist) && $otherArtist->id() !== $artist->id()) {
error("An artist with this alias already exists: {$otherArtist->name()} ({$otherArtist->id()})");
Error400::error(
"An artist with this alias already exists: {$otherArtist->name()} ({$otherArtist->id()})"
);
}
$result = $artist->renameAlias(
@@ -44,7 +46,7 @@ $result = $artist->renameAlias(
);
if (is_null($result)) {
error("The specified name is already in use.");
Error::error("The specified name is already in use.");
}
header("Location: artist.php?artistid={$artist->id()}&action=edit");

View File

@@ -7,14 +7,14 @@ namespace Gazelle;
$way = trim($_GET['way']);
if (!in_array($way, ['up', 'down'])) {
error('Missing artist vote decision');
Error::error('Missing artist vote decision');
}
$artistMan = new Manager\Artist();
$artist = $artistMan->findById((int)($_GET['artistid'] ?? 0));
$similar = $artistMan->findById((int)($_GET['similarid'] ?? 0));
if (is_null($artist) || is_null($similar)) {
error("One of the artists was not found");
Error::error("One of the artists was not found");
}
$artist->similar()->voteSimilar($Viewer, $similar, $way === 'up');

View File

@@ -10,7 +10,7 @@ $userMan = new Manager\User();
if (isset($_GET['userid']) && $Viewer->permitted('users_override_paranoia')) {
$user = $userMan->findById((int)$_GET['userid']);
if (is_null($user)) {
error(404);
Error404::error();
}
} else {
$user = $Viewer;
@@ -34,7 +34,7 @@ $better = match ($type) {
'single' => new Better\SingleSeeded($user, $filter, (new Manager\Torrent())->setViewer($Viewer)),
'files', 'folders', 'lineage', 'tags', 'trumpable'
=> (new Better\Bad($user, $filter, new Manager\Torrent()))->setBadType($type),
default => error(404),
default => Error404::error(),
};
if (isset($_GET['remove']) && $better instanceof Better\Bad && $Viewer->permitted('admin_reports')) {

View File

@@ -20,11 +20,11 @@ if (!isset($_GET['userid'])) {
$user = $Viewer;
} else {
if (!$Viewer->permitted('users_override_paranoia')) {
error(403);
Error403::error();
}
$user = (new Manager\User())->findById((int)$_GET['userid']);
if (is_null($user)) {
error(404);
Error404::error();
}
}

View File

@@ -6,13 +6,15 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('admin_manage_blog')) {
error(403);
Error403::error();
}
authorize();
$blog = (new Manager\Blog())->findById((int)($_GET['id'] ?? 0));
if (is_null($blog)) {
error('Please provide the ID of a blog post from which to remove the thread link.');
Error404::error(
'Please provide the ID of a blog post from which to remove the thread link.'
);
}
$blog->removeThread();

View File

@@ -6,14 +6,14 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('admin_manage_blog')) {
error(403);
Error403::error();
}
authorize();
$blogMan = new Manager\Blog();
$blog = $blogMan->findById((int)($_GET['id'] ?? 0));
if (is_null($blog)) {
error('You must provide an ID of a blog to delete');
Error404::error('You must provide an ID of a blog to delete');
}
$blog->remove();
$blogMan->flush();

View File

@@ -6,23 +6,23 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('admin_manage_blog')) {
error(403);
Error403::error();
}
authorize();
$body = trim($_POST['body']);
if (empty($body)) {
error('The body of the blog article must not be empty');
Error400::error('The body of the blog article must not be empty');
}
$title = trim($_POST['title']);
if (empty($title)) {
error('The title of the blog article must not be empty');
Error400::error('The title of the blog article must not be empty');
}
$blog = (new Manager\Blog())->findById((int)($_POST['blogid'] ?? 0));
if (is_null($blog)) {
error(404);
Error404::error();
}
$manager = new Manager\ForumThread();

View File

@@ -8,18 +8,18 @@ namespace Gazelle;
use Gazelle\Enum\NotificationType;
if (!$Viewer->permitted('admin_manage_blog')) {
error(403);
Error403::error();
}
authorize();
$body = trim($_POST['body']);
if (empty($body)) {
error('The body of the blog article must not be empty');
Error400::error('The body of the blog article must not be empty');
}
$title = trim($_POST['title']);
if (empty($title)) {
error('The title of the blog article must not be empty');
Error400::error('The title of the blog article must not be empty');
}
$thread = match ((int)($_POST['thread'] ?? -1)) {

View File

@@ -28,11 +28,11 @@ if (empty($_GET['userid'])) {
$ownProfile = true;
} else {
if (!$Viewer->permitted('admin_bp_history')) {
error(403);
Error403::error();
}
$user = $userMan->findById((int)($_GET['userid'] ?? 0));
if (is_null($user)) {
error(404);
Error404::error();
}
$ownProfile = false;
}

View File

@@ -10,11 +10,11 @@ if (!isset($_GET['userid'])) {
$user = $Viewer;
} else {
if (!$Viewer->permitted('admin_bp_history')) {
error(403);
Error403::error();
}
$user = (new Manager\User())->findById((int)($_GET['userid'] ?? 0));
if (is_null($user)) {
error(404);
Error404::error();
}
}

View File

@@ -6,7 +6,7 @@ declare(strict_types=1);
namespace Gazelle;
if ($Viewer->disableBonusPoints()) {
error('Your bonus points have been deactivated.');
Error403::error('Your bonus points have been deactivated.');
}
const DEFAULT_PAGE = 'store.php';
@@ -24,7 +24,7 @@ switch ($_GET['action'] ?? '') {
}
$Price = $viewerBonus->effectivePrice($Label);
if ($Price > $Viewer->bonusPointsTotal()) {
error('You cannot afford this item.');
Error400::error('You cannot afford this item.');
}
include_once match ($Label) {
'invite' => 'invite.php',

View File

@@ -7,6 +7,8 @@ namespace Gazelle;
authorize();
if (!(new User\Bonus($Viewer))->purchaseInvite()) {
error("You cannot purchase an invite (either you don't have the privilege or you don't have enough bonus points).");
Error400::error(
"You cannot purchase an invite (either you don't have the privilege or you don't have enough bonus points)."
);
}
header('Location: bonus.php?complete=invite');

View File

@@ -12,19 +12,19 @@ $bonus = new User\Bonus($Viewer);
if ($label === 'collage-1') {
if (!$bonus->purchaseCollage($label)) {
error('Could not purchase a personal collage slot due to lack of funds.');
Error400::error('Could not purchase a personal collage slot due to lack of funds.');
}
header("Location: bonus.php?complete=$label");
} elseif ($label === 'seedbox') {
if (!$bonus->unlockSeedbox()) {
error('Could not unlock the seedbox viewer. Either you have already unlocked it, or you lack the required bonus points.');
Error400::error('Could not unlock the seedbox viewer. Either you have already unlocked it, or you lack the required bonus points.');
}
header("Location: bonus.php?complete=$label");
} elseif ($label === 'file-count') {
if (!$bonus->purchaseFeatureFilecount()) {
error('Could not purchase the file count feature. Either you have already own it, or you lack the required bonus points.');
Error400::error('Could not purchase the file count feature. Either you have already own it, or you lack the required bonus points.');
}
header("Location: bonus.php?complete=$label");
} else {
error(403);
Error403::error();
}

View File

@@ -30,17 +30,19 @@ if ($Label === 'title-bb-y') {
} elseif ($Label === 'title-bb-n') {
$BBCode = 'false';
} else {
error(403);
Error403::error();
}
if (isset($_POST['confirm'])) {
authorize();
if (!isset($_POST['title'])) {
error(403);
Error403::error();
}
$viewerBonus = new \Gazelle\User\Bonus($Viewer);
if (!$viewerBonus->purchaseTitle($Label, $_POST['title'])) {
error('This title is too long, you must reduce the length (or you do not have enough bonus points).');
Error400::error(
'This title is too long, you must reduce the length (or you do not have enough bonus points).'
);
}
header('Location: bonus.php?complete=' . urlencode($Label));
exit;

View File

@@ -15,17 +15,19 @@ namespace Gazelle;
if (isset($_POST['confirm'])) {
authorize();
if (empty($_POST['user'])) {
error('You have to enter a username to give tokens to.');
Error404::error('You have to enter a username to give tokens to.');
}
$user = (new Manager\User())->findByUsername(urldecode($_POST['user']));
if (is_null($user)) {
error('Nobody with that name found at ' . SITE_NAME . '. Try a user search and give them tokens from their profile page.');
Error404::error(
'Nobody with that name found. Try a user search and give them tokens from their profile page.'
);
} elseif ($user->id() == $Viewer->id()) {
error('You cannot gift yourself tokens, they are cheaper to buy directly.');
Error400::error('You cannot gift yourself tokens, they are cheaper to buy directly.');
}
$viewerBonus = new \Gazelle\User\Bonus($Viewer);
if (!$viewerBonus->purchaseTokenOther($user, $Label, $_POST['message'] ?? '')) {
error('Purchase for other not concluded. Either you lacked funds or they have chosen to decline FL tokens.');
Error400::error('Purchase for other not concluded. Either you lacked funds or they have chosen to decline FL tokens.');
}
header('Location: bonus.php?complete=' . urlencode($Label));
}

View File

@@ -12,12 +12,14 @@ namespace Gazelle;
authorize();
if (!preg_match('/^token-[1-4]$/', $Label, $match)) {
error(403);
Error403::error();
}
$viewerBonus = new \Gazelle\User\Bonus($Viewer);
if (!$viewerBonus->purchaseToken($Label)) {
error("You aren't able to buy those tokens. Do you have enough bonus points?");
Error400::error(
"You aren't able to buy those tokens. Do you have enough bonus points?"
);
}
header('Location: bonus.php?complete=' . urlencode($Label));

View File

@@ -12,10 +12,10 @@ if (!isset($_GET['userid'])) {
} else {
$user = $userMan->findById((int)$_GET['userid']);
if (is_null($user)) {
error(404);
Error404::error();
}
if ($user->id() != $Viewer->id() && !$Viewer->permitted('users_override_paranoia')) {
error(403);
Error403::error();
}
}

View File

@@ -10,11 +10,11 @@ if (empty($_GET['userid'])) {
$user = $Viewer;
} else {
if (!$Viewer->permitted('users_override_paranoia')) {
error(403);
Error403::error();
}
$user = (new Manager\User())->findById((int)($_GET['userid'] ?? 0));
if (is_null($user)) {
error(404);
Error404::error();
}
}

View File

@@ -24,7 +24,7 @@ switch ($_REQUEST['action'] ?? 'view') {
case 'edit':
match ($_REQUEST['type'] ?? '') {
'torrents' => include_once 'edit_torrents.php',
default => error(404),
default => Error404::error(),
};
break;
@@ -45,10 +45,10 @@ switch ($_REQUEST['action'] ?? 'view') {
include_once __DIR__ . '/../requests/requests.php';
break;
default:
error(404);
Error404::error();
}
break;
default:
error(404);
Error404::error();
}

View File

@@ -19,11 +19,11 @@ if (empty($_GET['userid'])) {
$ownProfile = true;
} else {
if (!$Viewer->permitted('users_override_paranoia')) {
error(403);
Error403::error();
}
$user = $userMan->findById((int)($_GET['userid'] ?? 0));
if (is_null($user)) {
error(404);
Error404::error();
}
$ownProfile = ($user->id() === $Viewer->id());
}

View File

@@ -8,7 +8,7 @@ namespace Gazelle;
authorize();
if (!in_array($_POST['action'], ['add_artist', 'add_artist_batch'])) {
error(403);
Error403::error();
}
$collageMan = new Manager\Collage();
@@ -29,18 +29,18 @@ if (is_null($collage) && isset($_POST['collage_ref'])) {
$collage = $collageMan->findById((int)$_POST['collageid']);
}
if (is_null($collage)) {
error(404);
Error404::error();
}
if (!$Viewer->permitted('site_collages_delete')) {
if ($collage->isLocked()) {
error('This collage is locked');
Error400::error('This collage is locked');
}
if ($collage->isPersonal() && !$collage->isOwner($Viewer)) {
error("You cannot edit someone else's personal collage.");
Error400::error("You cannot edit someone else's personal collage.");
}
if ($collage->maxGroups() > 0 && $collage->numEntries() >= $collage->maxGroups()) {
error('This collage already holds its maximum allowed number of entries.');
Error400::error('This collage already holds its maximum allowed number of entries.');
}
}
@@ -74,7 +74,7 @@ foreach ($URL as $u) {
? $artistMan->findById((int)$match['id'])
: null;
if (is_null($artist)) {
error("The artist " . htmlspecialchars($u) . " does not exist.");
Error400::error("The artist " . htmlspecialchars($u) . " does not exist.");
}
$list[] = $artist;
}
@@ -84,13 +84,15 @@ if (!$Viewer->permitted('site_collages_delete')) {
$maxGroupsPerUser = $collage->maxGroupsPerUser();
if ($maxGroupsPerUser > 0) {
if ($collage->contributionTotal($Viewer) + count($list) > $maxGroupsPerUser) {
error("You may add no more than $maxGroupsPerUser entries to this collage.");
Error400::error(
"You may add no more than $maxGroupsPerUser entries to this collage."
);
}
}
$maxGroups = $collage->maxGroups();
if ($maxGroups > 0 && ($collage->numEntries() + count($list) > $maxGroups)) {
error("This collage can hold only $maxGroups entries.");
Error400::error("This collage can hold only $maxGroups entries.");
}
}

View File

@@ -8,10 +8,10 @@ namespace Gazelle;
authorize();
if (!in_array($_REQUEST['action'], ['add_torrent', 'add_torrent_batch'])) {
error(403);
Error403::error();
}
if (!$Viewer->permitted('site_collages_manage') && !$Viewer->activePersonalCollages()) {
error(403);
Error403::error();
}
$collageMan = new Manager\Collage();
@@ -27,18 +27,18 @@ if (isset($_POST['collage_combo']) && (int)$_POST['collage_combo']) {
$collage = $collageMan->findById((int)$_POST['collageid']); // From collage page
}
if (!$collage) {
error(404);
Error404::error();
}
if (!$Viewer->permitted('site_collages_delete')) {
if ($collage->isLocked()) {
error('This collage is locked');
Error400::error('This collage is locked');
}
if ($collage->isPersonal() && !$collage->isOwner($Viewer)) {
error('You cannot edit someone else\'s personal collage.');
Error400::error('You cannot edit someone else\'s personal collage.');
}
if ($collage->maxGroups() > 0 && $collage->numEntries() >= $collage->maxGroups()) {
error('This collage already holds its maximum allowed number of entries.');
Error400::error('This collage already holds its maximum allowed number of entries.');
}
}
@@ -70,7 +70,7 @@ foreach ($URL as $u) {
preg_match(TGROUP_REGEXP, $u, $match);
$tgroup = $tgroupMan->findById((int)($match['id'] ?? 0));
if (is_null($tgroup)) {
error("The torrent " . htmlspecialchars($u) . " does not exist.");
Error400::error("The torrent " . htmlspecialchars($u) . " does not exist.");
}
$list[] = $tgroup;
}
@@ -80,14 +80,16 @@ if (!$Viewer->permitted('site_collages_delete')) {
if ($maxGroupsPerUser > 0) {
if ($collage->contributionTotal($Viewer) + count($list) > $maxGroupsPerUser) {
$entry = $maxGroupsPerUser === 1 ? 'entry' : 'entries';
error("You may add no more than $maxGroupsPerUser $entry to this collage.");
Error400::error(
"You may add no more than $maxGroupsPerUser $entry to this collage."
);
}
}
$maxGroups = $collage->maxGroups();
if ($maxGroups > 0 && ($collage->numEntries() + count($list) > $maxGroups)) {
$entry = $maxGroupsPerUser === 1 ? 'entry' : 'entries';
error("This collage can hold only $maxGroups $entry.");
Error400::error("This collage can hold only $maxGroups $entry.");
}
}

View File

@@ -8,7 +8,7 @@ namespace Gazelle;
$collage = (new Manager\Collage())->findById((int)($_GET['collageid'] ?? 0));
if (is_null($collage)) {
error(404);
Error404::error();
}
$commentPage = new Comment\Collage($collage->id(), (int)($_GET['page'] ?? 0), (int)($_GET['postid'] ?? 0));

View File

@@ -40,16 +40,16 @@ if (($_GET['action'] ?? '') === 'mine') {
if (!empty($_GET['userid'])) {
$user = $userMan->findById((int)$_GET['userid']);
if (is_null($user)) {
error(404);
Error404::error();
}
if (empty($_GET['contrib'])) {
if (!$user->propertyVisible($Viewer, 'collages')) {
error(403);
Error403::error();
}
$search->setUser($user);
} else {
if (!$user->propertyVisible($Viewer, 'collagecontribs')) {
error(403);
Error403::error();
}
$search->setContributor($user);
}

View File

@@ -7,7 +7,7 @@ namespace Gazelle;
$collageMan = new Manager\Collage();
$Collage = $collageMan->findById((int)($_GET['id'] ?? 0));
if (is_null($Collage)) {
error(404);
Error404::error();
}
if ($Collage->isDeleted()) {

View File

@@ -8,10 +8,10 @@ namespace Gazelle;
$collage = (new Manager\Collage())->findById((int)($_GET['collageid'] ?? 0));
if (is_null($collage)) {
error(404);
Error404::error();
}
if ($collage->isDeleted() && !$collage->isOwner($Viewer) && !$Viewer->permitted('site_collages_delete')) {
error(403);
Error403::error();
}
echo $Twig->render('collage/delete.twig', [

View File

@@ -9,15 +9,15 @@ authorize();
$reason = trim($_POST['reason']);
if (!$reason) {
error('You must enter a reason!');
Error400::error('You must enter a reason!');
}
$collage = (new Manager\Collage())->findById((int)$_POST['collageid']);
if (is_null($collage)) {
error(404);
Error404::error();
}
if (!$Viewer->permitted('site_collages_delete') && !$collage->isOwner($Viewer)) {
error(403);
Error403::error();
}
$collageId = $collage->id();

View File

@@ -6,21 +6,21 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('zip_downloader')) {
error(403);
Error403::error();
}
if (!isset($_REQUEST['preference']) || count($_REQUEST['list']) === 0) {
error('No collage collector preference specified');
Error400::error('No collage collector preference specified');
}
$collage = (new Manager\Collage())->findById((int)($_REQUEST['collageid'] ?? 0));
if (is_null($collage)) {
error(404);
Error404::error();
}
$collector = new Collector\Collage($Viewer, new Manager\Torrent(), $collage, (int)$_REQUEST['preference']);
if (!$collector->prepare($_REQUEST['list'])) {
error("Nothing to gather, choose some encodings and media!");
Error400::error("Nothing to gather, choose some encodings and media!");
}
$Viewer->modifyOption('Collector', [implode(':', $_REQUEST['list']), $_REQUEST['preference']]);

View File

@@ -7,15 +7,15 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_edit_wiki')) {
error(403);
Error403::error();
}
$collage = (new Manager\Collage())->findById((int)($_GET['collageid'] ?? 0));
if (is_null($collage)) {
error(404);
Error404::error();
}
if ($collage->isPersonal() && !$collage->isOwner($Viewer) && !$Viewer->permitted('site_collages_delete')) {
error(403);
Error403::error();
}
$torMan = new Manager\Torrent();

View File

@@ -9,7 +9,7 @@ use Gazelle\Enum\LeechType;
use Gazelle\Enum\LeechReason;
if (!$Viewer->permitted('site_edit_wiki')) {
error(403);
Error403::error();
}
authorize();
@@ -17,15 +17,15 @@ authorize();
$collageMan = new Manager\Collage();
$collage = $collageMan->findById((int)($_POST['collageid'] ?? 0));
if (is_null($collage)) {
error(404);
Error404::error();
}
if (!$collage->isPersonal()) {
if (!$Viewer->permitted('site_collages_manage')) {
error(403);
Error403::error();
}
} elseif (!$collage->isOwner($Viewer) && !$Viewer->permitted('site_collages_delete')) {
// only owner or mod+ can edit personal collages
error(403);
Error403::error();
}
if (isset($_POST['name'])) {
@@ -43,7 +43,7 @@ if (isset($_POST['name'])) {
}
if ($collage->isOwner($Viewer)) {
if (!$Viewer->permitted('site_collages_renamepersonal') && !stristr($name, $Viewer->username())) {
error("Your personal collage's title must include your username.");
Error400::error("Your personal collage's title must include your username.");
}
}
}
@@ -81,7 +81,7 @@ if (
if (isset($_POST['category']) && isset(COLLAGE[$_POST['category']]) && (int)$_POST['category'] !== $collage->categoryId()) {
if ($collage->isPersonal() && !$Viewer->permitted('site_collages_delete')) {
error(403);
Error403::error();
}
$collage->setField('CategoryID', (int)$_POST['category']);
}

View File

@@ -7,15 +7,15 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_collages_manage')) {
error(403);
Error403::error();
}
$collage = (new Manager\Collage())->findById((int)($_GET['collageid'] ?? $_GET['id'] ?? 0));
if (is_null($collage) || $collage->isArtist()) {
error(404);
Error404::error();
}
if ($collage->isPersonal() && !$collage->isOwner($Viewer) && !$Viewer->permitted('site_collages_delete')) {
error(403);
Error403::error();
}
echo $Twig->render('collage/manage-tgroup.twig', [

View File

@@ -7,17 +7,17 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_collages_create')) {
error(403);
Error403::error();
}
$collage = (new Manager\Collage())->findById((int)$_GET['collageid']);
if (is_null($collage)) {
error(404);
Error404::error();
}
if ($collage->isPersonal() && !$collage->isOwner($Viewer) && !$Viewer->permitted('site_collages_delete')) {
error(403);
Error403::error();
}
if (!$collage->isArtist()) {
error(404);
Error404::error();
}
echo $Twig->render('collage/manage-artists.twig', [

View File

@@ -6,21 +6,21 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_collages_create')) {
error(403);
Error403::error();
}
authorize();
$artist = (new Manager\Artist())->findById((int)($_POST['artistid'] ?? 0));
if (is_null($artist)) {
error(404);
Error404::error();
}
$collage = (new Manager\Collage())->findById((int)$_POST['collageid']);
if (is_null($collage)) {
error(404);
Error404::error();
}
if (!$collage->isArtist()) {
error(403);
Error403::error();
}
if (isset($_POST['drag_drop_collage_sort_order'])) {
@@ -30,7 +30,7 @@ if (isset($_POST['drag_drop_collage_sort_order'])) {
} else {
$sequence = (int)$_POST['sort'];
if (!$sequence) {
error(404);
Error404::error();
}
$collage->updateSequenceEntry($artist, $sequence);
}

View File

@@ -6,17 +6,17 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_collages_manage')) {
error(403);
Error403::error();
}
authorize();
$collage = (new Manager\Collage())->findById((int)($_POST['collageid']));
if (is_null($collage)) {
error("Cannot find the requested collage");
Error404::error("Cannot find the requested collage");
}
if ($collage->isPersonal() && !$collage->isOwner($Viewer) && !$Viewer->permitted('site_collages_delete')) {
error(403);
Error403::error();
}
if (isset($_POST['drag_drop_collage_sort_order'])) {
@@ -24,11 +24,13 @@ if (isset($_POST['drag_drop_collage_sort_order'])) {
} elseif (isset($_POST['groupid'])) {
$tgroup = (new Manager\TGroup())->findById((int)($_POST['groupid'] ?? 0));
if (is_null($tgroup)) {
error("Cannot find torrent group");
Error404::error("Cannot find torrent group");
}
if (isset($_POST['sort'])) {
$collage->updateSequenceEntry($tgroup, (int)$_POST['sort']);
} elseif ($_POST['submit'] === 'Remove') {
}
if ($_POST['submit'] === 'Remove') {
$userId = $collage->entryUserId($tgroup);
if ($collage->removeEntry($tgroup)) {
$collage->logger()->general(

View File

@@ -9,7 +9,7 @@ namespace Gazelle;
use Gazelle\Enum\CollageType;
if (!$Viewer->permitted('site_collages_create') && !$Viewer->canCreatePersonalCollage()) {
error(403);
Error403::error();
}
// the variables below are instantiated via new_handle.php in the event of an error

View File

@@ -8,13 +8,13 @@ namespace Gazelle;
use Gazelle\Enum\CollageType;
if (!$Viewer->permitted('site_collages_create') && !$Viewer->canCreatePersonalCollage()) {
error(403);
Error403::error();
}
authorize();
if (!isset($_POST['category'])) {
error(403);
Error403::error();
}
$categoryId = (int)$_POST['category'];
$collageMan = new Manager\Collage();

View File

@@ -7,7 +7,7 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_collages_recover')) {
error(403);
Error403::error();
}
$_POST['id'] = (int)($_POST['id'] ?? 0);
@@ -25,7 +25,7 @@ if (!empty($_POST['id']) || $_POST['name'] !== '') {
$collage = $collageMan->recoverByName($_POST['name']);
}
if (!$collage) {
error('Collage is completely deleted');
Error404::error('Collage is completely deleted');
} else {
$collageId = $collage->flush()->id();
$collage->logger()->general("Collage $collageId was recovered by " . $Viewer->username());

View File

@@ -28,10 +28,10 @@ if (!isset($_GET['id'])) {
} else {
$User = $userMan->findById((int)($_GET['id'] ?? 0));
if (is_null($User)) {
error(404);
Error404::error();
}
if (!$User->propertyVisible($Viewer, 'torrentcomments')) {
error(403);
Error403::error();
}
}
$UserID = $User->id();
@@ -177,7 +177,7 @@ switch ($Action) {
}
break;
default:
error('What are you trying to comment on?');
Error400::error('What are you trying to comment on?');
}
$Join[] = "INNER JOIN comments C ON (C.Page = ? AND C.PageID = $idField)";

View File

@@ -6,12 +6,12 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_moderate_forums')) {
error(403);
Error403::error();
}
authorize();
$comment = (new Manager\Comment())->findById((int)($_REQUEST['postid'] ?? 0));
if (is_null($comment)) {
error(404);
Error404::error();
}
$comment->remove();

View File

@@ -6,25 +6,25 @@ declare(strict_types=1);
namespace Gazelle;
if ($Viewer->disablePosting()) {
error('Your posting privileges have been removed.');
Error403::error('Your posting privileges have been removed.');
}
authorize();
$body = trim($_POST['body'] ?? '');
if (!strlen($body)) {
error(404);
Error404::error();
}
$comment = (new Manager\Comment())->findById((int)($_REQUEST['postid'] ?? 0));
if (is_null($comment)) {
error(404);
Error404::error();
}
if ($comment->userId() != $Viewer->id() && !$Viewer->permitted('site_moderate_forums')) {
error(403);
Error403::error();
}
$user = (new Manager\User())->findById($comment->userId());
if (is_null($user)) {
error(404);
Error404::error();
}
$comment->setField('Body', $body)->setField('EditedUserID', $Viewer->id())->modify();

View File

@@ -6,7 +6,7 @@ namespace Gazelle;
$body = (new Manager\Comment())->findBodyById((int)($_GET['postid'] ?? 0));
if (is_null($body)) {
error(404);
Error404::error();
}
header('Content-type: text/plain');

View File

@@ -6,6 +6,6 @@ namespace Gazelle;
$comment = (new Manager\Comment())->findById((int)($_REQUEST['postid'] ?? 0));
if (is_null($comment)) {
error(404);
Error404::error();
}
header('Location: ' . $comment->location());

View File

@@ -6,18 +6,18 @@ declare(strict_types=1);
namespace Gazelle;
if ($Viewer->disablePosting()) {
error('Your posting privileges have been removed.');
Error403::error('Your posting privileges have been removed.');
}
authorize();
$page = $_REQUEST['page'] ?? null;
if (!in_array($page, ['artist', 'collages', 'requests', 'torrents'])) {
error(403);
Error403::error();
}
$pageId = (int)($_REQUEST['pageid'] ?? 0);
if (!$pageId) {
error(404);
Error404::error();
}
$commentMan = new Manager\Comment();

View File

@@ -7,12 +7,12 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('users_warn')) {
error(403);
Error403::error();
}
$comment = (new Manager\Comment())->findById((int)($_POST['postid'] ?? 0));
if (is_null($comment)) {
error(404);
Error404::error();
}
echo $Twig->render('comment/warn.twig', [

View File

@@ -7,7 +7,7 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('admin_manage_contest')) {
error(403);
Error403::error();
}
$contestMan = new Manager\Contest();

View File

@@ -16,7 +16,7 @@ if (!isset($_GET['token'])) {
$enabler = (new Manager\AutoEnable())->findByToken($_GET['token']);
if (is_null($enabler)) {
error('invalid enable token');
Error400::error('invalid enable token');
}
echo $Twig->render('enable/processed.twig', [

View File

@@ -1,9 +0,0 @@
<?php
declare(strict_types=1);
namespace Gazelle;
notify(IRC_CHAN_STATUS, '403', $_SERVER['REQUEST_URI']);
?>
<h1>Error: 403</h1> Forbidden.

View File

@@ -1,12 +0,0 @@
<?php
namespace Gazelle;
?>
<h1>Error: 404</h1> Not Found.
<?php
//Hide alerts for missing images and static requests
if (!preg_match("/\.(ico|jpg|jpeg|gif|png)$/", $_SERVER['REQUEST_URI']) && substr($_SERVER['REQUEST_URI'], 0, 9) !== '/static/') {
notify(IRC_CHAN_STATUS, '404');
}

View File

@@ -1,7 +0,0 @@
<?php
namespace Gazelle;
notify(IRC_CHAN_STATUS, '413');
?>
<h1>Error: 413</h1> Request is too large.

View File

@@ -1,7 +0,0 @@
<?php
namespace Gazelle;
notify(IRC_CHAN_STATUS, '504');
?>
<h1>Error: 504</h1> Gateway timeout.

View File

@@ -1,61 +0,0 @@
<?php
// phpcs:disable PSR1.Files.SideEffects.FoundWithSymbols
/** @phpstan-var \Gazelle\User $Viewer */
/** @phpstan-var \Twig\Environment $Twig */
declare(strict_types=1);
namespace Gazelle;
use Gazelle\Util\Irc;
function notify($Viewer, $Channel, $Message) {
$ipaddr = $Viewer->requestContext()->remoteAddr();
Irc::sendMessage($Channel,
$Message . " error by "
. ($Viewer
? $Viewer->publicLocation() . " (" . $Viewer->username() . ")"
: $ipaddr
)
. " (" . (new \Gazelle\Util\GeoIP(new \Gazelle\Util\Curl()))->countryISO($ipaddr) . ")"
. " accessing " . SITE_URL . $_SERVER['REQUEST_URI'] . ' (' . $_SERVER['REQUEST_METHOD'] . ')'
. (!empty($_SERVER['HTTP_REFERER']) ? " from " . $_SERVER['HTTP_REFERER'] : '')
);
}
switch ($Error) {
case '403':
$Title = "Error 403";
$Description = "You tried to go to a page that you don't have enough permission to view.";
notify($Viewer, IRC_CHAN_STATUS, 403);
break;
case '404':
$Title = "Error 404";
$Description = "You tried to go to a page that doesn't exist.";
break;
case '429':
$Title = "Error 429";
$Description = "You tried to do something too frequently.";
break;
default:
if (empty($Error)) {
$Title = "Unexpected Error";
$Description = "You have encountered an unexpected error.";
} else {
$Title = 'Error';
$Description = $Error;
}
}
if (isset($Log) && $Log) {
$Description .= ' <a href="log.php?search=' . $Log . '">Search Log</a>';
}
if (empty($NoHTML) && isset($Error) && $Error != -1) {
echo $Twig->render('error.twig', [
'title' => $Title,
'description' => $Description,
]);
} else {
echo $Description;
}

View File

@@ -6,16 +6,16 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_moderate_forums')) {
error(403);
Error403::error();
}
authorize();
$poll = (new Manager\ForumPoll())->findById((int)($_POST['threadid'] ?? 0));
if (is_null($poll)) {
error(404);
Error404::error();
}
if (!$poll->hasRevealVotes()) {
error(403);
Error403::error();
}
$poll->addAnswer(trim($_POST['new_option']));

View File

@@ -15,7 +15,7 @@ if (($_GET['forumid'] ?? '') == 'all') {
$forum = (new Manager\Forum())->findById((int)($_GET['forumid'] ?? 0));
if (is_null($forum)) {
error(404);
Error404::error();
}
$forum->userCatchup($Viewer);

View File

@@ -9,15 +9,15 @@ authorize();
$poll = (new Manager\ForumPoll())->findById((int)($_POST['threadid'] ?? 0));
if (is_null($poll)) {
error(404);
Error404::error();
}
if (!$Viewer->permitted('site_moderate_forums') && !$poll->hasRevealVotes()) {
error(403);
Error403::error();
}
$vote = (int)$_GET['vote'];
if (!$vote) {
error(404);
Error404::error();
}
$poll->modifyVote($Viewer, $vote);

View File

@@ -6,15 +6,15 @@ declare(strict_types=1);
namespace Gazelle;
if (!$Viewer->permitted('site_forum_post_delete')) {
error(403);
Error403::error();
}
authorize();
$post = (new Manager\ForumPost())->findById((int)($_GET['postid'] ?? 0));
if (is_null($post)) {
error(404);
Error404::error();
}
if (!$post->remove()) {
error(404);
Error404::error();
}

View File

@@ -8,20 +8,20 @@ namespace Gazelle;
authorize();
if (!$Viewer->permitted('site_moderate_forums')) {
error(403);
Error403::error();
}
$poll = (new Manager\ForumPoll())->findById((int)($_POST['threadid'] ?? 0));
if (is_null($poll)) {
error(404);
Error404::error();
}
if (!$poll->hasRevealVotes()) {
error(403);
Error403::error();
}
$vote = (int)$_GET['vote'];
if (!$vote) {
error(404);
Error404::error();
}
$poll->removeAnswer($vote);

View File

@@ -11,34 +11,36 @@ function handleWarningRequest(\Gazelle\Manager\ForumPost|\Gazelle\Manager\Commen
global $Viewer;
if (!$Viewer->permitted('users_warn')) {
error(403);
Error403::error();
}
authorize();
$postId = (int)($_POST['postid'] ?? 0);
$post = $manager->findById($postId);
if (is_null($post)) {
error(404);
Error404::error();
}
$userMan = new \Gazelle\Manager\User();
$user = $userMan->findById($post->userId());
if (is_null($user)) {
error(404);
Error404::error();
}
if ($user->classLevel() >= $Viewer->classLevel()) {
error(403);
Error403::error();
}
$body = trim($_POST['body'] ?? '');
if (empty($body)) {
error("Post body cannot be left empty (you can leave a reason for others to see)");
Error400::error(
"Post body cannot be left empty (you can leave a reason for others to see)"
);
}
if (empty($_POST['reason'])) {
error("Reason for warning not provided");
Error400::error("Reason for warning not provided");
}
if (!isset($_POST['length']) || !strlen($_POST['length'])) {
error("Length of warning not provided");
Error400::error("Length of warning not provided");
}
$weeks = (int)$_POST['length'];

View File

@@ -6,30 +6,30 @@ declare(strict_types=1);
namespace Gazelle;
if ($Viewer->disablePosting()) {
error("Your posting privileges have been removed.");
Error403::error("Your posting privileges have been removed.");
}
authorize();
$post = (new Manager\ForumPost())->findById((int)($_POST['post'] ?? 0));
if (!$post) {
error(display_str("No forum post #{$_POST['post']} found"));
Error404::error(display_str("No forum post #{$_POST['post']} found"));
}
$thread = $post->thread();
if (!$Viewer->writeAccess($thread->forum())) {
error("You lack the permission to edit this post.");
Error403::error("You lack the permission to edit this post.");
}
if ($thread->isLocked() && !$Viewer->permitted('site_moderate_forums')) {
error("You cannot edit a post in a locked thread.");
Error403::error("You cannot edit a post in a locked thread.");
}
if ($Viewer->id() != $post->userId()) {
if (!$Viewer->permitted('site_moderate_forums')) {
error("You cannot edit someone else's post");
Error403::error("You cannot edit someone else's post");
}
if ($_POST['pm'] ?? 0) {
$user = (new Manager\User())->findById($post->userId());
if (is_null($user)) {
error('Author of post not found');
Error404::error('Author of post not found');
}
$user->inbox()->createSystem(
"Your post #{$post->id()} has been edited",

View File

@@ -17,11 +17,11 @@ Things to expect in $_GET:
$forum = (new Manager\Forum())->findById((int)$_GET['forumid']);
if (!$forum) {
error(404);
Error404::error();
}
$forumId = $forum->id();
if (!$Viewer->readAccess($forum)) {
error(403);
Error403::error();
}
$paginator = new Util\Paginator(TOPICS_PER_PAGE, (int)($_GET['page'] ?? 1));

View File

@@ -7,10 +7,10 @@ namespace Gazelle;
$post = (new Manager\ForumPost())->findById((int)($_GET['post'] ?? 0));
if (is_null($post)) {
error(404);
Error404::error();
}
if (!$Viewer->readAccess($post->thread()->forum())) {
error(403);
Error403::error();
}
header('Content-type: text/plain');
echo $post->body();

Some files were not shown because too many files have changed in this diff Show More