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

Commit 0f0ca05

Browse files
committed
More tests pass..
1 parent 63f7d65 commit 0f0ca05

File tree

9 files changed

+195
-18
lines changed

9 files changed

+195
-18
lines changed

AutoRoute/Adapter/PhpcrOdmAdapter.php

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
1818
use PHPCR\Util\NodeHelper;
1919
use Symfony\Cmf\Bundle\RoutingAutoBundle\Model\AutoRoute;
20+
use PHPCR\InvalidItemStateException;
2021

2122
/**
2223
* Abstraction adapter for PHPCR-ODM
@@ -52,30 +53,47 @@ public function translateObject($contentDocument, $locale)
5253
return $contentDocument;
5354
}
5455

55-
public function createRoute($url, $contentDocument)
56+
public function removeDefunctRoute($route, $canonicalRoute)
5657
{
57-
$path = $this->getPathFromUrl($url);
58-
$pathElements = explode('/', $path);
59-
$headName = array_pop($pathElements);
60-
$parentPath = implode('/', $pathElements);
61-
62-
// bypass the ODM ... but changes will still only be
63-
// persisted when the PHPCR session is saved in the ODMs flush().
64-
NodeHelper::createPath($this->dm->getPhpcrSession(), $parentPath);
58+
$session = $this->dm->getPhpcrSession();
59+
try {
60+
$node = $this->dm->getNodeForDocument($route);
61+
$canonicalNode = $this->dm->getNodeForDocument($canonicalRoute);
62+
$nodeChildren = $node->getNodes();
63+
foreach ($nodeChildren as $nodeChild) {
64+
$session->move($nodeChild->getPath(), $canonicalNode->getPath() . '/' . $nodeChild->getName());
65+
}
66+
$session->removeItem($node->getPath());
67+
} catch (InvalidItemStateException $e) {
68+
// nothing ..
69+
}
6570

66-
$autoRouteParent = $this->dm->find(null, $parentPath);
71+
$session->save();
72+
}
6773

68-
if (!$autoRouteParent) {
69-
throw new \RuntimeException(sprintf(
70-
'Hmph, could not find parent path "%s", this really should not have happened.',
71-
$parentPath
72-
));
74+
public function createRoute($url, $contentDocument)
75+
{
76+
$path = $this->baseRoutePath;
77+
$parentDocument = $this->dm->find(null, $path);
78+
79+
$segments = preg_split('#/#', $url, null, PREG_SPLIT_NO_EMPTY);
80+
$headName = array_pop($segments);
81+
foreach ($segments as $segment) {
82+
$path .= '/' . $segment;
83+
$document = $this->dm->find(null, $path);
84+
85+
if (null === $document) {
86+
$document = new Generic();
87+
$document->setParent($parentDocument);
88+
$document->setNodeName($segment);
89+
$this->dm->persist($document);
90+
}
7391
}
7492

7593
$headRoute = new AutoRoute();
7694
$headRoute->setContent($contentDocument);
7795
$headRoute->setName($headName);
78-
$headRoute->setParent($autoRouteParent);
96+
$headRoute->setParent($document);
7997

8098
return $headRoute;
8199
}
@@ -113,3 +131,4 @@ private function getPathFromUrl($url)
113131
return $this->baseRoutePath . $url;
114132
}
115133
}
134+

AutoRoute/AutoRouteManager.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ class AutoRouteManager
2626
protected $urlGenerator;
2727
protected $defunctRouteHandler;
2828

29+
private $defunctRouteStack = array();
30+
2931
/**
3032
* @param AdapterInterface $adapter Database adapter
3133
* @param UrlGeneratorInterface $urlGenerator Routing auto URL generator
@@ -66,11 +68,20 @@ public function buildOperationStack(OperationStack $operationStack, $document)
6668
$operationStack->pushNewRoute($newRoute);
6769
}
6870

69-
$this->defunctRouteHandler->handleDefunctRoutes($document, $operationStack);
71+
$this->defunctRouteStack[] = array($document, $operationStack);
7072

73+
// do we really need the operation stack now? We can just persist...
7174
return $operationStack;
7275
}
7376

77+
public function handleDefunctRoutes()
78+
{
79+
while ($defunctRoute = array_pop($this->defunctRouteStack)) {
80+
list ($document, $operationStack) = $defunctRoute;
81+
$this->defunctRouteHandler->handleDefunctRoutes($document, $operationStack);
82+
}
83+
}
84+
7485
private function getUrlsForDocument($document)
7586
{
7687
$urls = array();

AutoRoute/DefunctRouteHandler.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
namespace Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute;
44

55
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\OperationStack;
6+
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Mapping\MetadataFactory;
7+
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Adapter\AdapterInterface;
8+
use Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\ServiceRegistry;
69

710
/**
811
* Class which takes actions on routes which are left behind
@@ -25,7 +28,7 @@ class DefunctRouteHandler implements DefunctRouteHandlerInterface
2528
* @param AdapterInterface auto routing backend adapter
2629
* @param MetadataFactory auto routing metadata factory
2730
*/
28-
public function __consturct(
31+
public function __construct(
2932
MetadataFactory $metadataFactory,
3033
AdapterInterface $adapter,
3134
ServiceRegistry $serviceRegistry
@@ -41,5 +44,13 @@ public function __consturct(
4144
*/
4245
public function handleDefunctRoutes($document, OperationStack $operationStack)
4346
{
47+
$referrerCollection = $this->adapter->getReferringRoutes($document);
48+
49+
foreach ($referrerCollection as $referrer) {
50+
if (!$operationStack->containsRoute($referrer)) {
51+
$canonicalRoutes = $operationStack->getPersistStack();
52+
$this->adapter->removeDefunctRoute($referrer, $canonicalRoutes[0]);
53+
}
54+
}
4455
}
4556
}

AutoRoute/OperationStack.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,15 @@ public function getPersistStack()
1717
{
1818
return $this->persistStack;
1919
}
20+
21+
public function containsRoute(RouteObjectInterface $targetRoute)
22+
{
23+
foreach ($this->persistStack as $route) {
24+
if ($route === $targetRoute) {
25+
return true;
26+
}
27+
}
28+
29+
return false;
30+
}
2031
}

Doctrine/Phpcr/AutoRouteListener.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ public function onFlush(ManagerEventArgs $args)
8888
}
8989
}
9090

91+
public function postFlush()
92+
{
93+
$arm = $this->getAutoRouteManager();
94+
$arm->handleDefunctRoutes();
95+
}
96+
9197
private function isAutoRouteable($document)
9298
{
9399
return $this->getMetadataFactory()->getMetadataForClass(get_class($document));

Resources/config/auto_route.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<service id="cmf_routing_auto.phpcrodm_auto_route_listener" class="%cmf_routing_auto.phpcrodm_auto_route_listener.class%">
6868
<argument type="service" id="service_container"/>
6969
<tag name="doctrine_phpcr.event_listener" event="onFlush"/>
70+
<tag name="doctrine_phpcr.event_listener" event="postFlush"/>
7071
</service>
7172

7273
<!-- Metadata -->

Tests/Functional/BaseTestCase.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public function setUp(array $options = array(), $routebase = null)
2626

2727
if (!$session->nodeExists('/test')) {
2828
$session->getRootNode()->addNode('test', 'nt:unstructured');
29+
$session->getNode('/test')->addNode('auto-route');
2930
}
3031

3132
$session->save();

Tests/Functional/EventListener/AutoRouteListenerTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ public function testUpdateRenameBlog($withPosts = false)
9595
$this->assertNotNull($post);
9696

9797
$routes = $post->routes;
98+
99+
$this->assertNotNull($routes[0]);
98100
$this->getDm()->refresh($routes[0]);
99101

100102
$this->assertEquals('/test/auto-route/blog/foobar/2013/03/21/this-is-a-post-title', $routes[0]->getId());

sr Yl CmSele RootSiteSelector.php

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony CMF package.
5+
*
6+
* (c) 2011-2013 Symfony CMF
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Cmf\Bundle\RoutingAutoBundle\AutoRoute\Adapter;
13+
14+
use Doctrine\ODM\PHPCR\DocumentManager;
15+
use Doctrine\ODM\PHPCR\Document\Generic;
16+
use Doctrine\Common\Util\ClassUtils;
17+
use Symfony\Cmf\Component\Routing\RouteObjectInterface;
18+
use PHPCR\Util\NodeHelper;
19+
use Symfony\Cmf\Bundle\RoutingAutoBundle\Model\AutoRoute;
20+
21+
/**
22+
* Abstraction adapter for PHPCR-ODM
23+
*
24+
* This class will eventually encapsulate all of the PHPCR-ODM
25+
* specific logic to enable support for multiple backends.
26+
*/
27+
class PhpcrOdmAdapter implements AdapterInterface
28+
{
29+
protected $dm;
30+
protected $baseRoutePath;
31+
32+
public function __construct(DocumentManager $dm, $routeBasePath)
33+
{
34+
$this->dm = $dm;
35+
$this->baseRoutePath = $routeBasePath;
36+
}
37+
38+
public function getLocales($contentDocument)
39+
{
40+
if ($this->dm->isDocumentTranslatable($contentDocument)) {
41+
return $this->dm->getLocalesFor($contentDocument);
42+
}
43+
44+
return array();
45+
}
46+
47+
public function translateObject($contentDocument, $locale)
48+
{
49+
$meta = $this->dm->getMetadataFactory()->getMetadataFor(get_class($contentDocument));
50+
$contentDocument = $this->dm->findTranslation($meta->getName(), $meta->getIdentifierValue($contentDocument), $locale);
51+
52+
return $contentDocument;
53+
}
54+
55+
public function createRoute($url, $contentDocument)
56+
{
57+
$path = $this->getPathFromUrl($url);
58+
$pathElements = explode('/', $path);
59+
$headName = array_pop($pathElements);
60+
$parentPath = implode('/', $pathElements);
61+
62+
// bypass the ODM ... but changes will still only be
63+
// persisted when the PHPCR session is saved in the ODMs flush().
64+
NodeHelper::createPath($this->dm->getPhpcrSession(), $parentPath);
65+
66+
$autoRouteParent = $this->dm->find(null, $parentPath);
67+
68+
if (!$autoRouteParent) {
69+
throw new \RuntimeException(sprintf(
70+
'Hmph, could not find parent path "%s", this really should not have happened.',
71+
$parentPath
72+
));
73+
}
74+
75+
$headRoute = new AutoRoute();
76+
$headRoute->setContent($contentDocument);
77+
$headRoute->setName($headName);
78+
$headRoute->setParent($autoRouteParent);
79+
80+
return $headRoute;
81+
}
82+
83+
public function getRealClassName($className)
84+
{
85+
return ClassUtils::getRealClass($className);
86+
}
87+
88+
public function compareRouteContent(RouteObjectInterface $route, $contentDocument)
89+
{
90+
if ($route->getContent() === $contentDocument) {
91+
return true;
92+
}
93+
94+
return false;
95+
}
96+
97+
public function getReferringRoutes($contentDocument)
98+
{
99+
return $this->dm->getReferrers($contentDocument, null, null, null, 'Symfony\Cmf\Component\Routing\RouteObjectInterface');
100+
}
101+
102+
/**
103+
* {@inheritDoc}
104+
*/
105+
public function findRouteForUrl($url)
106+
{
107+
$path = $this->getPathFromUrl($url);
108+
return $this->dm->find(null, $path);
109+
}
110+
111+
private function getPathFromUrl($url)
112+
{
113+
return $this->baseRoutePath . $url;
114+
}
115+
}

0 commit comments

Comments
 (0)