I have to be able to display a list of PDF "resource" files using DOM that lists the following attributes:
Name
Description
Keywords
Language
Date of upload/modification
Brand
Category
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)
Language
Brand
Category
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!)
<?php
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(
$this->class,
$fields,
$filters
);
}
}
?>
In my ResourcePage.php
<?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
array(
'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
);
$manager->setFilter(
'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 "."
$manager->setAllowedFileTypes(array('pdf'));
// 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.
$manager->setGridLabelField('Name');
// Plural form of the objects being managed. Used on the "Add" button.
// If left out, this defaults to [MyObjectName]s
$manager->setPluralTitle('Resources');
$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",
$fields,
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!)