diff --git a/CmfRoutingBundle.php b/CmfRoutingBundle.php
index 72612e2c..fcce4960 100644
--- a/CmfRoutingBundle.php
+++ b/CmfRoutingBundle.php
@@ -3,6 +3,7 @@
namespace Symfony\Cmf\Bundle\RoutingBundle;
use Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass;
+use Symfony\Cmf\Bundle\CoreBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -33,10 +34,39 @@ public function build(ContainerBuilder $container)
realpath(__DIR__ . '/Resources/config/doctrine-model') => 'Symfony\Cmf\Bundle\RoutingBundle\Model',
realpath(__DIR__ . '/Resources/config/doctrine-phpcr') => 'Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr',
),
- array('cmf_routing.manager_name')
+ array('cmf_routing.dynamic.persistence.phpcr.manager_name'),
+ 'cmf_routing.backend_type_phpcr'
)
);
}
+
+ if (class_exists('Symfony\Cmf\Bundle\CoreBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass')) {
+ $container->addCompilerPass($this->buildBaseOrmCompilerPass());
+ $container->addCompilerPass(
+ DoctrineOrmMappingsPass::createXmlMappingDriver(
+ array(
+ realpath(__DIR__ . '/Resources/config/doctrine-model') => 'Symfony\Cmf\Bundle\RoutingBundle\Model',
+ realpath(__DIR__ . '/Resources/config/doctrine-orm') => 'Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Orm',
+ ),
+ array('cmf_routing.dynamic.persistence.orm.manager_name'),
+ 'cmf_routing.backend_type_orm'
+ )
+ );
+ }
+ }
+
+ private function buildBaseOrmCompilerPass()
+ {
+ $arguments = array(array(realpath(__DIR__ . '/Resources/config/doctrine-base')), '.orm.xml');
+ $locator = new Definition('Doctrine\Common\Persistence\Mapping\Driver\DefaultFileLocator', $arguments);
+ $driver = new Definition('Doctrine\ORM\Mapping\Driver\XmlDriver', array($locator));
+
+ return new DoctrineOrmMappingsPass(
+ $driver,
+ array('Symfony\Component\Routing'),
+ array('cmf_routing.dynamic.persistence.orm.manager_name'),
+ 'cmf_routing.backend_type_orm'
+ );
}
/**
@@ -55,7 +85,7 @@ private function buildBasePhpcrCompilerPass()
return new DoctrinePhpcrMappingsPass(
$driver,
array('Symfony\Component\Routing'),
- array('cmf_routing.manager_name'),
+ array('cmf_routing.dynamic.persistence.phpcr.manager_name'),
'cmf_routing.backend_type_phpcr'
);
}
diff --git a/DependencyInjection/CmfRoutingExtension.php b/DependencyInjection/CmfRoutingExtension.php
index 5a1ed2c9..9bd43515 100644
--- a/DependencyInjection/CmfRoutingExtension.php
+++ b/DependencyInjection/CmfRoutingExtension.php
@@ -93,6 +93,12 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
$hasProvider = true;
$hasContentRepository = true;
}
+
+ if (!empty($config['persistence']['orm']['enabled'])) {
+ $this->loadOrmProvider($config['persistence']['orm'], $loader, $container);
+ $hasProvider = true;
+ }
+
if (isset($config['route_provider_service_id'])) {
$container->setAlias('cmf_routing.route_provider', $config['route_provider_service_id']);
$hasProvider = true;
@@ -142,10 +148,10 @@ public function loadPhpcrProvider($config, XmlFileLoader $loader, ContainerBuild
$container->setParameter($this->getAlias() . '.backend_type_phpcr', true);
- $container->setParameter($this->getAlias() . '.persistence.phpcr.route_basepath', $config['route_basepath']);
- $container->setParameter($this->getAlias() . '.persistence.phpcr.content_basepath', $config['content_basepath']);
+ $container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.route_basepath', $config['route_basepath']);
+ $container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.content_basepath', $config['content_basepath']);
- $container->setParameter($this->getAlias() . '.manager_name', $config['manager_name']);
+ $container->setParameter($this->getAlias() . '.dynamic.persistence.phpcr.manager_name', $config['manager_name']);
$container->setAlias($this->getAlias() . '.route_provider', $this->getAlias() . '.phpcr_route_provider');
$container->setAlias($this->getAlias() . '.content_repository', $this->getAlias() . '.phpcr_content_repository');
@@ -171,6 +177,13 @@ public function loadSonataPhpcrAdmin($config, XmlFileLoader $loader, ContainerBu
$loader->load('admin-phpcr.xml');
}
+ public function loadOrmProvider($config, XmlFileLoader $loader, ContainerBuilder $container)
+ {
+ $container->setParameter($this->getAlias() . '.dynamic.persistence.orm.manager_name', $config['manager_name']);
+ $container->setParameter($this->getAlias() . '.backend_type_orm', true);
+ $loader->load('provider_orm.xml');
+ }
+
/**
* Returns the base path for the XSD files.
*
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index cb89a4ea..d7d4a4e1 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -72,6 +72,12 @@ public function getConfigTreeBuilder()
->end()
->end()
->end()
+ ->arrayNode('orm')
+ ->children()
+ ->scalarNode('enabled')->defaultNull()->end()
+ ->scalarNode('manager_name')->defaultNull()->end()
+ ->end()
+ ->end()
->end()
->end()
->scalarNode('uri_filter_regexp')->defaultValue('')->end()
diff --git a/Doctrine/DoctrineProvider.php b/Doctrine/DoctrineProvider.php
index 368f5d5d..e2f705a5 100644
--- a/Doctrine/DoctrineProvider.php
+++ b/Doctrine/DoctrineProvider.php
@@ -40,6 +40,7 @@ abstract class DoctrineProvider
public function __construct(ManagerRegistry $managerRegistry, $className = null)
{
$this->managerRegistry = $managerRegistry;
+ $this->className = $className;
}
/**
diff --git a/Doctrine/Orm/ContentRepository.php b/Doctrine/Orm/ContentRepository.php
new file mode 100644
index 00000000..4d7d087c
--- /dev/null
+++ b/Doctrine/Orm/ContentRepository.php
@@ -0,0 +1,61 @@
+getModelAndId($id);
+
+ return $this->getObjectManager()->getRepository($model)->find($modelId);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getContentId($content)
+ {
+ if (! is_object($content)) {
+ return null;
+ }
+
+ try {
+ $meta = $this->getObjectManager()->getClassMetadata(get_class($content));
+ $ids = $meta->getIdentifierValues($content);
+ if (0 !== count($ids)) {
+ throw new \Exception('Multi identifier values not supported in ' . get_class($content));
+ }
+
+ return implode(':', array(
+ get_class($content),
+ reset($ids)
+ ));
+ } catch (\Exception $e) {
+ return null;
+ }
+ }
+}
diff --git a/Doctrine/Orm/Route.php b/Doctrine/Orm/Route.php
new file mode 100644
index 00000000..114fc8f4
--- /dev/null
+++ b/Doctrine/Orm/Route.php
@@ -0,0 +1,22 @@
+NOT not a doctrine repository but just the route
+ * provider for the NestedMatcher. (you could of course implement this
+ * interface in a repository class, if you need that)
+ *
+ * @author david.buchmann@liip.ch
+ */
+class RouteProvider extends DoctrineProvider implements RouteProviderInterface
+{
+ protected function getCandidates($url)
+ {
+ $candidates = array();
+ if ('/' !== $url) {
+ if (preg_match('/(.+)\.[a-z]+$/i', $url, $matches)) {
+ $candidates[] = $url;
+ $url = $matches[1];
+ }
+
+ $part = $url;
+ while (false !== ($pos = strrpos($part, '/'))) {
+ $candidates[] = $part;
+ $part = substr($url, 0, $pos);
+ }
+ }
+
+ $candidates[] = '/';
+
+ return $candidates;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getRouteByName($name, $parameters = array())
+ {
+ $route = $this->getRoutesRepository()->findBy(array('name' => $name));
+ if (!$route) {
+ throw new RouteNotFoundException("No route found for name '$name'");
+ }
+
+ return $route;
+ }
+
+ public function getRoutesByNames($names, $parameters = array())
+ {
+ }
+
+ public function getRouteCollectionForRequest(Request $request)
+ {
+ $url = $request->getPathInfo();
+
+ $candidates = $this->getCandidates($url);
+
+ $collection = new RouteCollection();
+
+ if (empty($candidates)) {
+ return $collection;
+ }
+
+ try {
+ $routes = $this->getRoutesRepository()->findByStaticPrefix($candidates, array('position' => 'ASC'));
+
+ foreach ($routes as $key => $route) {
+ if (preg_match('/.+\.([a-z]+)$/i', $url, $matches)) {
+ if ($route->getDefault('_format') === $matches[1]) {
+ continue;
+ }
+
+ $route->setDefault('_format', $matches[1]);
+ }
+ // SYMFONY 2.1 COMPATIBILITY: tweak route name
+ $key = trim(preg_replace('/[^a-z0-9A-Z_.]/', '_', $key), '_');
+ $collection->add($key, $route);
+ }
+ } catch (RepositoryException $e) {
+ // TODO: how to determine whether this is a relevant exception or not?
+ // for example, getting /my//test (note the double /) is just an invalid path
+ // and means another router might handle this.
+ // but if the PHPCR backend is down for example, we want to alert the user
+ }
+
+ return $collection;
+ }
+
+ protected function getRoutesRepository()
+ {
+ return $this->getObjectManager()->getRepository($this->className);
+ }
+}
diff --git a/Resources/config/admin-phpcr.xml b/Resources/config/admin-phpcr.xml
index daab38c9..2e9aa97c 100644
--- a/Resources/config/admin-phpcr.xml
+++ b/Resources/config/admin-phpcr.xml
@@ -25,11 +25,11 @@
- %cmf_routing.persistence.phpcr.content_basepath%
+ %cmf_routing.dynamic.persistence.phpcr.content_basepath%
- %cmf_routing.persistence.phpcr.route_basepath%
+ %cmf_routing.dynamic.persistence.phpcr.route_basepath%
@@ -47,7 +47,7 @@
- %cmf_routing.persistence.phpcr.route_basepath%
+ %cmf_routing.dynamic.persistence.phpcr.route_basepath%
diff --git a/Resources/config/doctrine-base/Symfony.Component.Routing.Route.orm.xml b/Resources/config/doctrine-base/Symfony.Component.Routing.Route.orm.xml
new file mode 100644
index 00000000..29192202
--- /dev/null
+++ b/Resources/config/doctrine-base/Symfony.Component.Routing.Route.orm.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Resources/config/doctrine-model/Route.orm.xml b/Resources/config/doctrine-model/Route.orm.xml
new file mode 100644
index 00000000..d815a646
--- /dev/null
+++ b/Resources/config/doctrine-model/Route.orm.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Resources/config/doctrine-orm/Route.orm.xml b/Resources/config/doctrine-orm/Route.orm.xml
new file mode 100644
index 00000000..039081d3
--- /dev/null
+++ b/Resources/config/doctrine-orm/Route.orm.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Resources/config/provider-phpcr.xml b/Resources/config/provider-phpcr.xml
index 2dd23b5a..59a60c7d 100644
--- a/Resources/config/provider-phpcr.xml
+++ b/Resources/config/provider-phpcr.xml
@@ -15,23 +15,23 @@
%cmf_routing.route_model_class%
- %cmf_routing.manager_name%
- %cmf_routing.persistence.phpcr.route_basepath%
+ %cmf_routing.dynamic.persistence.phpcr.manager_name%
+ %cmf_routing.dynamic.persistence.phpcr.route_basepath%
- %cmf_routing.manager_name%
+ %cmf_routing.dynamic.persistence.phpcr.manager_name%
- %cmf_routing.persistence.phpcr.route_basepath%
+ %cmf_routing.dynamic.persistence.phpcr.route_basepath%
- %cmf_routing.persistence.phpcr.route_basepath%
+ %cmf_routing.dynamic.persistence.phpcr.route_basepath%
%cmf_routing.locales%
@@ -40,7 +40,7 @@
- %cmf_routing.persistence.phpcr.route_basepath%
+ %cmf_routing.dynamic.persistence.phpcr.route_basepath%
diff --git a/Resources/config/provider_orm.xml b/Resources/config/provider_orm.xml
new file mode 100644
index 00000000..4e8fc709
--- /dev/null
+++ b/Resources/config/provider_orm.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Orm\Route
+ Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Orm\RouteProvider
+ Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Orm\ContentRepository
+
+
+
+
+
+
+
+
+
+
+ %cmf_routing.route_entity_class%
+ %cmf_routing.dynamic.persistence.orm.manager_name%
+
+
+