Jump to:

23376 Posts in 18232 Topics by 2867 members

General Questions

SilverStripe Forums » General Questions » Help with DOM/many_many and Search

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

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

Page: 1
Go to End
Author Topic: 1966 Views
  • AlaVive
    Avatar
    Community Member
    42 Posts

    Help with DOM/many_many and Search Link to this post

    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!)

  • javelin
    Avatar
    Community Member
    12 Posts

    Re: Help with DOM/many_many and Search Link to this post

    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):
    http://www.silverstripe.org/form-questions/show/282088?start=0

    I'll be working from that from now on.

    Now if you've found a solution?

    1966 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.