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

Commit

Permalink
Merge pull request #33 from symfony-cmf/multilang_refactoring
Browse files Browse the repository at this point in the history
[WIP] Adding support for multilang
  • Loading branch information
dantleech committed Dec 27, 2013
2 parents b9f770c + d07b40b commit e325fed
Show file tree
Hide file tree
Showing 16 changed files with 386 additions and 43 deletions.
40 changes: 28 additions & 12 deletions AutoRoute/AutoRouteManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\AutoRouteStack;
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack\Builder;
use Doctrine\Common\Util\ClassUtils;
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver\DriverInterface;

/**
* This class is concerned with the automatic creation of route objects.
Expand All @@ -15,11 +16,13 @@
class AutoRouteManager
{
protected $factory;
protected $driver;

public function __construct(Factory $factory, Builder $builder)
public function __construct(DriverInterface $driver, Factory $factory, Builder $builder)
{
$this->factory = $factory;
$this->builder = $builder;
$this->driver = $driver;
}

/**
Expand All @@ -30,25 +33,38 @@ public function __construct(Factory $factory, Builder $builder)
*
* @param object Mapped document for which to generate the AutoRoute
*
* @return BuilderContext
* @return BuilderContext[]
*/
public function updateAutoRouteForDocument($document)
{
$classFqn = ClassUtils::getClass($document);
$locales = $this->driver->getLocales($document) ? : array(null);

$context = new BuilderContext;
$context->setContent($document);
$contexts = array();

// build chain
$builderUnitChain = $this->factory->getRouteStackBuilderUnitChain($classFqn);
$builderUnitChain->executeChain($context);
foreach ($locales as $locale) {
if (null !== $locale) {
$document = $this->driver->translateObject($document, $locale);
}

// persist the auto route
$autoRouteStack = new AutoRouteStack($context);
$builderUnit = $this->factory->getContentNameBuilderUnit($classFqn);
$this->builder->build($autoRouteStack, $builderUnit);
$context = new BuilderContext;

return $context;
$context->setContent($document);
$context->setLocale($locale);

// build path elements
$builderUnitChain = $this->factory->getRouteStackBuilderUnitChain($classFqn);
$builderUnitChain->executeChain($context);

// persist the content name element (the autoroute)
$autoRouteStack = new AutoRouteStack($context);
$builderUnit = $this->factory->getContentNameBuilderUnit($classFqn);
$this->builder->build($autoRouteStack, $builderUnit);

$contexts[] = $context;
}

return $contexts;
}

/**
Expand Down
23 changes: 23 additions & 0 deletions AutoRoute/BuilderContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,14 @@ class BuilderContext
{
/** @var RouteStack[] */
protected $routeStacks = array();

/** @var RouteStack */
protected $stagedRouteStack;

protected $content;

protected $locale;

/**
* Return an ordered array of all routes from
* all stacks.
Expand Down Expand Up @@ -134,4 +138,23 @@ public function getContent()
{
return $this->content;
}

/**
* Return the locale for this context
*
* @return string
*/
public function getLocale()
{
return $this->locale;
}
/**
* Set the locale for this context
*
* @param string
*/
public function setLocale($locale)
{
$this->locale = $locale;
}
}
21 changes: 21 additions & 0 deletions AutoRoute/Driver/DriverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver;

/**
* Drivers will (eventually) abstract all database operations
* with the aim of enabling other providers such as ORM.
*
* @author Daniel Leech <[email protected]>
*/
interface DriverInterface
{
/**
* Return locales for object
*
* @return array
*/
public function getLocales($object);

public function translateObject($object, $locale);
}
38 changes: 38 additions & 0 deletions AutoRoute/Driver/PhpcrOdmDriver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

namespace Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver;

use Doctrine\ODM\PHPCR\DocumentManager;
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver\DriverInterface;

/**
* Abstraction driver for PHPCR-ODM
*
* This class will eventually encapsulate all of the PHPCR-ODM
* specific logic to enable support for multiple backends.
*/
class PhpcrOdmDriver implements DriverInterface
{
protected $dm;

public function __construct(DocumentManager $dm)
{
$this->dm = $dm;
}

public function getLocales($document)
{
if ($this->dm->isDocumentTranslatable($document)) {
return $this->dm->getLocalesFor($document);
}

return array();
}

public function translateObject($document, $locale)
{
$meta = $this->dm->getMetadataFactory()->getMetadataFor(get_class($document));
$this->dm->findTranslation(get_class($document), $meta->getIdentifierValue($document), $locale);
return $document;
}
}
39 changes: 39 additions & 0 deletions AutoRoute/PathProvider/LocaleProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider;

use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProviderInterface;
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Exception\MissingOptionException;
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Exception\CouldNotFindRouteException;
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack;
use Symfony\Cmf\Bundle\CoreBundle\Slugifier\SlugifierInterface;
use Doctrine\ODM\PHPCR\DocumentManager;
use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route;
use Doctrine\Common\Collections\ArrayCollection;

/**
* Provides a ISO-639-1 locale path element based
* on the locale in the context.
*
* @author Daniel Leech <[email protected]>
*/
class LocaleProvider implements PathProviderInterface
{
public function init(array $options)
{
}

public function providePath(RouteStack $routeStack)
{
$context = $routeStack->getContext();
$locale = $context->getLocale();

if (!$locale) {
throw new \RuntimeException(
'LocaleProvider requires that a locale is set on the BuilderContext'
);
}

$routeStack->addPathElements(array($locale));
}
}
36 changes: 19 additions & 17 deletions Command/RefreshCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,25 @@ public function execute(InputInterface $input, OutputInterface $output)
foreach ($result as $autoRouteableDocument) {
$id = $uow->getDocumentId($autoRouteableDocument);
$output->writeln(' <info>Refreshing: </info>'.$id);
$context = $arm->updateAutoRouteForDocument($autoRouteableDocument);

foreach ($context->getRoutes() as $route) {
$dm->persist($route);
$routeId = $uow->getDocumentId($route);

if ($verbose) {
$output->writeln(sprintf(
'<comment> - %sPersisting: </comment> %s <comment>%s</comment>',
$dryRun ? '(dry run) ' : '',
$routeId,
'[...]'.substr(get_class($route), -10)
));
}

if (true !== $dryRun) {
$dm->flush();
$contexts = $arm->updateAutoRouteForDocument($autoRouteableDocument);

foreach ($contexts as $context) {
foreach ($context->getRoutes() as $route) {
$dm->persist($route);
$routeId = $uow->getDocumentId($route);

if ($verbose) {
$output->writeln(sprintf(
'<comment> - %sPersisting: </comment> %s <comment>%s</comment>',
$dryRun ? '(dry run) ' : '',
$routeId,
'[...]'.substr(get_class($route), -10)
));
}

if (true !== $dryRun) {
$dm->flush();
}
}
}
}
Expand Down
39 changes: 29 additions & 10 deletions EventListener/AutoRouteListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,35 @@ public function onFlush(ManagerEventArgs $args)

foreach ($updates as $document) {
if ($this->getArm()->isAutoRouteable($document)) {
$context = $this->getArm()->updateAutoRouteForDocument($document);
foreach ($context->getRoutes() as $route) {
$dm->persist($route);

// this was originally computeSingleDocumentChangeset
// however this caused problems in a real usecase
// (functional tests were fine)
//
// this is probably not very efficient, but it works
$uow->computeChangeSets();
$contexts = $this->getArm()->updateAutoRouteForDocument($document);

$persistedRoutes = array();

foreach ($contexts as $context) {
foreach ($context->getRoutes() as $route) {

if ($route instanceof AutoRoute) {
$routeParent = $route->getParent();
$id = spl_object_hash($routeParent).$route->getName();
} else {
$metadata = $dm->getClassMetadata(get_class($route));
$id = $metadata->getIdentifierValue($route);
}

if (isset($persistedRoutes[$id])) {
continue;
}

$dm->persist($route);
$persistedRoutes[$id] = true;

// this was originally computeSingleDocumentChangeset
// however this caused problems in a real usecase
// (functional tests were fine)
//
// this is probably not very efficient, but it works
$uow->computeChangeSets();
}
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions Resources/config/auto_route.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<parameter key="cmf_routing_auto.factory_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Factory</parameter>
<parameter key="cmf_routing_auto.route_stack_builder_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RouteStack\Builder</parameter>
<parameter key="cmf_routing_auto.route_patcher_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\RoutePatcher\GenericPatcher</parameter>
<parameter key="cmf_routing_auto.driver.phpcr_odm_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Driver\PhpcrOdmDriver</parameter>

</parameters>

Expand All @@ -25,6 +26,7 @@
id="cmf_routing_auto.auto_route_manager"
class="Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\AutoRouteManager"
>
<argument type="service" id="cmf_routing_auto.driver.phpcr_odm"/>
<argument type="service" id="cmf_routing_auto.factory"/>
<argument type="service" id="cmf_routing_auto.route_stack_builder"/>
</service>
Expand All @@ -48,5 +50,8 @@
<argument type="service" id="doctrine_phpcr.odm.default_document_manager"/>
</service>

<service id="cmf_routing_auto.driver.phpcr_odm" class="%cmf_routing_auto.driver.phpcr_odm_class%">
<argument type="service" id="doctrine_phpcr.odm.default_document_manager"/>
</service>
</services>
</container>
9 changes: 9 additions & 0 deletions Resources/config/path_provider.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<parameter key="cmf_routing_auto.provider.content_method_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider\ContentMethodProvider</parameter>
<parameter key="cmf_routing_auto.provider.content_object_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider\ContentObjectProvider</parameter>
<parameter key="cmf_routing_auto.provider.content_datetime_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider\ContentDateTimeProvider</parameter>
<parameter key="cmf_routing_auto.provider.locale_class">Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\PathProvider\LocaleProvider</parameter>

</parameters>

Expand Down Expand Up @@ -48,5 +49,13 @@
<argument type="service" id="doctrine_phpcr.odm.default_document_manager"/>
<tag name="cmf_routing_auto.provider" alias="content_object"/>
</service>

<service
id="cmf_routing_auto.path_provider.locale"
class="%cmf_routing_auto.provider.locale_class%"
scope="prototype"
>
<tag name="cmf_routing_auto.provider" alias="locale"/>
</service>
</services>
</container>
Loading

0 comments on commit e325fed

Please sign in to comment.