Cascade document versions

147 views
Skip to first unread message

Lars Janssen

unread,
Feb 15, 2013, 6:54:07 AM2/15/13
to symfony-...@googlegroups.com
Hi all,

I'm about to try my first implementation of document versions using the CMF with PHPCR-ODM and Jackrabbit.

A feature I'd like is for versions to "cascade", so if I create a new version of a document, a corresponding new version is made of all child documents. In fact it's a little more complex, because I will need the cascade to only apply to documents of certain types. For example, if I create a new version of a page, this should cascade to any child blocks, but not child pages.

The only mention I've been able to find of this concept is here:

   - "Children can be versioned by defining a PHCPR node type that specifies to cascade versioning."

My first question is, how do I go about defining such a node type as suggested?

Secondly, will this support selective cascading?

If not, I guess I will need to create my own mechanism that iterates through all the relevant children and creates new versions as needed.

Thanks for any thoughts or tips!

Lars.

David Buchmann

unread,
Feb 15, 2013, 7:34:25 AM2/15/13
to symfony-...@googlegroups.com, Lars Janssen
hi,

the node type is how its supposed to work. you should find information
on how to register your custom node type and how to make your document
use that type in the doc.

then you want do explicitly declare that your document may have a child
called additionalInfoBlock (or whichever node name your blocks have) and
define the onParentVersion attribute. cnd can look like this:

http://stackoverflow.com/questions/11509093/jcr-jackrabbit-xpath-expression-for-search-content-text-of-a-file-contained

and this post explains the options for onParentVersion quite well (at
the end of the article, just before the commnets start)

http://jtoee.com/jsr-170/compact-node-type-notation-in-a-nutshell/

i think you will need to also have the blocks use a node type that
versions all children, otherwise you will only version the container
block. if you use the wildcard "*" as child node name, you can use the
same phpcr node type for all types of blocks.

then you want to make sure that when loading an old version, you
actually get the old versions of the children as well - i am not 100%
sure that it all works as it should, i don't think we have any tests in
phpcr-odm about this.

if you run into problems, the best you can do would be to write failing
tests that demonstrate the problem and do a PR on phpcr-odm with them.
(well the very best would be of course if you can fix the problems as
well, but that might be rather involved :-)

cheers,david
> --
> You received this message because you are subscribed to the Google
> Groups "symfony-cmf-devs" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to symfony-cmf-de...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

--
Liip AG // Agile Web Development // T +41 26 422 25 11
CH-1700 Fribourg // PGP 0xA581808B // www.liip.ch

Lars Janssen

unread,
Feb 15, 2013, 8:14:07 AM2/15/13
to symfony-...@googlegroups.com, Lars Janssen, David Buchmann
Hi David,

Thanks for all the help & links. Sorry, still not quite clear on the first point, how to register a node type.

I'm not sure what you're saying in the first paragraph, are you saying there's some documentation on the PHPCR project? I've been searching in there a lot.

Are there any examples in PHP where a node type has been created? I'm struggling to visualise what a node type should provide. From the Stackoverflow link it looks like a combination of annotated classes and the custom_nodes.xml file; is that how it's done in PHP, and where should the XML file be defined or referenced?

Once I can get a simple example running I'll be happy to send test cases for any problems.

Thanks,

Lars.

David Buchmann

unread,
Feb 15, 2013, 9:15:21 AM2/15/13
to Lars Janssen, symfony-...@googlegroups.com
its indeed rather scattered over the documentation, sorry about that.

the command you want to run is

doctrine:phpcr:register-node-types

and you need to feed it something in the short cnd format, not the long
xml format (the internet has a mix of those, as jackrabbit 1 was using
xml and 2 the short form)
this is explained somewhat in the jackrabbit wiki:
http://jackrabbit.apache.org/node-type-notation.html

to use the node type in your document, declare it in the nodeType
attribute of the document:

http://docs.doctrine-project.org/projects/doctrine-phpcr-odm/en/latest/reference/basic-mapping.html#specify-a-node-type

for example, to map the build-in node type nt:file, this is:
https://github.com/doctrine/phpcr-odm/blob/master/lib/Doctrine/ODM/PHPCR/Document/File.php#L28

cheers,david
> > an email to symfony-cmf-de...@googlegroups.com <javascript:>.
> > For more options, visit https://groups.google.com/groups/opt_out
> <https://groups.google.com/groups/opt_out>.
> >
> >
>
> --
> Liip AG // Agile Web Development // T +41 26 422 25 11
> CH-1700 Fribourg // PGP 0xA581808B // www.liip.ch <http://www.liip.ch>

Lars Janssen

unread,
Feb 15, 2013, 10:21:22 AM2/15/13
to symfony-...@googlegroups.com, Lars Janssen, David Buchmann
No need to be sorry! It's all coming together now and I've registered a node type that extends nt:file... next steps will be to specify all the fields I need for my class (otherwise I get an error that the node type definition does not allow the property name '...').

Thanks again. :)

Lars Janssen

unread,
Feb 19, 2013, 5:20:09 AM2/19/13
to symfony-...@googlegroups.com, Lars Janssen, David Buchmann
I've noticed a possible bug (but probable user error :D) when trying to get all the versions of a document.

It seems that once I call $manager->getAllLinearVersions(), the result doesn't change, even if there are further checkpoints made in the same PHP script:


    /** TestDocument class **/

    use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCRODM;
    use Doctrine\ODM\PHPCR\Document\Generic;
    
    /**
     * @PHPCRODM\Document(referenceable=true, versionable="full")
     */
    class TestDocument extends Generic
    {
    }


    /** Code from my test command **/

    // Setup
    $manager = $this->getApplication()->getKernel()->getContainer()->get('doctrine_phpcr.odm.document_manager');
    $rootNode = $manager->find(null, '/');

    // Start with a blank slate each time
    $document = $manager->find(null, '/test');
    if (null !== $document) {
        $manager->remove($document);
        $manager->flush();
    }

    // Create a test document
    $document = new TestDocument();
    $document->setNodename('test');
    $document->setParent($rootNode);
    $manager->persist($document);
    $manager->flush();

    // Create a version
    $manager->checkpoint($document);
    $manager->flush();

    // Comment me out to see the result of the var_dump below change
    // Gives "2" as expected
    var_dump(count($manager->getAllLinearVersions($document)));

    // Create a version
    $manager->checkpoint($document);
    $manager->flush();

    // This should give 3, but gives 2 if the above call to getAllLinearVersions runs
    var_dump(count($manager->getAllLinearVersions($document)));

    // Try to reset everything
    $manager->clear();
    $document = $manager->find(null, '/test');

    // This is still stuck on the result of the first call :(
    var_dump(count($manager->getAllLinearVersions($document)));


Is there anything I can do to 'reset' the getAllLinearVersions() result, or is this a bug?

Thanks,

Lars.

David Buchmann

unread,
Feb 24, 2013, 10:32:26 AM2/24/13
to Lars Janssen, symfony-...@googlegroups.com
sorry i somehow missed this email.

i don't see why that fails, as the odm does not cache any of the version
history information (at all, might be good to actually cache it). from a
quick glance through jackalope however, i fear we might have a caching
issue in jackalope.

the flush should not be needed, as checkpoint is executed immediately.

* if you only get the linear versions at the very end, do you get 3 or
2? is there a caching problem somewhere, or is the version not created?
* can you try to do the same with directly PHPCR and see if that works
or fails? [1] i guess you work with jackalope-jackrabbit?

[1]
https://github.com/phpcr/phpcr-api-tests/blob/master/tests/15_Versioning/VersionHistoryTest.php

it would be very helpful to get a phpcr-api-test that fails and demos
the problem you found.

cheers,david
> <http://www.liip.ch> <http://www.liip.ch>

Lars Janssen

unread,
Feb 26, 2013, 6:23:20 AM2/26/13
to symfony-...@googlegroups.com, Lars Janssen, David Buchmann
Hi David,

No worries about replying, I was at the PHP London conference anyway. :)

Yes, I'm using Jackalope-Jackrabbit (switched over from the MySQL-based implementation recently). If I only usse getAllLinearVersions() at the very end (commenting out all previous calls), then the count is 3 as expected.

I must admit I'm not sure about the distinction between getAllVersions() and getAllLinearVersions(), however I'm guessing it's something to do with branching off from older versions. In my simple use cases, should getAllVersions() and getAllLinearVersions() always be the same?

Anyway, from all my digging around it seems that getAllVersions() works as I expect, but getAllLinearVersions() is the one that gets 'stuck'. I've just submitted a PR: https://github.com/phpcr/phpcr-api-tests/pull/84 to show this.

My previous post in this topic uses PHPCR-ODM, whereas the examples in the test PHPCR directly. Am I right in thinking the ODM doesn't have getAllVersions()?

BTW, do you need any more feedback on https://github.com/doctrine/phpcr-odm/pull/247 ?

Thanks,

Lars.

David Buchmann

unread,
Feb 26, 2013, 6:51:55 AM2/26/13
to Lars Janssen, symfony-...@googlegroups.com
hi lars,

thanks for the test showing the problem. i think it should not be too
hard to fix, i will try to do it unless you want to have a go at it?

> I must admit I'm not sure about the distinction between getAllVersions()
> and getAllLinearVersions(), however I'm guessing it's something to do
> with branching off from older versions. In my simple use cases, should
> getAllVersions() and getAllLinearVersions() always be the same?

PHPCR / JCR define simple and full versioning. full versioning allows to
create branches, while simple is just a plain list of versions (hence
"linear"). in jackalope we only implemented linear versioning i think,
or at least creating branches is not supported.

> Anyway, from all my digging around it seems that getAllVersions() works
> as I expect, but getAllLinearVersions() is the one that gets 'stuck'.
> I've just submitted a
> PR: https://github.com/phpcr/phpcr-api-tests/pull/84 to show this.

that would be suprising to me if getAllVersions would work correctly. it
caches as well.

> My previous post in this topic uses PHPCR-ODM, whereas the examples in
> the test PHPCR directly. Am I right in thinking the ODM doesn't have
> getAllVersions()?

yeah i think we did not do getAllVersions as its not useful if you can't
create branches anyways.

> BTW, do you need any more feedback
> on https://github.com/doctrine/phpcr-odm/pull/247 ?

i think its clear now, but needs somebody to find time to work on it :-/

cheers,david

Lars Janssen

unread,
Feb 26, 2013, 7:09:00 AM2/26/13
to symfony-...@googlegroups.com, Lars Janssen
I'll have a go at fixing the Jackalope issue (see comments on the PR), but feel free to step in if it doesn't work out. ;)

Cascading versions is probably beyond me, but I'll have a look anyway and see if I can understand what's going on...

Lars Janssen

unread,
Mar 11, 2013, 6:33:46 AM3/11/13
to symfony-...@googlegroups.com, Lars Janssen
I've posted about this issue on the Jackrabbit list (http://www.mail-archive.com/us...@jackrabbit.apache.org/msg19201.html) but unfortunately haven't managed to make a breakthrough with automatic version cascading.

I'm wondering if anyone else has tried this or had any experience? I'm probably going to handle this in my application for now; that is, when making a version of a page, iterate through all the child blocks and make versions of these too. However, it would be good to come back to this in future and let PHPCR/Jackrabbit take care of this...
Reply all
Reply to author
Forward
0 new messages