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   2541 Views

Avatar
Matze0681

Community Member, 25 Posts

23 September 2010 at 5:31pm

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

Forum Moderator, 1799 Posts

24 September 2010 at 12:52am

Edited: 24/09/2010 12:54am

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

Community Member, 271 Posts

24 September 2010 at 1:19am

Edited: 24/09/2010 1:19am

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

Forum Moderator, 1799 Posts

24 September 2010 at 1:22am

Hey Martijn,

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

Avatar
Martijn

Community Member, 271 Posts

24 September 2010 at 2:48am

You mean in the DO itself?

Not that I know..

Avatar
Martijn

Community Member, 271 Posts

28 September 2010 at 3:45am

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

Forum Moderator, 1799 Posts

28 September 2010 at 4:04am

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

Community Member, 271 Posts

28 September 2010 at 5:13am

Edited: 28/09/2010 5:15am

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