From 27fd23f4899c175714e462b24eb47c7f89ce3910 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Sun, 12 May 2024 21:40:23 +0200 Subject: [PATCH 01/10] IBX-8280: Move previewableTranslations info to node extended info endpoint --- .../Content/ContentTreeController.php | 45 ++++++++++++++++++- .../ValueObjectVisitor/ContentTree/Node.php | 2 +- .../ContentTree/NodeExtendedInfoVisitor.php | 15 +++++++ src/lib/REST/Value/ContentTree/Node.php | 10 ++--- .../Value/ContentTree/NodeExtendedInfo.php | 17 ++++++- src/lib/UI/Module/ContentTree/NodeFactory.php | 39 +--------------- .../Schemas/ContentTreeNodeExtendedInfo.json | 6 ++- .../Schemas/ContentTreeNodeExtendedInfo.xsd | 1 + .../ContentTreeNodeExtendedInfo.json | 3 +- .../Snapshots/ContentTreeNodeExtendedInfo.xml | 1 + .../REST/Snapshots/ContentTreeRoot.json | 4 +- 11 files changed, 92 insertions(+), 51 deletions(-) diff --git a/src/bundle/Controller/Content/ContentTreeController.php b/src/bundle/Controller/Content/ContentTreeController.php index f27bd5afcc..ee4b02826f 100644 --- a/src/bundle/Controller/Content/ContentTreeController.php +++ b/src/bundle/Controller/Content/ContentTreeController.php @@ -13,12 +13,14 @@ use Ibexa\AdminUi\REST\Value\ContentTree\Node; use Ibexa\AdminUi\REST\Value\ContentTree\NodeExtendedInfo; use Ibexa\AdminUi\REST\Value\ContentTree\Root; +use Ibexa\AdminUi\Siteaccess\SiteaccessResolverInterface; use Ibexa\AdminUi\Specification\ContentType\ContentTypeIsUser; use Ibexa\AdminUi\UI\Module\ContentTree\NodeFactory; use Ibexa\Contracts\AdminUi\Permission\PermissionCheckerInterface; use Ibexa\Contracts\Core\Limitation\Target; use Ibexa\Contracts\Core\Repository\LocationService; use Ibexa\Contracts\Core\Repository\PermissionResolver; +use Ibexa\Contracts\Core\Repository\Values\Content\Content; use Ibexa\Contracts\Core\Repository\Values\Content\Location; use Ibexa\Contracts\Core\Repository\Values\Content\Query; use Ibexa\Contracts\Core\Repository\Values\User\Limitation; @@ -44,13 +46,16 @@ class ContentTreeController extends RestController private ConfigResolverInterface $configResolver; + private SiteaccessResolverInterface $siteaccessResolver; + public function __construct( LocationService $locationService, PermissionCheckerInterface $permissionChecker, LookupLimitationsTransformer $lookupLimitationsTransformer, NodeFactory $contentTreeNodeFactory, PermissionResolver $permissionResolver, - ConfigResolverInterface $configResolver + ConfigResolverInterface $configResolver, + SiteaccessResolverInterface $siteaccessResolver ) { $this->locationService = $locationService; $this->permissionChecker = $permissionChecker; @@ -58,6 +63,7 @@ public function __construct( $this->contentTreeNodeFactory = $contentTreeNodeFactory; $this->permissionResolver = $permissionResolver; $this->configResolver = $configResolver; + $this->siteaccessResolver = $siteaccessResolver; } /** @@ -145,7 +151,15 @@ public function loadNodeExtendedInfoAction(Location $location): NodeExtendedInfo { $locationPermissionRestrictions = $this->getLocationPermissionRestrictions($location); - return new NodeExtendedInfo($locationPermissionRestrictions); + $content = $location->getContent(); + $versionInfo = $content->getVersionInfo(); + $translations = $versionInfo->languageCodes; + $previewableTranslations = array_filter( + $translations, + fn (string $languageCode): bool => $this->isPreviewable($location, $content, $languageCode) + ); + + return new NodeExtendedInfo($locationPermissionRestrictions, $previewableTranslations); } /** @@ -245,6 +259,33 @@ private function canUserHideContent(Location $location): bool [$target] ); } + + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException + */ + private function isPreviewable( + Location $location, + Content $content, + string $languageCode + ): bool { + $versionNo = $content->getVersionInfo()->versionNo; + + $siteAccesses = $this->siteaccessResolver->getSiteAccessesListForLocation( + $location, + $versionNo, + $languageCode + ); + + $canPreview = $this->permissionResolver->canUser( + 'content', + 'versionread', + $content, + [$location] + ); + + return $canPreview && !empty($siteAccesses); + } } class_alias(ContentTreeController::class, 'EzSystems\EzPlatformAdminUiBundle\Controller\Content\ContentTreeController'); diff --git a/src/lib/REST/Output/ValueObjectVisitor/ContentTree/Node.php b/src/lib/REST/Output/ValueObjectVisitor/ContentTree/Node.php index 3e98d51fbb..41e666161f 100644 --- a/src/lib/REST/Output/ValueObjectVisitor/ContentTree/Node.php +++ b/src/lib/REST/Output/ValueObjectVisitor/ContentTree/Node.php @@ -41,7 +41,7 @@ public function visit(Visitor $visitor, Generator $generator, $data) $generator->valueElement('translations', implode(',', $data->translations)); - $generator->valueElement('previewableTranslations', implode(',', $data->previewableTranslations)); + $generator->valueElement('mainLanguageCode', $data->mainLanguageCode); $generator->startValueElement('name', $data->name); $generator->endValueElement('name'); diff --git a/src/lib/REST/Output/ValueObjectVisitor/ContentTree/NodeExtendedInfoVisitor.php b/src/lib/REST/Output/ValueObjectVisitor/ContentTree/NodeExtendedInfoVisitor.php index 34e3057e6f..c17a94375e 100644 --- a/src/lib/REST/Output/ValueObjectVisitor/ContentTree/NodeExtendedInfoVisitor.php +++ b/src/lib/REST/Output/ValueObjectVisitor/ContentTree/NodeExtendedInfoVisitor.php @@ -30,10 +30,25 @@ public function visit(Visitor $visitor, Generator $generator, $data): void $visitor->setStatus(Response::HTTP_OK); $this->buildPermissionNode($data->getPermissionRestrictions(), $generator); + $this->buildPreviewableTranslationsNode($data->getPreviewableTranslation(), $generator); $generator->endObjectElement(self::MAIN_ELEMENT); } + /** + * @param string[]|null $previewableTranslation + */ + protected function buildPreviewableTranslationsNode( + ?array $previewableTranslation, + Generator $generator + ): void { + if ($previewableTranslation === null) { + return; + } + + $generator->valueElement('previewableTranslationsString', implode(',', $previewableTranslation)); + } + /** * @phpstan-param TPermissionRestrictions $permissionRestrictions */ diff --git a/src/lib/REST/Value/ContentTree/Node.php b/src/lib/REST/Value/ContentTree/Node.php index 30201f4274..9aa1755652 100644 --- a/src/lib/REST/Value/ContentTree/Node.php +++ b/src/lib/REST/Value/ContentTree/Node.php @@ -26,9 +26,6 @@ class Node extends RestValue /** @var string[] */ public array $translations; - /** @var string[] */ - public array $previewableTranslations; - /** @var string */ public $name; @@ -56,12 +53,13 @@ class Node extends RestValue public string $pathString; + public string $mainLanguageCode; + /** * @param int $depth * @param int $locationId * @param int $contentId * @param string[] $translations - * @param string[] $previewableTranslations * @param string $name * @param string $contentTypeIdentifier * @param bool $isContainer @@ -76,7 +74,6 @@ public function __construct( int $contentId, int $versionNo, array $translations, - array $previewableTranslations, string $name, string $contentTypeIdentifier, bool $isContainer, @@ -85,6 +82,7 @@ public function __construct( int $totalChildrenCount, int $reverseRelationsCount, bool $isBookmarked, + string $mainLanguageCode, array $children = [], string $pathString = '' ) { @@ -93,7 +91,6 @@ public function __construct( $this->contentId = $contentId; $this->versionNo = $versionNo; $this->translations = $translations; - $this->previewableTranslations = $previewableTranslations; $this->name = $name; $this->isInvisible = $isInvisible; $this->contentTypeIdentifier = $contentTypeIdentifier; @@ -104,6 +101,7 @@ public function __construct( $this->isBookmarked = $isBookmarked; $this->children = $children; $this->pathString = $pathString; + $this->mainLanguageCode = $mainLanguageCode; } } diff --git a/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php b/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php index 5fc578f026..9a70a82bc5 100644 --- a/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php +++ b/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php @@ -28,13 +28,20 @@ final class NodeExtendedInfo extends RestValue /** @phpstan-var TPermissionRestrictions|null */ private ?array $permissions; + /** @var string[]|null */ + private ?array $previewableTranslation; + /** * @phpstan-param TPermissionRestrictions|null $permissions + * + * @param string[]|null $previewableTranslation */ public function __construct( - ?array $permissions = null + ?array $permissions = null, + ?array $previewableTranslation = null, ) { $this->permissions = $permissions; + $this->previewableTranslation = $previewableTranslation; } /** @@ -44,4 +51,12 @@ public function getPermissionRestrictions(): ?array { return $this->permissions; } + + /** + * @return string[]|null + */ + public function getPreviewableTranslation(): ?array + { + return $this->previewableTranslation; + } } diff --git a/src/lib/UI/Module/ContentTree/NodeFactory.php b/src/lib/UI/Module/ContentTree/NodeFactory.php index fa2204d72e..be8c41ee67 100644 --- a/src/lib/UI/Module/ContentTree/NodeFactory.php +++ b/src/lib/UI/Module/ContentTree/NodeFactory.php @@ -10,7 +10,6 @@ use Ibexa\AdminUi\REST\Value\ContentTree\LoadSubtreeRequestNode; use Ibexa\AdminUi\REST\Value\ContentTree\Node; -use Ibexa\AdminUi\Siteaccess\SiteaccessResolverInterface; use Ibexa\Contracts\Core\Repository\BookmarkService; use Ibexa\Contracts\Core\Repository\ContentService; use Ibexa\Contracts\Core\Repository\Exceptions\NotImplementedException; @@ -63,8 +62,6 @@ final class NodeFactory private Repository $repository; - private SiteaccessResolverInterface $siteaccessResolver; - /** @var int */ private $maxLocationIdsInSingleAggregation; @@ -76,7 +73,6 @@ public function __construct( ConfigResolverInterface $configResolver, PermissionResolver $permissionResolver, Repository $repository, - SiteaccessResolverInterface $siteaccessResolver, int $maxLocationIdsInSingleAggregation ) { $this->bookmarkService = $bookmarkService; @@ -86,7 +82,6 @@ public function __construct( $this->configResolver = $configResolver; $this->permissionResolver = $permissionResolver; $this->repository = $repository; - $this->siteaccessResolver = $siteaccessResolver; $this->maxLocationIdsInSingleAggregation = $maxLocationIdsInSingleAggregation; } @@ -397,10 +392,7 @@ private function buildNode( } $translations = $versionInfo->languageCodes; - $previewableTranslations = array_filter( - $translations, - fn (string $languageCode): bool => $this->isPreviewable($location, $content, $languageCode) - ); + $mainLanguageCode = $content->contentInfo->mainLanguageCode; return new Node( $depth, @@ -408,7 +400,6 @@ private function buildNode( $location->contentId, $versionInfo->versionNo, $translations, - $previewableTranslations, '', // node name will be provided later by `supplyTranslatedContentName` method $contentType ? $contentType->identifier : '', $contentType ? $contentType->isContainer : true, @@ -417,6 +408,7 @@ private function buildNode( $totalChildrenCount, $this->getReverseRelationsCount($contentInfo), isset($bookmarkLocations[$location->id]), + $mainLanguageCode, $children, $location->getPathString() ); @@ -468,33 +460,6 @@ private function supplyChildrenCount( $this->supplyChildrenCount($child, $aggregationResult, $requestFilter); } } - - /** - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\BadStateException - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException - */ - private function isPreviewable( - Location $location, - Content $content, - string $languageCode - ): bool { - $versionNo = $content->getVersionInfo()->versionNo; - - $siteAccesses = $this->siteaccessResolver->getSiteAccessesListForLocation( - $location, - $versionNo, - $languageCode - ); - - $canPreview = $this->permissionResolver->canUser( - 'content', - 'versionread', - $content, - [$location] - ); - - return $canPreview && !empty($siteAccesses); - } } class_alias(NodeFactory::class, 'EzSystems\EzPlatformAdminUi\UI\Module\ContentTree\NodeFactory'); diff --git a/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.json b/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.json index 632e43c99e..7e5e1126a3 100644 --- a/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.json +++ b/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.json @@ -53,11 +53,15 @@ "hasAccess" ] } + }, + "previewableTranslationsString": { + "type": "string" } }, "required": [ "_media-type", - "permissions" + "permissions", + "previewableTranslationsString" ] } }, diff --git a/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.xsd b/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.xsd index 38cebade76..cabfd602ab 100644 --- a/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.xsd +++ b/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.xsd @@ -26,6 +26,7 @@ + diff --git a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json index ceef092019..abeb307263 100644 --- a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json +++ b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json @@ -35,6 +35,7 @@ "_name": "hide", "hasAccess": false } - ] + ], + "previewableTranslationsString": "" } } diff --git a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml index 64fed756ca..c2a307493a 100644 --- a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml +++ b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml @@ -23,4 +23,5 @@ false + diff --git a/tests/integration/Resources/REST/Snapshots/ContentTreeRoot.json b/tests/integration/Resources/REST/Snapshots/ContentTreeRoot.json index 2fdf2a13f9..1a7c7c051d 100644 --- a/tests/integration/Resources/REST/Snapshots/ContentTreeRoot.json +++ b/tests/integration/Resources/REST/Snapshots/ContentTreeRoot.json @@ -5,10 +5,10 @@ { "_media-type": "application\/vnd.ibexa.api.ContentTreeNode+json", "locationId": 2, + "mainLanguageCode": "eng-GB", "contentId": 57, "versionNo": 1, "translations": "eng-GB", - "previewableTranslations": "eng-GB", "name": "Home", "pathString": "/1/2/", "contentTypeIdentifier": "landing_page", @@ -22,10 +22,10 @@ { "_media-type": "application\/vnd.ibexa.api.ContentTreeNode+json", "locationId": 60, + "mainLanguageCode": "eng-GB", "contentId": 58, "versionNo": 1, "translations": "eng-GB", - "previewableTranslations": "eng-GB", "name": "Contact Us", "pathString": "/1/2/60/", "contentTypeIdentifier": "feedback_form", From 428a3971475625bd7f49877ff05f4ffef5d69d13 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Mon, 13 May 2024 10:52:38 +0200 Subject: [PATCH 02/10] phpstan fixes --- .../Pagination/Mapper/AbstractPagerContentToDataMapper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lib/Pagination/Mapper/AbstractPagerContentToDataMapper.php b/src/lib/Pagination/Mapper/AbstractPagerContentToDataMapper.php index 1319c81fd7..23fb047241 100644 --- a/src/lib/Pagination/Mapper/AbstractPagerContentToDataMapper.php +++ b/src/lib/Pagination/Mapper/AbstractPagerContentToDataMapper.php @@ -113,11 +113,13 @@ protected function setTranslatedContentTypesNames(array &$data, array $contentTy $this->userLanguagePreferenceProvider->getPreferredLanguages() ); + $contentTypesArray = [...$contentTypes]; + foreach ($data as $idx => $item) { // get content type from bulk-loaded list or fallback to lazy loaded one if not present $contentTypeId = $item['contentTypeId']; /** @var \Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType $contentType */ - $contentType = $contentTypes[$contentTypeId] ?? $item['content']->getContentType(); + $contentType = $contentTypesArray[$contentTypeId] ?? $item['content']->getContentType(); $data[$idx]['type'] = $contentType->getName(); unset($data[$idx]['content'], $data[$idx]['contentTypeId']); From b37a2f14960b95a914d4ff56235c70eb52e9f57e Mon Sep 17 00:00:00 2001 From: tischsoic Date: Mon, 13 May 2024 11:01:02 +0200 Subject: [PATCH 03/10] unnecessary comma --- src/lib/REST/Value/ContentTree/NodeExtendedInfo.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php b/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php index 9a70a82bc5..72a2968b49 100644 --- a/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php +++ b/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php @@ -38,7 +38,7 @@ final class NodeExtendedInfo extends RestValue */ public function __construct( ?array $permissions = null, - ?array $previewableTranslation = null, + ?array $previewableTranslation = null ) { $this->permissions = $permissions; $this->previewableTranslation = $previewableTranslation; From 9156b787a443923f55bc478aba93c6126cf59c4d Mon Sep 17 00:00:00 2001 From: tischsoic Date: Mon, 20 May 2024 10:55:42 +0200 Subject: [PATCH 04/10] after CR --- .../AbstractPagerContentToDataMapper.php | 4 +--- .../ContentTree/NodeExtendedInfoVisitor.php | 16 +++++++++------- .../Value/ContentTree/NodeExtendedInfo.php | 16 ++++++++-------- .../Schemas/ContentTreeNodeExtendedInfo.json | 18 ++++++++++++++---- .../Schemas/ContentTreeNodeExtendedInfo.xsd | 8 +++++++- .../Snapshots/ContentTreeNodeExtendedInfo.json | 4 +++- .../Snapshots/ContentTreeNodeExtendedInfo.xml | 2 +- 7 files changed, 43 insertions(+), 25 deletions(-) diff --git a/src/lib/Pagination/Mapper/AbstractPagerContentToDataMapper.php b/src/lib/Pagination/Mapper/AbstractPagerContentToDataMapper.php index 23fb047241..1319c81fd7 100644 --- a/src/lib/Pagination/Mapper/AbstractPagerContentToDataMapper.php +++ b/src/lib/Pagination/Mapper/AbstractPagerContentToDataMapper.php @@ -113,13 +113,11 @@ protected function setTranslatedContentTypesNames(array &$data, array $contentTy $this->userLanguagePreferenceProvider->getPreferredLanguages() ); - $contentTypesArray = [...$contentTypes]; - foreach ($data as $idx => $item) { // get content type from bulk-loaded list or fallback to lazy loaded one if not present $contentTypeId = $item['contentTypeId']; /** @var \Ibexa\Contracts\Core\Repository\Values\ContentType\ContentType $contentType */ - $contentType = $contentTypesArray[$contentTypeId] ?? $item['content']->getContentType(); + $contentType = $contentTypes[$contentTypeId] ?? $item['content']->getContentType(); $data[$idx]['type'] = $contentType->getName(); unset($data[$idx]['content'], $data[$idx]['contentTypeId']); diff --git a/src/lib/REST/Output/ValueObjectVisitor/ContentTree/NodeExtendedInfoVisitor.php b/src/lib/REST/Output/ValueObjectVisitor/ContentTree/NodeExtendedInfoVisitor.php index c17a94375e..3d073f88d7 100644 --- a/src/lib/REST/Output/ValueObjectVisitor/ContentTree/NodeExtendedInfoVisitor.php +++ b/src/lib/REST/Output/ValueObjectVisitor/ContentTree/NodeExtendedInfoVisitor.php @@ -30,23 +30,25 @@ public function visit(Visitor $visitor, Generator $generator, $data): void $visitor->setStatus(Response::HTTP_OK); $this->buildPermissionNode($data->getPermissionRestrictions(), $generator); - $this->buildPreviewableTranslationsNode($data->getPreviewableTranslation(), $generator); + $this->buildPreviewableTranslationsNode($data->getPreviewableTranslations(), $generator); $generator->endObjectElement(self::MAIN_ELEMENT); } /** - * @param string[]|null $previewableTranslation + * @param string[] $previewableTranslations */ protected function buildPreviewableTranslationsNode( - ?array $previewableTranslation, + array $previewableTranslations, Generator $generator ): void { - if ($previewableTranslation === null) { - return; + $generator->startHashElement('previewableTranslations'); + $generator->startList('values'); + foreach ($previewableTranslations as $value) { + $generator->valueElement('value', $value); } - - $generator->valueElement('previewableTranslationsString', implode(',', $previewableTranslation)); + $generator->endList('values'); + $generator->endHashElement('previewableTranslations'); } /** diff --git a/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php b/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php index 72a2968b49..7258507c65 100644 --- a/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php +++ b/src/lib/REST/Value/ContentTree/NodeExtendedInfo.php @@ -28,20 +28,20 @@ final class NodeExtendedInfo extends RestValue /** @phpstan-var TPermissionRestrictions|null */ private ?array $permissions; - /** @var string[]|null */ - private ?array $previewableTranslation; + /** @var string[] */ + private array $previewableTranslations; /** * @phpstan-param TPermissionRestrictions|null $permissions * - * @param string[]|null $previewableTranslation + * @param string[] $previewableTranslation */ public function __construct( ?array $permissions = null, - ?array $previewableTranslation = null + array $previewableTranslation = [] ) { $this->permissions = $permissions; - $this->previewableTranslation = $previewableTranslation; + $this->previewableTranslations = $previewableTranslation; } /** @@ -53,10 +53,10 @@ public function getPermissionRestrictions(): ?array } /** - * @return string[]|null + * @return string[] */ - public function getPreviewableTranslation(): ?array + public function getPreviewableTranslations(): array { - return $this->previewableTranslation; + return $this->previewableTranslations; } } diff --git a/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.json b/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.json index 7e5e1126a3..753b688a84 100644 --- a/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.json +++ b/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.json @@ -54,14 +54,24 @@ ] } }, - "previewableTranslationsString": { - "type": "string" - } + "previewableTranslations": { + "type": "object", + "properties": { + "values": { + "type": "array", + "items": [ + { + "type": "string" + } + ] + } + } + } }, "required": [ "_media-type", "permissions", - "previewableTranslationsString" + "previewableTranslations" ] } }, diff --git a/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.xsd b/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.xsd index cabfd602ab..cd01c211ce 100644 --- a/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.xsd +++ b/tests/integration/Resources/REST/Schemas/ContentTreeNodeExtendedInfo.xsd @@ -26,7 +26,13 @@ - + + + + + + + diff --git a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json index abeb307263..b46b56f24d 100644 --- a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json +++ b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json @@ -36,6 +36,8 @@ "hasAccess": false } ], - "previewableTranslationsString": "" + "previewableTranslations": { + "values": [] + } } } diff --git a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml index c2a307493a..4e2af6d822 100644 --- a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml +++ b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml @@ -23,5 +23,5 @@ false - + From 5e7656d9f2fdf6526264c37225e4f2f1ff7ad63d Mon Sep 17 00:00:00 2001 From: tischsoic Date: Thu, 23 May 2024 12:12:04 +0200 Subject: [PATCH 05/10] Extend tests to cover non-empty previewableTranslations --- tests/integration/REST/GetContentTreeExtendedInfoTest.php | 1 + .../Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json | 2 +- .../Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/integration/REST/GetContentTreeExtendedInfoTest.php b/tests/integration/REST/GetContentTreeExtendedInfoTest.php index 9e8472a918..847e5465b4 100644 --- a/tests/integration/REST/GetContentTreeExtendedInfoTest.php +++ b/tests/integration/REST/GetContentTreeExtendedInfoTest.php @@ -35,6 +35,7 @@ protected function setUp(): void [ 'user/login' => [], 'content/read' => [], + 'content/versionread' => [], 'content/create' => [ new ContentTypeLimitation( ['limitationValues' => ['1', '16']] diff --git a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json index b46b56f24d..85be359381 100644 --- a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json +++ b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.json @@ -37,7 +37,7 @@ } ], "previewableTranslations": { - "values": [] + "values": ["eng-GB"] } } } diff --git a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml index 4e2af6d822..926eeef47f 100644 --- a/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml +++ b/tests/integration/Resources/REST/Snapshots/ContentTreeNodeExtendedInfo.xml @@ -23,5 +23,7 @@ false - + + eng-GB + From bc29202fed020a50913c155d9cc8a2de185fcae8 Mon Sep 17 00:00:00 2001 From: tischsoic Date: Thu, 23 May 2024 16:27:21 +0200 Subject: [PATCH 06/10] after CR --- .../Content/ContentTreeController.php | 20 +++++++++++-------- src/lib/UI/Module/ContentTree/NodeFactory.php | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/bundle/Controller/Content/ContentTreeController.php b/src/bundle/Controller/Content/ContentTreeController.php index ee4b02826f..09993918e9 100644 --- a/src/bundle/Controller/Content/ContentTreeController.php +++ b/src/bundle/Controller/Content/ContentTreeController.php @@ -269,6 +269,17 @@ private function isPreviewable( Content $content, string $languageCode ): bool { + $canPreview = $this->permissionResolver->canUser( + 'content', + 'versionread', + $content, + [$location] + ); + + if (!$canPreview) { + return false; + } + $versionNo = $content->getVersionInfo()->versionNo; $siteAccesses = $this->siteaccessResolver->getSiteAccessesListForLocation( @@ -277,14 +288,7 @@ private function isPreviewable( $languageCode ); - $canPreview = $this->permissionResolver->canUser( - 'content', - 'versionread', - $content, - [$location] - ); - - return $canPreview && !empty($siteAccesses); + return !empty($siteAccesses); } } diff --git a/src/lib/UI/Module/ContentTree/NodeFactory.php b/src/lib/UI/Module/ContentTree/NodeFactory.php index be8c41ee67..3f6563ffa9 100644 --- a/src/lib/UI/Module/ContentTree/NodeFactory.php +++ b/src/lib/UI/Module/ContentTree/NodeFactory.php @@ -392,7 +392,7 @@ private function buildNode( } $translations = $versionInfo->languageCodes; - $mainLanguageCode = $content->contentInfo->mainLanguageCode; + $mainLanguageCode = $versionInfo->getContentInfo()->getMainLanguageCode(); return new Node( $depth, From 4e7a81111488c10595d1234e3c76c1d88d430781 Mon Sep 17 00:00:00 2001 From: Andrew Longosz Date: Fri, 8 Mar 2024 22:21:52 +0100 Subject: [PATCH 07/10] Replaced usage of magic getters affecting subtree loading performance --- .../InContextTranslationListener.php | 2 +- .../AbstractSiteaccessPreviewVoter.php | 2 +- src/lib/Siteaccess/SiteaccessResolver.php | 2 +- .../Strategy/ContentTypeThumbnailStrategy.php | 2 +- src/lib/UI/Module/ContentTree/NodeFactory.php | 28 +++++++++---------- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/lib/EventListener/InContextTranslationListener.php b/src/lib/EventListener/InContextTranslationListener.php index fcc17bc13f..a894da239a 100644 --- a/src/lib/EventListener/InContextTranslationListener.php +++ b/src/lib/EventListener/InContextTranslationListener.php @@ -59,7 +59,7 @@ public function setInContextTranslation(RequestEvent $event): void return; } - $inContextSetting = $this->userSettingService->getUserSetting('in_context_translation')->value; + $inContextSetting = $this->userSettingService->getUserSetting('in_context_translation')->getValue(); if ($inContextSetting !== InContextTranslation::ENABLED_OPTION) { return; diff --git a/src/lib/Siteaccess/AbstractSiteaccessPreviewVoter.php b/src/lib/Siteaccess/AbstractSiteaccessPreviewVoter.php index b3bb438af7..f4629eee02 100644 --- a/src/lib/Siteaccess/AbstractSiteaccessPreviewVoter.php +++ b/src/lib/Siteaccess/AbstractSiteaccessPreviewVoter.php @@ -36,7 +36,7 @@ public function vote(SiteaccessPreviewVoterContext $context): bool $location = $context->getLocation(); $languageCode = $context->getLanguageCode(); - if (empty(array_intersect($this->getRootLocationIds($siteAccess), $location->path))) { + if (empty(array_intersect($this->getRootLocationIds($siteAccess), $location->getPath()))) { return false; } diff --git a/src/lib/Siteaccess/SiteaccessResolver.php b/src/lib/Siteaccess/SiteaccessResolver.php index cefa3f312f..6df66b2bf5 100644 --- a/src/lib/Siteaccess/SiteaccessResolver.php +++ b/src/lib/Siteaccess/SiteaccessResolver.php @@ -81,7 +81,7 @@ public function getSiteAccessesListForLocation( ): array { $contentInfo = $location->getContentInfo(); $versionInfo = $this->contentService->loadVersionInfo($contentInfo, $versionNo); - $languageCode = $languageCode ?? $contentInfo->mainLanguageCode; + $languageCode = $languageCode ?? $contentInfo->getMainLanguageCode(); $eligibleSiteAccesses = []; /** @var \Ibexa\Core\MVC\Symfony\SiteAccess $siteAccess */ diff --git a/src/lib/Strategy/ContentTypeThumbnailStrategy.php b/src/lib/Strategy/ContentTypeThumbnailStrategy.php index dca897a4c7..8973379174 100644 --- a/src/lib/Strategy/ContentTypeThumbnailStrategy.php +++ b/src/lib/Strategy/ContentTypeThumbnailStrategy.php @@ -34,7 +34,7 @@ public function getThumbnail( ?VersionInfo $versionInfo = null ): ?Thumbnail { try { - $contentTypeIcon = $this->contentTypeIconResolver->getContentTypeIcon($contentType->identifier); + $contentTypeIcon = $this->contentTypeIconResolver->getContentTypeIcon($contentType->getIdentifier()); return new Thumbnail([ 'resource' => $contentTypeIcon, diff --git a/src/lib/UI/Module/ContentTree/NodeFactory.php b/src/lib/UI/Module/ContentTree/NodeFactory.php index fa2204d72e..ee2213cd59 100644 --- a/src/lib/UI/Module/ContentTree/NodeFactory.php +++ b/src/lib/UI/Module/ContentTree/NodeFactory.php @@ -158,7 +158,7 @@ private function findSubitems( string $sortOrder = Query::SORT_ASC, ?Criterion $requestFilter = null ): SearchResult { - $searchQuery = $this->getSearchQuery($parentLocation->id, $requestFilter); + $searchQuery = $this->getSearchQuery($parentLocation->getId(), $requestFilter); $searchQuery->limit = $limit; $searchQuery->offset = $offset; @@ -347,17 +347,17 @@ private function buildNode( ?Criterion $requestFilter = null ): Node { $contentInfo = $location->getContentInfo(); - $contentId = $location->contentId; + $contentId = $location->getContentId(); if (!isset($uninitializedContentInfoList[$contentId])) { $uninitializedContentInfoList[$contentId] = $contentInfo; } // Top Level Location (id = 1) does not have a content type - $contentType = $location->depth > 0 + $contentType = $location->getDepth() > 0 ? $contentInfo->getContentType() : null; - if ($contentType !== null && $contentType->isContainer) { + if ($contentType !== null && $contentType->isContainer()) { $containerLocations[] = $location; } @@ -378,7 +378,7 @@ private function buildNode( /** @var \Ibexa\Contracts\Core\Repository\Values\Content\Location $childLocation */ foreach (array_column($searchResult->searchHits, 'valueObject') as $childLocation) { $childLoadSubtreeRequestNode = null !== $loadSubtreeRequestNode - ? $this->findChild($childLocation->id, $loadSubtreeRequestNode) + ? $this->findChild($childLocation->getId(), $loadSubtreeRequestNode) : null; $children[] = $this->buildNode( @@ -396,7 +396,7 @@ private function buildNode( } } - $translations = $versionInfo->languageCodes; + $translations = $versionInfo->getLanguageCodes(); $previewableTranslations = array_filter( $translations, fn (string $languageCode): bool => $this->isPreviewable($location, $content, $languageCode) @@ -404,19 +404,19 @@ private function buildNode( return new Node( $depth, - $location->id, - $location->contentId, - $versionInfo->versionNo, + $location->getId(), + $location->getContentId(), + $versionInfo->getVersionNo(), $translations, $previewableTranslations, '', // node name will be provided later by `supplyTranslatedContentName` method - $contentType ? $contentType->identifier : '', - $contentType ? $contentType->isContainer : true, - $location->invisible || $location->hidden, + null !== $contentType ? $contentType->getIdentifier() : '', + !(null !== $contentType) || $contentType->isContainer(), + $location->isInvisible() || $location->isHidden(), $limit, $totalChildrenCount, $this->getReverseRelationsCount($contentInfo), - isset($bookmarkLocations[$location->id]), + isset($bookmarkLocations[$location->getId()]), $children, $location->getPathString() ); @@ -478,7 +478,7 @@ private function isPreviewable( Content $content, string $languageCode ): bool { - $versionNo = $content->getVersionInfo()->versionNo; + $versionNo = $content->getVersionInfo()->getVersionNo(); $siteAccesses = $this->siteaccessResolver->getSiteAccessesListForLocation( $location, From 58792265c93fcf9ba7668d169f957ab780f7f4ff Mon Sep 17 00:00:00 2001 From: Andrew Longosz Date: Fri, 24 May 2024 16:09:24 +0200 Subject: [PATCH 08/10] Simplified logic when creating new Node MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Paweł Niedzielski --- src/lib/UI/Module/ContentTree/NodeFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/UI/Module/ContentTree/NodeFactory.php b/src/lib/UI/Module/ContentTree/NodeFactory.php index ee2213cd59..c3e5976563 100644 --- a/src/lib/UI/Module/ContentTree/NodeFactory.php +++ b/src/lib/UI/Module/ContentTree/NodeFactory.php @@ -411,7 +411,7 @@ private function buildNode( $previewableTranslations, '', // node name will be provided later by `supplyTranslatedContentName` method null !== $contentType ? $contentType->getIdentifier() : '', - !(null !== $contentType) || $contentType->isContainer(), + null === $contentType || $contentType->isContainer(), $location->isInvisible() || $location->isHidden(), $limit, $totalChildrenCount, From b7f28033dfba481577fce3d124b30cd1619ff673 Mon Sep 17 00:00:00 2001 From: Andrew Longosz Date: Fri, 24 May 2024 16:20:01 +0200 Subject: [PATCH 09/10] Dropped usage of removed property `NodeFactory::$allowedContentTypes` --- src/lib/UI/Module/ContentTree/NodeFactory.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/UI/Module/ContentTree/NodeFactory.php b/src/lib/UI/Module/ContentTree/NodeFactory.php index c3e5976563..5f7ef7e1da 100644 --- a/src/lib/UI/Module/ContentTree/NodeFactory.php +++ b/src/lib/UI/Module/ContentTree/NodeFactory.php @@ -181,7 +181,7 @@ private function getSearchQuery(int $parentLocationId, ?Criterion $requestFilter $contentTypeCriterion = new Criterion\ContentTypeIdentifier($this->getSetting('allowed_content_types')); } - if (empty($this->allowedContentTypes) && !empty($this->getSetting('ignored_content_types'))) { + if (!empty($this->getSetting('ignored_content_types'))) { $contentTypeCriterion = new Criterion\LogicalNot( new Criterion\ContentTypeIdentifier($this->getSetting('ignored_content_types')) ); From 69e2b98c3e4e1172a7c8daa85a1c62a81c9d7889 Mon Sep 17 00:00:00 2001 From: Andrew Longosz Date: Thu, 23 May 2024 15:27:31 +0200 Subject: [PATCH 10/10] [TMP] Required dev dependencies --- .github/workflows/ci.yaml | 9 +++++++++ dependencies.json | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 dependencies.json diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 44cbf32882..432b070e82 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -62,6 +62,9 @@ jobs: dependency-versions: "highest" composer-options: "--prefer-dist --no-progress" + - name: 'Use dev dependency' + run: composer req ibexa/core:'dev-ibx-7911-drop-magic-getters as 4.6.x-dev' ibexa/user:'dev-ibx-7911-drop-magic-getters as 4.6.x-dev' + - name: Setup problem matchers for PHPUnit run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" @@ -113,6 +116,9 @@ jobs: with: dependency-versions: "highest" + - name: 'Use dev dependency' + run: composer req ibexa/core:'dev-ibx-7911-drop-magic-getters as 4.6.x-dev' ibexa/user:'dev-ibx-7911-drop-magic-getters as 4.6.x-dev' + - name: Setup problem matchers for PHPUnit run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" @@ -168,6 +174,9 @@ jobs: with: dependency-versions: "highest" + - name: 'Use dev dependency' + run: composer req ibexa/core:'dev-ibx-7911-drop-magic-getters as 4.6.x-dev' ibexa/user:'dev-ibx-7911-drop-magic-getters as 4.6.x-dev' + - name: Setup problem matchers for PHPUnit run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" diff --git a/dependencies.json b/dependencies.json new file mode 100644 index 0000000000..9d48d3a667 --- /dev/null +++ b/dependencies.json @@ -0,0 +1,17 @@ +{ + "recipesEndpoint": "", + "packages": [ + { + "requirement": "dev-ibx-7911-drop-magic-getters as 4.6.x-dev", + "repositoryUrl": "https://github.com/ibexa/core", + "package": "ibexa/core", + "shouldBeAddedAsVCS": false + }, + { + "requirement": "dev-ibx-7911-drop-magic-getters as 4.6.x-dev", + "repositoryUrl": "https://github.com/ibexa/user", + "package": "ibexa/user", + "shouldBeAddedAsVCS": false + } + ] +} \ No newline at end of file