Closed SalvatorePollaci closed 7 years ago
One quick solution would be to define your own service definition:
If you want to use a different document manager based on context (e.g.
live / staging) you could decorate the default Adapter and inject the
doctrine.odm.phpcr.registry
(or similar) and choose based on some
custom logic.
On Tue, Mar 21, 2017 at 08:48:38AM -0700, SalvatorePollaci wrote:
Hi, as you can observe below, the Default Document Manager gets injected into the PhpcrOdmAdapter:
%cmf_routing_auto.persistence.phpcr.route_basepath% Therefore when 2 Document Managers are used(eg: default and live), the routing autobundle will not be able to correctly persist AutoRoutes when the Non default document manager is used to persist the relative content.
My Case We have the following base paths: /cms/pages => contains the content pages(eg /cms/pages/home) /cms/routes => contains the autoroutes relative to the content pages (eg /cms/routes/home)
When i try to persist the 'home' page (Content Document) with the 'live' document manager the following happens:
1. The Live Document Manager's UnitOfWork instance correctly prepares the persistence of the 'home' page(Content Document). Moreover such instance of the UnitOfWork contains the following 3 elements in the array attribute 'identitymap'('/cms', '/cms/pages', '/cms/pages/home').
2. The 'AutoRouteListener' onFlush method is called.
* The AutoRouteManager service gets injected into the AutoRouteListener service. * The PhpcrOdmAdapter service gets injected into the AutoRouteManager service * The 'Default' Document Manager service gets injected into the PhpcrOdmAdapter * As we are now using the 'Default' Document Manager and not the live one, such document manager unitofwork's 'identityMap' array is empty. * Consequently, when such document manager tries to persist the '/cms/routes/home' AutoRoute Document, it must first generate its id which depends on the id of its parent Documents. As the default document manager unitofwork's 'identityMap' is empty, it doesn't recognize the '/cms' document.
3. UnitOfWork throws a PHPCRException with message 'Document is not managed and has no id: routes'.
How can the PhpcrOdmAdapter be used when multiple Document Managers are used?
Thank you
— You are receiving this because you are subscribed to this thread. Reply to this email directly, [1]view it on GitHub, or [2]mute the thread.
Reverse link: [3]unknown
References
Visible links
agree with dan.
one note though: some of the cmf bundles let you inject the registry and the manager name. e.g. https://github.com/symfony-cmf/routing-bundle/blob/201ca313b599bda335cea350256045da05972412/src/Doctrine/DoctrineProvider.php - if you want to refactor the adapter in this bundle to follow the same pattern, please do that. if you find time for it this week, we could even have that in version 2, as we did not release yet.
though that probably wont help in your use case, i think. seems to me like having 2 service instances sounds like the cleanest solution.
Thanks for the quick answers guys. I'm currently trying to implement a decorator for the adapter. What I'm having difficulty with is: on which condition can i base myself on to distinguish which document manager to inject.
i don't know, you need to know that. but its why i said maybe separate services makes most sense. then you can check if the document manager is in charge for the content in question and skip doing anything if its not the right manager.
Hi guys, this is the solution i came up with. Its more of a workaround, but it allows me to persist AutoRoutes using the live Document Manager.
1)Create 2 services associated to the original PhpcrOdmAdapter class, the first with the Default Document Manager injected and the second with the Live Document Manager injected.
services.yml
cmf_routing_auto.adapter.phpcr_odm.default:
class: Symfony\Cmf\Bundle\RoutingAutoBundle\Adapter\PhpcrOdmAdapter
arguments:
- '@doctrine_phpcr.odm.default_document_manager'
- '%cmf_routing_auto.persistence.phpcr.route_basepath%'
cmf_routing_auto.adapter.phpcr_odm.live:
class: Symfony\Cmf\Bundle\RoutingAutoBundle\Adapter\PhpcrOdmAdapter
arguments:
- '@doctrine_phpcr.odm.live_document_manager'
- '%cmf_routing_auto.persistence.phpcr.route_basepath%'
2)Create a Doctrine PHPCR Event Listener which recieves a ManagerEventArgs object which contains the current Document Manager. With such information we can override the original 'cmf_routing_auto.adapter.phpcr_odm' service to point to one of our 2 custom defined services.
services.yml
my.doctrine_phpcr.listener.document_manager:
class: <path>/DocumentManagerListener
arguments:
- '@service_container'
tags:
- { name: doctrine_phpcr.event_listener, event: preFlush, priority: 33 }
- { name: doctrine_phpcr.event_listener, event: onFlush, priority: 33 }
- { name: doctrine_phpcr.event_listener, event: postFlush, priority: 33 }
- { name: doctrine_phpcr.event_listener, event: endFlush, priority: 33 }
DocumentManagerListener.php
...
/**
* @param ManagerEventArgs $args
*/
protected function managePhpcrOdmAdapterService(ManagerEventArgs $args)
{
/** @var $dm DocumentManager */
$dm = $args->getObjectManager();
$workspace = $dm->getPhpcrSession()->getWorkspace()->getName();
$phpcrAdapterLive = $this->container->get('cmf_routing_auto.adapter.phpcr_odm' . '.' . $workspace);
$this->container->set('cmf_routing_auto.adapter.phpcr_odm', $phpcrAdapterLive);
}
...
Thanks for the support.
glad you found a solution!
Hi, as you can observe below, the Default Document Manager gets injected into the PhpcrOdmAdapter:
Therefore when 2 Document Managers are used(eg: default and live), the routing autobundle will not be able to correctly persist AutoRoutes when the Non default document manager is used to persist the relative content.
My Case We have the following base paths: /cms/pages => contains the content pages(eg /cms/pages/home) /cms/routes => contains the autoroutes relative to the content pages (eg /cms/routes/home)
When i try to persist the 'home' page (Content Document) with the 'live' document manager the following happens:
The Live Document Manager's UnitOfWork instance correctly prepares the persistence of the 'home' page(Content Document). Moreover such instance of the UnitOfWork contains the following 3 elements in the array attribute 'identitymap'('/cms', '/cms/pages', '/cms/pages/home').
The 'AutoRouteListener' onFlush method is called.
UnitOfWork throws a PHPCRException with message 'Document is not managed and has no id: routes'.
How can the PhpcrOdmAdapter be used when multiple Document Managers are used?
Thank you