Hi all,
For the past 4/5 days I have been working on a POC for a Doctrine ORM
"Content Repository" - that is a wrapper that allows you to access
Doctrine ORM Entities as if they were stored in a tree:
https://github.com/dantleech/doctrine-cr
The motivation behind this is to :
- Provide less of a barrier to people "wanting to add CMS functionality
to their existing apps".
- Use the CMF tree-like components (menu, tree browser) with the
Doctrine ORM.
- Allow easier integration with third-party tools (e.g. integration with
Sylius / Sonata would require a lot less specialization).
The current approach is quite simple:
- Decorate the EntityManager (currently adding a `move` method and
dispatching a few events).
- Intercept find() and perform a look up in a "path" table to determine
the class FQN of the target entity, forward to real EM.
- All "managed" objects must (currently) use a UUID (automatically
assigned) as their primary key - this primary key is the same as that
of the row entries in the path table.
- As with Jackalope-Doctrine-Dbal there is an operation queue which is
flushed when the EM is flushed, so we do not get any "order of
operation" issues as with the PHPCR-ODM.
It currently "works"[1] and supports:
- Mapping "parent", "children", "path", "depth", etc. via. an XML
driver.
- Persisting, Updating, Removal.
- Moving: implicit (setting the parent) and explicit
($em->move($srcPath, $destPath))
Some ideas for the future:
- Provide a PHPCR API - browse/modify the "Content Repository" with the PHPCR
Shell (using restrictive node types based on the Class FQNs).
- Support Mongo DB etc - provide something even more analagous to
PHPCR-ODM.
- Support for hierarchical queries in the query builder.
- Support FK relationship between path table and target "entity" table
(one column per relationship).
As for performance, I did some benchmarks comparing against the
PHPCR-ODM - I dare to say that they can be improved:
suite: 1339ff93fe7abf1496b925d952b4b7551761c006, date: 2016-05-05, stime: 22:45:19
+------------------+-------------+---------------+-------------+----------+
| Benchmark | Create tree | find() single | Remove tree | Move |
+------------------+-------------+---------------+-------------+----------+
| PhpcrOdmBench | 128.594ms | 26.757ms | 25.773ms | 27.857ms |
| DoctrineCrBench | 167.484ms | 21.900ms | 38.961ms | 18.935ms |
| DoctrineOrmBench | | 7.770ms | | |
+------------------+-------------+---------------+-------------+----------+
Note: that Doctrine ORM is only hydrating a single field compared to
multiple fields for the other two, which may account for its drastic
advantage, also DoctrineCr uses 2 paths to move, where the PhpcrOdm
requires an Entity + a path.
So, there it is - its just an idea, next I will try and write a bundle
and integrate it with f.e. the ResourceRest component so that it can use
the TreeBrowser.
And if this proves to be a success it should find a place to live
(guessing Doctrine would be the best place).
What do you think?
Dan
[1] "works": It has been written quickly and it is lacking much test
coverage.