This repository has been archived on 2024-09-05. You can view files and clone it, but cannot push or open issues or pull requests.
shimmie2/ext/bulk_actions/main.php

273 lines
8.3 KiB
PHP
Raw Normal View History

2019-06-05 23:03:22 +00:00
<?php
/*
* Name: Bulk Actions
* Author: Matthew Barbour
* License: WTFPL
* Description: Provides query and selection-based bulk action support
* Documentation: Provides bulk action section in list view. Allows performing actions against a set of images based on query or manual selection.
* Based on Mass Tagger by Christian Walde <walde.christian@googlemail.com>, contributions by Shish and Agasa.
*/
2019-06-06 00:37:07 +00:00
class BulkActionBlockBuildingEvent extends Event
{
/** @var array */
2019-06-14 12:47:50 +00:00
public $actions = [];
2019-06-06 00:37:07 +00:00
public function add_action(String $action, string $button_text, String $confirmation_message = "", String $block = "", int $position = 40)
2019-06-06 00:37:07 +00:00
{
2019-06-14 12:47:50 +00:00
if ($block == null) {
2019-06-05 23:03:22 +00:00
$block = "";
2019-06-14 12:47:50 +00:00
}
2019-06-05 23:03:22 +00:00
2019-06-06 00:37:07 +00:00
array_push(
$this->actions,
2019-06-14 12:47:50 +00:00
[
2019-06-06 00:37:07 +00:00
"block" => $block,
"confirmation_message" => $confirmation_message,
"action" => $action,
"button_text" => $button_text,
2019-06-06 00:37:07 +00:00
"position" => $position
2019-06-14 12:47:50 +00:00
]
2019-06-05 23:03:22 +00:00
);
2019-06-06 00:37:07 +00:00
}
2019-06-05 23:03:22 +00:00
}
2019-06-06 00:37:07 +00:00
class BulkActionEvent extends Event
{
/** @var string */
2019-06-05 23:03:22 +00:00
public $action;
/** @var array */
2019-06-05 23:03:22 +00:00
public $items;
/** @var PageRequestEvent */
2019-06-05 23:03:22 +00:00
public $page_request;
2019-06-14 12:47:50 +00:00
public function __construct(String $action, PageRequestEvent $pageRequestEvent, array $items)
2019-06-06 00:37:07 +00:00
{
2019-06-05 23:03:22 +00:00
$this->action = $action;
$this->page_request = $pageRequestEvent;
$this->items = $items;
}
}
class BulkActions extends Extension
{
public function onPostListBuilding(PostListBuildingEvent $event)
{
global $config, $page, $user;
2019-06-06 00:37:07 +00:00
if ($user->is_logged_in()) {
$babbe = new BulkActionBlockBuildingEvent();
send_event($babbe);
2019-06-14 12:47:50 +00:00
if (sizeof($babbe->actions) == 0) {
return;
}
2019-06-14 12:47:50 +00:00
usort($babbe->actions, [$this, "sort_blocks"]);
$this->theme->display_selector($page, $babbe->actions, Tag::implode($event->search_terms));
}
2019-06-05 23:03:22 +00:00
}
2019-06-06 00:37:07 +00:00
public function onBulkActionBlockBuilding(BulkActionBlockBuildingEvent $event)
2019-06-05 23:03:22 +00:00
{
global $user;
if ($user->can("delete_image")) {
2019-06-14 12:47:50 +00:00
$event->add_action("bulk_delete", "Delete", "Delete selected images?", "", 10);
2019-06-05 23:03:22 +00:00
}
if ($user->can("bulk_edit_image_tag")) {
2019-06-14 12:47:50 +00:00
$event->add_action("bulk_tag", "Tag", "", $this->theme->render_tag_input(), 10);
2019-06-05 23:03:22 +00:00
}
if ($user->can("bulk_edit_image_source")) {
2019-06-14 12:47:50 +00:00
$event->add_action("bulk_source", "Set Source", "", $this->theme->render_source_input(), 10);
2019-06-05 23:03:22 +00:00
}
}
public function onBulkAction(BulkActionEvent $event)
{
global $user;
2019-06-06 00:37:07 +00:00
switch ($event->action) {
case "bulk_delete":
2019-06-05 23:03:22 +00:00
if ($user->can("delete_image")) {
$i = $this->delete_items($event->items);
flash_message("Deleted $i items");
2019-06-05 23:03:22 +00:00
}
break;
case "bulk_tag":
2019-06-05 23:03:22 +00:00
if (!isset($_POST['bulk_tags'])) {
return;
}
if ($user->can("bulk_edit_image_tag")) {
$tags = $_POST['bulk_tags'];
$replace = false;
2019-06-06 00:37:07 +00:00
if (isset($_POST['bulk_tags_replace']) && $_POST['bulk_tags_replace'] == "true") {
2019-06-05 23:03:22 +00:00
$replace = true;
}
2019-06-06 00:37:07 +00:00
$i= $this->tag_items($event->items, $tags, $replace);
flash_message("Tagged $i items");
2019-06-05 23:03:22 +00:00
}
break;
case "bulk_source":
2019-06-05 23:03:22 +00:00
if (!isset($_POST['bulk_source'])) {
return;
}
if ($user->can("bulk_edit_image_source")) {
$source = $_POST['bulk_source'];
$i = $this->set_source($event->items, $source);
flash_message("Set source for $i items");
2019-06-05 23:03:22 +00:00
}
break;
}
}
public function onPageRequest(PageRequestEvent $event)
{
global $page, $user;
if ($event->page_matches("bulk_action") && $user->is_admin()) {
if (!isset($_POST['bulk_action'])) {
return;
}
$action = $_POST['bulk_action'];
$items = [];
2019-06-06 00:37:07 +00:00
if (isset($_POST['bulk_selected_ids']) && $_POST['bulk_selected_ids'] != "") {
2019-06-05 23:03:22 +00:00
$data = json_decode($_POST['bulk_selected_ids']);
2019-06-06 00:37:07 +00:00
if (is_array($data)) {
2019-06-05 23:03:22 +00:00
foreach ($data as $id) {
2019-06-06 00:37:07 +00:00
if (is_numeric($id)) {
array_push($items, int_escape($id));
2019-06-05 23:03:22 +00:00
}
}
}
2019-06-14 12:47:50 +00:00
} elseif (isset($_POST['bulk_query']) && $_POST['bulk_query'] != "") {
2019-06-05 23:03:22 +00:00
$query = $_POST['bulk_query'];
2019-06-06 00:37:07 +00:00
if ($query != null && $query != "") {
2019-06-05 23:03:22 +00:00
$n = 0;
$tags = Tag::explode($query);
2019-06-05 23:03:22 +00:00
while (true) {
$results = Image::find_image_ids($n, 100, $tags);
if (count($results) == 0) {
2019-06-05 23:03:22 +00:00
break;
}
2019-06-06 00:37:07 +00:00
reset($results); // rewind to first element in array.
$items = array_merge($items, $results);
$n += count($results);
2019-06-05 23:03:22 +00:00
}
}
}
if (sizeof($items) > 0) {
reset($items); // rewind to first element in array.
$newEvent = new BulkActionEvent($action, $event, $items);
send_event($newEvent);
}
2019-06-05 23:03:22 +00:00
$page->set_mode("redirect");
if (!isset($_SERVER['HTTP_REFERER'])) {
$_SERVER['HTTP_REFERER'] = make_link();
}
$page->set_redirect($_SERVER['HTTP_REFERER']);
}
}
private function sort_blocks($a, $b)
2019-06-14 12:47:50 +00:00
{
return $a["position"] - $b["position"];
}
private function delete_items(array $items): int
2019-06-06 00:37:07 +00:00
{
2019-06-05 23:03:22 +00:00
$total = 0;
foreach ($items as $id) {
2019-06-05 23:03:22 +00:00
try {
$image = Image::by_id($id);
2019-06-14 12:47:50 +00:00
if ($image==null) {
continue;
}
send_event(new ImageDeletionEvent($image));
2019-06-05 23:03:22 +00:00
$total++;
2019-06-06 00:37:07 +00:00
} catch (Exception $e) {
flash_message("Error while removing $id: " . $e->getMessage(), "error");
2019-06-05 23:03:22 +00:00
}
2019-06-06 00:37:07 +00:00
}
return $total;
2019-06-05 23:03:22 +00:00
}
private function tag_items(array $items, string $tags, bool $replace): int
2019-06-06 00:37:07 +00:00
{
2019-06-05 23:03:22 +00:00
$tags = Tag::explode($tags);
$pos_tag_array = [];
$neg_tag_array = [];
foreach ($tags as $new_tag) {
if (strpos($new_tag, '-') === 0) {
$neg_tag_array[] = substr($new_tag, 1);
} else {
$pos_tag_array[] = $new_tag;
}
}
$total = 0;
if ($replace) {
foreach ($items as $id) {
$image = Image::by_id($id);
2019-06-14 12:47:50 +00:00
if ($image==null) {
continue;
}
send_event(new TagSetEvent($image, $tags));
2019-06-05 23:03:22 +00:00
$total++;
}
} else {
foreach ($items as $id) {
$image = Image::by_id($id);
2019-06-14 12:47:50 +00:00
if ($image==null) {
continue;
}
2019-06-05 23:03:22 +00:00
$img_tags = [];
if (!empty($neg_tag_array)) {
$img_tags = array_merge($pos_tag_array, $image->get_tag_array());
2019-06-05 23:03:22 +00:00
$img_tags = array_diff($img_tags, $neg_tag_array);
} else {
$img_tags = array_merge($tags, $image->get_tag_array());
2019-06-05 23:03:22 +00:00
}
send_event(new TagSetEvent($image, $img_tags));
2019-06-05 23:03:22 +00:00
$total++;
}
}
return $total;
2019-06-05 23:03:22 +00:00
}
private function set_source(array $items, String $source): int
2019-06-06 00:37:07 +00:00
{
2019-06-05 23:03:22 +00:00
$total = 0;
foreach ($items as $id) {
2019-06-05 23:03:22 +00:00
try {
$image = Image::by_id($id);
2019-06-14 12:47:50 +00:00
if ($image==null) {
continue;
}
send_event(new SourceSetEvent($image, $source));
2019-06-05 23:03:22 +00:00
$total++;
2019-06-06 00:37:07 +00:00
} catch (Exception $e) {
flash_message("Error while setting source for $id: " . $e->getMessage(), "error");
2019-06-05 23:03:22 +00:00
}
}
return $total;
2019-06-05 23:03:22 +00:00
}
}