Fix broken tests (H1), align interface signatures with implementations (H3), remove dead code (H4), add missing input guard (M1), replace raw $_SESSION access with SessionStoreInterface (M2), sync update script schema (M4), use shared getAppBase utility (L2), document fragment stripping (L3), and apply app- CSS class prefix convention (L5). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
191 lines
5.4 KiB
PHP
191 lines
5.4 KiB
PHP
<?php
|
|
|
|
namespace MintyPHP\Repository\User;
|
|
|
|
use MintyPHP\DB;
|
|
use MintyPHP\Repository\Support\RepoQuery;
|
|
use MintyPHP\Repository\Support\RepositoryArrayHelper;
|
|
|
|
class BookmarkGroupRepository implements BookmarkGroupRepositoryInterface
|
|
{
|
|
private function unwrapList(mixed $rows): array
|
|
{
|
|
return RepositoryArrayHelper::unwrapList($rows, 'user_bookmark_groups');
|
|
}
|
|
|
|
public function listByUser(int $userId, array $options = []): array
|
|
{
|
|
if ($userId <= 0) {
|
|
return [];
|
|
}
|
|
[$limit, $offset] = RepoQuery::sanitizeLimitOffset($options, 100, 1, 100);
|
|
$rows = DB::select(
|
|
'select id, user_id, name, icon, sort_order, created, modified from user_bookmark_groups where user_id = ? order by sort_order, id limit ? offset ?',
|
|
(string) $userId,
|
|
(string) $limit,
|
|
(string) $offset
|
|
);
|
|
return $this->unwrapList($rows);
|
|
}
|
|
|
|
public function countByUser(int $userId): int
|
|
{
|
|
if ($userId <= 0) {
|
|
return 0;
|
|
}
|
|
$count = DB::selectValue(
|
|
'select count(*) from user_bookmark_groups where user_id = ?',
|
|
(string) $userId
|
|
);
|
|
return $count ? (int) $count : 0;
|
|
}
|
|
|
|
public function findById(int $id, int $userId): array|false
|
|
{
|
|
if ($id <= 0 || $userId <= 0) {
|
|
return false;
|
|
}
|
|
$rows = DB::select(
|
|
'select id, user_id, name, icon, sort_order, created, modified from user_bookmark_groups where id = ? and user_id = ?',
|
|
(string) $id,
|
|
(string) $userId
|
|
);
|
|
$list = $this->unwrapList($rows);
|
|
return $list[0] ?? false;
|
|
}
|
|
|
|
public function create(array $data): int|false
|
|
{
|
|
$userId = (int) ($data['user_id'] ?? 0);
|
|
$name = trim((string) ($data['name'] ?? ''));
|
|
$icon = trim((string) ($data['icon'] ?? 'bi-folder'));
|
|
$sortOrder = (int) ($data['sort_order'] ?? 0);
|
|
if ($userId <= 0 || $name === '' || $icon === '') {
|
|
return false;
|
|
}
|
|
return DB::insert(
|
|
'insert into user_bookmark_groups (user_id, name, icon, sort_order, created) values (?,?,?,?,NOW())',
|
|
(string) $userId,
|
|
$name,
|
|
$icon,
|
|
(string) $sortOrder
|
|
);
|
|
}
|
|
|
|
public function update(int $id, int $userId, array $data): bool
|
|
{
|
|
if ($id <= 0 || $userId <= 0) {
|
|
return false;
|
|
}
|
|
|
|
$sets = [];
|
|
$params = [];
|
|
|
|
if (array_key_exists('name', $data)) {
|
|
$name = trim((string) $data['name']);
|
|
if ($name === '') {
|
|
return false;
|
|
}
|
|
$sets[] = 'name = ?';
|
|
$params[] = $name;
|
|
}
|
|
if (array_key_exists('icon', $data)) {
|
|
$icon = trim((string) $data['icon']);
|
|
if ($icon === '') {
|
|
return false;
|
|
}
|
|
$sets[] = 'icon = ?';
|
|
$params[] = $icon;
|
|
}
|
|
|
|
if ($sets === []) {
|
|
return false;
|
|
}
|
|
|
|
$params[] = (string) $id;
|
|
$params[] = (string) $userId;
|
|
|
|
$affected = DB::update(
|
|
'update user_bookmark_groups set ' . implode(', ', $sets) . ' where id = ? and user_id = ?',
|
|
...$params
|
|
);
|
|
return $affected !== false;
|
|
}
|
|
|
|
public function delete(int $id, int $userId): bool
|
|
{
|
|
if ($id <= 0 || $userId <= 0) {
|
|
return false;
|
|
}
|
|
$deleted = DB::delete(
|
|
'delete from user_bookmark_groups where id = ? and user_id = ?',
|
|
(string) $id,
|
|
(string) $userId
|
|
);
|
|
return $deleted !== false && (int) $deleted > 0;
|
|
}
|
|
|
|
public function updateSortOrders(int $userId, array $idOrderPairs): bool
|
|
{
|
|
if ($userId <= 0 || $idOrderPairs === []) {
|
|
return false;
|
|
}
|
|
|
|
$idList = [];
|
|
foreach ($idOrderPairs as $pair) {
|
|
$id = (int) $pair['id'];
|
|
if ($id <= 0) {
|
|
return false;
|
|
}
|
|
$idList[] = $id;
|
|
}
|
|
$idList = array_values(array_unique($idList));
|
|
|
|
$existingCount = DB::selectValue(
|
|
'select count(*) from user_bookmark_groups where user_id = ? and id in (???)',
|
|
(string) $userId,
|
|
array_map('strval', $idList)
|
|
);
|
|
|
|
if ((int) $existingCount !== count($idList)) {
|
|
return false;
|
|
}
|
|
|
|
$db = DB::handle();
|
|
try {
|
|
$db->begin_transaction();
|
|
|
|
foreach ($idOrderPairs as $pair) {
|
|
$id = (int) $pair['id'];
|
|
$sortOrder = (int) $pair['sort_order'];
|
|
if ($id <= 0 || $sortOrder <= 0) {
|
|
$db->rollback();
|
|
return false;
|
|
}
|
|
|
|
$updated = DB::update(
|
|
'update user_bookmark_groups set sort_order = ? where id = ? and user_id = ?',
|
|
(string) $sortOrder,
|
|
(string) $id,
|
|
(string) $userId
|
|
);
|
|
|
|
if ($updated === false) {
|
|
$db->rollback();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
$db->commit();
|
|
return true;
|
|
} catch (\Throwable) {
|
|
try {
|
|
$db->rollback();
|
|
} catch (\Throwable) {
|
|
// no-op
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|