diff --git a/ext/pools/main.php b/ext/pools/main.php index db908e91..57755648 100644 --- a/ext/pools/main.php +++ b/ext/pools/main.php @@ -42,7 +42,12 @@ class PoolCreationEvent extends Event public $new_id = -1; - public function __construct(string $title, User $pool_user = null, bool $public = false, string $description = "") + public function __construct( + string $title, + User $pool_user = null, + bool $public = false, + string $description = "" + ) { parent::__construct(); global $user; @@ -54,6 +59,33 @@ class PoolCreationEvent extends Event } } +class Pool { + public $id; + public $user_id; + public $user_name; + public $public; + public $title; + public $description; + public $date; + public $posts; + + public function __construct(array $row) + { + $this->id = (int)$row['id']; + $this->user_id = (int)$row['user_id']; + $this->user_name = $row['user_name'] ?? null; + $this->public = bool_escape($row['public']); + $this->title = $row['title']; + $this->description = $row['description']; + $this->date = $row['date']; + $this->posts = (int)$row['posts']; + } + + public static function makePool(array $row): Pool { + return new Pool($row); + } +} + class Pools extends Extension { /** @var PoolsTheme */ @@ -154,7 +186,7 @@ class Pools extends Extension public function onPageRequest(PageRequestEvent $event) { - global $page, $user; + global $config, $database, $page, $user; if ($event->page_matches("pool")) { $pool_id = 0; @@ -219,7 +251,12 @@ class Pools extends Extension case "edit": // Edit the pool (remove images) if ($this->have_permission($user, $pool)) { - $this->theme->edit_pool($page, $this->get_pool($pool_id), $this->edit_posts($pool_id)); + $result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $pool_id]); + $images = []; + while ($row = $result->fetch()) { + $images[] = Image::by_id((int)$row["image_id"]); + } + $this->theme->edit_pool($page, $pool, $images); } else { $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/" . $pool_id)); @@ -229,14 +266,40 @@ class Pools extends Extension case "order": // Order the pool (view and change the order of images within the pool) if (isset($_POST["order_view"])) { if ($this->have_permission($user, $pool)) { - $this->theme->edit_order($page, $this->get_pool($pool_id), $this->edit_order($pool_id)); + $result = $database->execute( + "SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", + ["pid" => $pool_id] + ); + $images = []; + + while ($row = $result->fetch()) { + $image = $database->get_row( + " + SELECT * FROM images AS i + INNER JOIN pool_images AS p ON i.id = p.image_id + WHERE pool_id=:pid AND i.id=:iid", + ["pid" => $pool_id, "iid" => (int)$row['image_id']] + ); + $images[] = ($image ? new Image($image) : null); + } + + $this->theme->edit_order($page, $pool, $images); } else { $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/" . $pool_id)); } } else { if ($this->have_permission($user, $pool)) { - $this->order_posts(); + foreach ($_POST['imgs'] as $data) { + list($imageORDER, $imageID) = $data; + $database->execute( + " + UPDATE pool_images + SET image_order = :ord + WHERE pool_id = :pid AND image_id = :iid", + ["ord" => $imageORDER, "pid" => int_escape($_POST['pool_id']), "iid" => $imageID] + ); + } $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/" . $pool_id)); } else { @@ -247,7 +310,11 @@ class Pools extends Extension case "import": if ($this->have_permission($user, $pool)) { - $this->import_posts($pool_id); + $images = Image::find_images( + 0, $config->get_int(PoolsConfig::MAX_IMPORT_RESULTS, 1000), + Tag::explode($_POST["pool_tag"]) + ); + $this->theme->pool_result($page, $images, $pool); } else { $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); } @@ -269,7 +336,19 @@ class Pools extends Extension case "remove_posts": if ($this->have_permission($user, $pool)) { - $this->remove_posts(); + $images = ""; + foreach ($_POST['check'] as $imageID) { + $database->execute( + "DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid", + ["pid" => $pool_id, "iid" => $imageID] + ); + $images .= " " . $imageID; + } + $count = (int)$database->get_one( + "SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", + ["pid" => $pool_id] + ); + $this->add_history($pool_id, 0, $images, $count); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/" . $pool_id)); } else { @@ -280,7 +359,10 @@ class Pools extends Extension case "edit_description": if ($this->have_permission($user, $pool)) { - $this->edit_description(); + $database->execute( + "UPDATE pools SET description=:dsc WHERE id=:pid", + ["dsc" => $_POST['description'], "pid" => int_escape($_POST['pool_id'])] + ); $page->set_mode(PageMode::REDIRECT); $page->set_redirect(make_link("pool/view/" . $pool_id)); } else { @@ -300,11 +382,6 @@ class Pools extends Extension $this->theme->display_error(403, "Permission Denied", "You do not have permission to access this page"); } break; - - default: - $page->set_mode(PageMode::REDIRECT); - $page->set_redirect(make_link("pool/list")); - break; } } } @@ -335,13 +412,10 @@ class Pools extends Extension foreach ($poolsIDs as $poolID) { $pool = $this->get_single_pool($poolID); - $navInfo[$pool['id']] = []; - $navInfo[$pool['id']]['info'] = $pool; - - // Optionally show a link the Prev/Next image in the Pool. - if ($show_nav) { - $navInfo[$pool['id']]['nav'] = $this->get_nav_posts($pool, $imageID); - } + $navInfo[$pool->id] = [ + "info" => $pool, + "nav" => $show_nav ? $this->get_nav_posts($pool, $imageID) : null, + ]; } $this->theme->pool_info($navInfo); } @@ -352,11 +426,12 @@ class Pools extends Extension global $config, $database, $user; if ($config->get_bool(PoolsConfig::ADDER_ON_VIEW_IMAGE) && !$user->is_anonymous()) { if ($user->can(Permissions::POOLS_ADMIN)) { - $pools = $database->get_all("SELECT * FROM pools"); + $rows = $database->get_all("SELECT * FROM pools"); } else { - $pools = $database->get_all("SELECT * FROM pools WHERE user_id=:id", ["id" => $user->id]); + $rows = $database->get_all("SELECT * FROM pools WHERE user_id=:id", ["id" => $user->id]); } - if (count($pools) > 0) { + if (count($rows) > 0) { + $pools = array_map([Pool::class, "makePool"], $rows); $event->add_part($this->theme->get_adder_html($event->image, $pools)); } } @@ -423,7 +498,7 @@ class Pools extends Extension $pool = $this->get_single_pool_from_title($poolTag); } - if ($pool ? $this->have_permission($user, $pool) : false) { + if ($pool && $this->have_permission($user, $pool)) { $image_order = ($matches[2] ?: 0); $this->add_post($pool['id'], $event->image_id, true, $image_order); } @@ -434,7 +509,10 @@ class Pools extends Extension { global $database; - $pools = $database->get_all("SELECT * FROM pools ORDER BY title "); + $pools = array_map( + [Pool::class, "makePool"], + $database->get_all("SELECT * FROM pools ORDER BY title ") + ); $event->add_action("bulk_pool_add_existing", "Add To (P)ool", "p", "", $this->theme->get_bulk_pool_selector($pools)); $event->add_action("bulk_pool_add_new", "Create Pool", "", "", $this->theme->get_bulk_pool_input($event->search_terms)); @@ -450,7 +528,7 @@ class Pools extends Extension return; } $pool_id = intval($_POST['bulk_pool_select']); - $pool = $this->get_pool($pool_id); + $pool = $this->get_single_pool($pool_id); if ($this->have_permission($user, $pool)) { send_event( @@ -479,14 +557,16 @@ class Pools extends Extension * * TODO: Should the user variable be global? */ - private function have_permission(User $user, array $pool): bool + private function have_permission(User $user, Pool $pool): bool { - // If the pool is public and user is logged OR if the user is admin OR if the pool is owned by the user. - if ((($pool['public'] == "Y" || $pool['public'] == "y") && !$user->is_anonymous()) || $user->can(Permissions::POOLS_ADMIN) || $user->id == $pool['user_id']) { - return true; - } else { - return false; - } + // If the pool is public and user is logged + // OR if the user is admin + // OR if the pool is owned by the user. + return ( + ($pool->public && !$user->is_anonymous()) || + $user->can(Permissions::POOLS_ADMIN) || + $user->id == $pool->user_id + ); } private function list_pools(Page $page, int $pageNumber) @@ -509,15 +589,14 @@ class Pools extends Extension $order_by = "ORDER BY p.posts DESC"; } - $pools = $database->get_all(" - SELECT p.id, p.user_id, p.public, p.title, p.description, - p.posts, u.name as user_name + $pools = array_map([Pool::class, "makePool"], $database->get_all(" + SELECT p.*, u.name as user_name FROM pools AS p INNER JOIN users AS u ON p.user_id = u.id $order_by LIMIT :l OFFSET :o - ", ["l" => $poolsPerPage, "o" => $pageNumber * $poolsPerPage]); + ", ["l" => $poolsPerPage, "o" => $pageNumber * $poolsPerPage])); $totalPages = (int)ceil((int)$database->get_one("SELECT COUNT(*) FROM pools") / $poolsPerPage); @@ -542,7 +621,7 @@ class Pools extends Extension " INSERT INTO pools (user_id, public, title, description, date) VALUES (:uid, :public, :title, :desc, now())", - ["uid" => $event->user->id, "public" => $event->public ? "Y" : "N", "title" => $event->title, "desc" => $event->description] + ["uid" => $event->user->id, "public" => $event->public, "title" => $event->title, "desc" => $event->description] ); $poolID = $database->get_last_insert_id('pools_id_seq'); @@ -551,33 +630,23 @@ class Pools extends Extension $event->new_id = $poolID; } - /** - * Retrieve information about pools given multiple pool IDs. - * - * TODO: What is the difference between this and get_single_pool() other than the db query? - */ - private function get_pool(int $poolID): array - { - global $database; - return $database->get_all("SELECT * FROM pools WHERE id=:id", ["id" => $poolID]); - } - /** * Retrieve information about a pool given a pool ID. */ - private function get_single_pool(int $poolID): array + private function get_single_pool(int $poolID): Pool { global $database; - return $database->get_row("SELECT * FROM pools WHERE id=:id", ["id" => $poolID]); + return new Pool($database->get_row("SELECT * FROM pools WHERE id=:id", ["id" => $poolID])); } /** * Retrieve information about a pool given a pool title. */ - private function get_single_pool_from_title(string $poolTitle): ?array + private function get_single_pool_from_title(string $poolTitle): ?Pool { global $database; - return $database->get_row("SELECT * FROM pools WHERE title=:title", ["title" => $poolTitle]); + $row = $database->get_row("SELECT * FROM pools WHERE title=:title", ["title" => $poolTitle]); + return $row ? new Pool($row) : null; } /** @@ -595,23 +664,10 @@ class Pools extends Extension /** * Retrieve information about the last pool the given userID created */ - private function get_last_userpool(int $userID): array + private function get_last_userpool(int $userID): Pool { global $database; - return $database->get_row("SELECT * FROM pools WHERE user_id=:uid ORDER BY id DESC", ["uid" => $userID]); - } - - /** - * HERE WE GET THE IMAGES FROM THE TAG ON IMPORT - */ - private function import_posts(int $pool_id) - { - global $page, $config; - - $poolsMaxResults = $config->get_int(PoolsConfig::MAX_IMPORT_RESULTS, 1000); - - $images = $images = Image::find_images(0, $poolsMaxResults, Tag::explode($_POST["pool_tag"])); - $this->theme->pool_result($page, $images, $this->get_pool($pool_id)); + return new Pool($database->get_row("SELECT * FROM pools WHERE user_id=:uid ORDER BY id DESC", ["uid" => $userID])); } /** @@ -634,94 +690,28 @@ class Pools extends Extension } if (!strlen($images) == 0) { - $count = int_escape($database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $event->pool_id])); + $count = (int)$database->get_one( + "SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", + ["pid" => $event->pool_id] + ); $this->add_history($event->pool_id, 1, $images, $count); } } - /** - * TODO: Fix this so that the pool ID and images are passed as Arguments to the function. - */ - private function order_posts(): int - { - global $database; - - $poolID = int_escape($_POST['pool_id']); - - foreach ($_POST['imgs'] as $data) { - list($imageORDER, $imageID) = $data; - $database->execute( - " - UPDATE pool_images - SET image_order = :ord - WHERE pool_id = :pid AND image_id = :iid", - ["ord" => $imageORDER, "pid" => $poolID, "iid" => $imageID] - ); - } - - return $poolID; - } - - /** - * HERE WE REMOVE CHECKED IMAGES FROM POOL AND UPDATE THE HISTORY - * - * TODO: Fix this so that the pool ID and images are passed as Arguments to the function. - */ - private function remove_posts(): int - { - global $database; - - $poolID = int_escape($_POST['pool_id']); - $images = ""; - - foreach ($_POST['check'] as $imageID) { - $database->execute("DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid", ["pid" => $poolID, "iid" => $imageID]); - $images .= " " . $imageID; - } - - $count = (int)$database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]); - $this->add_history($poolID, 0, $images, $count); - return $poolID; - } - - /** - * Allows editing of pool description. - */ - private function edit_description(): int - { - global $database; - - $poolID = int_escape($_POST['pool_id']); - $database->execute("UPDATE pools SET description=:dsc WHERE id=:pid", ["dsc" => $_POST['description'], "pid" => $poolID]); - - return $poolID; - } - - /** - * This function checks if a given image is contained within a given pool. - * Used by add_posts() - */ - private function check_post(int $poolID, int $imageID): bool - { - global $database; - $result = (int)$database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid AND image_id=:iid", ["pid" => $poolID, "iid" => $imageID]); - return ($result != 0); - } - /** * Gets the previous and next successive images from a pool, given a pool ID and an image ID. * * #return int[] Array returning two elements (prev, next) in 1 dimension. Each returns ImageID or NULL if none. */ - private function get_nav_posts(array $pool, int $imageID): array + private function get_nav_posts(Pool $pool, int $imageID): array { global $database; - if (empty($pool) || empty($imageID)) { + if (empty($imageID)) { return null; } - $result = $database->get_row( + return $database->get_row( " SELECT ( SELECT image_id @@ -751,15 +741,8 @@ class Pools extends Extension ) AS next LIMIT 1", - ["pid" => $pool['id'], "iid" => $imageID] + ["pid" => $pool->id, "iid" => $imageID] ); - - if (empty($result)) { - // assume that we are at the end of the pool - return null; - } else { - return $result; - } } /** @@ -770,12 +753,12 @@ class Pools extends Extension global $config, $user, $database; $pageNumber = $event->try_page_num(2) - 1; - $pool = $this->get_pool($poolID); + $pool = $this->get_single_pool($poolID); $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 + 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 @@ -784,7 +767,7 @@ class Pools extends Extension $query .= "AND i.rating IN (".Ratings::privs_to_sql(Ratings::get_user_class_privs($user)).")"; } if (Extension::is_enabled(TrashInfo::KEY)) { - $query .= $database->scoreql_to_sql(" AND trash = SCORE_BOOL_N "); + $query .= $database->scoreql_to_sql(" AND trash = SCORE_BOOL_N "); } $result = $database->get_all( @@ -809,52 +792,6 @@ class Pools extends Extension $this->theme->view_pool($pool, $images, $pageNumber + 1, $totalPages); } - /** - * This function gets the current order of images from a given pool. - * #return Image[] Array of image objects. - */ - private function edit_posts(int $poolID): array - { - global $database; - - $result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $poolID]); - $images = []; - - while ($row = $result->fetch()) { - $image = Image::by_id((int)$row["image_id"]); - $images[] = [$image]; - } - - return $images; - } - - /** - * WE GET THE ORDER OF THE IMAGES BUT HERE WE SEND KEYS ADDED IN ARRAY TO GET THE ORDER IN THE INPUT VALUE. - * - * #return Image[] - */ - private function edit_order(int $poolID): array - { - global $database; - - $result = $database->execute("SELECT image_id FROM pool_images WHERE pool_id=:pid ORDER BY image_order ASC", ["pid" => $poolID]); - $images = []; - - while ($row = $result->fetch()) { - $image = $database->get_row( - " - SELECT * FROM images AS i - INNER JOIN pool_images AS p ON i.id = p.image_id - WHERE pool_id=:pid AND i.id=:iid", - ["pid" => $poolID, "iid" => (int)$row['image_id']] - ); - $image = ($image ? new Image($image) : null); - $images[] = [$image]; - } - - return $images; - } - /** * HERE WE NUKE ENTIRE POOL. WE REMOVE POOLS AND POSTS FROM REMOVED POOL AND HISTORIES ENTRIES FROM REMOVED POOL. */ @@ -948,13 +885,15 @@ class Pools extends Extension } } elseif ($entry['action'] == 1) { // DELETE ENTRIES - foreach ($images as $image) { - $imageID = $image; - $this->delete_post($poolID, $imageID); - + foreach ($images as $imageID) { + $database->execute( + "DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid", + ["pid" => $poolID, "iid" => $imageID] + ); $imageArray .= " " . $imageID; $newAction = 0; } + $this->update_count($poolID); } else { // FIXME: should this throw an exception instead? log_error("pools", "Invalid history action."); @@ -974,7 +913,12 @@ class Pools extends Extension { global $database, $config; - if (!$this->check_post($poolID, $imageID)) { + $result = (int)$database->get_one( + "SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid AND image_id=:iid", + ["pid" => $poolID, "iid" => $imageID] + ); + + if ($result == 0) { if ($config->get_bool(PoolsConfig::AUTO_INCREMENT_ORDER) && $imageOrder === 0) { $imageOrder = (int)$database->get_one( " @@ -1005,27 +949,12 @@ class Pools extends Extension return true; } - private function update_count($pool_id) + private function update_count(int $pool_id) { global $database; - $database->execute("UPDATE pools SET posts=(SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid) WHERE id=:pid", ["pid" => $pool_id]); - } - - /** - * HERE WE REMOVE A SIMPLE POST FROM POOL. - * USED WITH FOREACH IN revert_history() & onTagTermParse(). - */ - private function delete_post(int $poolID, int $imageID, bool $history = false) - { - global $database; - - $database->execute("DELETE FROM pool_images WHERE pool_id = :pid AND image_id = :iid", ["pid" => $poolID, "iid" => $imageID]); - - $this->update_count($poolID); - - if ($history) { - $count = (int)$database->get_one("SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid", ["pid" => $poolID]); - $this->add_history($poolID, 0, (string)$imageID, $count); - } + $database->execute( + "UPDATE pools SET posts=(SELECT COUNT(*) FROM pool_images WHERE pool_id=:pid) WHERE id=:pid", + ["pid" => $pool_id] + ); } } diff --git a/ext/pools/test.php b/ext/pools/test.php index 2776a98d..fc9d78ff 100644 --- a/ext/pools/test.php +++ b/ext/pools/test.php @@ -39,6 +39,7 @@ class PoolsTest extends ShimmiePHPUnitTestCase global $config; $config->set_bool(PoolsConfig::ADDER_ON_VIEW_IMAGE, true); $config->set_bool(PoolsConfig::INFO_ON_VIEW_IMAGE, true); + $config->set_bool(PoolsConfig::SHOW_NAV_LINKS, true); $this->get_page("post/view/{$image_ids[0]}"); $this->assert_text("Pool"); diff --git a/ext/pools/theme.php b/ext/pools/theme.php index e70aaefd..8988674f 100644 --- a/ext/pools/theme.php +++ b/ext/pools/theme.php @@ -11,16 +11,16 @@ class PoolsTheme extends Themelet global $page; $linksPools = []; - foreach ($navIDs as $poolID => $pool) { - $linksPools[] = "" . html_escape($pool['info']['title']) . ""; + foreach ($navIDs as $poolID => $poolInfo) { + $linksPools[] = "" . html_escape($poolInfo['info']->title) . ""; - if (array_key_exists('nav', $pool)) { + if (!empty($poolInfo['nav'])) { $navlinks = ""; - if (!empty($pool['nav']['prev'])) { - $navlinks .= 'Prev'; + if (!empty($poolInfo['nav']['prev'])) { + $navlinks .= 'Prev'; } - if (!empty($pool['nav']['next'])) { - $navlinks .= 'Next'; + if (!empty($poolInfo['nav']['next'])) { + $navlinks .= 'Next'; } if (!empty($navlinks)) { $navlinks .= "
"; @@ -38,7 +38,7 @@ class PoolsTheme extends Themelet { $h = ""; foreach ($pools as $pool) { - $h .= ""; + $h .= ""; } return "\n" . make_form(make_link("pool/add_post")) . " - + ' . make_form(make_link('pool/edit')) . ' - + ' . make_form(make_link('pool/order')) . ' - + '; - if ($user->id == $pool['user_id'] || $user->can(Permissions::POOLS_ADMIN)) { + if ($user->id == $pool->user_id || $user->can(Permissions::POOLS_ADMIN)) { $editor .= "