mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Merge pull request #5539 from sminnee/sitetree-docblock-improvements
PHPDoc improvements for Hierarchy and Versioned
This commit is contained in:
commit
11f73de330
@ -1,9 +1,14 @@
|
||||
<?php
|
||||
/**
|
||||
* DataObjects that use the Hierarchy extension can be be organised as a hierarchy, with children and parents.
|
||||
* The most obvious example of this is SiteTree.
|
||||
* DataObjects that use the Hierarchy extension can be be organised as a hierarchy, with children and parents. The most
|
||||
* obvious example of this is SiteTree.
|
||||
*
|
||||
* @package framework
|
||||
* @subpackage model
|
||||
*
|
||||
* @property int ParentID
|
||||
* @property DataObject owner
|
||||
* @method DataObject Parent
|
||||
*/
|
||||
class Hierarchy extends DataExtension {
|
||||
|
||||
@ -11,30 +16,28 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
protected $markingFilter;
|
||||
|
||||
/**
|
||||
* @var Int
|
||||
*/
|
||||
/** @var int */
|
||||
protected $_cache_numChildren;
|
||||
|
||||
/**
|
||||
* The lower bounds for the amount of nodes to mark. If set, the logic will expand nodes until it reaches at least
|
||||
* this number, and then stops. Root nodes will always show regardless of this settting. Further nodes can be
|
||||
* lazy-loaded via ajax. This isn't a hard limit. Example: On a value of 10, with 20 root nodes, each having 30
|
||||
* children, the actual node count will be 50 (all root nodes plus first expanded child).
|
||||
*
|
||||
* @config
|
||||
* @var integer The lower bounds for the amount of nodes to mark. If set, the logic will expand
|
||||
* nodes until it reaches at least this number, and then stops. Root nodes will always
|
||||
* show regardless of this settting. Further nodes can be lazy-loaded via ajax.
|
||||
* This isn't a hard limit. Example: On a value of 10, with 20 root nodes, each having
|
||||
* 30 children, the actual node count will be 50 (all root nodes plus first expanded child).
|
||||
* @var int
|
||||
*/
|
||||
private static $node_threshold_total = 50;
|
||||
|
||||
/**
|
||||
* Limit on the maximum children a specific node can display. Serves as a hard limit to avoid exceeding available
|
||||
* server resources in generating the tree, and browser resources in rendering it. Nodes with children exceeding
|
||||
* this value typically won't display any children, although this is configurable through the $nodeCountCallback
|
||||
* parameter in {@link getChildrenAsUL()}. "Root" nodes will always show all children, regardless of this setting.
|
||||
*
|
||||
* @config
|
||||
* @var integer Limit on the maximum children a specific node can display.
|
||||
* Serves as a hard limit to avoid exceeding available server resources
|
||||
* in generating the tree, and browser resources in rendering it.
|
||||
* Nodes with children exceeding this value typically won't display
|
||||
* any children, although this is configurable through the $nodeCountCallback
|
||||
* parameter in {@link getChildrenAsUL()}. "Root" nodes will always show
|
||||
* all children, regardless of this setting.
|
||||
* @var int
|
||||
*/
|
||||
private static $node_threshold_leaf = 250;
|
||||
|
||||
@ -46,6 +49,8 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Validate the owner object - check for existence of infinite loops.
|
||||
*
|
||||
* @param ValidationResult $validationResult
|
||||
*/
|
||||
public function validate(ValidationResult $validationResult) {
|
||||
// The object is new, won't be looping.
|
||||
@ -78,19 +83,21 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the children of this DataObject as an XHTML UL. This will be called recursively on each child,
|
||||
* so if they have children they will be displayed as a UL inside a LI.
|
||||
* @param string $attributes Attributes to add to the UL.
|
||||
* @param string|callable $titleEval PHP code to evaluate to start each child - this should include '<li>'
|
||||
* @param string $extraArg Extra arguments that will be passed on to children, for if they overload this function.
|
||||
* @param boolean $limitToMarked Display only marked children.
|
||||
* @param string $childrenMethod The name of the method used to get children from each object
|
||||
* @param boolean $rootCall Set to true for this first call, and then to false for calls inside the recursion. You
|
||||
* should not change this.
|
||||
* @param int $nodeCountThreshold See {@link self::$node_threshold_total}
|
||||
* @param callable $nodeCountCallback Called with the node count, which gives the callback an opportunity
|
||||
* to intercept the query. Useful e.g. to avoid excessive children listings
|
||||
* (Arguments: $parent, $numChildren)
|
||||
* Returns the children of this DataObject as an XHTML UL. This will be called recursively on each child, so if they
|
||||
* have children they will be displayed as a UL inside a LI.
|
||||
*
|
||||
* @param string $attributes Attributes to add to the UL
|
||||
* @param string|callable $titleEval PHP code to evaluate to start each child - this should include '<li>'
|
||||
* @param string $extraArg Extra arguments that will be passed on to children, for if they
|
||||
* overload this function
|
||||
* @param bool $limitToMarked Display only marked children
|
||||
* @param string $childrenMethod The name of the method used to get children from each object
|
||||
* @param bool $rootCall Set to true for this first call, and then to false for calls inside
|
||||
* the recursion. You should not change this.
|
||||
* @param int $nodeCountThreshold See {@link self::$node_threshold_total}
|
||||
* @param callable $nodeCountCallback Called with the node count, which gives the callback an opportunity to
|
||||
* intercept the query. Useful e.g. to avoid excessive children listings
|
||||
* (Arguments: $parent, $numChildren)
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -175,11 +182,12 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Mark a segment of the tree, by calling mark().
|
||||
* The method performs a breadth-first traversal until the number of nodes is more than minCount.
|
||||
* This is used to get a limited number of tree nodes to show in the CMS initially.
|
||||
*
|
||||
* This method returns the number of nodes marked. After this method is called other methods
|
||||
* can check isExpanded() and isMarked() on individual nodes.
|
||||
* The method performs a breadth-first traversal until the number of nodes is more than minCount. This is used to
|
||||
* get a limited number of tree nodes to show in the CMS initially.
|
||||
*
|
||||
* This method returns the number of nodes marked. After this method is called other methods can check
|
||||
* {@link isExpanded()} and {@link isMarked()} on individual nodes.
|
||||
*
|
||||
* @param int $nodeCountThreshold See {@link getChildrenAsUL()}
|
||||
* @return int The actual number of nodes marked.
|
||||
@ -205,9 +213,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the marking to only those object with $node->$parameterName = $parameterValue
|
||||
* @param string $parameterName The parameter on each node to check when marking.
|
||||
* @param mixed $parameterValue The value the parameter must be to be marked.
|
||||
* Filter the marking to only those object with $node->$parameterName == $parameterValue
|
||||
*
|
||||
* @param string $parameterName The parameter on each node to check when marking.
|
||||
* @param mixed $parameterValue The value the parameter must be to be marked.
|
||||
*/
|
||||
public function setMarkingFilter($parameterName, $parameterValue) {
|
||||
$this->markingFilter = array(
|
||||
@ -217,9 +226,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the marking to only those where the function returns true.
|
||||
* The node in question will be passed to the function.
|
||||
* @param string $funcName The function name.
|
||||
* Filter the marking to only those where the function returns true. The node in question will be passed to the
|
||||
* function.
|
||||
*
|
||||
* @param string $funcName The name of the function to call
|
||||
*/
|
||||
public function setMarkingFilterFunction($funcName) {
|
||||
$this->markingFilter = array(
|
||||
@ -229,8 +239,9 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Returns true if the marking filter matches on the given node.
|
||||
* @param DataObject $node Node to check.
|
||||
* @return boolean
|
||||
*
|
||||
* @param DataObject $node Node to check
|
||||
* @return bool
|
||||
*/
|
||||
public function markingFilterMatches($node) {
|
||||
if(!$this->markingFilter) {
|
||||
@ -257,7 +268,11 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Mark all children of the given node that match the marking filter.
|
||||
* @param DataObject $node Parent node.
|
||||
*
|
||||
* @param DataObject $node Parent node
|
||||
* @param mixed $context
|
||||
* @param string $childrenMethod The name of the instance method to call to get the object's list of children
|
||||
* @param string $numChildrenMethod The name of the instance method to call to count the object's children
|
||||
* @return DataList
|
||||
*/
|
||||
public function markChildren($node, $context = null, $childrenMethod = "AllChildrenIncludingDeleted",
|
||||
@ -288,8 +303,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure marked nodes that have children are also marked expanded.
|
||||
* Call this after marking but before iterating over the tree.
|
||||
* Ensure marked nodes that have children are also marked expanded. Call this after marking but before iterating
|
||||
* over the tree.
|
||||
*
|
||||
* @param string $numChildrenMethod The name of the instance method to call to count the object's children
|
||||
*/
|
||||
protected function markingFinished($numChildrenMethod = "numChildren") {
|
||||
// Mark childless nodes as expanded.
|
||||
@ -303,9 +320,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return CSS classes of 'unexpanded', 'closed', both, or neither, as well as a
|
||||
* 'jstree-*' state depending on the marking of this DataObject.
|
||||
* Return CSS classes of 'unexpanded', 'closed', both, or neither, as well as a 'jstree-*' state depending on the
|
||||
* marking of this DataObject.
|
||||
*
|
||||
* @param string $numChildrenMethod The name of the instance method to call to count the object's children
|
||||
* @return string
|
||||
*/
|
||||
public function markingClasses($numChildrenMethod="numChildren") {
|
||||
@ -327,8 +345,10 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Mark the children of the DataObject with the given ID.
|
||||
* @param int $id ID of parent node.
|
||||
* @param boolean $open If this is true, mark the parent node as opened.
|
||||
*
|
||||
* @param int $id ID of parent node
|
||||
* @param bool $open If this is true, mark the parent node as opened
|
||||
* @return bool
|
||||
*/
|
||||
public function markById($id, $open = false) {
|
||||
if(isset($this->markedNodes[$id])) {
|
||||
@ -344,6 +364,7 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Expose the given object in the tree, by marking this page and all it ancestors.
|
||||
*
|
||||
* @param DataObject $childObj
|
||||
*/
|
||||
public function markToExpose($childObj) {
|
||||
@ -356,7 +377,9 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the IDs of all the marked nodes
|
||||
* Return the IDs of all the marked nodes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function markedNodeIDs() {
|
||||
return array_keys($this->markedNodes);
|
||||
@ -364,7 +387,8 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Return an array of this page and its ancestors, ordered item -> root.
|
||||
* @return array
|
||||
*
|
||||
* @return SiteTree[]
|
||||
*/
|
||||
public function parentStack() {
|
||||
$p = $this->owner;
|
||||
@ -378,20 +402,20 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this DataObject is marked.
|
||||
* @var boolean
|
||||
* Cache of DataObjects' marked statuses: [ClassName][ID] = bool
|
||||
* @var array
|
||||
*/
|
||||
protected static $marked = array();
|
||||
|
||||
/**
|
||||
* True if this DataObject is expanded.
|
||||
* @var boolean
|
||||
* Cache of DataObjects' expanded statuses: [ClassName][ID] = bool
|
||||
* @var array
|
||||
*/
|
||||
protected static $expanded = array();
|
||||
|
||||
/**
|
||||
* True if this DataObject is opened.
|
||||
* @var boolean
|
||||
* Cache of DataObjects' opened statuses: [ClassName][ID] = bool
|
||||
* @var array
|
||||
*/
|
||||
protected static $treeOpened = array();
|
||||
|
||||
@ -430,7 +454,8 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Check if this DataObject is marked.
|
||||
* @return boolean
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMarked() {
|
||||
$baseClass = ClassInfo::baseDataClass($this->owner->class);
|
||||
@ -440,7 +465,8 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Check if this DataObject is expanded.
|
||||
* @return boolean
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isExpanded() {
|
||||
$baseClass = ClassInfo::baseDataClass($this->owner->class);
|
||||
@ -450,6 +476,8 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Check if this DataObject's tree is opened.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isTreeOpened() {
|
||||
$baseClass = ClassInfo::baseDataClass($this->owner->class);
|
||||
@ -459,7 +487,8 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Get a list of this DataObject's and all it's descendants IDs.
|
||||
* @return int
|
||||
*
|
||||
* @return int[]
|
||||
*/
|
||||
public function getDescendantIDList() {
|
||||
$idList = array();
|
||||
@ -468,8 +497,9 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of this DataObject's and all it's descendants ID, and put it in $idList.
|
||||
* @var array $idList Array to put results in.
|
||||
* Get a list of this DataObject's and all it's descendants ID, and put them in $idList.
|
||||
*
|
||||
* @param array $idList Array to put results in.
|
||||
*/
|
||||
public function loadDescendantIDListInto(&$idList) {
|
||||
if($children = $this->AllChildren()) {
|
||||
@ -488,7 +518,8 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Get the children for this DataObject.
|
||||
* @return ArrayList
|
||||
*
|
||||
* @return DataList
|
||||
*/
|
||||
public function Children() {
|
||||
if(!(isset($this->_cache_children) && $this->_cache_children)) {
|
||||
@ -506,7 +537,8 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Return all children, including those 'not in menus'.
|
||||
* @return SS_List
|
||||
*
|
||||
* @return DataList
|
||||
*/
|
||||
public function AllChildren() {
|
||||
return $this->owner->stageChildren(true);
|
||||
@ -514,11 +546,13 @@ class Hierarchy extends DataExtension {
|
||||
|
||||
/**
|
||||
* Return all children, including those that have been deleted but are still in live.
|
||||
* Deleted children will be marked as "DeletedFromStage"
|
||||
* Added children will be marked as "AddedToStage"
|
||||
* Modified children will be marked as "ModifiedOnStage"
|
||||
* Everything else has "SameOnStage" set, as an indicator that this information has been looked up.
|
||||
* @return SS_List
|
||||
* - Deleted children will be marked as "DeletedFromStage"
|
||||
* - Added children will be marked as "AddedToStage"
|
||||
* - Modified children will be marked as "ModifiedOnStage"
|
||||
* - Everything else has "SameOnStage" set, as an indicator that this information has been looked up.
|
||||
*
|
||||
* @param mixed $context
|
||||
* @return ArrayList
|
||||
*/
|
||||
public function AllChildrenIncludingDeleted($context = null) {
|
||||
return $this->doAllChildrenIncludingDeleted($context);
|
||||
@ -527,8 +561,8 @@ class Hierarchy extends DataExtension {
|
||||
/**
|
||||
* @see AllChildrenIncludingDeleted
|
||||
*
|
||||
* @param unknown_type $context
|
||||
* @return SS_List
|
||||
* @param mixed $context
|
||||
* @return ArrayList
|
||||
*/
|
||||
public function doAllChildrenIncludingDeleted($context = null) {
|
||||
if(!$this->owner) user_error('Hierarchy::doAllChildrenIncludingDeleted() called without $this->owner');
|
||||
@ -560,8 +594,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the children that this page had, including pages that were deleted
|
||||
* from both stage & live.
|
||||
* Return all the children that this page had, including pages that were deleted from both stage & live.
|
||||
*
|
||||
* @return DataList
|
||||
* @throws Exception
|
||||
*/
|
||||
public function AllHistoricalChildren() {
|
||||
if(!$this->owner->hasExtension('Versioned')) {
|
||||
@ -574,7 +610,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of children that this page ever had, including pages that were deleted
|
||||
* Return the number of children that this page ever had, including pages that were deleted.
|
||||
*
|
||||
* @return int
|
||||
* @throws Exception
|
||||
*/
|
||||
public function numHistoricalChildren() {
|
||||
if(!$this->owner->hasExtension('Versioned')) {
|
||||
@ -586,11 +625,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of direct children.
|
||||
* By default, values are cached after the first invocation.
|
||||
* Can be augumented by {@link augmentNumChildrenCountQuery()}.
|
||||
* Return the number of direct children. By default, values are cached after the first invocation. Can be
|
||||
* augumented by {@link augmentNumChildrenCountQuery()}.
|
||||
*
|
||||
* @param Boolean $cache
|
||||
* @param bool $cache Whether to retrieve values from cache
|
||||
* @return int
|
||||
*/
|
||||
public function numChildren($cache = true) {
|
||||
@ -606,10 +644,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return children from the stage site
|
||||
* Return children in the stage site.
|
||||
*
|
||||
* @param showAll Inlcude all of the elements, even those not shown in the menus.
|
||||
* (only applicable when extension is applied to {@link SiteTree}).
|
||||
* @param bool $showAll Include all of the elements, even those not shown in the menus. Only applicable when
|
||||
* extension is applied to {@link SiteTree}.
|
||||
* @return DataList
|
||||
*/
|
||||
public function stageChildren($showAll = false) {
|
||||
@ -625,12 +663,13 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return children from the live site, if it exists.
|
||||
* Return children in the live site, if it exists.
|
||||
*
|
||||
* @param boolean $showAll Include all of the elements, even those not shown in the menus.
|
||||
* (only applicable when extension is applied to {@link SiteTree}).
|
||||
* @param boolean $onlyDeletedFromStage Only return items that have been deleted from stage
|
||||
* @return SS_List
|
||||
* @param bool $showAll Include all of the elements, even those not shown in the menus. Only
|
||||
* applicable when extension is applied to {@link SiteTree}.
|
||||
* @param bool $onlyDeletedFromStage Only return items that have been deleted from stage
|
||||
* @return DataList
|
||||
* @throws Exception
|
||||
*/
|
||||
public function liveChildren($showAll = false, $onlyDeletedFromStage = false) {
|
||||
if(!$this->owner->hasExtension('Versioned')) {
|
||||
@ -652,7 +691,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent of this class.
|
||||
* Get this object's parent, optionally filtered by an SQL clause. If the clause doesn't match the parent, nothing
|
||||
* is returned.
|
||||
*
|
||||
* @param string $filter
|
||||
* @return DataObject
|
||||
*/
|
||||
public function getParent($filter = null) {
|
||||
@ -669,7 +711,7 @@ class Hierarchy extends DataExtension {
|
||||
/**
|
||||
* Return all the parents of this class in a set ordered from the lowest to highest parent.
|
||||
*
|
||||
* @return SS_List
|
||||
* @return ArrayList
|
||||
*/
|
||||
public function getAncestors() {
|
||||
$ancestors = new ArrayList();
|
||||
@ -683,11 +725,10 @@ class Hierarchy extends DataExtension {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable, flattened representation of the path to the object,
|
||||
* using its {@link Title()} attribute.
|
||||
* Returns a human-readable, flattened representation of the path to the object, using its {@link Title} attribute.
|
||||
*
|
||||
* @param String
|
||||
* @return String
|
||||
* @param string $separator
|
||||
* @return string
|
||||
*/
|
||||
public function getBreadcrumbs($separator = ' » ') {
|
||||
$crumbs = array();
|
||||
@ -702,22 +743,25 @@ class Hierarchy extends DataExtension {
|
||||
* then search the parents.
|
||||
*
|
||||
* @todo Write!
|
||||
*
|
||||
* @param string $className Class name of the node to find
|
||||
* @param DataObject $afterNode Used for recursive calls to this function
|
||||
* @return DataObject
|
||||
*/
|
||||
public function naturalPrev( $className, $afterNode = null ) {
|
||||
public function naturalPrev($className, $afterNode = null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next node in the tree of the type. If there is no instance of the className descended from this node,
|
||||
* then search the parents.
|
||||
* @param string $className Class name of the node to find.
|
||||
* @param string|int $root ID/ClassName of the node to limit the search to
|
||||
* @param DataObject afterNode Used for recursive calls to this function
|
||||
* @param string $className Class name of the node to find.
|
||||
* @param string|int $root ID/ClassName of the node to limit the search to
|
||||
* @param DataObject $afterNode Used for recursive calls to this function
|
||||
* @return DataObject
|
||||
*/
|
||||
public function naturalNext( $className = null, $root = 0, $afterNode = null ) {
|
||||
// If this node is not the node we are searching from, then we can possibly return this
|
||||
// node as a solution
|
||||
public function naturalNext($className = null, $root = 0, $afterNode = null ) {
|
||||
// If this node is not the node we are searching from, then we can possibly return this node as a solution
|
||||
if($afterNode && $afterNode->ID != $this->owner->ID) {
|
||||
if(!$className || ($className && $this->owner->class == $className)) {
|
||||
return $this->owner;
|
||||
@ -761,6 +805,14 @@ class Hierarchy extends DataExtension {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush all Hierarchy caches:
|
||||
* - Children (instance)
|
||||
* - NumChildren (instance)
|
||||
* - Marked (global)
|
||||
* - Expanded (global)
|
||||
* - TreeOpened (global)
|
||||
*/
|
||||
public function flushCache() {
|
||||
$this->_cache_children = null;
|
||||
$this->_cache_numChildren = null;
|
||||
@ -769,6 +821,12 @@ class Hierarchy extends DataExtension {
|
||||
self::$treeOpened = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset global Hierarchy caches:
|
||||
* - Marked
|
||||
* - Expanded
|
||||
* - TreeOpened
|
||||
*/
|
||||
public static function reset() {
|
||||
self::$marked = array();
|
||||
self::$expanded = array();
|
||||
|
@ -1,16 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* The Versioned extension allows your DataObjects to have several versions,
|
||||
* allowing you to rollback changes and view history. An example of this is
|
||||
* the pages used in the CMS.
|
||||
* The Versioned extension allows your DataObjects to have several versions, allowing you to rollback changes and view
|
||||
* history. An example of this is the pages used in the CMS.
|
||||
*
|
||||
* @property int $Version
|
||||
*
|
||||
* @package framework
|
||||
* @subpackage model
|
||||
*
|
||||
* @property DataObject owner
|
||||
*
|
||||
* @property int RecordID
|
||||
* @property int Version
|
||||
* @property bool WasPublished
|
||||
* @property int AuthorID
|
||||
* @property int PublisherID
|
||||
*/
|
||||
class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
|
||||
/**
|
||||
* An array of possible stages.
|
||||
* @var array
|
||||
@ -35,40 +43,33 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
const DEFAULT_MODE = 'Stage.Live';
|
||||
|
||||
/**
|
||||
* A version that a DataObject should be when it is 'migrating',
|
||||
* that is, when it is in the process of moving from one stage to another.
|
||||
* A version that a DataObject should be when it is 'migrating', that is, when it is in the process of moving from
|
||||
* one stage to another.
|
||||
* @var string
|
||||
*/
|
||||
public $migratingVersion;
|
||||
|
||||
/**
|
||||
* A cache used by get_versionnumber_by_stage().
|
||||
* Clear through {@link flushCache()}.
|
||||
*
|
||||
* A cache used by get_versionnumber_by_stage(). Clear through {@link flushCache()}.
|
||||
* @var array
|
||||
*/
|
||||
protected static $cache_versionnumber;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
/** @var string */
|
||||
protected static $reading_mode = null;
|
||||
|
||||
/**
|
||||
* @var Boolean Flag which is temporarily changed during the write() process
|
||||
* to influence augmentWrite() behaviour. If set to TRUE, no new version will be created
|
||||
* for the following write. Needs to be public as other classes introspect this state
|
||||
* during the write process in order to adapt to this versioning behaviour.
|
||||
* Flag which is temporarily changed during the write() process to influence augmentWrite() behaviour. If set to
|
||||
* true, no new version will be created for the following write. Needs to be public as other classes introspect this
|
||||
* state during the write process in order to adapt to this versioning behaviour.
|
||||
* @var bool
|
||||
*/
|
||||
public $_nextWriteWithoutVersion = false;
|
||||
|
||||
/**
|
||||
* Additional database columns for the new
|
||||
* "_versions" table. Used in {@link augmentDatabase()}
|
||||
* and all Versioned calls extending or creating
|
||||
* SELECT statements.
|
||||
*
|
||||
* @var array $db_for_versions_table
|
||||
* Additional database columns for the new "_versions" table. Used in {@link augmentDatabase()} and all Versioned
|
||||
* calls extending or creating SELECT statements.
|
||||
* @var array
|
||||
*/
|
||||
private static $db_for_versions_table = array(
|
||||
"RecordID" => "Int",
|
||||
@ -78,33 +79,25 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
"PublisherID" => "Int"
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $db = array(
|
||||
'Version' => 'Int'
|
||||
);
|
||||
|
||||
/**
|
||||
* Used to enable or disable the prepopulation of the version number cache.
|
||||
* Defaults to true.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
* Used to enable or disable the prepopulation of the version number cache. Defaults to true.
|
||||
* @var bool
|
||||
*/
|
||||
private static $prepopulate_versionnumber_cache = true;
|
||||
|
||||
/**
|
||||
* Keep track of the archive tables that have been created.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $archive_tables = array();
|
||||
|
||||
/**
|
||||
* Additional database indexes for the new
|
||||
* "_versions" table. Used in {@link augmentDatabase()}.
|
||||
*
|
||||
* @var array $indexes_for_versions_table
|
||||
* Additional database indexes for the new "_versions" table. Used in {@link augmentDatabase()}.
|
||||
* @var array
|
||||
*/
|
||||
private static $indexes_for_versions_table = array(
|
||||
'RecordID_Version' => '("RecordID","Version")',
|
||||
@ -116,10 +109,9 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
|
||||
|
||||
/**
|
||||
* An array of DataObject extensions that may require versioning for extra tables
|
||||
* The array value is a set of suffixes to form these table names, assuming a preceding '_'.
|
||||
* E.g. if Extension1 creates a new table 'Class_suffix1'
|
||||
* and Extension2 the tables 'Class_suffix2' and 'Class_suffix3':
|
||||
* An array of DataObject extensions that may require versioning for extra tables. The array value is a set of
|
||||
* suffixes to form these table names, assuming a preceding '_'. E.g. if Extension1 creates a new table
|
||||
* 'Class_suffix1' and Extension2 the tables 'Class_suffix2' and 'Class_suffix3':
|
||||
*
|
||||
* $versionableExtensions = array(
|
||||
* 'Extension1' => 'suffix1',
|
||||
@ -142,9 +134,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
* Config::inst()->update($this->owner->class, 'versionableExtensions',
|
||||
* array('Extension1' => 'suffix1', 'Extension2' => array('suffix2', 'suffix3')));
|
||||
*
|
||||
*
|
||||
* Make sure your extension has a static $enabled-property that determines if it is
|
||||
* processed by Versioned.
|
||||
* Make sure your extension has a static $enabled-property that determines if it is processed by Versioned.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@ -170,9 +160,8 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Construct a new Versioned object.
|
||||
*
|
||||
* @var array $stages The different stages the versioned object can be.
|
||||
* The first stage is considered the 'default' stage, the last stage is
|
||||
* considered the 'live' stage.
|
||||
* @param array $stages The different stages the versioned object can be. The first stage is considered the
|
||||
* 'default' stage, the last stage is considered the 'live' stage.
|
||||
*/
|
||||
public function __construct($stages = array('Stage','Live')) {
|
||||
parent::__construct();
|
||||
@ -187,11 +176,10 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Amend freshly created DataQuery objects with versioned-specific
|
||||
* information.
|
||||
* Amend freshly created DataQuery objects with versioned-specific information.
|
||||
*
|
||||
* @param SQLQuery
|
||||
* @param DataQuery
|
||||
* @param SQLQuery $query
|
||||
* @param DataQuery $dataQuery
|
||||
*/
|
||||
public function augmentDataQueryCreation(SQLQuery &$query, DataQuery &$dataQuery) {
|
||||
$parts = explode('.', Versioned::get_reading_mode());
|
||||
@ -206,12 +194,14 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
$dataQuery->setQueryParam('Versioned.mode', 'stage');
|
||||
$dataQuery->setQueryParam('Versioned.stage', $parts[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Augment the the SQLQuery that is created by the DataQuery
|
||||
* Augment the the SQLQuery that is created by the DataQuery.
|
||||
* @todo Should this all go into VersionedDataQuery?
|
||||
*
|
||||
* @param SQLQuery $query
|
||||
* @param DataQuery $dataQuery
|
||||
*/
|
||||
public function augmentSQL(SQLQuery &$query, DataQuery &$dataQuery = null) {
|
||||
if(!$dataQuery || !$dataQuery->getQueryParam('Versioned.mode')) {
|
||||
@ -328,9 +318,8 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
$query->setOrderBy($orders);
|
||||
|
||||
// latest_version has one more step
|
||||
// Return latest version instances, regardless of whether they are on a particular stage
|
||||
// This provides "show all, including deleted" functonality
|
||||
// latest_version has one more step. Return latest version instances, regardless of whether they are on a
|
||||
// particular stage. This provides "show all, including deleted" functonality
|
||||
if($dataQuery->getQueryParam('Versioned.mode') == 'latest_versions') {
|
||||
$query->addWhere(
|
||||
"\"{$alias}_versions\".\"Version\" IN
|
||||
@ -355,17 +344,16 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* For lazy loaded fields requiring extra sql manipulation, ie versioning.
|
||||
* For lazy loaded fields requiring extra SQL manipulation, ie versioning.
|
||||
*
|
||||
* @param SQLQuery $query
|
||||
* @param DataQuery $dataQuery
|
||||
* @param SQLQuery $query
|
||||
* @param DataQuery $dataQuery
|
||||
* @param DataObject $dataObject
|
||||
*/
|
||||
public function augmentLoadLazyFields(SQLQuery &$query, DataQuery &$dataQuery = null, $dataObject) {
|
||||
// The VersionedMode local variable ensures that this decorator only applies to
|
||||
// queries that have originated from the Versioned object, and have the Versioned
|
||||
// metadata set on the query object. This prevents regular queries from
|
||||
// accidentally querying the *_versions tables.
|
||||
// The VersionedMode local variable ensures that this decorator only applies to queries that have originated
|
||||
// from the Versioned object, and have the Versioned metadata set on the query object. This prevents regular
|
||||
// queries from accidentally querying the *_versions tables.
|
||||
$versionedMode = $dataObject->getSourceQueryParam('Versioned.mode');
|
||||
$dataClass = $dataQuery->dataClass();
|
||||
$modesToAllowVersioning = array('all_versions', 'latest_versions', 'archive');
|
||||
@ -382,7 +370,6 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by {@link SapphireTest} when the database is reset.
|
||||
*
|
||||
@ -498,8 +485,8 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
if(DB::get_schema()->hasTable("{$table}_versions")) {
|
||||
// Fix data that lacks the uniqueness constraint (since this was added later and
|
||||
// bugs meant that the constraint was validated)
|
||||
// Fix data that lacks the uniqueness constraint (since this was added later and bugs meant that
|
||||
// the constraint was validated)
|
||||
$duplications = DB::query("SELECT MIN(\"ID\") AS \"ID\", \"RecordID\", \"Version\"
|
||||
FROM \"{$table}_versions\" GROUP BY \"RecordID\", \"Version\"
|
||||
HAVING COUNT(*) > 1");
|
||||
@ -514,8 +501,8 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
);
|
||||
}
|
||||
|
||||
// Remove junk which has no data in parent classes. Only needs to run the following
|
||||
// when versioned data is spread over multiple tables
|
||||
// Remove junk which has no data in parent classes. Only needs to run the following when versioned
|
||||
// data is spread over multiple tables
|
||||
if(!$isRootClass && ($versionedTables = ClassInfo::dataClassesFor($table))) {
|
||||
|
||||
foreach($versionedTables as $child) {
|
||||
@ -595,9 +582,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Generates a ($table)_version DB manipulation and injects it into the current $manipulation
|
||||
*
|
||||
* @param array $manipulation Source manipulation data
|
||||
* @param string $table Name of table
|
||||
* @param int $recordID ID of record to version
|
||||
* @param SQLQuery $manipulation The query to augment
|
||||
*/
|
||||
protected function augmentWriteVersioned(&$manipulation, $table, $recordID) {
|
||||
$baseDataClass = ClassInfo::baseDataClass($table);
|
||||
@ -740,8 +725,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
$this->migrateVersion(null);
|
||||
}
|
||||
|
||||
// Add the new version # back into the data object, for accessing
|
||||
// after this write
|
||||
// Add the new version # back into the data object, for accessing after this write
|
||||
if(isset($thisVersion)) {
|
||||
$this->owner->Version = str_replace("'","", $thisVersion);
|
||||
}
|
||||
@ -749,9 +733,8 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
|
||||
/**
|
||||
* Perform a write without affecting the version table.
|
||||
* On objects without versioning.
|
||||
*
|
||||
* @return int The ID of the record
|
||||
* @return int The ID of the written record
|
||||
*/
|
||||
public function writeWithoutVersion() {
|
||||
$this->_nextWriteWithoutVersion = true;
|
||||
@ -759,18 +742,13 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
return $this->owner->write();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function onAfterWrite() {
|
||||
$this->_nextWriteWithoutVersion = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If a write was skipped, then we need to ensure that we don't leave a
|
||||
* migrateVersion() value lying around for the next write.
|
||||
*
|
||||
*
|
||||
* If a write was skipped, then we need to ensure that we don't leave a migrateVersion() value lying around for the
|
||||
* next write.
|
||||
*/
|
||||
public function onAfterSkippedWrite() {
|
||||
$this->migrateVersion(null);
|
||||
@ -867,11 +845,10 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a table is supporting the Versioned extensions (e.g.
|
||||
* $table_versions does exists).
|
||||
* Determine if a table supports the Versioned extensions (e.g. $table_versions does exists).
|
||||
*
|
||||
* @param string $table Table name
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function canBeVersioned($table) {
|
||||
return ClassInfo::exists($table)
|
||||
@ -883,8 +860,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
* Check if a certain table has the 'Version' field.
|
||||
*
|
||||
* @param string $table Table name
|
||||
*
|
||||
* @return boolean Returns false if the field isn't in the table, true otherwise
|
||||
* @return bool
|
||||
*/
|
||||
public function hasVersionField($table) {
|
||||
$rPos = strrpos($table,'_');
|
||||
@ -900,7 +876,6 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
|
||||
/**
|
||||
* @param string $table
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function extendWithSuffix($table) {
|
||||
@ -921,7 +896,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the latest published DataObject.
|
||||
* Get the latest published version of this object.
|
||||
*
|
||||
* @return DataObject
|
||||
*/
|
||||
@ -942,10 +917,10 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Move a database record from one stage to the other.
|
||||
*
|
||||
* @param int|string $fromStage Place to copy from. Can be either a stage name or a version number.
|
||||
* @param string $toStage Place to copy to. Must be a stage name.
|
||||
* @param bool $createNewVersion Set this to true to create a new version number.
|
||||
* By default, the existing version number will be copied over.
|
||||
* @param string $fromStage Place to copy from. Can be either a stage name or a version number.
|
||||
* @param string $toStage Place to copy to. Must be a stage name.
|
||||
* @param bool $createNewVersion Set this to true to create a new version number. By default, the existing
|
||||
* version number will be copied over.
|
||||
*/
|
||||
public function publish($fromStage, $toStage, $createNewVersion = false) {
|
||||
$this->owner->extend('onBeforeVersionedPublish', $fromStage, $toStage, $createNewVersion);
|
||||
@ -1005,19 +980,18 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Set the migrating version.
|
||||
*
|
||||
* @param string $version The version.
|
||||
* @param string $version
|
||||
*/
|
||||
public function migrateVersion($version) {
|
||||
$this->migratingVersion = $version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two stages to see if they're different.
|
||||
* Compare two stages to see if they're different. Only checks the version numbers, not the actual content.
|
||||
*
|
||||
* Only checks the version numbers, not the actual content.
|
||||
*
|
||||
* @param string $stage1 The first stage to check.
|
||||
* @param string $stage2
|
||||
* @param string $stage1 The first stage to check
|
||||
* @param string $stage2 The second stage to check
|
||||
* @return bool
|
||||
*/
|
||||
public function stagesDiffer($stage1, $stage2) {
|
||||
$table1 = $this->baseTable($stage1);
|
||||
@ -1027,8 +1001,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We test for equality - if one of the versions doesn't exist, this
|
||||
// will be false.
|
||||
// We test for equality - if one of the versions doesn't exist, this will be false.
|
||||
|
||||
// TODO: DB Abstraction: if statement here:
|
||||
$stagesAreEqual = DB::prepared_query(
|
||||
@ -1042,24 +1015,28 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of versions for this object, optionally with additional SQL parameters
|
||||
*
|
||||
* @param string $filter
|
||||
* @param string $sort
|
||||
* @param string $limit
|
||||
* @param string $join Deprecated, use leftJoin($table, $joinClause) instead
|
||||
* @param string $having
|
||||
* @return DataList
|
||||
*/
|
||||
public function Versions($filter = "", $sort = "", $limit = "", $join = "", $having = "") {
|
||||
return $this->allVersions($filter, $sort, $limit, $join, $having);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of all the versions available.
|
||||
* Get a list of versions for this object, optionally with additional SQL parameters
|
||||
*
|
||||
* @param string $filter
|
||||
* @param string $sort
|
||||
* @param string $limit
|
||||
* @param string $join Deprecated, use leftJoin($table, $joinClause) instead
|
||||
* @param string $join Deprecated, use leftJoin($table, $joinClause) instead
|
||||
* @param string $having
|
||||
* @return DataList
|
||||
*/
|
||||
public function allVersions($filter = "", $sort = "", $limit = "", $join = "", $having = "") {
|
||||
// Make sure the table names are not postfixed (e.g. _Live)
|
||||
@ -1106,11 +1083,10 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two version, and return the diff between them.
|
||||
*
|
||||
* @param string $from The version to compare from.
|
||||
* @param string $to The version to compare to.
|
||||
* Compare two version, and return the differences between them.
|
||||
*
|
||||
* @param string $from The version to compare from
|
||||
* @param string $to The version to compare to
|
||||
* @return DataObject
|
||||
*/
|
||||
public function compareVersions($from, $to) {
|
||||
@ -1125,6 +1101,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Return the base table - the class that directly extends DataObject.
|
||||
*
|
||||
* @param string $stage Override the stage used
|
||||
* @return string
|
||||
*/
|
||||
public function baseTable($stage = null) {
|
||||
@ -1162,16 +1139,12 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Choose the stage the site is currently on.
|
||||
* Choose the stage the site is currently on:
|
||||
* - If $_GET['stage'] is set, then it will use that stage, and store it in the session.
|
||||
* - If $_GET['archiveDate'] is set, it will use that date, and store it in the session.
|
||||
* - If neither of these are set, it checks the session, otherwise the stage is set to 'Live'.
|
||||
*
|
||||
* If $_GET['stage'] is set, then it will use that stage, and store it in
|
||||
* the session.
|
||||
*
|
||||
* if $_GET['archiveDate'] is set, it will use that date, and store it in
|
||||
* the session.
|
||||
*
|
||||
* If neither of these are set, it checks the session, otherwise the stage
|
||||
* is set to 'Live'.
|
||||
* @param Session $session Optional session within which to store the resulting stage
|
||||
*/
|
||||
public static function choose_site_stage() {
|
||||
// Check any pre-existing session mode
|
||||
@ -1268,7 +1241,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Set the reading stage.
|
||||
*
|
||||
* @param string $stage New reading stage.
|
||||
* @param string $stage
|
||||
*/
|
||||
public static function reading_stage($stage) {
|
||||
Versioned::set_reading_mode('Stage.' . $stage);
|
||||
@ -1277,21 +1250,20 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Set the reading archive date.
|
||||
*
|
||||
* @param string $date New reading archived date.
|
||||
* @param string $date
|
||||
*/
|
||||
public static function reading_archived_date($date) {
|
||||
Versioned::set_reading_mode('Archive.' . $date);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a singleton instance of a class in the given stage.
|
||||
*
|
||||
* @param string $class The name of the class.
|
||||
* @param string $stage The name of the stage.
|
||||
* @param string $filter A filter to be inserted into the WHERE clause.
|
||||
* @param boolean $cache Use caching.
|
||||
* @param string $orderby A sort expression to be inserted into the ORDER BY clause.
|
||||
* @param string $class The name of the class
|
||||
* @param string $stage The name of the stage
|
||||
* @param string $filter A filter to be inserted into the WHERE clause
|
||||
* @param bool $cache Whether to load from the cache instead of fresh from the database
|
||||
* @param string $sort A sort expression to be inserted into the ORDER BY clause.
|
||||
*
|
||||
* @return DataObject
|
||||
*/
|
||||
@ -1305,10 +1277,10 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Gets the current version number of a specific record.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $stage
|
||||
* @param int $id
|
||||
* @param boolean $cache
|
||||
* @param string $class The classname of the desired object
|
||||
* @param string $stage The name of the stage to load from
|
||||
* @param int $id The object's ID
|
||||
* @param bool $cache Whether to load from the cache instead of fresh from the database
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
@ -1321,11 +1293,8 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
return self::$cache_versionnumber[$baseClass][$stage][$id];
|
||||
}
|
||||
|
||||
// get version as performance-optimized SQL query (gets called for each page in the sitetree)
|
||||
$version = DB::prepared_query(
|
||||
"SELECT \"Version\" FROM \"$stageTable\" WHERE \"ID\" = ?",
|
||||
array($id)
|
||||
)->value();
|
||||
// get version as performance-optimized SQL query (gets called for each object of this class in the database)
|
||||
$version = DB::query("SELECT \"Version\" FROM \"$stageTable\" WHERE \"ID\" = $id")->value();
|
||||
|
||||
// cache value (if required)
|
||||
if($cache) {
|
||||
@ -1344,13 +1313,12 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Pre-populate the cache for Versioned::get_versionnumber_by_stage() for
|
||||
* a list of record IDs, for more efficient database querying. If $idList
|
||||
* is null, then every page will be pre-cached.
|
||||
* Prepopulate the cache for Versioned::get_versionnumber_by_stage() for a list of record IDs, for more efficient
|
||||
* database querying. If $idList is null, then every object will be pre-cached.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $stage
|
||||
* @param array $idList
|
||||
* @param string $class The object class to prepopulate version numbers for
|
||||
* @param string $stage The stage to prepopulate version numbers from
|
||||
* @param array $idList A whitelist of IDs to use when prepopulating
|
||||
*/
|
||||
public static function prepopulate_versionnumber_cache($class, $stage, $idList = null) {
|
||||
if (!Config::inst()->get('Versioned', 'prepopulate_versionnumber_cache')) {
|
||||
@ -1383,13 +1351,13 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Get a set of class instances by the given stage.
|
||||
*
|
||||
* @param string $class The name of the class.
|
||||
* @param string $stage The name of the stage.
|
||||
* @param string $filter A filter to be inserted into the WHERE clause.
|
||||
* @param string $sort A sort expression to be inserted into the ORDER BY clause.
|
||||
* @param string $join Deprecated, use leftJoin($table, $joinClause) instead
|
||||
* @param int $limit A limit on the number of records returned from the database.
|
||||
* @param string $containerClass The container class for the result set (default is DataList)
|
||||
* @param string $class The name of the class.
|
||||
* @param string $stage The name of the stage.
|
||||
* @param string $filter A filter to be inserted into the WHERE clause.
|
||||
* @param string $sort A sort expression to be inserted into the ORDER BY clause.
|
||||
* @param string $join Deprecated, use leftJoin($table, $joinClause) instead
|
||||
* @param string|int $limit A limit on the number of records returned from the database.
|
||||
* @param string $containerClass The container class for the result set (default is DataList)
|
||||
*
|
||||
* @return DataList A modified DataList designated to the specified stage
|
||||
*/
|
||||
@ -1404,9 +1372,9 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stage
|
||||
* Delete this item from the specified stage.
|
||||
*
|
||||
* @return int
|
||||
* @param string $stage
|
||||
*/
|
||||
public function deleteFromStage($stage) {
|
||||
$oldMode = Versioned::get_reading_mode();
|
||||
@ -1423,8 +1391,11 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $stage
|
||||
* @param boolean $forceInsert
|
||||
* Write this item to the specified stage.
|
||||
*
|
||||
* @param string $stage The stage to write this item to
|
||||
* @param bool $forceInsert Whether to force an INSERT query over an UPDATE query
|
||||
* @return int The ID of the item being written
|
||||
*/
|
||||
public function writeToStage($stage, $forceInsert = false) {
|
||||
$oldMode = Versioned::get_reading_mode();
|
||||
@ -1438,10 +1409,11 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll the draft version of this page to match the published page.
|
||||
* Roll the draft version of this object to match the published one.
|
||||
*
|
||||
* Caution: Doesn't overwrite the object properties with the rolled back version.
|
||||
*
|
||||
* @param int $version Either the string 'Live' or a version number
|
||||
* @param string|int $version Either the string 'Live' or a version number
|
||||
*/
|
||||
public function doRollbackTo($version) {
|
||||
$this->owner->extend('onBeforeRollback', $version);
|
||||
@ -1453,8 +1425,10 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the latest version of the given page.
|
||||
* Return the latest version of the given object.
|
||||
*
|
||||
* @param string $class The classname of the object to lookup
|
||||
* @param string $id The object of the ID to retrieve
|
||||
* @return DataObject
|
||||
*/
|
||||
public static function get_latest_version($class, $id) {
|
||||
@ -1474,7 +1448,7 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
* @see get_latest_version()
|
||||
* @see latestPublished
|
||||
*
|
||||
* @return boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isLatestVersion() {
|
||||
$version = self::get_latest_version($this->owner->class, $this->owner->ID);
|
||||
@ -1486,14 +1460,12 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the equivalent of a DataList::create() call, querying the latest
|
||||
* version of each page stored in the (class)_versions tables.
|
||||
* Return the equivalent of a DataList::create() call, querying the latest version of each object stored in the
|
||||
* (class)_versions tables. In particular, this will query deleted records as well as active ones.
|
||||
*
|
||||
* In particular, this will query deleted records as well as active ones.
|
||||
*
|
||||
* @param string $class
|
||||
* @param string $filter
|
||||
* @param string $sort
|
||||
* @param string $class The type of object to lookup
|
||||
* @param string $filter An optional SQL comparison to add to the WHERE clause
|
||||
* @param string $sort An optional SQL statement to add to the SORT clause
|
||||
*/
|
||||
public static function get_including_deleted($class, $filter = "", $sort = "") {
|
||||
$list = DataList::create($class)
|
||||
@ -1505,16 +1477,14 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the specific version of the given id.
|
||||
* Return the specific version of the given ID.
|
||||
*
|
||||
* Caution: The record is retrieved as a DataObject, but saving back
|
||||
* modifications via write() will create a new version, rather than
|
||||
* modifying the existing one.
|
||||
*
|
||||
* @param string $class
|
||||
* @param int $id
|
||||
* @param int $version
|
||||
* Caution: The record is retrieved as a DataObject, but saving back modifications via write() will create a new
|
||||
* version, rather than modifying the existing one.
|
||||
*
|
||||
* @param string $class The type of object to lookup
|
||||
* @param int $id The ID of the object to retrieve
|
||||
* @param int $version The desired version of the object
|
||||
* @return DataObject
|
||||
*/
|
||||
public static function get_version($class, $id, $version) {
|
||||
@ -1530,8 +1500,8 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
/**
|
||||
* Return a list of all versions for a given id.
|
||||
*
|
||||
* @param string $class
|
||||
* @param int $id
|
||||
* @param string $class The type of object to lookup
|
||||
* @param int $id The ID of the object to retrieve
|
||||
*
|
||||
* @return DataList
|
||||
*/
|
||||
@ -1551,9 +1521,6 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
$labels['Versions'] = _t('Versioned.has_many_Versions', 'Versions', 'Past Versions of this page');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FieldList
|
||||
*/
|
||||
public function updateCMSFields(FieldList $fields) {
|
||||
// remove the version field from the CMS as this should be left
|
||||
// entirely up to the extension (not the cms user).
|
||||
@ -1570,12 +1537,15 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
$this->owner->Version = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the cached version numbers from previous queries.
|
||||
*/
|
||||
public function flushCache() {
|
||||
self::$cache_versionnumber = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a piece of text to keep DataObject cache keys appropriately specific.
|
||||
* Returns a piece of text to keep DataObject cache keys appropriately specific.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@ -1615,14 +1585,11 @@ class Versioned extends DataExtension implements TemplateGlobalProvider {
|
||||
* @see Versioned
|
||||
*/
|
||||
class Versioned_Version extends ViewableData {
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
||||
/** @var array */
|
||||
protected $record;
|
||||
|
||||
/**
|
||||
* @var DataObject
|
||||
*/
|
||||
/** @var DataObject */
|
||||
protected $object;
|
||||
|
||||
public function __construct($record) {
|
||||
@ -1637,6 +1604,8 @@ class Versioned_Version extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a CSS classname to use representing whether this version was published or not.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function PublishedClass() {
|
||||
@ -1644,6 +1613,8 @@ class Versioned_Version extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this version's author (the person who saved to Stage).
|
||||
*
|
||||
* @return Member
|
||||
*/
|
||||
public function Author() {
|
||||
@ -1651,6 +1622,8 @@ class Versioned_Version extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this version's publisher.
|
||||
*
|
||||
* @return Member
|
||||
*/
|
||||
public function Publisher() {
|
||||
@ -1662,7 +1635,9 @@ class Versioned_Version extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
* Determines if this version was ever published.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function Published() {
|
||||
return !empty($this->record['WasPublished']);
|
||||
@ -1670,6 +1645,9 @@ class Versioned_Version extends ViewableData {
|
||||
|
||||
/**
|
||||
* Copied from DataObject to allow access via dot notation.
|
||||
*
|
||||
* @param string $fieldName
|
||||
* @return mixed
|
||||
*/
|
||||
public function relField($fieldName) {
|
||||
$component = $this;
|
||||
|
Loading…
x
Reference in New Issue
Block a user