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:

General Questions /

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

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

Help with DOM/many_many and Search

Go to End

2 Posts   2481 Views


Community Member, 42 Posts

6 November 2009 at 9:46am

Edited: 07/11/2009 11:57am

I have to be able to display a list of PDF "resource" files using DOM that lists the following attributes:

Date of upload/modification
Document Type

In the end, I need to be able to search the documents using the following search criteria:

Keywords (should search "keywords," "Description," "Date," Category" and "Keywords" fields)
Document Type

I've managed to make this work (to some extent-- still didn't figure out how to merge the attributes to be searched by the Keywords field) using the following-- implementing ComplexSearch:

In Resource.php (I must warn you, I'm green at this!)


class Resource extends DataObject
	static $db = array (
		'Name' => 'Text',
		'Type' => "Enum('Management Guides, Performance Goals, Technical Articles, Nutrition Guides')",
		'Description' => 'Text',
		'Category' => "Enum('Corporate, Chicken, Turkey')",
		'Brand' => "Text",
		'Language' => "Enum('English–USA, English–EUR, Arabic, Balkan, Bulgarian, Chinese, Czech, French, Hungarian, Portuguese, Russian, Romanian, Spanish')",
		"Keywords" => "Text",
		'Date' => 'Date'
	static $has_one = array (
		'Attachment' => 'File',
		'ResourcePage' => 'ResourcePage'
	static $searchable_fields = array(
	'Keywords' => 'PartialMatchFilter',
	'Type' => 'PartialMatchFilter',
	'Language' => 'PartialMatchFilter',
	'Brand' => 'PartialMatchFilter'
	public function getCMSFields_forPopup()
		return new FieldSet(
			new TextField('Name'),
			new DropdownField('Type','Document Type', singleton('Resource')->dbObject('Type')->enumValues()),
			new TextareaField('Description'),
			new DropdownField('Category','Category', singleton('Resource')->dbObject('Category')->enumValues()),
			new TextField('Brand'),
			new DropdownField('Language','Language', singleton('Resource')->dbObject('Language')->enumValues()),
			new CalendarDateField('Date'),
			new TextAreaField('Keywords'),
			new FileIFrameField('Attachment')
	public function getCustomSearchContext() {
		$fields = $this->scaffoldSearchFields(array('Keywords','Name','Type','Category','Brand','Language')
		$filters = array(
			'Keywords' => new PartialMatchFilter('Keywords'),
			'Name' => new PartialMatchFilter('Name'),
			'Type' => new PartialMatchFilter('Type'),
			'Category' => new PartialMatchFilter('Category'),
			'Brand' => new PartialMatchFilter('Brand'),
			'Language' => new PartialMatchFilter('Language'),
		return new SearchContext(

In my ResourcePage.php

class ResourcePage extends Page 
   static $has_many = array ( 
      'Resources' => 'Resource' 
   public function getCMSFields() 
      $f = parent::getCMSFields(); 
	  $f->removeByName("Row 2 Content");	
      $manager = new FileDataObjectManager( 
         $this, // Controller 
         'Resources', // Source name 
         'Resource', // Source class 
         'Attachment', // File name on DataObject 
            'Name' => 'Name', 
            'Description' => 'Description', 
            'Category' => 'Category', 
			'Brand' => 'Brand',
			'Language' => 'Language',
			'Date' => 'Date'
         ), // Headings 
         'getCMSFields_forPopup' // Detail fields (function name or FieldSet object) 
         // Filter clause 
         // Sort clause 
         // Join clause 
         'Category', // Name of field to filter 
         'Filter by Category', // Label for filter 
         singleton('Resource')->dbObject('Category')->enumValues() // Map for filter (could be $dataObject->toDropdownMap(), e.g.) 
      // If undefined, all types are allowed. Pass with or without a leading "."       
      // Label for the upload button in the popup 
      $manager->setBrowseButtonText("Upload (PDF files only)"); 
      // In grid view, what field will appear underneath the icon. If left out, it defaults to the file title. 
      // Plural form of the objects being managed. Used on the "Add" button. 
      // If left out, this defaults to [MyObjectName]s 
      $f->addFieldToTab("Root.Content.Resources", $manager);

      return $f; 
   function MyFileObjects() 
      $filter = Director::urlParam('Action'); 
      return $filter ? $this->Resources("Category = '$filter'") : $this->Resources();


class ResourcePage_Controller extends Page_Controller 
function FilteredResources() 
$filter = Director::urlParam('Action'); 
return $filter ? $this->Resources("Category = '$filter'") : $this->Resources(); 

In my page.php

	 * Tech Documents Search
   public function TechSearchForm() {
		$context = singleton('Resource')->getCustomSearchContext();
		$fields = $context->getSearchFields();
		$form = new Form($this, "TechSearchForm",
			new FieldSet(
				new FormAction('doSearch')
		return $form;
	 * Process and render Tech Documents search results
	public function doSearch($data, $form) {
	$context = singleton('Resource')->getCustomSearchContext();
	$results = $this->getResults($data);
	return $this->customise(array(
		'Results' => $results
	))->renderWith(array('ResourceSearch_results', 'Page'));

The problem is that the Brand, Category, and Document Type attributes need to be changed to a many_many relationship, so that multiple brand names, multiple category names, and multiple Document Types can be added to each PDF.

Furthermore, when I run a search, the search has to appear differetly on three different levels of the site:
On the corporate level, all files should be searched.
On the division level, only files related to that division and its related brands should be searched.
On the Brand pages, only files relevant to the brand should be searched.

I believe I can create three different search functions if I can just figure out the many_many relationship issue and the initial search. But, I am struggling and am on a deadline.

Can ANYONE help me?
(Thanks in advance to anyone willing to TRY!)


Community Member, 12 Posts

16 April 2010 at 5:06am

I have the exact same problem, but without DOM mixed in. I guess the only viable way is to filter the results after the search has been performed because I can't find any support for limiting the search-context to any less than a full class.

I found another forum post with a different problem that might give us some clues (post number 2):

I'll be working from that from now on.

Now if you've found a solution?