Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

We've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

Data Model Questions /

Moderators: martimiz, Sean, Ed, biapar, Willr, Ingo, swaiba

Filter Model Admin to only show certain records


Go to End


5 Posts   4012 Views

Avatar
Optic Blaze

Community Member, 190 Posts

10 January 2014 at 4:06am

Hi,

I have extended the Member Class so that i can have a group called mymembers.
I am making use of Model Admin and setting up permissions so that non-admins can view the info, but cant change it.
How do i filter the Model Admin to display on the group called 'mymembers' and not show all other members and all other users?

At the moment i have this:

<?php
class MemberAdmin extends ModelAdmin {
static $managed_models = array('Member');
static $url_segment = 'memberadmin';
static $menu_title = 'Member Admin';

// Set Fields for export
public function getExportFields() {
return array(
'FirstName' => 'FirstName',
'Surname' => 'Surname',
'CompanyName' => 'CompanyName',
'CompanyTel' => 'CompanyTel',
'CompanyFax'=> 'CompanyFax',
'CompanyAddress'=> 'CompanyAddress',
'CompanyEmail'=> 'CompanyEmail',
'CompanyWebsite'=> 'CompanyWebsite',
'CompanyCEO'=> 'CompanyCEO',
'IndustryGroup'=> 'IndustryGroup',
'NumberEmployees'=> 'NumberEmployees',
'Newsletter'=> 'Newsletter',
'Sectors'=> 'Sectors'
);
}

};

Avatar
swaiba

Forum Moderator, 1899 Posts

10 January 2014 at 6:45am

Hi,

Probably not the best and certainly this code isn't tested, but hope this helps...

class MemberAdmin extends ModelAdmin {
	...
	static $collection_controller_class = "MemberAdmin_CollectionController";
	...
}

class MemberAdmin_CollectionController extends ModelAdmin_CollectionController {

	function modifySearchQuery($query,$searchCriteria){

		if ($this->modelClass == 'Member'){
			//do some complex joinging sql here
			$query->where[] = '
				EXISTS (
					SELECT 1
					FROM Group_Members g_m, Group g
					WHERE g_m.MemberID = Member.ID
						AND g.ID = g_m.GroupID
						AND g.Title = 'mymembers'
				)
			';
		}

		return $query;
	}

Avatar
martimiz

Forum Moderator, 1391 Posts

10 January 2014 at 7:04am

I'm not sure if one should use the SearchContext in some way - because the actua DataList before filtering is retreived in SearchContext::getResult()... But it looks awfully complex. II suppose you could filter the list afterwards by doing something like this in your modeladmin:

	public function getList() {
		$list = parent::getList();                         //<-- takes care of custom filters, but gets all members
		if ($this->modelClass == 'Member') {
			$list = $list
				->innerjoin('Group_Members', 'Member.ID = Group_Members.MemberID')
				->innerjoin('Group', 'Group_Members.GroupID = Group.ID')
				->where("Group.Code = 'content-authors'");
		}
		return $list;
	}

You'd still have to make very very sure that an administrator isn't also a mymember, because that would be exposed as well... Tricky...

Avatar
Optic Blaze

Community Member, 190 Posts

10 January 2014 at 9:14pm

Thanks swabia & martimiz that worked really well.
I am not too concerned regarding the admins because they are not going to be part of the group.

Avatar
SpiritLevel

Community Member, 5 Posts

14 November 2016 at 12:54pm

Edited: 14/11/2016 1:23pm

As an alternative to martimiz's construction of the list, one could use:

$list = $list->filter(array('Groups.Code' => 'content-authors'));

which is possible since Member has a $belongs_many_many relation called Groups of type Group, and, Group has a property called Code.

You could add more filter criteria:

$list = $list->filter(array('Groups.Code' => 'administrators', 'FirstName'=>'David'));

Also, you can simplify if only using one criterion:

$list = $list->filter('Groups.Code','content-authors');

:)