diff --git a/code/MemberTableField.php b/code/MemberTableField.php index 91f5647e..8bfbd052 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)); } @@ -241,6 +252,13 @@ class MemberTableField extends ComplexTableField { $this->group = $group; } + /** + * @return Group + */ + function getGroup() { + return $this->group; + } + function setController($controller) { $this->controller = $controller; } @@ -333,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 @@ -340,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. @@ -381,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 @@ -390,10 +443,15 @@ class MemberTableField_ItemRequest extends ComplexTableField_ItemRequest { return false; } - $groupID = $this->ctf->sourceID(); - $this->dataObj()->Groups()->remove($groupID); + // 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(); + $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 916a4685..7ea2d512 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