Skip to content

move document to model #112

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 19, 2013
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Admin/RouteAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Sonata\DoctrinePHPCRAdminBundle\Admin\Admin;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use PHPCR\Util\PathHelper;

class RouteAdmin extends Admin
{
Expand Down Expand Up @@ -74,7 +75,8 @@ protected function configureDatagridFilters(DatagridMapper $datagridMapper)

public function setRouteRoot($routeRoot)
{
$this->routeRoot = $routeRoot;
// TODO: fix widget to show root node when root is selectable
$this->routeRoot = PathHelper::getParentPath($routeRoot);
}

public function setContentRoot($contentRoot)
Expand Down
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
Changelog
=========

* **2013-06-15**: [Model] Separated database agnostic, doctrine generic and
PHPCR-ODM specific code to prepare for Doctrine ORM support. Deprecated
RoutingBundle\Document\Route and RedirectRoute in favor of
RoutingBundle\Doctrine\Phpcr\Route resp. RedirectRoute and also moved the
PHPCR-ODM specific listeners and repository implementations to Doctrine\Phpcr
Configuration was cleaned up as well. PHPCR specific configurations moved
into dynamic.phpcr_provider: use_sonata_admin, 'manager_registry,
manager_name, route_basepath, content_basepath.
In preparation of other route provider support, you need to at least set
`phpcr_provider: ~` to have the PHPCR provider loaded.
Dropped redundant routing_repositoryroot.

1.1.0-beta1
-----------

* **2013-05-28**: [Bundle] Only include Doctrine PHPCR compiler pass if PHPCR-ODM is present
* **2013-05-25**: [Bundle] Drop symfony_ from symfony_cmf prefix
* **2013-05-24**: [Document] ContentRepository now requires ManagerRegistry in the constructor and provides `setManagerName()` in the same way as RouteProvider
Expand Down
9 changes: 9 additions & 0 deletions CmfRoutingBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ public function build(ContainerBuilder $container)

if (class_exists('Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass')) {
$container->addCompilerPass($this->buildBasePhpcrCompilerPass());
$container->addCompilerPass(
DoctrinePhpcrMappingsPass::createXmlMappingDriver(
array(
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')
)
);
}
}

Expand Down
61 changes: 39 additions & 22 deletions DependencyInjection/CmfRoutingExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,6 @@ public function load(array $configs, ContainerBuilder $container)
$resources = $container->getParameter('twig.form.resources');
$container->setParameter('twig.form.resources', array_merge($resources, array('CmfRoutingBundle:Form:terms_form_type.html.twig')));
}

if ($config['use_sonata_admin']) {
$this->loadSonataAdmin($config, $loader, $container);
}
}

public function setupFormTypes(array $config, ContainerBuilder $container, LoaderInterface $loader)
Expand Down Expand Up @@ -93,22 +89,18 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
$container->setParameter($this->getAlias() . '.defined_templates_class', $controllerForTemplates);
$container->setParameter($this->getAlias() . '.uri_filter_regexp', $config['uri_filter_regexp']);

$loader->load('cmf_routing.xml');
$container->setParameter($this->getAlias() . '.routing_repositoryroot', $config['routing_repositoryroot']);
if (isset($config['locales']) && $config['locales']) {
$container->setParameter($this->getAlias() . '.locales', $config['locales']);
} else {
$container->removeDefinition('cmf_routing.phpcrodm_route_localeupdater_listener');
}
$loader->load('dynamic_routing.xml');

$container->setAlias('cmf_routing.route_provider', $config['route_provider_service_id']);
$container->setAlias('cmf_routing.content_repository', $config['content_repository_service_id']);
if (isset($config['phpcr_provider'])) {
$this->loadPhpcrProvider($config['phpcr_provider'], $loader, $container);
}

$routeProvider = $container->getDefinition($this->getAlias() . '.default_route_provider');
$routeProvider->replaceArgument(0, new Reference($config['manager_registry']));
$contentRepository = $container->getDefinition($this->getAlias() . '.default_content_repository');
$contentRepository->replaceArgument(0, new Reference($config['manager_registry']));
$container->setParameter($this->getAlias() . '.manager_name', $config['manager_name']);
if (isset($config['route_provider_service_id'])) {
$container->setAlias('cmf_routing.route_provider', $config['route_provider_service_id']);
}
if (isset($config['content_repository_service_id'])) {
$container->setAlias('cmf_routing.content_repository', $config['content_repository_service_id']);
}

$dynamic = $container->getDefinition($this->getAlias().'.dynamic_router');

Expand All @@ -134,16 +126,41 @@ private function setupDynamicRouter(array $config, ContainerBuilder $container,
}
}

public function loadSonataAdmin($config, XmlFileLoader $loader, ContainerBuilder $container)
public function loadPhpcrProvider($config, XmlFileLoader $loader, ContainerBuilder $container)
{
$loader->load('provider_phpcr.xml');

$container->setParameter($this->getAlias() . '.phpcr_provider.route_basepath', $config['route_basepath']);
$container->setParameter($this->getAlias() . '.phpcr_provider.content_basepath', $config['content_basepath']);

$routeProvider = $container->getDefinition($this->getAlias() . '.phpcr_route_provider');
$routeProvider->replaceArgument(0, new Reference($config['manager_registry']));
$contentRepository = $container->getDefinition($this->getAlias() . '.phpcr_content_repository');
$contentRepository->replaceArgument(0, new Reference($config['manager_registry']));
$container->setParameter($this->getAlias() . '.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');

if (isset($config['locales']) && $config['locales']) {
$container->setParameter($this->getAlias() . '.locales', $config['locales']);
} else {
$container->removeDefinition('cmf_routing.phpcrodm_route_locale_listener');
}

if ($config['use_sonata_admin']) {
$this->loadSonataPhpcrAdmin($config, $loader, $container);
}
}

public function loadSonataPhpcrAdmin($config, XmlFileLoader $loader, ContainerBuilder $container)
{
$bundles = $container->getParameter('kernel.bundles');
if ('auto' === $config['use_sonata_admin'] && !isset($bundles['SonataDoctrinePHPCRAdminBundle'])) {
return;
}

$loader->load('routing-admin.xml');
$container->setParameter($this->getAlias() . '.content_basepath', $config['content_basepath']);
$container->setParameter($this->getAlias() . '.route_basepath', $config['route_basepath']);
$loader->load('admin_phpcr.xml');
}

/**
Expand Down
26 changes: 14 additions & 12 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,29 +58,31 @@ public function getConfigTreeBuilder()
->useAttributeAsKey('alias')
->prototype('scalar')->end()
->end()
->scalarNode('manager_registry')->defaultValue('doctrine_phpcr')->end()
->scalarNode('manager_name')->defaultValue('default')->end()
->arrayNode('phpcr_provider')
->children()
->scalarNode('manager_registry')->defaultValue('doctrine_phpcr')->end()
->scalarNode('manager_name')->defaultValue('default')->end()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this rather default to NULL? Otherwise the default manager as defined by phpcr_odm is worthless?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ups, very true. fixed.

->scalarNode('route_basepath')->defaultValue('/cms/routes')->end()
->scalarNode('content_basepath')->defaultValue('/cms/content')->end()
->enumNode('use_sonata_admin')
->values(array(true, false, 'auto'))
->defaultValue('auto')
->end()
->end()
->end()
->scalarNode('uri_filter_regexp')->defaultValue('')->end()
->scalarNode('route_provider_service_id')->defaultValue('cmf_routing.default_route_provider')->end()
->scalarNode('route_provider_service_id')->end()
->arrayNode('route_filters_by_id')
->canBeUnset()
->useAttributeAsKey('id')
->prototype('scalar')->end()
->end()
->scalarNode('content_repository_service_id')->defaultValue('cmf_routing.default_content_repository')->end()
->scalarNode('routing_repositoryroot')->defaultValue('/cms/routes')->end()
->scalarNode('content_repository_service_id')->end()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove the defaults for content_repository_service_id and route_provider_service_id?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because if you enable phpcr, the DI extension will set those alias to the phpcr route provider + content repository now. these options are to override the automatic alias that happens because of your choice of backend.

->arrayNode('locales')
->prototype('scalar')->end()
->end()
->end()
->end()
->enumNode('use_sonata_admin')
->values(array(true, false, 'auto'))
->defaultValue('auto')
->end()
->scalarNode('content_basepath')->defaultValue('/cms/content')->end()
// TODO: fix widget to show root node when root is selectable, then use routing_repositoryroot for both
->scalarNode('route_basepath')->defaultValue('/cms')->end()
->end()
;

Expand Down
65 changes: 65 additions & 0 deletions Doctrine/DoctrineProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace Symfony\Cmf\Bundle\RoutingBundle\Doctrine;

use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\Common\Persistence\ObjectManager;

/**
* Abstract class for doctrine based content repository and route provider
* implementations.
*
* @author Uwe Jäger
* @author David Buchmann <[email protected]>
*/
abstract class DoctrineProvider
{
/**
* If this is null, the manager registry will return the default manager.
*
* @var string|null Name of object manager to use
*/
protected $managerName;

/**
* @var ManagerRegistry
*/
protected $managerRegistry;

/**
* Class name of the object class to find, null for PHPCR-ODM as it can
* determine the class on its own.
*
* @var string|null
*/
protected $className;

/**
* @param ManagerRegistry $managerRegistry
*/
public function __construct(ManagerRegistry $managerRegistry, $className = null)
{
$this->managerRegistry = $managerRegistry;
}

/**
* Set the object manager name to use for this loader. If not set, the
* default manager as decided by the manager registry will be used.
*
* @param string|null $managerName
*/
public function setManagerName($managerName)
{
$this->managerName = $managerName;
}

/**
* Get the object manager named $managerName from the registry.
*
* @return ObjectManager
*/
protected function getObjectManager()
{
return $this->managerRegistry->getManager($this->managerName);
}
}
41 changes: 41 additions & 0 deletions Doctrine/Phpcr/ContentRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr;

use Symfony\Cmf\Component\Routing\ContentRepositoryInterface;
use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\DoctrineProvider;

/**
* Implement ContentRepositoryInterface for PHPCR-ODM
*
* This is <strong>NOT</strong> not a doctrine repository but just the content
* provider for the NestedMatcher. (you could of course implement this
* interface in a repository class, if you need that)
*
* @author Uwe Jäger
*/
class ContentRepository extends DoctrineProvider implements ContentRepositoryInterface
{
/**
* {@inheritDoc}
*/
public function findById($id)
{
return $this->getObjectManager()->find(null, $id);
}

/**
* {@inheritDoc}
*/
public function getContentId($content)
{
if (! is_object($content)) {
return null;
}
try {
return $this->getObjectManager()->getUnitOfWork()->getDocumentId($content);
} catch (\Exception $e) {
return null;
}
}
}
12 changes: 6 additions & 6 deletions Listener/IdPrefix.php → Doctrine/Phpcr/IdPrefixListener.php
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<?php

namespace Symfony\Cmf\Bundle\RoutingBundle\Listener;
namespace Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr;

use Symfony\Cmf\Bundle\RoutingBundle\Document\Route;
use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;

/**
* Doctrine PHPCR-ODM listener to set the idPrefix on new routes
* Doctrine PHPCR-ODM listener to set the idPrefix on routes
*
* @author david.buchmann@liip.ch
* @author David Buchmann <mail@davidbu.ch>
*/
class IdPrefix
class IdPrefixListener
{
/**
* The prefix to add to the url to create the repository path
Expand Down Expand Up @@ -48,7 +48,7 @@ protected function updateId(LifecycleEventArgs $args)

// only update route objects and only if the prefix can match, to allow
// for more than one listener and more than one route root
if ($doc instanceof Route
if (($doc instanceof Route || $doc instanceof RedirectRoute)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is one of the drawbacks of not having multiple inheritance/traits to build the document classes...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand, why can't they at least implement an interface?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well then we would define a PhpcrPathPrefixInterface or something, just sounds weird as its just an implementation detail. if this was a Trait, we could check the class for having the trait. (but until php 5.3 can be dropped, i guess we are at least in Symfony3...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Why would such an interface be a bad idea? Although, the only problem I can see here is if/when the user wants another type of Routing object à la "RedirectRoute". They would have to override this class - creating a little interface in the Doctrine/PHPCR namespace seems like a painless solution?

If we were to implement the interface I guess we would also have to determine the ID from either the DM or the metadata also.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, convinced. i added the interface

&& ! strncmp($this->idPrefix, $doc->getId(), strlen($this->idPrefix))
) {
$doc->setPrefix($this->idPrefix);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
<?php

namespace Symfony\Cmf\Bundle\RoutingBundle\Listener;
namespace Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr;

use Symfony\Cmf\Bundle\RoutingBundle\Document\Route;
use Doctrine\ODM\PHPCR\Event\MoveEventArgs;
use Doctrine\Common\Persistence\Event\LifecycleEventArgs;

use Symfony\Cmf\Bundle\RoutingBundle\Doctrine\Phpcr\Route;

/**
* Doctrine PHPCR-ODM listener to update the locale on routes based on the URL.
*
* It uses the idPrefix and looks at the path segment right after the prefix to
* determine if that segment matches one of the configured locales and if so
* sets a requirement and default named _locale for that locale.
*
* @author David Buchmann <david@liip.ch>
* @author David Buchmann <mail@davidbu.ch>
*/
class LocaleUpdater
class LocaleListener
{
/**
* The prefix to add to the url to create the repository path
Expand Down
Loading