Skip to content

Commit

Permalink
Merge pull request #152 from sweoggy/sitemap-support
Browse files Browse the repository at this point in the history
Sitemap support
  • Loading branch information
patrick477 authored Jun 22, 2018
2 parents 3407816 + 03b68ff commit 633781f
Show file tree
Hide file tree
Showing 20 changed files with 508 additions and 6,202 deletions.
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ $ bin/console doctrine:schema:update --force
$ bin/console assets:install
```

### Optional, Sitemap integration
This plugin has a ready to go integration with [Sylius Sitemap Plugin](https://github.com/stefandoorn/sitemap-plugin).

To enable the integration you need to add the following to your `app/config/config.yml` file:
```yaml
# app/config/config.yml
imports:
...
- { resource: "@BitBagSyliusCmsPlugin/Resources/config/services/sitemap_provider.yml" }
```

## Usage

### Blocks
Expand Down
6 changes: 5 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
"license": "MIT",
"require": {
"php": "^7.1",

"sylius/sylius": "^1.1"
},
"require-dev": {
Expand All @@ -19,15 +18,20 @@
"friends-of-behat/service-container-extension": "^1.0",
"friends-of-behat/symfony-extension": "^1.0",
"friends-of-behat/variadic-extension": "^1.0",
"lakion/api-test-case": "^1.1",
"lakion/mink-debug-extension": "^1.2.3",
"phpspec/phpspec": "^3.2",
"phpstan/phpstan-shim": "^0.9.2",
"phpunit/phpunit": "^5.6",
"se/selenium-server-standalone": "^2.52",
"stefandoorn/sitemap-plugin": "^1.0.8",
"symplify/easy-coding-standard": "^2.4",
"sylius-labs/coding-standard": "^1.0",
"matthiasnoback/symfony-config-test": "^2.1.0"
},
"suggest": {
"stefandoorn/sitemap-plugin": "If you want SEO friendly sitemaps generated for your CMS pages"
},
"prefer-stable": true,
"minimum-stability": "alpha",
"autoload": {
Expand Down
3 changes: 2 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="BitBagSyliusCmsPlugin Test Suite">

<directory>tests</directory>
</testsuite>
</testsuites>

<php>
<server name="KERNEL_CLASS_PATH" value="/tests/Application/AppKernel.php"/>
<server name="KERNEL_DIR" value="tests/Application/app/" />
<server name="IS_DOCTRINE_ORM_SUPPORTED" value="true"/>
<server name="EXPECTED_RESPONSE_DIR" value="../../Responses/Expected"/>
</php>
</phpunit>
2 changes: 1 addition & 1 deletion src/Fixture/Factory/PageFixtureFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ private function createPage(string $code, array $pageData, bool $generateSlug =
if ($translation['image_path']) {
$image = new PageImage();
$path = $translation['image_path'];
$uploadedImage = new UploadedFile($path, md5($path).'.jpg');
$uploadedImage = new UploadedFile($path, md5($path) . '.jpg');

$image->setFile($uploadedImage);
$pageTranslation->setImage($image);
Expand Down
15 changes: 15 additions & 0 deletions src/Repository/PageRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,21 @@ public function createListQueryBuilder(string $locale): QueryBuilder
;
}

/**
* {@inheritdoc}
*/
public function findByEnabled(bool $enabled): array
{
return $this->createQueryBuilder('o')
->addSelect('translation')
->innerJoin('o.translations', 'translation')
->andWhere('o.enabled = :enabled')
->setParameter('enabled', $enabled)
->getQuery()
->getResult()
;
}

/**
* {@inheritdoc}
*/
Expand Down
7 changes: 7 additions & 0 deletions src/Repository/PageRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ interface PageRepositoryInterface extends RepositoryInterface
*/
public function createListQueryBuilder(string $locale): QueryBuilder;

/**
* @param bool $enabled
*
* @return array|PageInterface[]
*/
public function findByEnabled(bool $enabled): array;

/**
* @param string $code
* @param string|null $localeCode
Expand Down
2 changes: 1 addition & 1 deletion src/Repository/ProductRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ interface ProductRepositoryInterface extends BaseProductRepositoryInterface
{
/**
* @param string $phrase
* @param null|string $locale
* @param string|null $locale
*
* @return array|ProductInterface[]
*/
Expand Down
11 changes: 11 additions & 0 deletions src/Resources/config/services/sitemap_provider.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
bitbag_sylius_cms_plugin.sitemap_provider.page:
class: BitBag\SyliusCmsPlugin\Sitemap\Provider\PageUrlProvider
arguments:
- "@bitbag_sylius_cms_plugin.repository.page"
- "@router"
- "@sylius.sitemap_url_factory"
- "@sylius.context.locale"
- "@sylius.context.channel"
tags:
- "sylius.sitemap_provider"
184 changes: 184 additions & 0 deletions src/Sitemap/Provider/PageUrlProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
<?php

declare(strict_types=1);

namespace BitBag\SyliusCmsPlugin\Sitemap\Provider;

use BitBag\SyliusCmsPlugin\Entity\PageInterface;
use BitBag\SyliusCmsPlugin\Entity\PageTranslationInterface;
use BitBag\SyliusCmsPlugin\Repository\PageRepositoryInterface;
use Doctrine\Common\Collections\Collection;
use SitemapPlugin\Factory\SitemapUrlFactoryInterface;
use SitemapPlugin\Model\ChangeFrequency;
use SitemapPlugin\Model\SitemapUrlInterface;
use SitemapPlugin\Provider\UrlProviderInterface;
use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
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;

class PageUrlProvider implements UrlProviderInterface
{
/**
* @var PageRepositoryInterface|EntityRepository
*/
private $pageRepository;

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

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

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

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

/**
* @var array
*/
private $urls = [];

/**
* @var array
*/
private $channelLocaleCodes;

/**
* @param PageRepositoryInterface $pageRepository
* @param RouterInterface $router
* @param SitemapUrlFactoryInterface $sitemapUrlFactory
* @param LocaleContextInterface $localeContext
* @param ChannelContextInterface $channelContext
*/
public function __construct(
PageRepositoryInterface $pageRepository,
RouterInterface $router,
SitemapUrlFactoryInterface $sitemapUrlFactory,
LocaleContextInterface $localeContext,
ChannelContextInterface $channelContext
) {
$this->pageRepository = $pageRepository;
$this->router = $router;
$this->sitemapUrlFactory = $sitemapUrlFactory;
$this->localeContext = $localeContext;
$this->channelContext = $channelContext;
}

/**
* @return string
*/
public function getName(): string
{
return 'cms_pages';
}

/**
* {@inheritdoc}
*/
public function generate(): iterable
{
foreach ($this->getPages() as $product) {
$this->urls[] = $this->createPageUrl($product);
}

return $this->urls;
}

/**
* @param PageInterface $page
*
* @return Collection|PageTranslationInterface[]
*/
private function getTranslations(PageInterface $page): Collection
{
return $page->getTranslations()->filter(function (TranslationInterface $translation) {
return $this->localeInLocaleCodes($translation);
});
}

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

/**
* @return array|PageInterface[]
*/
private function getPages(): iterable
{
return $this->pageRepository->findByEnabled(true);
}

/**
* @return array
*/
private function getLocaleCodes(): array
{
if (null === $this->channelLocaleCodes) {
/** @var ChannelInterface $channel */
$channel = $this->channelContext->getChannel();
$this->channelLocaleCodes = $channel->getLocales()->map(function (LocaleInterface $locale) {
return $locale->getCode();
})->toArray();
}

return $this->channelLocaleCodes;
}

/**
* @param PageInterface $page
*
* @return SitemapUrlInterface
*/
private function createPageUrl(PageInterface $page): SitemapUrlInterface
{
$pageUrl = $this->sitemapUrlFactory->createNew();
$pageUrl->setChangeFrequency(ChangeFrequency::daily());
$pageUrl->setPriority(0.7);
if ($page->getUpdatedAt()) {
$pageUrl->setLastModification($page->getUpdatedAt());
} elseif ($page->getCreatedAt()) {
$pageUrl->setLastModification($page->getCreatedAt());
}
/** @var PageTranslationInterface $translation */
foreach ($this->getTranslations($page) as $translation) {
if (!$translation->getLocale()) {
continue;
}
if (!$this->localeInLocaleCodes($translation)) {
continue;
}
$location = $this->router->generate('bitbag_sylius_cms_plugin_shop_page_show', [
'slug' => $translation->getSlug(),
'_locale' => $translation->getLocale(),
]);
if ($translation->getLocale() === $this->localeContext->getLocaleCode()) {
$pageUrl->setLocalization($location);

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

return $pageUrl;
}
}
72 changes: 72 additions & 0 deletions tests/Api/Sitemap/Provider/AbstractTestController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

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

use Lakion\ApiTestCase\XmlApiTestCase;
use Sylius\Component\Core\Model\Channel;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Currency\Model\Currency;
use Sylius\Component\Currency\Model\CurrencyInterface;
use Sylius\Component\Locale\Model\Locale;
use Sylius\Component\Locale\Model\LocaleInterface;

abstract class AbstractTestController extends XmlApiTestCase
{

/**
* @var ChannelInterface
*/
protected $channel;

/**
* @var LocaleInterface
*/
protected $locale;

/**
* @var LocaleInterface
*/
protected $secondLocale;

/**
* @var CurrencyInterface
*/
protected $currency;

/**
* @before
*/
public function setupDatabase()
{
parent::setUpDatabase();

$this->locale = new Locale();
$this->locale->setCode('en_US');

$this->getEntityManager()->persist($this->locale);

$this->secondLocale = new Locale();
$this->secondLocale->setCode('nl_NL');

$this->getEntityManager()->persist($this->secondLocale);

$this->currency = new Currency();
$this->currency->setCode('USD');

$this->getEntityManager()->persist($this->currency);

$this->channel = new Channel();
$this->channel->setCode('US_WEB');
$this->channel->setName('US Web Store');
$this->channel->setDefaultLocale($this->locale);
$this->channel->setBaseCurrency($this->currency);
$this->channel->setTaxCalculationStrategy('order_items_based');

$this->channel->addLocale($this->locale);
$this->channel->addLocale($this->secondLocale);

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

}
Loading

0 comments on commit 633781f

Please sign in to comment.