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.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

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

SearchContext and ModelAdmin issue


3 Posts   331 Views


Community Member, 4 Posts

5 February 2014 at 6:20am

Edited: 05/02/2014 7:37am

I am having enormous amount of problems with this framework/cms. Any help would be appreciated at this point...

So here is my problems:
I am trying to do something relatively simple: listing the groups that each member belongs to on the member listing page, and then be able to search on these listed member groups.

So that i can could have the search functionality i had to extend the model admin

class CartusModelAdmin extends ModelAdmin{
   private static $managed_models = array('CartusMember');
   private static $url_segment = "members";
   private static $menu_title = "Network Members";
   private static $tree_class = 'Group';
   private static $subitem_class = 'Member';
   private static $allowed_actions = array("SearchForm",'groups');

   public $showImportForm = false;

public function getEditForm($id=null,$fields=null){
      $form = parent::getEditForm($id, $fields);

      $gridField = $form->Fields()->fieldByName($this->sanitiseClassName($this->modelClass));

      $con = $gridField->getConfig()->getComponentByType('GridFieldDataColumns');
      $con->setDisplayFields(array("Surname"=>"Last Name","Email"=>"Email Address","StatusName"=>"Status","DefaultCartusGroup"=>"Default Group","GroupsAsString"=>"Groups"));

      return $form;

public function getSearchContext(){
      $search_status = "Active";
      $search_groups ="";
      if($this->request->getVar('q') != ""){
         $q = $this->request->getVar('q');
            $search_status = $q['StatusName'];
            $search_groups = $q['Groups'];

      $context = parent::getSearchContext();
      $f = $context->getFields();
      $f->push(new ListboxField('q[StatusName]','Status',CartusConfig::$allstatus,$search_status,null,true));
      $f->push(new ListboxField('q[Groups]','Groups',DataObject::get("Group")->map('ID','Title')->toArray(),$search_groups,null,true));
      $filters = array(
            'Email' => new PartialMatchFilter('Email')
            ,'StatusName' => new ExactMatchFilter('StatusName')
            ,'Groups' => new ExactMatchFilter('GroupsAsString') //<-- PROBLEM AREA

      return $context;


class CartusMemberExtension extends DataExtension {
   //public static $allowed_actions = array("SearchForm");
   public static $db= array(
         "DefaultCartusGroup" => "Varchar(255)"
         ,"StatusName" =>"Enum('Active,Legacy User,Pending Access,Inactive,Password Locked,Denied,Expired,New Account')"//HAS to match the same order and name as CartusConfig::allstatus property
         ,"StatusReason" => "Enum('Not in Network,Removed from Network,Client Directed - Limited Restricted Access Supplier,User no longer in Role,User registered in Error,User Not Accessing Site,Cartus Leadership Directed Access Removal')"
   private static $summary_fields = array('Surname','Email','StatusName','DefaultCartusGroup','GroupsAsString');

   public function updateCMSFields(Fieldlist $fields) {
      $fields->addFieldToTab("Root.Main",new DropdownField('DefaultCartusGroup','Default Cartus Group',self::getMemberGroups("val_val"), $multiple=false));
      $fields->addFieldToTab("Root.Main",new DropdownField('StatusName','Status',CartusConfig::$allstatus,$multiple=false));
      $ff = new DropdownField('StatusReason','Reason',CartusConfig::$allreasons,$multiple=false);

      return $fields;
   public function getGroupName($id){
      $g = DataObject::get_one("Group", "ID ='".$id."'");
      return $g->getTreeTitle();
   public static function getAllGroups(){
      return DataObject::get("Group")->map('ID','Title');
   public static function getAllGroupsTitleTitle(){
      return DataObject::get("Group")->map('Title','Title');

* @param string $type = id_val will return array[$id]=$val while val_val will return array[$val]=$val
* @return multitype:NULL
   public function getMemberGroups($type="id_val"){
      $id = Controller::curr()->getRequest()->param('ID');
      //   $member = Member::get()->byID($id);
      $arr_grp = array();
      if($id != "new"){
         $member_groups = permission::groupList($id);
         foreach($member_groups as $gid){
            $g = DataObject::get_one("Group", "ID ='".$gid."'");
            if($type =="id_val")
            elseif($type =="val_val")
      return $arr_grp;
   public function getGroupsAsString(){
      $g = DB::query("SELECT DISTINCT `Group`.`Title` FROM `Group`
                      INNER JOIN `Group_Members` AS `GM` ON `GM`.`GroupID` = `Group`.`ID` WHERE `GM`.`MemberID`='".$this->owner->ID."'");

      $gg =array();
      foreach ($g as $gr){
         $gg[] = $gr['Title'];
      if (count($gg) ==0) {
         return 'no Group';
      return implode(', ', $gg);
      // or if one field is not enough for you, you can use a foreach loop:
      // $teamsArray= array();
      // foreach ($this->Teams() as $team) {
      // $teamsArray[] = "{$team->ID} {$team->Title}";
      // }
      // return implode(', ', $teamsArray);



class CartusMember extends Member {

   public static $allowed_actions = array("groups");

   private static $searchable_fields = array("Email","StatusName");
   private static $field_labels = array(
         'Surname' => 'Last Name'
         ,'StatusName' => 'Status'
         ,'DefaultCartusGroup'=>'Default Group'
   static $belongs_many_many = array(
         "Groups" => "Group"
   private static $summary_fields = array('Surname','Email','StatusName','DefaultCartusGroup','GroupsAsString');

So the CartusMember class which extend the member class managed by the CartusModelAdmin allows me to tie in the GroupsAsString which then gets the groups a user belongs to and make a comma seperated string which then gets inserted into the listing.

Why do i get an error that " the column GroupsAsString is a unknown column in the where clause" If i already tied in the listing page with the group why is it not joined in searchresults?

Maybe i am doing this all wrong.

the end goal for this is:
1. I want to be able to list members with the groups they belong to and
2. search members by groups that they belong to.



Community Member, 4 Posts

7 February 2014 at 4:31am

Ok the solution is to create my own custom filter class and update the getSearchContext method to point to that new filter class.

public function getSearchContext(){
$filters = array(
'Email' => new PartialMatchFilter('Email')
,'StatusName' => new ExactMatchFilter('StatusName')
,'Groups' => new ExactMatchFilter('GroupsAsString') //<-- PROBLEM AREA



public function getSearchContext(){
$filters = array(
'Email' => new PartialMatchFilter('Email')
,'StatusName' => new ExactMatchFilter('StatusName')
,'Groups' => new GroupsRelationsFilter('Groups') //<-- PROBLEM AREA

class GroupsRelationsFilter extends SearchFilter{

protected function applyOne(DataQuery $query){

public function apply(DataQuery $query) {
$values = array();
foreach($this->getValue() as $value) {
$values[] = Convert::raw2sql($value);
$query->leftJoin('Group_Members','`Group_Members`.`MemberID` = `Member`.`ID`')->leftJoin('Group','`Group`.`ID` = `Group_Members`.`GroupID`');
$vv = array();
foreach ($values as $v ){
$vv[] ="`Group`.`ID`='$v'";

return $query;

protected function excludeOne(DataQuery $query) {

public function isEmpty() {
return $this->getValue() == null || $this->getValue() == '';



Community Member, 2 Posts

16 June 2014 at 12:16pm

Love it when someone takes the time to post an answer to their own question, especially when it's likely to be useful to others