Skip to content
This repository was archived by the owner on Sep 16, 2021. It is now read-only.

Commit e325fed

Browse files
committed
Merge pull request #33 from symfony-cmf/multilang_refactoring
[WIP] Adding support for multilang
2 parents b9f770c + d07b40b commit e325fed

File tree

16 files changed

+386
-43
lines changed

16 files changed

+386
-43
lines changed

AutoRoute/AutoRouteManager.php

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\AutoRouteStack;
77
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack\Builder;
88
use Doctrine\Common\Util\ClassUtils;
9+
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver\DriverInterface;
910

1011
/**
1112
* This class is concerned with the automatic creation of route objects.
@@ -15,11 +16,13 @@
1516
class AutoRouteManager
1617
{
1718
protected $factory;
19+
protected $driver;
1820

19-
public function __construct(Factory $factory, Builder $builder)
21+
public function __construct(DriverInterface $driver, Factory $factory, Builder $builder)
2022
{
2123
$this->factory = $factory;
2224
$this->builder = $builder;
25+
$this->driver = $driver;
2326
}
2427

2528
/**
@@ -30,25 +33,38 @@ public function __construct(Factory $factory, Builder $builder)
3033
*
3134
* @param object Mapped document for which to generate the AutoRoute
3235
*
33-
* @return BuilderContext
36+
* @return BuilderContext[]
3437
*/
3538
public function updateAutoRouteForDocument($document)
3639
{
3740
$classFqn = ClassUtils::getClass($document);
41+
$locales = $this->driver->getLocales($document) ? : array(null);
3842

39-
$context = new BuilderContext;
40-
$context->setContent($document);
43+
$contexts = array();
4144

42-
// build chain
43-
$builderUnitChain = $this->factory->getRouteStackBuilderUnitChain($classFqn);
44-
$builderUnitChain->executeChain($context);
45+
foreach ($locales as $locale) {
46+
if (null !== $locale) {
47+
$document = $this->driver->translateObject($document, $locale);
48+
}
4549

46-
// persist the auto route
47-
$autoRouteStack = new AutoRouteStack($context);
48-
$builderUnit = $this->factory->getContentNameBuilderUnit($classFqn);
49-
$this->builder->build($autoRouteStack, $builderUnit);
50+
$context = new BuilderContext;
5051

51-
return $context;
52+
$context->setContent($document);
53+
$context->setLocale($locale);
54+
55+
// build path elements
56+
$builderUnitChain = $this->factory->getRouteStackBuilderUnitChain($classFqn);
57+
$builderUnitChain->executeChain($context);
58+
59+
// persist the content name element (the autoroute)
60+
$autoRouteStack = new AutoRouteStack($context);
61+
$builderUnit = $this->factory->getContentNameBuilderUnit($classFqn);
62+
$this->builder->build($autoRouteStack, $builderUnit);
63+
64+
$contexts[] = $context;
65+
}
66+
67+
return $contexts;
5268
}
5369

5470
/**

AutoRoute/BuilderContext.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ class BuilderContext
1616
{
1717
/** @var RouteStack[] */
1818
protected $routeStacks = array();
19+
1920
/** @var RouteStack */
2021
protected $stagedRouteStack;
22+
2123
protected $content;
2224

25+
protected $locale;
26+
2327
/**
2428
* Return an ordered array of all routes from
2529
* all stacks.
@@ -134,4 +138,23 @@ public function getContent()
134138
{
135139
return $this->content;
136140
}
141+
142+
/**
143+
* Return the locale for this context
144+
*
145+
* @return string
146+
*/
147+
public function getLocale()
148+
{
149+
return $this->locale;
150+
}
151+
/**
152+
* Set the locale for this context
153+
*
154+
* @param string
155+
*/
156+
public function setLocale($locale)
157+
{
158+
$this->locale = $locale;
159+
}
137160
}

AutoRoute/Driver/DriverInterface.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver;
4+
5+
/**
6+
* Drivers will (eventually) abstract all database operations
7+
* with the aim of enabling other providers such as ORM.
8+
*
9+
* @author Daniel Leech <[email protected]>
10+
*/
11+
interface DriverInterface
12+
{
13+
/**
14+
* Return locales for object
15+
*
16+
* @return array
17+
*/
18+
public function getLocales($object);
19+
20+
public function translateObject($object, $locale);
21+
}

AutoRoute/Driver/PhpcrOdmDriver.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver;
4+
5+
use Doctrine\ODM\PHPCR\DocumentManager;
6+
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver\DriverInterface;
7+
8+
/**
9+
* Abstraction driver for PHPCR-ODM
10+
*
11+
* This class will eventually encapsulate all of the PHPCR-ODM
12+
* specific logic to enable support for multiple backends.
13+
*/
14+
class PhpcrOdmDriver implements DriverInterface
15+
{
16+
protected $dm;
17+
18+
public function __construct(DocumentManager $dm)
19+
{
20+
$this->dm = $dm;
21+
}
22+
23+
public function getLocales($document)
24+
{
25+
if ($this->dm->isDocumentTranslatable($document)) {
26+
return $this->dm->getLocalesFor($document);
27+
}
28+
29+
return array();
30+
}
31+
32+
public function translateObject($document, $locale)
33+
{
34+
$meta = $this->dm->getMetadataFactory()->getMetadataFor(get_class($document));
35+
$this->dm->findTranslation(get_class($document), $meta->getIdentifierValue($document), $locale);
36+
return $document;
37+
}
38+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider;
4+
5+
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProviderInterface;
6+
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Exception\MissingOptionException;
7+
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Exception\CouldNotFindRouteException;
8+
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack;
9+
use Symfony\Cmf\Bundle\CoreBundle\Slugifier\SlugifierInterface;
10+
use Doctrine\ODM\PHPCR\DocumentManager;
11+
use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route;
12+
use Doctrine\Common\Collections\ArrayCollection;
13+
14+
/**
15+
* Provides a ISO-639-1 locale path element based
16+
* on the locale in the context.
17+
*
18+
* @author Daniel Leech <[email protected]>
19+
*/
20+
class LocaleProvider implements PathProviderInterface
21+
{
22+
public function init(array $options)
23+
{
24+
}
25+
26+
public function providePath(RouteStack $routeStack)
27+
{
28+
$context = $routeStack->getContext();
29+
$locale = $context->getLocale();
30+
31+
if (!$locale) {
32+
throw new \RuntimeException(
33+
'LocaleProvider requires that a locale is set on the BuilderContext'
34+
);
35+
}
36+
37+
$routeStack->addPathElements(array($locale));
38+
}
39+
}

Command/RefreshCommand.php

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,25 @@ public function execute(InputInterface $input, OutputInterface $output)
7878
foreach ($result as $autoRouteableDocument) {
7979
$id = $uow->getDocumentId($autoRouteableDocument);
8080
$output->writeln(' <info>Refreshing: </info>'.$id);
81-
$context = $arm->updateAutoRouteForDocument($autoRouteableDocument);
82-
83-
foreach ($context->getRoutes() as $route) {
84-
$dm->persist($route);
85-
$routeId = $uow->getDocumentId($route);
86-
87-
if ($verbose) {
88-
$output->writeln(sprintf(
89-
'<comment> - %sPersisting: </comment> %s <comment>%s</comment>',
90-
$dryRun ? '(dry run) ' : '',
91-
$routeId,
92-
'[...]'.substr(get_class($route), -10)
93-
));
94-
}
95-
96-
if (true !== $dryRun) {
97-
$dm->flush();
81+
$contexts = $arm->updateAutoRouteForDocument($autoRouteableDocument);
82+
83+
foreach ($contexts as $context) {
84+
foreach ($context->getRoutes() as $route) {
85+
$dm->persist($route);
86+
$routeId = $uow->getDocumentId($route);
87+
88+
if ($verbose) {
89+
$output->writeln(sprintf(
90+
'<comment> - %sPersisting: </comment> %s <comment>%s</comment>',
91+
$dryRun ? '(dry run) ' : '',
92+
$routeId,
93+
'[...]'.substr(get_class($route), -10)
94+
));
95+
}
96+
97+
if (true !== $dryRun) {
98+
$dm->flush();
99+
}
98100
}
99101
}
100102
}

EventListener/AutoRouteListener.php

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,35 @@ public function onFlush(ManagerEventArgs $args)
4141

4242
foreach ($updates as $document) {
4343
if ($this->getArm()->isAutoRouteable($document)) {
44-
$context = $this->getArm()->updateAutoRouteForDocument($document);
45-
foreach ($context->getRoutes() as $route) {
46-
$dm->persist($route);
47-
48-
// this was originally computeSingleDocumentChangeset
49-
// however this caused problems in a real usecase
50-
// (functional tests were fine)
51-
//
52-
// this is probably not very efficient, but it works
53-
$uow->computeChangeSets();
44+
$contexts = $this->getArm()->updateAutoRouteForDocument($document);
45+
46+
$persistedRoutes = array();
47+
48+
foreach ($contexts as $context) {
49+
foreach ($context->getRoutes() as $route) {
50+
51+
if ($route instanceof AutoRoute) {
52+
$routeParent = $route->getParent();
53+
$id = spl_object_hash($routeParent).$route->getName();
54+
} else {
55+
$metadata = $dm->getClassMetadata(get_class($route));
56+
$id = $metadata->getIdentifierValue($route);
57+
}
58+
59+
if (isset($persistedRoutes[$id])) {
60+
continue;
61+
}
62+
63+
$dm->persist($route);
64+
$persistedRoutes[$id] = true;
65+
66+
// this was originally computeSingleDocumentChangeset
67+
// however this caused problems in a real usecase
68+
// (functional tests were fine)
69+
//
70+
// this is probably not very efficient, but it works
71+
$uow->computeChangeSets();
72+
}
5473
}
5574
}
5675
}

Resources/config/auto_route.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<parameter key="cmf_routing_auto.factory_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Factory</parameter>
1111
<parameter key="cmf_routing_auto.route_stack_builder_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack\Builder</parameter>
1212
<parameter key="cmf_routing_auto.route_patcher_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RoutePatcher\GenericPatcher</parameter>
13+
<parameter key="cmf_routing_auto.driver.phpcr_odm_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver\PhpcrOdmDriver</parameter>
1314

1415
</parameters>
1516

@@ -25,6 +26,7 @@
2526
id="cmf_routing_auto.auto_route_manager"
2627
class="Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\AutoRouteManager"
2728
>
29+
<argument type="service" id="cmf_routing_auto.driver.phpcr_odm"/>
2830
<argument type="service" id="cmf_routing_auto.factory"/>
2931
<argument type="service" id="cmf_routing_auto.route_stack_builder"/>
3032
</service>
@@ -48,5 +50,8 @@
4850
<argument type="service" id="doctrine_phpcr.odm.default_document_manager"/>
4951
</service>
5052

53+
<service id="cmf_routing_auto.driver.phpcr_odm" class="%cmf_routing_auto.driver.phpcr_odm_class%">
54+
<argument type="service" id="doctrine_phpcr.odm.default_document_manager"/>
55+
</service>
5156
</services>
5257
</container>

Resources/config/path_provider.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<parameter key="cmf_routing_auto.provider.content_method_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider\ContentMethodProvider</parameter>
1010
<parameter key="cmf_routing_auto.provider.content_object_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider\ContentObjectProvider</parameter>
1111
<parameter key="cmf_routing_auto.provider.content_datetime_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider\ContentDateTimeProvider</parameter>
12+
<parameter key="cmf_routing_auto.provider.locale_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider\LocaleProvider</parameter>
1213

1314
</parameters>
1415

@@ -48,5 +49,13 @@
4849
<argument type="service" id="doctrine_phpcr.odm.default_document_manager"/>
4950
<tag name="cmf_routing_auto.provider" alias="content_object"/>
5051
</service>
52+
53+
<service
54+
id="cmf_routing_auto.path_provider.locale"
55+
class="%cmf_routing_auto.provider.locale_class%"
56+
scope="prototype"
57+
>
58+
<tag name="cmf_routing_auto.provider" alias="locale"/>
59+
</service>
5160
</services>
5261
</container>

0 commit comments

Comments
 (0)