Skip to content
Permalink
Browse files

EZP-30029: As a Developer I'd like API for bulk loading Content Info …

…Items (ezsystems#2529)
  • Loading branch information...
andrerom committed Feb 19, 2019
1 parent 6c3e1a9 commit f2dfe9c30fe5a05028d5eb9c57215ba5d22eb159
@@ -38,6 +38,17 @@ interface ContentService
*/
public function loadContentInfo($contentId);
/**
* Bulk-load ContentInfo items by id's.
*
* Note: It does not throw exceptions on load, just skips erroneous (NotFound or Unauthorized) ContentInfo items.
*
* @param int[] $contentIds
*
* @return \eZ\Publish\API\Repository\Values\Content\ContentInfo[] list of ContentInfo with Content Ids as keys
*/
public function loadContentInfoList(array $contentIds): iterable;
/**
* Loads a content info object for the given remoteId.
*
@@ -139,6 +139,24 @@ public function testSudo()
);
}
/**
* Test for the loadContentInfoList() method.
*
* @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
* @depends eZ\Publish\API\Repository\Tests\ContentServiceTest::testLoadContentInfoList
*/
public function testLoadContentInfoListSkipsUnauthorizedItems()
{
$repository = $this->getRepository();
$contentId = $this->generateId('object', 10);
$contentService = $repository->getContentService();
$repository->setCurrentUser($this->createAnonymousWithEditorRole());
$list = $contentService->loadContentInfoList([$contentId]);
$this->assertCount(0, $list);
}
/**
* Test for the loadContentInfoByRemoteId() method.
*
@@ -571,6 +571,44 @@ public function testLoadContentInfoThrowsNotFoundException()
/* END: Use Case */
}
/**
* Test for the loadContentInfoList() method.
*
* @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
*/
public function testLoadContentInfoList()
{
$repository = $this->getRepository();
$mediaFolderId = $this->generateId('object', 41);
$contentService = $repository->getContentService();
$list = $contentService->loadContentInfoList([$mediaFolderId]);
$this->assertCount(1, $list);
$this->assertEquals([$mediaFolderId], array_keys($list), 'Array key was not content id');
$this->assertInstanceOf(
ContentInfo::class,
$list[$mediaFolderId]
);
}
/**
* Test for the loadContentInfoList() method.
*
* @see \eZ\Publish\API\Repository\ContentService::loadContentInfoList()
* @depends testLoadContentInfoList
*/
public function testLoadContentInfoListSkipsNotFoundItems()
{
$repository = $this->getRepository();
$nonExistentContentId = $this->generateId('object', self::DB_INT_MAX);
$contentService = $repository->getContentService();
$list = $contentService->loadContentInfoList([$nonExistentContentId]);
$this->assertCount(0, $list);
}
/**
* Test for the loadContentInfoByRemoteId() method.
*
@@ -3,8 +3,6 @@
namespace eZ\Publish\Core\MVC\Symfony\FieldType\RelationList;
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
use eZ\Publish\API\Repository\Values\Content\Field;
use eZ\Publish\Core\MVC\Symfony\FieldType\View\ParameterProviderInterface;
@@ -34,18 +32,18 @@ public function __construct(ContentService $contentService)
*/
public function getViewParameters(Field $field)
{
$available = [];
foreach ($field->value->destinationContentIds as $contentId) {
try {
$contentInfo = $this->contentService->loadContentInfo($contentId);
$available[$contentId] = !$contentInfo->isTrashed();
} catch (NotFoundException $exception) {
$available[$contentId] = false;
} catch (UnauthorizedException $exception) {
$available[$contentId] = false;
}
$ids = $field->value->destinationContentIds;
$list = $this->contentService->loadContentInfoList($ids);
// Start by setting missing ids as false on $available
$available = array_fill_keys(
array_diff($ids, array_keys($list)),
false
);
// Check if loaded items are in trash or not, for availability
foreach ($list as $contentId => $contentInfo) {
$available[$contentId] = !$contentInfo->isTrashed();
}
return [
@@ -5,8 +5,6 @@
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
use eZ\Publish\API\Repository\Values\Content\Field;
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
use eZ\Publish\Core\Base\Exceptions\UnauthorizedException;
use eZ\Publish\Core\FieldType\RelationList\Value;
use eZ\Publish\Core\MVC\Symfony\FieldType\RelationList\ParameterProvider;
use PHPUnit\Framework\TestCase;
@@ -30,12 +28,24 @@ public function testGetViewParameters(array $desinationContentIds, array $expect
{
$contentServiceMock = $this->createMock(ContentService::class);
$contentServiceMock
->method('loadContentInfo')
->will(TestCase::returnValueMap([
[123, new ContentInfo(['status' => ContentInfo::STATUS_DRAFT])],
[456, new ContentInfo(['status' => ContentInfo::STATUS_PUBLISHED])],
[789, new ContentInfo(['status' => ContentInfo::STATUS_TRASHED])],
]));
->method('loadContentInfoList')
->with($desinationContentIds)
->will($this->returnCallback(function ($arg) {
$return = [];
if (in_array(123, $arg)) {
$return[123] = new ContentInfo(['status' => ContentInfo::STATUS_DRAFT]);
}
if (in_array(456, $arg)) {
$return[456] = new ContentInfo(['status' => ContentInfo::STATUS_PUBLISHED]);
}
if (in_array(789, $arg)) {
$return[789] = new ContentInfo(['status' => ContentInfo::STATUS_TRASHED]);
}
return $return;
}));
$parameterProvider = new ParameterProvider($contentServiceMock);
$parameters = $parameterProvider->getViewParameters(new Field([
@@ -51,8 +61,9 @@ public function testNotFoundGetViewParameters()
$contentServiceMock = $this->createMock(ContentService::class);
$contentServiceMock
->method('loadContentInfo')
->will(TestCase::throwException(new NotFoundException('ContentInfo', $contentId)));
->method('loadContentInfoList')
->with([$contentId])
->willReturn([]);
$parameterProvider = new ParameterProvider($contentServiceMock);
$parameters = $parameterProvider->getViewParameters(new Field([
@@ -68,8 +79,9 @@ public function testUnauthorizedGetViewParameters()
$contentServiceMock = $this->createMock(ContentService::class);
$contentServiceMock
->method('loadContentInfo')
->will(TestCase::throwException(new UnauthorizedException('content', 'read')));
->method('loadContentInfoList')
->with([$contentId])
->willReturn([]);
$parameterProvider = new ParameterProvider($contentServiceMock);
$parameters = $parameterProvider->getViewParameters(new Field([
@@ -113,6 +113,14 @@ public function loadContentInfo($contentId)
return $this->completeContentInfo($restContentInfo);
}
/**
* {@inheritdoc}
*/
public function loadContentInfoList(array $contentIds): iterable
{
throw new \Exception('@todo: Implement.');
}
/**
* Loads a content info object for the given remoteId.
*
@@ -139,6 +139,23 @@ public function loadContentInfo($contentId)
return $contentInfo;
}
/**
* {@inheritdoc}
*/
public function loadContentInfoList(array $contentIds): iterable
{
$contentInfoList = [];
$spiInfoList = $this->persistenceHandler->contentHandler()->loadContentInfoList($contentIds);
foreach ($spiInfoList as $id => $spiInfo) {
$contentInfo = $this->domainMapper->buildContentInfoDomainObject($spiInfo);
if ($this->repository->canUser('content', 'read', $contentInfo)) {
$contentInfoList[$id] = $contentInfo;
}
}
return $contentInfoList;
}
/**
* Loads a content info object.
*
@@ -49,6 +49,14 @@ public function loadContentInfo($contentId)
return $this->service->loadContentInfo($contentId);
}
/**
* {@inheritdoc}
*/
public function loadContentInfoList(array $contentIds): iterable
{
return $this->service->loadContentInfoList($contentIds);
}
public function loadContentInfoByRemoteId($remoteId)
{
return $this->service->loadContentInfoByRemoteId($remoteId);
@@ -39,6 +39,7 @@ public function providerForPassTroughMethods()
// string $method, array $arguments, bool $return = true
return [
['loadContentInfo', [42]],
['loadContentInfoList', [[42]], [$contentInfo]],
['loadContentInfoByRemoteId', ['f348tj4gorgji4']],
@@ -85,6 +85,14 @@ public function loadContentInfo($contentId)
return $this->service->loadContentInfo($contentId);
}
/**
* {@inheritdoc}
*/
public function loadContentInfoList(array $contentIds): iterable
{
return $this->service->loadContentInfoList($contentIds);
}
/**
* Loads a content info object for the given remoteId.
*
@@ -85,6 +85,12 @@ public function serviceProvider()
$contentInfo,
0,
),
array(
'loadContentInfoList',
array(array($contentId)),
[$contentInfo],
0,
),
array(
'loadContentInfoByRemoteId',
array($remoteId),

0 comments on commit f2dfe9c

Please sign in to comment.
You can’t perform that action at this time.