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're retiring the forums!

The SilverStripe forums have passed their heyday. They'll stick around, but will be read only. We'd encourage you to get involved in the community via the following channels instead:

Customising the CMS /

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

Exclude Dataobjects from modeladmin searchresults


Go to End


9 Posts   3665 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, 1899 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, 1899 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, 1899 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