[core] merge method-check and permission-check into page_matches()
This commit is contained in:
parent
5735320a95
commit
cc9de6b4b2
61 changed files with 1472 additions and 1799 deletions
|
@ -37,15 +37,6 @@ class BaseThemelet
|
|||
$page->add_block(new Block("Error", $message));
|
||||
}
|
||||
|
||||
/**
|
||||
* A specific, common error message
|
||||
*/
|
||||
public function display_permission_denied(): void
|
||||
{
|
||||
$this->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generic thumbnail code; returns HTML rather than adding
|
||||
* a block since thumbs tend to go inside blocks...
|
||||
|
|
|
@ -59,6 +59,7 @@ class PageRequestEvent extends Event
|
|||
public array $args;
|
||||
public int $arg_count;
|
||||
public int $part_count;
|
||||
public bool $is_authed;
|
||||
|
||||
/**
|
||||
* @param string $method The HTTP method used to make the request
|
||||
|
@ -68,6 +69,7 @@ class PageRequestEvent extends Event
|
|||
*/
|
||||
public function __construct(string $method, string $path, array $get, array $post)
|
||||
{
|
||||
global $user;
|
||||
parent::__construct();
|
||||
global $config;
|
||||
|
||||
|
@ -81,6 +83,7 @@ class PageRequestEvent extends Event
|
|||
$this->path = $path;
|
||||
$this->GET = $get;
|
||||
$this->POST = $post;
|
||||
$this->is_authed = $user->check_auth_token();
|
||||
|
||||
// break the path into parts
|
||||
$args = explode('/', $path);
|
||||
|
@ -163,28 +166,40 @@ class PageRequestEvent extends Event
|
|||
*
|
||||
* If it matches, store the remaining path elements in $args
|
||||
*/
|
||||
public function page_matches(string $name): bool
|
||||
public function page_matches(string $name, ?string $method = null, ?bool $authed = null, ?string $permission = null): bool
|
||||
{
|
||||
$parts = explode("/", $name);
|
||||
$this->part_count = count($parts);
|
||||
global $user;
|
||||
|
||||
if ($this->part_count > $this->arg_count) {
|
||||
assert($method === null || in_array($method, ["GET", "POST", "OPTIONS"]));
|
||||
$authed = $authed ?? $method == "POST";
|
||||
|
||||
// method check is fast so do that first
|
||||
if($method !== null && $this->method !== $method) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if the path matches
|
||||
$parts = explode("/", $name);
|
||||
$this->part_count = count($parts);
|
||||
if ($this->part_count > $this->arg_count) {
|
||||
return false;
|
||||
}
|
||||
for ($i = 0; $i < $this->part_count; $i++) {
|
||||
if ($parts[$i] != $this->args[$i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// if we matched the method and the path, but the page requires
|
||||
// authentication and the user is not authenticated, then complain
|
||||
if($authed && $this->is_authed === false) {
|
||||
throw new PermissionDeniedException("Permission Denied");
|
||||
}
|
||||
if($permission !== null && !$user->can($permission)) {
|
||||
throw new PermissionDeniedException("Permission Denied");
|
||||
}
|
||||
|
||||
public function authed_page_matches(string $name): bool
|
||||
{
|
||||
global $user;
|
||||
return $this->page_matches($name) && $user->check_auth_token();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -88,7 +88,7 @@ abstract class Permissions
|
|||
public const BULK_EDIT_VOTE = "bulk_edit_vote";
|
||||
public const EDIT_OTHER_VOTE = "edit_other_vote";
|
||||
|
||||
public const VIEW_SYSINTO = "view_sysinfo";
|
||||
public const VIEW_SYSINFO = "view_sysinfo";
|
||||
|
||||
public const HELLBANNED = "hellbanned";
|
||||
public const VIEW_HELLBANNED = "view_hellbanned";
|
||||
|
|
|
@ -188,7 +188,7 @@ new UserClass("admin", "base", [
|
|||
Permissions::BULK_EDIT_VOTE => true,
|
||||
Permissions::EDIT_OTHER_VOTE => true,
|
||||
Permissions::CREATE_VOTE => true,
|
||||
Permissions::VIEW_SYSINTO => true,
|
||||
Permissions::VIEW_SYSINFO => true,
|
||||
|
||||
Permissions::HELLBANNED => false,
|
||||
Permissions::VIEW_HELLBANNED => true,
|
||||
|
|
|
@ -49,29 +49,22 @@ class AdminPage extends Extension
|
|||
{
|
||||
global $database, $page, $user;
|
||||
|
||||
if ($event->page_matches("admin")) {
|
||||
if (!$user->can(Permissions::MANAGE_ADMINTOOLS)) {
|
||||
$this->theme->display_permission_denied();
|
||||
if ($event->page_matches("admin", permission: Permissions::MANAGE_ADMINTOOLS)) {
|
||||
if ($event->count_args() == 0) {
|
||||
send_event(new AdminBuildingEvent($page));
|
||||
} else {
|
||||
if ($event->count_args() == 0) {
|
||||
send_event(new AdminBuildingEvent($page));
|
||||
} else {
|
||||
$action = $event->get_arg(0);
|
||||
$aae = new AdminActionEvent($action, $event->POST);
|
||||
$action = $event->get_arg(0);
|
||||
$aae = new AdminActionEvent($action, $event->POST);
|
||||
|
||||
if ($user->check_auth_token()) {
|
||||
log_info("admin", "Util: $action");
|
||||
shm_set_timeout(null);
|
||||
$database->set_timeout(null);
|
||||
send_event($aae);
|
||||
} else {
|
||||
throw new SCoreException("Invalid CSRF token");
|
||||
}
|
||||
$user->ensure_authed();
|
||||
log_info("admin", "Util: $action");
|
||||
shm_set_timeout(null);
|
||||
$database->set_timeout(null);
|
||||
send_event($aae);
|
||||
|
||||
if ($aae->redirect) {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("admin"));
|
||||
}
|
||||
if ($aae->redirect) {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("admin"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@ class AdminPageTest extends ShimmiePHPUnitTestCase
|
|||
public function testAuth(): void
|
||||
{
|
||||
send_event(new UserLoginEvent(User::by_name(self::$anon_name)));
|
||||
$page = $this->get_page('admin');
|
||||
$this->assertEquals(403, $page->code);
|
||||
$this->assertEquals("Permission Denied", $page->title);
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->get_page('admin');
|
||||
});
|
||||
|
||||
send_event(new UserLoginEvent(User::by_name(self::$user_name)));
|
||||
$page = $this->get_page('admin');
|
||||
$this->assertEquals(403, $page->code);
|
||||
$this->assertEquals("Permission Denied", $page->title);
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->get_page('admin');
|
||||
});
|
||||
|
||||
send_event(new UserLoginEvent(User::by_name(self::$admin_name)));
|
||||
$page = $this->get_page('admin');
|
||||
|
|
|
@ -66,27 +66,23 @@ class AliasEditor extends Extension
|
|||
global $config, $database, $page, $user;
|
||||
|
||||
if ($event->page_matches("alias")) {
|
||||
if ($event->get_arg(0) == "add") {
|
||||
if ($user->can(Permissions::MANAGE_ALIAS_LIST)) {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["c_oldtag" => "string", "c_newtag" => "string"]);
|
||||
try {
|
||||
send_event(new AddAliasEvent($input['c_oldtag'], $input['c_newtag']));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("alias/list"));
|
||||
} catch (AddAliasException $ex) {
|
||||
$this->theme->display_error(500, "Error adding alias", $ex->getMessage());
|
||||
}
|
||||
}
|
||||
} elseif ($event->get_arg(0) == "remove") {
|
||||
if ($user->can(Permissions::MANAGE_ALIAS_LIST)) {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["d_oldtag" => "string"]);
|
||||
send_event(new DeleteAliasEvent($input['d_oldtag']));
|
||||
if ($event->page_matches("alias/add", method: "POST", permission: Permissions::MANAGE_ALIAS_LIST)) {
|
||||
$input = validate_input(["c_oldtag" => "string", "c_newtag" => "string"]);
|
||||
try {
|
||||
send_event(new AddAliasEvent($input['c_oldtag'], $input['c_newtag']));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("alias/list"));
|
||||
} catch (AddAliasException $ex) {
|
||||
$this->theme->display_error(500, "Error adding alias", $ex->getMessage());
|
||||
}
|
||||
} elseif ($event->get_arg(0) == "list") {
|
||||
}
|
||||
if ($event->page_matches("alias/remove", method: "POST", permission: Permissions::MANAGE_ALIAS_LIST)) {
|
||||
$input = validate_input(["d_oldtag" => "string"]);
|
||||
send_event(new DeleteAliasEvent($input['d_oldtag']));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("alias/list"));
|
||||
}
|
||||
if ($event->page_matches("alias/list")) {
|
||||
$t = new AliasTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
|
@ -96,25 +92,23 @@ class AliasEditor extends Extension
|
|||
$t->delete_url = make_link("alias/remove");
|
||||
}
|
||||
$this->theme->display_aliases($t->table($t->query()), $t->paginator());
|
||||
} elseif ($event->get_arg(0) == "export") {
|
||||
}
|
||||
if ($event->page_matches("alias/export")) {
|
||||
$page->set_mode(PageMode::DATA);
|
||||
$page->set_mime(MimeType::CSV);
|
||||
$page->set_filename("aliases.csv");
|
||||
$page->set_data($this->get_alias_csv($database));
|
||||
} elseif ($event->get_arg(0) == "import") {
|
||||
if ($user->can(Permissions::MANAGE_ALIAS_LIST)) {
|
||||
if (count($_FILES) > 0) {
|
||||
$tmp = $_FILES['alias_file']['tmp_name'];
|
||||
$contents = file_get_contents_ex($tmp);
|
||||
$this->add_alias_csv($contents);
|
||||
log_info("alias_editor", "Imported aliases from file", "Imported aliases"); # FIXME: how many?
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("alias/list"));
|
||||
} else {
|
||||
$this->theme->display_error(400, "No File Specified", "You have to upload a file");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("alias/import", method: "POST", permission: Permissions::MANAGE_ALIAS_LIST)) {
|
||||
if (count($_FILES) > 0) {
|
||||
$tmp = $_FILES['alias_file']['tmp_name'];
|
||||
$contents = file_get_contents_ex($tmp);
|
||||
$this->add_alias_csv($contents);
|
||||
log_info("alias_editor", "Imported aliases from file", "Imported aliases"); # FIXME: how many?
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("alias/list"));
|
||||
} else {
|
||||
$this->theme->display_error(401, "Admins Only", "Only admins can edit the alias list");
|
||||
$this->theme->display_error(400, "No File Specified", "You have to upload a file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,16 +40,14 @@ class Approval extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->page_matches("approve_image") && $user->can(Permissions::APPROVE_IMAGE)) {
|
||||
// Try to get the image ID
|
||||
if ($event->page_matches("approve_image", method: "POST", permission: Permissions::APPROVE_IMAGE)) {
|
||||
$image_id = int_escape(null_throws($event->get_arg(0)));
|
||||
self::approve_image($image_id);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/" . $image_id));
|
||||
}
|
||||
|
||||
if ($event->page_matches("disapprove_image") && $user->can(Permissions::APPROVE_IMAGE)) {
|
||||
// Try to get the image ID
|
||||
if ($event->page_matches("disapprove_image", method: "POST", permission: Permissions::APPROVE_IMAGE)) {
|
||||
$image_id = int_escape(null_throws($event->get_arg(0)));
|
||||
self::disapprove_image($image_id);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
|
|
|
@ -169,262 +169,182 @@ class Artists extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->page_matches("artist")) {
|
||||
switch ($event->get_arg(0)) {
|
||||
//*************ARTIST SECTION**************
|
||||
case "list":
|
||||
{
|
||||
$this->get_listing($event);
|
||||
$this->theme->sidebar_options("neutral");
|
||||
break;
|
||||
}
|
||||
case "new":
|
||||
{
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->new_artist_composer();
|
||||
} else {
|
||||
$this->theme->display_error(401, "Error", "You must be registered and logged in to create a new artist.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "new_artist":
|
||||
{
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/new"));
|
||||
break;
|
||||
}
|
||||
case "create":
|
||||
{
|
||||
if (!$user->is_anonymous()) {
|
||||
$newArtistID = $this->add_artist();
|
||||
if ($newArtistID == -1) {
|
||||
$this->theme->display_error(400, "Error", "Error when entering artist data.");
|
||||
} else {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$newArtistID));
|
||||
}
|
||||
} else {
|
||||
$this->theme->display_error(401, "Error", "You must be registered and logged in to create a new artist.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case "view":
|
||||
{
|
||||
$artistID = int_escape($event->get_arg(1));
|
||||
$artist = $this->get_artist($artistID);
|
||||
$aliases = $this->get_alias($artist['id']);
|
||||
$members = $this->get_members($artist['id']);
|
||||
$urls = $this->get_urls($artist['id']);
|
||||
|
||||
$userIsLogged = !$user->is_anonymous();
|
||||
$userIsAdmin = $user->can(Permissions::ARTISTS_ADMIN);
|
||||
|
||||
$images = Search::find_images(limit: 4, tags: Tag::explode($artist['name']));
|
||||
|
||||
$this->theme->show_artist($artist, $aliases, $members, $urls, $images, $userIsLogged, $userIsAdmin);
|
||||
/*
|
||||
if ($userIsLogged) {
|
||||
$this->theme->show_new_alias_composer($artistID);
|
||||
$this->theme->show_new_member_composer($artistID);
|
||||
$this->theme->show_new_url_composer($artistID);
|
||||
}
|
||||
*/
|
||||
|
||||
$this->theme->sidebar_options("editor", $artistID, $userIsAdmin);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case "edit":
|
||||
{
|
||||
$artistID = int_escape($event->get_arg(1));
|
||||
$artist = $this->get_artist($artistID);
|
||||
$aliases = $this->get_alias($artistID);
|
||||
$members = $this->get_members($artistID);
|
||||
$urls = $this->get_urls($artistID);
|
||||
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->show_artist_editor($artist, $aliases, $members, $urls);
|
||||
|
||||
$userIsAdmin = $user->can(Permissions::ARTISTS_ADMIN);
|
||||
$this->theme->sidebar_options("editor", $artistID, $userIsAdmin);
|
||||
} else {
|
||||
$this->theme->display_error(401, "Error", "You must be registered and logged in to edit an artist.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "edit_artist":
|
||||
{
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/edit/".$artistID));
|
||||
break;
|
||||
}
|
||||
case "edited":
|
||||
{
|
||||
$artistID = int_escape($event->get_POST('id'));
|
||||
$this->update_artist();
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
case "nuke_artist":
|
||||
{
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/nuke/".$artistID));
|
||||
break;
|
||||
}
|
||||
case "nuke":
|
||||
{
|
||||
$artistID = int_escape($event->get_arg(1));
|
||||
$this->delete_artist($artistID); // this will delete the artist, its alias, its urls and its members
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/list"));
|
||||
break;
|
||||
}
|
||||
case "add_alias":
|
||||
{
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->theme->show_new_alias_composer($artistID);
|
||||
break;
|
||||
}
|
||||
case "add_member":
|
||||
{
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->theme->show_new_member_composer($artistID);
|
||||
break;
|
||||
}
|
||||
case "add_url":
|
||||
{
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->theme->show_new_url_composer($artistID);
|
||||
break;
|
||||
}
|
||||
//***********ALIAS SECTION ***********************
|
||||
case "alias":
|
||||
{
|
||||
switch ($event->get_arg(1)) {
|
||||
case "add":
|
||||
{
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->add_alias();
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
case "delete":
|
||||
{
|
||||
$aliasID = int_escape($event->get_arg(2));
|
||||
$artistID = $this->get_artistID_by_aliasID($aliasID);
|
||||
$this->delete_alias($aliasID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
case "edit":
|
||||
{
|
||||
$aliasID = int_escape($event->get_arg(2));
|
||||
$alias = $this->get_alias_by_id($aliasID);
|
||||
$this->theme->show_alias_editor($alias);
|
||||
break;
|
||||
}
|
||||
case "edited":
|
||||
{
|
||||
$this->update_alias();
|
||||
$aliasID = int_escape($event->req_POST('aliasID'));
|
||||
$artistID = $this->get_artistID_by_aliasID($aliasID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break; // case: alias
|
||||
}
|
||||
|
||||
//**************** URLS SECTION **********************
|
||||
case "url":
|
||||
{
|
||||
switch ($event->get_arg(1)) {
|
||||
case "add":
|
||||
{
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->add_urls();
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
case "delete":
|
||||
{
|
||||
$urlID = int_escape($event->get_arg(2));
|
||||
$artistID = $this->get_artistID_by_urlID($urlID);
|
||||
$this->delete_url($urlID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
case "edit":
|
||||
{
|
||||
$urlID = int_escape($event->get_arg(2));
|
||||
$url = $this->get_url_by_id($urlID);
|
||||
$this->theme->show_url_editor($url);
|
||||
break;
|
||||
}
|
||||
case "edited":
|
||||
{
|
||||
$this->update_url();
|
||||
$urlID = int_escape($event->req_POST('urlID'));
|
||||
$artistID = $this->get_artistID_by_urlID($urlID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break; // case: urls
|
||||
}
|
||||
//******************* MEMBERS SECTION *********************
|
||||
case "member":
|
||||
{
|
||||
switch ($event->get_arg(1)) {
|
||||
case "add":
|
||||
{
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->add_members();
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
case "delete":
|
||||
{
|
||||
$memberID = int_escape($event->get_arg(2));
|
||||
$artistID = $this->get_artistID_by_memberID($memberID);
|
||||
$this->delete_member($memberID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
case "edit":
|
||||
{
|
||||
$memberID = int_escape($event->get_arg(2));
|
||||
$member = $this->get_member_by_id($memberID);
|
||||
$this->theme->show_member_editor($member);
|
||||
break;
|
||||
}
|
||||
case "edited":
|
||||
{
|
||||
$this->update_member();
|
||||
$memberID = int_escape($event->req_POST('memberID'));
|
||||
$artistID = $this->get_artistID_by_memberID($memberID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/".$artistID));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break; //case: members
|
||||
}
|
||||
if ($event->page_matches("artist/list")) {
|
||||
$this->get_listing(clamp(int_escape($event->get_arg(0)), 1, null) - 1);
|
||||
$this->theme->sidebar_options("neutral");
|
||||
}
|
||||
if ($event->page_matches("artist/new")) {
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->new_artist_composer();
|
||||
} else {
|
||||
$this->theme->display_error(401, "Error", "You must be registered and logged in to create a new artist.");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("artist/new_artist")) {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/new"));
|
||||
}
|
||||
if ($event->page_matches("artist/create")) {
|
||||
if (!$user->is_anonymous()) {
|
||||
$newArtistID = $this->add_artist();
|
||||
if ($newArtistID == -1) {
|
||||
$this->theme->display_error(400, "Error", "Error when entering artist data.");
|
||||
} else {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $newArtistID));
|
||||
}
|
||||
} else {
|
||||
$this->theme->display_error(401, "Error", "You must be registered and logged in to create a new artist.");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("artist/view")) {
|
||||
$artistID = int_escape($event->get_arg(0));
|
||||
$artist = $this->get_artist($artistID);
|
||||
$aliases = $this->get_alias($artist['id']);
|
||||
$members = $this->get_members($artist['id']);
|
||||
$urls = $this->get_urls($artist['id']);
|
||||
|
||||
$userIsLogged = !$user->is_anonymous();
|
||||
$userIsAdmin = $user->can(Permissions::ARTISTS_ADMIN);
|
||||
|
||||
$images = Search::find_images(limit: 4, tags: Tag::explode($artist['name']));
|
||||
|
||||
$this->theme->show_artist($artist, $aliases, $members, $urls, $images, $userIsLogged, $userIsAdmin);
|
||||
/*
|
||||
if ($userIsLogged) {
|
||||
$this->theme->show_new_alias_composer($artistID);
|
||||
$this->theme->show_new_member_composer($artistID);
|
||||
$this->theme->show_new_url_composer($artistID);
|
||||
}
|
||||
*/
|
||||
|
||||
$this->theme->sidebar_options("editor", $artistID, $userIsAdmin);
|
||||
}
|
||||
if ($event->page_matches("artist/edit")) {
|
||||
$artistID = int_escape($event->get_arg(0));
|
||||
$artist = $this->get_artist($artistID);
|
||||
$aliases = $this->get_alias($artistID);
|
||||
$members = $this->get_members($artistID);
|
||||
$urls = $this->get_urls($artistID);
|
||||
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->show_artist_editor($artist, $aliases, $members, $urls);
|
||||
|
||||
$userIsAdmin = $user->can(Permissions::ARTISTS_ADMIN);
|
||||
$this->theme->sidebar_options("editor", $artistID, $userIsAdmin);
|
||||
} else {
|
||||
$this->theme->display_error(401, "Error", "You must be registered and logged in to edit an artist.");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("artist/edit_artist")) {
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/edit/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/edited")) {
|
||||
$artistID = int_escape($event->get_POST('id'));
|
||||
$this->update_artist();
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/nuke_artist")) {
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/nuke/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/nuke")) {
|
||||
$artistID = int_escape($event->get_arg(0));
|
||||
$this->delete_artist($artistID); // this will delete the artist, its alias, its urls and its members
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/list"));
|
||||
}
|
||||
if ($event->page_matches("artist/add_alias")) {
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->theme->show_new_alias_composer($artistID);
|
||||
}
|
||||
if ($event->page_matches("artist/add_member")) {
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->theme->show_new_member_composer($artistID);
|
||||
}
|
||||
if ($event->page_matches("artist/add_url")) {
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->theme->show_new_url_composer($artistID);
|
||||
}
|
||||
if ($event->page_matches("artist/alias/add")) {
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->add_alias();
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/alias/delete")) {
|
||||
$aliasID = int_escape($event->get_arg(0));
|
||||
$artistID = $this->get_artistID_by_aliasID($aliasID);
|
||||
$this->delete_alias($aliasID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/alias/edit")) {
|
||||
$aliasID = int_escape($event->get_arg(0));
|
||||
$alias = $this->get_alias_by_id($aliasID);
|
||||
$this->theme->show_alias_editor($alias);
|
||||
}
|
||||
if ($event->page_matches("artist/alias/edited")) {
|
||||
$this->update_alias();
|
||||
$aliasID = int_escape($event->req_POST('aliasID'));
|
||||
$artistID = $this->get_artistID_by_aliasID($aliasID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/url/add")) {
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->add_urls();
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/url/delete")) {
|
||||
$urlID = int_escape($event->get_arg(0));
|
||||
$artistID = $this->get_artistID_by_urlID($urlID);
|
||||
$this->delete_url($urlID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/url/edit")) {
|
||||
$urlID = int_escape($event->get_arg(0));
|
||||
$url = $this->get_url_by_id($urlID);
|
||||
$this->theme->show_url_editor($url);
|
||||
}
|
||||
if ($event->page_matches("artist/url/edited")) {
|
||||
$this->update_url();
|
||||
$urlID = int_escape($event->req_POST('urlID'));
|
||||
$artistID = $this->get_artistID_by_urlID($urlID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/member/add")) {
|
||||
$artistID = int_escape($event->req_POST('artist_id'));
|
||||
$this->add_members();
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/member/delete")) {
|
||||
$memberID = int_escape($event->get_arg(0));
|
||||
$artistID = $this->get_artistID_by_memberID($memberID);
|
||||
$this->delete_member($memberID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
if ($event->page_matches("artist/member/edit")) {
|
||||
$memberID = int_escape($event->get_arg(0));
|
||||
$member = $this->get_member_by_id($memberID);
|
||||
$this->theme->show_member_editor($member);
|
||||
}
|
||||
if ($event->page_matches("artist/member/edited")) {
|
||||
$this->update_member();
|
||||
$memberID = int_escape($event->req_POST('memberID'));
|
||||
$artistID = $this->get_artistID_by_memberID($memberID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("artist/view/" . $artistID));
|
||||
}
|
||||
}
|
||||
|
||||
private function get_artistName_by_imageID(int $imageID): string
|
||||
|
@ -468,37 +388,37 @@ class Artists extends Extension
|
|||
private function get_artistID_by_url(string $url): int
|
||||
{
|
||||
global $database;
|
||||
return (int)$database->get_one("SELECT artist_id FROM artist_urls WHERE url = :url", ['url' => $url]);
|
||||
return (int) $database->get_one("SELECT artist_id FROM artist_urls WHERE url = :url", ['url' => $url]);
|
||||
}
|
||||
|
||||
private function get_artistID_by_memberName(string $member): int
|
||||
{
|
||||
global $database;
|
||||
return (int)$database->get_one("SELECT artist_id FROM artist_members WHERE name = :name", ['name' => $member]);
|
||||
return (int) $database->get_one("SELECT artist_id FROM artist_members WHERE name = :name", ['name' => $member]);
|
||||
}
|
||||
|
||||
private function get_artistName_by_artistID(int $artistID): string
|
||||
{
|
||||
global $database;
|
||||
return (string)$database->get_one("SELECT name FROM artists WHERE id = :id", ['id' => $artistID]);
|
||||
return (string) $database->get_one("SELECT name FROM artists WHERE id = :id", ['id' => $artistID]);
|
||||
}
|
||||
|
||||
private function get_artistID_by_aliasID(int $aliasID): int
|
||||
{
|
||||
global $database;
|
||||
return (int)$database->get_one("SELECT artist_id FROM artist_alias WHERE id = :id", ['id' => $aliasID]);
|
||||
return (int) $database->get_one("SELECT artist_id FROM artist_alias WHERE id = :id", ['id' => $aliasID]);
|
||||
}
|
||||
|
||||
private function get_artistID_by_memberID(int $memberID): int
|
||||
{
|
||||
global $database;
|
||||
return (int)$database->get_one("SELECT artist_id FROM artist_members WHERE id = :id", ['id' => $memberID]);
|
||||
return (int) $database->get_one("SELECT artist_id FROM artist_members WHERE id = :id", ['id' => $memberID]);
|
||||
}
|
||||
|
||||
private function get_artistID_by_urlID(int $urlID): int
|
||||
{
|
||||
global $database;
|
||||
return (int)$database->get_one("SELECT artist_id FROM artist_urls WHERE id = :id", ['id' => $urlID]);
|
||||
return (int) $database->get_one("SELECT artist_id FROM artist_urls WHERE id = :id", ['id' => $urlID]);
|
||||
}
|
||||
|
||||
private function delete_alias(int $aliasID): void
|
||||
|
@ -818,7 +738,7 @@ class Artists extends Extension
|
|||
);
|
||||
|
||||
$num = count($result);
|
||||
for ($i = 0 ; $i < $num ; $i++) {
|
||||
for ($i = 0; $i < $num; $i++) {
|
||||
$result[$i]["name"] = stripslashes($result[$i]["name"]);
|
||||
}
|
||||
|
||||
|
@ -837,7 +757,7 @@ class Artists extends Extension
|
|||
);
|
||||
|
||||
$num = count($result);
|
||||
for ($i = 0 ; $i < $num ; $i++) {
|
||||
for ($i = 0; $i < $num; $i++) {
|
||||
$result[$i]["url"] = stripslashes($result[$i]["url"]);
|
||||
}
|
||||
|
||||
|
@ -847,7 +767,7 @@ class Artists extends Extension
|
|||
private function get_artist_id(string $name): int
|
||||
{
|
||||
global $database;
|
||||
return (int)$database->get_one(
|
||||
return (int) $database->get_one(
|
||||
"SELECT id FROM artists WHERE name = :name",
|
||||
['name' => $name]
|
||||
);
|
||||
|
@ -857,7 +777,7 @@ class Artists extends Extension
|
|||
{
|
||||
global $database;
|
||||
|
||||
return (int)$database->get_one(
|
||||
return (int) $database->get_one(
|
||||
"SELECT artist_id FROM artist_alias WHERE alias = :alias",
|
||||
['alias' => $alias]
|
||||
);
|
||||
|
@ -873,60 +793,59 @@ class Artists extends Extension
|
|||
}
|
||||
|
||||
/*
|
||||
* HERE WE GET THE LIST OF ALL ARTIST WITH PAGINATION
|
||||
*/
|
||||
private function get_listing(PageRequestEvent $event): void
|
||||
* HERE WE GET THE LIST OF ALL ARTIST WITH PAGINATION
|
||||
*/
|
||||
private function get_listing(int $pageNumber): void
|
||||
{
|
||||
global $config, $database;
|
||||
|
||||
$pageNumber = clamp(int_escape($event->get_arg(1)), 1, null) - 1;
|
||||
$artistsPerPage = $config->get_int("artistsPerPage");
|
||||
|
||||
$listing = $database->get_all(
|
||||
"
|
||||
(
|
||||
SELECT a.id, a.user_id, a.name, u.name AS user_name, COALESCE(t.count, 0) AS posts
|
||||
, 'artist' as type, a.id AS artist_id, a.name AS artist_name, a.updated
|
||||
FROM artists AS a
|
||||
INNER JOIN users AS u
|
||||
ON a.user_id = u.id
|
||||
LEFT OUTER JOIN tags AS t
|
||||
ON a.name = t.tag
|
||||
GROUP BY a.id, a.user_id, a.name, u.name
|
||||
ORDER BY a.updated DESC
|
||||
)
|
||||
(
|
||||
SELECT a.id, a.user_id, a.name, u.name AS user_name, COALESCE(t.count, 0) AS posts
|
||||
, 'artist' as type, a.id AS artist_id, a.name AS artist_name, a.updated
|
||||
FROM artists AS a
|
||||
INNER JOIN users AS u
|
||||
ON a.user_id = u.id
|
||||
LEFT OUTER JOIN tags AS t
|
||||
ON a.name = t.tag
|
||||
GROUP BY a.id, a.user_id, a.name, u.name
|
||||
ORDER BY a.updated DESC
|
||||
)
|
||||
|
||||
UNION
|
||||
UNION
|
||||
|
||||
(
|
||||
SELECT aa.id, aa.user_id, aa.alias AS name, u.name AS user_name, COALESCE(t.count, 0) AS posts
|
||||
, 'alias' as type, a.id AS artist_id, a.name AS artist_name, aa.updated
|
||||
FROM artist_alias AS aa
|
||||
INNER JOIN users AS u
|
||||
ON aa.user_id = u.id
|
||||
INNER JOIN artists AS a
|
||||
ON aa.artist_id = a.id
|
||||
LEFT OUTER JOIN tags AS t
|
||||
ON aa.alias = t.tag
|
||||
GROUP BY aa.id, a.user_id, aa.alias, u.name, a.id, a.name
|
||||
ORDER BY aa.updated DESC
|
||||
)
|
||||
(
|
||||
SELECT aa.id, aa.user_id, aa.alias AS name, u.name AS user_name, COALESCE(t.count, 0) AS posts
|
||||
, 'alias' as type, a.id AS artist_id, a.name AS artist_name, aa.updated
|
||||
FROM artist_alias AS aa
|
||||
INNER JOIN users AS u
|
||||
ON aa.user_id = u.id
|
||||
INNER JOIN artists AS a
|
||||
ON aa.artist_id = a.id
|
||||
LEFT OUTER JOIN tags AS t
|
||||
ON aa.alias = t.tag
|
||||
GROUP BY aa.id, a.user_id, aa.alias, u.name, a.id, a.name
|
||||
ORDER BY aa.updated DESC
|
||||
)
|
||||
|
||||
UNION
|
||||
UNION
|
||||
|
||||
(
|
||||
SELECT m.id, m.user_id, m.name AS name, u.name AS user_name, COALESCE(t.count, 0) AS posts
|
||||
, 'member' AS type, a.id AS artist_id, a.name AS artist_name, m.updated
|
||||
FROM artist_members AS m
|
||||
INNER JOIN users AS u
|
||||
ON m.user_id = u.id
|
||||
INNER JOIN artists AS a
|
||||
ON m.artist_id = a.id
|
||||
LEFT OUTER JOIN tags AS t
|
||||
ON m.name = t.tag
|
||||
GROUP BY m.id, m.user_id, m.name, u.name, a.id, a.name
|
||||
ORDER BY m.updated DESC
|
||||
)
|
||||
(
|
||||
SELECT m.id, m.user_id, m.name AS name, u.name AS user_name, COALESCE(t.count, 0) AS posts
|
||||
, 'member' AS type, a.id AS artist_id, a.name AS artist_name, m.updated
|
||||
FROM artist_members AS m
|
||||
INNER JOIN users AS u
|
||||
ON m.user_id = u.id
|
||||
INNER JOIN artists AS a
|
||||
ON m.artist_id = a.id
|
||||
LEFT OUTER JOIN tags AS t
|
||||
ON m.name = t.tag
|
||||
GROUP BY m.id, m.user_id, m.name, u.name, a.id, a.name
|
||||
ORDER BY m.updated DESC
|
||||
)
|
||||
ORDER BY updated DESC
|
||||
LIMIT :offset, :limit
|
||||
",
|
||||
|
@ -938,7 +857,7 @@ class Artists extends Extension
|
|||
|
||||
$number_of_listings = count($listing);
|
||||
|
||||
for ($i = 0 ; $i < $number_of_listings ; $i++) {
|
||||
for ($i = 0; $i < $number_of_listings; $i++) {
|
||||
$listing[$i]["name"] = stripslashes($listing[$i]["name"]);
|
||||
$listing[$i]["user_name"] = stripslashes($listing[$i]["user_name"]);
|
||||
$listing[$i]["artist_name"] = stripslashes($listing[$i]["artist_name"]);
|
||||
|
@ -953,14 +872,14 @@ class Artists extends Extension
|
|||
ON a.id = aa.artist_id
|
||||
");
|
||||
|
||||
$totalPages = (int)ceil($count / $artistsPerPage);
|
||||
$totalPages = (int) ceil($count / $artistsPerPage);
|
||||
|
||||
$this->theme->list_artists($listing, $pageNumber + 1, $totalPages);
|
||||
}
|
||||
|
||||
/*
|
||||
* HERE WE ADD AN ALIAS
|
||||
*/
|
||||
* HERE WE ADD AN ALIAS
|
||||
*/
|
||||
private function add_urls(): void
|
||||
{
|
||||
global $user;
|
||||
|
@ -1081,7 +1000,7 @@ class Artists extends Extension
|
|||
", ['artist_id' => $artistID]);
|
||||
|
||||
$rc = count($result);
|
||||
for ($i = 0 ; $i < $rc ; $i++) {
|
||||
for ($i = 0; $i < $rc; $i++) {
|
||||
$result[$i]["alias_name"] = stripslashes($result[$i]["alias_name"]);
|
||||
}
|
||||
return $result;
|
||||
|
|
|
@ -72,27 +72,23 @@ class AutoTagger extends Extension
|
|||
global $config, $database, $page, $user;
|
||||
|
||||
if ($event->page_matches("auto_tag")) {
|
||||
if ($event->get_arg(0) == "add") {
|
||||
if ($user->can(Permissions::MANAGE_AUTO_TAG)) {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["c_tag" => "string", "c_additional_tags" => "string"]);
|
||||
try {
|
||||
send_event(new AddAutoTagEvent($input['c_tag'], $input['c_additional_tags']));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("auto_tag/list"));
|
||||
} catch (AddAutoTagException $ex) {
|
||||
$this->theme->display_error(500, "Error adding auto-tag", $ex->getMessage());
|
||||
}
|
||||
}
|
||||
} elseif ($event->get_arg(0) == "remove") {
|
||||
if ($user->can(Permissions::MANAGE_AUTO_TAG)) {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["d_tag" => "string"]);
|
||||
send_event(new DeleteAutoTagEvent($input['d_tag']));
|
||||
if ($event->page_matches("auto_tag/add", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) {
|
||||
$input = validate_input(["c_tag" => "string", "c_additional_tags" => "string"]);
|
||||
try {
|
||||
send_event(new AddAutoTagEvent($input['c_tag'], $input['c_additional_tags']));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("auto_tag/list"));
|
||||
} catch (AddAutoTagException $ex) {
|
||||
$this->theme->display_error(500, "Error adding auto-tag", $ex->getMessage());
|
||||
}
|
||||
} elseif ($event->get_arg(0) == "list") {
|
||||
}
|
||||
if ($event->page_matches("auto_tag/remove", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) {
|
||||
$input = validate_input(["d_tag" => "string"]);
|
||||
send_event(new DeleteAutoTagEvent($input['d_tag']));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("auto_tag/list"));
|
||||
}
|
||||
if ($event->page_matches("auto_tag/list")) {
|
||||
$t = new AutoTaggerTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
|
@ -102,25 +98,23 @@ class AutoTagger extends Extension
|
|||
$t->delete_url = make_link("auto_tag/remove");
|
||||
}
|
||||
$this->theme->display_auto_tagtable($t->table($t->query()), $t->paginator());
|
||||
} elseif ($event->get_arg(0) == "export") {
|
||||
}
|
||||
if ($event->page_matches("auto_tag/export")) {
|
||||
$page->set_mode(PageMode::DATA);
|
||||
$page->set_mime(MimeType::CSV);
|
||||
$page->set_filename("auto_tag.csv");
|
||||
$page->set_data($this->get_auto_tag_csv($database));
|
||||
} elseif ($event->get_arg(0) == "import") {
|
||||
if ($user->can(Permissions::MANAGE_AUTO_TAG)) {
|
||||
if (count($_FILES) > 0) {
|
||||
$tmp = $_FILES['auto_tag_file']['tmp_name'];
|
||||
$contents = file_get_contents_ex($tmp);
|
||||
$count = $this->add_auto_tag_csv($contents);
|
||||
log_info(AutoTaggerInfo::KEY, "Imported $count auto-tag definitions from file from file", "Imported $count auto-tag definitions");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("auto_tag/list"));
|
||||
} else {
|
||||
$this->theme->display_error(400, "No File Specified", "You have to upload a file");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("auto_tag/import", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) {
|
||||
if (count($_FILES) > 0) {
|
||||
$tmp = $_FILES['auto_tag_file']['tmp_name'];
|
||||
$contents = file_get_contents_ex($tmp);
|
||||
$count = $this->add_auto_tag_csv($contents);
|
||||
log_info(AutoTaggerInfo::KEY, "Imported $count auto-tag definitions from file from file", "Imported $count auto-tag definitions");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("auto_tag/list"));
|
||||
} else {
|
||||
$this->theme->display_error(401, "Admins Only", "Only admins can edit the auto-tag list");
|
||||
$this->theme->display_error(400, "No File Specified", "You have to upload a file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,11 @@ class Biography extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $page, $user, $user_config;
|
||||
if ($event->page_matches("biography")) {
|
||||
if ($user->check_auth_token()) {
|
||||
$user_config->set_string("biography", $event->get_POST('biography'));
|
||||
$page->flash("Bio Updated");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
}
|
||||
if ($event->page_matches("biography", method: "POST")) {
|
||||
$user_config->set_string("biography", $event->get_POST('biography'));
|
||||
$page->flash("Bio Updated");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,39 +68,36 @@ class Blocks extends Extension
|
|||
}
|
||||
}
|
||||
|
||||
if ($event->page_matches("blocks") && $user->can(Permissions::MANAGE_BLOCKS)) {
|
||||
if ($event->get_arg(0) == "add") {
|
||||
if ($user->check_auth_token()) {
|
||||
$database->execute("
|
||||
INSERT INTO blocks (pages, title, area, priority, content, userclass)
|
||||
VALUES (:pages, :title, :area, :priority, :content, :userclass)
|
||||
", ['pages' => $event->req_POST('pages'), 'title' => $event->req_POST('title'), 'area' => $event->req_POST('area'), 'priority' => (int)$event->req_POST('priority'), 'content' => $event->req_POST('content'), 'userclass' => $event->req_POST('userclass')]);
|
||||
log_info("blocks", "Added Block #".($database->get_last_insert_id('blocks_id_seq'))." (".$event->req_POST('title').")");
|
||||
$cache->delete("blocks");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("blocks/list"));
|
||||
}
|
||||
if ($event->page_matches("blocks", permission: Permissions::MANAGE_BLOCKS)) {
|
||||
if ($event->page_matches("blocks/add", method: "POST")) {
|
||||
$database->execute("
|
||||
INSERT INTO blocks (pages, title, area, priority, content, userclass)
|
||||
VALUES (:pages, :title, :area, :priority, :content, :userclass)
|
||||
", ['pages' => $event->req_POST('pages'), 'title' => $event->req_POST('title'), 'area' => $event->req_POST('area'), 'priority' => (int)$event->req_POST('priority'), 'content' => $event->req_POST('content'), 'userclass' => $event->req_POST('userclass')]);
|
||||
log_info("blocks", "Added Block #".($database->get_last_insert_id('blocks_id_seq'))." (".$event->req_POST('title').")");
|
||||
$cache->delete("blocks");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("blocks/list"));
|
||||
}
|
||||
if ($event->get_arg(0) == "update") {
|
||||
if ($user->check_auth_token()) {
|
||||
if (!empty($event->req_POST('delete'))) {
|
||||
$database->execute("
|
||||
DELETE FROM blocks
|
||||
WHERE id=:id
|
||||
", ['id' => $event->req_POST('id')]);
|
||||
log_info("blocks", "Deleted Block #".$event->req_POST('id'));
|
||||
} else {
|
||||
$database->execute("
|
||||
UPDATE blocks SET pages=:pages, title=:title, area=:area, priority=:priority, content=:content, userclass=:userclass
|
||||
WHERE id=:id
|
||||
", ['pages' => $event->req_POST('pages'), 'title' => $event->req_POST('title'), 'area' => $event->req_POST('area'), 'priority' => (int)$event->req_POST('priority'), 'content' => $event->req_POST('content'), 'userclass' => $event->req_POST('userclass'), 'id' => $event->req_POST('id')]);
|
||||
log_info("blocks", "Updated Block #".$event->req_POST('id')." (".$event->req_POST('title').")");
|
||||
}
|
||||
$cache->delete("blocks");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("blocks/list"));
|
||||
if ($event->page_matches("blocks/update", method: "POST")) {
|
||||
if (!empty($event->req_POST('delete'))) {
|
||||
$database->execute("
|
||||
DELETE FROM blocks
|
||||
WHERE id=:id
|
||||
", ['id' => $event->req_POST('id')]);
|
||||
log_info("blocks", "Deleted Block #".$event->req_POST('id'));
|
||||
} else {
|
||||
$database->execute("
|
||||
UPDATE blocks SET pages=:pages, title=:title, area=:area, priority=:priority, content=:content, userclass=:userclass
|
||||
WHERE id=:id
|
||||
", ['pages' => $event->req_POST('pages'), 'title' => $event->req_POST('title'), 'area' => $event->req_POST('area'), 'priority' => (int)$event->req_POST('priority'), 'content' => $event->req_POST('content'), 'userclass' => $event->req_POST('userclass'), 'id' => $event->req_POST('id')]);
|
||||
log_info("blocks", "Updated Block #".$event->req_POST('id')." (".$event->req_POST('title').")");
|
||||
}
|
||||
} elseif ($event->get_arg(0) == "list") {
|
||||
$cache->delete("blocks");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("blocks/list"));
|
||||
}
|
||||
if ($event->page_matches("blocks/list")) {
|
||||
$this->theme->display_blocks($database->get_all("SELECT * FROM blocks ORDER BY area, priority"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,60 +72,32 @@ class Blotter extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $page, $database, $user;
|
||||
if ($event->page_matches("blotter") && $event->count_args() > 0) {
|
||||
switch ($event->get_arg(0)) {
|
||||
case "editor":
|
||||
/**
|
||||
* Displays the blotter editor.
|
||||
*/
|
||||
if (!$user->can(Permissions::BLOTTER_ADMIN)) {
|
||||
$this->theme->display_permission_denied();
|
||||
} else {
|
||||
$entries = $database->get_all("SELECT * FROM blotter ORDER BY id DESC");
|
||||
$this->theme->display_editor($entries);
|
||||
}
|
||||
break;
|
||||
case "add":
|
||||
/**
|
||||
* Adds an entry
|
||||
*/
|
||||
if (!$user->can(Permissions::BLOTTER_ADMIN) || !$user->check_auth_token()) {
|
||||
$this->theme->display_permission_denied();
|
||||
} else {
|
||||
$entry_text = $event->req_POST('entry_text');
|
||||
$important = !is_null($event->get_POST('important'));
|
||||
// Now insert into db:
|
||||
$database->execute(
|
||||
"INSERT INTO blotter (entry_date, entry_text, important) VALUES (now(), :text, :important)",
|
||||
["text" => $entry_text, "important" => $important]
|
||||
);
|
||||
log_info("blotter", "Added Message: $entry_text");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("blotter/editor"));
|
||||
}
|
||||
break;
|
||||
case "remove":
|
||||
/**
|
||||
* Removes an entry
|
||||
*/
|
||||
if (!$user->can(Permissions::BLOTTER_ADMIN) || !$user->check_auth_token()) {
|
||||
$this->theme->display_permission_denied();
|
||||
} else {
|
||||
$id = int_escape($event->req_POST('id'));
|
||||
$database->execute("DELETE FROM blotter WHERE id=:id", ["id" => $id]);
|
||||
log_info("blotter", "Removed Entry #$id");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("blotter/editor"));
|
||||
}
|
||||
break;
|
||||
case "list":
|
||||
/**
|
||||
* Displays all blotter entries
|
||||
*/
|
||||
$entries = $database->get_all("SELECT * FROM blotter ORDER BY id DESC");
|
||||
$this->theme->display_blotter_page($entries);
|
||||
break;
|
||||
}
|
||||
if ($event->page_matches("blotter/editor", method: "GET", permission: Permissions::BLOTTER_ADMIN)) {
|
||||
$entries = $database->get_all("SELECT * FROM blotter ORDER BY id DESC");
|
||||
$this->theme->display_editor($entries);
|
||||
}
|
||||
if ($event->page_matches("blotter/add", method: "POST", permission: Permissions::BLOTTER_ADMIN)) {
|
||||
$entry_text = $event->req_POST('entry_text');
|
||||
$important = !is_null($event->get_POST('important'));
|
||||
// Now insert into db:
|
||||
$database->execute(
|
||||
"INSERT INTO blotter (entry_date, entry_text, important) VALUES (now(), :text, :important)",
|
||||
["text" => $entry_text, "important" => $important]
|
||||
);
|
||||
log_info("blotter", "Added Message: $entry_text");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("blotter/editor"));
|
||||
}
|
||||
if ($event->page_matches("blotter/remove", method: "POST", permission: Permissions::BLOTTER_ADMIN)) {
|
||||
$id = int_escape($event->req_POST('id'));
|
||||
$database->execute("DELETE FROM blotter WHERE id=:id", ["id" => $id]);
|
||||
log_info("blotter", "Removed Entry #$id");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("blotter/editor"));
|
||||
}
|
||||
if ($event->page_matches("blotter/list", method: "GET")) {
|
||||
$entries = $database->get_all("SELECT * FROM blotter ORDER BY id DESC");
|
||||
$this->theme->display_blotter_page($entries);
|
||||
}
|
||||
/**
|
||||
* Finally, display the blotter on whatever page we're viewing.
|
||||
|
@ -137,7 +109,7 @@ class Blotter extends Extension
|
|||
{
|
||||
global $database, $config;
|
||||
$limit = $config->get_int("blotter_recent", 5);
|
||||
$sql = 'SELECT * FROM blotter ORDER BY id DESC LIMIT '.intval($limit);
|
||||
$sql = 'SELECT * FROM blotter ORDER BY id DESC LIMIT ' . intval($limit);
|
||||
$entries = $database->get_all($sql);
|
||||
$this->theme->display_blotter($entries);
|
||||
}
|
||||
|
|
|
@ -8,12 +8,15 @@ class BlotterTest extends ShimmiePHPUnitTestCase
|
|||
{
|
||||
public function testDenial(): void
|
||||
{
|
||||
$this->get_page("blotter/editor");
|
||||
$this->assert_response(403);
|
||||
$this->get_page("blotter/add");
|
||||
$this->assert_response(403);
|
||||
$this->get_page("blotter/remove");
|
||||
$this->assert_response(403);
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->get_page("blotter/editor");
|
||||
});
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->post_page("blotter/add");
|
||||
});
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->post_page("blotter/remove");
|
||||
});
|
||||
}
|
||||
|
||||
public function testAddViewRemove(): void
|
||||
|
|
|
@ -169,7 +169,7 @@ class BulkActions extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $page, $user;
|
||||
if ($event->page_matches("bulk_action") && $user->can(Permissions::PERFORM_BULK_ACTIONS)) {
|
||||
if ($event->page_matches("bulk_action", method: "POST", permission: Permissions::PERFORM_BULK_ACTIONS)) {
|
||||
$action = $event->req_POST('bulk_action');
|
||||
|
||||
try {
|
||||
|
|
|
@ -30,13 +30,11 @@ class BulkAdd extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $page, $user;
|
||||
if ($event->page_matches("bulk_add")) {
|
||||
$dir = $event->get_POST('dir');
|
||||
if ($user->can(Permissions::BULK_ADD) && $user->check_auth_token() && $dir) {
|
||||
shm_set_timeout(null);
|
||||
$bae = send_event(new BulkAddEvent($dir));
|
||||
$this->theme->display_upload_results($page, $bae->results);
|
||||
}
|
||||
if ($event->page_matches("bulk_add", method: "POST", permission: Permissions::BULK_ADD)) {
|
||||
$dir = $event->req_POST('dir');
|
||||
shm_set_timeout(null);
|
||||
$bae = send_event(new BulkAddEvent($dir));
|
||||
$this->theme->display_upload_results($page, $bae->results);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,11 @@ class BulkAddCSV extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $page, $user;
|
||||
if ($event->page_matches("bulk_add_csv")) {
|
||||
$csv = $event->get_POST('csv');
|
||||
if ($user->can(Permissions::BULK_ADD) && $user->check_auth_token() && $csv) {
|
||||
shm_set_timeout(null);
|
||||
$this->add_csv($csv);
|
||||
$this->theme->display_upload_results($page);
|
||||
}
|
||||
if ($event->page_matches("bulk_add_csv", method: "POST", permission: Permissions::BULK_ADD)) {
|
||||
$csv = $event->req_POST('csv');
|
||||
shm_set_timeout(null);
|
||||
$this->add_csv($csv);
|
||||
$this->theme->display_upload_results($page);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -201,74 +201,32 @@ class CommentList extends Extension
|
|||
|
||||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
if ($event->page_matches("comment")) {
|
||||
switch ($event->get_arg(0)) {
|
||||
case "add":
|
||||
$this->onPageRequest_add($event);
|
||||
break;
|
||||
case "delete":
|
||||
$this->onPageRequest_delete($event);
|
||||
break;
|
||||
case "bulk_delete":
|
||||
$this->onPageRequest_bulk_delete($event);
|
||||
break;
|
||||
case "list":
|
||||
$this->onPageRequest_list($event);
|
||||
break;
|
||||
case "beta-search":
|
||||
$this->onPageRequest_beta_search($event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function onRobotsBuilding(RobotsBuildingEvent $event): void
|
||||
{
|
||||
// comment lists change all the time, crawlers should
|
||||
// index individual image's comments
|
||||
$event->add_disallow("comment");
|
||||
}
|
||||
|
||||
private function onPageRequest_add(PageRequestEvent $event): void
|
||||
{
|
||||
global $user, $page;
|
||||
try {
|
||||
$i_iid = int_escape($event->req_POST('image_id'));
|
||||
send_event(new CommentPostingEvent($i_iid, $user, $event->req_POST('comment')));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$i_iid", null, "comment_on_$i_iid"));
|
||||
} catch (CommentPostingException $ex) {
|
||||
$this->theme->display_error(403, "Comment Blocked", $ex->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private function onPageRequest_delete(PageRequestEvent $event): void
|
||||
{
|
||||
global $user, $page;
|
||||
if ($user->can(Permissions::DELETE_COMMENT)) {
|
||||
// FIXME: post, not args
|
||||
if ($event->count_args() === 3) {
|
||||
send_event(new CommentDeletionEvent(int_escape($event->get_arg(1))));
|
||||
$page->flash("Deleted comment");
|
||||
global $cache, $config, $database, $user, $page;
|
||||
if ($event->page_matches("comment/add", method: "POST", permission: Permissions::CREATE_COMMENT)) {
|
||||
try {
|
||||
$i_iid = int_escape($event->req_POST('image_id'));
|
||||
send_event(new CommentPostingEvent($i_iid, $user, $event->req_POST('comment')));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link("post/view/" . $event->get_arg(2))));
|
||||
$page->set_redirect(make_link("post/view/$i_iid", null, "comment_on_$i_iid"));
|
||||
} catch (CommentPostingException $ex) {
|
||||
$this->theme->display_error(403, "Comment Blocked", $ex->getMessage());
|
||||
}
|
||||
} else {
|
||||
$this->theme->display_permission_denied();
|
||||
}
|
||||
}
|
||||
|
||||
private function onPageRequest_bulk_delete(PageRequestEvent $event): void
|
||||
{
|
||||
global $user, $database, $page;
|
||||
if ($user->can(Permissions::DELETE_COMMENT)) {
|
||||
if ($event->page_matches("comment/delete", permission: Permissions::DELETE_COMMENT)) {
|
||||
// FIXME: post, not args
|
||||
send_event(new CommentDeletionEvent(int_escape($event->get_arg(0))));
|
||||
$page->flash("Deleted comment");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link("post/view/" . $event->get_arg(1))));
|
||||
}
|
||||
if ($event->page_matches("comment/bulk_delete", method: "POST", permission: Permissions::DELETE_COMMENT)) {
|
||||
$ip = $event->req_POST('ip');
|
||||
|
||||
$comment_ids = $database->get_col("
|
||||
SELECT id
|
||||
FROM comments
|
||||
WHERE owner_ip=:ip
|
||||
", ["ip" => $ip]);
|
||||
SELECT id
|
||||
FROM comments
|
||||
WHERE owner_ip=:ip
|
||||
", ["ip" => $ip]);
|
||||
$num = count($comment_ids);
|
||||
log_warning("comment", "Deleting $num comments from $ip");
|
||||
foreach ($comment_ids as $cid) {
|
||||
|
@ -278,74 +236,73 @@ class CommentList extends Extension
|
|||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("admin"));
|
||||
} else {
|
||||
$this->theme->display_permission_denied();
|
||||
}
|
||||
if ($event->page_matches("comment/list")) {
|
||||
$threads_per_page = 10;
|
||||
|
||||
$where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : "";
|
||||
|
||||
$total_pages = cache_get_or_set("comment_pages", fn () => (int)ceil($database->get_one("
|
||||
SELECT COUNT(c1)
|
||||
FROM (SELECT COUNT(image_id) AS c1 FROM comments $where GROUP BY image_id) AS s1
|
||||
") / $threads_per_page), 600);
|
||||
$total_pages = max($total_pages, 1);
|
||||
|
||||
$current_page = $event->try_page_num(1, $total_pages);
|
||||
$start = $threads_per_page * $current_page;
|
||||
|
||||
$result = $database->execute("
|
||||
SELECT image_id,MAX(posted) AS latest
|
||||
FROM comments
|
||||
$where
|
||||
GROUP BY image_id
|
||||
ORDER BY latest DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
", ["limit" => $threads_per_page, "offset" => $start]);
|
||||
|
||||
$user_ratings = Extension::is_enabled(RatingsInfo::KEY) ? Ratings::get_user_class_privs($user) : [];
|
||||
|
||||
$images = [];
|
||||
while ($row = $result->fetch()) {
|
||||
$image = Image::by_id((int)$row["image_id"]);
|
||||
if (
|
||||
Extension::is_enabled(RatingsInfo::KEY) && !is_null($image) &&
|
||||
!in_array($image['rating'], $user_ratings)
|
||||
) {
|
||||
$image = null; // this is "clever", I may live to regret it
|
||||
}
|
||||
if (
|
||||
Extension::is_enabled(ApprovalInfo::KEY) && !is_null($image) &&
|
||||
$config->get_bool(ApprovalConfig::IMAGES) &&
|
||||
$image['approved'] !== true
|
||||
) {
|
||||
$image = null;
|
||||
}
|
||||
if (!is_null($image)) {
|
||||
$comments = $this->get_comments($image->id);
|
||||
$images[] = [$image, $comments];
|
||||
}
|
||||
}
|
||||
|
||||
$this->theme->display_comment_list($images, $current_page + 1, $total_pages, $user->can(Permissions::CREATE_COMMENT));
|
||||
}
|
||||
if ($event->page_matches("comment/beta-search")) {
|
||||
$search = $event->get_arg(0);
|
||||
$page_num = $event->try_page_num(1);
|
||||
$duser = User::by_name($search);
|
||||
$i_comment_count = Comment::count_comments_by_user($duser);
|
||||
$com_per_page = 50;
|
||||
$total_pages = (int)ceil($i_comment_count / $com_per_page);
|
||||
$comments = $this->get_user_comments($duser->id, $com_per_page, $page_num * $com_per_page);
|
||||
$this->theme->display_all_user_comments($comments, $page_num + 1, $total_pages, $duser);
|
||||
}
|
||||
}
|
||||
|
||||
private function onPageRequest_list(PageRequestEvent $event): void
|
||||
public function onRobotsBuilding(RobotsBuildingEvent $event): void
|
||||
{
|
||||
global $cache, $config, $database, $user;
|
||||
|
||||
$threads_per_page = 10;
|
||||
|
||||
$where = SPEED_HAX ? "WHERE posted > now() - interval '24 hours'" : "";
|
||||
|
||||
$total_pages = cache_get_or_set("comment_pages", fn () => (int)ceil($database->get_one("
|
||||
SELECT COUNT(c1)
|
||||
FROM (SELECT COUNT(image_id) AS c1 FROM comments $where GROUP BY image_id) AS s1
|
||||
") / $threads_per_page), 600);
|
||||
$total_pages = max($total_pages, 1);
|
||||
|
||||
$current_page = $event->try_page_num(1, $total_pages);
|
||||
$start = $threads_per_page * $current_page;
|
||||
|
||||
$result = $database->execute("
|
||||
SELECT image_id,MAX(posted) AS latest
|
||||
FROM comments
|
||||
$where
|
||||
GROUP BY image_id
|
||||
ORDER BY latest DESC
|
||||
LIMIT :limit OFFSET :offset
|
||||
", ["limit" => $threads_per_page, "offset" => $start]);
|
||||
|
||||
$user_ratings = Extension::is_enabled(RatingsInfo::KEY) ? Ratings::get_user_class_privs($user) : [];
|
||||
|
||||
$images = [];
|
||||
while ($row = $result->fetch()) {
|
||||
$image = Image::by_id((int)$row["image_id"]);
|
||||
if (
|
||||
Extension::is_enabled(RatingsInfo::KEY) && !is_null($image) &&
|
||||
!in_array($image['rating'], $user_ratings)
|
||||
) {
|
||||
$image = null; // this is "clever", I may live to regret it
|
||||
}
|
||||
if (
|
||||
Extension::is_enabled(ApprovalInfo::KEY) && !is_null($image) &&
|
||||
$config->get_bool(ApprovalConfig::IMAGES) &&
|
||||
$image['approved'] !== true
|
||||
) {
|
||||
$image = null;
|
||||
}
|
||||
if (!is_null($image)) {
|
||||
$comments = $this->get_comments($image->id);
|
||||
$images[] = [$image, $comments];
|
||||
}
|
||||
}
|
||||
|
||||
$this->theme->display_comment_list($images, $current_page + 1, $total_pages, $user->can(Permissions::CREATE_COMMENT));
|
||||
}
|
||||
|
||||
private function onPageRequest_beta_search(PageRequestEvent $event): void
|
||||
{
|
||||
$search = $event->get_arg(1);
|
||||
$page_num = $event->try_page_num(2);
|
||||
$duser = User::by_name($search);
|
||||
$i_comment_count = Comment::count_comments_by_user($duser);
|
||||
$com_per_page = 50;
|
||||
$total_pages = (int)ceil($i_comment_count / $com_per_page);
|
||||
$comments = $this->get_user_comments($duser->id, $com_per_page, $page_num * $com_per_page);
|
||||
$this->theme->display_all_user_comments($comments, $page_num + 1, $total_pages, $duser);
|
||||
// comment lists change all the time, crawlers should
|
||||
// index individual image's comments
|
||||
$event->add_disallow("comment");
|
||||
}
|
||||
|
||||
public function onAdminBuilding(AdminBuildingEvent $event): void
|
||||
|
|
|
@ -16,10 +16,8 @@ class ET extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $user;
|
||||
if ($event->page_matches("system_info")) {
|
||||
if ($user->can(Permissions::VIEW_SYSINTO)) {
|
||||
$this->theme->display_info_page($this->to_yaml($this->get_info()));
|
||||
}
|
||||
if ($event->page_matches("system_info", permission: Permissions::VIEW_SYSINFO)) {
|
||||
$this->theme->display_info_page($this->to_yaml($this->get_info()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +25,7 @@ class ET extends Extension
|
|||
{
|
||||
global $user;
|
||||
if ($event->parent === "system") {
|
||||
if ($user->can(Permissions::VIEW_SYSINTO)) {
|
||||
if ($user->can(Permissions::VIEW_SYSINFO)) {
|
||||
$event->add_nav_link("system_info", new Link('system_info'), "System Info", null, 10);
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +34,7 @@ class ET extends Extension
|
|||
public function onUserBlockBuilding(UserBlockBuildingEvent $event): void
|
||||
{
|
||||
global $user;
|
||||
if ($user->can(Permissions::VIEW_SYSINTO)) {
|
||||
if ($user->can(Permissions::VIEW_SYSINFO)) {
|
||||
$event->add_link("System Info", make_link("system_info"), 99);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,13 +67,13 @@ class Favorites extends Extension
|
|||
return;
|
||||
} // FIXME: proper permissions
|
||||
|
||||
if ($event->authed_page_matches("favourite/add")) {
|
||||
if ($event->page_matches("favourite/add", method: "POST")) {
|
||||
$image_id = int_escape($event->get_arg(0));
|
||||
send_event(new FavoriteSetEvent($image_id, $user, true));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
}
|
||||
if ($event->authed_page_matches("favourite/remove")) {
|
||||
if ($event->page_matches("favourite/remove", method: "POST")) {
|
||||
$image_id = int_escape($event->get_arg(0));
|
||||
send_event(new FavoriteSetEvent($image_id, $user, false));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
|
|
|
@ -19,16 +19,14 @@ class Featured extends Extension
|
|||
{
|
||||
global $config, $page, $user;
|
||||
if ($event->page_matches("featured_image")) {
|
||||
if ($event->get_arg(0) == "set" && $user->check_auth_token()) {
|
||||
$id = int_escape($event->get_POST('image_id'));
|
||||
if ($user->can(Permissions::EDIT_FEATURE) && $id > 0) {
|
||||
$config->set_int("featured_id", $id);
|
||||
log_info("featured", "Featured post set to >>$id", "Featured post set");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$id"));
|
||||
}
|
||||
if ($event->page_matches("featured_image/set", method: "POST", permission: Permissions::EDIT_FEATURE)) {
|
||||
$id = int_escape($event->req_POST('image_id'));
|
||||
$config->set_int("featured_id", $id);
|
||||
log_info("featured", "Featured post set to >>$id", "Featured post set");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$id"));
|
||||
}
|
||||
if ($event->get_arg(0) == "download") {
|
||||
if ($event->page_matches("featured_image/download")) {
|
||||
$image = Image::by_id($config->get_int("featured_id"));
|
||||
if (!is_null($image)) {
|
||||
$page->set_mode(PageMode::DATA);
|
||||
|
@ -36,7 +34,7 @@ class Featured extends Extension
|
|||
$page->set_data(file_get_contents_ex($image->get_image_filename()));
|
||||
}
|
||||
}
|
||||
if ($event->get_arg(0) == "view") {
|
||||
if ($event->page_matches("featured_image/view")) {
|
||||
$image = Image::by_id($config->get_int("featured_id"));
|
||||
if (!is_null($image)) {
|
||||
send_event(new DisplayingImageEvent($image));
|
||||
|
|
|
@ -99,99 +99,97 @@ class Forum extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->page_matches("forum")) {
|
||||
switch ($event->get_arg(0)) {
|
||||
case "index":
|
||||
$this->show_last_threads($page, $event, $user->can(Permissions::FORUM_ADMIN));
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->display_new_thread_composer($page);
|
||||
}
|
||||
break;
|
||||
case "view":
|
||||
$threadID = int_escape($event->get_arg(1));
|
||||
// $pageNumber = int_escape($event->get_arg(2));
|
||||
$errors = $this->sanity_check_viewed_thread($threadID);
|
||||
|
||||
if (count($errors) > 0) {
|
||||
$this->theme->display_error(500, "Error", implode("<br>", $errors));
|
||||
break;
|
||||
}
|
||||
|
||||
$this->show_posts($event, $user->can(Permissions::FORUM_ADMIN));
|
||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||
$this->theme->add_actions_block($page, $threadID);
|
||||
}
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->display_new_post_composer($page, $threadID);
|
||||
}
|
||||
break;
|
||||
case "new":
|
||||
global $page;
|
||||
$this->theme->display_new_thread_composer($page);
|
||||
break;
|
||||
case "create":
|
||||
$redirectTo = "forum/index";
|
||||
if (!$user->is_anonymous()) {
|
||||
$errors = $this->sanity_check_new_thread();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
$this->theme->display_error(500, "Error", implode("<br>", $errors));
|
||||
break;
|
||||
}
|
||||
|
||||
$newThreadID = $this->save_new_thread($user);
|
||||
$this->save_new_post($newThreadID, $user);
|
||||
$redirectTo = "forum/view/".$newThreadID."/1";
|
||||
}
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link($redirectTo));
|
||||
|
||||
break;
|
||||
case "delete":
|
||||
$threadID = int_escape($event->get_arg(1));
|
||||
$postID = int_escape($event->get_arg(2));
|
||||
|
||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||
$this->delete_post($postID);
|
||||
}
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/view/".$threadID));
|
||||
break;
|
||||
case "nuke":
|
||||
$threadID = int_escape($event->get_arg(1));
|
||||
|
||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||
$this->delete_thread($threadID);
|
||||
}
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/index"));
|
||||
break;
|
||||
case "answer":
|
||||
$threadID = int_escape($event->req_POST("threadID"));
|
||||
$total_pages = $this->get_total_pages_for_thread($threadID);
|
||||
if (!$user->is_anonymous()) {
|
||||
$errors = $this->sanity_check_new_post();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
$this->theme->display_error(500, "Error", implode("<br>", $errors));
|
||||
break;
|
||||
}
|
||||
$this->save_new_post($threadID, $user);
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/view/".$threadID."/".$total_pages));
|
||||
break;
|
||||
default:
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/index"));
|
||||
//$this->theme->display_error(400, "Invalid action", "You should check forum/index.");
|
||||
break;
|
||||
if ($event->page_matches("forum/index")) {
|
||||
if ($event->count_args() >= 2) {
|
||||
$pageNumber = page_number($event->get_arg(1));
|
||||
} else {
|
||||
$pageNumber = 0;
|
||||
}
|
||||
$this->show_last_threads($page, $pageNumber, $user->can(Permissions::FORUM_ADMIN));
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->display_new_thread_composer($page);
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("forum/view")) {
|
||||
$threadID = int_escape($event->get_arg(1));
|
||||
// $pageNumber = int_escape($event->get_arg(2));
|
||||
$errors = $this->sanity_check_viewed_thread($threadID);
|
||||
|
||||
if (count($errors) > 0) {
|
||||
throw new UserErrorException(implode("<br>", $errors));
|
||||
}
|
||||
|
||||
$threadID = int_escape($event->get_arg(1));
|
||||
if ($event->count_args() >= 3) {
|
||||
$pageNumber = page_number($event->get_arg(2));
|
||||
} else {
|
||||
$pageNumber = 0;
|
||||
}
|
||||
|
||||
$this->show_posts($threadID, $pageNumber, $user->can(Permissions::FORUM_ADMIN));
|
||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||
$this->theme->add_actions_block($page, $threadID);
|
||||
}
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->display_new_post_composer($page, $threadID);
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("forum/new")) {
|
||||
$this->theme->display_new_thread_composer($page);
|
||||
}
|
||||
if ($event->page_matches("forum/create")) {
|
||||
$redirectTo = "forum/index";
|
||||
if (!$user->is_anonymous()) {
|
||||
$errors = $this->sanity_check_new_thread();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
throw new UserErrorException(implode("<br>", $errors));
|
||||
}
|
||||
|
||||
$newThreadID = $this->save_new_thread($user);
|
||||
$this->save_new_post($newThreadID, $user);
|
||||
$redirectTo = "forum/view/" . $newThreadID . "/1";
|
||||
}
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link($redirectTo));
|
||||
}
|
||||
if ($event->page_matches("forum/delete")) {
|
||||
$threadID = int_escape($event->get_arg(1));
|
||||
$postID = int_escape($event->get_arg(2));
|
||||
|
||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||
$this->delete_post($postID);
|
||||
}
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/view/" . $threadID));
|
||||
}
|
||||
if ($event->page_matches("forum/nuke")) {
|
||||
$threadID = int_escape($event->get_arg(1));
|
||||
|
||||
if ($user->can(Permissions::FORUM_ADMIN)) {
|
||||
$this->delete_thread($threadID);
|
||||
}
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/index"));
|
||||
}
|
||||
if ($event->page_matches("forum/answer")) {
|
||||
$threadID = int_escape($event->req_POST("threadID"));
|
||||
$total_pages = $this->get_total_pages_for_thread($threadID);
|
||||
if (!$user->is_anonymous()) {
|
||||
$errors = $this->sanity_check_new_post();
|
||||
|
||||
if (count($errors) > 0) {
|
||||
throw new UserErrorException(implode("<br>", $errors));
|
||||
}
|
||||
$this->save_new_post($threadID, $user);
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("forum/view/" . $threadID . "/" . $total_pages));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function get_total_pages_for_thread(int $threadID): int
|
||||
|
@ -203,7 +201,7 @@ class Forum extends Extension
|
|||
WHERE thread_id = :thread_id
|
||||
", ['thread_id' => $threadID]);
|
||||
|
||||
return (int)ceil($result["count"] / $config->get_int("forumPostsPerPage"));
|
||||
return (int) ceil($result["count"] / $config->get_int("forumPostsPerPage"));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,55 +266,42 @@ class Forum extends Extension
|
|||
return $database->get_one("SELECT t.title FROM forum_threads AS t WHERE t.id = :id ", ['id' => $threadID]);
|
||||
}
|
||||
|
||||
private function show_last_threads(Page $page, PageRequestEvent $event, bool $showAdminOptions = false): void
|
||||
private function show_last_threads(Page $page, int $pageNumber, bool $showAdminOptions = false): void
|
||||
{
|
||||
global $config, $database;
|
||||
$threadsPerPage = $config->get_int('forumThreadsPerPage', 15);
|
||||
$totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM forum_threads") / $threadsPerPage);
|
||||
|
||||
if ($event->count_args() >= 2) {
|
||||
$pageNumber = page_number($event->get_arg(1), $totalPages);
|
||||
} else {
|
||||
$pageNumber = 0;
|
||||
}
|
||||
$totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM forum_threads") / $threadsPerPage);
|
||||
|
||||
$threads = $database->get_all(
|
||||
"SELECT f.id, f.sticky, f.title, f.date, f.uptodate, u.name AS user_name, u.email AS user_email, u.class AS user_class, sum(1) - 1 AS response_count ".
|
||||
"FROM forum_threads AS f ".
|
||||
"INNER JOIN users AS u ".
|
||||
"ON f.user_id = u.id ".
|
||||
"INNER JOIN forum_posts AS p ".
|
||||
"ON p.thread_id = f.id ".
|
||||
"GROUP BY f.id, f.sticky, f.title, f.date, u.name, u.email, u.class ".
|
||||
"ORDER BY f.sticky ASC, f.uptodate DESC LIMIT :limit OFFSET :offset",
|
||||
"SELECT f.id, f.sticky, f.title, f.date, f.uptodate, u.name AS user_name, u.email AS user_email, u.class AS user_class, sum(1) - 1 AS response_count " .
|
||||
"FROM forum_threads AS f " .
|
||||
"INNER JOIN users AS u " .
|
||||
"ON f.user_id = u.id " .
|
||||
"INNER JOIN forum_posts AS p " .
|
||||
"ON p.thread_id = f.id " .
|
||||
"GROUP BY f.id, f.sticky, f.title, f.date, u.name, u.email, u.class " .
|
||||
"ORDER BY f.sticky ASC, f.uptodate DESC LIMIT :limit OFFSET :offset",
|
||||
["limit" => $threadsPerPage, "offset" => $pageNumber * $threadsPerPage]
|
||||
);
|
||||
|
||||
$this->theme->display_thread_list($page, $threads, $showAdminOptions, $pageNumber + 1, $totalPages);
|
||||
}
|
||||
|
||||
private function show_posts(PageRequestEvent $event, bool $showAdminOptions = false): void
|
||||
private function show_posts(int $threadID, int $pageNumber, bool $showAdminOptions = false): void
|
||||
{
|
||||
global $config, $database;
|
||||
$threadID = int_escape($event->get_arg(1));
|
||||
$postsPerPage = $config->get_int('forumPostsPerPage', 15);
|
||||
$totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM forum_posts WHERE thread_id = :id", ['id' => $threadID]) / $postsPerPage);
|
||||
$totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM forum_posts WHERE thread_id = :id", ['id' => $threadID]) / $postsPerPage);
|
||||
$threadTitle = $this->get_thread_title($threadID);
|
||||
|
||||
if ($event->count_args() >= 3) {
|
||||
$pageNumber = page_number($event->get_arg(2), $totalPages);
|
||||
} else {
|
||||
$pageNumber = 0;
|
||||
}
|
||||
|
||||
$posts = $database->get_all(
|
||||
"SELECT p.id, p.date, p.message, u.name as user_name, u.email AS user_email, u.class AS user_class ".
|
||||
"FROM forum_posts AS p ".
|
||||
"INNER JOIN users AS u ".
|
||||
"ON p.user_id = u.id ".
|
||||
"WHERE thread_id = :thread_id ".
|
||||
"ORDER BY p.date ASC ".
|
||||
"LIMIT :limit OFFSET :offset",
|
||||
"SELECT p.id, p.date, p.message, u.name as user_name, u.email AS user_email, u.class AS user_class " .
|
||||
"FROM forum_posts AS p " .
|
||||
"INNER JOIN users AS u " .
|
||||
"ON p.user_id = u.id " .
|
||||
"WHERE thread_id = :thread_id " .
|
||||
"ORDER BY p.date ASC " .
|
||||
"LIMIT :limit OFFSET :offset",
|
||||
["thread_id" => $threadID, "offset" => $pageNumber * $postsPerPage, "limit" => $postsPerPage]
|
||||
);
|
||||
$this->theme->display_thread($posts, $showAdminOptions, $threadTitle, $threadID, $pageNumber + 1, $totalPages);
|
||||
|
|
|
@ -88,19 +88,17 @@ class ImageIO extends Extension
|
|||
$thumb_height = $config->get_int(ImageConfig::THUMB_HEIGHT, 192);
|
||||
$page->add_html_header("<style>:root {--thumb-width: {$thumb_width}px; --thumb-height: {$thumb_height}px;}</style>");
|
||||
|
||||
if ($event->page_matches("image/delete")) {
|
||||
if ($event->page_matches("image/delete", method: "POST", permission: Permissions::DELETE_IMAGE)) {
|
||||
global $page, $user;
|
||||
if ($user->can(Permissions::DELETE_IMAGE) && $event->get_POST('image_id') && $user->check_auth_token()) {
|
||||
$image = Image::by_id(int_escape($event->get_POST('image_id')));
|
||||
if ($image) {
|
||||
send_event(new ImageDeletionEvent($image));
|
||||
$image = Image::by_id(int_escape($event->req_POST('image_id')));
|
||||
if ($image) {
|
||||
send_event(new ImageDeletionEvent($image));
|
||||
|
||||
if ($config->get_string(ImageConfig::ON_DELETE) === ImageConfig::ON_DELETE_NEXT) {
|
||||
redirect_to_next_image($image, $event->get_GET('search'));
|
||||
} else {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link(), ['post/view']));
|
||||
}
|
||||
if ($config->get_string(ImageConfig::ON_DELETE) === ImageConfig::ON_DELETE_NEXT) {
|
||||
redirect_to_next_image($image, $event->get_GET('search'));
|
||||
} else {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link(), ['post/view']));
|
||||
}
|
||||
}
|
||||
} elseif ($event->page_matches("image")) {
|
||||
|
|
|
@ -89,41 +89,39 @@ class ImageBan extends Extension
|
|||
{
|
||||
global $database, $page, $user;
|
||||
|
||||
if ($event->page_matches("image_hash_ban")) {
|
||||
if ($user->can(Permissions::BAN_IMAGE)) {
|
||||
if ($event->get_arg(0) == "add") {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["c_hash" => "optional,string", "c_reason" => "string", "c_image_id" => "optional,int"]);
|
||||
$image = isset($input['c_image_id']) ? Image::by_id($input['c_image_id']) : null;
|
||||
$hash = isset($input["c_hash"]) ? $input["c_hash"] : $image->hash;
|
||||
$reason = isset($input['c_reason']) ? $input['c_reason'] : "DNP";
|
||||
if ($event->page_matches("image_hash_ban", permission: Permissions::BAN_IMAGE)) {
|
||||
if ($event->page_matches("image_hash_ban/add", method: "POST")) {
|
||||
$input = validate_input(["c_hash" => "optional,string", "c_reason" => "string", "c_image_id" => "optional,int"]);
|
||||
$image = isset($input['c_image_id']) ? Image::by_id($input['c_image_id']) : null;
|
||||
$hash = isset($input["c_hash"]) ? $input["c_hash"] : $image->hash;
|
||||
$reason = isset($input['c_reason']) ? $input['c_reason'] : "DNP";
|
||||
|
||||
if ($hash) {
|
||||
send_event(new AddImageHashBanEvent($hash, $reason));
|
||||
$page->flash("Post ban added");
|
||||
if ($hash) {
|
||||
send_event(new AddImageHashBanEvent($hash, $reason));
|
||||
$page->flash("Post ban added");
|
||||
|
||||
if ($image) {
|
||||
send_event(new ImageDeletionEvent($image));
|
||||
$page->flash("Post deleted");
|
||||
}
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
if ($image) {
|
||||
send_event(new ImageDeletionEvent($image));
|
||||
$page->flash("Post deleted");
|
||||
}
|
||||
} elseif ($event->get_arg(0) == "remove") {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["d_hash" => "string"]);
|
||||
send_event(new RemoveImageHashBanEvent($input['d_hash']));
|
||||
$page->flash("Post ban removed");
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
} elseif ($event->get_arg(0) == "list") {
|
||||
$t = new HashBanTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
$this->theme->display_crud("Post Bans", $t->table($t->query()), $t->paginator());
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("image_hash_ban/remove", method: "POST")) {
|
||||
$input = validate_input(["d_hash" => "string"]);
|
||||
send_event(new RemoveImageHashBanEvent($input['d_hash']));
|
||||
$page->flash("Post ban removed");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
}
|
||||
if ($event->page_matches("image_hash_ban/list")) {
|
||||
$t = new HashBanTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
$this->theme->display_crud("Post Bans", $t->table($t->query()), $t->paginator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -180,33 +180,31 @@ class IPBan extends Extension
|
|||
|
||||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
if ($event->page_matches("ip_ban")) {
|
||||
if ($event->page_matches("ip_ban", permission: Permissions::BAN_IP)) {
|
||||
global $database, $page, $user;
|
||||
if ($user->can(Permissions::BAN_IP)) {
|
||||
if ($event->get_arg(0) == "create") {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["c_ip" => "string", "c_mode" => "string", "c_reason" => "string", "c_expires" => "optional,date"]);
|
||||
send_event(new AddIPBanEvent($input['c_ip'], $input['c_mode'], $input['c_reason'], $input['c_expires']));
|
||||
$page->flash("Ban for {$input['c_ip']} added");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("ip_ban/list"));
|
||||
} elseif ($event->get_arg(0) == "delete") {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["d_id" => "int"]);
|
||||
send_event(new RemoveIPBanEvent($input['d_id']));
|
||||
$page->flash("Ban removed");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("ip_ban/list"));
|
||||
} elseif ($event->get_arg(0) == "list") {
|
||||
$event->GET['c_banner'] = $user->name;
|
||||
$event->GET['c_added'] = date('Y-m-d');
|
||||
$t = new IPBanTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
$this->theme->display_bans($page, $t->table($t->query()), $t->paginator());
|
||||
}
|
||||
} else {
|
||||
$this->theme->display_permission_denied();
|
||||
if ($event->page_matches("ip_ban/create", method: "POST")) {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["c_ip" => "string", "c_mode" => "string", "c_reason" => "string", "c_expires" => "optional,date"]);
|
||||
send_event(new AddIPBanEvent($input['c_ip'], $input['c_mode'], $input['c_reason'], $input['c_expires']));
|
||||
$page->flash("Ban for {$input['c_ip']} added");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("ip_ban/list"));
|
||||
}
|
||||
if ($event->page_matches("ip_ban/delete", method: "POST")) {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["d_id" => "int"]);
|
||||
send_event(new RemoveIPBanEvent($input['d_id']));
|
||||
$page->flash("Ban removed");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("ip_ban/list"));
|
||||
}
|
||||
if ($event->page_matches("ip_ban/list")) {
|
||||
$event->GET['c_banner'] = $user->name;
|
||||
$event->GET['c_added'] = date('Y-m-d');
|
||||
$t = new IPBanTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
$this->theme->display_bans($page, $t->table($t->query()), $t->paginator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ class IPBanTest extends ShimmiePHPUnitTestCase
|
|||
|
||||
public function testAccess(): void
|
||||
{
|
||||
$page = $this->get_page('ip_ban/list');
|
||||
$this->assertEquals(403, $page->code);
|
||||
$this->assertEquals("Permission Denied", $page->title);
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->get_page('ip_ban/list');
|
||||
});
|
||||
}
|
||||
|
||||
public function testIPBan(): void
|
||||
|
|
|
@ -278,12 +278,10 @@ class LogDatabase extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $database, $user;
|
||||
if ($event->page_matches("log/view")) {
|
||||
if ($user->can(Permissions::VIEW_EVENTLOG)) {
|
||||
$t = new LogTable($database->raw_db());
|
||||
$t->inputs = $event->GET;
|
||||
$this->theme->display_crud("Event Log", $t->table($t->query()), $t->paginator());
|
||||
}
|
||||
if ($event->page_matches("log/view", permission: Permissions::VIEW_EVENTLOG)) {
|
||||
$t = new LogTable($database->raw_db());
|
||||
$t->inputs = $event->GET;
|
||||
$this->theme->display_crud("Event Log", $t->table($t->query()), $t->paginator());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ class Media extends Extension
|
|||
global $page, $user;
|
||||
|
||||
if (
|
||||
$event->authed_page_matches("media_rescan") &&
|
||||
$event->page_matches("media_rescan", method: "POST") &&
|
||||
$user->can(Permissions::RESCAN_MEDIA)
|
||||
) {
|
||||
$image = Image::by_id(int_escape($event->get_arg(0)));
|
||||
|
|
|
@ -126,33 +126,31 @@ class NotATag extends Extension
|
|||
{
|
||||
global $database, $page, $user;
|
||||
|
||||
if ($event->page_matches("untag")) {
|
||||
if ($user->can(Permissions::BAN_IMAGE)) {
|
||||
if ($event->get_arg(0) == "add") {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["c_tag" => "string", "c_redirect" => "string"]);
|
||||
$database->execute(
|
||||
"INSERT INTO untags(tag, redirect) VALUES (:tag, :redirect)",
|
||||
["tag" => $input['c_tag'], "redirect" => $input['c_redirect']]
|
||||
);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
} elseif ($event->get_arg(0) == "remove") {
|
||||
$user->ensure_authed();
|
||||
$input = validate_input(["d_tag" => "string"]);
|
||||
$database->execute(
|
||||
"DELETE FROM untags WHERE LOWER(tag) = LOWER(:tag)",
|
||||
["tag" => $input['d_tag']]
|
||||
);
|
||||
$page->flash("Post ban removed");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
} elseif ($event->get_arg(0) == "list") {
|
||||
$t = new NotATagTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
$this->theme->display_crud("UnTags", $t->table($t->query()), $t->paginator());
|
||||
}
|
||||
if ($event->page_matches("untag", permission: Permissions::BAN_IMAGE)) {
|
||||
if ($event->page_matches("untag/add", method: "POST")) {
|
||||
$input = validate_input(["c_tag" => "string", "c_redirect" => "string"]);
|
||||
$database->execute(
|
||||
"INSERT INTO untags(tag, redirect) VALUES (:tag, :redirect)",
|
||||
["tag" => $input['c_tag'], "redirect" => $input['c_redirect']]
|
||||
);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
}
|
||||
if ($event->page_matches("untag/remove", method: "POST")) {
|
||||
$input = validate_input(["d_tag" => "string"]);
|
||||
$database->execute(
|
||||
"DELETE FROM untags WHERE LOWER(tag) = LOWER(:tag)",
|
||||
["tag" => $input['d_tag']]
|
||||
);
|
||||
$page->flash("Post ban removed");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
}
|
||||
if ($event->page_matches("untag/list")) {
|
||||
$t = new NotATagTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
$this->theme->display_crud("UnTags", $t->table($t->query()), $t->paginator());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,92 +78,81 @@ class Notes extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $page, $user;
|
||||
if ($event->page_matches("note")) {
|
||||
switch ($event->get_arg(0)) {
|
||||
case "list": //index
|
||||
$this->get_notes_list($event); // This should show images like post/list but i don't know how do that.
|
||||
break;
|
||||
case "requests": // The same as post/list but only for note_request table.
|
||||
$this->get_notes_requests($event); // This should show images like post/list but i don't know how do that.
|
||||
break;
|
||||
case "search":
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->search_notes_page($page);
|
||||
}
|
||||
break;
|
||||
case "updated": //Thinking how to build this function.
|
||||
$this->get_histories($event);
|
||||
break;
|
||||
case "history": //Thinking how to build this function.
|
||||
$this->get_history($event);
|
||||
break;
|
||||
case "revert":
|
||||
$noteID = int_escape($event->get_arg(1));
|
||||
$reviewID = int_escape($event->get_arg(2));
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->revert_history($noteID, $reviewID);
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("note/updated"));
|
||||
break;
|
||||
|
||||
case "add_request":
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->add_note_request($image_id);
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
break;
|
||||
case "nuke_requests":
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$this->nuke_requests($image_id);
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
break;
|
||||
|
||||
case "create_note":
|
||||
$page->set_mode(PageMode::DATA);
|
||||
if (!$user->is_anonymous()) {
|
||||
$note_id = $this->add_new_note();
|
||||
$page->set_data(json_encode_ex([
|
||||
'status' => 'success',
|
||||
'note_id' => $note_id,
|
||||
]));
|
||||
}
|
||||
break;
|
||||
case "update_note":
|
||||
$page->set_mode(PageMode::DATA);
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->update_note();
|
||||
$page->set_data(json_encode_ex(['status' => 'success']));
|
||||
}
|
||||
break;
|
||||
case "delete_note":
|
||||
$page->set_mode(PageMode::DATA);
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$this->delete_note();
|
||||
$page->set_data(json_encode_ex(['status' => 'success']));
|
||||
}
|
||||
break;
|
||||
case "nuke_notes":
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$this->nuke_notes($image_id);
|
||||
}
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
break;
|
||||
|
||||
default:
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("note/list"));
|
||||
break;
|
||||
if ($event->page_matches("note/lost")) {
|
||||
$this->get_notes_list($event->try_page_num(0)); // This should show images like post/list but i don't know how do that.
|
||||
}
|
||||
if ($event->page_matches("note/requests")) {
|
||||
$this->get_notes_requests($event->try_page_num(0)); // This should show images like post/list but i don't know how do that.
|
||||
}
|
||||
if ($event->page_matches("note/search")) {
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->search_notes_page($page);
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("note/updated")) {
|
||||
$this->get_histories($event->try_page_num(0));
|
||||
}
|
||||
if ($event->page_matches("note/history")) {
|
||||
$this->get_history(int_escape($event->get_arg(0)), $event->try_page_num(1));
|
||||
}
|
||||
if ($event->page_matches("note/revert")) {
|
||||
$noteID = int_escape($event->get_arg(0));
|
||||
$reviewID = int_escape($event->get_arg(1));
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->revert_history($noteID, $reviewID);
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("note/updated"));
|
||||
}
|
||||
if ($event->page_matches("note/add_request")) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->add_note_request($image_id);
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
}
|
||||
if ($event->page_matches("note/nuke_requests")) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$this->nuke_requests($image_id);
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
}
|
||||
if ($event->page_matches("note/create_note")) {
|
||||
$page->set_mode(PageMode::DATA);
|
||||
if (!$user->is_anonymous()) {
|
||||
$note_id = $this->add_new_note();
|
||||
$page->set_data(json_encode_ex([
|
||||
'status' => 'success',
|
||||
'note_id' => $note_id,
|
||||
]));
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("note/update_note")) {
|
||||
$page->set_mode(PageMode::DATA);
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->update_note();
|
||||
$page->set_data(json_encode_ex(['status' => 'success']));
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("note/delete_note")) {
|
||||
$page->set_mode(PageMode::DATA);
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$this->delete_note();
|
||||
$page->set_data(json_encode_ex(['status' => 'success']));
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("note/nuke_notes")) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
if ($user->can(Permissions::NOTES_ADMIN)) {
|
||||
$this->nuke_notes($image_id);
|
||||
}
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -364,13 +353,12 @@ class Notes extends Extension
|
|||
log_info("notes", "Requests deleted from {$image_id} by {$user->name}");
|
||||
}
|
||||
|
||||
private function get_notes_list(PageRequestEvent $event): void
|
||||
private function get_notes_list(int $pageNumber): void
|
||||
{
|
||||
global $database, $config;
|
||||
|
||||
$pageNumber = $event->try_page_num(1);
|
||||
$notesPerPage = $config->get_int('notesNotesPerPage');
|
||||
$totalPages = (int)ceil($database->get_one("SELECT COUNT(DISTINCT image_id) FROM notes") / $notesPerPage);
|
||||
$totalPages = (int) ceil($database->get_one("SELECT COUNT(DISTINCT image_id) FROM notes") / $notesPerPage);
|
||||
|
||||
//$result = $database->get_all("SELECT * FROM pool_images WHERE pool_id=:pool_id", ['pool_id'=>$poolID]);
|
||||
$image_ids = $database->get_col(
|
||||
|
@ -383,19 +371,17 @@ class Notes extends Extension
|
|||
);
|
||||
|
||||
$images = [];
|
||||
foreach($image_ids as $id) {
|
||||
foreach ($image_ids as $id) {
|
||||
$images[] = Image::by_id($id);
|
||||
}
|
||||
|
||||
$this->theme->display_note_list($images, $pageNumber + 1, $totalPages);
|
||||
}
|
||||
|
||||
private function get_notes_requests(PageRequestEvent $event): void
|
||||
private function get_notes_requests(int $pageNumber): void
|
||||
{
|
||||
global $config, $database;
|
||||
|
||||
$pageNumber = $event->try_page_num(1);
|
||||
|
||||
$requestsPerPage = $config->get_int('notesRequestsPerPage');
|
||||
|
||||
//$result = $database->get_all("SELECT * FROM pool_images WHERE pool_id=:pool_id", ['pool_id'=>$poolID]);
|
||||
|
@ -408,7 +394,7 @@ class Notes extends Extension
|
|||
["offset" => $pageNumber * $requestsPerPage, "limit" => $requestsPerPage]
|
||||
);
|
||||
|
||||
$totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM note_request") / $requestsPerPage);
|
||||
$totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM note_request") / $requestsPerPage);
|
||||
|
||||
$images = [];
|
||||
while ($row = $result->fetch()) {
|
||||
|
@ -430,54 +416,60 @@ class Notes extends Extension
|
|||
INSERT INTO note_histories (note_enable, note_id, review_id, image_id, user_id, user_ip, date, x1, y1, height, width, note)
|
||||
VALUES (:note_enable, :note_id, :review_id, :image_id, :user_id, :user_ip, now(), :x1, :y1, :height, :width, :note)
|
||||
",
|
||||
['note_enable' => $noteEnable, 'note_id' => $noteID, 'review_id' => $reviewID, 'image_id' => $imageID, 'user_id' => $user->id, 'user_ip' => get_real_ip(),
|
||||
'x1' => $noteX1, 'y1' => $noteY1, 'height' => $noteHeight, 'width' => $noteWidth, 'note' => $noteText]
|
||||
[
|
||||
'note_enable' => $noteEnable,
|
||||
'note_id' => $noteID,
|
||||
'review_id' => $reviewID,
|
||||
'image_id' => $imageID,
|
||||
'user_id' => $user->id,
|
||||
'user_ip' => get_real_ip(),
|
||||
'x1' => $noteX1,
|
||||
'y1' => $noteY1,
|
||||
'height' => $noteHeight,
|
||||
'width' => $noteWidth,
|
||||
'note' => $noteText
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function get_histories(PageRequestEvent $event): void
|
||||
private function get_histories(int $pageNumber): void
|
||||
{
|
||||
global $config, $database;
|
||||
|
||||
$pageNumber = $event->try_page_num(1);
|
||||
|
||||
$historiesPerPage = $config->get_int('notesHistoriesPerPage');
|
||||
|
||||
//ORDER BY IMAGE & DATE
|
||||
$histories = $database->get_all(
|
||||
"SELECT h.note_id, h.review_id, h.image_id, h.date, h.note, u.name AS user_name ".
|
||||
"FROM note_histories AS h ".
|
||||
"INNER JOIN users AS u ".
|
||||
"ON u.id = h.user_id ".
|
||||
"ORDER BY date DESC LIMIT :limit OFFSET :offset",
|
||||
"SELECT h.note_id, h.review_id, h.image_id, h.date, h.note, u.name AS user_name " .
|
||||
"FROM note_histories AS h " .
|
||||
"INNER JOIN users AS u " .
|
||||
"ON u.id = h.user_id " .
|
||||
"ORDER BY date DESC LIMIT :limit OFFSET :offset",
|
||||
['offset' => $pageNumber * $historiesPerPage, 'limit' => $historiesPerPage]
|
||||
);
|
||||
|
||||
$totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM note_histories") / $historiesPerPage);
|
||||
$totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM note_histories") / $historiesPerPage);
|
||||
|
||||
$this->theme->display_histories($histories, $pageNumber + 1, $totalPages);
|
||||
}
|
||||
|
||||
private function get_history(PageRequestEvent $event): void
|
||||
private function get_history(int $noteID, int $pageNumber): void
|
||||
{
|
||||
global $config, $database;
|
||||
|
||||
$noteID = $event->get_arg(1);
|
||||
$pageNumber = $event->try_page_num(2);
|
||||
|
||||
$historiesPerPage = $config->get_int('notesHistoriesPerPage');
|
||||
|
||||
$histories = $database->get_all(
|
||||
"SELECT h.note_id, h.review_id, h.image_id, h.date, h.note, u.name AS user_name ".
|
||||
"FROM note_histories AS h ".
|
||||
"INNER JOIN users AS u ".
|
||||
"ON u.id = h.user_id ".
|
||||
"WHERE note_id = :note_id ".
|
||||
"ORDER BY date DESC LIMIT :limit OFFSET :offset",
|
||||
"SELECT h.note_id, h.review_id, h.image_id, h.date, h.note, u.name AS user_name " .
|
||||
"FROM note_histories AS h " .
|
||||
"INNER JOIN users AS u " .
|
||||
"ON u.id = h.user_id " .
|
||||
"WHERE note_id = :note_id " .
|
||||
"ORDER BY date DESC LIMIT :limit OFFSET :offset",
|
||||
['note_id' => $noteID, 'offset' => $pageNumber * $historiesPerPage, 'limit' => $historiesPerPage]
|
||||
);
|
||||
|
||||
$totalPages = (int)ceil($database->get_one("SELECT COUNT(*) FROM note_histories WHERE note_id = :note_id", ['note_id' => $noteID]) / $historiesPerPage);
|
||||
$totalPages = (int) ceil($database->get_one("SELECT COUNT(*) FROM note_histories WHERE note_id = :note_id", ['note_id' => $noteID]) / $historiesPerPage);
|
||||
|
||||
$this->theme->display_history($histories, $pageNumber + 1, $totalPages);
|
||||
}
|
||||
|
@ -492,13 +484,13 @@ class Notes extends Extension
|
|||
$history = $database->get_row("SELECT * FROM note_histories WHERE note_id = :note_id AND review_id = :review_id", ['note_id' => $noteID, 'review_id' => $reviewID]);
|
||||
|
||||
$noteEnable = $history['note_enable'];
|
||||
$noteID = $history['note_id'];
|
||||
$imageID = $history['image_id'];
|
||||
$noteX1 = $history['x1'];
|
||||
$noteY1 = $history['y1'];
|
||||
$noteID = $history['note_id'];
|
||||
$imageID = $history['image_id'];
|
||||
$noteX1 = $history['x1'];
|
||||
$noteY1 = $history['y1'];
|
||||
$noteHeight = $history['height'];
|
||||
$noteWidth = $history['width'];
|
||||
$noteText = $history['note'];
|
||||
$noteWidth = $history['width'];
|
||||
$noteText = $history['note'];
|
||||
|
||||
$database->execute("
|
||||
UPDATE notes
|
||||
|
|
|
@ -156,36 +156,30 @@ class NumericScore extends Extension
|
|||
$html .= "</td></tr>";
|
||||
}
|
||||
die($html);
|
||||
} elseif ($event->page_matches("numeric_score_vote") && $user->check_auth_token()) {
|
||||
if ($user->can(Permissions::CREATE_VOTE)) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
$score = int_escape($event->req_POST("vote"));
|
||||
if (($score == -1 || $score == 0 || $score == 1) && $image_id > 0) {
|
||||
send_event(new NumericScoreSetEvent($image_id, $user, $score));
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
}
|
||||
} elseif ($event->page_matches("numeric_score/remove_votes_on") && $user->check_auth_token()) {
|
||||
if ($user->can(Permissions::EDIT_OTHER_VOTE)) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
$database->execute(
|
||||
"DELETE FROM numeric_score_votes WHERE image_id=:image_id",
|
||||
['image_id' => $image_id]
|
||||
);
|
||||
$database->execute(
|
||||
"UPDATE images SET numeric_score=0 WHERE id=:id",
|
||||
['id' => $image_id]
|
||||
);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
}
|
||||
} elseif ($event->page_matches("numeric_score/remove_votes_by") && $user->check_auth_token()) {
|
||||
if ($user->can(Permissions::EDIT_OTHER_VOTE)) {
|
||||
$this->delete_votes_by(int_escape($event->req_POST('user_id')));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link());
|
||||
} elseif ($event->page_matches("numeric_score_vote", method: "POST", permission: Permissions::CREATE_VOTE)) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
$score = int_escape($event->req_POST("vote"));
|
||||
if (($score == -1 || $score == 0 || $score == 1) && $image_id > 0) {
|
||||
send_event(new NumericScoreSetEvent($image_id, $user, $score));
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
} elseif ($event->page_matches("numeric_score/remove_votes_on", method: "POST", permission: Permissions::EDIT_OTHER_VOTE)) {
|
||||
$image_id = int_escape($event->req_POST("image_id"));
|
||||
$database->execute(
|
||||
"DELETE FROM numeric_score_votes WHERE image_id=:image_id",
|
||||
['image_id' => $image_id]
|
||||
);
|
||||
$database->execute(
|
||||
"UPDATE images SET numeric_score=0 WHERE id=:id",
|
||||
['id' => $image_id]
|
||||
);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
} elseif ($event->page_matches("numeric_score/remove_votes_by", method: "POST", permission: Permissions::EDIT_OTHER_VOTE)) {
|
||||
$this->delete_votes_by(int_escape($event->req_POST('user_id')));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link());
|
||||
} elseif ($event->page_matches("popular_by_day") || $event->page_matches("popular_by_month") || $event->page_matches("popular_by_year")) {
|
||||
//FIXME: popular_by isn't linked from anywhere
|
||||
list($day, $month, $year) = [date("d"), date("m"), date("Y")];
|
||||
|
|
|
@ -227,66 +227,49 @@ class PrivMsg extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $cache, $database, $page, $user;
|
||||
if ($event->page_matches("pm")) {
|
||||
switch ($event->get_arg(0)) {
|
||||
case "read":
|
||||
if ($user->can(Permissions::READ_PM)) {
|
||||
$pm_id = int_escape($event->get_arg(1));
|
||||
$pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]);
|
||||
if (is_null($pm)) {
|
||||
$this->theme->display_error(404, "No such PM", "There is no PM #$pm_id");
|
||||
} elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) {
|
||||
$from_user = User::by_id((int)$pm["from_id"]);
|
||||
if ($pm["to_id"] == $user->id) {
|
||||
$database->execute("UPDATE private_message SET is_read=true WHERE id = :id", ["id" => $pm_id]);
|
||||
$cache->delete("pm-count-{$user->id}");
|
||||
}
|
||||
$pmo = PM::from_row($pm);
|
||||
$this->theme->display_message($page, $from_user, $user, $pmo);
|
||||
if($user->can(Permissions::SEND_PM)) {
|
||||
$this->theme->display_composer($page, $user, $from_user, "Re: ".$pmo->subject);
|
||||
}
|
||||
} else {
|
||||
$this->theme->display_permission_denied();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "delete":
|
||||
if ($user->can(Permissions::READ_PM)) {
|
||||
if ($user->check_auth_token()) {
|
||||
$pm_id = int_escape($event->get_POST("pm_id"));
|
||||
$pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]);
|
||||
if (is_null($pm)) {
|
||||
$this->theme->display_error(404, "No such PM", "There is no PM #$pm_id");
|
||||
} elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) {
|
||||
$database->execute("DELETE FROM private_message WHERE id = :id", ["id" => $pm_id]);
|
||||
$cache->delete("pm-count-{$user->id}");
|
||||
log_info("pm", "Deleted PM #$pm_id", "PM deleted");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "send":
|
||||
if ($user->can(Permissions::SEND_PM)) {
|
||||
if ($user->check_auth_token()) {
|
||||
$to_id = int_escape($event->get_POST("to_id"));
|
||||
$from_id = $user->id;
|
||||
$subject = $event->req_POST("subject");
|
||||
$message = $event->req_POST("message");
|
||||
send_event(new SendPMEvent(new PM($from_id, get_real_ip(), $to_id, $subject, $message)));
|
||||
$page->flash("PM sent");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->theme->display_error(400, "Invalid action", "That's not something you can do with a PM");
|
||||
break;
|
||||
if ($event->page_matches("pm/read", permission: Permissions::READ_PM)) {
|
||||
$pm_id = int_escape($event->get_arg(1));
|
||||
$pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]);
|
||||
if (is_null($pm)) {
|
||||
$this->theme->display_error(404, "No such PM", "There is no PM #$pm_id");
|
||||
} elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) {
|
||||
$from_user = User::by_id((int)$pm["from_id"]);
|
||||
if ($pm["to_id"] == $user->id) {
|
||||
$database->execute("UPDATE private_message SET is_read=true WHERE id = :id", ["id" => $pm_id]);
|
||||
$cache->delete("pm-count-{$user->id}");
|
||||
}
|
||||
$pmo = PM::from_row($pm);
|
||||
$this->theme->display_message($page, $from_user, $user, $pmo);
|
||||
if($user->can(Permissions::SEND_PM)) {
|
||||
$this->theme->display_composer($page, $user, $from_user, "Re: ".$pmo->subject);
|
||||
}
|
||||
} else {
|
||||
throw new PermissionDeniedException("You do not have permission to view this PM");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pm/delete", method: "POST", permission: Permissions::READ_PM)) {
|
||||
$pm_id = int_escape($event->req_POST("pm_id"));
|
||||
$pm = $database->get_row("SELECT * FROM private_message WHERE id = :id", ["id" => $pm_id]);
|
||||
if (is_null($pm)) {
|
||||
$this->theme->display_error(404, "No such PM", "There is no PM #$pm_id");
|
||||
} elseif (($pm["to_id"] == $user->id) || $user->can(Permissions::VIEW_OTHER_PMS)) {
|
||||
$database->execute("DELETE FROM private_message WHERE id = :id", ["id" => $pm_id]);
|
||||
$cache->delete("pm-count-{$user->id}");
|
||||
log_info("pm", "Deleted PM #$pm_id", "PM deleted");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pm/send", method: "POST", permission: Permissions::SEND_PM)) {
|
||||
$to_id = int_escape($event->req_POST("to_id"));
|
||||
$from_id = $user->id;
|
||||
$subject = $event->req_POST("subject");
|
||||
$message = $event->req_POST("message");
|
||||
send_event(new SendPMEvent(new PM($from_id, get_real_ip(), $to_id, $subject, $message)));
|
||||
$page->flash("PM sent");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(referer_or(make_link()));
|
||||
}
|
||||
}
|
||||
|
||||
public function onSendPM(SendPMEvent $event): void
|
||||
|
|
|
@ -93,14 +93,14 @@ class Pool
|
|||
*/
|
||||
public function __construct(array $row)
|
||||
{
|
||||
$this->id = (int)$row['id'];
|
||||
$this->user_id = (int)$row['user_id'];
|
||||
$this->id = (int) $row['id'];
|
||||
$this->user_id = (int) $row['user_id'];
|
||||
$this->user_name = $row['user_name'] ?? null;
|
||||
$this->public = bool_escape($row['public']);
|
||||
$this->title = $row['title'];
|
||||
$this->description = $row['description'];
|
||||
$this->date = $row['date'];
|
||||
$this->posts = (int)$row['posts'];
|
||||
$this->posts = (int) $row['posts'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -198,7 +198,7 @@ class Pools extends Extension
|
|||
// column non-deterministically, so let's check if it is there and
|
||||
// add it if needed.
|
||||
$cols = $database->raw_db()->describe("pools");
|
||||
if(!array_key_exists("lastupdated", $cols)) {
|
||||
if (!array_key_exists("lastupdated", $cols)) {
|
||||
$database->execute("ALTER TABLE pools ADD COLUMN lastupdated TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP");
|
||||
}
|
||||
$this->set_version("ext_pools_version", 5);
|
||||
|
@ -240,7 +240,7 @@ class Pools extends Extension
|
|||
if ($event->page_matches("pool/list")) { //index
|
||||
if ($event->get_GET('search')) {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link('pool/list').'/'.url_escape($event->get_GET('search')).'/'.strval($event->try_page_num(1)));
|
||||
$page->set_redirect(make_link('pool/list') . '/' . url_escape($event->get_GET('search')) . '/' . strval($event->try_page_num(1)));
|
||||
return;
|
||||
}
|
||||
if (count($event->args) >= 4) { // Assume first 2 args are search and page num
|
||||
|
@ -251,232 +251,218 @@ class Pools extends Extension
|
|||
$page_num = $event->try_page_num(0);
|
||||
}
|
||||
$this->list_pools($page, $page_num, $search);
|
||||
} elseif ($event->page_matches("pool")) {
|
||||
// What action are we trying to perform?
|
||||
switch ($event->get_arg(0)) {
|
||||
case "new": // Show form for new pools
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->new_pool_composer($page);
|
||||
} else {
|
||||
$errMessage = "You must be registered and logged in to create a new pool.";
|
||||
$this->theme->display_error(401, "Error", $errMessage);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ($event->page_matches("pool/new", method: "GET")) {
|
||||
if (!$user->is_anonymous()) {
|
||||
$this->theme->new_pool_composer($page);
|
||||
} else {
|
||||
$errMessage = "You must be registered and logged in to create a new pool.";
|
||||
$this->theme->display_error(401, "Error", $errMessage);
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/create", method: "POST")) {
|
||||
try {
|
||||
$pce = send_event(
|
||||
new PoolCreationEvent(
|
||||
$event->req_POST("title"),
|
||||
$user,
|
||||
bool_escape($event->req_POST("public")),
|
||||
$event->req_POST("description")
|
||||
)
|
||||
);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pce->new_id));
|
||||
} catch (PoolCreationException $e) {
|
||||
$this->theme->display_error(400, "Error", $e->error);
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/view", method: "GET")) {
|
||||
$poolID = int_escape($event->get_arg(0));
|
||||
$this->get_posts($event->try_page_num(1), $poolID);
|
||||
}
|
||||
if ($event->page_matches("pool/updated")) {
|
||||
$this->get_history($event->try_page_num(0));
|
||||
}
|
||||
if ($event->page_matches("pool/revert")) {
|
||||
if (!$user->is_anonymous()) {
|
||||
$historyID = int_escape($event->get_arg(0));
|
||||
$this->revert_history($historyID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/updated"));
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/edit")) {
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
case "create": // ADD _POST
|
||||
try {
|
||||
$event = send_event(new PoolCreationEvent(
|
||||
$event->req_POST("title"),
|
||||
$user,
|
||||
bool_escape($event->req_POST("public")),
|
||||
$event->req_POST("description")
|
||||
));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $event->new_id));
|
||||
} catch (PoolCreationException $e) {
|
||||
$this->theme->display_error(400, "Error", $e->error);
|
||||
}
|
||||
break;
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $pool_id]);
|
||||
$images = [];
|
||||
while ($row = $result->fetch()) {
|
||||
$images[] = Image::by_id((int) $row["image_id"]);
|
||||
}
|
||||
$this->theme->edit_pool($page, $pool, $images);
|
||||
} else {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/order")) {
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
case "view":
|
||||
$poolID = int_escape($event->get_arg(1));
|
||||
$this->get_posts($event, $poolID);
|
||||
break;
|
||||
if ($event->get_POST("order_view")) {
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$result = $database->execute(
|
||||
"SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC",
|
||||
["pid" => $pool_id]
|
||||
);
|
||||
$images = [];
|
||||
|
||||
case "updated":
|
||||
$this->get_history($event->try_page_num(1));
|
||||
break;
|
||||
|
||||
case "revert":
|
||||
if (!$user->is_anonymous()) {
|
||||
$historyID = int_escape($event->get_arg(1));
|
||||
$this->revert_history($historyID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/updated"));
|
||||
}
|
||||
break;
|
||||
|
||||
case "edit": // Edit the pool (remove images)
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $pool_id]);
|
||||
$images = [];
|
||||
while ($row = $result->fetch()) {
|
||||
$images[] = Image::by_id((int)$row["image_id"]);
|
||||
}
|
||||
$this->theme->edit_pool($page, $pool, $images);
|
||||
} else {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
}
|
||||
break;
|
||||
|
||||
case "order": // Order the pool (view and change the order of images within the pool)
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($event->get_POST("order_view")) {
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$result = $database->execute(
|
||||
"SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC",
|
||||
["pid" => $pool_id]
|
||||
);
|
||||
$images = [];
|
||||
|
||||
while ($row = $result->fetch()) {
|
||||
$image = $database->get_row(
|
||||
"
|
||||
SELECT * FROM images AS i
|
||||
INNER JOIN pool_images AS p ON i.id = p.image_id
|
||||
WHERE pool_id=:pid AND i.id=:iid",
|
||||
["pid" => $pool_id, "iid" => (int)$row['image_id']]
|
||||
);
|
||||
$images[] = ($image ? new Image($image) : null);
|
||||
}
|
||||
|
||||
$this->theme->edit_order($page, $pool, $images);
|
||||
} else {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
}
|
||||
} else {
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
foreach ($event->POST as $key => $value) {
|
||||
if(str_starts_with($key, "order_")) {
|
||||
$imageID = (int)substr($key, 6);
|
||||
$database->execute(
|
||||
"
|
||||
UPDATE pool_images
|
||||
SET image_order = :ord
|
||||
WHERE pool_id = :pid AND image_id = :iid",
|
||||
["ord" => $value, "pid" => int_escape($event->req_POST('pool_id')), "iid" => $imageID]
|
||||
);
|
||||
}
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "reverse":
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$database->with_savepoint(function () use ($pool_id) {
|
||||
global $database;
|
||||
$result = $database->execute(
|
||||
"SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order DESC",
|
||||
["pid" => $pool_id]
|
||||
);
|
||||
$image_order = 1;
|
||||
while ($row = $result->fetch()) {
|
||||
$database->execute(
|
||||
"
|
||||
UPDATE pool_images
|
||||
SET image_order=:ord
|
||||
WHERE pool_id = :pid AND image_id = :iid",
|
||||
["ord" => $image_order, "pid" => $pool_id, "iid" => (int)$row['image_id']]
|
||||
);
|
||||
$image_order = $image_order + 1;
|
||||
}
|
||||
});
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
break;
|
||||
case "import":
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$images = Search::find_images(
|
||||
limit: $config->get_int(PoolsConfig::MAX_IMPORT_RESULTS, 1000),
|
||||
tags: Tag::explode($event->req_POST("pool_tag"))
|
||||
while ($row = $result->fetch()) {
|
||||
$image = $database->get_row(
|
||||
"
|
||||
SELECT * FROM images AS i
|
||||
INNER JOIN pool_images AS p ON i.id = p.image_id
|
||||
WHERE pool_id=:pid AND i.id=:iid",
|
||||
["pid" => $pool_id, "iid" => (int) $row['image_id']]
|
||||
);
|
||||
$this->theme->pool_result($page, $images, $pool);
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
$images[] = ($image ? new Image($image) : null);
|
||||
}
|
||||
break;
|
||||
|
||||
case "add_posts":
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$image_ids = array_map('intval', $event->req_POST_array('check'));
|
||||
send_event(new PoolAddPostsEvent($pool_id, $image_ids));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
break;
|
||||
|
||||
case "remove_posts":
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$images = "";
|
||||
foreach ($event->req_POST_array('check') as $imageID) {
|
||||
$this->theme->edit_order($page, $pool, $images);
|
||||
} else {
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
}
|
||||
} else {
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
foreach ($event->POST as $key => $value) {
|
||||
if (str_starts_with($key, "order_")) {
|
||||
$imageID = (int) substr($key, 6);
|
||||
$database->execute(
|
||||
"DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid",
|
||||
["pid" => $pool_id, "iid" => $imageID]
|
||||
"
|
||||
UPDATE pool_images
|
||||
SET image_order = :ord
|
||||
WHERE pool_id = :pid AND image_id = :iid",
|
||||
["ord" => $value, "pid" => int_escape($event->req_POST('pool_id')), "iid" => $imageID]
|
||||
);
|
||||
$images .= " " . $imageID;
|
||||
}
|
||||
$count = (int)$database->get_one(
|
||||
"SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid",
|
||||
["pid" => $pool_id]
|
||||
);
|
||||
$this->add_history($pool_id, 0, $images, $count);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/reverse")) {
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
break;
|
||||
|
||||
case "edit_description":
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$database->with_savepoint(function () use ($pool_id) {
|
||||
global $database;
|
||||
$result = $database->execute(
|
||||
"SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order DESC",
|
||||
["pid" => $pool_id]
|
||||
);
|
||||
$image_order = 1;
|
||||
while ($row = $result->fetch()) {
|
||||
$database->execute(
|
||||
"UPDATE pools SET description=:dsc,lastupdated=CURRENT_TIMESTAMP WHERE id=:pid",
|
||||
["dsc" => $event->req_POST('description'), "pid" => $pool_id]
|
||||
"
|
||||
UPDATE pool_images
|
||||
SET image_order=:ord
|
||||
WHERE pool_id = :pid AND image_id = :iid",
|
||||
["ord" => $image_order, "pid" => $pool_id, "iid" => (int) $row['image_id']]
|
||||
);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
$image_order = $image_order + 1;
|
||||
}
|
||||
});
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/import")) {
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
break;
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$images = Search::find_images(
|
||||
limit: $config->get_int(PoolsConfig::MAX_IMPORT_RESULTS, 1000),
|
||||
tags: Tag::explode($event->req_POST("pool_tag"))
|
||||
);
|
||||
$this->theme->pool_result($page, $images, $pool);
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/add_posts")) {
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
case "nuke":
|
||||
// Completely remove the given pool.
|
||||
// -> Only admins and owners may do this
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$image_ids = array_map('intval', $event->req_POST_array('check'));
|
||||
send_event(new PoolAddPostsEvent($pool_id, $image_ids));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/remove_posts")) {
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($user->can(Permissions::POOLS_ADMIN) || $user->id == $pool->user_id) {
|
||||
send_event(new PoolDeletionEvent($pool_id));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/list"));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
break;
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$images = "";
|
||||
foreach ($event->req_POST_array('check') as $imageID) {
|
||||
$database->execute(
|
||||
"DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid",
|
||||
["pid" => $pool_id, "iid" => $imageID]
|
||||
);
|
||||
$images .= " " . $imageID;
|
||||
}
|
||||
$count = (int) $database->get_one(
|
||||
"SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid",
|
||||
["pid" => $pool_id]
|
||||
);
|
||||
$this->add_history($pool_id, 0, $images, $count);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/edit_description")) {
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($this->have_permission($user, $pool)) {
|
||||
$database->execute(
|
||||
"UPDATE pools SET description=:dsc,lastupdated=CURRENT_TIMESTAMP WHERE id=:pid",
|
||||
["dsc" => $event->req_POST('description'), "pid" => $pool_id]
|
||||
);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/view/" . $pool_id));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("pool/nuke")) {
|
||||
// Completely remove the given pool.
|
||||
// -> Only admins and owners may do this
|
||||
$pool_id = int_escape($event->req_POST("pool_id"));
|
||||
$pool = $this->get_single_pool($pool_id);
|
||||
|
||||
if ($user->can(Permissions::POOLS_ADMIN) || $user->id == $pool->user_id) {
|
||||
send_event(new PoolDeletionEvent($pool_id));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("pool/list"));
|
||||
} else {
|
||||
$this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -587,19 +573,19 @@ class Pools extends Extension
|
|||
$matches = [];
|
||||
if (preg_match("/^pool[=|:]([^:]*|lastcreated):?([0-9]*)$/i", $event->term, $matches)) {
|
||||
global $user;
|
||||
$poolTag = (string)str_replace("_", " ", $matches[1]);
|
||||
$poolTag = (string) str_replace("_", " ", $matches[1]);
|
||||
|
||||
$pool = null;
|
||||
if ($poolTag == 'lastcreated') {
|
||||
$pool = $this->get_last_userpool($user->id);
|
||||
} elseif (ctype_digit($poolTag)) { //If only digits, assume PoolID
|
||||
$pool = $this->get_single_pool((int)$poolTag);
|
||||
$pool = $this->get_single_pool((int) $poolTag);
|
||||
} else { //assume PoolTitle
|
||||
$pool = $this->get_single_pool_from_title($poolTag);
|
||||
}
|
||||
|
||||
if ($pool && $this->have_permission($user, $pool)) {
|
||||
$image_order = (int)($matches[2] ?: 0);
|
||||
$image_order = (int) ($matches[2] ?: 0);
|
||||
$this->add_post($pool->id, $event->image_id, true, $image_order);
|
||||
}
|
||||
}
|
||||
|
@ -612,8 +598,8 @@ class Pools extends Extension
|
|||
$options = $database->get_pairs("SELECT id,title FROM pools ORDER BY title");
|
||||
|
||||
// TODO: Don't cast into strings, make BABBE accept HTMLElement instead.
|
||||
$event->add_action("bulk_pool_add_existing", "Add To (P)ool", "p", "", (string)$this->theme->get_bulk_pool_selector($options));
|
||||
$event->add_action("bulk_pool_add_new", "Create Pool", "", "", (string)$this->theme->get_bulk_pool_input($event->search_terms));
|
||||
$event->add_action("bulk_pool_add_existing", "Add To (P)ool", "p", "", (string) $this->theme->get_bulk_pool_selector($options));
|
||||
$event->add_action("bulk_pool_add_new", "Create Pool", "", "", (string) $this->theme->get_bulk_pool_input($event->search_terms));
|
||||
}
|
||||
|
||||
public function onBulkAction(BulkActionEvent $event): void
|
||||
|
@ -680,7 +666,7 @@ class Pools extends Extension
|
|||
|
||||
$where_clause = "WHERE LOWER(title) like '%%'";
|
||||
if ($search != null) {
|
||||
$where_clause = "WHERE LOWER(title) like '%".strtolower($search)."%'";
|
||||
$where_clause = "WHERE LOWER(title) like '%" . strtolower($search) . "%'";
|
||||
}
|
||||
|
||||
$pools = array_map([Pool::class, "makePool"], $database->get_all("
|
||||
|
@ -692,7 +678,7 @@ class Pools extends Extension
|
|||
$order_by
|
||||
LIMIT :l OFFSET :o
|
||||
", ["l" => $poolsPerPage, "o" => $pageNumber * $poolsPerPage]));
|
||||
$totalPages = (int)ceil((int)$database->get_one("SELECT COUNT(*) FROM pools ".$where_clause) / $poolsPerPage);
|
||||
$totalPages = (int) ceil((int) $database->get_one("SELECT COUNT(*) FROM pools " . $where_clause) / $poolsPerPage);
|
||||
|
||||
$this->theme->list_pools($page, $pools, $search, $pageNumber + 1, $totalPages);
|
||||
}
|
||||
|
@ -784,7 +770,7 @@ class Pools extends Extension
|
|||
}
|
||||
|
||||
if (count($images) > 0) {
|
||||
$count = (int)$database->get_one(
|
||||
$count = (int) $database->get_one(
|
||||
"SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid",
|
||||
["pid" => $event->pool_id]
|
||||
);
|
||||
|
@ -839,11 +825,10 @@ class Pools extends Extension
|
|||
/**
|
||||
* Retrieve all the images in a pool, given a pool ID.
|
||||
*/
|
||||
private function get_posts(PageRequestEvent $event, int $poolID): void
|
||||
private function get_posts(int $pageNumber, int $poolID): void
|
||||
{
|
||||
global $config, $user, $database;
|
||||
|
||||
$pageNumber = $event->try_page_num(2);
|
||||
$pool = $this->get_single_pool($poolID);
|
||||
$imagesPerPage = $config->get_int(PoolsConfig::IMAGES_PER_PAGE);
|
||||
|
||||
|
@ -856,7 +841,7 @@ class Pools extends Extension
|
|||
// WE CHECK IF THE EXTENSION RATING IS INSTALLED, WHICH VERSION AND IF IT
|
||||
// WORKS TO SHOW/HIDE SAFE, QUESTIONABLE, EXPLICIT AND UNRATED IMAGES FROM USER
|
||||
if (Extension::is_enabled(RatingsInfo::KEY)) {
|
||||
$query .= "AND i.rating IN (".Ratings::privs_to_sql(Ratings::get_user_class_privs($user)).")";
|
||||
$query .= "AND i.rating IN (" . Ratings::privs_to_sql(Ratings::get_user_class_privs($user)) . ")";
|
||||
}
|
||||
if (Extension::is_enabled(TrashInfo::KEY)) {
|
||||
$query .= " AND trash != :true";
|
||||
|
@ -876,14 +861,14 @@ class Pools extends Extension
|
|||
] + $params
|
||||
);
|
||||
|
||||
$totalPages = (int)ceil((int)$database->get_one(
|
||||
$totalPages = (int) ceil((int) $database->get_one(
|
||||
"SELECT COUNT(*) FROM pool_images p $query",
|
||||
["pid" => $poolID] + $params
|
||||
) / $imagesPerPage);
|
||||
|
||||
$images = [];
|
||||
foreach ($result as $singleResult) {
|
||||
$images[] = Image::by_id((int)$singleResult["image_id"]);
|
||||
$images[] = Image::by_id((int) $singleResult["image_id"]);
|
||||
}
|
||||
|
||||
$this->theme->view_pool($pool, $images, $pageNumber + 1, $totalPages);
|
||||
|
@ -897,7 +882,7 @@ class Pools extends Extension
|
|||
global $user, $database;
|
||||
$poolID = $event->pool_id;
|
||||
|
||||
$owner_id = (int)$database->get_one("SELECT user_id FROM pools WHERE id = :pid", ["pid" => $poolID]);
|
||||
$owner_id = (int) $database->get_one("SELECT user_id FROM pools WHERE id = :pid", ["pid" => $poolID]);
|
||||
if ($owner_id == $user->id || $user->can(Permissions::POOLS_ADMIN)) {
|
||||
$database->execute("DELETE FROM pool_history WHERE pool_id = :pid", ["pid" => $poolID]);
|
||||
$database->execute("DELETE FROM pool_images WHERE pool_id = :pid", ["pid" => $poolID]);
|
||||
|
@ -940,7 +925,7 @@ class Pools extends Extension
|
|||
LIMIT :l OFFSET :o
|
||||
", ["l" => $historiesPerPage, "o" => $pageNumber * $historiesPerPage]);
|
||||
|
||||
$totalPages = (int)ceil((int)$database->get_one("SELECT COUNT(*) FROM pool_history") / $historiesPerPage);
|
||||
$totalPages = (int) ceil((int) $database->get_one("SELECT COUNT(*) FROM pool_history") / $historiesPerPage);
|
||||
|
||||
$this->theme->show_history($history, $pageNumber + 1, $totalPages);
|
||||
}
|
||||
|
@ -956,7 +941,7 @@ class Pools extends Extension
|
|||
foreach ($status as $entry) {
|
||||
$images = trim($entry['images']);
|
||||
$images = explode(" ", $images);
|
||||
$poolID = (int)$entry['pool_id'];
|
||||
$poolID = (int) $entry['pool_id'];
|
||||
$imageArray = "";
|
||||
$newAction = -1;
|
||||
|
||||
|
@ -985,7 +970,7 @@ class Pools extends Extension
|
|||
continue; // go on to the next one.
|
||||
}
|
||||
|
||||
$count = (int)$database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]);
|
||||
$count = (int) $database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]);
|
||||
$this->add_history($poolID, $newAction, $imageArray, $count);
|
||||
}
|
||||
}
|
||||
|
@ -998,14 +983,14 @@ class Pools extends Extension
|
|||
{
|
||||
global $database, $config;
|
||||
|
||||
$result = (int)$database->get_one(
|
||||
$result = (int) $database->get_one(
|
||||
"SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid AND image_id=:iid",
|
||||
["pid" => $poolID, "iid" => $imageID]
|
||||
);
|
||||
|
||||
if ($result == 0) {
|
||||
if ($config->get_bool(PoolsConfig::AUTO_INCREMENT_ORDER) && $imageOrder === 0) {
|
||||
$imageOrder = (int)$database->get_one(
|
||||
$imageOrder = (int) $database->get_one(
|
||||
"
|
||||
SELECT COALESCE(MAX(image_order),0) + 1
|
||||
FROM pool_images
|
||||
|
@ -1028,8 +1013,8 @@ class Pools extends Extension
|
|||
$this->update_count($poolID);
|
||||
|
||||
if ($history) {
|
||||
$count = (int)$database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]);
|
||||
$this->add_history($poolID, 1, (string)$imageID, $count);
|
||||
$count = (int) $database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]);
|
||||
$this->add_history($poolID, 1, (string) $imageID, $count);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ class PrivateImage extends Extension
|
|||
{
|
||||
global $page, $user, $user_config;
|
||||
|
||||
if ($event->page_matches("privatize_image") && $user->can(Permissions::SET_PRIVATE_IMAGE)) {
|
||||
if ($event->page_matches("privatize_image", method: "POST", permission: Permissions::SET_PRIVATE_IMAGE)) {
|
||||
// Try to get the image ID
|
||||
$image_id = int_escape(null_throws($event->get_arg(0)));
|
||||
$image = Image::by_id($image_id);
|
||||
|
@ -59,7 +59,7 @@ class PrivateImage extends Extension
|
|||
$page->set_redirect(make_link("post/view/" . $image_id));
|
||||
}
|
||||
|
||||
if ($event->page_matches("publicize_image")) {
|
||||
if ($event->page_matches("publicize_image", method: "POST")) {
|
||||
// Try to get the image ID
|
||||
$image_id = int_escape(null_throws($event->get_arg(0)));
|
||||
$image = Image::by_id($image_id);
|
||||
|
@ -75,29 +75,22 @@ class PrivateImage extends Extension
|
|||
$page->set_redirect(make_link("post/view/".$image_id));
|
||||
}
|
||||
|
||||
if ($event->page_matches("user_admin")) {
|
||||
if (!$user->check_auth_token()) {
|
||||
return;
|
||||
if ($event->page_matches("user_admin/private_image", method: "POST")) {
|
||||
$id = int_escape($event->req_POST('id'));
|
||||
if ($id != $user->id) {
|
||||
throw new SCoreException("Cannot change another user's settings");
|
||||
}
|
||||
switch ($event->get_arg(0)) {
|
||||
case "private_image":
|
||||
$id = int_escape($event->req_POST('id'));
|
||||
if ($id != $user->id) {
|
||||
throw new SCoreException("Cannot change another user's settings");
|
||||
}
|
||||
$set_default = array_key_exists("set_default", $event->POST);
|
||||
$view_default = array_key_exists("view_default", $event->POST);
|
||||
$set_default = array_key_exists("set_default", $event->POST);
|
||||
$view_default = array_key_exists("view_default", $event->POST);
|
||||
|
||||
$user_config->set_bool(PrivateImageConfig::USER_SET_DEFAULT, $set_default);
|
||||
$user_config->set_bool(PrivateImageConfig::USER_VIEW_DEFAULT, $view_default);
|
||||
$user_config->set_bool(PrivateImageConfig::USER_SET_DEFAULT, $set_default);
|
||||
$user_config->set_bool(PrivateImageConfig::USER_VIEW_DEFAULT, $view_default);
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("user"));
|
||||
|
||||
break;
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("user"));
|
||||
}
|
||||
}
|
||||
|
||||
public function onDisplayingImage(DisplayingImageEvent $event): void
|
||||
{
|
||||
global $user, $page;
|
||||
|
@ -108,7 +101,6 @@ class PrivateImage extends Extension
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
public const SEARCH_REGEXP = "/^private:(yes|no|any)/";
|
||||
public function onSearchTermParse(SearchTermParseEvent $event): void
|
||||
{
|
||||
|
|
|
@ -374,27 +374,23 @@ class Ratings extends Extension
|
|||
{
|
||||
global $user, $page;
|
||||
|
||||
if ($event->page_matches("admin/bulk_rate")) {
|
||||
if (!$user->can(Permissions::BULK_EDIT_IMAGE_RATING)) {
|
||||
throw new PermissionDeniedException("Permission denied");
|
||||
} else {
|
||||
$n = 0;
|
||||
while (true) {
|
||||
$images = Search::find_images($n, 100, Tag::explode($event->req_POST("query")));
|
||||
if (count($images) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
reset($images); // rewind to first element in array.
|
||||
|
||||
foreach ($images as $image) {
|
||||
send_event(new RatingSetEvent($image, $event->req_POST('rating')));
|
||||
}
|
||||
$n += 100;
|
||||
if ($event->page_matches("admin/bulk_rate", method: "POST", permission: Permissions::BULK_EDIT_IMAGE_RATING)) {
|
||||
$n = 0;
|
||||
while (true) {
|
||||
$images = Search::find_images($n, 100, Tag::explode($event->req_POST("query")));
|
||||
if (count($images) == 0) {
|
||||
break;
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link());
|
||||
|
||||
reset($images); // rewind to first element in array.
|
||||
|
||||
foreach ($images as $image) {
|
||||
send_event(new RatingSetEvent($image, $event->req_POST('rating')));
|
||||
}
|
||||
$n += 100;
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ class RegenThumb extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->page_matches("regen_thumb") && $user->can(Permissions::DELETE_IMAGE)) {
|
||||
if ($event->authed_page_matches("regen_thumb/one")) {
|
||||
if ($event->page_matches("regen_thumb", method: "POST", permission: Permissions::DELETE_IMAGE)) {
|
||||
if ($event->page_matches("regen_thumb/one")) {
|
||||
$image = Image::by_id(int_escape($event->get_arg(0)));
|
||||
|
||||
$this->regenerate_thumbnail($image);
|
||||
|
|
|
@ -13,12 +13,7 @@ class ReplaceFile extends Extension
|
|||
{
|
||||
global $cache, $page, $user;
|
||||
|
||||
if ($event->page_matches("replace")) {
|
||||
if (!$user->can(Permissions::REPLACE_IMAGE)) {
|
||||
$this->theme->display_error(403, "Error", "{$user->name} doesn't have permission to replace images");
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event->page_matches("replace", permission: Permissions::REPLACE_IMAGE)) {
|
||||
$image_id = int_escape($event->get_arg(0));
|
||||
$image = Image::by_id($image_id);
|
||||
if (is_null($image)) {
|
||||
|
@ -28,6 +23,7 @@ class ReplaceFile extends Extension
|
|||
if($event->method == "GET") {
|
||||
$this->theme->display_replace_page($page, $image_id);
|
||||
} elseif($event->method == "POST") {
|
||||
$user->ensure_authed();
|
||||
if (!empty($event->get_POST("url"))) {
|
||||
$tmp_filename = shm_tempnam("transload");
|
||||
fetch_url($event->req_POST("url"), $tmp_filename);
|
||||
|
|
|
@ -52,27 +52,24 @@ class ReportImage extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
if ($event->page_matches("image_report")) {
|
||||
if ($event->get_arg(0) == "add") {
|
||||
if ($event->page_matches("image_report/add")) {
|
||||
$image_id = int_escape($event->req_POST('image_id'));
|
||||
send_event(new AddReportedImageEvent(new ImageReport($image_id, $user->id, $event->req_POST('reason'))));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("post/view/$image_id"));
|
||||
} elseif ($event->get_arg(0) == "remove") {
|
||||
if ($user->can(Permissions::VIEW_IMAGE_REPORT)) {
|
||||
send_event(new RemoveReportedImageEvent(int_escape($event->req_POST('id'))));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("image_report/list"));
|
||||
}
|
||||
} elseif ($event->get_arg(0) == "remove_reports_by" && $user->check_auth_token()) {
|
||||
if ($user->can(Permissions::VIEW_IMAGE_REPORT)) {
|
||||
$this->delete_reports_by(int_escape($event->req_POST('user_id')));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link());
|
||||
}
|
||||
} elseif ($event->get_arg(0) == "list") {
|
||||
if ($user->can(Permissions::VIEW_IMAGE_REPORT)) {
|
||||
$this->theme->display_reported_images($page, $this->get_reported_images());
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("image_report/remove", method: "POST", permission: Permissions::VIEW_IMAGE_REPORT)) {
|
||||
send_event(new RemoveReportedImageEvent(int_escape($event->req_POST('id'))));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("image_report/list"));
|
||||
}
|
||||
if ($event->page_matches("image_report/remove_reports_by", method: "POST", permission: Permissions::VIEW_IMAGE_REPORT)) {
|
||||
$this->delete_reports_by(int_escape($event->req_POST('user_id')));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link());
|
||||
}
|
||||
if ($event->page_matches("image_report/list", permission: Permissions::VIEW_IMAGE_REPORT)) {
|
||||
$this->theme->display_reported_images($page, $this->get_reported_images());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ class ResizeImage extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->authed_page_matches("resize") && $user->can(Permissions::EDIT_FILES)) {
|
||||
if ($event->page_matches("resize", method: "POST", permission: Permissions::EDIT_FILES)) {
|
||||
// Try to get the image ID
|
||||
$image_id = int_escape(null_throws($event->get_arg(0)));
|
||||
$image = Image::by_id($image_id);
|
||||
|
|
|
@ -59,7 +59,7 @@ class RotateImage extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->authed_page_matches("rotate") && $user->can(Permissions::EDIT_FILES)) {
|
||||
if ($event->page_matches("rotate", method: "POST", permission: Permissions::EDIT_FILES)) {
|
||||
// Try to get the image ID
|
||||
$image_id = int_escape(null_throws($event->get_arg(0)));
|
||||
$image = Image::by_id($image_id);
|
||||
|
|
|
@ -129,10 +129,7 @@ class S3 extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $config, $page, $user;
|
||||
if (
|
||||
$event->authed_page_matches("s3/sync") &&
|
||||
$user->can(Permissions::DELETE_IMAGE)
|
||||
) {
|
||||
if ($event->page_matches("s3/sync", method: "POST", permission: Permissions::DELETE_IMAGE)) {
|
||||
$id = int_escape($event->get_arg(0));
|
||||
$this->sync_post(Image::by_id($id));
|
||||
log_info("s3", "Manual resync for >>$id", "File re-sync'ed");
|
||||
|
|
|
@ -336,23 +336,19 @@ class Setup extends Extension
|
|||
$page->set_data("ok");
|
||||
}
|
||||
|
||||
if ($event->page_matches("setup")) {
|
||||
if (!$user->can(Permissions::CHANGE_SETTING)) {
|
||||
$this->theme->display_permission_denied();
|
||||
} else {
|
||||
if ($event->count_args() == 0) {
|
||||
$panel = new SetupPanel($config);
|
||||
send_event(new SetupBuildingEvent($panel));
|
||||
$this->theme->display_page($page, $panel);
|
||||
} elseif ($event->get_arg(0) == "save" && $user->check_auth_token()) {
|
||||
send_event(new ConfigSaveEvent($config, $event->POST));
|
||||
$config->save();
|
||||
$page->flash("Config saved");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("setup"));
|
||||
} elseif ($event->get_arg(0) == "advanced") {
|
||||
$this->theme->display_advanced($page, $config->values);
|
||||
}
|
||||
if ($event->page_matches("setup", permission: Permissions::CHANGE_SETTING)) {
|
||||
if ($event->count_args() == 0) {
|
||||
$panel = new SetupPanel($config);
|
||||
send_event(new SetupBuildingEvent($panel));
|
||||
$this->theme->display_page($page, $panel);
|
||||
} elseif ($event->get_arg(0) == "save" && $user->check_auth_token()) {
|
||||
send_event(new ConfigSaveEvent($config, $event->POST));
|
||||
$config->save();
|
||||
$page->flash("Config saved");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("setup"));
|
||||
} elseif ($event->get_arg(0) == "advanced") {
|
||||
$this->theme->display_advanced($page, $config->values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,17 +18,17 @@ class SetupTest extends ShimmiePHPUnitTestCase
|
|||
|
||||
public function testAuthAnon(): void
|
||||
{
|
||||
$this->get_page('setup');
|
||||
$this->assert_response(403);
|
||||
$this->assert_title("Permission Denied");
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->get_page('setup');
|
||||
});
|
||||
}
|
||||
|
||||
public function testAuthUser(): void
|
||||
{
|
||||
$this->log_in_as_user();
|
||||
$this->get_page('setup');
|
||||
$this->assert_response(403);
|
||||
$this->assert_title("Permission Denied");
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->get_page('setup');
|
||||
});
|
||||
}
|
||||
|
||||
public function testAuthAdmin(): void
|
||||
|
|
|
@ -32,15 +32,11 @@ class SourceHistory extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->page_matches("source_history/revert")) {
|
||||
if ($event->page_matches("source_history/revert", method: "POST", permission: Permissions::EDIT_IMAGE_TAG)) {
|
||||
// this is a request to revert to a previous version of the source
|
||||
if ($user->can(Permissions::EDIT_IMAGE_TAG)) {
|
||||
$this->process_revert_request((int)$event->req_POST('revert'));
|
||||
}
|
||||
} elseif ($event->page_matches("source_history/bulk_revert")) {
|
||||
if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG) && $user->check_auth_token()) {
|
||||
$this->process_bulk_revert_request();
|
||||
}
|
||||
$this->process_revert_request((int)$event->req_POST('revert'));
|
||||
} elseif ($event->page_matches("source_history/bulk_revert", method: "POST", permission: Permissions::BULK_EDIT_IMAGE_TAG)) {
|
||||
$this->process_bulk_revert_request();
|
||||
} elseif ($event->page_matches("source_history/all")) {
|
||||
$page_id = int_escape($event->get_arg(0));
|
||||
$this->theme->display_global_page($page, $this->get_global_source_history($page_id), $page_id);
|
||||
|
|
|
@ -69,11 +69,11 @@ class TagCategories extends Extension
|
|||
{
|
||||
global $database, $page, $user;
|
||||
|
||||
if ($event->page_matches("tags/categories")) {
|
||||
if ($user->can(Permissions::EDIT_TAG_CATEGORIES)) {
|
||||
$this->page_update();
|
||||
$this->theme->show_tag_categories($page, $database->get_all('SELECT * FROM image_tag_categories'));
|
||||
}
|
||||
if ($event->page_matches("tags/categories", method: "GET")) {
|
||||
$this->theme->show_tag_categories($page, $database->get_all('SELECT * FROM image_tag_categories'));
|
||||
}
|
||||
if ($event->page_matches("tags/categories", method: "POST", permission: Permissions::EDIT_TAG_CATEGORIES)) {
|
||||
$this->page_update();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -146,22 +146,18 @@ class TagEdit extends Extension
|
|||
public function onPageRequest(PageRequestEvent $event): void
|
||||
{
|
||||
global $user, $page;
|
||||
if ($event->page_matches("tag_edit")) {
|
||||
if ($event->page_matches("tag_edit", method: "POST", permission: Permissions::MASS_TAG_EDIT)) {
|
||||
if ($event->get_arg(0) == "replace") {
|
||||
if ($user->can(Permissions::MASS_TAG_EDIT)) {
|
||||
$search = $event->req_POST('search');
|
||||
$replace = $event->req_POST('replace');
|
||||
$this->mass_tag_edit($search, $replace, true);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("admin"));
|
||||
}
|
||||
$search = $event->req_POST('search');
|
||||
$replace = $event->req_POST('replace');
|
||||
$this->mass_tag_edit($search, $replace, true);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("admin"));
|
||||
}
|
||||
if ($event->get_arg(0) == "mass_source_set") {
|
||||
if ($user->can(Permissions::MASS_TAG_EDIT)) {
|
||||
$this->mass_source_edit($event->req_POST('tags'), $event->req_POST('source'));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(search_link());
|
||||
}
|
||||
$this->mass_source_edit($event->req_POST('tags'), $event->req_POST('source'));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(search_link());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,15 +26,11 @@ class TagHistory extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->page_matches("tag_history/revert")) {
|
||||
if ($event->page_matches("tag_history/revert", method: "POST", permission: Permissions::EDIT_IMAGE_TAG)) {
|
||||
// this is a request to revert to a previous version of the tags
|
||||
if ($user->can(Permissions::EDIT_IMAGE_TAG)) {
|
||||
$this->process_revert_request((int)$event->req_POST('revert'));
|
||||
}
|
||||
} elseif ($event->page_matches("tag_history/bulk_revert")) {
|
||||
if ($user->can(Permissions::BULK_EDIT_IMAGE_TAG) && $user->check_auth_token()) {
|
||||
$this->process_bulk_revert_request();
|
||||
}
|
||||
$this->process_revert_request((int)$event->req_POST('revert'));
|
||||
} elseif ($event->page_matches("tag_history/bulk_revert", method: "POST", permission: Permissions::BULK_EDIT_IMAGE_TAG)) {
|
||||
$this->process_bulk_revert_request();
|
||||
} elseif ($event->page_matches("tag_history/all")) {
|
||||
$page_id = int_escape($event->get_arg(0));
|
||||
$this->theme->display_global_page($page, $this->get_global_tag_history($page_id), $page_id);
|
||||
|
|
|
@ -67,38 +67,32 @@ class Tips extends Extension
|
|||
|
||||
$this->getTip();
|
||||
|
||||
if ($event->page_matches("tips") && $user->can(Permissions::TIPS_ADMIN)) {
|
||||
switch ($event->get_arg(0)) {
|
||||
case "list":
|
||||
$this->manageTips();
|
||||
$this->getAll();
|
||||
break;
|
||||
case "save":
|
||||
if ($user->check_auth_token()) {
|
||||
send_event(new CreateTipEvent(
|
||||
$event->get_POST("enable") == "on",
|
||||
$event->req_POST("image"),
|
||||
$event->req_POST("text")
|
||||
));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("tips/list"));
|
||||
}
|
||||
break;
|
||||
case "status":
|
||||
// FIXME: HTTP GET CSRF
|
||||
$tipID = int_escape($event->get_arg(1));
|
||||
$this->setStatus($tipID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("tips/list"));
|
||||
break;
|
||||
case "delete":
|
||||
// FIXME: HTTP GET CSRF
|
||||
$tipID = int_escape($event->get_arg(1));
|
||||
send_event(new DeleteTipEvent($tipID));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("tips/list"));
|
||||
break;
|
||||
}
|
||||
if ($event->page_matches("tips/list", permission: Permissions::TIPS_ADMIN)) {
|
||||
$this->manageTips();
|
||||
$this->getAll();
|
||||
}
|
||||
if ($event->page_matches("tips/save", method: "POST", permission: Permissions::TIPS_ADMIN)) {
|
||||
send_event(new CreateTipEvent(
|
||||
$event->get_POST("enable") == "on",
|
||||
$event->req_POST("image"),
|
||||
$event->req_POST("text")
|
||||
));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("tips/list"));
|
||||
}
|
||||
if ($event->page_matches("tips/status", permission: Permissions::TIPS_ADMIN)) {
|
||||
// FIXME: HTTP GET CSRF
|
||||
$tipID = int_escape($event->get_arg(1));
|
||||
$this->setStatus($tipID);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("tips/list"));
|
||||
}
|
||||
if ($event->page_matches("tips/delete", permission: Permissions::TIPS_ADMIN)) {
|
||||
// FIXME: HTTP GET CSRF
|
||||
$tipID = int_escape($event->get_arg(1));
|
||||
send_event(new DeleteTipEvent($tipID));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("tips/list"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ class TranscodeImage extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->page_matches("transcode") && $user->can(Permissions::EDIT_FILES)) {
|
||||
if ($event->page_matches("transcode", method: "POST", permission: Permissions::EDIT_FILES)) {
|
||||
$image_id = int_escape($event->get_arg(0));
|
||||
$image_obj = Image::by_id($image_id);
|
||||
if (is_null($image_obj)) {
|
||||
|
|
|
@ -101,7 +101,7 @@ class TranscodeVideo extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->page_matches("transcode_video") && $user->can(Permissions::EDIT_FILES)) {
|
||||
if ($event->page_matches("transcode_video", method: "POST", permission: Permissions::EDIT_FILES)) {
|
||||
$image_id = int_escape($event->get_arg(0));
|
||||
$image_obj = Image::by_id($image_id);
|
||||
if (is_null($image_obj)) {
|
||||
|
|
|
@ -29,7 +29,7 @@ class Trash extends Extension
|
|||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($event->page_matches("trash_restore") && $user->can(Permissions::VIEW_TRASH)) {
|
||||
if ($event->page_matches("trash_restore", method: "POST", permission: Permissions::VIEW_TRASH)) {
|
||||
$image_id = int_escape(null_throws($event->get_arg(0)));
|
||||
self::set_trash($image_id, false);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
|
|
|
@ -36,27 +36,29 @@ class Update extends Extension
|
|||
global $user, $page;
|
||||
$sha = $event->get_GET('sha');
|
||||
|
||||
if ($user->can(Permissions::EDIT_FILES) && $sha) {
|
||||
if ($event->page_matches("update/download")) {
|
||||
$ok = $this->download_shimmie($sha);
|
||||
// FIXME: use POST
|
||||
if ($event->page_matches("update/download", permission: Permissions::EDIT_FILES)) {
|
||||
assert(!is_null($sha));
|
||||
$ok = $this->download_shimmie($sha);
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
if ($ok) {
|
||||
$page->set_redirect(make_link("update/update", "sha=".$sha));
|
||||
} else {
|
||||
$page->set_redirect(make_link("admin"));
|
||||
} //TODO: Show error?
|
||||
} elseif ($event->page_matches("update/update")) {
|
||||
$ok = $this->update_shimmie($sha);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
if ($ok) {
|
||||
$page->set_redirect(make_link("update/update", "sha=".$sha));
|
||||
} else {
|
||||
$page->set_redirect(make_link("admin"));
|
||||
} //TODO: Show error?
|
||||
}
|
||||
if ($event->page_matches("update/update", permission: Permissions::EDIT_FILES)) {
|
||||
assert(!is_null($sha));
|
||||
$ok = $this->update_shimmie($sha);
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
if ($ok) {
|
||||
$page->set_redirect(make_link("admin"));
|
||||
} //TODO: Show success?
|
||||
else {
|
||||
$page->set_redirect(make_link("admin"));
|
||||
} //TODO: Show error?
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
if ($ok) {
|
||||
$page->set_redirect(make_link("admin"));
|
||||
} //TODO: Show success?
|
||||
else {
|
||||
$page->set_redirect(make_link("admin"));
|
||||
} //TODO: Show error?
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -216,11 +216,7 @@ class Upload extends Extension
|
|||
}
|
||||
}
|
||||
|
||||
if ($event->page_matches("upload")) {
|
||||
if (!$user->can(Permissions::CREATE_IMAGE)) {
|
||||
$this->theme->display_error(403, "Error", "{$user->name} doesn't have permission to upload images");
|
||||
return;
|
||||
}
|
||||
if ($event->page_matches("upload", permission: Permissions::CREATE_IMAGE)) {
|
||||
if ($this->is_full) {
|
||||
$this->theme->display_error(507, "Error", "Can't upload images: disk nearly full");
|
||||
return;
|
||||
|
|
|
@ -165,92 +165,154 @@ class UserPage extends Extension
|
|||
|
||||
if ($user->can(Permissions::VIEW_HELLBANNED)) {
|
||||
$page->add_html_header("<style>DIV.hb, TR.hb TD {border: 1px solid red !important;}</style>");
|
||||
} elseif(!$user->can(Permissions::HELLBANNED)) {
|
||||
} elseif (!$user->can(Permissions::HELLBANNED)) {
|
||||
$page->add_html_header("<style>.hb {display: none !important;}</style>");
|
||||
}
|
||||
|
||||
if ($event->page_matches("user_admin")) {
|
||||
if ($event->get_arg(0) == "login") {
|
||||
if ($event->method == "POST") {
|
||||
$this->page_login($event->req_POST('user'), $event->req_POST('pass'));
|
||||
} else {
|
||||
$this->theme->display_login_page($page);
|
||||
}
|
||||
} elseif ($event->get_arg(0) == "recover") {
|
||||
$this->page_recover($event->req_POST('username'));
|
||||
} elseif ($event->get_arg(0) == "create") {
|
||||
$this->page_create($event);
|
||||
} elseif ($event->get_arg(0) == "create_other") {
|
||||
send_event(new UserCreationEvent(
|
||||
if ($event->page_matches("user_admin/login", method: "GET")) {
|
||||
$this->theme->display_login_page($page);
|
||||
}
|
||||
if ($event->page_matches("user_admin/login", method: "POST", authed: false)) {
|
||||
$this->page_login($event->req_POST('user'), $event->req_POST('pass'));
|
||||
}
|
||||
if ($event->page_matches("user_admin/recover", method: "POST")) {
|
||||
$this->page_recover($event->req_POST('username'));
|
||||
}
|
||||
if ($event->page_matches("user_admin/create", method: "GET", permission: Permissions::CREATE_USER)) {
|
||||
global $config, $page, $user;
|
||||
if (!$config->get_bool("login_signup_enabled")) {
|
||||
$this->theme->display_signups_disabled($page);
|
||||
return;
|
||||
}
|
||||
$this->theme->display_signup_page($page);
|
||||
}
|
||||
if ($event->page_matches("user_admin/create", method: "POST", authed: false, permission: Permissions::CREATE_USER)) {
|
||||
global $config, $page, $user;
|
||||
if (!$config->get_bool("login_signup_enabled")) {
|
||||
$this->theme->display_signups_disabled($page);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$uce = send_event(
|
||||
new UserCreationEvent(
|
||||
$event->req_POST('name'),
|
||||
$event->req_POST('pass1'),
|
||||
$event->req_POST('pass2'),
|
||||
$event->req_POST('email'),
|
||||
true
|
||||
)
|
||||
);
|
||||
$this->set_login_cookie($uce->username);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("user"));
|
||||
} catch (UserCreationException $ex) {
|
||||
$this->theme->display_error(400, "User Creation Error", $ex->getMessage());
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("user_admin/create_other", method: "POST", permission: Permissions::CREATE_OTHER_USER)) {
|
||||
send_event(
|
||||
new UserCreationEvent(
|
||||
$event->req_POST("name"),
|
||||
$event->req_POST("pass1"),
|
||||
$event->req_POST("pass1"),
|
||||
$event->req_POST("email"),
|
||||
false
|
||||
));
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("admin"));
|
||||
$page->flash("Created new user");
|
||||
} elseif ($event->get_arg(0) == "list") {
|
||||
$t = new UserTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
if ($user->can(Permissions::DELETE_USER)) {
|
||||
$col = new TextColumn("email", "Email");
|
||||
// $t->columns[] = $col;
|
||||
array_splice($t->columns, 2, 0, [$col]);
|
||||
}
|
||||
$this->theme->display_crud("Users", $t->table($t->query()), $t->paginator());
|
||||
} elseif ($event->get_arg(0) == "classes") {
|
||||
$this->theme->display_user_classes(
|
||||
$page,
|
||||
UserClass::$known_classes,
|
||||
(new \ReflectionClass(Permissions::class))->getReflectionConstants()
|
||||
);
|
||||
} elseif ($event->get_arg(0) == "logout") {
|
||||
$this->page_logout();
|
||||
)
|
||||
);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("admin"));
|
||||
$page->flash("Created new user");
|
||||
}
|
||||
if ($event->page_matches("user_admin/list", method: "GET")) {
|
||||
$t = new UserTable($database->raw_db());
|
||||
$t->token = $user->get_auth_token();
|
||||
$t->inputs = $event->GET;
|
||||
if ($user->can(Permissions::DELETE_USER)) {
|
||||
$col = new TextColumn("email", "Email");
|
||||
// $t->columns[] = $col;
|
||||
array_splice($t->columns, 2, 0, [$col]);
|
||||
}
|
||||
$this->theme->display_crud("Users", $t->table($t->query()), $t->paginator());
|
||||
}
|
||||
if ($event->page_matches("user_admin/classes", method: "GET")) {
|
||||
$this->theme->display_user_classes(
|
||||
$page,
|
||||
UserClass::$known_classes,
|
||||
(new \ReflectionClass(Permissions::class))->getReflectionConstants()
|
||||
);
|
||||
}
|
||||
if ($event->page_matches("user_admin/logout", method: "GET")) {
|
||||
// FIXME: security
|
||||
$this->page_logout();
|
||||
}
|
||||
|
||||
if (!$user->check_auth_token()) {
|
||||
return;
|
||||
} elseif ($event->get_arg(0) == "change_name") {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists',
|
||||
'name' => 'user_name',
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
$this->change_name_wrapper($duser, $input['name']);
|
||||
} elseif ($event->get_arg(0) == "change_pass") {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists',
|
||||
'pass1' => 'password',
|
||||
'pass2' => 'password',
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
$this->change_password_wrapper($duser, $input['pass1'], $input['pass2']);
|
||||
} elseif ($event->get_arg(0) == "change_email") {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists',
|
||||
'address' => 'email',
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
$this->change_email_wrapper($duser, $input['address']);
|
||||
} elseif ($event->get_arg(0) == "change_class") {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists',
|
||||
'class' => 'user_class',
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
$this->change_class_wrapper($duser, $input['class']);
|
||||
} elseif ($event->get_arg(0) == "delete_user") {
|
||||
$this->delete_user(
|
||||
$page,
|
||||
int_escape($event->req_POST('id')),
|
||||
$event->get_POST("with_images") == "on",
|
||||
$event->get_POST("with_comments") == "on"
|
||||
);
|
||||
if ($event->page_matches("user_admin/change_name", method: "POST", permission: Permissions::EDIT_USER_NAME)) {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists',
|
||||
'name' => 'user_name',
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
if ($this->user_can_edit_user($user, $duser)) {
|
||||
$duser->set_name($input['name']);
|
||||
$page->flash("Username changed");
|
||||
// TODO: set login cookie if user changed themselves
|
||||
$this->redirect_to_user($duser);
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("user_admin/change_pass", method: "POST")) {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists',
|
||||
'pass1' => 'password',
|
||||
'pass2' => 'password',
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
if ($this->user_can_edit_user($user, $duser)) {
|
||||
if ($input['pass1'] != $input['pass2']) {
|
||||
throw new UserErrorException("Passwords don't match");
|
||||
} else {
|
||||
// FIXME: send_event()
|
||||
$duser->set_password($input['pass1']);
|
||||
if ($duser->id == $user->id) {
|
||||
$this->set_login_cookie($duser->name);
|
||||
}
|
||||
$page->flash("Password changed");
|
||||
$this->redirect_to_user($duser);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("user_admin/change_email", method: "POST")) {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists',
|
||||
'address' => 'email',
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
if ($this->user_can_edit_user($user, $duser)) {
|
||||
$duser->set_email($input['address']);
|
||||
$page->flash("Email changed");
|
||||
$this->redirect_to_user($duser);
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("user_admin/change_class", method: "POST")) {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists',
|
||||
'class' => 'user_class',
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
// hard-coded that only admins can change people's classes
|
||||
if ($user->class->name == "admin") {
|
||||
$duser->set_class($input['class']);
|
||||
$page->flash("Class changed");
|
||||
$this->redirect_to_user($duser);
|
||||
}
|
||||
}
|
||||
if ($event->page_matches("user_admin/delete_user", method: "POST", permission: Permissions::DELETE_USER)) {
|
||||
$this->delete_user(
|
||||
$page,
|
||||
int_escape($event->req_POST('id')),
|
||||
$event->get_POST("with_images") == "on",
|
||||
$event->get_POST("with_comments") == "on"
|
||||
);
|
||||
}
|
||||
|
||||
if ($event->page_matches("user")) {
|
||||
$display_user = ($event->count_args() == 0) ? $user : User::by_name($event->get_arg(0));
|
||||
|
@ -267,7 +329,7 @@ class UserPage extends Extension
|
|||
$this->theme->display_error(
|
||||
404,
|
||||
"No Such User",
|
||||
"If you typed the ID by hand, try again; if you came from a link on this ".
|
||||
"If you typed the ID by hand, try again; if you came from a link on this " .
|
||||
"site, it might be bug report time..."
|
||||
);
|
||||
}
|
||||
|
@ -294,13 +356,14 @@ class UserPage extends Extension
|
|||
$av = $event->display_user->get_avatar_html();
|
||||
if ($av) {
|
||||
$event->add_stats($av, 0);
|
||||
} elseif ((
|
||||
$config->get_string("avatar_host") == "gravatar"
|
||||
) &&
|
||||
} elseif (
|
||||
(
|
||||
$config->get_string("avatar_host") == "gravatar"
|
||||
) &&
|
||||
($user->id == $event->display_user->id)
|
||||
) {
|
||||
$event->add_stats(
|
||||
"No avatar? This gallery uses <a href='https://gravatar.com'>Gravatar</a> for avatar hosting, use the".
|
||||
"No avatar? This gallery uses <a href='https://gravatar.com'>Gravatar</a> for avatar hosting, use the" .
|
||||
"<br>same email address here and there to have your avatar synced<br>",
|
||||
0
|
||||
);
|
||||
|
@ -459,8 +522,8 @@ class UserPage extends Extension
|
|||
}
|
||||
if (!preg_match('/^[a-zA-Z0-9-_]+$/', $name)) {
|
||||
throw new UserCreationException(
|
||||
"Username contains invalid characters. Allowed characters are ".
|
||||
"letters, numbers, dash, and underscore"
|
||||
"Username contains invalid characters. Allowed characters are " .
|
||||
"letters, numbers, dash, and underscore"
|
||||
);
|
||||
}
|
||||
if (User::by_name($name)) {
|
||||
|
@ -472,7 +535,7 @@ class UserPage extends Extension
|
|||
if ($event->password != $event->password2) {
|
||||
throw new UserCreationException("Passwords don't match");
|
||||
}
|
||||
if(
|
||||
if (
|
||||
// Users who can create other users (ie, admins) are exempt
|
||||
// from the email requirement
|
||||
!$user->can(Permissions::CREATE_OTHER_USER) &&
|
||||
|
@ -496,8 +559,10 @@ class UserPage extends Extension
|
|||
public static function has_user_query(array $context): bool
|
||||
{
|
||||
foreach ($context as $term) {
|
||||
if (preg_match(self::USER_SEARCH_REGEX, $term) ||
|
||||
preg_match(self::USER_ID_SEARCH_REGEX, $term)) {
|
||||
if (
|
||||
preg_match(self::USER_SEARCH_REGEX, $term) ||
|
||||
preg_match(self::USER_ID_SEARCH_REGEX, $term)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -517,7 +582,7 @@ class UserPage extends Extension
|
|||
$duser = User::by_name($matches[2]);
|
||||
if (is_null($duser)) {
|
||||
throw new SearchTermParseException(
|
||||
"Can't find the user named ".html_escape($matches[2])
|
||||
"Can't find the user named " . html_escape($matches[2])
|
||||
);
|
||||
}
|
||||
$event->add_querylet(new Querylet("images.owner_id {$matches[1]}= {$duser->id}"));
|
||||
|
@ -535,7 +600,7 @@ class UserPage extends Extension
|
|||
if ($event->key === HelpPages::SEARCH) {
|
||||
$block = new Block();
|
||||
$block->header = "Users";
|
||||
$block->body = (string)$this->theme->get_help_html();
|
||||
$block->body = (string) $this->theme->get_help_html();
|
||||
$event->add_block($block);
|
||||
}
|
||||
}
|
||||
|
@ -606,38 +671,6 @@ class UserPage extends Extension
|
|||
}
|
||||
}
|
||||
|
||||
private function page_create(PageRequestEvent $event): void
|
||||
{
|
||||
global $config, $page, $user;
|
||||
if (!$user->can(Permissions::CREATE_USER)) {
|
||||
$this->theme->display_error(403, "Account creation blocked", "Account creation is currently disabled");
|
||||
return;
|
||||
}
|
||||
if (!$config->get_bool("login_signup_enabled")) {
|
||||
$this->theme->display_signups_disabled($page);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($event->method == "GET") {
|
||||
$this->theme->display_signup_page($page);
|
||||
} else {
|
||||
try {
|
||||
$uce = send_event(new UserCreationEvent(
|
||||
$event->req_POST('name'),
|
||||
$event->req_POST('pass1'),
|
||||
$event->req_POST('pass2'),
|
||||
$event->req_POST('email'),
|
||||
true
|
||||
));
|
||||
$this->set_login_cookie($uce->username);
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("user"));
|
||||
} catch (UserCreationException $ex) {
|
||||
$this->theme->display_error(400, "User Creation Error", $ex->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function create_user(UserCreationEvent $event): User
|
||||
{
|
||||
global $database;
|
||||
|
@ -666,7 +699,7 @@ class UserPage extends Extension
|
|||
global $config;
|
||||
$addr = get_session_ip($config);
|
||||
$hash = User::by_name($name)->passhash;
|
||||
return md5($hash.$addr);
|
||||
return md5($hash . $addr);
|
||||
}
|
||||
|
||||
private function set_login_cookie(string $name): void
|
||||
|
@ -720,64 +753,6 @@ class UserPage extends Extension
|
|||
}
|
||||
}
|
||||
|
||||
private function change_name_wrapper(User $duser, string $name): void
|
||||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($user->can(Permissions::EDIT_USER_NAME) && $this->user_can_edit_user($user, $duser)) {
|
||||
$duser->set_name($name);
|
||||
$page->flash("Username changed");
|
||||
// TODO: set login cookie if user changed themselves
|
||||
$this->redirect_to_user($duser);
|
||||
} else {
|
||||
$this->theme->display_error(400, "Error", "Permission denied");
|
||||
}
|
||||
}
|
||||
|
||||
private function change_password_wrapper(User $duser, string $pass1, string $pass2): void
|
||||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($this->user_can_edit_user($user, $duser)) {
|
||||
if ($pass1 != $pass2) {
|
||||
$this->theme->display_error(400, "Error", "Passwords don't match");
|
||||
} else {
|
||||
// FIXME: send_event()
|
||||
$duser->set_password($pass1);
|
||||
|
||||
if ($duser->id == $user->id) {
|
||||
$this->set_login_cookie($duser->name);
|
||||
}
|
||||
|
||||
$page->flash("Password changed");
|
||||
$this->redirect_to_user($duser);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function change_email_wrapper(User $duser, string $address): void
|
||||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($this->user_can_edit_user($user, $duser)) {
|
||||
$duser->set_email($address);
|
||||
|
||||
$page->flash("Email changed");
|
||||
$this->redirect_to_user($duser);
|
||||
}
|
||||
}
|
||||
|
||||
private function change_class_wrapper(User $duser, string $class): void
|
||||
{
|
||||
global $page, $user;
|
||||
|
||||
if ($user->class->name == "admin") {
|
||||
$duser->set_class($class);
|
||||
$page->flash("Class changed");
|
||||
$this->redirect_to_user($duser);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, int>
|
||||
*/
|
||||
|
@ -837,47 +812,43 @@ class UserPage extends Extension
|
|||
$page->set_heading("Error");
|
||||
$page->add_block(new NavBlock());
|
||||
|
||||
if (!$user->can(Permissions::DELETE_USER)) {
|
||||
$page->add_block(new Block("Not Admin", "Only admins can delete accounts"));
|
||||
} else {
|
||||
$duser = User::by_id($uid);
|
||||
log_warning("user", "Deleting user #{$uid} (@{$duser->name})");
|
||||
$duser = User::by_id($uid);
|
||||
log_warning("user", "Deleting user #{$uid} (@{$duser->name})");
|
||||
|
||||
if ($with_images) {
|
||||
log_warning("user", "Deleting user #{$uid} (@{$duser->name})'s uploads");
|
||||
$image_ids = $database->get_col("SELECT id FROM images WHERE owner_id = :owner_id", ["owner_id" => $uid]);
|
||||
foreach ($image_ids as $image_id) {
|
||||
$image = Image::by_id((int)$image_id);
|
||||
if ($image) {
|
||||
send_event(new ImageDeletionEvent($image));
|
||||
}
|
||||
if ($with_images) {
|
||||
log_warning("user", "Deleting user #{$uid} (@{$duser->name})'s uploads");
|
||||
$image_ids = $database->get_col("SELECT id FROM images WHERE owner_id = :owner_id", ["owner_id" => $uid]);
|
||||
foreach ($image_ids as $image_id) {
|
||||
$image = Image::by_id((int) $image_id);
|
||||
if ($image) {
|
||||
send_event(new ImageDeletionEvent($image));
|
||||
}
|
||||
} else {
|
||||
$database->execute(
|
||||
"UPDATE images SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id",
|
||||
["new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $uid]
|
||||
);
|
||||
}
|
||||
|
||||
if ($with_comments) {
|
||||
log_warning("user", "Deleting user #{$uid} (@{$duser->name})'s comments");
|
||||
$database->execute("DELETE FROM comments WHERE owner_id = :owner_id", ["owner_id" => $uid]);
|
||||
} else {
|
||||
$database->execute(
|
||||
"UPDATE comments SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id",
|
||||
["new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $uid]
|
||||
);
|
||||
}
|
||||
|
||||
send_event(new UserDeletionEvent($uid));
|
||||
|
||||
} else {
|
||||
$database->execute(
|
||||
"DELETE FROM users WHERE id = :id",
|
||||
["id" => $uid]
|
||||
"UPDATE images SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id",
|
||||
["new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $uid]
|
||||
);
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link());
|
||||
}
|
||||
|
||||
if ($with_comments) {
|
||||
log_warning("user", "Deleting user #{$uid} (@{$duser->name})'s comments");
|
||||
$database->execute("DELETE FROM comments WHERE owner_id = :owner_id", ["owner_id" => $uid]);
|
||||
} else {
|
||||
$database->execute(
|
||||
"UPDATE comments SET owner_id = :new_owner_id WHERE owner_id = :old_owner_id",
|
||||
["new_owner_id" => $config->get_int('anon_id'), "old_owner_id" => $uid]
|
||||
);
|
||||
}
|
||||
|
||||
send_event(new UserDeletionEvent($uid));
|
||||
|
||||
$database->execute(
|
||||
"DELETE FROM users WHERE id = :id",
|
||||
["id" => $uid]
|
||||
);
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ class UserPageTest extends ShimmiePHPUnitTestCase
|
|||
{
|
||||
global $page;
|
||||
|
||||
$this->assertException(UserCreationException::class, function () {
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->log_out();
|
||||
$this->post_page('user_admin/create_other', [
|
||||
'name' => 'testnew',
|
||||
|
|
|
@ -125,47 +125,34 @@ class UserConfig extends Extension
|
|||
}
|
||||
}
|
||||
|
||||
if ($event->page_matches("user_admin")) {
|
||||
if (!$user->check_auth_token()) {
|
||||
return;
|
||||
}
|
||||
switch ($event->get_arg(0)) {
|
||||
case "reset_api_key":
|
||||
$user_config->set_string(self::API_KEY, "");
|
||||
if ($event->page_matches("user_admin/reset_api_key", method: "POST")) {
|
||||
$user_config->set_string(self::API_KEY, "");
|
||||
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("user"));
|
||||
|
||||
break;
|
||||
}
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("user"));
|
||||
}
|
||||
}
|
||||
|
||||
if ($event->page_matches("user_config")) {
|
||||
if (!$user->can(Permissions::CHANGE_USER_SETTING)) {
|
||||
$this->theme->display_permission_denied();
|
||||
} else {
|
||||
if ($event->count_args() == 0) {
|
||||
$uobe = send_event(new UserOptionsBuildingEvent($user, new SetupPanel($user_config)));
|
||||
$this->theme->display_user_config_page($page, $uobe->user, $uobe->panel);
|
||||
} elseif ($event->get_arg(0) == "save" && $user->check_auth_token()) {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists'
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
if ($event->page_matches("user_config", permission: Permissions::CHANGE_USER_SETTING)) {
|
||||
if ($event->count_args() == 0) {
|
||||
$uobe = send_event(new UserOptionsBuildingEvent($user, new SetupPanel($user_config)));
|
||||
$this->theme->display_user_config_page($page, $uobe->user, $uobe->panel);
|
||||
} elseif ($event->get_arg(0) == "save" && $user->check_auth_token()) {
|
||||
$input = validate_input([
|
||||
'id' => 'user_id,exists'
|
||||
]);
|
||||
$duser = User::by_id($input['id']);
|
||||
|
||||
if ($user->id != $duser->id && !$user->can(Permissions::CHANGE_OTHER_USER_SETTING)) {
|
||||
$this->theme->display_permission_denied();
|
||||
return;
|
||||
}
|
||||
|
||||
$target_config = UserConfig::get_for_user($duser->id);
|
||||
send_event(new ConfigSaveEvent($target_config, $event->POST));
|
||||
$target_config->save();
|
||||
$page->flash("Config saved");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("user_config"));
|
||||
if ($user->id != $duser->id && !$user->can(Permissions::CHANGE_OTHER_USER_SETTING)) {
|
||||
throw new PermissionDeniedException("You do not have permission to change other user's settings");
|
||||
}
|
||||
|
||||
$target_config = UserConfig::get_for_user($duser->id);
|
||||
send_event(new ConfigSaveEvent($target_config, $event->POST));
|
||||
$target_config->save();
|
||||
$page->flash("Config saved");
|
||||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("user_config"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,9 @@ class UserConfigTest extends ShimmiePHPUnitTestCase
|
|||
|
||||
public function testUserConfigPage(): void
|
||||
{
|
||||
$this->get_page('user_config');
|
||||
$this->assert_title("Permission Denied");
|
||||
$this->assert_no_text(self::OPTIONS_BLOCK_TITLE);
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->get_page('user_config');
|
||||
});
|
||||
|
||||
$this->log_in_as_user();
|
||||
$this->get_page('user_config');
|
||||
|
|
|
@ -72,7 +72,7 @@ class ViewPost extends Extension
|
|||
} else {
|
||||
$this->theme->display_error(404, "Post not found", "No post in the database has the ID #$image_id");
|
||||
}
|
||||
} elseif ($event->page_matches("post/set")) {
|
||||
} elseif ($event->page_matches("post/set", method: "POST")) {
|
||||
$image_id = int_escape($event->req_POST('image_id'));
|
||||
$image = Image::by_id($image_id);
|
||||
if (!$image->is_locked() || $user->can(Permissions::EDIT_IMAGE_LOCK)) {
|
||||
|
|
|
@ -197,7 +197,7 @@ class Wiki extends Extension
|
|||
if ($this->can_edit($user, $content)) {
|
||||
$this->theme->display_page_editor($page, $content);
|
||||
} else {
|
||||
$this->theme->display_permission_denied();
|
||||
throw new PermissionDeniedException("You are not allowed to edit this page");
|
||||
}
|
||||
} elseif($action == "save" && $user->check_auth_token()) {
|
||||
$rev = int_escape($event->req_POST('revision'));
|
||||
|
@ -214,7 +214,7 @@ class Wiki extends Extension
|
|||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("wiki/$u_title"));
|
||||
} else {
|
||||
$this->theme->display_permission_denied();
|
||||
throw new PermissionDeniedException("You are not allowed to edit this page");
|
||||
}
|
||||
} elseif($action == "delete_revision" && $user->check_auth_token()) {
|
||||
$content = $this->get_page($title);
|
||||
|
@ -225,7 +225,7 @@ class Wiki extends Extension
|
|||
$page->set_mode(PageMode::REDIRECT);
|
||||
$page->set_redirect(make_link("wiki/$u_title"));
|
||||
} else {
|
||||
$this->theme->display_permission_denied();
|
||||
throw new PermissionDeniedException("You are not allowed to edit this page");
|
||||
}
|
||||
} elseif($action == "delete_all" && $user->check_auth_token()) {
|
||||
if ($user->can(Permissions::WIKI_ADMIN)) {
|
||||
|
|
|
@ -22,8 +22,9 @@ class WikiTest extends ShimmiePHPUnitTestCase
|
|||
$this->assert_title("test");
|
||||
$this->assert_text("This is a default page");
|
||||
|
||||
$this->get_page("wiki/test/edit");
|
||||
$this->assert_no_text("Editor");
|
||||
$this->assertException(PermissionDeniedException::class, function () {
|
||||
$this->get_page("wiki/test/edit");
|
||||
});
|
||||
}
|
||||
|
||||
// Admins can edit
|
||||
|
|
10
index.php
10
index.php
|
@ -105,7 +105,15 @@ try {
|
|||
if ($database->is_transaction_open()) {
|
||||
$database->rollback();
|
||||
}
|
||||
_fatal_error($e);
|
||||
if(is_a($e, \Shimmie2\UserErrorException::class)) {
|
||||
$page->set_mode(PageMode::PAGE);
|
||||
$page->set_code($e->http_code);
|
||||
$page->set_title("Error");
|
||||
$page->add_block(new Block(null, \MicroHTML\SPAN($e->getMessage())));
|
||||
$page->display();
|
||||
} else {
|
||||
_fatal_error($e);
|
||||
}
|
||||
$exit_code = 1;
|
||||
} finally {
|
||||
$_tracer->end();
|
||||
|
|
Reference in a new issue