diff --git a/eZ/Publish/API/Repository/Tests/LocationServiceTest.php b/eZ/Publish/API/Repository/Tests/LocationServiceTest.php index 153f768ba7..f92c9ab5b1 100644 --- a/eZ/Publish/API/Repository/Tests/LocationServiceTest.php +++ b/eZ/Publish/API/Repository/Tests/LocationServiceTest.php @@ -1965,6 +1965,7 @@ public function testBookmarksAreSwappedAfterSwapLocation() $mediaLocationId = $this->generateId('location', 43); $demoDesignLocationId = $this->generateId('location', 56); + $contactUsLocationId = $this->generateId('location', 60); /* BEGIN: Use Case */ $locationService = $repository->getLocationService(); @@ -1972,6 +1973,7 @@ public function testBookmarksAreSwappedAfterSwapLocation() $mediaLocation = $locationService->loadLocation($mediaLocationId); $demoDesignLocation = $locationService->loadLocation($demoDesignLocationId); + $contactUsLocation = $locationService->loadLocation($contactUsLocationId); // Bookmark locations $bookmarkService->createBookmark($mediaLocation); @@ -1980,13 +1982,13 @@ public function testBookmarksAreSwappedAfterSwapLocation() $beforeSwap = $bookmarkService->loadBookmarks(); // Swaps the content referred to by the locations - $locationService->swapLocation($mediaLocation, $demoDesignLocation); + $locationService->swapLocation($demoDesignLocation, $contactUsLocation); $afterSwap = $bookmarkService->loadBookmarks(); /* END: Use Case */ - $this->assertEquals($beforeSwap->items[0]->id, $afterSwap->items[1]->id); - $this->assertEquals($beforeSwap->items[1]->id, $afterSwap->items[0]->id); + $this->assertEquals($contactUsLocationId, $afterSwap->items[0]->id); + $this->assertEquals($beforeSwap->items[1]->id, $afterSwap->items[1]->id); } /** diff --git a/eZ/Publish/Core/Persistence/Cache/BookmarkHandler.php b/eZ/Publish/Core/Persistence/Cache/BookmarkHandler.php index 0966283473..9c901b6f54 100644 --- a/eZ/Publish/Core/Persistence/Cache/BookmarkHandler.php +++ b/eZ/Publish/Core/Persistence/Cache/BookmarkHandler.php @@ -85,6 +85,8 @@ function (Bookmark $bookmark) { } /** + * @deprecated The "BookmarkHandler::loadUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::find()" and "Criterion\IsBookmarked" instead. + * * {@inheritdoc} */ public function loadUserBookmarks(int $userId, int $offset = 0, int $limit = -1): array @@ -99,6 +101,8 @@ public function loadUserBookmarks(int $userId, int $offset = 0, int $limit = -1) } /** + * @deprecated The "BookmarkHandler::countUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::count()" and "Criterion\IsBookmarked" instead. + * * {@inheritdoc} */ public function countUserBookmarks(int $userId): int diff --git a/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway.php b/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway.php index 8e69147284..d7355417f1 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway.php +++ b/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway.php @@ -44,6 +44,8 @@ abstract public function loadBookmarkDataByUserIdAndLocationId(int $userId, arra /** * Load data for all bookmarks owned by given $userId. * + * @deprecated Gateway::loadUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::find()" and "Criterion\IsBookmarked" instead. + * * @param int $userId ID of user * @param int $offset Offset to start listing from, 0 by default * @param int $limit Limit for the listing. -1 by default (no limit) @@ -55,6 +57,8 @@ abstract public function loadUserBookmarks(int $userId, int $offset = 0, int $li /** * Count bookmarks owned by given $userId. * + * @deprecated The "Gateway::countUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::count()" and "Criterion\IsBookmarked" instead. + * * @param int $userId ID of user * * @return int diff --git a/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway/DoctrineDatabase.php b/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway/DoctrineDatabase.php index 7673435d89..25b98677a3 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway/DoctrineDatabase.php +++ b/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway/DoctrineDatabase.php @@ -101,6 +101,8 @@ public function loadBookmarkDataByUserIdAndLocationId(int $userId, array $locati } /** + * @deprecated The "DoctrineDatabase::loadUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::find()" and "Criterion\IsBookmarked" instead. + * * {@inheritdoc} */ public function loadUserBookmarks(int $userId, int $offset = 0, int $limit = -1): array @@ -123,6 +125,8 @@ public function loadUserBookmarks(int $userId, int $offset = 0, int $limit = -1) } /** + * @deprecated The "DoctrineDatabase::countUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::count()" and "Criterion\IsBookmarked" instead. + * * {@inheritdoc} */ public function countUserBookmarks(int $userId): int diff --git a/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway/ExceptionConversion.php b/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway/ExceptionConversion.php index 9aaf17e437..b9f299fd56 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway/ExceptionConversion.php +++ b/eZ/Publish/Core/Persistence/Legacy/Bookmark/Gateway/ExceptionConversion.php @@ -56,6 +56,11 @@ public function loadBookmarkDataByUserIdAndLocationId(int $userId, array $locati } } + /** + * @deprecated The "ExceptionConversion::loadUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::find()" and "Criterion\IsBookmarked" instead. + * + * @return array + */ public function loadUserBookmarks(int $userId, int $offset = 0, int $limit = -1): array { try { @@ -65,6 +70,9 @@ public function loadUserBookmarks(int $userId, int $offset = 0, int $limit = -1) } } + /** + * @deprecated The "ExceptionConversion::countUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::count()" and "Criterion\IsBookmarked" instead. + */ public function countUserBookmarks(int $userId): int { try { diff --git a/eZ/Publish/Core/Persistence/Legacy/Bookmark/Handler.php b/eZ/Publish/Core/Persistence/Legacy/Bookmark/Handler.php index 935f9d1632..c40d7a2217 100644 --- a/eZ/Publish/Core/Persistence/Legacy/Bookmark/Handler.php +++ b/eZ/Publish/Core/Persistence/Legacy/Bookmark/Handler.php @@ -74,6 +74,8 @@ public function loadByUserIdAndLocationId(int $userId, array $locationIds): arra } /** + * @deprecated The "Handler::loadUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::find()" and "Criterion\IsBookmarked" instead. + * * {@inheritdoc} */ public function loadUserBookmarks(int $userId, int $offset = 0, int $limit = -1): array @@ -84,6 +86,8 @@ public function loadUserBookmarks(int $userId, int $offset = 0, int $limit = -1) } /** + * @deprecated The "Handler::countUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::count()" and "Criterion\IsBookmarked" instead. + * * {@inheritdoc} */ public function countUserBookmarks(int $userId): int diff --git a/eZ/Publish/Core/Repository/BookmarkService.php b/eZ/Publish/Core/Repository/BookmarkService.php index 05d5d08cde..2b97b20496 100644 --- a/eZ/Publish/Core/Repository/BookmarkService.php +++ b/eZ/Publish/Core/Repository/BookmarkService.php @@ -10,13 +10,19 @@ use Exception; use eZ\Publish\API\Repository\BookmarkService as BookmarkServiceInterface; +use eZ\Publish\API\Repository\Exceptions\BadStateException; use eZ\Publish\API\Repository\Repository as RepositoryInterface; use eZ\Publish\API\Repository\Values\Bookmark\BookmarkList; use eZ\Publish\API\Repository\Values\Content\Location; +use eZ\Publish\API\Repository\Values\Content\Query; +use eZ\Publish\API\Repository\Values\Filter\Filter; use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException; -use eZ\Publish\SPI\Persistence\Bookmark\Bookmark; use eZ\Publish\SPI\Persistence\Bookmark\CreateStruct; use eZ\Publish\SPI\Persistence\Bookmark\Handler as BookmarkHandler; +use Ibexa\Contracts\Core\Repository\Values\Content\Query\Criterion; +use Ibexa\Contracts\Core\Repository\Values\Content\Query\SortClause; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; class BookmarkService implements BookmarkServiceInterface { @@ -26,16 +32,17 @@ class BookmarkService implements BookmarkServiceInterface /** @var \eZ\Publish\SPI\Persistence\Bookmark\Handler */ protected $bookmarkHandler; + /** @var \Psr\Log\LoggerInterface */ + private $logger; + /** * BookmarkService constructor. - * - * @param \eZ\Publish\API\Repository\Repository $repository - * @param \eZ\Publish\SPI\Persistence\Bookmark\Handler $bookmarkHandler */ - public function __construct(RepositoryInterface $repository, BookmarkHandler $bookmarkHandler) + public function __construct(RepositoryInterface $repository, BookmarkHandler $bookmarkHandler, LoggerInterface $logger = null) { $this->repository = $repository; $this->bookmarkHandler = $bookmarkHandler; + $this->logger = $logger ?? new NullLogger(); } /** @@ -97,16 +104,26 @@ public function loadBookmarks(int $offset = 0, int $limit = 25): BookmarkList { $currentUserId = $this->getCurrentUserId(); - $list = new BookmarkList(); - $list->totalCount = $this->bookmarkHandler->countUserBookmarks($currentUserId); - if ($list->totalCount > 0) { - $bookmarks = $this->bookmarkHandler->loadUserBookmarks($currentUserId, $offset, $limit); - - $list->items = array_map(function (Bookmark $bookmark) { - return $this->repository->getLocationService()->loadLocation($bookmark->locationId); - }, $bookmarks); + $filter = new Filter(); + try { + $filter + ->withCriterion(new Criterion\IsBookmarked($currentUserId)) + ->withSortClause(new SortClause\BookmarkId(Query::SORT_DESC)) + ->sliceBy($limit, $offset); + + $result = $this->repository->getlocationService()->find($filter, []); + } catch (BadStateException $e) { + $this->logger->debug($e, [ + 'exception' => $e, + ]); + + return new BookmarkList(); } + $list = new BookmarkList(); + $list->totalCount = $result->totalCount; + $list->items = $result->locations; + return $list; } diff --git a/eZ/Publish/Core/Repository/Repository.php b/eZ/Publish/Core/Repository/Repository.php index a1459a7a8f..028bb5ca20 100644 --- a/eZ/Publish/Core/Repository/Repository.php +++ b/eZ/Publish/Core/Repository/Repository.php @@ -599,7 +599,8 @@ public function getBookmarkService(): BookmarkServiceInterface if ($this->bookmarkService === null) { $this->bookmarkService = new BookmarkService( $this, - $this->persistenceHandler->bookmarkHandler() + $this->persistenceHandler->bookmarkHandler(), + $this->logger ); } diff --git a/eZ/Publish/Core/Repository/Tests/Service/Mock/BookmarkTest.php b/eZ/Publish/Core/Repository/Tests/Service/Mock/BookmarkTest.php index 5c23d98b3e..8c23c0dbfc 100644 --- a/eZ/Publish/Core/Repository/Tests/Service/Mock/BookmarkTest.php +++ b/eZ/Publish/Core/Repository/Tests/Service/Mock/BookmarkTest.php @@ -12,6 +12,7 @@ use eZ\Publish\API\Repository\LocationService; use eZ\Publish\API\Repository\PermissionResolver; use eZ\Publish\API\Repository\Values\Content\ContentInfo; +use eZ\Publish\API\Repository\Values\Content\LocationList; use eZ\Publish\Core\Repository\BookmarkService; use eZ\Publish\Core\Repository\Tests\Service\Mock\Base as BaseServiceMockTest; use eZ\Publish\Core\Repository\Values\Content\Location; @@ -219,28 +220,13 @@ public function testLoadBookmarks() $expectedItems = array_map(function ($locationId) { return $this->createLocation($locationId); }, range(1, $expectedTotalCount)); - - $this->bookmarkHandler - ->expects($this->once()) - ->method('countUserBookmarks') - ->with(self::CURRENT_USER_ID) - ->willReturn($expectedTotalCount); - - $this->bookmarkHandler - ->expects($this->once()) - ->method('loadUserBookmarks') - ->with(self::CURRENT_USER_ID, $offset, $limit) - ->willReturn(array_map(static function ($locationId) { - return new Bookmark(['locationId' => $locationId]); - }, range(1, $expectedTotalCount))); + $locationList = new LocationList(['totalCount' => $expectedTotalCount, 'locations' => $expectedItems]); $locationServiceMock = $this->createMock(LocationService::class); $locationServiceMock - ->expects($this->exactly($expectedTotalCount)) - ->method('loadLocation') - ->willReturnCallback(function ($locationId) { - return $this->createLocation($locationId); - }); + ->expects(self::once()) + ->method('find') + ->willReturn($locationList); $repository = $this->getRepositoryMock(); $repository @@ -254,27 +240,6 @@ public function testLoadBookmarks() $this->assertEquals($expectedItems, $bookmarks->items); } - /** - * @covers \eZ\Publish\Core\Repository\BookmarkService::loadBookmarks - */ - public function testLoadBookmarksEmptyList() - { - $this->bookmarkHandler - ->expects($this->once()) - ->method('countUserBookmarks') - ->with(self::CURRENT_USER_ID) - ->willReturn(0); - - $this->bookmarkHandler - ->expects($this->never()) - ->method('loadUserBookmarks'); - - $bookmarks = $this->createBookmarkService()->loadBookmarks(0, 10); - - $this->assertEquals(0, $bookmarks->totalCount); - $this->assertEmpty($bookmarks->items); - } - /** * @covers \eZ\Publish\Core\Repository\BookmarkService::isBookmarked */ @@ -289,9 +254,6 @@ public function testLocationShouldNotBeBookmarked() $this->assertFalse($this->createBookmarkService()->isBookmarked($this->createLocation(self::LOCATION_ID))); } - /** - * @covers \eZ\Publish\Core\Repository\BookmarkService::isBookmarked - */ public function testLocationShouldBeBookmarked() { $this->bookmarkHandler diff --git a/eZ/Publish/Core/settings/storage_engines/legacy/filter/query_builders.yaml b/eZ/Publish/Core/settings/storage_engines/legacy/filter/query_builders.yaml index 663da66fbf..231658d505 100644 --- a/eZ/Publish/Core/settings/storage_engines/legacy/filter/query_builders.yaml +++ b/eZ/Publish/Core/settings/storage_engines/legacy/filter/query_builders.yaml @@ -9,6 +9,11 @@ services: eZ\Publish\Core\Persistence\Legacy\Filter\CriterionQueryBuilder\: resource: '../../../../Persistence/Legacy/Filter/CriterionQueryBuilder/*' + Ibexa\Core\Persistence\Legacy\Filter\CriterionQueryBuilder\: + resource: '../../../../../../../src/lib/Persistence/Legacy/Filter/CriterionQueryBuilder/*' + eZ\Publish\Core\Persistence\Legacy\Filter\SortClauseQueryBuilder\: resource: '../../../../Persistence/Legacy/Filter/SortClauseQueryBuilder/*' + Ibexa\Core\Persistence\Legacy\Filter\SortClauseQueryBuilder\: + resource: '../../../../../../../src/lib/Persistence/Legacy/Filter/SortClauseQueryBuilder/*' diff --git a/eZ/Publish/SPI/Persistence/Bookmark/Handler.php b/eZ/Publish/SPI/Persistence/Bookmark/Handler.php index c335f40297..9b69dae436 100644 --- a/eZ/Publish/SPI/Persistence/Bookmark/Handler.php +++ b/eZ/Publish/SPI/Persistence/Bookmark/Handler.php @@ -41,6 +41,8 @@ public function loadByUserIdAndLocationId(int $userId, array $locationIds): arra /** * Loads bookmarks owned by user. * + * @deprecated The "Handler::loadUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::find()" and "Criterion\IsBookmarked" instead. + * * @param int $userId * @param int $offset the start offset for paging * @param int $limit the number of bookmarked locations returned @@ -52,6 +54,8 @@ public function loadUserBookmarks(int $userId, int $offset = 0, int $limit = -1) /** * Count bookmarks owned by user. * + * @deprecated The "Handler::countUserBookmarks()" method is deprecated, will be removed in 5.0.0. Use "LocationService::count()" and "Criterion\IsBookmarked" instead. + * * @param int $userId * * @return int diff --git a/src/contracts/Repository/Values/Content/Query/Criterion/IsBookmarked.php b/src/contracts/Repository/Values/Content/Query/Criterion/IsBookmarked.php new file mode 100644 index 0000000000..15be989a8d --- /dev/null +++ b/src/contracts/Repository/Values/Content/Query/Criterion/IsBookmarked.php @@ -0,0 +1,43 @@ +joinOnce( + 'location', + DoctrineDatabase::TABLE_BOOKMARKS, + 'bookmark', + 'location.node_id = bookmark.node_id' + ); + + return $queryBuilder->expr()->eq( + 'bookmark.user_id', + $queryBuilder->createNamedParameter( + (int)$criterion->value[0], + ParameterType::INTEGER + ) + ); + } +} diff --git a/src/lib/Persistence/Legacy/Filter/SortClauseQueryBuilder/Bookmark/IdSortClauseQueryBuilder.php b/src/lib/Persistence/Legacy/Filter/SortClauseQueryBuilder/Bookmark/IdSortClauseQueryBuilder.php new file mode 100644 index 0000000000..e9859519b8 --- /dev/null +++ b/src/lib/Persistence/Legacy/Filter/SortClauseQueryBuilder/Bookmark/IdSortClauseQueryBuilder.php @@ -0,0 +1,31 @@ +addSelect('bookmark.id'); + $queryBuilder->addOrderBy('bookmark.id', $sortClause->direction); + } +} diff --git a/tests/lib/Persistence/Legacy/Filter/CriterionQueryBuilder/Location/BookmarkQueryBuilderTest.php b/tests/lib/Persistence/Legacy/Filter/CriterionQueryBuilder/Location/BookmarkQueryBuilderTest.php new file mode 100644 index 0000000000..6e45c6b7a4 --- /dev/null +++ b/tests/lib/Persistence/Legacy/Filter/CriterionQueryBuilder/Location/BookmarkQueryBuilderTest.php @@ -0,0 +1,42 @@ + [ + new IbexaCriterion\IsBookmarked(14), + 'bookmark.user_id = :dcValue1', + ['dcValue1' => 14], + ]; + + yield 'Bookmarks locations for user_id=14 OR user_id=7' => [ + new Criterion\LogicalOr( + [ + new IbexaCriterion\IsBookmarked(14), + new IbexaCriterion\IsBookmarked(7), + ] + ), + '(bookmark.user_id = :dcValue1) OR (bookmark.user_id = :dcValue2)', + ['dcValue1' => 14, 'dcValue2' => 7], + ]; + } + + protected function getCriterionQueryBuilders(): iterable + { + return [new BookmarkQueryBuilder()]; + } +}