Just like every marmelab recruit, my first weeks are spent working on various new technologies (Node.js, ElasticSearch, MongoDb, etc) with real use cases.
I've created a bundle, it can be found on GitHub.
Here's the README intro:
The Sonata Admin Bundle provides a web UI to many types of persistence (RDBMS, MongoDB, PHPCR), some of which have limited query capabilities. If you already have an ElasticSearch index for a given model, this bundle allows you to use this index instead of the native repository query system. This may provide a great performance boost, depending on your data structure and indexes.
Sonata Admin with no DB query
First Start: Bad Direction
It was clear that the configuration should be in the entity admin service's definition.
At first, I tried to add a new
manager_type=elastica in the
sonata.admintag. I wanted to override each class used by the admin bundle and/or elastica. I thought I must get rid of any little dependency on doctrine or propel.
That was a mistake.
First, because there was so many classes to override, that I almost wanted to give up.
Second, because my goal was to display a list view in the admin bundle with no query in database. I wanted to be able to filter, sort and paginate the elements, using the ElasticSearch index. But I did not want to override the detail view, the batch actions, ... So, depending on the action, I needed to keep the 'normal' behaviour.
Second Start: Better Understanding
For the second version, the idea was to keep the default
manager_type attribute and to add new parameters in the
sonata.admin tag. Just override what needs to be overridden, KISS as they said.
The goal was simple: to use the elastica index, just add two parameters in the tag:
I needed to use proxy classes that do the job when we need it, and let the ORM do the rest.
I had to create services for each entity to display from the ElasticSearch index. As I didn't want the potential user of the bundle to have to write a bunch of services for each admin class, I have created my first CompilerPass.
I defined an
ElasticaModelManager that is used over the orm
ModelManager. This proxy has a
baseManager attribute that corresponds to the orm
ModelManager. It’s linked to the admin class thanks to the CompilerPass:
$adminService->addMethodCall('setModelManager', array(new Reference($proxyManagerServiceId)));
Most of the time it returns what the ORM does, except for the
createQuery method, where it creates a new
This class implements the
ProxyQueryInterface, and stores an instance of
ElasticaProxyRepository, which is used to query the ElasticSearch index.
This is a real shortcut to explain the link between the admin class and the index, but if anyone is interested in more details, the code is open :)
Though I've already worked a little with Symfony and Sonata, I did only use them to do pretty basic stuff. Working on this bundle helped me to better understand some concepts such as the DIC, or to use the
debug_batcktrace() function !
I've also discovered the CompilerPass, a very powerful tool to override and create on demand services. But with great power comes... sometimes a bad headache.
It was also my first contribution to an open source project. I think it's just awesome. When I had a problem on a Sonata bundle, my PR has been merged in a few hours. And I had feedbacks on this bundle immediately after the repo is public!
I know that it is far for complete and/or finished (and/or totally functional?) but I had fun working on it and I hope it will be improved, used and helpful!