Tree operations

dbu edited this page Dec 13, 2011 · 4 revisions

We use the node path as the primary id of the entities. There is no NodeInterface::setName operation in PHPCR, meaning you can not just rename nodes (and thus change the paths of all subnodes). The only way to change the name of a node (xml element name) is the move operation. After the move, all children of the moved node need their path property updated.

For now, you will need to access the underlying PHPCR session to do a move, and then reset the document manager as it will not understand the move. We could expose the move() operation in the phpcr-odm and proxy this to PHPCR. After the move, doctrine would have to go over every currently loaded entity and update the path from the PHPCR nodes. Nodes requested after the move are already at the new path, of course.

To make things a bit more fun, there are two variants: Session method changes only for this transaction, persisted only on Session::save. Workspace offers a move as well, which is persisted immediately. I think we should only use the Session operation.

SessionInterface::move($srcAbsPath, $destAbsPath);
WorkspaceInterface::move($srcAbsPath, $destAbsPath);

One more thing on removing entities: In PHPCR, there is no way of removing a node and keeping the children. (Which makes sense, they would become orphans). If you have a node containing another node and remove the parent, its going to remove the children. This would even be true if you do not explicitly declare the containment to phpcr-odm but just add nodes beneath the node you remove.

NodeInterface::remove() removes the item *and its subgraph*

There are copy and clone methods, but i think we do not need to handle them in doctrine.

//new uuids, mostly to copy inside a workspace
SessionInterface::copy($srcAbsPath, $destAbsPath, $srcWorkspace = NULL);
//keep uuids, to copy between workspaces
SessionInterface::cloneFrom($srcWorkspace, $srcAbsPath, $destAbsPath, $removeExisting);

and with immediate dispatch to backend

WorkspaceInterface::copy($srcAbsPath, $destAbsPath, $srcWorkspace = NULL);
WorkspaceInterface::cloneFrom($srcWorkspace, $srcAbsPath, $destAbsPath, $removeExisting);