-
-
Notifications
You must be signed in to change notification settings - Fork 97
Versioning
We build this inside the phpcr-odm because versioning is a core feature of phpcr.
Versioning in PHPCR is described in (JCR 2.0, Chapter 15)[http://www.day.com/specs/jcr/2.0/15_Versioning.html]. Versioning is an optional feature, meaning not all PHPCR implementations support it.
There is 2 levels: simpleVersionable and (full) versionable. Simple versioning consists of a linear verison history and the checkin/checkout possibility. Checking in a node creates a new version and makes the node readonly. You need to check it out again to write to it (or just do a checkpoint to do both in one call). Full versioning additionally has non-linear versioning (which we won't provide any code for in phpcr-odm) and version labels. For each node, you can add labels to version, but one label string may only occur once per version history (meaning if you want to label another version, you need to remove the label from the first version before you add the label).
Version names are generated by PHPCR and can not be controlled by the client application. There is no concept of commit messages for PHPCR. We decided to not build something like that into the core of the ODM versioning system to avoid unnecessary overhead if the user does not need it. It is however easily doable with the allPredecessors parameters on a field
We don't want to replicate the complete Version API (VersionManager, VersionHistory and Version). For the full power, the user will need to get the underlying session and interact with the VersionManager directly. However, some glue methods for the most common operations will be provided.
- Create versions: checkpoint/checkin/checkout($document)
- Get list of old versions
- Get document from old version
- Restore old version
- Remove old version
- Support labels (full versioning only)
PHPCR-ODM must remain usable with repositories that don't support the Versioning capability, but versioning annotations and operations will not be supported.
@Document => versionable=none/simple/full
Nice-to-have:
- @Document => checkpoint=manual/auto to create a version on every change
- @Document => atLabel= to load a document at a specified label (i.e. "draft" or "stable"). this makes sense in combination with find with an explicit document name. its however a redundant method other way to make findVersionByLabel
- Field: @Version(label=) to hold another version of this document at a specific version. (yes, yet another redundant method)
- Field/Child/Parent...: allPredecessors=true
- Fields: @VersionName, @VersionCreated, @VersionLabels : the corresponding property of the version this documents represents
Change them to check on the versionable annotation of the document instead of just adding mix:versionable. Support simpleVersionable too.
/**
* Check in $document, that is create a new version and mark it as read only
*/
checkin($document)
/**
* Check out $document, make it writable
*/
checkout($document)
/**
* Do a checkin operation followed immediatly by a checkout operation.
*
* A new version is created and the writable document stays in checked out
* state
*/
public function checkpoint($document)
Contrary to translations, getting an old version does not change the document representing the current version. An old version can't be modified and can't be persisted. (Except with the special restoreVersion method.)
/**
* Get the version history information for a document
*
* @param $doc either a string denothing the path or the document itself
* @param $limit an optional limit to not get all versions
*
* @return array of <versionname> => array("labels" => <array of labels>, "created" => <DateTime>, "createdBy" => <username>)
*/
public function getLinearPredecessors($doc, $limit=-1)
/**
* Returns a read-only, detached document instance of the document at the
* specified path (id) with the specified version name.
*/
public function findVersionByName($path, $name)
/**
* Returns a read-only, detached document instance of the document at the
* specified path (id) with the specified version label.
*
* Only supported with documents that have versionable=full
*/
public function findVersionByLabel($path, $name)
/**
* Get the meta information about a specific version
*
* @param $doc either a string denoting the path or the document itself
* @param $name the version name (if not specified, the $doc must be a
* document and not a path. the version name of $doc is used)
*
* @return array with fields checkedin => <true/false>, name => <version name>,
* labels => <array with all labels of this version>, created => <DateTime>,
* createdBy => <username>
*/
public function getVersionInformation($doc, $name)
Current DocumentManager has a method restore($version, $document, $removeExisting)
.
We suggest renaming it to restoreVersion to make the naming consistent.
/**
* Restore the head of the history for $doc to the particular version
*
* @param $doc either a string denoting the path or the document itself
* @param $name the version name (if not specified, the $doc must be a
* document and not a path. the version name of $doc is used)
* @param $removeExisting whether to remove the existing head or add a new version
*/
public function restoreVersion($doc, $name=null, $removeExisting=false)
/**
* Delete the specified version to clean up the history.
*
* @param $doc either a string denoting the path or the document itself
* @param $name the version name (if not specified, the $doc must be a
* document and not a path. the version name of $doc is used)
*/
public function deleteVersion($doc, $name=null)
/**
*
* Only supported with documents that have versionable=full
*
* @param $label the label to remove
* @param $doc either a string denoting the path or the document itself
*/
removeLabel($label, $doc)
/**
* A version can have as many labels as you want, but per document version
* history, each label may only exist once.
*
* Only supported with documents that have versionable=full
*
* @param $label the label to add
* @param $doc either a string denoting the path or the document itself
* @param $name the version name (if not specified, the $doc must be a
* document and not a path. the version name of $doc is used)
* @param boolean $autoremove whether to remove the label from the version
* history or throw an error if it already exists
*/
addLabel($label, $doc, $name=null, $autoremove=true)