Join all translations if no localeCode provided in PaymentMethod translations order filter

This commit is contained in:
Kamil Grygierzec 2024-08-13 11:43:24 +02:00 committed by Grzegorz Sadowski
parent c3e0034118
commit 48a8e74587
4 changed files with 96 additions and 6 deletions

View file

@ -18,10 +18,16 @@ use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\ORM\QueryBuilder;
use Sylius\Bundle\ApiBundle\SectionResolver\ShopApiSection;
use Sylius\Bundle\CoreBundle\SectionResolver\SectionProviderInterface;
use Sylius\Component\Resource\Model\TranslatableInterface;
final class TranslationOrderLocaleExtension implements QueryCollectionExtensionInterface
{
public function __construct(private readonly SectionProviderInterface $sectionProvider)
{
}
/** @param array<string, mixed> $context */
public function applyToCollection(
QueryBuilder $queryBuilder,
@ -42,11 +48,24 @@ final class TranslationOrderLocaleExtension implements QueryCollectionExtensionI
}
$localeCode = $this->resolveContextLocaleCode($context);
$rootAlias = $queryBuilder->getRootAliases()[0];
if (empty($localeCode)) {
if ($this->sectionProvider->getSection() instanceof ShopApiSection) {
return;
}
$queryBuilder
->addSelect('translation')
->leftJoin(
sprintf('%s.translations', $rootAlias),
'translation',
)
;
return;
}
$rootAlias = $queryBuilder->getRootAliases()[0];
$localeCodeParameterName = $queryNameGenerator->generateParameterName('localeCode');
$queryBuilder

View file

@ -23,7 +23,7 @@ final class TranslationOrderNameAndLocaleFilter extends AbstractFilter
{
protected function filterProperty(
string $property,
$value,
$value,
QueryBuilder $queryBuilder,
QueryNameGeneratorInterface $queryNameGenerator,
string $resourceClass,

View file

@ -22,6 +22,7 @@
</service>
<service id="sylius_api.doctrine.orm.query_extension.common.translation_order_locale" class="Sylius\Bundle\ApiBundle\Doctrine\ORM\QueryExtension\Common\TranslationOrderLocaleExtension">
<argument type="service" id="sylius.section_resolver.uri_based_section_resolver" />
<tag name="api_platform.doctrine.orm.query_extension.collection" />
</service>

View file

@ -21,24 +21,29 @@ use Doctrine\ORM\QueryBuilder;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Sylius\Bundle\ApiBundle\Doctrine\ORM\QueryExtension\Common\TranslationOrderLocaleExtension;
use Sylius\Bundle\ApiBundle\SectionResolver\ShopApiSection;
use Sylius\Bundle\CoreBundle\SectionResolver\SectionProviderInterface;
use Sylius\Component\Core\Model\ProductInterface;
final class TranslationOrderLocaleExtensionTest extends TestCase
{
private QueryNameGeneratorInterface&MockObject $queryNameGenerator;
private MockObject&QueryNameGeneratorInterface $queryNameGenerator;
private QueryBuilder&MockObject $queryBuilder;
private MockObject&QueryBuilder $queryBuilder;
private EntityManagerInterface&MockObject $entityManager;
private ClassMetadata&MockObject $classMetadata;
private MockObject&SectionProviderInterface $sectionProvider;
protected function setUp(): void
{
$this->queryNameGenerator = $this->createMock(QueryNameGeneratorInterface::class);
$this->queryBuilder = $this->createMock(QueryBuilder::class);
$this->entityManager = $this->createMock(EntityManagerInterface::class);
$this->classMetadata = $this->createMock(ClassMetadata::class);
$this->sectionProvider = $this->createMock(SectionProviderInterface::class);
}
/** @test */
@ -101,7 +106,7 @@ final class TranslationOrderLocaleExtensionTest extends TestCase
}
/** @test */
public function it_does_nothing_when_no_locale_code_has_been_resolved_from_filters(): void
public function it_joins_all_translations_if_no_locale_code_has_been_resolved_from_filters(): void
{
$this->queryBuilder
->expects($this->once())
@ -123,6 +128,70 @@ final class TranslationOrderLocaleExtensionTest extends TestCase
->willReturn(true)
;
$this->queryBuilder
->expects($this->once())
->method('getRootAliases')
->willReturn(['alias'])
;
$this->queryBuilder
->expects($this->once())
->method('addSelect')
->with('translation')
->willReturnSelf()
;
$this->queryBuilder
->expects($this->once())
->method('leftJoin')
->with('alias.translations', 'translation')
->willReturnSelf()
;
$this->doApplyToCollection(ProductInterface::class, [
'filters' => [
'order' => [
'translation.name' => 'test',
],
],
]);
}
/** @test */
public function it_does_nothing_when_no_locale_code_has_been_resolved_from_filters_and_it_is_shop_section(): void
{
$this->queryBuilder
->expects($this->once())
->method('getEntityManager')
->willReturn($this->entityManager)
;
$this->entityManager
->expects($this->once())
->method('getClassMetadata')
->with(ProductInterface::class)
->willReturn($this->classMetadata)
;
$this->classMetadata
->expects($this->once())
->method('hasAssociation')
->with('translations')
->willReturn(true)
;
$this->queryBuilder
->expects($this->once())
->method('getRootAliases')
->willReturn(['alias'])
;
$this->sectionProvider
->expects($this->once())
->method('getSection')
->willReturn(new ShopApiSection())
;
$this->queryBuilder
->expects($this->never())
->method('leftJoin')
@ -140,6 +209,7 @@ final class TranslationOrderLocaleExtensionTest extends TestCase
/**
* @test
*
* @dataProvider getLocaleCodeContexts
*/
public function it_joins_on_a_specific_translation_when_locale_code_has_been_resolved_from_filters(
@ -210,7 +280,7 @@ final class TranslationOrderLocaleExtensionTest extends TestCase
/** @param array<string, mixed> $context */
private function doApplyToCollection(string $resourceClass, array $context = []): void
{
(new TranslationOrderLocaleExtension())->applyToCollection(
(new TranslationOrderLocaleExtension($this->sectionProvider))->applyToCollection(
queryBuilder: $this->queryBuilder,
queryNameGenerator: $this->queryNameGenerator,
resourceClass: $resourceClass,