From 0a137a4840e9795475696bd5957329787fe517db Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Tue, 23 Feb 2010 01:37:15 +0000 Subject: [PATCH] ENHANCEMENT Making setting optional in MemberTableField. Field instances without will list all members unfiltered, and remove members from the database rather than the group relation. ENHANCEMENT Allow disabling of 'inline add' formfields in a MemberTableField through setPermissions(array('inlineadd')) (from r98825) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@99677 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/MemberTableField.php | 81 +++++++++++++++++--- templates/Includes/MemberTableField.ss | 14 ++-- tests/MemberTableFieldTest.php | 101 +++++++++++++++++++++++++ tests/MemberTableFieldTest.yml | 27 +++++++ 4 files changed, 206 insertions(+), 17 deletions(-) create mode 100644 tests/MemberTableFieldTest.php create mode 100644 tests/MemberTableFieldTest.yml diff --git a/code/MemberTableField.php b/code/MemberTableField.php index 0c4dfb06..4ce8be34 100755 --- a/code/MemberTableField.php +++ b/code/MemberTableField.php @@ -30,6 +30,8 @@ class MemberTableField extends ComplexTableField { public $popupClass = 'MemberTableField_Popup'; + public $itemClass = 'MemberTableField_Item'; + static $data_class = 'Member'; /** @@ -37,6 +39,15 @@ class MemberTableField extends ComplexTableField { * @var int */ public static $page_size = 20; + + protected $permissions = array( + "add", + "edit", + "show", + "delete", + 'inlineadd' + //"export", + ); /** * Constructor method for MemberTableField. @@ -47,7 +58,7 @@ class MemberTableField extends ComplexTableField { * @param DataObjectSet $members Optional set of Members to set as the source items for this field * @param boolean $hidePassword Hide the password field or not in the summary? */ - function __construct($controller, $name, $group, $members = null, $hidePassword = true) { + function __construct($controller, $name, $group = null, $members = null, $hidePassword = true) { $sourceClass = self::$data_class; $SNG_member = singleton($sourceClass); $fieldList = $SNG_member->summaryFields(); @@ -64,7 +75,7 @@ class MemberTableField extends ComplexTableField { } elseif(is_numeric($group)) { $this->group = DataObject::get_by_id('Group', $group); } - } else if(isset($_REQUEST['ctf']) && is_numeric($_REQUEST['ctf'][$this->Name()]["ID"])) { + } else if(isset($_REQUEST['ctf'][$this->Name()]["ID"]) && is_numeric($_REQUEST['ctf'][$this->Name()]["ID"])) { $this->group = DataObject::get_by_id('Group', $_REQUEST['ctf'][$this->Name()]["ID"]); } @@ -76,7 +87,7 @@ class MemberTableField extends ComplexTableField { // @todo shouldn't this use $this->group? It's unclear exactly // what group it should be customising the custom Member set with. - if($members) { + if($members && $group) { $this->setCustomSourceItems($this->memberListWithGroupID($members, $group)); } @@ -240,6 +251,17 @@ class MemberTableField extends ComplexTableField { $this->group = $group; } + /** + * @return Group + */ + function getGroup() { + return $this->group; + } + + function setController($controller) { + $this->controller = $controller; + } + function GetControllerName() { return $this->controller->class; } @@ -329,6 +351,7 @@ class MemberTableField extends ComplexTableField { $start = isset($_REQUEST['ctf'][$this->Name()]['start']) ? $_REQUEST['ctf'][$this->Name()]['start'] : 0; $this->sourceItems = false; + if($this->group) { $this->sourceItems = $this->group->Members( $this->pageSize, // limit @@ -336,6 +359,13 @@ class MemberTableField extends ComplexTableField { $this->sourceFilter, $this->sourceSort ); + } else { + $this->sourceItems = DataObject::get(self::$data_class, + $this->sourceFilter, + $this->sourceSort, + null, + array('limit' => $this->pageSize, 'start' => $start) + ); } // Because we are not used $this->upagedSourceItems any more, and the DataObjectSet is usually the source // that a large member set runs out of memory. we disable it here. @@ -377,6 +407,33 @@ class MemberTableField_Popup extends ComplexTableField_Popup { } +class MemberTableField_Item extends ComplexTableField_Item { + + function Actions() { + $actions = parent::Actions(); + + foreach($actions as $action) { + if($action->Name == 'delete') { + if($this->parent->getGroup()) { + $action->TitleText = _t('MemberTableField.DeleteTitleText', + 'Delete from this group', + PR_MEDIUM, + 'Delete button hover text' + ); + } else { + $action->TitleText = _t('MemberTableField.DeleteTitleTextDatabase', + 'Delete from database and all groups', + PR_MEDIUM, + 'Delete button hover text' + ); + } + } + } + + return $actions; + } +} + class MemberTableField_ItemRequest extends ComplexTableField_ItemRequest { /** * Deleting an item from a member table field should just remove that member from the group @@ -386,17 +443,21 @@ class MemberTableField_ItemRequest extends ComplexTableField_ItemRequest { return false; } - $groupID = $this->ctf->sourceID(); - $group = DataObject::get_by_id('Group', $groupID); - - if ($group) { + // if a group limitation is set on the table, remove relation. + // otherwise remove the record from the database + if($this->ctf->getGroup()) { + $groupID = $this->ctf->sourceID(); + $group = DataObject::get_by_id('Group', $groupID); + + // Remove from group and all child groups foreach($group->getAllChildren() as $subGroup) { $this->dataObj()->Groups()->remove($subGroup); } $this->dataObj()->Groups()->remove($groupID); - } + } else { + $this->dataObj()->delete(); + } } - } -?> +?> \ No newline at end of file diff --git a/templates/Includes/MemberTableField.ss b/templates/Includes/MemberTableField.ss index 409247ba..434077ae 100755 --- a/templates/Includes/MemberTableField.ss +++ b/templates/Includes/MemberTableField.ss @@ -17,12 +17,13 @@ - <% if can(add) %> - - <% if Markable %> <% end_if %> - $AddRecordForm.CellFields - $AddRecordForm.CellActions - + <% if Can(inlineadd) %> + + <% if Markable %> <% end_if %> + $AddRecordForm.CellFields + $AddRecordForm.CellActions + + <% end_if %> <% if Markable %> <% end_if %> @@ -32,7 +33,6 @@ <% if Can(edit) %> <% end_if %> <% if Can(delete) %> <% end_if %> - <% end_if %> <% if Items %> diff --git a/tests/MemberTableFieldTest.php b/tests/MemberTableFieldTest.php new file mode 100644 index 00000000..253d99c7 --- /dev/null +++ b/tests/MemberTableFieldTest.php @@ -0,0 +1,101 @@ +objFromFixture('Member', 'member1'); + $member2 = $this->objFromFixture('Member', 'member2'); + $member3 = $this->objFromFixture('Member', 'member3'); + $group1 = $this->objFromFixture('Group', 'group1'); + + $tf = new MemberTableField( + $this, + "Members", + $group1 + ); + $members = $tf->sourceItems(); + + $this->assertContains($member1->ID, $members->column('ID'), + 'Members in the associated group are listed' + ); + $this->assertContains($member2->ID, $members->column('ID'), + 'Members in children groups are listed as well' + ); + $this->assertNotContains($member3->ID, $members->column('ID'), + 'Members in other groups are filtered out' + ); + } + + function testShowsAllMembersWithoutGroupParameter() { + $member1 = $this->objFromFixture('Member', 'member1'); + $member2 = $this->objFromFixture('Member', 'member2'); + $member3 = $this->objFromFixture('Member', 'member3'); + $group1 = $this->objFromFixture('Group', 'group1'); + + $tf = new MemberTableField( + $this, + "Members" + // no group assignment + ); + $members = $tf->sourceItems(); + + $this->assertContains($member1->ID, $members->column('ID'), + 'Members in the associated group are listed' + ); + $this->assertContains($member2->ID, $members->column('ID'), + 'Members in children groups are listed as well' + ); + $this->assertContains($member3->ID, $members->column('ID'), + 'Members in other groups are listed' + ); + } + + function testDeleteWithGroupOnlyDeletesRelation() { + $member1 = $this->objFromFixture('Member', 'member1'); + $group1 = $this->objFromFixture('Group', 'group1'); + + $tf = new MemberTableField( + $this, + "Members", + $group1 + ); + $tfItem = new MemberTableField_ItemRequest($tf, $member1->ID); + $tfItem->delete(); + + $group1->flushCache(); + + $this->assertNotContains($member1->ID, $group1->Members()->column('ID'), + 'Member relation to group is removed' + ); + $this->assertType( + 'DataObject', + DataObject::get_by_id('Member', $member1->ID), + 'Member record still exists' + ); + } + + function testDeleteWithoutGroupDeletesFromDatabase() { + $member1 = $this->objFromFixture('Member', 'member1'); + $member1ID = $member1->ID; + $group1 = $this->objFromFixture('Group', 'group1'); + + $tf = new MemberTableField( + $this, + "Members" + // no group assignment + ); + $tfItem = new MemberTableField_ItemRequest($tf, $member1->ID); + $tfItem->delete(); + + $group1->flushCache(); + + $this->assertNotContains($member1->ID, $group1->Members()->column('ID'), + 'Member relation to group is removed' + ); + DataObject::flush_and_destroy_cache(); + $this->assertFalse( + DataObject::get_by_id('Member', $member1ID), + 'Member record is removed from database' + ); + } +} \ No newline at end of file diff --git a/tests/MemberTableFieldTest.yml b/tests/MemberTableFieldTest.yml new file mode 100644 index 00000000..ee85785d --- /dev/null +++ b/tests/MemberTableFieldTest.yml @@ -0,0 +1,27 @@ +Group: + admin: + Title: Administrators + group1: + Title: Group1 + group1_child: + Title: Group1 Child + Parent: =>Group.group1 + group2: + Title: Group2 +Member: + admin: + Email: admin@example.com + Groups: =>Group.admin + member1: + Email: member1@test.com + Groups: =>Group.group1 + member2: + Email: member2@test.com + Groups: =>Group.group1_child + member3: + Email: member3@test.com + Groups: =>Group.group2 +Permission: + admin: + Code: ADMIN + GroupID: =>Group.admin \ No newline at end of file