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/private_image/main.php

271 lines
9.8 KiB
PHP
Raw Normal View History

2021-12-14 18:32:47 +00:00
<?php
declare(strict_types=1);
2020-06-02 23:08:24 +00:00
namespace Shimmie2;
2020-06-02 23:08:24 +00:00
abstract class PrivateImageConfig
{
2021-12-14 18:32:47 +00:00
public const VERSION = "ext_private_image_version";
public const USER_SET_DEFAULT = "user_private_image_set_default";
public const USER_VIEW_DEFAULT = "user_private_image_view_default";
2020-06-02 23:08:24 +00:00
}
class PrivateImage extends Extension
{
/** @var PrivateImageTheme */
2023-06-27 14:56:49 +00:00
protected Themelet $theme;
2020-06-02 23:08:24 +00:00
public function onInitExt(InitExtEvent $event): void
2020-06-02 23:08:24 +00:00
{
Image::$prop_types["private"] = ImagePropType::BOOL;
2020-06-02 23:08:24 +00:00
}
public function onInitUserConfig(InitUserConfigEvent $event): void
2020-06-02 23:08:24 +00:00
{
$event->user_config->set_default_bool(PrivateImageConfig::USER_SET_DEFAULT, false);
$event->user_config->set_default_bool(PrivateImageConfig::USER_VIEW_DEFAULT, true);
}
public function onUserOptionsBuilding(UserOptionsBuildingEvent $event): void
2020-06-02 23:08:24 +00:00
{
2023-03-20 16:47:59 +00:00
global $user;
$sb = $event->panel->create_new_block("Private Posts");
$sb->start_table();
2023-06-27 10:45:27 +00:00
if ($user->can(Permissions::SET_PRIVATE_IMAGE)) {
2023-03-20 16:47:59 +00:00
$sb->add_bool_option(PrivateImageConfig::USER_SET_DEFAULT, "Mark posts private by default", true);
}
$sb->add_bool_option(PrivateImageConfig::USER_VIEW_DEFAULT, "View private posts by default", true);
$sb->end_table();
2020-06-02 23:08:24 +00:00
}
public function onPageRequest(PageRequestEvent $event): void
2020-06-02 23:08:24 +00:00
{
global $page, $user, $user_config;
2024-02-11 11:34:09 +00:00
if ($event->page_matches("privatize_image/{image_id}", method: "POST", permission: Permissions::SET_PRIVATE_IMAGE)) {
$image_id = $event->get_iarg('image_id');
$image = Image::by_id_ex($image_id);
2023-11-11 21:49:12 +00:00
if ($image->owner_id != $user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) {
2024-02-11 15:47:40 +00:00
throw new PermissionDenied("Cannot set another user's image to private.");
2020-06-02 23:08:24 +00:00
}
self::privatize_image($image_id);
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("post/view/" . $image_id));
}
2024-02-11 11:34:09 +00:00
if ($event->page_matches("publicize_image/{image_id}", method: "POST")) {
$image_id = $event->get_iarg('image_id');
$image = Image::by_id_ex($image_id);
2023-11-11 21:49:12 +00:00
if ($image->owner_id != $user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) {
2024-02-11 15:47:40 +00:00
throw new PermissionDenied("Cannot set another user's image to public.");
2020-06-02 23:08:24 +00:00
}
self::publicize_image($image_id);
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("post/view/".$image_id));
}
if ($event->page_matches("user_admin/private_image", method: "POST")) {
$id = int_escape($event->req_POST('id'));
if ($id != $user->id) {
2024-02-11 15:47:40 +00:00
throw new PermissionDenied("Cannot change another user's settings");
2020-06-02 23:08:24 +00:00
}
$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);
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("user"));
2020-06-02 23:08:24 +00:00
}
}
public function onDisplayingImage(DisplayingImageEvent $event): void
2020-06-02 23:08:24 +00:00
{
2020-10-26 21:54:43 +00:00
global $user, $page;
2020-06-02 23:08:24 +00:00
if ($event->image['private'] === true && $event->image->owner_id != $user->id && !$user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) {
2020-06-02 23:08:24 +00:00
$page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link());
2020-06-02 23:08:24 +00:00
}
}
2021-12-14 18:32:47 +00:00
public const SEARCH_REGEXP = "/^private:(yes|no|any)/";
public function onSearchTermParse(SearchTermParseEvent $event): void
2020-06-02 23:08:24 +00:00
{
2020-10-29 01:28:46 +00:00
global $user, $user_config;
2020-06-02 23:08:24 +00:00
$show_private = $user_config->get_bool(PrivateImageConfig::USER_VIEW_DEFAULT);
$matches = [];
if (is_null($event->term) && $this->no_private_query($event->context)) {
if ($show_private) {
$event->add_querylet(
new Querylet(
"private != :true OR owner_id = :private_owner_id",
2023-11-11 21:49:12 +00:00
["private_owner_id" => $user->id, "true" => true]
2020-06-02 23:08:24 +00:00
)
);
} else {
$event->add_querylet(
2023-11-11 21:49:12 +00:00
new Querylet("private != :true", ["true" => true])
2020-06-02 23:08:24 +00:00
);
}
}
if (is_null($event->term)) {
return;
}
if (preg_match(self::SEARCH_REGEXP, strtolower($event->term), $matches)) {
$params = [];
$query = "";
switch ($matches[1]) {
case "no":
$query .= "private != :true";
$params["true"] = true;
break;
case "yes":
2020-10-26 21:54:43 +00:00
$query .= "private = :true";
$params["true"] = true;
// Admins can view others private images, but they have to specify the user
if (!$user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES) ||
!UserPage::has_user_query($event->context)) {
$query .= " AND owner_id = :private_owner_id";
$params["private_owner_id"] = $user->id;
}
break;
case "any":
$query .= "private != :true OR owner_id = :private_owner_id";
$params["true"] = true;
2020-06-02 23:08:24 +00:00
$params["private_owner_id"] = $user->id;
break;
2020-06-02 23:08:24 +00:00
}
2020-10-26 21:54:43 +00:00
$event->add_querylet(new Querylet($query, $params));
2020-06-02 23:08:24 +00:00
}
}
public function onHelpPageBuilding(HelpPageBuildingEvent $event): void
2020-06-02 23:08:24 +00:00
{
2023-11-11 21:49:12 +00:00
if ($event->key === HelpPages::SEARCH) {
2020-06-02 23:08:24 +00:00
$block = new Block();
2020-10-26 15:17:47 +00:00
$block->header = "Private Posts";
2020-06-02 23:08:24 +00:00
$block->body = $this->theme->get_help_html();
$event->add_block($block);
}
}
/**
* @param string[] $context
*/
2020-06-02 23:08:24 +00:00
private function no_private_query(array $context): bool
{
foreach ($context as $term) {
if (preg_match(self::SEARCH_REGEXP, $term)) {
return false;
}
}
return true;
}
public static function privatize_image(int $image_id): void
2020-06-02 23:08:24 +00:00
{
2020-10-29 01:28:46 +00:00
global $database;
2020-06-02 23:08:24 +00:00
$database->execute(
"UPDATE images SET private = :true WHERE id = :id AND private = :false",
2023-11-11 21:49:12 +00:00
["id" => $image_id, "true" => true, "false" => false]
2020-06-02 23:08:24 +00:00
);
}
public static function publicize_image(int $image_id): void
2020-06-02 23:08:24 +00:00
{
global $database;
$database->execute(
"UPDATE images SET private = :false WHERE id = :id AND private = :true",
2023-11-11 21:49:12 +00:00
["id" => $image_id, "true" => true, "false" => false]
2020-06-02 23:08:24 +00:00
);
}
public function onImageAdminBlockBuilding(ImageAdminBlockBuildingEvent $event): void
2020-06-02 23:08:24 +00:00
{
2020-10-29 01:28:46 +00:00
global $user;
2023-11-11 21:49:12 +00:00
if (($user->can(Permissions::SET_PRIVATE_IMAGE) && $user->id == $event->image->owner_id) || $user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) {
2024-02-10 18:35:55 +00:00
if ($event->image['private'] === false) {
$event->add_button("Make Private", "privatize_image/".$event->image->id);
} else {
$event->add_button("Make Public", "publicize_image/".$event->image->id);
}
2020-06-02 23:08:24 +00:00
}
}
public function onImageAddition(ImageAdditionEvent $event): void
2020-06-02 23:08:24 +00:00
{
2023-03-21 04:31:57 +00:00
global $user, $user_config;
if ($user_config->get_bool(PrivateImageConfig::USER_SET_DEFAULT) && $user->can(Permissions::SET_PRIVATE_IMAGE)) {
2020-06-02 23:08:24 +00:00
self::privatize_image($event->image->id);
}
}
public function onBulkActionBlockBuilding(BulkActionBlockBuildingEvent $event): void
2020-06-02 23:08:24 +00:00
{
2020-10-29 01:28:46 +00:00
global $user;
2020-06-02 23:08:24 +00:00
if ($user->can(Permissions::SET_PRIVATE_IMAGE)) {
$event->add_action("bulk_privatize_image", "Make Private");
$event->add_action("bulk_publicize_image", "Make Public");
}
}
public function onBulkAction(BulkActionEvent $event): void
2020-06-02 23:08:24 +00:00
{
global $page, $user;
switch ($event->action) {
case "bulk_privatize_image":
if ($user->can(Permissions::SET_PRIVATE_IMAGE)) {
$total = 0;
foreach ($event->items as $image) {
2023-11-11 21:49:12 +00:00
if ($image->owner_id == $user->id ||
2020-06-02 23:08:24 +00:00
$user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) {
self::privatize_image($image->id);
$total++;
}
}
$page->flash("Made $total items private");
}
break;
case "bulk_publicize_image":
$total = 0;
foreach ($event->items as $image) {
2023-11-11 21:49:12 +00:00
if ($image->owner_id == $user->id ||
2020-06-02 23:08:24 +00:00
$user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) {
self::publicize_image($image->id);
$total++;
}
}
$page->flash("Made $total items public");
break;
}
}
public function onDatabaseUpgrade(DatabaseUpgradeEvent $event): void
2020-06-02 23:08:24 +00:00
{
global $database;
if ($this->get_version(PrivateImageConfig::VERSION) < 1) {
$database->execute("ALTER TABLE images ADD COLUMN private BOOLEAN NOT NULL DEFAULT FALSE");
2020-06-02 23:08:24 +00:00
$database->execute("CREATE INDEX images_private_idx ON images(private)");
2020-10-26 21:54:43 +00:00
$this->set_version(PrivateImageConfig::VERSION, 2);
}
if ($this->get_version(PrivateImageConfig::VERSION) < 2) {
$database->standardise_boolean("images", "private");
$this->set_version(PrivateImageConfig::VERSION, 2);
2020-06-02 23:08:24 +00:00
}
}
}