-
Notifications
You must be signed in to change notification settings - Fork 80
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added urls parameter to serialization (#187)
- Loading branch information
1 parent
f0ea23e
commit 1375f63
Showing
3 changed files
with
278 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Sulu. | ||
* | ||
* (c) MASSIVE ART WebServices GmbH | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace Sulu\Bundle\ArticleBundle\Document\Serializer; | ||
|
||
use Doctrine\ORM\NoResultException; | ||
use JMS\Serializer\EventDispatcher\Events; | ||
use JMS\Serializer\EventDispatcher\EventSubscriberInterface; | ||
use JMS\Serializer\EventDispatcher\ObjectEvent; | ||
use Sulu\Bundle\ArticleBundle\Document\ArticleDocument; | ||
use Sulu\Bundle\RouteBundle\Entity\RouteRepositoryInterface; | ||
use Sulu\Bundle\RouteBundle\Model\RouteInterface; | ||
use Sulu\Component\Webspace\Analyzer\Attributes\RequestAttributes; | ||
use Sulu\Component\Webspace\Webspace; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
|
||
/** | ||
* Add the urls to the serialized result. | ||
*/ | ||
class WebsiteArticleUrlsSubscriber implements EventSubscriberInterface | ||
{ | ||
/** | ||
* @var RequestStack | ||
*/ | ||
private $requestStack; | ||
|
||
/** | ||
* @var RouteRepositoryInterface | ||
*/ | ||
private $routeRepository; | ||
|
||
/** | ||
* @param RequestStack $requestStack | ||
* @param RouteRepositoryInterface $routeRepository | ||
*/ | ||
public function __construct(RequestStack $requestStack, RouteRepositoryInterface $routeRepository) | ||
{ | ||
$this->requestStack = $requestStack; | ||
$this->routeRepository = $routeRepository; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static function getSubscribedEvents() | ||
{ | ||
return [ | ||
[ | ||
'event' => Events::POST_SERIALIZE, | ||
'format' => 'array', | ||
'method' => 'addUrlsOnPostSerialize', | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* Loops thru current webspace locales and generates routes for them. | ||
* | ||
* @param ObjectEvent $event | ||
*/ | ||
public function addUrlsOnPostSerialize(ObjectEvent $event) | ||
{ | ||
$article = $event->getObject(); | ||
$visitor = $event->getVisitor(); | ||
$context = $event->getContext(); | ||
$request = $this->requestStack->getCurrentRequest(); | ||
|
||
if (!$article instanceof ArticleDocument || !$context->attributes->containsKey('website') || !$request) { | ||
return; | ||
} | ||
|
||
/** @var RequestAttributes $attributes */ | ||
$attributes = $request->get('_sulu'); | ||
if (!$attributes) { | ||
return; | ||
} | ||
|
||
/** @var Webspace $webspace */ | ||
$webspace = $attributes->getAttribute('webspace'); | ||
if (!$webspace) { | ||
return; | ||
} | ||
|
||
$urls = []; | ||
foreach ($webspace->getAllLocalizations() as $localization) { | ||
$locale = $localization->getLocale(); | ||
$route = $this->findByEntity(get_class($article), $article->getUuid(), $locale); | ||
|
||
$urls[$locale] = '/'; | ||
if ($route) { | ||
$urls[$locale] = $route->getPath(); | ||
} | ||
} | ||
|
||
$visitor->addData('urls', $context->accept($urls)); | ||
} | ||
|
||
/** | ||
* Return route for given entity information. | ||
* | ||
* @param string $entityClass | ||
* @param string $entityId | ||
* @param string $locale | ||
* | ||
* TODO replace this with $this->routeRepository->findByEntity when merging to develop | ||
* | ||
* @return RouteInterface | ||
*/ | ||
private function findByEntity($entityClass, $entityId, $locale) | ||
{ | ||
$query = $this->routeRepository->createQueryBuilder('entity') | ||
->andWhere('entity.entityClass = :entityClass') | ||
->andWhere('entity.entityId = :entityId') | ||
->andWhere('entity.locale = :locale') | ||
->andWhere('entity.history = false') | ||
->getQuery() | ||
->setParameters(['entityClass' => $entityClass, 'entityId' => $entityId, 'locale' => $locale]); | ||
|
||
try { | ||
return $query->getSingleResult(); | ||
} catch (NoResultException $e) { | ||
return; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
135 changes: 135 additions & 0 deletions
135
Tests/Unit/Document/Serializer/WebsiteArticleUrlsSubscriberTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
<?php | ||
|
||
/* | ||
* This file is part of Sulu. | ||
* | ||
* (c) MASSIVE ART WebServices GmbH | ||
* | ||
* This source file is subject to the MIT license that is bundled | ||
* with this source code in the file LICENSE. | ||
*/ | ||
|
||
namespace Sulu\Bundle\ArticleBundle\Tests\Unit\Document\Serializer; | ||
|
||
use Doctrine\ORM\AbstractQuery; | ||
use Doctrine\ORM\QueryBuilder; | ||
use JMS\Serializer\EventDispatcher\ObjectEvent; | ||
use JMS\Serializer\SerializationContext; | ||
use PhpCollection\Map; | ||
use Sulu\Bundle\ArticleBundle\Document\ArticleDocument; | ||
use Sulu\Bundle\ArticleBundle\Document\Serializer\WebsiteArticleUrlsSubscriber; | ||
use Sulu\Bundle\RouteBundle\Entity\RouteRepository; | ||
use Sulu\Bundle\RouteBundle\Entity\RouteRepositoryInterface; | ||
use Sulu\Bundle\RouteBundle\Model\RouteInterface; | ||
use Sulu\Component\Localization\Localization; | ||
use Sulu\Component\Serializer\ArraySerializationVisitor; | ||
use Sulu\Component\Webspace\Analyzer\Attributes\RequestAttributes; | ||
use Sulu\Component\Webspace\Webspace; | ||
use Symfony\Component\HttpFoundation\Request; | ||
use Symfony\Component\HttpFoundation\RequestStack; | ||
|
||
class WebsiteArticleUrlsSubscriberTest extends \PHPUnit_Framework_TestCase | ||
{ | ||
/** | ||
* @var RequestStack | ||
*/ | ||
private $requestStack; | ||
|
||
/** | ||
* @var RouteRepositoryInterface | ||
*/ | ||
private $routeRepository; | ||
|
||
/** | ||
* @var WebsiteArticleUrlsSubscriber | ||
*/ | ||
private $urlsSubscriber; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
protected function setUp() | ||
{ | ||
$this->requestStack = $this->prophesize(RequestStack::class); | ||
$this->routeRepository = $this->prophesize(RouteRepository::class); | ||
|
||
$this->urlsSubscriber = new WebsiteArticleUrlsSubscriber( | ||
$this->requestStack->reveal(), | ||
$this->routeRepository->reveal() | ||
); | ||
|
||
$webspace = new Webspace(); | ||
$webspace->addLocalization(new Localization('en')); | ||
$webspace->addLocalization(new Localization('de')); | ||
|
||
$request = $this->prophesize(Request::class); | ||
$request->get('_sulu')->willReturn(new RequestAttributes(['webspace' => $webspace])); | ||
$this->requestStack->getCurrentRequest()->willReturn($request->reveal()); | ||
} | ||
|
||
public function testAddUrlsOnPostSerialize() | ||
{ | ||
$article = $this->prophesize(ArticleDocument::class); | ||
$visitor = $this->prophesize(ArraySerializationVisitor::class); | ||
$context = $this->prophesize(SerializationContext::class); | ||
|
||
$entityId = '123-123-123'; | ||
$article->getUuid()->willReturn($entityId); | ||
|
||
$contextAttributes = $this->prophesize(Map::class); | ||
$contextAttributes->containsKey('website')->willReturn(true); | ||
$context->reveal()->attributes = $contextAttributes->reveal(); | ||
|
||
$event = $this->prophesize(ObjectEvent::class); | ||
$event->getObject()->willReturn($article->reveal()); | ||
$event->getVisitor()->willReturn($visitor->reveal()); | ||
$event->getContext()->willReturn($context->reveal()); | ||
|
||
$expected = ['de' => '/seite', 'en' => '/page']; | ||
$query = $this->mockQuery(); | ||
|
||
$entityClass = get_class($article->reveal()); | ||
foreach ($expected as $locale => $path) { | ||
$route = $this->prophesize(RouteInterface::class); | ||
$route->getPath()->willReturn($path); | ||
|
||
$localedQuery = $this->prophesize(AbstractQuery::class); | ||
$query->setParameters(['entityClass' => $entityClass, 'entityId' => $entityId, 'locale' => $locale]) | ||
->willReturn($localedQuery->reveal()); | ||
|
||
$localedQuery->getSingleResult()->willReturn($route->reveal()); | ||
} | ||
|
||
$context->accept($expected)->willReturn($expected)->shouldBeCalled(); | ||
$visitor->addData('urls', $expected)->shouldBeCalled(); | ||
|
||
$this->urlsSubscriber->addUrlsOnPostSerialize($event->reveal()); | ||
} | ||
|
||
/** | ||
* @return \Prophecy\Prophecy\ObjectProphecy | ||
*/ | ||
private function mockQuery() | ||
{ | ||
$queryBuilder = $this->prophesize(QueryBuilder::class); | ||
$queryBuilder->andWhere('entity.entityClass = :entityClass') | ||
->shouldBeCalled() | ||
->willReturn($queryBuilder->reveal()); | ||
$queryBuilder->andWhere('entity.entityId = :entityId') | ||
->shouldBeCalled() | ||
->willReturn($queryBuilder->reveal()); | ||
$queryBuilder->andWhere('entity.locale = :locale') | ||
->shouldBeCalled() | ||
->willReturn($queryBuilder->reveal()); | ||
$queryBuilder->andWhere('entity.history = false') | ||
->shouldBeCalled() | ||
->willReturn($queryBuilder->reveal()); | ||
|
||
$query = $this->prophesize(AbstractQuery::class); | ||
|
||
$this->routeRepository->createQueryBuilder('entity')->willReturn($queryBuilder->reveal()); | ||
$queryBuilder->getQuery()->willReturn($query->reveal()); | ||
|
||
return $query; | ||
} | ||
} |