From cd2a017e840ec5fed0efd5c0825bfcb3d09f6275 Mon Sep 17 00:00:00 2001 From: Ambroise Maupate Date: Wed, 13 Dec 2023 11:41:35 +0100 Subject: [PATCH 1/2] fix(Api): Added `AttributeValueQueryExtension` and `NodesTagsQueryExtension` to restrict tags and attributes linked to any published node. --- lib/RoadizCoreBundle/config/services.yaml | 15 ++++ .../AttributeValueQueryExtension.php | 81 +++++++++++++++++ .../Api/Extension/NodesTagsQueryExtension.php | 89 +++++++++++++++++++ 3 files changed, 185 insertions(+) create mode 100644 lib/RoadizCoreBundle/src/Api/Extension/AttributeValueQueryExtension.php create mode 100644 lib/RoadizCoreBundle/src/Api/Extension/NodesTagsQueryExtension.php diff --git a/lib/RoadizCoreBundle/config/services.yaml b/lib/RoadizCoreBundle/config/services.yaml index 320fc593..bd71d3e9 100644 --- a/lib/RoadizCoreBundle/config/services.yaml +++ b/lib/RoadizCoreBundle/config/services.yaml @@ -114,6 +114,21 @@ services: # Extension must be called after all filtering BUT before default pagination extension tags: [ { name: 'api_platform.doctrine.orm.query_extension.collection', priority: -40 } ] + # + # These API doctrine extension must be called last before pagination + # to perform on existing JOIN with node entities (found after filtering) + # + RZ\Roadiz\CoreBundle\Api\Extension\AttributeValueQueryExtension: + tags: [ + { name: 'api_platform.doctrine.orm.query_extension.collection', priority: -40 }, + { name: 'api_platform.doctrine.orm.query_extension.item', priority: -40 }, + ] + RZ\Roadiz\CoreBundle\Api\Extension\NodesTagsQueryExtension: + tags: [ + { name: 'api_platform.doctrine.orm.query_extension.collection', priority: -40 }, + { name: 'api_platform.doctrine.orm.query_extension.item', priority: -40 }, + ] + RZ\Roadiz\CoreBundle\Bag\: resource: '../src/Bag/' autowire: true diff --git a/lib/RoadizCoreBundle/src/Api/Extension/AttributeValueQueryExtension.php b/lib/RoadizCoreBundle/src/Api/Extension/AttributeValueQueryExtension.php new file mode 100644 index 00000000..7915f9bb --- /dev/null +++ b/lib/RoadizCoreBundle/src/Api/Extension/AttributeValueQueryExtension.php @@ -0,0 +1,81 @@ +previewResolver = $previewResolver; + } + + public function applyToItem( + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator, + string $resourceClass, + array $identifiers, + ?Operation $operation = null, + array $context = [] + ): void { + $this->apply($queryBuilder, $resourceClass); + } + + public function applyToCollection( + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator, + string $resourceClass, + ?Operation $operation = null, + array $context = [] + ): void { + $this->apply($queryBuilder, $resourceClass); + } + + private function apply( + QueryBuilder $queryBuilder, + string $resourceClass + ): void { + if ( + $resourceClass !== AttributeValue::class + ) { + return; + } + + $parts = $queryBuilder->getDQLPart('join'); + $rootAlias = $queryBuilder->getRootAliases()[0]; + if (!\is_array($parts) || !isset($parts[$rootAlias])) { + return; + } + + $existingNodeJoin = QueryBuilderHelper::getExistingJoin($queryBuilder, 'o', 'node'); + if (null === $existingNodeJoin || !$existingNodeJoin->getAlias()) { + return; + } + + if ($this->previewResolver->isPreview()) { + $queryBuilder + ->andWhere($queryBuilder->expr()->lte($existingNodeJoin->getAlias() . '.status', ':status')) + ->setParameter(':status', Node::PUBLISHED); + return; + } + + $queryBuilder + ->andWhere($queryBuilder->expr()->eq($existingNodeJoin->getAlias() . '.status', ':status')) + ->setParameter(':status', Node::PUBLISHED); + return; + } +} diff --git a/lib/RoadizCoreBundle/src/Api/Extension/NodesTagsQueryExtension.php b/lib/RoadizCoreBundle/src/Api/Extension/NodesTagsQueryExtension.php new file mode 100644 index 00000000..a5ea3cb3 --- /dev/null +++ b/lib/RoadizCoreBundle/src/Api/Extension/NodesTagsQueryExtension.php @@ -0,0 +1,89 @@ +previewResolver = $previewResolver; + } + + public function applyToItem( + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator, + string $resourceClass, + array $identifiers, + ?Operation $operation = null, + array $context = [] + ): void { + $this->apply($queryBuilder, $resourceClass); + } + + public function applyToCollection( + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator, + string $resourceClass, + ?Operation $operation = null, + array $context = [] + ): void { + $this->apply($queryBuilder, $resourceClass); + } + + private function apply( + QueryBuilder $queryBuilder, + string $resourceClass + ): void { + if ( + $resourceClass !== Tag::class + ) { + return; + } + + $parts = $queryBuilder->getDQLPart('join'); + $rootAlias = $queryBuilder->getRootAliases()[0]; + if (!\is_array($parts) || !isset($parts[$rootAlias])) { + return; + } + + $existingJoin = QueryBuilderHelper::getExistingJoin($queryBuilder, 'o', 'nodesTags'); + if (null === $existingJoin || !$existingJoin->getAlias()) { + return; + } + $existingNodeJoin = QueryBuilderHelper::getExistingJoin( + $queryBuilder, + $existingJoin->getAlias(), + 'node' + ); + if (null === $existingNodeJoin || !$existingNodeJoin->getAlias()) { + return; + } + + if ($this->previewResolver->isPreview()) { + $queryBuilder + ->andWhere($queryBuilder->expr()->lte($existingNodeJoin->getAlias() . '.status', ':status')) + ->setParameter(':status', Node::PUBLISHED); + return; + } + + $queryBuilder + ->andWhere($queryBuilder->expr()->eq($existingNodeJoin->getAlias() . '.status', ':status')) + ->setParameter(':status', Node::PUBLISHED); + return; + } +} From b21ad0b440a00fcc4e0df45ebdbcb5b2f4bfaeaa Mon Sep 17 00:00:00 2001 From: Ambroise Maupate Date: Wed, 13 Dec 2023 11:44:03 +0100 Subject: [PATCH 2/2] chore: Bumped --- CHANGELOG.md | 7 +++++++ lib/RoadizCoreBundle/config/services.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90201619..74642d1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [v2.2.1](https://github.com/roadiz/core-bundle-dev-app/compare/v2.2.0...v2.2.1) (2023-12-13) + + +### Bug Fixes + +* **Api:** Added `AttributeValueQueryExtension` and `NodesTagsQueryExtension` to restrict tags and attributes linked to any published node. ([cd2a017](https://github.com/roadiz/core-bundle-dev-app/commit/cd2a017e840ec5fed0efd5c0825bfcb3d09f6275)) + ## [v2.2.0](https://github.com/roadiz/core-bundle-dev-app/compare/v2.1.51...v2.2.0) (2023-12-12) diff --git a/lib/RoadizCoreBundle/config/services.yaml b/lib/RoadizCoreBundle/config/services.yaml index bd71d3e9..30949db2 100644 --- a/lib/RoadizCoreBundle/config/services.yaml +++ b/lib/RoadizCoreBundle/config/services.yaml @@ -1,6 +1,6 @@ --- parameters: - roadiz_core.cms_version: '2.2.0' + roadiz_core.cms_version: '2.2.1' roadiz_core.cms_version_prefix: 'main' env(APP_NAMESPACE): "roadiz" env(APP_VERSION): "0.1.0"