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.

Customising the CMS

Exclude Dataobjects from modeladmin searchresults


Go to End
Reply

9 Posts   2460 Views

Avatar
Matze0681

23 September 2010 at 5:31pm Community Member, 25 Posts

hi,

i need to exclude Dataobjects from the search results by default. For example dont show dataobjects in manged model´s searchresult where a field "ShowInCMS = false".
couldnt find a clue about this..

thanks in advance
matze

Avatar
swaiba

24 September 2010 at 12:52am (Last edited: 24 September 2010 12:54am), Forum Moderator, 1796 Posts

Check this out, works really nicely...

http://www.silverstripe.org/general-questions/show/255859?start=16

I'd add the extra condition to ensure only the managed model you require is filtered...

if ($this->modelClass == 'DataObjectName')
{
   $query->where[] = "ShowInCMS = true";
}

Hope this helps

Barry

Avatar
Martijn

24 September 2010 at 1:19am (Last edited: 24 September 2010 1:19am), Community Member, 271 Posts

I was just struggling with the same, but then for frontend.

A much cleaner way is to decorate the DataObject and use augmentSQL.

So something like:

// _config.php Object::add_extension('SomeObject', 'SomeObjectDecorator');
class SomeObjectDecorator extends DataObjectDecorator {      
   
   function augmentSQL(SQLQuery &$query) {
      if(!is_subclass_of(Controller::curr(), 'ContentController')){ // not on frontend
         $query->where[] = "\"SomeObject\".\"ShowInCMS\" = 1";
      }
   }
}

Avatar
swaiba

24 September 2010 at 1:22am Forum Moderator, 1796 Posts

Hey Martijn,

Could you do the same thing, but without having to decorate the DataObject?

Avatar
Martijn

24 September 2010 at 2:48am Community Member, 271 Posts

You mean in the DO itself?

Not that I know..

Avatar
Martijn

28 September 2010 at 3:45am Community Member, 271 Posts

I found an other way to limit searchresults based on the canView method in your dataobject by subclassing the ModelAdmin_CollectionController as well.

in your CustomModelAdmin set :

public static $collection_controller_class = "MyCustomModelAdmin_CollectionController";

Use code below to overload the getResultsTable method and perform a canView check on each sourceItem:

class MyCustomAdmin_CollectionController extends ModelAdmin_CollectionController {
   
   // copied from ModelAdmin
   function getResultsTable($searchCriteria) {
      
      $summaryFields = $this->getResultColumns($searchCriteria);

      $className = $this->parentController->resultsTableClassName();
      $tf = new $className(
         $this->modelClass,
         $this->modelClass,
         $summaryFields
      );

      $tf->setCustomQuery($this->getSearchQuery($searchCriteria));
      $tf->setPageSize($this->parentController->stat('page_length'));
      $tf->setShowPagination(true);
      // @todo Remove records that can't be viewed by the current user
      $tf->setPermissions(array_merge(array('view','export'), TableListField::permissions_for_object($this->modelClass)));

      // csv export settings (select all columns regardless of user checkbox settings in 'ResultsAssembly')
      $exportFields = $this->getResultColumns($searchCriteria, false);
      $tf->setFieldListCsv($exportFields);

      $url = '<a href=\"' . $this->Link() . '/$ID/edit\">$value</a>';
      $tf->setFieldFormatting(array_combine(array_keys($summaryFields), array_fill(0,count($summaryFields), $url)));
      
      // performCanViewOnEachItem
      if($tf->sourceItems()){
         $tf->setCustomSourceItems($this->performCanViewOnEachItem($tf->sourceItems()));   
      }
      
      return $tf;
   }
   
   function performCanViewOnEachItem($sourceItems){
      if($items = $sourceItems){
         foreach($items as $item){
            if(!$item->canView()){
               $items->remove($item);
            }         
         }
         return $items;   
      }
   }
}

Avatar
swaiba

28 September 2010 at 4:04am Forum Moderator, 1796 Posts

Hmmm... I'll stick with the original method (found here http://www.silverstripe.org/general-questions/show/255859?start=16) because it is the simplest and impacts the least code. But as ever many thanks for all your contributions.

<begin thread pollution>
I have to get round to a ModelAdmin improvements module that includes a bunch of stuff I have done and I'll add helpers for this as I did say I would at the uk ss meetup. BTW I've test the Panel Admin and it is great!

Avatar
Martijn

28 September 2010 at 5:13am (Last edited: 28 September 2010 5:15am), Community Member, 271 Posts

Thanks!

Trunk is now updated with canView, canEdit, canDelete on each item.

Yes, the example you linked to is less code, but I think those permissions need to be in the DataObject itself. What about if you want to do things like this:

//only current user items, except for admins
   function canView(){
      if(!Permission::check('ADMIN')){
         if($this->AuthorID == Member::currentUserID()){
            return true;   
         }
      } else {//if admin
         return true;
      }
   }

   //same as canView
   function canEdit(){
      return $this->canView();
   }
   //only when there are less then 10 SomeChildClasses
   function canCreate(){
      if($this->SomeChildClasses()->Count() <= 10){
         return true;
      }
   }
   //only if not more than a week old.
   function canDelete(){
      if(!Permission::check('ADMIN')){
         if(strtotime($this->Created) >= strtotime(date('Y-m-d', strtotime('-1 week')))){
            return true;   
         }
      } else {//if admin
       return true;
}      
   }

and on another DataObject, you have even more different Can permissions set...
I would not want that all set in my AdminModule, but in the DO itself..

At least, I do :)

Go to Top