mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-09-29 20:59:23 +02:00
API CHANGE Deprecated DataObjectDecorator->augmentBeforeWrite(), use DataObjectDecorator->onBeforeWrite()
API CHANGE Deprecated DataObjectDecorator->augmentPopulateDefaults(), use DataObjectDecorator->populateDefaults() API CHANGE Deprecated DataObjectDecorator->augmentDefaultRecords(), use DataObjectDecorator->requireDefaultRecords() API CHANGE Deprecated DataObjectDecorator->alternateCan(), use DataObjectDecorator->can() API CHANGE Deprecated DataObjectDecorator->alternateCanAddChildren(), use DataObjectDecorator->canAddChildren() API CHANGE Deprecated DataObjectDecorator->alternateCanView(), use DataObjectDecorator->canView() API CHANGE Deprecated DataObjectDecorator->alternateCanDelete(), use DataObjectDecorator->canDelete() API CHANGE Deprecated DataObjectDecorator->alternateCanEdit(), use DataObjectDecorator->canEdit() API CHANGE Deprecated DataObjectDecorator->alternateCanCreate(), use DataObjectDecorator->canCreate() ENHANCEMENT Added DataObject->onAfterDelete() and DataObjectDecorator->onAfterDelete() ENHANCEMENT Added stub methods to DataObjectDecorator for documentation purposes git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@65453 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
cfde8adaee
commit
137b76e271
@ -562,12 +562,18 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
* database. Don't forget to call parent::onBeforeWrite(), though!
|
* database. Don't forget to call parent::onBeforeWrite(), though!
|
||||||
*
|
*
|
||||||
* This called after {@link $this->validate()}, so you can be sure that your data is valid.
|
* This called after {@link $this->validate()}, so you can be sure that your data is valid.
|
||||||
|
*
|
||||||
|
* @uses DataObjectDecorator->onBeforeWrite()
|
||||||
*/
|
*/
|
||||||
protected function onBeforeWrite() {
|
protected function onBeforeWrite() {
|
||||||
$this->brokenOnWrite = false;
|
$this->brokenOnWrite = false;
|
||||||
|
|
||||||
|
// DEPRECATED 2.3: use onBeforeWrite()
|
||||||
$dummy = null;
|
$dummy = null;
|
||||||
$this->extend('augmentBeforeWrite', $dummy);
|
$this->extend('augmentBeforeWrite', $dummy);
|
||||||
|
|
||||||
|
$dummy = null;
|
||||||
|
$this->extend('onBeforeWrite', $dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -575,10 +581,16 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
* You can overload this to act upon changes made to the data after it is written.
|
* You can overload this to act upon changes made to the data after it is written.
|
||||||
* $this->changed will have a record
|
* $this->changed will have a record
|
||||||
* database. Don't forget to call parent::onAfterWrite(), though!
|
* database. Don't forget to call parent::onAfterWrite(), though!
|
||||||
|
*
|
||||||
|
* @uses DataObjectDecorator->onAfterWrite()
|
||||||
*/
|
*/
|
||||||
protected function onAfterWrite() {
|
protected function onAfterWrite() {
|
||||||
|
// DEPRECATED 2.3: use onAfterWrite()
|
||||||
$dummy = null;
|
$dummy = null;
|
||||||
$this->extend('augmentAfterWrite', $dummy);
|
$this->extend('augmentAfterWrite', $dummy);
|
||||||
|
|
||||||
|
$dummy = null;
|
||||||
|
$this->extend('onAfterWrite', $dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -591,9 +603,18 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
* Event handler called before deleting from the database.
|
* Event handler called before deleting from the database.
|
||||||
* You can overload this to clean up or otherwise process data before delete this
|
* You can overload this to clean up or otherwise process data before delete this
|
||||||
* record. Don't forget to call parent::onBeforeDelete(), though!
|
* record. Don't forget to call parent::onBeforeDelete(), though!
|
||||||
|
*
|
||||||
|
* @uses DataObjectDecorator->onBeforeDelete()
|
||||||
*/
|
*/
|
||||||
protected function onBeforeDelete() {
|
protected function onBeforeDelete() {
|
||||||
$this->brokenOnDelete = false;
|
$this->brokenOnDelete = false;
|
||||||
|
|
||||||
|
$dummy = null;
|
||||||
|
$this->extend('onBeforeDelete', $dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function onAfterDelete() {
|
||||||
|
$this->extend('onAfterDelete');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -606,6 +627,8 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
* Load the default values in from the self::$defaults array.
|
* Load the default values in from the self::$defaults array.
|
||||||
* Will traverse the defaults of the current class and all its parent classes.
|
* Will traverse the defaults of the current class and all its parent classes.
|
||||||
* Called by the constructor when creating new records.
|
* Called by the constructor when creating new records.
|
||||||
|
*
|
||||||
|
* @uses DataObjectDecorator->populateDefaults()
|
||||||
*/
|
*/
|
||||||
public function populateDefaults() {
|
public function populateDefaults() {
|
||||||
$classes = array_reverse(ClassInfo::ancestry($this));
|
$classes = array_reverse(ClassInfo::ancestry($this));
|
||||||
@ -630,7 +653,10 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEPRECATED 2.3: use populateDefaults()
|
||||||
$this->extend('augmentPopulateDefaults');
|
$this->extend('augmentPopulateDefaults');
|
||||||
|
|
||||||
|
$this->extend('populateDefaults');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -641,6 +667,8 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
* - Extensions such as Versioned will ammend the database-write to ensure that a version is saved.
|
* - Extensions such as Versioned will ammend the database-write to ensure that a version is saved.
|
||||||
* - Calls to {@link DataObjectLog} can be used to see everything that's been changed.
|
* - Calls to {@link DataObjectLog} can be used to see everything that's been changed.
|
||||||
*
|
*
|
||||||
|
* @uses DataObjectDecorator->augmentWrite()
|
||||||
|
*
|
||||||
* @param boolean $showDebug Show debugging information
|
* @param boolean $showDebug Show debugging information
|
||||||
* @param boolean $forceInsert Run INSERT command rather than UPDATE, even if record already exists
|
* @param boolean $forceInsert Run INSERT command rather than UPDATE, even if record already exists
|
||||||
* @param boolean $forceWrite Write to database even if there are no changes
|
* @param boolean $forceWrite Write to database even if there are no changes
|
||||||
@ -768,6 +796,7 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->extend('augmentWrite', $manipulation);
|
$this->extend('augmentWrite', $manipulation);
|
||||||
|
|
||||||
// New records have their insert into the base data table done first, so that they can pass the
|
// New records have their insert into the base data table done first, so that they can pass the
|
||||||
// generated ID on to the rest of the manipulation
|
// generated ID on to the rest of the manipulation
|
||||||
if(isset($isNewRecord) && $isNewRecord && isset($manipulation[$baseTable])) {
|
if(isset($isNewRecord) && $isNewRecord && isset($manipulation[$baseTable])) {
|
||||||
@ -838,6 +867,7 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
* Delete this data object.
|
* Delete this data object.
|
||||||
* $this->onBeforeDelete() gets called.
|
* $this->onBeforeDelete() gets called.
|
||||||
* Note that in Versioned objects, both Stage and Live will be deleted.
|
* Note that in Versioned objects, both Stage and Live will be deleted.
|
||||||
|
* @uses DataObjectDecorator->augmentSQL()
|
||||||
*/
|
*/
|
||||||
public function delete() {
|
public function delete() {
|
||||||
$this->brokenOnDelete = true;
|
$this->brokenOnDelete = true;
|
||||||
@ -845,6 +875,7 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
if($this->brokenOnDelete) {
|
if($this->brokenOnDelete) {
|
||||||
user_error("$this->class has a broken onBeforeDelete() function. Make sure that you call parent::onBeforeDelete().", E_USER_ERROR);
|
user_error("$this->class has a broken onBeforeDelete() function. Make sure that you call parent::onBeforeDelete().", E_USER_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->getClassAncestry() as $ancestor) {
|
foreach($this->getClassAncestry() as $ancestor) {
|
||||||
if(self::has_own_table($ancestor)) {
|
if(self::has_own_table($ancestor)) {
|
||||||
$sql = new SQLQuery();
|
$sql = new SQLQuery();
|
||||||
@ -856,6 +887,8 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->onAfterDelete();
|
||||||
|
|
||||||
$this->OldID = $this->ID;
|
$this->OldID = $this->ID;
|
||||||
$this->ID = 0;
|
$this->ID = 0;
|
||||||
|
|
||||||
@ -2076,12 +2109,13 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
/**
|
/**
|
||||||
* Like {@link buildSQL}, but applies the extension modifications.
|
* Like {@link buildSQL}, but applies the extension modifications.
|
||||||
*
|
*
|
||||||
|
* @uses DataObjectDecorator->augmentSQL()
|
||||||
|
*
|
||||||
* @param string $filter A filter to be inserted into the WHERE clause.
|
* @param string $filter A filter to be inserted into the WHERE clause.
|
||||||
* @param string|array $sort A sort expression to be inserted into the ORDER BY clause. If omitted, self::$default_sort will be used.
|
* @param string|array $sort A sort expression to be inserted into the ORDER BY clause. If omitted, self::$default_sort will be used.
|
||||||
* @param string|array $limit A limit expression to be inserted into the LIMIT clause.
|
* @param string|array $limit A limit expression to be inserted into the LIMIT clause.
|
||||||
* @param string $join A single join clause. This can be used for filtering, only 1 instance of each DataObject will be returned.
|
* @param string $join A single join clause. This can be used for filtering, only 1 instance of each DataObject will be returned.
|
||||||
* @param string $having A filter to be inserted into the HAVING clause.
|
* @param string $having A filter to be inserted into the HAVING clause.
|
||||||
*
|
|
||||||
* @return SQLQuery Query built
|
* @return SQLQuery Query built
|
||||||
*/
|
*/
|
||||||
public function extendedSQL($filter = "", $sort = "", $limit = "", $join = "", $having = ""){
|
public function extendedSQL($filter = "", $sort = "", $limit = "", $join = "", $having = ""){
|
||||||
@ -2229,9 +2263,10 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
/**
|
/**
|
||||||
* Does the hard work for get_one()
|
* Does the hard work for get_one()
|
||||||
*
|
*
|
||||||
|
* @uses DataObjectDecorator->augmentSQL()
|
||||||
|
*
|
||||||
* @param string $filter A filter to be inserted into the WHERE clause
|
* @param string $filter A filter to be inserted into the WHERE clause
|
||||||
* @param string $orderby A sort expression to be inserted into the ORDER BY clause.
|
* @param string $orderby A sort expression to be inserted into the ORDER BY clause.
|
||||||
*
|
|
||||||
* @return DataObject The first item matching the query
|
* @return DataObject The first item matching the query
|
||||||
*/
|
*/
|
||||||
public function instance_get_one($filter, $orderby = null) {
|
public function instance_get_one($filter, $orderby = null) {
|
||||||
@ -2329,6 +2364,8 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the database schema and update it as necessary.
|
* Check the database schema and update it as necessary.
|
||||||
|
*
|
||||||
|
* @uses DataObjectDecorator->augmentDatabase()
|
||||||
*/
|
*/
|
||||||
public function requireTable() {
|
public function requireTable() {
|
||||||
// Only build the table if we've actually got fields
|
// Only build the table if we've actually got fields
|
||||||
@ -2373,6 +2410,8 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
* database is built, after the database tables have all been created. Overload
|
* database is built, after the database tables have all been created. Overload
|
||||||
* this to add default records when the database is built, but make sure you
|
* this to add default records when the database is built, but make sure you
|
||||||
* call parent::requireDefaultRecords().
|
* call parent::requireDefaultRecords().
|
||||||
|
*
|
||||||
|
* @uses DataObjectDecorator->requireDefaultRecords()
|
||||||
*/
|
*/
|
||||||
public function requireDefaultRecords() {
|
public function requireDefaultRecords() {
|
||||||
$defaultRecords = $this->stat('default_records');
|
$defaultRecords = $this->stat('default_records');
|
||||||
@ -2389,8 +2428,11 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let any extentions make their own database default data
|
// DEPRECATED 2.3: Use requireDefaultRecords()
|
||||||
$this->extend('augmentDefaultRecords', $dummy);
|
$this->extend('augmentDefaultRecords', $dummy);
|
||||||
|
|
||||||
|
// Let any extentions make their own database default data
|
||||||
|
$this->extend('requireDefaultRecords', $dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2476,8 +2518,8 @@ class DataObject extends ViewableData implements DataObjectInterface,i18nEntityP
|
|||||||
if(!$fields) $fields = array_keys($this->summaryFields());
|
if(!$fields) $fields = array_keys($this->summaryFields());
|
||||||
|
|
||||||
// we need to make sure the format is unified before
|
// we need to make sure the format is unified before
|
||||||
// augumenting fields, so decorators can apply consistent checks
|
// augmenting fields, so decorators can apply consistent checks
|
||||||
// but also after augumenting fields, because the decorator
|
// but also after augmenting fields, because the decorator
|
||||||
// might use the shorthand notation as well
|
// might use the shorthand notation as well
|
||||||
|
|
||||||
// rewrite array, if it is using shorthand syntax
|
// rewrite array, if it is using shorthand syntax
|
||||||
|
@ -81,6 +81,35 @@ abstract class DataObjectDecorator extends Extension {
|
|||||||
function augmentWrite(&$manipulation) {
|
function augmentWrite(&$manipulation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onBeforeWrite() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAfterWrite() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function onBeforeDelete() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAfterDelete() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function requireDefaultRecords() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateDefaults() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function can($member) {
|
||||||
|
}
|
||||||
|
|
||||||
|
function canEdit($member) {
|
||||||
|
}
|
||||||
|
|
||||||
|
function canDelete($member) {
|
||||||
|
}
|
||||||
|
|
||||||
|
function canCreate($member) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define extra database fields
|
* Define extra database fields
|
||||||
@ -108,7 +137,6 @@ abstract class DataObjectDecorator extends Extension {
|
|||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is used to provide modifications to the form in the CMS
|
* This function is used to provide modifications to the form in the CMS
|
||||||
* by the decorator. By default, no changes are made.
|
* by the decorator. By default, no changes are made.
|
||||||
@ -135,6 +163,9 @@ abstract class DataObjectDecorator extends Extension {
|
|||||||
function updateFormFields(FieldSet &$fields) {
|
function updateFormFields(FieldSet &$fields) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateCMSActions(FieldSet &$actions) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* this function is used to provide modifications to the summary fields in CMS
|
* this function is used to provide modifications to the summary fields in CMS
|
||||||
* by the decorator
|
* by the decorator
|
||||||
|
@ -503,13 +503,13 @@ class SiteTree extends DataObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This function should return true if the current user can add children
|
* This function should return true if the current user can add children
|
||||||
* to this page.
|
* to this page. It can be overloaded to customise the security model for an
|
||||||
*
|
|
||||||
* It can be overloaded to customise the security model for an
|
|
||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
* Returns true if the member is allowed to do the given action.
|
* Returns true if the member is allowed to do the given action.
|
||||||
*
|
*
|
||||||
|
* @uses DataObjectDecorator->can()
|
||||||
|
*
|
||||||
* @param string $perm The permission to be checked, such as 'View'.
|
* @param string $perm The permission to be checked, such as 'View'.
|
||||||
* @param Member $member The member whose permissions need checking.
|
* @param Member $member The member whose permissions need checking.
|
||||||
* Defaults to the currently logged in user.
|
* Defaults to the currently logged in user.
|
||||||
@ -520,9 +520,8 @@ class SiteTree extends DataObject {
|
|||||||
* @todo Check we get a endless recursion if we use parent::can()
|
* @todo Check we get a endless recursion if we use parent::can()
|
||||||
*/
|
*/
|
||||||
function can($perm, $member = null) {
|
function can($perm, $member = null) {
|
||||||
if(!isset($member)) {
|
if(!isset($member)) $member = Member::currentUser();
|
||||||
$member = Member::currentUser();
|
|
||||||
}
|
|
||||||
if(Permission::checkMember($member, "ADMIN")) return true;
|
if(Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
if(method_exists($this, 'can' . ucfirst($perm))) {
|
if(method_exists($this, 'can' . ucfirst($perm))) {
|
||||||
@ -530,13 +529,14 @@ class SiteTree extends DataObject {
|
|||||||
return $this->$method($member);
|
return $this->$method($member);
|
||||||
}
|
}
|
||||||
|
|
||||||
$args = array($perm, $member, true);
|
// DEPRECATED 2.3: Use can()
|
||||||
$this->extend('alternateCan', $args);
|
$results = $this->extend('alternateCan', $member);
|
||||||
if($args[2] == false) return false;
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
|
$results = $this->extend('can', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
//return parent::can($perm, $member);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -550,7 +550,7 @@ class SiteTree extends DataObject {
|
|||||||
* - canEdit() is not granted
|
* - canEdit() is not granted
|
||||||
* - There are no classes defined in {@link $allowed_children}
|
* - There are no classes defined in {@link $allowed_children}
|
||||||
*
|
*
|
||||||
* @uses alternateCanAddChildren()
|
* @uses DataObjectDecorator->canAddChildren()
|
||||||
* @uses canEdit()
|
* @uses canEdit()
|
||||||
* @uses $allowed_children
|
* @uses $allowed_children
|
||||||
*
|
*
|
||||||
@ -562,9 +562,12 @@ class SiteTree extends DataObject {
|
|||||||
}
|
}
|
||||||
if(Permission::checkMember($member, "ADMIN")) return true;
|
if(Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
$args = array($member, true);
|
// DEPRECATED 2.3: use canAddChildren() instead
|
||||||
$this->extend('alternateCanAddChildren', $args);
|
$results = $this->extend('alternateCanAddChildren', $member);
|
||||||
if($args[1] == false) return false;
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
|
$results = $this->extend('canAddChildren', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
return $this->canEdit() && $this->stat('allowed_children') != 'none';
|
return $this->canEdit() && $this->stat('allowed_children') != 'none';
|
||||||
}
|
}
|
||||||
@ -576,12 +579,12 @@ class SiteTree extends DataObject {
|
|||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
* Denies permission if any of the following conditions is TRUE:
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
* - alternateCanView() on any decorator returns FALSE
|
* - canView() on any decorator returns FALSE
|
||||||
* - "CanViewType" directive is set to "Inherit" and any parent page return false for canView()
|
* - "CanViewType" directive is set to "Inherit" and any parent page return false for canView()
|
||||||
* - "CanViewType" directive is set to "LoggedInUsers" and no user is logged in
|
* - "CanViewType" directive is set to "LoggedInUsers" and no user is logged in
|
||||||
* - "CanViewType" directive is set to "OnlyTheseUsers" and user is not in the given groups
|
* - "CanViewType" directive is set to "OnlyTheseUsers" and user is not in the given groups
|
||||||
*
|
*
|
||||||
* @uses alternateCanView()
|
* @uses DataObjectDecorator->canView()
|
||||||
* @uses ViewerGroups()
|
* @uses ViewerGroups()
|
||||||
*
|
*
|
||||||
* @return boolean True if the current user can view this page.
|
* @return boolean True if the current user can view this page.
|
||||||
@ -592,10 +595,13 @@ class SiteTree extends DataObject {
|
|||||||
// admin override
|
// admin override
|
||||||
if(Permission::checkMember($member, "ADMIN")) return true;
|
if(Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
|
// DEPRECATED 2.3: use canView() instead
|
||||||
|
$results = $this->extend('alternateCanView', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
// decorated access checks
|
// decorated access checks
|
||||||
$args = array($member, true);
|
$results = $this->extend('canView', $member);
|
||||||
$this->extend('alternateCanView', $args);
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
if($args[1] == false) return false;
|
|
||||||
|
|
||||||
// check for empty spec
|
// check for empty spec
|
||||||
if(
|
if(
|
||||||
@ -629,12 +635,11 @@ class SiteTree extends DataObject {
|
|||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
* Denies permission if any of the following conditions is TRUE:
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
* - alternateCanDelete() returns FALSE on any decorator
|
* - canDelete() returns FALSE on any decorator
|
||||||
* - canEdit() returns FALSE
|
* - canEdit() returns FALSE
|
||||||
* - any descendant page returns FALSE for canDelete()
|
* - any descendant page returns FALSE for canDelete()
|
||||||
*
|
*
|
||||||
* @todo Check if all children can be deleted as well
|
* @uses canDelete()
|
||||||
* @uses alternateCanDelete()
|
|
||||||
* @uses canEdit()
|
* @uses canEdit()
|
||||||
*
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
@ -645,9 +650,13 @@ class SiteTree extends DataObject {
|
|||||||
|
|
||||||
if(Permission::checkMember($member, "ADMIN")) return true;
|
if(Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
$args = array($member, true);
|
// DEPRECATED 2.3: use canDelete() instead
|
||||||
$this->extend('alternateCanDelete', $args);
|
$results = $this->extend('alternateCanDelete', $member);
|
||||||
if($args[1] == false) return false;
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
|
// decorated access checks
|
||||||
|
$results = $this->extend('canDelete', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
// if page can't be edited, don't grant delete permissions
|
// if page can't be edited, don't grant delete permissions
|
||||||
if(!$this->canEdit()) return false;
|
if(!$this->canEdit()) return false;
|
||||||
@ -667,12 +676,11 @@ class SiteTree extends DataObject {
|
|||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
* Denies permission if any of the following conditions is TRUE:
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
* - alternateCanCreate() returns FALSE on any decorator
|
* - canCreate() returns FALSE on any decorator
|
||||||
* - $can_create is set to FALSE and the site is not in "dev mode"
|
* - $can_create is set to FALSE and the site is not in "dev mode"
|
||||||
*
|
*
|
||||||
* Use {@link canAddChildren()} to control behaviour of creating children under this page.
|
* Use {@link canAddChildren()} to control behaviour of creating children under this page.
|
||||||
*
|
*
|
||||||
* @uses alternateCanCreate()
|
|
||||||
* @uses $can_create
|
* @uses $can_create
|
||||||
*
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
@ -683,9 +691,13 @@ class SiteTree extends DataObject {
|
|||||||
|
|
||||||
if(Permission::checkMember($member, "ADMIN")) return true;
|
if(Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
$args = array($member, true);
|
// DEPRECATED 2.3: use canCreate() instead
|
||||||
$this->extend('alternateCanCreate', $args);
|
$results = $this->extend('alternateCanCreate', $member);
|
||||||
if($args[1] == false) return false;
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
|
// decorated permission checks
|
||||||
|
$results = $this->extend('canCreate', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
return $this->stat('can_create') != false || Director::isDev();
|
return $this->stat('can_create') != false || Director::isDev();
|
||||||
}
|
}
|
||||||
@ -697,13 +709,12 @@ class SiteTree extends DataObject {
|
|||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
* Denies permission if any of the following conditions is TRUE:
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
* - alternateCanEdit() on any decorator returns FALSE
|
* - canEdit() on any decorator returns FALSE
|
||||||
* - canView() return false
|
* - canView() return false
|
||||||
* - "CanEditType" directive is set to "Inherit" and any parent page return false for canEdit()
|
* - "CanEditType" directive is set to "Inherit" and any parent page return false for canEdit()
|
||||||
* - "CanEditType" directive is set to "LoggedInUsers" and no user is logged in or doesn't have the CMS_Access_CMSMAIN permission code
|
* - "CanEditType" directive is set to "LoggedInUsers" and no user is logged in or doesn't have the CMS_Access_CMSMAIN permission code
|
||||||
* - "CanEditType" directive is set to "OnlyTheseUsers" and user is not in the given groups
|
* - "CanEditType" directive is set to "OnlyTheseUsers" and user is not in the given groups
|
||||||
*
|
*
|
||||||
* @uses alternateCanEdit()
|
|
||||||
* @uses canView()
|
* @uses canView()
|
||||||
* @uses EditorGroups()
|
* @uses EditorGroups()
|
||||||
*
|
*
|
||||||
@ -711,13 +722,17 @@ class SiteTree extends DataObject {
|
|||||||
* @return boolean True if the current user can edit this page.
|
* @return boolean True if the current user can edit this page.
|
||||||
*/
|
*/
|
||||||
public function canEdit($member = null) {
|
public function canEdit($member = null) {
|
||||||
if(Permission::checkMember($member, "ADMIN")) return true;
|
|
||||||
if(!$member) $member = Member::currentUser();
|
if(!$member) $member = Member::currentUser();
|
||||||
|
|
||||||
|
if(Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
|
// DEPRECATED 2.3: use canEdit() instead
|
||||||
|
$results = $this->extend('alternateCanEdit', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
// decorated access checks
|
// decorated access checks
|
||||||
$args = array($member, true);
|
$results = $this->extend('canEdit', $member);
|
||||||
$this->extend('alternateCanEdit', $args);
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
if($args[1] == false) return false;
|
|
||||||
|
|
||||||
// if page can't be viewed, don't grant edit permissions
|
// if page can't be viewed, don't grant edit permissions
|
||||||
if(!$this->canView()) return false;
|
if(!$this->canView()) return false;
|
||||||
@ -754,20 +769,27 @@ class SiteTree extends DataObject {
|
|||||||
* application.
|
* application.
|
||||||
*
|
*
|
||||||
* Denies permission if any of the following conditions is TRUE:
|
* Denies permission if any of the following conditions is TRUE:
|
||||||
* - alternateCanPublish() on any decorator returns FALSE
|
* - canPublish() on any decorator returns FALSE
|
||||||
* - canEdit() returns FALSE
|
* - canEdit() returns FALSE
|
||||||
*
|
*
|
||||||
* @uses alternateCanPublish()
|
* @uses DataObjectDecorator->canPublish()
|
||||||
*
|
*
|
||||||
* @param Member $member
|
* @param Member $member
|
||||||
* @return boolean True if the current user can publish this page.
|
* @return boolean True if the current user can publish this page.
|
||||||
*/
|
*/
|
||||||
public function canPublish($member = null) {
|
public function canPublish($member = null) {
|
||||||
|
if(!$member) $member = Member::currentUser();
|
||||||
|
|
||||||
|
if(Permission::checkMember($member, "ADMIN")) return true;
|
||||||
|
|
||||||
|
// DEPRECATED 2.3: use canPublish() instead
|
||||||
|
$results = $this->extend('alternateCanPublish', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
// If we have a result, then that means at least one decorator specified alternateCanPublish
|
// If we have a result, then that means at least one decorator specified alternateCanPublish
|
||||||
// Allow the permission check only if *all* voting decorators allow it.
|
// Allow the permission check only if *all* voting decorators allow it.
|
||||||
if(!$member) $member = Member::currentUser();
|
$results = $this->extend('canPublish', $member);
|
||||||
$results = $this->extend('alternateCanPublish', $member);
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
if($results && is_array($results)) return min($results);
|
|
||||||
|
|
||||||
// Normal case
|
// Normal case
|
||||||
return $this->canEdit();
|
return $this->canEdit();
|
||||||
@ -830,8 +852,11 @@ class SiteTree extends DataObject {
|
|||||||
}
|
}
|
||||||
$tags .= "<meta http-equiv=\"Content-Language\" content=\"". Translatable::current_lang() ."\"/>\n";
|
$tags .= "<meta http-equiv=\"Content-Language\" content=\"". Translatable::current_lang() ."\"/>\n";
|
||||||
|
|
||||||
|
// DEPRECATED 2.3: Use MetaTags
|
||||||
$this->extend('updateMetaTags', $tags);
|
$this->extend('updateMetaTags', $tags);
|
||||||
|
|
||||||
|
$this->extend('MetaTags', $tags);
|
||||||
|
|
||||||
return $tags;
|
return $tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
class DataObjectDecoratorTest extends SapphireTest {
|
class DataObjectDecoratorTest extends SapphireTest {
|
||||||
static $fixture_file = 'sapphire/tests/DataObjectTest.yml';
|
static $fixture_file = 'sapphire/tests/DataObjectDecoratorTest.yml';
|
||||||
|
|
||||||
function testOneToManyAssociationWithDecorator() {
|
function testOneToManyAssociationWithDecorator() {
|
||||||
// Fails in RestfulServerTest
|
// Fails in RestfulServerTest
|
||||||
@ -31,6 +31,31 @@ class DataObjectDecoratorTest extends SapphireTest {
|
|||||||
$contact->delete();
|
$contact->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testPermissionDecoration() {
|
||||||
|
// testing behaviour in isolation, too many sideeffects and other checks
|
||||||
|
// in SiteTree->can*() methods to test one single feature reliably with them
|
||||||
|
|
||||||
|
$obj = $this->objFromFixture('DataObjectDecoratorTest_MyObject', 'object1');
|
||||||
|
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||||
|
$admin = $this->objFromFixture('Member', 'admin');
|
||||||
|
|
||||||
|
$this->assertFalse(
|
||||||
|
$obj->canOne($websiteuser),
|
||||||
|
'Both decorators return true, but original method returns false'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertFalse(
|
||||||
|
$obj->canTwo($websiteuser),
|
||||||
|
'One decorator returns false, original returns true, but decorator takes precedence'
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->assertTrue(
|
||||||
|
$obj->canThree($admin),
|
||||||
|
'Undefined decorator methods returning NULL dont influence the original method'
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataObjectDecoratorTest_Member extends DataObject implements TestOnly {
|
class DataObjectDecoratorTest_Member extends DataObject implements TestOnly {
|
||||||
@ -55,6 +80,7 @@ class DataObjectDecoratorTest_ContactRole extends DataObjectDecorator implements
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DataObjectDecoratorTest_RelatedObject extends DataObject implements TestOnly {
|
class DataObjectDecoratorTest_RelatedObject extends DataObject implements TestOnly {
|
||||||
@ -71,4 +97,68 @@ class DataObjectDecoratorTest_RelatedObject extends DataObject implements TestOn
|
|||||||
}
|
}
|
||||||
|
|
||||||
DataObject::add_extension('DataObjectDecoratorTest_Member', 'DataObjectDecoratorTest_ContactRole');
|
DataObject::add_extension('DataObjectDecoratorTest_Member', 'DataObjectDecoratorTest_ContactRole');
|
||||||
|
|
||||||
|
class DataObjectDecoratorTest_MyObject extends DataObject implements TestOnly {
|
||||||
|
|
||||||
|
static $db = array(
|
||||||
|
'Title' => 'Varchar',
|
||||||
|
);
|
||||||
|
|
||||||
|
function canOne($member = null) {
|
||||||
|
// decorated access checks
|
||||||
|
$results = $this->extend('canOne', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canTwo($member = null) {
|
||||||
|
// decorated access checks
|
||||||
|
$results = $this->extend('canTwo', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canThree($member = null) {
|
||||||
|
// decorated access checks
|
||||||
|
$results = $this->extend('canThree', $member);
|
||||||
|
if($results && is_array($results)) if(!min($results)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataObjectDecoratorTest_Ext1 extends DataObjectDecorator implements TestOnly {
|
||||||
|
|
||||||
|
function canOne($member = null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canTwo($member = null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canThree($member = null) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class DataObjectDecoratorTest_Ext2 extends DataObjectDecorator implements TestOnly {
|
||||||
|
|
||||||
|
function canOne($member = null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canTwo($member = null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function canThree($member = null) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DataObject::add_extension('DataObjectDecoratorTest_MyObject', 'DataObjectDecoratorTest_Ext1');
|
||||||
|
DataObject::add_extension('DataObjectDecoratorTest_MyObject', 'DataObjectDecoratorTest_Ext2');
|
||||||
?>
|
?>
|
@ -11,7 +11,6 @@ PageComment:
|
|||||||
comment4:
|
comment4:
|
||||||
Name: Bob
|
Name: Bob
|
||||||
Comment: Second comment by Bob
|
Comment: Second comment by Bob
|
||||||
|
|
||||||
Page:
|
Page:
|
||||||
home:
|
home:
|
||||||
Title: Home
|
Title: Home
|
||||||
@ -22,4 +21,18 @@ Page:
|
|||||||
Comments: =>PageComment.comment3,=>PageComment.comment4
|
Comments: =>PageComment.comment3,=>PageComment.comment4
|
||||||
page2:
|
page2:
|
||||||
Title: Second Page
|
Title: Second Page
|
||||||
|
Permission:
|
||||||
|
adminpermission:
|
||||||
|
Code: ADMIN
|
||||||
|
Group:
|
||||||
|
admingroup:
|
||||||
|
Permissions: =>Permission.adminpermission
|
||||||
|
Member:
|
||||||
|
admin:
|
||||||
|
Email: admin@test.com
|
||||||
|
Groups: =>Group.admingroup
|
||||||
|
websiteuser:
|
||||||
|
Email: websiteuser@test.com
|
||||||
|
DataObjectDecoratorTest_MyObject:
|
||||||
|
object1:
|
||||||
|
Title: Object 1
|
Loading…
Reference in New Issue
Block a user