diff --git a/AutoRoute/PathProvider/ContentObjectProvider.php b/AutoRoute/PathProvider/ContentObjectProvider.php index eb14544..1339195 100644 --- a/AutoRoute/PathProvider/ContentObjectProvider.php +++ b/AutoRoute/PathProvider/ContentObjectProvider.php @@ -18,6 +18,8 @@ use Doctrine\ODM\PHPCR\DocumentManager; use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route; use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Util\ClassUtils; +use Symfony\Cmf\Bundle\RoutingAutoBundle\Model\AutoRoute; /** * Provides path elements by determining them from @@ -65,15 +67,28 @@ public function providePath(RouteStack $routeStack) $object = $contentObject->$method(); - $routeFilter = function ($referrer) use ($object) { - if ($referrer instanceof Route && $referrer->getContent() === $object) { - return true; + if (!$object) { + throw new \RuntimeException(sprintf( + 'The %s:%s method has returned an empty value "%s"', + get_class($contentObject), + $method, + var_export($object, true) + )); + } + + $routeFilter = function ($referrer) use ($object, $context) { + if ($referrer instanceof AutoRoute && $referrer->getContent() === $object) { + + // filter the referrering routes by locale + if ($referrer->getLocale() == $context->getLocale()) { + return true; + } } return false; }; - $referringRoutes = new ArrayCollection; + $referringRoutes = new ArrayCollection(); if ($this->documentIsPersisted($object)) { // check to see existing routes @@ -91,7 +106,7 @@ public function providePath(RouteStack $routeStack) if (count($routes) > 1) { throw new \RuntimeException( - 'Multiple referring routes (i.e. translations) not supported yet.' + 'Found more than one referring auto route, this should not happen.' ); } diff --git a/AutoRoute/RouteMaker/AutoRouteMaker.php b/AutoRoute/RouteMaker/AutoRouteMaker.php index 3dbaa04..b20aedc 100644 --- a/AutoRoute/RouteMaker/AutoRouteMaker.php +++ b/AutoRoute/RouteMaker/AutoRouteMaker.php @@ -44,6 +44,7 @@ public function make(RouteStack $routeStack) } $autoRoute->setName($routeStack->getPath()); + $autoRoute->setLocale($context->getLocale()); $autoRoute->setParent($context->getTopRoute()); $routeStack->addRoute($autoRoute); @@ -75,25 +76,6 @@ protected function getAutoRouteForDocument($document) $metadata = $dm->getClassMetadata(get_class($document)); - $locale = null; // $uow->getLocale($document, $locale); - - // If the document is translated, filter locales - if (null !== $locale) { - throw new \Exception( - 'Translations not yet supported for Auto Routes - '. - 'Should be easy.' - ); - - // array_filter($referrers, function ($referrer) use ($dm, $uow, $locale) { - // $metadata = $dm->getClassMetadata($refferer); - // if ($locale == $uow->getLocaleFor($referrer, $referrer)) { - // return true; - // } - - // return false; - // }); - } - if ($referrers->count() > 1) { throw new \RuntimeException(sprintf( 'More than one auto route for document "%s"', diff --git a/Model/AutoRoute.php b/Model/AutoRoute.php index bd4eda8..b63296b 100644 --- a/Model/AutoRoute.php +++ b/Model/AutoRoute.php @@ -21,4 +21,16 @@ */ class AutoRoute extends Route { + protected $locale; + + public function getLocale() + { + return $this->locale; + } + + public function setLocale($locale) + { + $this->locale = $locale; + } + } diff --git a/Resources/config/doctrine-model/AutoRoute.phpcr.xml b/Resources/config/doctrine-model/AutoRoute.phpcr.xml index 7c4c600..03d9002 100644 --- a/Resources/config/doctrine-model/AutoRoute.phpcr.xml +++ b/Resources/config/doctrine-model/AutoRoute.phpcr.xml @@ -1,6 +1,9 @@ - + + + + diff --git a/Tests/Functional/EventListener/AutoRouteListenerMultilangTest.php b/Tests/Functional/EventListener/AutoRouteListenerMultilangTest.php new file mode 100644 index 0000000..5fa3b40 --- /dev/null +++ b/Tests/Functional/EventListener/AutoRouteListenerMultilangTest.php @@ -0,0 +1,113 @@ + 'Hello everybody!', + 'fr' => 'Bonjour le monde!', + 'de' => 'Gutentag', + 'es' => 'Hola todo el mundo', + ), + array( + 'test/auto-route/articles/en/hello-everybody', + 'test/auto-route/articles/fr/bonjour-le-monde', + 'test/auto-route/articles/de/gutentag', + 'test/auto-route/articles/es/hola-todo-el-mundo', + ), + ), + ); + } + + /** + * @dataProvider provideMultilangArticle + */ + public function testMultilangCategory($data, $expectedPaths) + { + $category = new Category(); + $category->path = '/test/category1'; + $this->getDm()->persist($category); + + foreach (array( + 'de' => 'Meine neue Kategorie', + 'fr' => 'Ma nouvelle catégorie', + 'en' => 'My new category', + ) as $locale => $title) { + $category->title = $title; + $this->getDm()->bindTranslation($category, $locale); + } + } + + public function provideMultilangArticle() + { + return array( + array( + array( + 'en' => 'Hello everybody!', + 'fr' => 'Bonjour le monde!', + 'de' => 'Gutentag', + 'es' => 'Hola todo el mundo', + ), + array( + 'test/auto-route/articles/en/category/hello-everybody', + 'test/auto-route/articles/fr/category/bonjour-le-monde', + 'test/auto-route/articles/de/category/gutentag', + 'test/auto-route/articles/es/category/hola-todo-el-mundo', + ), + ), + ); + } + + /** + * @dataProvider provideMultilangArticle + */ + public function testMultilangArticle($data, $expectedPaths) + { + $category = new Category(); + $category->path = '/test/category1'; + $category->title = 'category'; + $this->getDm()->persist($category); + foreach (array_keys($data) as $lang) { + $this->getDm()->bindTranslation($category, $lang); + } + + $article = new Article; + $article->path = '/test/article-1'; + $article->categories[] = $category; + + $this->getDm()->persist($article); + + foreach ($data as $lang => $title) { + $article->title = $title; + $this->getDm()->bindTranslation($article, $lang); + } + + $this->getDm()->flush(); + $this->getDm()->clear(); + + $articleTitles = array_values($data); + foreach ($expectedPaths as $i => $expectedPath) { + $route = $this->getDm()->find(null, $expectedPath); + + $this->assertNotNull($route, 'Found route with path ' . $expectedPath); + $this->assertInstanceOf('Symfony\Cmf\Bundle\RoutingAutoBundle\Model\AutoRoute', $route); + + $content = $route->getContent(); + + $this->assertNotNull($content); + $this->assertInstanceOf('Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Article', $content); + + // We havn't loaded the translation for the document, so it is always in the default language + $this->assertEquals('Hello everybody!', $content->title); + } + } +} diff --git a/Tests/Functional/EventListener/AutoRouteListenerTest.php b/Tests/Functional/EventListener/AutoRouteListenerTest.php index 6478c57..d7f1455 100644 --- a/Tests/Functional/EventListener/AutoRouteListenerTest.php +++ b/Tests/Functional/EventListener/AutoRouteListenerTest.php @@ -14,7 +14,6 @@ use Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Functional\BaseTestCase; use Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Blog; use Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Post; -use Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Article; use Symfony\Cmf\Bundle\RoutingAutoBundle\Model\AutoRoute; use Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\ConcreteContent; @@ -182,60 +181,6 @@ public function testUpdatePost() ); } - public function provideMultilangArticle() - { - return array( - array( - array( - 'en' => 'Hello everybody!', - 'fr' => 'Bonjour le monde!', - 'de' => 'Gutentag', - 'es' => 'Hola todo el mundo', - ), - array( - 'test/auto-route/articles/en/hello-everybody', - 'test/auto-route/articles/fr/bonjour-le-monde', - 'test/auto-route/articles/de/gutentag', - 'test/auto-route/articles/es/hola-todo-el-mundo', - ), - ), - ); - } - - /** - * @dataProvider provideMultilangArticle - */ - public function testMultilangArticle($data, $expectedPaths) - { - $article = new Article; - $article->path = '/test/article-1'; - $this->getDm()->persist($article); - - foreach ($data as $lang => $title) { - $article->title = $title; - $this->getDm()->bindTranslation($article, $lang); - } - - $this->getDm()->flush(); - $this->getDm()->clear(); - - $articleTitles = array_values($data); - foreach ($expectedPaths as $i => $expectedPath) { - $route = $this->getDm()->find(null, $expectedPath); - - $this->assertNotNull($route); - $this->assertInstanceOf('Symfony\Cmf\Bundle\RoutingAutoBundle\Model\AutoRoute', $route); - - $content = $route->getContent(); - - $this->assertNotNull($content); - $this->assertInstanceOf('Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Article', $content); - - // We havn't loaded the translation for the document, so it is always in the default language - $this->assertEquals('Hello everybody!', $content->title); - } - } - /** * Ensure that we can map parent classes: #56 */ diff --git a/Tests/Resources/Document/Article.php b/Tests/Resources/Document/Article.php index da5abff..886fa50 100644 --- a/Tests/Resources/Document/Article.php +++ b/Tests/Resources/Document/Article.php @@ -12,6 +12,8 @@ namespace Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document; use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCR; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\ODM\PHPCR\PersistentCollection; /** * @PHPCR\Document(translator="child", referenceable=true) @@ -36,11 +38,24 @@ class Article */ public $title; + /** + * @PHPCR\Referrers( + * referringDocument="Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Category", + * referencedBy="articles" + * ) + */ + public $categories = array(); + /** * @PHPCR\Locale() */ public $locale; + public function getCategory() + { + return current($this->categories); + } + public function getTitle() { return $this->title; diff --git a/Tests/Resources/Document/Category.php b/Tests/Resources/Document/Category.php new file mode 100644 index 0000000..4e8faef --- /dev/null +++ b/Tests/Resources/Document/Category.php @@ -0,0 +1,54 @@ +title; + } +} diff --git a/Tests/Resources/app/config/routingautoroute.yml b/Tests/Resources/app/config/routingautoroute.yml index b7324b2..6d4f297 100644 --- a/Tests/Resources/app/config/routingautoroute.yml +++ b/Tests/Resources/app/config/routingautoroute.yml @@ -64,8 +64,7 @@ cmf_routing_auto: exists_action: [ auto_increment, { pattern: -%d } ] not_exists_action: [ create ] - # Article document for multilang tests - Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Article: + Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Category: content_path: path_units: @@ -82,6 +81,20 @@ cmf_routing_auto: exists_action: [ auto_increment, { pattern: -%d } ] not_exists_action: create + # Article document for multilang tests + Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\Article: + + content_path: + path_units: + category: + provider: [ content_object, { method: getCategory } ] + exists_action: use + not_exists_action: throw_exception + content_name: + provider: [ content_method, { method: getTitle } ] + exists_action: [ auto_increment, { pattern: -%d } ] + not_exists_action: create + # AbstractContent for ensuring that parent class mapping works Symfony\Cmf\Bundle\RoutingAutoBundle\Tests\Resources\Document\AbstractContent: diff --git a/Tests/Unit/AutoRoute/PathProvider/ContentObjectProviderTest.php b/Tests/Unit/AutoRoute/PathProvider/ContentObjectProviderTest.php index a65af89..77a45e5 100644 --- a/Tests/Unit/AutoRoute/PathProvider/ContentObjectProviderTest.php +++ b/Tests/Unit/AutoRoute/PathProvider/ContentObjectProviderTest.php @@ -44,7 +44,7 @@ public function setUp() ->getMock(); $this->contentObject = new \stdClass; - $this->route1 = $this->getMock('Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route'); + $this->route1 = $this->getMock('Symfony\Cmf\Bundle\RoutingAutoBundle\Model\AutoRoute'); $this->object = new ContentObjectTestClass($this->contentObject); $this->provider = new ContentObjectProvider($this->dm);