mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
213 lines
7.4 KiB
PHP
213 lines
7.4 KiB
PHP
<?php
|
|
|
|
namespace Gazelle\Manager;
|
|
|
|
use Gazelle\Error400;
|
|
|
|
class Comment extends \Gazelle\BaseManager {
|
|
final public const CATALOG = '%s_comments_%d_cat_%d';
|
|
|
|
protected function className(string $page): string {
|
|
return match ($page) {
|
|
'artist' => \Gazelle\Comment\Artist::class,
|
|
'collages' => \Gazelle\Comment\Collage::class,
|
|
'requests' => \Gazelle\Comment\Request::class,
|
|
'torrents' => \Gazelle\Comment\Torrent::class,
|
|
default => Error400::error("no comments for " . html_escape($page)),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Post a comment on an artist, request or torrent page.
|
|
*/
|
|
public function create(
|
|
\Gazelle\User $user,
|
|
string $page,
|
|
int $pageId,
|
|
string $body,
|
|
): \Gazelle\Comment\Artist|\Gazelle\Comment\Collage|\Gazelle\Comment\Request|\Gazelle\Comment\Torrent {
|
|
self::$db->prepared_query("
|
|
INSERT INTO comments
|
|
(Page, PageID, AuthorID, Body)
|
|
VALUES (?, ?, ?, ?)
|
|
", $page, $pageId, $user->id(), $body
|
|
);
|
|
$postId = self::$db->inserted_id();
|
|
$catalogueId = (int)self::$db->scalar("
|
|
SELECT floor((ceil(count(*) / ?) - 1) * ? / ?)
|
|
FROM comments
|
|
WHERE Page = ? AND PageID = ?
|
|
", TORRENT_COMMENTS_PER_PAGE, TORRENT_COMMENTS_PER_PAGE, THREAD_CATALOGUE, $page, $pageId
|
|
);
|
|
self::$cache->delete_multi([
|
|
sprintf(self::CATALOG, $page, $pageId, $catalogueId),
|
|
"{$page}_comments_{$pageId}"
|
|
]);
|
|
if ($page == 'collages') {
|
|
self::$cache->delete_value("{$page}_comments_recent_{$pageId}");
|
|
}
|
|
(new \Gazelle\User\Notification\Quote($user))
|
|
->create($page, $pageId, $postId, $body);
|
|
(new Subscription())->flushPage($page, $pageId);
|
|
|
|
$className = $this->className($page);
|
|
return new $className($pageId, 0, $postId); /** @phpstan-ignore-line */
|
|
}
|
|
|
|
public function findById(
|
|
int $postId,
|
|
): \Gazelle\Comment\Artist|\Gazelle\Comment\Collage|\Gazelle\Comment\Request|\Gazelle\Comment\Torrent|null {
|
|
[$page, $pageId] = self::$db->row("
|
|
SELECT Page, PageID FROM comments WHERE ID = ?
|
|
", $postId
|
|
);
|
|
if (is_null($page)) {
|
|
return null;
|
|
}
|
|
$className = $this->className($page);
|
|
return new $className($pageId, 0, $postId); /** @phpstan-ignore-line */
|
|
}
|
|
|
|
public function findBodyById(int $postId): ?string {
|
|
$body = self::$db->scalar("
|
|
SELECT Body FROM comments WHERE ID = ?
|
|
", $postId
|
|
);
|
|
return is_null($body) ? null : (string)$body;
|
|
}
|
|
|
|
public function merge(string $page, int $pageId, int $targetPageId): int {
|
|
self::$db->prepared_query("
|
|
UPDATE comments SET
|
|
PageID = ?
|
|
WHERE Page = ? AND PageID = ?
|
|
", $targetPageId, $page, $pageId
|
|
);
|
|
$affected = self::$db->affected_rows();
|
|
$pageCount = (int)self::$db->scalar("
|
|
SELECT ceil(count(*) / ?) AS Pages
|
|
FROM comments
|
|
WHERE Page = ? AND PageID = ?
|
|
GROUP BY PageID
|
|
", TORRENT_COMMENTS_PER_PAGE, $page, $targetPageId
|
|
);
|
|
$last = floor((TORRENT_COMMENTS_PER_PAGE * $pageCount - TORRENT_COMMENTS_PER_PAGE) / THREAD_CATALOGUE);
|
|
|
|
// quote notifications
|
|
self::$db->prepared_query("
|
|
UPDATE users_notify_quoted SET
|
|
PageID = ?
|
|
WHERE Page = ? AND PageID = ?
|
|
", $targetPageId, $page, $pageId
|
|
);
|
|
|
|
// comment subscriptions
|
|
$subscription = new \Gazelle\Manager\Subscription();
|
|
$subscription->move($page, $pageId, $targetPageId);
|
|
|
|
for ($i = 0; $i <= $last; ++$i) {
|
|
self::$cache->delete_value(sprintf(self::CATALOG, $page, $targetPageId, $i));
|
|
}
|
|
self::$cache->delete_value("{$page}_comments_{$targetPageId}");
|
|
return $affected;
|
|
}
|
|
|
|
/**
|
|
* Remove all comments on $page/$pageId (handle quote notifications and subscriptions as well)
|
|
*
|
|
* @return int number of comments that were removed
|
|
*/
|
|
public function remove(string $page, int $pageId): int {
|
|
$qid = self::$db->get_query_id();
|
|
|
|
$pageCount = (int)self::$db->scalar("
|
|
SELECT ceil(count(*) / ?) AS Pages
|
|
FROM comments
|
|
WHERE Page = ? AND PageID = ?
|
|
GROUP BY PageID
|
|
", TORRENT_COMMENTS_PER_PAGE, $page, $pageId
|
|
);
|
|
if ($pageCount === 0) {
|
|
return 0;
|
|
}
|
|
$last = floor((TORRENT_COMMENTS_PER_PAGE * $pageCount - TORRENT_COMMENTS_PER_PAGE) / THREAD_CATALOGUE);
|
|
|
|
self::$db->prepared_query("
|
|
DELETE FROM comments WHERE Page = ? AND PageID = ?
|
|
", $page, $pageId
|
|
);
|
|
$affected = self::$db->affected_rows();
|
|
|
|
// literally, move the comment thread to nowhere i.e. delete
|
|
(new \Gazelle\Manager\Subscription())->move($page, $pageId, null);
|
|
|
|
self::$db->prepared_query("
|
|
DELETE FROM users_notify_quoted WHERE Page = ? AND PageID = ?
|
|
", $page, $pageId
|
|
);
|
|
self::$db->set_query_id($qid);
|
|
|
|
// Clear cache
|
|
for ($i = 0; $i <= $last; ++$i) {
|
|
self::$cache->delete_value(sprintf(self::CATALOG, $page, $pageId, $i));
|
|
}
|
|
self::$cache->delete_value($page . '_comments_' . $pageId);
|
|
|
|
return $affected;
|
|
}
|
|
|
|
public function loadEdits(string $page, int $postId): array {
|
|
$key = "edit_{$page}_{$postId}";
|
|
$edits = self::$cache->get_value($key);
|
|
if ($edits === false) {
|
|
self::$db->prepared_query("
|
|
SELECT EditUser, EditTime, Body
|
|
FROM comments_edits
|
|
WHERE Page = ?
|
|
AND PostID = ?
|
|
ORDER BY EditTime DESC
|
|
", $page, $postId
|
|
);
|
|
$edits = self::$db->to_array(false, MYSQLI_NUM, false);
|
|
self::$cache->cache_value($key, $edits, 7200);
|
|
}
|
|
return $edits;
|
|
}
|
|
|
|
/**
|
|
* Load recent collage comments. Used for displaying recent comments on collage pages.
|
|
* @return array ($Comments)
|
|
* $Comments
|
|
* ID: Comment ID
|
|
* Body: Comment body
|
|
* AuthorID: Author of comment
|
|
* Username: Their username
|
|
* AddedTime: Date of comment creation
|
|
*/
|
|
public function collageSummary($collageId, $count = 5): array {
|
|
$key = "collages_comments_recent_$collageId";
|
|
$list = self::$cache->get_value($key);
|
|
if ($list === false) {
|
|
$qid = self::$db->get_query_id();
|
|
self::$db->prepared_query("
|
|
SELECT c.ID AS id,
|
|
c.Body as body,
|
|
c.AuthorID as author_id,
|
|
c.AddedTime as added
|
|
FROM comments AS c
|
|
LEFT JOIN users_main AS um ON (um.ID = c.AuthorID)
|
|
WHERE c.Page = ? AND c.PageID = ?
|
|
ORDER BY c.ID DESC
|
|
LIMIT ?
|
|
", 'collages', $collageId, $count
|
|
);
|
|
$list = self::$db->to_array(false, MYSQLI_ASSOC, false);
|
|
self::$db->set_query_id($qid);
|
|
if (count($list)) {
|
|
self::$cache->cache_value($key, $list, 7200);
|
|
}
|
|
}
|
|
return $list;
|
|
}
|
|
}
|