diff --git a/composer.lock b/composer.lock
index dd97dbb2..c5f59c31 100644
--- a/composer.lock
+++ b/composer.lock
@@ -342,16 +342,16 @@
},
{
"name": "shish/ffsphp",
- "version": "v0.0.1",
+ "version": "v0.0.2",
"source": {
"type": "git",
"url": "https://github.com/shish/ffsphp.git",
- "reference": "6b1874cf05b0b6bbdf7b118ca081097d1f830cd7"
+ "reference": "16c98d57c80bb4848f20253c8c1e5fe7f6c5823f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/shish/ffsphp/zipball/6b1874cf05b0b6bbdf7b118ca081097d1f830cd7",
- "reference": "6b1874cf05b0b6bbdf7b118ca081097d1f830cd7",
+ "url": "https://api.github.com/repos/shish/ffsphp/zipball/16c98d57c80bb4848f20253c8c1e5fe7f6c5823f",
+ "reference": "16c98d57c80bb4848f20253c8c1e5fe7f6c5823f",
"shasum": ""
},
"require": {
@@ -380,7 +380,7 @@
],
"description": "A collection of workarounds for stupid PHP things",
"homepage": "https://github.com/shish/ffsphp",
- "time": "2019-11-25T15:37:09+00:00"
+ "time": "2019-11-29T12:00:09+00:00"
},
{
"name": "shish/microcrud",
@@ -429,7 +429,15 @@
"crud",
"generator"
],
+<<<<<<< HEAD
"time": "2019-11-29T02:11:55+00:00"
+=======
+<<<<<<< HEAD
+ "time": "2019-11-29T21:15:17+00:00"
+=======
+ "time": "2019-11-29T10:55:02+00:00"
+>>>>>>> e926b15d5ffeb6f7c0510acacaaa846294212f5c
+>>>>>>> 0a330cd0baebc7f9387fd63a36a88c38d4338a0f
},
{
"name": "shish/microhtml",
diff --git a/core/permissions.php b/core/permissions.php
index 84eb292e..a2eb842b 100644
--- a/core/permissions.php
+++ b/core/permissions.php
@@ -13,6 +13,7 @@ abstract class Permissions
public const VIEW_IP = "view_ip"; # view IP addresses associated with things
public const BAN_IP = "ban_ip";
+ public const CREATE_USER = "create_user";
public const EDIT_USER_NAME = "edit_user_name";
public const EDIT_USER_PASSWORD = "edit_user_password";
public const EDIT_USER_INFO = "edit_user_info"; # email address, etc
diff --git a/core/userclass.php b/core/userclass.php
index e639167d..faf41bbe 100644
--- a/core/userclass.php
+++ b/core/userclass.php
@@ -83,6 +83,7 @@ new UserClass("base", null, [
Permissions::VIEW_IP => false, # view IP addresses associated with things
Permissions::BAN_IP => false,
+ Permissions::CREATE_USER => false,
Permissions::EDIT_USER_NAME => false,
Permissions::EDIT_USER_PASSWORD => false,
Permissions::EDIT_USER_INFO => false, # email address, etc
@@ -163,6 +164,7 @@ new UserClass("ghost", "base", [
// Anonymous users can't do anything by default, but
// the admin might grant them some permissions
new UserClass("anonymous", "base", [
+ Permissions::CREATE_USER => true,
]);
new UserClass("user", "base", [
diff --git a/ext/alias_editor/main.php b/ext/alias_editor/main.php
index 74fb02eb..8fadfd66 100644
--- a/ext/alias_editor/main.php
+++ b/ext/alias_editor/main.php
@@ -1,5 +1,27 @@
table = "aliases";
+ $this->base_query = "SELECT * FROM aliases";
+ $this->primary_key = "oldtag";
+ $this->size = 100;
+ $this->limit = 1000000;
+ $this->columns = [
+ new TextColumn("oldtag", "Old Tag"),
+ new TextColumn("newtag", "New Tag"),
+ ];
+ $this->order_by = ["oldtag"];
+ $this->table_attrs = ["class" => "zebra"];
+ }
+}
+
class AddAliasEvent extends Event
{
/** @var string */
@@ -27,52 +49,36 @@ class AliasEditor extends Extension
if ($event->page_matches("alias")) {
if ($event->get_arg(0) == "add") {
if ($user->can(Permissions::MANAGE_ALIAS_LIST)) {
- if (isset($_POST['oldtag']) && isset($_POST['newtag'])) {
- try {
- $aae = new AddAliasEvent($_POST['oldtag'], $_POST['newtag']);
- send_event($aae);
- $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());
- }
+ $user->ensure_authed();
+ $input = validate_input(["c_oldtag"=>"string", "c_newtag"=>"string"]);
+ try {
+ $aae = new AddAliasEvent($input['c_oldtag'], $input['c_newtag']);
+ send_event($aae);
+ $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)) {
- if (isset($_POST['oldtag'])) {
- $database->execute("DELETE FROM aliases WHERE oldtag=:oldtag", ["oldtag" => $_POST['oldtag']]);
- log_info("alias_editor", "Deleted alias for ".$_POST['oldtag'], "Deleted alias");
-
- $page->set_mode(PageMode::REDIRECT);
- $page->set_redirect(make_link("alias/list"));
- }
+ $user->ensure_authed();
+ $input = validate_input(["d_oldtag"=>"string"]);
+ $database->execute("DELETE FROM aliases WHERE oldtag=:oldtag", ["oldtag" => $input['d_oldtag']]);
+ log_info("alias_editor", "Deleted alias for ".$input['d_oldtag'], "Deleted alias");
+ $page->set_mode(PageMode::REDIRECT);
+ $page->set_redirect(make_link("alias/list"));
}
} elseif ($event->get_arg(0) == "list") {
- if ($event->count_args() == 2) {
- $page_number = $event->get_arg(1);
- if (!is_numeric($page_number)) {
- $page_number = 0;
- } elseif ($page_number <= 0) {
- $page_number = 0;
- } else {
- $page_number--;
- }
- } else {
- $page_number = 0;
+ $t = new AliasTable($database->raw_db());
+ $t->token = $user->get_auth_token();
+ $t->inputs = $_GET;
+ $t->size = $config->get_int('alias_items_per_page', 30);
+ if($user->can(Permissions::MANAGE_ALIAS_LIST)) {
+ $t->create_url = make_link("alias/add");
+ $t->delete_url = make_link("alias/remove");
}
-
- $alias_per_page = $config->get_int('alias_items_per_page', 30);
-
- $query = "SELECT oldtag, newtag FROM aliases ORDER BY newtag ASC LIMIT :limit OFFSET :offset";
- $alias = $database->get_pairs(
- $query,
- ["limit"=>$alias_per_page, "offset"=>$page_number * $alias_per_page]
- );
-
- $total_pages = ceil($database->get_one("SELECT COUNT(*) FROM aliases") / $alias_per_page);
-
- $this->theme->display_aliases($alias, $page_number + 1, $total_pages);
+ $this->theme->display_aliases($t->table($t->query()), $t->paginator());
} elseif ($event->get_arg(0) == "export") {
$page->set_mode(PageMode::DATA);
$page->set_type("text/csv");
diff --git a/ext/alias_editor/theme.php b/ext/alias_editor/theme.php
index 732139d4..3997e2f2 100644
--- a/ext/alias_editor/theme.php
+++ b/ext/alias_editor/theme.php
@@ -7,51 +7,14 @@ class AliasEditorTheme extends Themelet
*
* Note: $can_manage = whether things like "add new alias" should be shown
*/
- public function display_aliases(array $aliases, int $pageNumber, int $totalPages): void
+ public function display_aliases($table, $paginator): void
{
global $page, $user;
$can_manage = $user->can(Permissions::MANAGE_ALIAS_LIST);
- if ($can_manage) {
- $h_action = "
Action ";
- $h_add = "
-
- ".make_form(make_link("alias/add"))."
-
-
-
-
-
- ";
- } else {
- $h_action = "";
- $h_add = "";
- }
-
- $h_aliases = "";
- foreach ($aliases as $old => $new) {
- $h_old = html_escape($old);
- $h_new = "".html_escape($new)." ";
-
- $h_aliases .= "$h_old $h_new ";
- if ($can_manage) {
- $h_aliases .= "
-
- ".make_form(make_link("alias/remove"))."
-
-
-
-
- ";
- }
- $h_aliases .= " ";
- }
$html = "
-
- From To $h_action
- $h_aliases
- $h_add
-
+ $table
+ $paginator
Download as CSV
";
@@ -69,7 +32,5 @@ class AliasEditorTheme extends Themelet
if ($can_manage) {
$page->add_block(new Block("Bulk Upload", $bulk_html, "main", 51));
}
-
- $this->display_paginator($page, "alias/list", null, $pageNumber, $totalPages);
}
}
diff --git a/ext/ipban/main.php b/ext/ipban/main.php
index c059d7b7..1d1cd559 100644
--- a/ext/ipban/main.php
+++ b/ext/ipban/main.php
@@ -23,7 +23,12 @@ class IPBanTable extends Table
$this->limit = 1000000;
$this->columns = [
new InetColumn("ip", "IP"),
- new EnumColumn("mode", "Mode", ["Block"=>"block", "Firewall"=>"firewall", "Ghost"=>"ghost"]),
+ new EnumColumn("mode", "Mode", [
+ "Block"=>"block",
+ "Firewall"=>"firewall",
+ "Ghost"=>"ghost",
+ "Anon Ghost"=>"anon-ghost"
+ ]),
new TextColumn("reason", "Reason"),
new StringColumn("banner", "Banner"),
new DateColumn("added", "Added"),
@@ -35,7 +40,7 @@ class IPBanTable extends Table
];
$this->create_url = make_link("ip_ban/create");
$this->delete_url = make_link("ip_ban/delete");
- $this->table_attrs = ["class" => "zebra"];
+ $this->table_attrs = ["class" => "zebra"];
}
}
@@ -88,95 +93,107 @@ class IPBan extends Extension
{
global $cache, $config, $database, $page, $user, $_shm_user_classes;
- // Get lists of banned IPs and banned networks
+ // Get lists of banned IPs and banned networks
$ips = $cache->get("ip_bans");
$networks = $cache->get("network_bans");
if ($ips === false || $networks === false) {
- $rows = $database->get_pairs("
+ $rows = $database->get_pairs("
SELECT ip, id
FROM bans
WHERE ((expires > CURRENT_TIMESTAMP) OR (expires IS NULL))
");
- $ips = []; # "0.0.0.0" => 123;
- $networks = []; # "0.0.0.0/32" => 456;
- foreach ($rows as $ip => $id) {
- if (strstr($ip, '/')) {
- $networks[$ip] = $id;
- } else {
- $ips[$ip] = $id;
- }
- }
+ $ips = []; # "0.0.0.0" => 123;
+ $networks = []; # "0.0.0.0/32" => 456;
+ foreach ($rows as $ip => $id) {
+ if (strstr($ip, '/')) {
+ $networks[$ip] = $id;
+ } else {
+ $ips[$ip] = $id;
+ }
+ }
- $cache->set("ip_bans", $ips, 600);
- $cache->set("network_bans", $networks, 600);
+ $cache->set("ip_bans", $ips, 60);
+ $cache->set("network_bans", $networks, 60);
}
- // Check if our current IP is in either of the ban lists
+ // Check if our current IP is in either of the ban lists
$remote = $_SERVER['REMOTE_ADDR'];
- $active_ban_id = null;
+ $active_ban_id = null;
if (isset($ips[$remote])) {
$active_ban_id = $ips[$remote];
+ } else {
+ foreach ($networks as $range => $ban_id) {
+ if (ip_in_range($remote, $range)) {
+ $active_ban_id = $ban_id;
+ }
+ }
}
- else {
- foreach ($networks as $range => $ban_id) {
- if (ip_in_range($remote, $range)) {
- $active_ban_id = $ban_id;
- }
- }
- }
- // If an active ban is found, act on it
- if(!is_null($active_ban_id)) {
- $row = $database->get_row("SELECT * FROM bans WHERE id=:id", ["id"=>$active_ban_id]);
+ // If an active ban is found, act on it
+ if (!is_null($active_ban_id)) {
+ $row = $database->get_row("SELECT * FROM bans WHERE id=:id", ["id"=>$active_ban_id]);
+ if (empty($row)) {
+ return;
+ }
- $msg = $config->get_string("ipban_message");
- $msg = str_replace('$IP', $row["ip"], $msg);
- $msg = str_replace('$DATE', $row['expires'], $msg);
- $msg = str_replace('$ADMIN', User::by_id($row['banner_id'])->name, $msg);
- $msg = str_replace('$REASON', $row['reason'], $msg);
- $contact_link = contact_link();
- if (!empty($contact_link)) {
- $msg = str_replace('$CONTACT', "Contact the staff (be sure to include this message) ", $msg);
- } else {
- $msg = str_replace('$CONTACT', "", $msg);
- }
+ $msg = $config->get_string("ipban_message_{$row['mode']}") ?? $config->get_string("ipban_message");
+ $msg = str_replace('$IP', $row["ip"], $msg);
+ $msg = str_replace('$DATE', $row['expires'] ?? 'the end of time', $msg);
+ $msg = str_replace('$ADMIN', User::by_id($row['banner_id'])->name, $msg);
+ $msg = str_replace('$REASON', $row['reason'], $msg);
+ $contact_link = contact_link();
+ if (!empty($contact_link)) {
+ $msg = str_replace('$CONTACT', "Contact the staff (be sure to include this message) ", $msg);
+ } else {
+ $msg = str_replace('$CONTACT', "", $msg);
+ }
+ $msg .= "";
- if($row["mode"] == "ghost") {
- $b = new Block(null, $msg, "main", 0);
- $b->is_content = false;
- $page->add_block($b);
- $event->user->class = $_shm_user_classes["ghost"];
- } else {
- header("HTTP/1.0 403 Forbidden");
- print "$msg";
- exit;
- }
- }
+ if ($row["mode"] == "ghost") {
+ $b = new Block(null, $msg, "main", 0);
+ $b->is_content = false;
+ $page->add_block($b);
+ $page->add_cookie("nocache", "Ghost Banned", time()+60*60*2, "/");
+ $event->user->class = $_shm_user_classes["ghost"];
+ } elseif ($row["mode"] == "anon-ghost") {
+ if ($event->user->is_anonymous()) {
+ $b = new Block(null, $msg, "main", 0);
+ $b->is_content = false;
+ $page->add_block($b);
+ $page->add_cookie("nocache", "Ghost Banned", time()+60*60*2, "/");
+ $event->user->class = $_shm_user_classes["ghost"];
+ }
+ } else {
+ header("HTTP/1.0 403 Forbidden");
+ print "$msg";
+ exit;
+ }
+ }
}
public function onPageRequest(PageRequestEvent $event)
{
if ($event->page_matches("ip_ban")) {
- global $database, $page, $user;
+ 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']));
- flash_message("Ban for {$input['c_ip']} added");
- $page->set_mode(PageMode::REDIRECT);
- $page->set_redirect(make_link("ip_ban/list"));
+ $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']));
+ flash_message("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']));
- flash_message("Ban removed");
- $page->set_mode(PageMode::REDIRECT);
- $page->set_redirect(make_link("ip_ban/list"));
+ $user->ensure_authed();
+ $input = validate_input(["d_id"=>"int"]);
+ send_event(new RemoveIPBanEvent($input['d_id']));
+ flash_message("Ban removed");
+ $page->set_mode(PageMode::REDIRECT);
+ $page->set_redirect(make_link("ip_ban/list"));
} elseif ($event->get_arg(0) == "list") {
- $_GET['c_banner'] = $user->name;
- $_GET['c_added'] = date('Y-m-d');
+ $_GET['c_banner'] = $user->name;
+ $_GET['c_added'] = date('Y-m-d');
$t = new IPBanTable($database->raw_db());
$t->token = $user->get_auth_token();
$t->inputs = $_GET;
@@ -190,8 +207,16 @@ class IPBan extends Extension
public function onSetupBuilding(SetupBuildingEvent $event)
{
+ global $config;
+
$sb = new SetupBlock("IP Ban");
$sb->add_longtext_option("ipban_message", 'Message to show to banned users: (with $IP, $DATE, $ADMIN, $REASON, and $CONTACT)');
+ if ($config->get_string("ipban_message_ghost")) {
+ $sb->add_longtext_option("ipban_message_ghost", 'Message to show to ghost users:');
+ }
+ if ($config->get_string("ipban_message_anon-ghost")) {
+ $sb->add_longtext_option("ipban_message_anon-ghost", 'Message to show to ghost anons:');
+ }
$event->panel->add_block($sb);
}
@@ -218,7 +243,8 @@ class IPBan extends Extension
global $cache, $user, $database;
$sql = "INSERT INTO bans (ip, mode, reason, expires, banner_id) VALUES (:ip, :mode, :reason, :expires, :admin_id)";
$database->Execute($sql, ["ip"=>$event->ip, "mode"=>$event->mode, "reason"=>$event->reason, "expires"=>$event->expires, "admin_id"=>$user->id]);
- $cache->delete("ip_bans_sorted");
+ $cache->delete("ip_bans");
+ $cache->delete("network_bans");
log_info("ipban", "Banned {$event->ip} because '{$event->reason}' until {$event->expires}");
}
@@ -228,7 +254,8 @@ class IPBan extends Extension
$ban = $database->get_row("SELECT * FROM bans WHERE id = :id", ["id"=>$event->id]);
if ($ban) {
$database->Execute("DELETE FROM bans WHERE id = :id", ["id"=>$event->id]);
- $cache->delete("ip_bans_sorted");
+ $cache->delete("ip_bans");
+ $cache->delete("network_bans");
log_info("ipban", "Removed {$ban['ip']}'s ban");
}
}
diff --git a/ext/log_db/main.php b/ext/log_db/main.php
index a8d5644a..2c652335 100644
--- a/ext/log_db/main.php
+++ b/ext/log_db/main.php
@@ -1,5 +1,74 @@
make_link("user/{$row['username']}"), "title"=>$row['address']], $row['username']);
+ }
+ }
+}
+
+class MessageColumn extends TextColumn {
+ public function display($row)
+ {
+ $c = "#000";
+ switch ($row['priority']) {
+ case SCORE_LOG_DEBUG: $c = "#999"; break;
+ case SCORE_LOG_INFO: $c = "#000"; break;
+ case SCORE_LOG_WARNING: $c = "#800"; break;
+ case SCORE_LOG_ERROR: $c = "#C00"; break;
+ case SCORE_LOG_CRITICAL: $c = "#F00"; break;
+ }
+ return SPAN(["style"=>"color: $c"], $this->scan_entities($row[$this->name]));
+ }
+
+ protected function scan_entities($line)
+ {
+ return preg_replace_callback("/Image #(\d+)/s", [$this, "link_image"], $line);
+ }
+
+ protected function link_image($id)
+ {
+ $iid = int_escape($id[1]);
+ return "Image #$iid ";
+ }
+}
+
+class LogTable extends Table
+{
+ public function __construct(\FFSPHP\PDO $db)
+ {
+ parent::__construct($db);
+ $this->table = "score_log";
+ $this->base_query = "SELECT * FROM score_log";
+ $this->size = 100;
+ $this->limit = 1000000;
+ $this->columns = [
+ new DateTimeColumn("date_sent", "Time"),
+ new TextColumn("section", "Module"),
+ new ActorColumn("username_or_address", "User"),
+ new MessageColumn("message", "Message")
+ ];
+ $this->order_by = ["date_sent DESC"];
+ $this->table_attrs = ["class" => "zebra"];
+ }
+}
+
class LogDatabase extends Extension
{
public function onInitExt(InitExtEvent $event)
diff --git a/ext/log_db/theme.php b/ext/log_db/theme.php
index 94d656b8..ee02dc86 100644
--- a/ext/log_db/theme.php
+++ b/ext/log_db/theme.php
@@ -2,133 +2,12 @@
class LogDatabaseTheme extends Themelet
{
- protected function heie($var)
+ public function display_events($table, $paginator)
{
- if (isset($_GET[$var])) {
- return html_escape($_GET[$var]);
- } else {
- return "";
- }
- }
-
- protected function ueie($var)
- {
- if (isset($_GET[$var])) {
- return $var."=".url_escape($_GET[$var]);
- } else {
- return "";
- }
- }
-
- public function display_events($events, $page_num, $page_total)
- {
- $table = "
-
-";
-
global $page;
$page->set_title("Event Log");
$page->set_heading("Event Log");
$page->add_block(new NavBlock());
- $page->add_block(new Block("Events", $table));
- $this->display_paginator($page, "log/view", $this->get_args(), $page_num, $page_total);
- }
-
- protected function get_args()
- {
- $args = "";
- // Check if each arg is actually empty and skip it if so
- if (strlen($this->ueie("time-start"))) {
- $args .= $this->ueie("time-start")."&";
- }
- if (strlen($this->ueie("time-end"))) {
- $args .= $this->ueie("time-end")."&";
- }
- if (strlen($this->ueie("module"))) {
- $args .= $this->ueie("module")."&";
- }
- if (strlen($this->ueie("user"))) {
- $args .= $this->ueie("user")."&";
- }
- if (strlen($this->ueie("message"))) {
- $args .= $this->ueie("message")."&";
- }
- if (strlen($this->ueie("priority"))) {
- $args .= $this->ueie("priority");
- }
- // If there are no args at all, set $args to null to prevent an unnecessary ? at the end of the paginator url
- if (strlen($args) == 0) {
- $args = null;
- }
- return $args;
- }
-
- protected function pri_to_col($pri)
- {
- switch ($pri) {
- case SCORE_LOG_DEBUG: return "#999";
- case SCORE_LOG_INFO: return "#000";
- case SCORE_LOG_WARNING: return "#800";
- case SCORE_LOG_ERROR: return "#C00";
- case SCORE_LOG_CRITICAL: return "#F00";
- default: return "";
- }
- }
-
- protected function scan_entities($line)
- {
- $line = preg_replace_callback("/Image #(\d+)/s", [$this, "link_image"], $line);
- return $line;
- }
-
- protected function link_image($id)
- {
- $iid = int_escape($id[1]);
- return "Image #$iid ";
+ $page->add_block(new Block("Events", $table . $paginator));
}
}
diff --git a/ext/source_history/main.php b/ext/source_history/main.php
index 0afb0729..90edc8f0 100644
--- a/ext/source_history/main.php
+++ b/ext/source_history/main.php
@@ -373,7 +373,7 @@ class SourceHistory extends Extension
"
INSERT INTO source_histories(image_id, source, user_id, user_ip, date_set)
VALUES (:image_id, :source, :user_id, :user_ip, now())",
- ["image_id"=>$image->id, "source"=>$old_tags, "user_id"=>$config->get_int('anon_id'), "user_ip"=>'127.0.0.1']
+ ["image_id"=>$image->id, "source"=>$old_source, "user_id"=>$config->get_int('anon_id'), "user_ip"=>'127.0.0.1']
);
$entries++;
}
diff --git a/ext/user/main.php b/ext/user/main.php
index 9ac332e9..e690d148 100644
--- a/ext/user/main.php
+++ b/ext/user/main.php
@@ -2,6 +2,61 @@
require_once "events.php";
+use function MicroHTML\A;
+use MicroCRUD\Column;
+use MicroCRUD\EnumColumn;
+use MicroCRUD\TextColumn;
+use MicroCRUD\Table;
+
+class UserNameColumn extends TextColumn {
+ public function display(array $row) {
+ return A(["href"=>make_link("user/{$row[$this->name]}")], $row[$this->name]);
+ }
+}
+
+class UserLinksColumn extends Column {
+ public function __construct() {
+ parent::__construct("links", "User Links", "(1=1)");
+ $this->sortable = false;
+ }
+ public function create_input(array $inputs) {
+ return "";
+ }
+ public function read_input(array $inputs) {
+ return "";
+ }
+ public function display(array $row) {
+ return A(["href"=>make_link("post/list/user_id={$row['id']}/1")], "Posts");
+ }
+}
+
+class UserTable extends Table
+{
+ public function __construct(\FFSPHP\PDO $db)
+ {
+ global $_shm_user_classes;
+ $classes = [];
+ foreach($_shm_user_classes as $cls) {
+ $classes[$cls->name] = $cls->name;
+ }
+ ksort($classes);
+ parent::__construct($db);
+ $this->table = "users";
+ $this->base_query = "SELECT * FROM users";
+ $this->size = 100;
+ $this->limit = 1000000;
+ $this->columns = [
+ new UserNameColumn("name", "Name"),
+ new EnumColumn("class", "Class", $classes),
+ // Added later, for admins only
+ // new TextColumn("email", "Email"),
+ new UserLinksColumn(),
+ ];
+ $this->order_by = ["name"];
+ $this->table_attrs = ["class" => "zebra"];
+ }
+}
+
class UserCreationException extends SCoreException
{
}
@@ -51,36 +106,15 @@ class UserPage extends Extension
} elseif ($event->get_arg(0) == "create") {
$this->page_create();
} elseif ($event->get_arg(0) == "list") {
- $limit = 50;
-
- $page_num = $event->try_page_num(1);
- $offset = ($page_num-1) * $limit;
-
- $q = "WHERE 1=1";
- $a = [];
-
- if (@$_GET['username']) {
- $q .= " AND SCORE_STRNORM(name) LIKE SCORE_STRNORM(:name)";
- $a["name"] = '%' . $_GET['username'] . '%';
+ $t = new UserTable($database->raw_db());
+ $t->token = $user->get_auth_token();
+ $t->inputs = $_GET;
+ if ($user->can(Permissions::DELETE_USER)) {
+ $col = new TextColumn("email", "Email");
+ // $t->columns[] = $col;
+ array_splice($t->columns, 2, 0, [$col]);
}
-
- if ($user->can(Permissions::DELETE_USER) && @$_GET['email']) {
- $q .= " AND SCORE_STRNORM(email) LIKE SCORE_STRNORM(:email)";
- $a["email"] = '%' . $_GET['email'] . '%';
- }
-
- if (@$_GET['class']) {
- $q .= " AND class LIKE :class";
- $a["class"] = $_GET['class'];
- }
- $where = $database->scoreql_to_sql($q);
-
- $count = $database->get_one("SELECT count(*) FROM users $where", $a);
- $a["offset"] = $offset;
- $a["limit"] = $limit;
- $rows = $database->get_all("SELECT * FROM users $where LIMIT :limit OFFSET :offset", $a);
- $users = array_map("_new_user", $rows);
- $this->theme->display_user_list($page, $users, $user, $page_num, $count/$limit);
+ $this->theme->display_user_list($page, $t->table($t->query()), $t->paginator());
} elseif ($event->get_arg(0) == "logout") {
$this->page_logout();
}
@@ -156,6 +190,9 @@ class UserPage extends Extension
}
$event->add_stats("Joined: $h_join_date", 10);
+ if($user->name == $event->display_user->name) {
+ $event->add_stats("Current IP: {$_SERVER['REMOTE_ADDR']}", 80);
+ }
$event->add_stats("Class: $h_class", 90);
$av = $event->display_user->get_avatar_html();
@@ -184,7 +221,6 @@ class UserPage extends Extension
}
}
-
private function display_stats(UserPageBuildingEvent $event)
{
global $user, $page, $config;
@@ -201,7 +237,6 @@ class UserPage extends Extension
}
}
-
if ($user->id == $event->display_user->id) {
$ubbe = new UserBlockBuildingEvent();
send_event($ubbe);
@@ -397,7 +432,12 @@ class UserPage extends Extension
private function page_create()
{
- global $config, $page;
+ 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);
} elseif (!isset($_POST['name'])) {
diff --git a/ext/user/theme.php b/ext/user/theme.php
index 3c41641d..125fdacb 100644
--- a/ext/user/theme.php
+++ b/ext/user/theme.php
@@ -13,88 +13,12 @@ class UserPageTheme extends Themelet
));
}
- /**
- * #param User[] $users
- */
- public function display_user_list(Page $page, array $users, User $user, int $page_num, int $page_total)
+ public function display_user_list(Page $page, $table, $paginator)
{
$page->set_title("User List");
$page->set_heading("User List");
$page->add_block(new NavBlock());
-
- $html = "";
-
- $page->add_block(new Block("Users", $html));
- $this->display_paginator($page, "user_admin/list", $this->get_args(), $page_num, $page_total);
- }
-
- protected function ueie($var)
- {
- if (isset($_GET[$var])) {
- return $var."=".url_escape($_GET[$var]);
- } else {
- return "";
- }
- }
- protected function get_args()
- {
- $args = "";
- // Check if each arg is actually empty and skip it if so
- if (strlen($this->ueie("username"))) {
- $args .= $this->ueie("username")."&";
- }
- if (strlen($this->ueie("email"))) {
- $args .= $this->ueie("email")."&";
- }
- if (strlen($this->ueie("class"))) {
- $args .= $this->ueie("class")."&";
- }
- // If there are no args at all, set $args to null to prevent an unnecessary ? at the end of the paginator url
- if (strlen($args) == 0) {
- $args = null;
- }
- return $args;
+ $page->add_block(new Block("Users", $table . $paginator));
}
public function display_user_links(Page $page, User $user, $parts)
@@ -167,7 +91,7 @@ class UserPageTheme extends Themelet
public function display_login_block(Page $page)
{
- global $config;
+ global $config, $user;
$html = '
'.make_form(make_link("user_admin/login"))."
";
- if ($config->get_bool("login_signup_enabled")) {
+ if ($config->get_bool("login_signup_enabled") && $user->can(Permissions::CREATE_USER)) {
$html .= "Create Account ";
}
$page->add_block(new Block("Login", $html, "left", 90));