Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use channel default locale as main localization to generate url #197

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 106 additions & 3 deletions spec/Provider/ProductUrlProviderSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
]));
Expand Down Expand Up @@ -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,
Expand All @@ -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');
Expand Down Expand Up @@ -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',
Expand All @@ -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);
}
}
22 changes: 18 additions & 4 deletions src/Provider/ProductUrlProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ final class ProductUrlProvider implements UrlProviderInterface

private ChannelInterface $channel;

private string $defaultLocaleCode;

/** @var array<string|null> */
private array $channelLocaleCodes;

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand All @@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Tests\SitemapPlugin\Controller;

final class SitemapProductControllerApiChannelDefaultLocaleTest extends XmlApiTestCase
{
public function testShowActionResponse(): void
{
$this->loadFixturesFromFiles(['channel_with_locale_different_from_default.yaml', 'product_with_locales.yaml']);
$this->generateSitemaps();

$response = $this->getBufferedResponse('/sitemap/products.xml');
$this->assertResponse($response, 'show_sitemap_products_with_channel_default_locale');
$this->deleteSitemaps();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Sylius\Component\Core\Model\Channel:
web_channel:
code: "WEB"
name: "Web Store"
hostname: "localhost"
description: "Lorem ipsum"
baseCurrency: "@usd"
defaultLocale: "@locale_nl_nl"
locales: ["@locale_nl_nl"]
color: "black"
enabled: true
taxCalculationStrategy: "order_items_based"
accountVerificationRequired: true

Sylius\Component\Currency\Model\Currency:
usd:
code: USD
euro:
code: EUR

Sylius\Component\Locale\Model\Locale:
locale_nl_nl:
code: nl_NL
locale_en_us:
code: en_US
20 changes: 20 additions & 0 deletions tests/DataFixtures/ORM/product_with_locales.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Sylius\Component\Core\Model\Product:
test_product:
code: "test-code"
channels: ["@web_channel"]
currentLocale: "nl_NL"
translations:
- "@nl_nl_test_product_translation"
- "@en_us_test_product_translation"

Sylius\Component\Core\Model\ProductTranslation:
nl_nl_test_product_translation:
slug: "test-code"
locale: "nl_NL"
name: "Test"
translatable: "@test_product"
en_us_test_product_translation:
slug: "test-code"
locale: "en_US"
name: "Test"
translatable: "@test_product"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>http://localhost/nl_NL/products/test-code</loc>
<lastmod>@[email protected]()</lastmod>
<changefreq>always</changefreq>
<priority>0.5</priority>
</url>
</urlset>