Make admin part of core, with tag_tools as a separate extension
This commit is contained in:
parent
8871591cab
commit
4aabb77a4f
8 changed files with 199 additions and 144 deletions
|
@ -9,15 +9,7 @@ class AdminPageInfo extends ExtensionInfo
|
||||||
public $url = self::SHIMMIE_URL;
|
public $url = self::SHIMMIE_URL;
|
||||||
public $authors = self::SHISH_AUTHOR;
|
public $authors = self::SHISH_AUTHOR;
|
||||||
public $license = self::LICENSE_GPLV2;
|
public $license = self::LICENSE_GPLV2;
|
||||||
public $description = "Various things to make admins' lives easier";
|
public $description = "Provides a base for various small admin functions";
|
||||||
public $documentation =
|
public $core = true;
|
||||||
"Various moderate-level tools for admins; for advanced, obscure, and possibly dangerous tools see the shimmie2-utils script set
|
public $visibility = self::VISIBLE_HIDDEN;
|
||||||
<p>Lowercase all tags:
|
|
||||||
<br>Set all tags to lowercase for consistency
|
|
||||||
<p>Recount tag use:
|
|
||||||
<br>If the counts of posts per tag get messed up somehow, this will reset them, and remove any unused tags
|
|
||||||
<p>Database dump:
|
|
||||||
<br>Download the contents of the database in plain text format, useful for backups.
|
|
||||||
<p>Post dump:
|
|
||||||
<br>Download all the posts as a .zip file (Requires ZipArchive)";
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,6 @@ class AdminPage extends Extension
|
||||||
public function onAdminBuilding(AdminBuildingEvent $event)
|
public function onAdminBuilding(AdminBuildingEvent $event)
|
||||||
{
|
{
|
||||||
$this->theme->display_page();
|
$this->theme->display_page();
|
||||||
$this->theme->display_form();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onPageSubNavBuilding(PageSubNavBuildingEvent $event)
|
public function onPageSubNavBuilding(PageSubNavBuildingEvent $event)
|
||||||
|
@ -152,46 +151,4 @@ class AdminPage extends Extension
|
||||||
$event->add_link("Board Admin", make_link("admin"));
|
$event->add_link("Board Admin", make_link("admin"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function onAdminAction(AdminActionEvent $event)
|
|
||||||
{
|
|
||||||
$action = $event->action;
|
|
||||||
if (method_exists($this, $action)) {
|
|
||||||
$event->redirect = $this->$action();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function set_tag_case()
|
|
||||||
{
|
|
||||||
global $database;
|
|
||||||
$database->execute(
|
|
||||||
"UPDATE tags SET tag=:tag1 WHERE LOWER(tag) = LOWER(:tag2)",
|
|
||||||
["tag1" => $_POST['tag'], "tag2" => $_POST['tag']]
|
|
||||||
);
|
|
||||||
log_info("admin", "Fixed the case of {$_POST['tag']}", "Fixed case");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function lowercase_all_tags()
|
|
||||||
{
|
|
||||||
global $database;
|
|
||||||
$database->execute("UPDATE tags SET tag=lower(tag)");
|
|
||||||
log_warning("admin", "Set all tags to lowercase", "Set all tags to lowercase");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function recount_tag_use()
|
|
||||||
{
|
|
||||||
global $database;
|
|
||||||
$database->execute("
|
|
||||||
UPDATE tags
|
|
||||||
SET count = COALESCE(
|
|
||||||
(SELECT COUNT(image_id) FROM image_tags WHERE tag_id=tags.id GROUP BY tag_id),
|
|
||||||
0
|
|
||||||
)
|
|
||||||
");
|
|
||||||
$database->execute("DELETE FROM tags WHERE count=0");
|
|
||||||
log_warning("admin", "Re-counted tags", "Re-counted tags");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,59 +19,6 @@ class AdminPageTest extends ShimmiePHPUnitTestCase
|
||||||
$this->assertEquals("Admin Tools", $page->title);
|
$this->assertEquals("Admin Tools", $page->title);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testLowercaseAndSetCase()
|
|
||||||
{
|
|
||||||
// Create a problem
|
|
||||||
$ts = time(); // we need a tag that hasn't been used before
|
|
||||||
send_event(new UserLoginEvent(User::by_name(self::$admin_name)));
|
|
||||||
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "TeStCase$ts");
|
|
||||||
|
|
||||||
// Validate problem
|
|
||||||
$page = $this->get_page("post/view/$image_id_1");
|
|
||||||
$this->assertEquals("Post $image_id_1: TeStCase$ts", $page->title);
|
|
||||||
|
|
||||||
// Fix
|
|
||||||
send_event(new AdminActionEvent('lowercase_all_tags'));
|
|
||||||
|
|
||||||
// Validate fix
|
|
||||||
$this->get_page("post/view/$image_id_1");
|
|
||||||
$this->assert_title("Post $image_id_1: testcase$ts");
|
|
||||||
|
|
||||||
// Change
|
|
||||||
$_POST["tag"] = "TestCase$ts";
|
|
||||||
send_event(new AdminActionEvent('set_tag_case'));
|
|
||||||
|
|
||||||
// Validate change
|
|
||||||
$this->get_page("post/view/$image_id_1");
|
|
||||||
$this->assert_title("Post $image_id_1: TestCase$ts");
|
|
||||||
}
|
|
||||||
|
|
||||||
# FIXME: make sure the admin tools actually work
|
|
||||||
public function testRecount()
|
|
||||||
{
|
|
||||||
global $database;
|
|
||||||
|
|
||||||
// Create a problem
|
|
||||||
$ts = time(); // we need a tag that hasn't been used before
|
|
||||||
send_event(new UserLoginEvent(User::by_name(self::$admin_name)));
|
|
||||||
$database->execute(
|
|
||||||
"INSERT INTO tags(tag, count) VALUES(:tag, :count)",
|
|
||||||
["tag"=>"tes$ts", "count"=>42]
|
|
||||||
);
|
|
||||||
|
|
||||||
// Fix
|
|
||||||
send_event(new AdminActionEvent('recount_tag_use'));
|
|
||||||
|
|
||||||
// Validate fix
|
|
||||||
$this->assertEquals(
|
|
||||||
0,
|
|
||||||
$database->get_one(
|
|
||||||
"SELECT count FROM tags WHERE tag = :tag",
|
|
||||||
["tag"=>"tes$ts"]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testCommands()
|
public function testCommands()
|
||||||
{
|
{
|
||||||
send_event(new UserLoginEvent(User::by_name(self::$admin_name)));
|
send_event(new UserLoginEvent(User::by_name(self::$admin_name)));
|
||||||
|
|
|
@ -14,41 +14,4 @@ class AdminPageTheme extends Themelet
|
||||||
$page->set_heading("Admin Tools");
|
$page->set_heading("Admin Tools");
|
||||||
$page->add_block(new NavBlock());
|
$page->add_block(new NavBlock());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function button(string $name, string $action, bool $protected=false): string
|
|
||||||
{
|
|
||||||
$c_protected = $protected ? " protected" : "";
|
|
||||||
$html = make_form(make_link("admin/$action"), "POST", false, "admin$c_protected");
|
|
||||||
if ($protected) {
|
|
||||||
$html .= "<input type='submit' id='$action' value='$name' disabled='disabled'>";
|
|
||||||
$html .= "<input type='checkbox' onclick='$(\"#$action\").attr(\"disabled\", !$(this).is(\":checked\"))'>";
|
|
||||||
} else {
|
|
||||||
$html .= "<input type='submit' id='$action' value='$name'>";
|
|
||||||
}
|
|
||||||
$html .= "</form>\n";
|
|
||||||
return $html;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Show a form which links to admin_utils with POST[action] set to one of:
|
|
||||||
* 'lowercase all tags'
|
|
||||||
* 'recount tag use'
|
|
||||||
* etc
|
|
||||||
*/
|
|
||||||
public function display_form()
|
|
||||||
{
|
|
||||||
global $page;
|
|
||||||
|
|
||||||
$html = "";
|
|
||||||
$html .= $this->button("All tags to lowercase", "lowercase_all_tags", true);
|
|
||||||
$html .= $this->button("Recount tag use", "recount_tag_use", false);
|
|
||||||
$page->add_block(new Block("Misc Admin Tools", $html));
|
|
||||||
|
|
||||||
$html = (string)SHM_SIMPLE_FORM(
|
|
||||||
"admin/set_tag_case",
|
|
||||||
INPUT(["type"=>'text', "name"=>'tag', "placeholder"=>'Enter tag with correct case', "class"=>'autocomplete_tags', "autocomplete"=>'off']),
|
|
||||||
SHM_SUBMIT('Set Tag Case'),
|
|
||||||
);
|
|
||||||
$page->add_block(new Block("Set Tag Case", $html));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
13
ext/tag_tools/info.php
Normal file
13
ext/tag_tools/info.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
class TagToolsInfo extends ExtensionInfo
|
||||||
|
{
|
||||||
|
public const KEY = "tag_tools";
|
||||||
|
|
||||||
|
public $key = self::KEY;
|
||||||
|
public $name = "Tag Tools";
|
||||||
|
public $url = self::SHIMMIE_URL;
|
||||||
|
public $authors = self::SHISH_AUTHOR;
|
||||||
|
public $license = self::LICENSE_GPLV2;
|
||||||
|
public $description = "Recount / Rename / Etc";
|
||||||
|
}
|
85
ext/tag_tools/main.php
Normal file
85
ext/tag_tools/main.php
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
<?php /** @noinspection PhpUnusedPrivateMethodInspection */
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
class TagTools extends Extension
|
||||||
|
{
|
||||||
|
/** @var TagToolsTheme */
|
||||||
|
protected $theme;
|
||||||
|
|
||||||
|
public function onPageRequest(PageRequestEvent $event)
|
||||||
|
{
|
||||||
|
global $database, $page, $user;
|
||||||
|
|
||||||
|
if ($event->page_matches("admin")) {
|
||||||
|
if (!$user->can(Permissions::MANAGE_ADMINTOOLS)) {
|
||||||
|
$this->theme->display_permission_denied();
|
||||||
|
} else {
|
||||||
|
if ($event->count_args() == 0) {
|
||||||
|
send_event(new AdminBuildingEvent($page));
|
||||||
|
} else {
|
||||||
|
$action = $event->get_arg(0);
|
||||||
|
$aae = new AdminActionEvent($action);
|
||||||
|
|
||||||
|
if ($user->check_auth_token()) {
|
||||||
|
log_info("admin", "Util: $action");
|
||||||
|
set_time_limit(0);
|
||||||
|
$database->set_timeout(300000);
|
||||||
|
send_event($aae);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($aae->redirect) {
|
||||||
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
|
$page->set_redirect(make_link("admin"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onAdminBuilding(AdminBuildingEvent $event)
|
||||||
|
{
|
||||||
|
$this->theme->display_form();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onAdminAction(AdminActionEvent $event)
|
||||||
|
{
|
||||||
|
$action = $event->action;
|
||||||
|
if (method_exists($this, $action)) {
|
||||||
|
$event->redirect = $this->$action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function set_tag_case()
|
||||||
|
{
|
||||||
|
global $database;
|
||||||
|
$database->execute(
|
||||||
|
"UPDATE tags SET tag=:tag1 WHERE LOWER(tag) = LOWER(:tag2)",
|
||||||
|
["tag1" => $_POST['tag'], "tag2" => $_POST['tag']]
|
||||||
|
);
|
||||||
|
log_info("admin", "Fixed the case of {$_POST['tag']}", "Fixed case");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function lowercase_all_tags()
|
||||||
|
{
|
||||||
|
global $database;
|
||||||
|
$database->execute("UPDATE tags SET tag=lower(tag)");
|
||||||
|
log_warning("admin", "Set all tags to lowercase", "Set all tags to lowercase");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function recount_tag_use()
|
||||||
|
{
|
||||||
|
global $database;
|
||||||
|
$database->execute("
|
||||||
|
UPDATE tags
|
||||||
|
SET count = COALESCE(
|
||||||
|
(SELECT COUNT(image_id) FROM image_tags WHERE tag_id=tags.id GROUP BY tag_id),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
");
|
||||||
|
$database->execute("DELETE FROM tags WHERE count=0");
|
||||||
|
log_warning("admin", "Re-counted tags", "Re-counted tags");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
56
ext/tag_tools/test.php
Normal file
56
ext/tag_tools/test.php
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
class TagToolsTest extends ShimmiePHPUnitTestCase
|
||||||
|
{
|
||||||
|
public function testLowercaseAndSetCase()
|
||||||
|
{
|
||||||
|
// Create a problem
|
||||||
|
$ts = time(); // we need a tag that hasn't been used before
|
||||||
|
send_event(new UserLoginEvent(User::by_name(self::$admin_name)));
|
||||||
|
$image_id_1 = $this->post_image("tests/pbx_screenshot.jpg", "TeStCase$ts");
|
||||||
|
|
||||||
|
// Validate problem
|
||||||
|
$page = $this->get_page("post/view/$image_id_1");
|
||||||
|
$this->assertEquals("Post $image_id_1: TeStCase$ts", $page->title);
|
||||||
|
|
||||||
|
// Fix
|
||||||
|
send_event(new AdminActionEvent('lowercase_all_tags'));
|
||||||
|
|
||||||
|
// Validate fix
|
||||||
|
$this->get_page("post/view/$image_id_1");
|
||||||
|
$this->assert_title("Post $image_id_1: testcase$ts");
|
||||||
|
|
||||||
|
// Change
|
||||||
|
$_POST["tag"] = "TestCase$ts";
|
||||||
|
send_event(new AdminActionEvent('set_tag_case'));
|
||||||
|
|
||||||
|
// Validate change
|
||||||
|
$this->get_page("post/view/$image_id_1");
|
||||||
|
$this->assert_title("Post $image_id_1: TestCase$ts");
|
||||||
|
}
|
||||||
|
|
||||||
|
# FIXME: make sure the admin tools actually work
|
||||||
|
public function testRecount()
|
||||||
|
{
|
||||||
|
global $database;
|
||||||
|
|
||||||
|
// Create a problem
|
||||||
|
$ts = time(); // we need a tag that hasn't been used before
|
||||||
|
send_event(new UserLoginEvent(User::by_name(self::$admin_name)));
|
||||||
|
$database->execute(
|
||||||
|
"INSERT INTO tags(tag, count) VALUES(:tag, :count)",
|
||||||
|
["tag"=>"tes$ts", "count"=>42]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Fix
|
||||||
|
send_event(new AdminActionEvent('recount_tag_use'));
|
||||||
|
|
||||||
|
// Validate fix
|
||||||
|
$this->assertEquals(
|
||||||
|
0,
|
||||||
|
$database->get_one(
|
||||||
|
"SELECT count FROM tags WHERE tag = :tag",
|
||||||
|
["tag"=>"tes$ts"]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
42
ext/tag_tools/theme.php
Normal file
42
ext/tag_tools/theme.php
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
use function MicroHTML\INPUT;
|
||||||
|
|
||||||
|
class TagToolsTheme extends Themelet
|
||||||
|
{
|
||||||
|
protected function button(string $name, string $action, bool $protected=false): string
|
||||||
|
{
|
||||||
|
$c_protected = $protected ? " protected" : "";
|
||||||
|
$html = make_form(make_link("admin/$action"), "POST", false, "admin$c_protected");
|
||||||
|
if ($protected) {
|
||||||
|
$html .= "<input type='submit' id='$action' value='$name' disabled='disabled'>";
|
||||||
|
$html .= "<input type='checkbox' onclick='$(\"#$action\").attr(\"disabled\", !$(this).is(\":checked\"))'>";
|
||||||
|
} else {
|
||||||
|
$html .= "<input type='submit' id='$action' value='$name'>";
|
||||||
|
}
|
||||||
|
$html .= "</form>\n";
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show a form which links to admin_utils with POST[action] set to one of:
|
||||||
|
* 'lowercase all tags'
|
||||||
|
* 'recount tag use'
|
||||||
|
* etc
|
||||||
|
*/
|
||||||
|
public function display_form()
|
||||||
|
{
|
||||||
|
global $page;
|
||||||
|
|
||||||
|
$html = "";
|
||||||
|
$html .= $this->button("All tags to lowercase", "lowercase_all_tags", true);
|
||||||
|
$html .= $this->button("Recount tag use", "recount_tag_use", false);
|
||||||
|
$page->add_block(new Block("Misc Admin Tools", $html));
|
||||||
|
|
||||||
|
$html = (string)SHM_SIMPLE_FORM(
|
||||||
|
"admin/set_tag_case",
|
||||||
|
INPUT(["type"=>'text', "name"=>'tag', "placeholder"=>'Enter tag with correct case', "class"=>'autocomplete_tags', "autocomplete"=>'off']),
|
||||||
|
SHM_SUBMIT('Set Tag Case'),
|
||||||
|
);
|
||||||
|
$page->add_block(new Block("Set Tag Case", $html));
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue