Skip to content

Commit

Permalink
Add sitemap provider for sections
Browse files Browse the repository at this point in the history
  • Loading branch information
stefandoorn committed Aug 24, 2018
1 parent 88da802 commit 78fac40
Show file tree
Hide file tree
Showing 7 changed files with 288 additions and 1 deletion.
13 changes: 12 additions & 1 deletion src/Resources/config/services/sitemap_provider.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,15 @@ services:
- "@sylius.context.locale"
- "@sylius.context.channel"
tags:
- "sylius.sitemap_provider"
- "sylius.sitemap_provider"

bitbag_sylius_cms_plugin.sitemap_provider.section:
class: BitBag\SyliusCmsPlugin\SitemapProvider\SectionUrlProvider
arguments:
- "@bitbag_sylius_cms_plugin.repository.section"
- "@router"
- "@sylius.sitemap_url_factory"
- "@sylius.context.locale"
- "@sylius.context.channel"
tags:
- { name: sylius.sitemap_provider }
133 changes: 133 additions & 0 deletions src/SitemapProvider/SectionUrlProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* another great project.
* You can find more information about us on https://bitbag.shop and write us
* an email on [email protected].
*/

declare(strict_types=1);

namespace BitBag\SyliusCmsPlugin\SitemapProvider;

use BitBag\SyliusCmsPlugin\Entity\SectionInterface;
use BitBag\SyliusCmsPlugin\Entity\SectionTranslationInterface;
use BitBag\SyliusCmsPlugin\Repository\SectionRepositoryInterface;
use Doctrine\Common\Collections\Collection;
use SitemapPlugin\Factory\SitemapUrlFactoryInterface;
use SitemapPlugin\Model\ChangeFrequency;
use SitemapPlugin\Model\SitemapUrlInterface;
use SitemapPlugin\Provider\UrlProviderInterface;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Model\TranslationInterface;
use Symfony\Component\Routing\RouterInterface;

final class SectionUrlProvider implements UrlProviderInterface
{
/** @var SectionRepositoryInterface */
private $sectionRepository;

/** @var RouterInterface */
private $router;

/** @var SitemapUrlFactoryInterface */
private $sitemapUrlFactory;

/** @var LocaleContextInterface */
private $localeContext;

/** @var ChannelContextInterface */
private $channelContext;

public function __construct(
SectionRepositoryInterface $sectionRepository,
RouterInterface $router,
SitemapUrlFactoryInterface $sitemapUrlFactory,
LocaleContextInterface $localeContext,
ChannelContextInterface $channelContext
) {
$this->sectionRepository = $sectionRepository;
$this->router = $router;
$this->sitemapUrlFactory = $sitemapUrlFactory;
$this->localeContext = $localeContext;
$this->channelContext = $channelContext;
}

public function getName(): string
{
return 'cms_sections';
}

public function generate(): iterable
{
$urls = [];

foreach ($this->getSections() as $section) {
$urls[] = $this->createSectionUrl($section);
}

return $urls;
}

private function getTranslations(SectionInterface $section): Collection
{
return $section->getTranslations()->filter(function (TranslationInterface $translation) {
return $this->localeInLocaleCodes($translation);
});
}

private function localeInLocaleCodes(TranslationInterface $translation): bool
{
return in_array($translation->getLocale(), $this->getLocaleCodes());
}

private function getSections(): iterable
{
return $this->sectionRepository->findAll();
}

private function getLocaleCodes(): array
{
/** @var ChannelInterface $channel */
$channel = $this->channelContext->getChannel();

return $channel->getLocales()->map(function (LocaleInterface $locale) {
return $locale->getCode();
})->toArray();
}

private function createSectionUrl(SectionInterface $section): SitemapUrlInterface
{
$url = $this->sitemapUrlFactory->createNew();

$url->setChangeFrequency(ChangeFrequency::daily());
$url->setPriority(0.7);

/** @var SectionTranslationInterface $translation */
foreach ($this->getTranslations($section) as $translation) {
if (!$translation->getLocale() || !$this->localeInLocaleCodes($translation)) {
continue;
}

$location = $this->router->generate('bitbag_sylius_cms_plugin_shop_section_show', [
'code' => $section->getCode(),
'_locale' => $translation->getLocale(),
]);

if ($translation->getLocale() === $this->localeContext->getLocaleCode()) {
$url->setLocalization($location);

continue;
}

$url->addAlternative($location, $translation->getLocale());
}

return $url;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public function setUpDatabase(): void
$page->setSlug('test 2');
$page->setEnabled(false);
$this->getEntityManager()->persist($page);

$this->getEntityManager()->flush();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* another great project.
* You can find more information about us on https://bitbag.shop and write us
* an email on [email protected].
*/

declare(strict_types=1);

namespace Tests\BitBag\SyliusCmsPlugin\Api\Sitemap\Provider;

use BitBag\SyliusCmsPlugin\Entity\Section;

class SitemapSectionControllerApiLocalesTest extends AbstractTestController
{
/**
* @before
*/
public function setUpDatabase(): void
{
parent::setUpDatabase();

$section = new Section();
$section->setCurrentLocale('en_US');
$section->setName('Test');
$section->setCode('test');
$section->setCurrentLocale('nl_NL');
$section->setName('Test');
$this->getEntityManager()->persist($section);

$section = new Section();
$section->setCurrentLocale('en_US');
$section->setName('Mock');
$section->setCode('mock');
$section->setCurrentLocale('nl_NL');
$section->setName('Mock');
$this->getEntityManager()->persist($section);

$this->getEntityManager()->flush();
}

public function testShowActionResponse(): void
{
$this->client->request('GET', '/sitemap/cms_sections.xml');
$response = $this->client->getResponse();
$this->assertResponse($response, 'show_sitemap_sections_locale');
}
}
47 changes: 47 additions & 0 deletions tests/Api/Sitemap/Provider/SitemapSectionControllerApiTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* another great project.
* You can find more information about us on https://bitbag.shop and write us
* an email on [email protected].
*/

declare(strict_types=1);

namespace Tests\BitBag\SyliusCmsPlugin\Api\Sitemap\Provider;

use BitBag\SyliusCmsPlugin\Entity\Section;

class SitemapSectionControllerApiTest extends AbstractTestController
{
/**
* @before
*/
public function setUpDatabase(): void
{
parent::setUpDatabase();

$section = new Section();
$section->setCurrentLocale('en_US');
$section->setName('Test');
$section->setCode('test');
$this->getEntityManager()->persist($section);

$section = new Section();
$section->setCurrentLocale('en_US');
$section->setName('Mock');
$section->setCode('mock');
$this->getEntityManager()->persist($section);

$this->getEntityManager()->flush();
}

public function testShowActionResponse(): void
{
$this->client->request('GET', '/sitemap/cms_sections.xml');
$response = $this->client->getResponse();
$this->assertResponse($response, 'show_sitemap_sections');
}
}
13 changes: 13 additions & 0 deletions tests/Responses/Expected/show_sitemap_sections.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://localhost/en_US/section/test</loc>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://localhost/en_US/section/mock</loc>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
</urlset>
31 changes: 31 additions & 0 deletions tests/Responses/Expected/show_sitemap_sections_locale.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
<url>
<loc>http://localhost/en_US/section/test</loc>
<xhtml:link rel="alternate" hreflang="en" href="http://localhost/en_US/section/test"/>
<xhtml:link rel="alternate" hreflang="nl" href="http://localhost/nl_NL/section/test"/>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://localhost/nl_NL/section/test</loc>
<xhtml:link rel="alternate" hreflang="en" href="http://localhost/en_US/section/test"/>
<xhtml:link rel="alternate" hreflang="nl" href="http://localhost/nl_NL/section/test"/>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://localhost/en_US/section/mock</loc>
<xhtml:link rel="alternate" hreflang="en" href="http://localhost/en_US/section/mock"/>
<xhtml:link rel="alternate" hreflang="nl" href="http://localhost/nl_NL/section/mock"/>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>http://localhost/nl_NL/section/mock</loc>
<xhtml:link rel="alternate" hreflang="en" href="http://localhost/en_US/section/mock"/>
<xhtml:link rel="alternate" hreflang="nl" href="http://localhost/nl_NL/section/mock"/>
<changefreq>daily</changefreq>
<priority>0.7</priority>
</url>
</urlset>

0 comments on commit 78fac40

Please sign in to comment.