227 lines
7.1 KiB
PHP
227 lines
7.1 KiB
PHP
<?php
|
|
namespace Misuzu\Comments;
|
|
|
|
use InvalidArgumentException;
|
|
use RuntimeException;
|
|
use Index\Db\{DbConnection,DbStatement,DbStatementCache};
|
|
use Misuzu\Pagination;
|
|
use Misuzu\Users\UserInfo;
|
|
|
|
class CommentsCategoriesData {
|
|
private DbStatementCache $cache;
|
|
|
|
public function __construct(DbConnection $dbConn) {
|
|
$this->cache = new DbStatementCache($dbConn);
|
|
}
|
|
|
|
public function countCategories(
|
|
UserInfo|string|null $owner = null
|
|
): int {
|
|
if($owner instanceof UserInfo)
|
|
$owner = $owner->id;
|
|
|
|
$hasOwner = $owner !== null;
|
|
|
|
$query = 'SELECT COUNT(*) FROM msz_comments_categories';
|
|
if($hasOwner)
|
|
$query .= ' WHERE user_id = ?';
|
|
|
|
$stmt = $this->cache->get($query);
|
|
$stmt->nextParameter($owner);
|
|
$stmt->execute();
|
|
|
|
$count = 0;
|
|
$result = $stmt->getResult();
|
|
|
|
if($result->next())
|
|
$count = $result->getInteger(0);
|
|
|
|
return $count;
|
|
}
|
|
|
|
/** @return \Iterator<int, CommentsCategoryInfo> */
|
|
public function getCategories(
|
|
UserInfo|string|null $owner = null,
|
|
?Pagination $pagination = null
|
|
): iterable {
|
|
if($owner instanceof UserInfo)
|
|
$owner = $owner->id;
|
|
|
|
$hasOwner = $owner !== null;
|
|
$hasPagination = $pagination !== null;
|
|
|
|
$query = <<<SQL
|
|
SELECT category_id, category_name, user_id,
|
|
UNIX_TIMESTAMP(category_created),
|
|
UNIX_TIMESTAMP(category_locked)
|
|
FROM msz_comments_categories
|
|
SQL;
|
|
if($hasOwner)
|
|
$query .= ' WHERE user_id = ?';
|
|
$query .= ' ORDER BY category_id ASC'; // should order by date but no index on
|
|
if($hasPagination)
|
|
$query .= ' LIMIT ? RANGE ?';
|
|
|
|
$stmt = $this->cache->get($query);
|
|
|
|
if($hasOwner)
|
|
$stmt->nextParameter($owner);
|
|
if($hasPagination)
|
|
$pagination->addToStatement($stmt);
|
|
|
|
$stmt->execute();
|
|
|
|
return $stmt->getResultIterator(CommentsCategoryInfo::fromResult(...));
|
|
}
|
|
|
|
public function getCategory(
|
|
?string $categoryId = null,
|
|
?string $name = null,
|
|
CommentsPostInfo|string|null $postInfo = null
|
|
): CommentsCategoryInfo {
|
|
$hasCategoryId = $categoryId !== null;
|
|
$hasName = $name !== null;
|
|
$hasPostInfo = $postInfo !== null;
|
|
|
|
if(!$hasCategoryId && !$hasName && !$hasPostInfo)
|
|
throw new InvalidArgumentException('At least one of the arguments must be set.');
|
|
// there has got to be a better way to do this
|
|
if(($hasCategoryId && ($hasName || $hasPostInfo)) || ($hasName && ($hasCategoryId || $hasPostInfo)) || ($hasPostInfo && ($hasCategoryId || $hasName)))
|
|
throw new InvalidArgumentException('Only one of the arguments may be specified.');
|
|
|
|
$query = <<<SQL
|
|
SELECT category_id, category_name, user_id,
|
|
UNIX_TIMESTAMP(category_created),
|
|
UNIX_TIMESTAMP(category_locked)
|
|
FROM msz_comments_categories
|
|
SQL;
|
|
$value = null;
|
|
if($hasCategoryId) {
|
|
$query .= ' WHERE category_id = ?';
|
|
$value = $categoryId;
|
|
}
|
|
if($hasName) {
|
|
$query .= ' WHERE category_name = ?';
|
|
$value = $name;
|
|
}
|
|
if($hasPostInfo) {
|
|
if($postInfo instanceof CommentsPostInfo) {
|
|
$query .= ' WHERE category_id = ?';
|
|
$value = $postInfo->categoryId;
|
|
} else {
|
|
$query .= ' WHERE category_id = (SELECT category_id FROM msz_comments_posts WHERE comment_id = ?)';
|
|
$value = $postInfo;
|
|
}
|
|
}
|
|
|
|
$stmt = $this->cache->get($query);
|
|
$stmt->nextParameter($value);
|
|
$stmt->execute();
|
|
$result = $stmt->getResult();
|
|
|
|
if(!$result->next())
|
|
throw new RuntimeException('Comments category not found.');
|
|
|
|
return CommentsCategoryInfo::fromResult($result);
|
|
}
|
|
|
|
private function createCategoryInternal(
|
|
string $name,
|
|
UserInfo|string|null $owner = null,
|
|
): DbStatement {
|
|
if($owner instanceof UserInfo)
|
|
$owner = $owner->id;
|
|
|
|
$name = trim($name);
|
|
if(empty($name))
|
|
throw new InvalidArgumentException('$name may not be empty.');
|
|
|
|
$stmt = $this->cache->get(<<<SQL
|
|
INSERT INTO msz_comments_categories (
|
|
category_name, user_id
|
|
) VALUES (?, ?)
|
|
SQL);
|
|
$stmt->nextParameter($name);
|
|
$stmt->nextParameter($owner);
|
|
$stmt->execute();
|
|
|
|
return $stmt;
|
|
}
|
|
|
|
public function createCategory(
|
|
string $name,
|
|
UserInfo|string|null $owner = null
|
|
): CommentsCategoryInfo {
|
|
return $this->getCategory(
|
|
categoryId: (string)$this->createCategoryInternal($name, $owner)->lastInsertId,
|
|
);
|
|
}
|
|
|
|
public function ensureCategoryExists(
|
|
string $name,
|
|
UserInfo|string|null $owner = null
|
|
): void {
|
|
$stmt = $this->cache->get(<<<SQL
|
|
SELECT COUNT(*)
|
|
FROM msz_comments_categories
|
|
WHERE category_name = ?
|
|
SQL);
|
|
$stmt->nextParameter($name);
|
|
$stmt->execute();
|
|
|
|
$result = $stmt->getResult();
|
|
if(!$result->next())
|
|
throw new RuntimeException('failed to query for the existence of comments category');
|
|
|
|
if(!$result->getBoolean(0))
|
|
$this->createCategoryInternal($name, $owner);
|
|
}
|
|
|
|
public function deleteCategory(CommentsCategoryInfo|string $category): void {
|
|
if($category instanceof CommentsCategoryInfo)
|
|
$category = $category->id;
|
|
|
|
$stmt = $this->cache->get(<<<SQL
|
|
DELETE FROM msz_comments_categories
|
|
WHERE category_id = ?
|
|
SQL);
|
|
$stmt->nextParameter($category);
|
|
$stmt->execute();
|
|
}
|
|
|
|
public function updateCategory(
|
|
CommentsCategoryInfo|string $infoOrId,
|
|
?string $name = null,
|
|
?bool $locked = null,
|
|
UserInfo|string|false|null $ownerInfo = null
|
|
): void {
|
|
$fields = [];
|
|
$values = [];
|
|
|
|
if($name !== null) {
|
|
if(trim($name) === '')
|
|
throw new InvalidArgumentException('$name must be null or a non-empty string.');
|
|
|
|
$fields[] = 'category_name = ?';
|
|
$values[] = $name;
|
|
}
|
|
|
|
if($locked !== null)
|
|
$fields[] = $locked ? 'category_locked = COALESCE(category_locked, NOW())' : 'category_locked = NULL';
|
|
|
|
if($ownerInfo !== null) {
|
|
if($ownerInfo === false) {
|
|
$fields[] = 'user_id = NULL';
|
|
} else {
|
|
$fields[] = 'user_id = ?';
|
|
$values[] = $ownerInfo instanceof UserInfo ? $ownerInfo->id : $ownerInfo;
|
|
}
|
|
}
|
|
|
|
$stmt = $this->cache->get(sprintf('UPDATE msz_comments_categories SET %s WHERE category_id = ?', implode(', ', $fields)));
|
|
foreach($values as $value)
|
|
$stmt->nextParameter($value);
|
|
$stmt->nextParameter($infoOrId instanceof CommentsCategoryInfo ? $infoOrId->id : $infoOrId);
|
|
$stmt->execute();
|
|
}
|
|
}
|