Files
breadcrumb-the-shire/modules/bookmarks/lib/Module/Bookmarks/Repository/BookmarkRepository.php
fs 8f6c9951c1 refactor(bookmarks): remove factory chain, interfaces, and duplicated sort logic
Remove BookmarkRepositoryFactory, BookmarkServicesFactory, and all 3
repository interfaces — single-consumer abstractions with no
polymorphism. Simplify container registrar to wire directly. Extract
duplicated updateSortOrders() (60 identical lines in two repos) into
SortOrderTrait. Consolidate icon labels from template into
BookmarkService::allowedGroupIconLabels() single source of truth.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 12:10:05 +01:00

220 lines
6.6 KiB
PHP

<?php
namespace MintyPHP\Module\Bookmarks\Repository;
use MintyPHP\DB;
use MintyPHP\Repository\Support\RepoQuery;
use MintyPHP\Repository\Support\RepositoryArrayHelper;
class BookmarkRepository
{
use SortOrderTrait;
protected function sortOrderTableName(): string
{
return 'user_bookmarks';
}
private function unwrapList(mixed $rows): array
{
return RepositoryArrayHelper::unwrapList($rows, 'user_bookmarks');
}
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, group_id, name, url, sort_order, created, modified from user_bookmarks where user_id = ? order by sort_order, id limit ? offset ?',
(string) $userId,
(string) $limit,
(string) $offset
);
return $this->unwrapList($rows);
}
public function nextBookmarkSortOrder(int $userId, ?int $groupId): int
{
if ($userId <= 0) {
return 1;
}
if ($groupId !== null && $groupId > 0) {
$max = DB::selectValue(
'select COALESCE(max(sort_order), 0) from user_bookmarks where user_id = ? and group_id = ?',
(string) $userId,
(string) $groupId
);
return max(1, ((int) $max) + 1);
}
$max = DB::selectValue(
'select COALESCE(max(sort_order), 0) from user_bookmarks where user_id = ? and group_id is NULL',
(string) $userId
);
return max(1, ((int) $max) + 1);
}
public function countByUser(int $userId): int
{
if ($userId <= 0) {
return 0;
}
$count = DB::selectValue(
'select count(*) from user_bookmarks 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, group_id, name, url, sort_order, created, modified from user_bookmarks where id = ? and user_id = ?',
(string) $id,
(string) $userId
);
$list = $this->unwrapList($rows);
return $list[0] ?? false;
}
public function findByUserAndUrl(int $userId, string $url): array|false
{
$url = trim($url);
if ($userId <= 0 || $url === '') {
return false;
}
$rows = DB::select(
'select id, user_id, group_id, name, url, sort_order, created, modified from user_bookmarks where user_id = ? and url = ? order by id desc limit 1',
(string) $userId,
$url
);
$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'] ?? ''));
$url = trim((string) ($data['url'] ?? ''));
$groupId = isset($data['group_id']) ? (int) $data['group_id'] : null;
$sortOrder = (int) ($data['sort_order'] ?? 0);
if ($userId <= 0 || $name === '' || $url === '') {
return false;
}
$groupIdParam = ($groupId !== null && $groupId > 0) ? (string) $groupId : null;
return DB::insert(
'insert into user_bookmarks (user_id, group_id, name, url, sort_order, created) values (?,?,?,?,?,NOW())',
(string) $userId,
$groupIdParam,
$name,
$url,
(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('group_id', $data)) {
$sets[] = 'group_id = ?';
$groupId = $data['group_id'];
$params[] = ($groupId !== null && (int) $groupId > 0) ? (string) (int) $groupId : null;
}
if (array_key_exists('url', $data)) {
$url = trim((string) $data['url']);
if ($url === '') {
return false;
}
$sets[] = 'url = ?';
$params[] = $url;
}
if (array_key_exists('sort_order', $data)) {
$sortOrder = (int) $data['sort_order'];
if ($sortOrder <= 0) {
return false;
}
$sets[] = 'sort_order = ?';
$params[] = (string) $sortOrder;
}
if ($sets === []) {
return false;
}
$params[] = (string) $id;
$params[] = (string) $userId;
$affected = DB::update(
'update user_bookmarks 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_bookmarks where id = ? and user_id = ?',
(string) $id,
(string) $userId
);
return $deleted !== false && (int) $deleted > 0;
}
/** @return list<array<string, mixed>> */
public function listByGroup(int $userId, int $groupId): array
{
if ($userId <= 0 || $groupId <= 0) {
return [];
}
$rows = DB::select(
'select id, user_id, group_id, name, url, sort_order from user_bookmarks where user_id = ? and group_id = ? order by sort_order, id',
(string) $userId,
(string) $groupId
);
return $this->unwrapList($rows);
}
public function unsetGroupId(int $bookmarkId, int $userId, int $sortOrder): bool
{
if ($bookmarkId <= 0 || $userId <= 0 || $sortOrder <= 0) {
return false;
}
$updated = DB::update(
'update user_bookmarks set group_id = NULL, sort_order = ? where id = ? and user_id = ?',
(string) $sortOrder,
(string) $bookmarkId,
(string) $userId
);
return $updated !== false;
}
}