From 351cd902bb24f06e96daad82246e74f98cd4d314 Mon Sep 17 00:00:00 2001 From: Lorenzo Ruozzi Date: Fri, 14 Jan 2022 17:10:05 +0100 Subject: [PATCH] Use channel default locale as main locale to generate url --- spec/Provider/ProductUrlProviderSpec.php | 109 ++++++++++++++++++++++- src/Provider/ProductUrlProvider.php | 22 ++++- 2 files changed, 124 insertions(+), 7 deletions(-) diff --git a/spec/Provider/ProductUrlProviderSpec.php b/spec/Provider/ProductUrlProviderSpec.php index b011654a..b51db9c5 100644 --- a/spec/Provider/ProductUrlProviderSpec.php +++ b/spec/Provider/ProductUrlProviderSpec.php @@ -75,6 +75,8 @@ function it_generates_urls_for_the_unique_channel_locale( $locale->getCode()->willReturn('en_US'); + $channel->getDefaultLocale()->shouldBeCalledOnce()->willReturn($locale); + $channel->getLocales()->shouldBeCalled()->willReturn(new ArrayCollection([ $locale->getWrappedObject(), ])); @@ -138,7 +140,7 @@ function it_generates_urls_for_the_unique_channel_locale( $this->generate($channel); } - function it_generates_urls_for_all_channel_locales( + function it_generates_urls_using_the_default_channel_locale_as_main_and_others_as_alternatives( ProductRepository $repository, RouterInterface $router, UrlFactoryInterface $urlFactory, @@ -161,7 +163,9 @@ function it_generates_urls_for_all_channel_locales( ): void { $now = new \DateTime(); - $localeContext->getLocaleCode()->willReturn('en_US'); + $localeContext->getLocaleCode()->shouldNotBeCalled()->willReturn('en_US'); + + $channel->getDefaultLocale()->shouldBeCalledOnce()->willReturn($enUSLocale); $enUSLocale->getCode()->willReturn('en_US'); $nlNLLocale->getCode()->willReturn('nl_NL'); @@ -213,7 +217,7 @@ function it_generates_urls_for_all_channel_locales( $router->generate('sylius_shop_product_show', [ 'slug' => 't-shirt', '_locale' => 'en_US', - ])->willReturn('http://sylius.org/en_US/products/t-shirt'); + ])->shouldBeCalled()->willReturn('http://sylius.org/en_US/products/t-shirt'); $router->generate('sylius_shop_product_show', [ 'slug' => 't-shirt', @@ -234,4 +238,103 @@ function it_generates_urls_for_all_channel_locales( $this->generate($channel); } + + function it_generates_urls_using_the_storage_context_locale_as_main_and_others_as_alternatives( + ProductRepository $repository, + RouterInterface $router, + UrlFactoryInterface $urlFactory, + AlternativeUrlFactoryInterface $alternativeUrlFactory, + LocaleContextInterface $localeContext, + LocaleInterface $enUSLocale, + LocaleInterface $nlNLLocale, + Collection $products, + \Iterator $iterator, + ProductInterface $product, + ProductImageInterface $productImage, + ProductTranslation $productEnUSTranslation, + ProductTranslation $productNlNLTranslation, + UrlInterface $url, + AlternativeUrlInterface $alternativeUrl, + QueryBuilder $queryBuilder, + AbstractQuery $query, + ChannelInterface $channel, + ProductImagesToSitemapImagesCollectionGeneratorInterface $productToImageSitemapArrayGenerator + ): void { + $now = new \DateTime(); + + $localeContext->getLocaleCode()->shouldBeCalledOnce()->willReturn('nl_NL'); + + $channel->getDefaultLocale()->shouldBeCalledOnce()->willReturn(null); + + $enUSLocale->getCode()->willReturn('en_US'); + $nlNLLocale->getCode()->willReturn('nl_NL'); + + $channel->getLocales()->shouldBeCalled()->willReturn(new ArrayCollection([ + $enUSLocale->getWrappedObject(), + $nlNLLocale->getWrappedObject(), + ])); + + $repository->createQueryBuilder('o')->willReturn($queryBuilder); + $queryBuilder->addSelect('translation')->willReturn($queryBuilder); + $queryBuilder->innerJoin('o.translations', 'translation')->willReturn($queryBuilder); + $queryBuilder->andWhere(':channel MEMBER OF o.channels')->willReturn($queryBuilder); + $queryBuilder->andWhere('o.enabled = :enabled')->willReturn($queryBuilder); + $queryBuilder->setParameter('channel', $channel)->willReturn($queryBuilder); + $queryBuilder->setParameter('enabled', true)->willReturn($queryBuilder); + $queryBuilder->getQuery()->willReturn($query); + $query->getResult()->willReturn($products); + + $products->getIterator()->willReturn($iterator); + $iterator->valid()->willReturn(true, false); + $iterator->next()->shouldBeCalled(); + $iterator->rewind()->shouldBeCalled(); + + $iterator->current()->willReturn($product); + + $productImage->getPath()->willReturn(null); + + $product->getUpdatedAt()->willReturn($now); + $product->getImages()->willReturn(new ArrayCollection([ + $productImage->getWrappedObject(), + ])); + + $sitemapImageCollection = new ArrayCollection([]); + + $productToImageSitemapArrayGenerator->generate($product)->willReturn($sitemapImageCollection); + + $productEnUSTranslation->getLocale()->willReturn('en_US'); + $productEnUSTranslation->getSlug()->willReturn('t-shirt'); + + $productNlNLTranslation->getLocale()->willReturn('nl_NL'); + $productNlNLTranslation->getSlug()->willReturn('t-shirt'); + + $product->getTranslations()->shouldBeCalled()->willReturn(new ArrayCollection([ + $productEnUSTranslation->getWrappedObject(), + $productNlNLTranslation->getWrappedObject(), + ])); + + $router->generate('sylius_shop_product_show', [ + 'slug' => 't-shirt', + '_locale' => 'en_US', + ])->shouldBeCalled()->willReturn('http://sylius.org/en_US/products/t-shirt'); + + $router->generate('sylius_shop_product_show', [ + 'slug' => 't-shirt', + '_locale' => 'nl_NL', + ])->shouldBeCalled()->willReturn('http://sylius.org/nl_NL/products/t-shirt'); + + $urlFactory->createNew('')->willReturn($url); + $alternativeUrlFactory->createNew('http://sylius.org/en_US/products/t-shirt', 'en_US')->willReturn($alternativeUrl); + + $url->setImages($sitemapImageCollection)->shouldBeCalled(); + $url->setLocation('http://sylius.org/en_US/products/t-shirt')->shouldNotBeCalled(); + $url->setLocation('http://sylius.org/nl_NL/products/t-shirt')->shouldBeCalled(); + $url->setLastModification($now)->shouldBeCalled(); + $url->setChangeFrequency(ChangeFrequency::always())->shouldBeCalled(); + $url->setPriority(0.5)->shouldBeCalled(); + + $url->addAlternative($alternativeUrl)->shouldBeCalled(); + + $this->generate($channel); + } } diff --git a/src/Provider/ProductUrlProvider.php b/src/Provider/ProductUrlProvider.php index 5ad11e24..e5c1c38a 100644 --- a/src/Provider/ProductUrlProvider.php +++ b/src/Provider/ProductUrlProvider.php @@ -33,6 +33,8 @@ final class ProductUrlProvider implements UrlProviderInterface private ChannelInterface $channel; + private string $defaultLocaleCode; + /** @var array */ private array $channelLocaleCodes; @@ -67,6 +69,8 @@ public function generate(ChannelInterface $channel): iterable $this->channel = $channel; $urls = []; $this->channelLocaleCodes = []; + $channelDefaultLocaleCode = $this->getChannelDefaultLocaleCode($channel); + $this->defaultLocaleCode = $channelDefaultLocaleCode ?? $this->localeContext->getLocaleCode(); foreach ($this->getProducts() as $product) { $urls[] = $this->createProductUrl($product); @@ -127,9 +131,9 @@ private function createProductUrl(ProductInterface $product): UrlInterface /** @var ProductTranslationInterface $translation */ foreach ($this->getTranslations($product) as $translation) { - $locale = $translation->getLocale(); + $localeCode = $translation->getLocale(); - if ($locale === null) { + if ($localeCode === null) { continue; } @@ -142,15 +146,25 @@ private function createProductUrl(ProductInterface $product): UrlInterface '_locale' => $translation->getLocale(), ]); - if ($locale === $this->localeContext->getLocaleCode()) { + if ($localeCode === $this->defaultLocaleCode) { $productUrl->setLocation($location); continue; } - $productUrl->addAlternative($this->urlAlternativeFactory->createNew($location, $locale)); + $productUrl->addAlternative($this->urlAlternativeFactory->createNew($location, $localeCode)); } return $productUrl; } + + private function getChannelDefaultLocaleCode(ChannelInterface $channel): ?string + { + $channelDefaultLocale = $channel->getDefaultLocale(); + if ($channelDefaultLocale === null) { + return null; + } + + return $channelDefaultLocale->getCode(); + } }