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

Commit 0cb652e

Browse files
committed
Ported AutoRouteManager test and dependeencies from RoutingExtra
0 parents  commit 0cb652e

File tree

13 files changed

+648
-0
lines changed

13 files changed

+648
-0
lines changed

.travis.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
language: php
2+
3+
php:
4+
- 5.3
5+
- 5.4
6+
7+
env:
8+
- SYMFONY_VERSION=2.1.*
9+
- SYMFONY_VERSION=dev-master
10+
11+
before_script:
12+
- composer install --dev
13+
- cp ./Tests/Functional/config/parameters.yml.dist ./Tests/Functional/config/parameters.yml
14+
- php Tests/Functional/console doctrine:phpcr:init:dbal
15+
- php Tests/Functional/console doctrine:phpcr:register-system-node-types
16+
17+
script: phpunit --coverage-text
18+
19+
notifications:
20+
irc: "irc.freenode.org#symfony-cmf"
21+

AutoRoute/AutoRouteManager.php

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Bundle\RoutingAutoRouteBundle\AutoRoute;
4+
5+
use Doctrine\ODM\PHPCR\DocumentManager;
6+
use Metadata\MetadataFactoryInterface;
7+
use Symfony\Cmf\Bundle\RoutingAutoRouteBundle\Document\AutoRoute;
8+
use Symfony\Cmf\Bundle\CoreBundle\Slugifier\SlugifierInterface;
9+
10+
/**
11+
* This class is concerned with the automatic creation of route objects.
12+
*
13+
* @author Daniel Leech <[email protected]>
14+
* @author Sjoerd Peters <[email protected]>
15+
*/
16+
class AutoRouteManager
17+
{
18+
protected $dm;
19+
protected $metadataFactory;
20+
protected $defaultPath;
21+
protected $slugifier;
22+
23+
protected $metadata;
24+
25+
/**
26+
* @TODO: Should defaultPath be contained in a service to
27+
* enable this property to be modified at runtime?
28+
* @TODO: Replace Slugifier with TransformerFactory or similar.
29+
*
30+
* @param DocumentManager $dm PHPCR-ODM Document Manager
31+
* @param array $mapping Class => configuration mapping
32+
* @param SlugifierInterface $slugifier Slugifier
33+
* @param string $defaultPath Default base path for new routes
34+
*/
35+
public function __construct(
36+
DocumentManager $dm,
37+
$mapping,
38+
SlugifierInterface $slugifier,
39+
$defaultPath
40+
)
41+
{
42+
$this->dm = $dm;
43+
$this->mapping = $mapping;
44+
$this->slugifier = $slugifier;
45+
$this->defaultPath = $defaultPath;
46+
}
47+
48+
/**
49+
* Create or update the automatically generated route for
50+
* the given document.
51+
*
52+
* When this is finished it will support multiple locales.
53+
*
54+
* @param object Mapped document for which to generate the AutoRoute
55+
*
56+
* @return AutoRoute
57+
*/
58+
public function updateAutoRouteForDocument($document)
59+
{
60+
$metadata = $this->getMetadata($document);
61+
$autoRoute = $this->getAutoRouteForDocument($document);
62+
63+
$autoRouteName = $this->getRouteName($document);
64+
$autoRoute->setName($autoRouteName);
65+
66+
$autoRouteParent = $this->getParentRoute($document);
67+
$autoRoute->setParent($autoRouteParent);
68+
69+
$this->dm->persist($autoRoute);
70+
71+
return $autoRoute;
72+
}
73+
74+
/**
75+
* Remove all auto routes associated with the given document.
76+
*
77+
* @param object $document Mapped document
78+
*
79+
* @todo: Test me
80+
*
81+
* @return array Array of removed routes
82+
*/
83+
public function removeAutoRoutesForDocument($document)
84+
{
85+
$autoRoutes = $this->fetchAutoRoutesForDocument($document);
86+
foreach ($autoRoutes as $autoRoute) {
87+
$this->dm->remove($autoRoute);
88+
}
89+
90+
return $autoRoutes;
91+
}
92+
93+
/**
94+
* Return true if the given document is mapped with AutoRoute
95+
*
96+
* @param object $document Document
97+
*
98+
* @return boolean
99+
*/
100+
public function isAutoRouteable($document)
101+
{
102+
$metadata = $this->metadataFactory->getMetadataForClass(get_class($document));
103+
104+
return $metadata->autoRouteable == 1 ? true : false;
105+
}
106+
107+
/**
108+
* Generate a route name based on the designated route name method in
109+
* the given mapped document.
110+
*
111+
* Here we use the slugifier service given to this class to normalize
112+
* the title.
113+
*
114+
* @param object Mapped document
115+
*
116+
* @return string
117+
*/
118+
protected function getRouteName($document)
119+
{
120+
$metadata = $this->getMetadata($document);
121+
122+
$routeNameMethod = $metadata['route_method_name'];
123+
$routeName = $document->$routeNameMethod();
124+
$routeName = $this->slugifier->slugify($routeName);
125+
126+
return $routeName;
127+
}
128+
129+
/**
130+
* Return the parent route for the generated AutoRoute.
131+
*
132+
* Currently we check to see if a base route path has been specified
133+
* in the given mapped document, if not we fall back to the global default.
134+
*
135+
* @TODO: Enable dynamic parents (e.g. name-of-my-blog/my-post)
136+
*
137+
* @param object Get parent route of this mapped document.
138+
*
139+
* @return Route
140+
*/
141+
protected function getParentRoute($document)
142+
{
143+
$metadata = $this->getMetadata($document);
144+
$defaultPath = $metadata['base_path'] ? : $this->defaultPath;
145+
$parent = $this->dm->find(null, $defaultPath);
146+
147+
if (!$parent) {
148+
throw new \Exception(sprintf(
149+
'Could not find default route parent at path "%s"',
150+
$defaultPath
151+
));
152+
}
153+
154+
return $parent;
155+
}
156+
157+
/**
158+
* Convenience method for retrieving Metadata.
159+
*/
160+
protected function getMetadata($document)
161+
{
162+
foreach ($this->mapping as $classFqn => $metadata) {
163+
if ($document instanceof $classFqn) {
164+
return $metadata;
165+
}
166+
}
167+
}
168+
169+
/**
170+
* Return the existing or a new AutoRoute for the given document.
171+
*
172+
* @throws \Exception If we have more than one
173+
*
174+
* @param object $document Mapped document that needs an AutoRoute
175+
*
176+
* @return AutoRoute
177+
*/
178+
protected function getAutoRouteForDocument($document)
179+
{
180+
$autoRoutes = array();
181+
182+
if ($this->isDocumentPersisted($document)) {
183+
$autoRoutes = $this->fetchAutoRoutesForDocument($document);
184+
}
185+
186+
// @TODO: get locale from ODM
187+
$locale = null;
188+
189+
if ($locale) {
190+
// filter non-matching locales, note that we could do this with the QueryBuilder
191+
// but currently searching array values is not supported by jackalope-doctrine-dbal.
192+
array_filter($res, function ($route) use ($locale) {
193+
if ($route->getDefault('_locale') != $locale) {
194+
return false;
195+
}
196+
197+
return true;
198+
});
199+
}
200+
201+
if (count($autoRoutes) > 1) {
202+
throw new Exception\MoreThanOneAutoRoute($document);
203+
} elseif (count($autoRoutes) == 1) {
204+
$autoRoute = $autoRoutes->first();
205+
} else {
206+
$autoRoute = new AutoRoute;
207+
$autoRoute->setRouteContent($document);
208+
}
209+
210+
return $autoRoute;
211+
}
212+
213+
/**
214+
* Fetch all the automatic routes for the given document
215+
*
216+
* @param object $document Mapped document
217+
*
218+
* @return array
219+
*/
220+
public function fetchAutoRoutesForDocument($document)
221+
{
222+
$routes = $this->dm->getReferrers($document, null, 'routeContent');
223+
$routes = $routes->filter(function ($route) {
224+
if ($route instanceof AutoRoute) {
225+
return true;
226+
}
227+
228+
return false;
229+
});
230+
231+
return $routes;
232+
}
233+
234+
protected function isDocumentPersisted($document)
235+
{
236+
$metadata = $this->dm->getClassMetadata(get_class($document));
237+
$id = $metadata->getIdentifierValue($document);
238+
239+
return $this->dm->getPhpcrSession()->nodeExists($id);
240+
}
241+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Bundle\RoutingAutoRouteBundle\AutoRoute\Exception;
4+
5+
class MoreThanOneAutoRoute extends \Exception
6+
{
7+
public function __construct($document)
8+
{
9+
$message = sprintf(
10+
'Found more than one AutoRoute for document of class "%s"',
11+
get_class($document)
12+
);
13+
parent::__construct($message);
14+
}
15+
16+
}
17+

Document/AutoRoute.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Bundle\RoutingAutoRouteBundle\Document;
4+
5+
use Doctrine\Common\Collections\Collection;
6+
use Symfony\Cmf\Bundle\RoutingExtraBundle\Document\Route;
7+
8+
/**
9+
* Sub class of Route to enable automatically generated routes
10+
* to be identified.
11+
*
12+
* @author Daniel Leech <[email protected]>
13+
*/
14+
class AutoRoute extends Route
15+
{
16+
}
17+

LICENSE

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
RoutingAutoRouteBundle
2+
3+
The MIT License
4+
5+
Copyright (c) 2011-2012 Symfony2 CMF
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in
15+
all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
THE SOFTWARE.
24+

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# [WIP] Symfony CMF Routing Auto Route Bundle [![Build Status](https://secure.travis-ci.org/symfony-cmf/RoutingAutoRouteBundle.png)](http://travis-ci.org/symfony-cmf/RoutingExtraBundle)
2+
3+
This bundle automatically creates and manages routes for given persisted document classes.
4+
5+
User stories:
6+
7+
* Blog posts: To be able to view a blog posts, blog posts must have a route which
8+
is appended to that of its parent, the blog.
9+
10+
- When a Post is created an auto-route is automatically created.
11+
- When the Post is updated, the auto-route is updated.
12+
- When the Post is deleted, the auto-route is deleted.
13+
14+
Restrictions:
15+
16+
* Only documents stored with PHPCR-ODM are supported.
17+
* You must have the RoutingExtraBundle installed.

0 commit comments

Comments
 (0)