New trash extension. For undelete-type stuff.
This commit is contained in:
parent
92bb96049f
commit
32d37254f7
5 changed files with 207 additions and 29 deletions
|
@ -6,6 +6,8 @@
|
||||||
*/
|
*/
|
||||||
abstract class Event
|
abstract class Event
|
||||||
{
|
{
|
||||||
|
public $stop_processing = false;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,7 @@ function send_event(Event $event): void
|
||||||
// SHIT: http://bugs.php.net/bug.php?id=35106
|
// SHIT: http://bugs.php.net/bug.php?id=35106
|
||||||
$my_event_listeners = $_shm_event_listeners[get_class($event)];
|
$my_event_listeners = $_shm_event_listeners[get_class($event)];
|
||||||
ksort($my_event_listeners);
|
ksort($my_event_listeners);
|
||||||
|
|
||||||
foreach ($my_event_listeners as $listener) {
|
foreach ($my_event_listeners as $listener) {
|
||||||
if ($ctx_enabled) {
|
if ($ctx_enabled) {
|
||||||
$_shm_ctx->log_start(get_class($listener));
|
$_shm_ctx->log_start(get_class($listener));
|
||||||
|
@ -131,6 +132,9 @@ function send_event(Event $event): void
|
||||||
if ($ctx_enabled) {
|
if ($ctx_enabled) {
|
||||||
$_shm_ctx->log_endok();
|
$_shm_ctx->log_endok();
|
||||||
}
|
}
|
||||||
|
if($event->stop_processing===true) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$_shm_event_count++;
|
$_shm_event_count++;
|
||||||
if ($ctx_enabled) {
|
if ($ctx_enabled) {
|
||||||
|
|
|
@ -768,44 +768,38 @@ class Pools extends Extension
|
||||||
|
|
||||||
$imagesPerPage = $config->get_int(PoolsConfig::IMAGES_PER_PAGE);
|
$imagesPerPage = $config->get_int(PoolsConfig::IMAGES_PER_PAGE);
|
||||||
|
|
||||||
|
|
||||||
|
$query = "
|
||||||
|
INNER JOIN images AS i ON i.id = p.image_id
|
||||||
|
WHERE p.pool_id = :pid
|
||||||
|
";
|
||||||
|
|
||||||
|
|
||||||
// WE CHECK IF THE EXTENSION RATING IS INSTALLED, WHICH VERSION AND IF IT
|
// 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
|
// WORKS TO SHOW/HIDE SAFE, QUESTIONABLE, EXPLICIT AND UNRATED IMAGES FROM USER
|
||||||
if (ext_is_live("Ratings")) {
|
if (ext_is_live("Ratings")) {
|
||||||
$rating = Ratings::privs_to_sql(Ratings::get_user_privs($user));
|
$query .= "AND i.rating IN (".Ratings::privs_to_sql(Ratings::get_user_privs($user)).")";
|
||||||
}
|
}
|
||||||
if (isset($rating) && !empty($rating)) {
|
if(ext_is_live("trash")) {
|
||||||
$result = $database->get_all(
|
$query .= $database->scoreql_to_sql(" AND trash = SCORE_BOOL_N ");
|
||||||
"
|
}
|
||||||
SELECT p.image_id
|
|
||||||
FROM pool_images AS p
|
$result = $database->get_all(
|
||||||
INNER JOIN images AS i ON i.id = p.image_id
|
"
|
||||||
WHERE p.pool_id = :pid AND i.rating IN ($rating)
|
SELECT p.image_id FROM pool_images p
|
||||||
|
$query
|
||||||
ORDER BY p.image_order ASC
|
ORDER BY p.image_order ASC
|
||||||
LIMIT :l OFFSET :o",
|
LIMIT :l OFFSET :o",
|
||||||
["pid" => $poolID, "l" => $imagesPerPage, "o" => $pageNumber * $imagesPerPage]
|
["pid" => $poolID, "l" => $imagesPerPage, "o" => $pageNumber * $imagesPerPage]
|
||||||
);
|
);
|
||||||
|
|
||||||
$totalPages = ceil($database->get_one(
|
$totalPages = ceil($database->get_one(
|
||||||
"
|
|
||||||
SELECT COUNT(*)
|
|
||||||
FROM pool_images AS p
|
|
||||||
INNER JOIN images AS i ON i.id = p.image_id
|
|
||||||
WHERE pool_id=:pid AND i.rating IN ($rating)",
|
|
||||||
["pid" => $poolID]
|
|
||||||
) / $imagesPerPage);
|
|
||||||
} else {
|
|
||||||
$result = $database->get_all(
|
|
||||||
"
|
"
|
||||||
SELECT image_id
|
SELECT COUNT(*) FROM pool_images p
|
||||||
FROM pool_images
|
$query",
|
||||||
WHERE pool_id=:pid
|
["pid" => $poolID]
|
||||||
ORDER BY image_order ASC
|
) / $imagesPerPage);
|
||||||
LIMIT :l OFFSET :o",
|
|
||||||
["pid" => $poolID, "l" => $imagesPerPage, "o" => $pageNumber * $imagesPerPage]
|
|
||||||
);
|
|
||||||
|
|
||||||
$totalPages = ceil($database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]) / $imagesPerPage);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$images = [];
|
$images = [];
|
||||||
|
|
164
ext/trash/main.php
Normal file
164
ext/trash/main.php
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
<?php
|
||||||
|
/*
|
||||||
|
* Name: Trash
|
||||||
|
* Author: Matthew Barbour <matthew@darkohlme.net>
|
||||||
|
* License: MIT
|
||||||
|
* Description: Provides "Trash" or "Recycle Bin"-type functionality, storing delete images for later recovery
|
||||||
|
* Documentation:
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class TrashConfig
|
||||||
|
{
|
||||||
|
const VERSION = "ext_trash_version";
|
||||||
|
}
|
||||||
|
|
||||||
|
class Trash extends Extension
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $db_support = [DatabaseDriver::MYSQL, DatabaseDriver::PGSQL];
|
||||||
|
|
||||||
|
public function get_priority(): int
|
||||||
|
{
|
||||||
|
// Needs to be early to intercept delete events
|
||||||
|
return 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onInitExt(InitExtEvent $event)
|
||||||
|
{
|
||||||
|
global $config;
|
||||||
|
|
||||||
|
if ($config->get_int(TrashConfig::VERSION) < 1) {
|
||||||
|
$this->install();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function onPageRequest(PageRequestEvent $event)
|
||||||
|
{
|
||||||
|
global $page, $user;
|
||||||
|
|
||||||
|
if ($event->page_matches("trash_restore") && $user->can("view_trash")) {
|
||||||
|
// Try to get the image ID
|
||||||
|
$image_id = int_escape($event->get_arg(0));
|
||||||
|
if (empty($image_id)) {
|
||||||
|
$image_id = isset($_POST['image_id']) ? $_POST['image_id'] : null;
|
||||||
|
}
|
||||||
|
if (empty($image_id)) {
|
||||||
|
throw new SCoreException("Can not restore image: No valid Image ID given.");
|
||||||
|
}
|
||||||
|
|
||||||
|
self::set_trash($image_id, false);
|
||||||
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
|
$page->set_redirect(make_link("post/view/".$image_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function onDisplayingImage(DisplayingImageEvent $event)
|
||||||
|
{
|
||||||
|
global $user, $page;
|
||||||
|
|
||||||
|
if(!$user->can("view_trash")) {
|
||||||
|
$page->set_mode(PageMode::REDIRECT);
|
||||||
|
$page->set_redirect(make_link("post/list"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onImageDeletion(ImageDeletionEvent $event)
|
||||||
|
{
|
||||||
|
if($event->image->trash===false) {
|
||||||
|
self::set_trash($event->image->id, true);
|
||||||
|
$event->stop_processing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const SEARCH_REGEXP = "/^in:trash$/";
|
||||||
|
public function onSearchTermParse(SearchTermParseEvent $event)
|
||||||
|
{
|
||||||
|
global $user, $database;
|
||||||
|
|
||||||
|
$matches = [];
|
||||||
|
|
||||||
|
if (is_null($event->term) && $this->no_trash_query($event->context)) {
|
||||||
|
$event->add_querylet(new Querylet($database->scoreql_to_sql("trash = SCORE_BOOL_N ")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (preg_match(self::SEARCH_REGEXP, strtolower($event->term), $matches)) {
|
||||||
|
if($user->can("view_trash")) {
|
||||||
|
$event->add_querylet(new Querylet($database->scoreql_to_sql("trash = SCORE_BOOL_Y ")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function no_trash_query(array $context): bool
|
||||||
|
{
|
||||||
|
foreach ($context as $term) {
|
||||||
|
if (preg_match(self::SEARCH_REGEXP, $term)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function set_trash($image_id, $trash) {
|
||||||
|
global $database;
|
||||||
|
|
||||||
|
$database->execute("UPDATE images SET trash = :trash WHERE id = :id",
|
||||||
|
["trash"=>$database->scoresql_value_prepare($trash),"id"=>$image_id]);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event)
|
||||||
|
{
|
||||||
|
global $config, $database, $user;
|
||||||
|
if($event->image->trash===true && $user->can("view_trash")) {
|
||||||
|
$event->add_part($this->theme->get_image_admin_html($event->image->id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onBulkActionBlockBuilding(BulkActionBlockBuildingEvent $event)
|
||||||
|
{
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
if ($user->can("view_trash")&&in_array("in:trash", $event->search_terms)) {
|
||||||
|
$event->add_action("bulk_trash_restore","Restore From Trash");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onBulkAction(BulkActionEvent $event)
|
||||||
|
{
|
||||||
|
global $user;
|
||||||
|
|
||||||
|
switch ($event->action) {
|
||||||
|
case "bulk_trash_restore":
|
||||||
|
if ($user->can("view_trash")) {
|
||||||
|
$total = 0;
|
||||||
|
foreach ($event->items as $id) {
|
||||||
|
self::set_trash($id, false);
|
||||||
|
$total++;
|
||||||
|
}
|
||||||
|
flash_message("Restored $total items from trash");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function install()
|
||||||
|
{
|
||||||
|
global $database, $config;
|
||||||
|
|
||||||
|
if ($config->get_int(TrashConfig::VERSION) < 1) {
|
||||||
|
$database->Execute($database->scoreql_to_sql(
|
||||||
|
"ALTER TABLE images ADD COLUMN trash SCORE_BOOL NOT NULL DEFAULT SCORE_BOOL_N"
|
||||||
|
));
|
||||||
|
$database->Execute("CREATE INDEX images_trash_idx ON images(trash)");
|
||||||
|
$config->set_int(TrashConfig::VERSION, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
ext/trash/theme.php
Normal file
14
ext/trash/theme.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class TrashTheme extends Themelet
|
||||||
|
{
|
||||||
|
function get_image_admin_html(int $image_id) {
|
||||||
|
$html = "
|
||||||
|
".make_form(make_link('trash_restore/'.$image_id), 'POST')."
|
||||||
|
<input type='hidden' name='image_id' value='$image_id'>
|
||||||
|
<input type='submit' value='Restore From Trash'>
|
||||||
|
</form>
|
||||||
|
";
|
||||||
|
|
||||||
|
return $html; }
|
||||||
|
}
|
Reference in a new issue