feat: extract bookmarks as standalone module with MintyPHP\Module\Bookmarks namespace
Moves bookmarks from core hardcoding into modules/bookmarks/ as a
fully self-contained module, following the same pattern as addressbook.
Module contributions via platform slots:
- aside.tab_panel: bookmark sidebar panel
- topbar.right_item: bookmark toggle button
- layout.body_end_template: bookmark/group dialogs
- layout.head_style: bookmark CSS (form + sidebar)
- runtime.component: bookmark-save and bookmark-panel (phase: late)
- search.resource_item: bookmarks in global search (user-scoped via {{userId}})
Backend fully in module namespace (MintyPHP\Module\Bookmarks\*):
- Service: BookmarkService, BookmarkServicesFactory, BookmarkRepositoryFactory
- Repository: BookmarkRepository, BookmarkGroupRepository, BookmarkNavigationRepository
- Support: BookmarkUrlNormalizer
- Providers: BookmarksSessionProvider, BookmarksLayoutProvider, BookmarksSearchProvider
Core cleanup:
- Removed all bookmark-specific markup from core templates
- Removed core DI registrations for bookmark services
- Removed core bookmark pages, JS, CSS
- AuthSessionTenantContextService delegates to module SessionProvider
Architecture guards:
- NoBookmarksHardcodingTest: verifies zero bookmark references in core
- testModuleClassesUseModuleNamespace: prevents core namespace leakage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,190 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Repository\User;
|
||||
|
||||
interface BookmarkGroupRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param array{limit?: int, offset?: int} $options
|
||||
* @return list<array<string, mixed>>
|
||||
*/
|
||||
public function listByUser(int $userId, array $options = []): array;
|
||||
|
||||
public function countByUser(int $userId): int;
|
||||
|
||||
/** @return array<string, mixed>|false */
|
||||
public function findById(int $id, int $userId): array|false;
|
||||
|
||||
public function create(array $data): int|false;
|
||||
|
||||
public function update(int $id, int $userId, array $data): bool;
|
||||
|
||||
public function delete(int $id, int $userId): bool;
|
||||
|
||||
/** @param list<array{id: int, sort_order: int}> $idOrderPairs */
|
||||
public function updateSortOrders(int $userId, array $idOrderPairs): bool;
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Repository\User;
|
||||
|
||||
use MintyPHP\DB;
|
||||
|
||||
class BookmarkNavigationRepository implements BookmarkNavigationRepositoryInterface
|
||||
{
|
||||
public function nextRootSortOrder(int $userId): int
|
||||
{
|
||||
if ($userId <= 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
$max = DB::selectValue(
|
||||
'select GREATEST(
|
||||
COALESCE((select max(sort_order) from user_bookmark_groups where user_id = ?), 0),
|
||||
COALESCE((select max(sort_order) from user_bookmarks where user_id = ? and group_id is NULL), 0)
|
||||
)',
|
||||
(string) $userId,
|
||||
(string) $userId
|
||||
);
|
||||
|
||||
return max(1, ((int) $max) + 1);
|
||||
}
|
||||
|
||||
public function updateRootSortOrders(int $userId, array $rootOrderPairs): bool
|
||||
{
|
||||
if ($userId <= 0 || $rootOrderPairs === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$groupPairs = [];
|
||||
$bookmarkPairs = [];
|
||||
$groupIds = [];
|
||||
$bookmarkIds = [];
|
||||
|
||||
foreach ($rootOrderPairs as $pair) {
|
||||
$kind = trim((string) ($pair['kind'] ?? ''));
|
||||
$id = (int) ($pair['id'] ?? 0);
|
||||
$sortOrder = (int) ($pair['sort_order'] ?? 0);
|
||||
if ($id <= 0 || $sortOrder <= 0 || ($kind !== 'group' && $kind !== 'bookmark')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($kind === 'group') {
|
||||
$groupPairs[] = ['id' => $id, 'sort_order' => $sortOrder];
|
||||
$groupIds[] = $id;
|
||||
continue;
|
||||
}
|
||||
|
||||
$bookmarkPairs[] = ['id' => $id, 'sort_order' => $sortOrder];
|
||||
$bookmarkIds[] = $id;
|
||||
}
|
||||
|
||||
if ($groupPairs === [] && $bookmarkPairs === []) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($groupIds !== []) {
|
||||
$uniqueGroupIds = array_values(array_unique($groupIds));
|
||||
$groupCount = DB::selectValue(
|
||||
'select count(*) from user_bookmark_groups where user_id = ? and id in (???)',
|
||||
(string) $userId,
|
||||
array_map('strval', $uniqueGroupIds)
|
||||
);
|
||||
if ((int) $groupCount !== count($uniqueGroupIds)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($bookmarkIds !== []) {
|
||||
$uniqueBookmarkIds = array_values(array_unique($bookmarkIds));
|
||||
$bookmarkCount = DB::selectValue(
|
||||
'select count(*) from user_bookmarks where user_id = ? and group_id is NULL and id in (???)',
|
||||
(string) $userId,
|
||||
array_map('strval', $uniqueBookmarkIds)
|
||||
);
|
||||
if ((int) $bookmarkCount !== count($uniqueBookmarkIds)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$db = DB::handle();
|
||||
try {
|
||||
$db->begin_transaction();
|
||||
|
||||
foreach ($groupPairs as $pair) {
|
||||
$updated = DB::update(
|
||||
'update user_bookmark_groups set sort_order = ? where id = ? and user_id = ?',
|
||||
(string) $pair['sort_order'],
|
||||
(string) $pair['id'],
|
||||
(string) $userId
|
||||
);
|
||||
if ($updated === false) {
|
||||
$db->rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($bookmarkPairs as $pair) {
|
||||
$updated = DB::update(
|
||||
'update user_bookmarks set sort_order = ? where id = ? and user_id = ? and group_id is NULL',
|
||||
(string) $pair['sort_order'],
|
||||
(string) $pair['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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Repository\User;
|
||||
|
||||
interface BookmarkNavigationRepositoryInterface
|
||||
{
|
||||
public function nextRootSortOrder(int $userId): int;
|
||||
|
||||
/** @param list<array{kind: 'group'|'bookmark', id: int, sort_order: int}> $rootOrderPairs */
|
||||
public function updateRootSortOrders(int $userId, array $rootOrderPairs): bool;
|
||||
}
|
||||
@@ -1,308 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Repository\User;
|
||||
|
||||
use MintyPHP\DB;
|
||||
|
||||
class BookmarkRepository implements BookmarkRepositoryInterface
|
||||
{
|
||||
private function unwrapList(mixed $rows): array
|
||||
{
|
||||
if (!is_array($rows)) {
|
||||
return [];
|
||||
}
|
||||
$list = [];
|
||||
foreach ($rows as $row) {
|
||||
$data = $row['user_bookmarks'] ?? $row;
|
||||
if (is_array($data)) {
|
||||
$list[] = $data;
|
||||
}
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function listByUser(int $userId): array
|
||||
{
|
||||
if ($userId <= 0) {
|
||||
return [];
|
||||
}
|
||||
$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',
|
||||
(string) $userId
|
||||
);
|
||||
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;
|
||||
}
|
||||
|
||||
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_bookmarks 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_bookmarks 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;
|
||||
}
|
||||
}
|
||||
|
||||
public function clearGroupId(int $groupId, int $userId): bool
|
||||
{
|
||||
if ($groupId <= 0 || $userId <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$db = DB::handle();
|
||||
try {
|
||||
$db->begin_transaction();
|
||||
|
||||
$baseSort = DB::selectValue(
|
||||
'select GREATEST(
|
||||
COALESCE((select max(sort_order) from user_bookmarks where user_id = ? and group_id is NULL), 0),
|
||||
COALESCE((select max(sort_order) from user_bookmark_groups where user_id = ?), 0)
|
||||
)',
|
||||
(string) $userId,
|
||||
(string) $userId
|
||||
);
|
||||
$nextSort = (int) $baseSort;
|
||||
|
||||
$rows = DB::select(
|
||||
'select id from user_bookmarks where user_id = ? and group_id = ? order by sort_order, id',
|
||||
(string) $userId,
|
||||
(string) $groupId
|
||||
);
|
||||
$bookmarks = $this->unwrapList($rows);
|
||||
|
||||
foreach ($bookmarks as $bookmark) {
|
||||
$bookmarkId = (int) ($bookmark['id'] ?? 0);
|
||||
if ($bookmarkId <= 0) {
|
||||
continue;
|
||||
}
|
||||
$nextSort++;
|
||||
$updated = DB::update(
|
||||
'update user_bookmarks set group_id = NULL, sort_order = ? where id = ? and user_id = ?',
|
||||
(string) $nextSort,
|
||||
(string) $bookmarkId,
|
||||
(string) $userId
|
||||
);
|
||||
if ($updated === false) {
|
||||
$db->rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$db->commit();
|
||||
return true;
|
||||
} catch (\Throwable) {
|
||||
try {
|
||||
$db->rollback();
|
||||
} catch (\Throwable) {
|
||||
// no-op
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace MintyPHP\Repository\User;
|
||||
|
||||
interface BookmarkRepositoryInterface
|
||||
{
|
||||
/**
|
||||
* @param array{limit?: int, offset?: int} $options
|
||||
* @return list<array<string, mixed>>
|
||||
*/
|
||||
public function listByUser(int $userId, array $options = []): array;
|
||||
|
||||
public function nextBookmarkSortOrder(int $userId, ?int $groupId): int;
|
||||
|
||||
public function countByUser(int $userId): int;
|
||||
|
||||
/** @return array<string, mixed>|false */
|
||||
public function findById(int $id, int $userId): array|false;
|
||||
|
||||
/** @return array<string, mixed>|false */
|
||||
public function findByUserAndUrl(int $userId, string $url): array|false;
|
||||
|
||||
public function create(array $data): int|false;
|
||||
|
||||
public function update(int $id, int $userId, array $data): bool;
|
||||
|
||||
public function delete(int $id, int $userId): bool;
|
||||
|
||||
/** @param list<array{id: int, sort_order: int}> $idOrderPairs */
|
||||
public function updateSortOrders(int $userId, array $idOrderPairs): bool;
|
||||
|
||||
/** @return list<array<string, mixed>> */
|
||||
public function listByGroup(int $userId, int $groupId): array;
|
||||
|
||||
public function unsetGroupId(int $bookmarkId, int $userId, int $sortOrder): bool;
|
||||
}
|
||||
Reference in New Issue
Block a user