2026-03-14 21:45:58 +01:00
< ? php
2026-03-18 22:20:20 +01:00
namespace MintyPHP\Module\Bookmarks\Repository ;
2026-03-14 21:45:58 +01:00
use MintyPHP\DB ;
2026-03-18 22:20:20 +01:00
use MintyPHP\Repository\Support\RepoQuery ;
use MintyPHP\Repository\Support\RepositoryArrayHelper ;
2026-03-14 21:45:58 +01:00
class BookmarkRepository implements BookmarkRepositoryInterface
{
private function unwrapList ( mixed $rows ) : array
{
2026-03-18 22:20:20 +01:00
return RepositoryArrayHelper :: unwrapList ( $rows , 'user_bookmarks' );
2026-03-14 21:45:58 +01:00
}
2026-03-18 22:20:20 +01:00
public function listByUser ( int $userId , array $options = []) : array
2026-03-14 21:45:58 +01:00
{
if ( $userId <= 0 ) {
return [];
}
2026-03-18 22:20:20 +01:00
[ $limit , $offset ] = RepoQuery :: sanitizeLimitOffset ( $options , 100 , 1 , 100 );
2026-03-14 21:45:58 +01:00
$rows = DB :: select (
2026-03-18 22:20:20 +01:00
'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
2026-03-14 21:45:58 +01:00
);
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 ;
}
}
2026-03-18 22:20:20 +01:00
/** @return list<array<string, mixed>> */
public function listByGroup ( int $userId , int $groupId ) : array
2026-03-14 21:45:58 +01:00
{
2026-03-18 22:20:20 +01:00
if ( $userId <= 0 || $groupId <= 0 ) {
return [];
2026-03-14 21:45:58 +01:00
}
2026-03-18 22:20:20 +01:00
$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 );
}
2026-03-14 21:45:58 +01:00
2026-03-18 22:20:20 +01:00
public function unsetGroupId ( int $bookmarkId , int $userId , int $sortOrder ) : bool
{
if ( $bookmarkId <= 0 || $userId <= 0 || $sortOrder <= 0 ) {
2026-03-14 21:45:58 +01:00
return false ;
}
2026-03-18 22:20:20 +01:00
$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 ;
2026-03-14 21:45:58 +01:00
}
}