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 /

Search Form, Results, Custom Fields


Reply


17 Posts   4529 Views

Avatar
stew

Community Member, 30 Posts

15 July 2010 at 11:08pm

Barry you are a genius!

Works perfectly. The only bit that I can't workout is how to allow searching on multiple fields. At the moment I have this:

    $dos = DataObject::get('DatabaseEntry',"Address LIKE '".$strSearchQuery."'");

Just wondering how I can get it to search in Title, Category and Description as well... just don't know how, and now it's working don't want to break it all. lol.

Avatar
swaiba

Forum Moderator, 1805 Posts

15 July 2010 at 11:15pm

Glad it worked out for you :)

The following code is fairly crude search, so if I put "Bristol city" in the search it will use LIKE '%Bristol%city%'..

$arrSearchQuery = explode(' ',$form->getSearchQuery());
$strSearchQuery = '%'.implode('%',$arrSearchQuery).'%';

$dos = DataObject::get('YOURDATAOBJECT',"FIELD LIKE '".$strSearchQuery."'");

if you wanted to search two fields just expand your where clause...

$dos = DataObject::get('YOURDATAOBJECT',
"FIELD LIKE '".$strSearchQuery."'"
." OR OTHERFIELD LIKE '".$strSearchQuery."'"
);

If you want to search over a couple of DataObject... just repeat the DataObject::get and then the "if ($dos){..." this will get more objects and then push them on the search results.

if you want one set higher than the other in the results change the " $p->Relevance = 1; " part

Barry

Avatar
stew

Community Member, 30 Posts

15 July 2010 at 11:19pm

Yet again the silverstripe community comes through!

Thanks Barry, that extra bit of code worked perfectly, only a few bits left to do and the sites done :)

Avatar
stew

Community Member, 30 Posts

20 July 2010 at 12:07am

Found a wee bit of a problem, if I enter a search term that is across two or more of the fields (ie. Category and Address) then I don't get any results, it just says nothing found.

Is there a way of tweaking the code slightly to allow it to search across multiple fields?

Avatar
swaiba

Forum Moderator, 1805 Posts

20 July 2010 at 12:59am

As I said it is a bit crude, I don't have time to re-jig this right now, I can let you know later if I do. In the meantime you can try and do it yourself by...

1)repeating the whole thing afterwards like....

foreach ($arrSearchQuery as $strSearchQuery)
{
   $strSearchQuery = '%'.$strSearchQuery.'%';

   //repeat code to do DataOBject::get
   //add to $dosNewResults
}

2)
before the

//strip out the html from the results and append them to the results
//above - so that the ones with things to buy are first
if ($data['Results']->Count() > 0)

you will need to strip out the duplicates in some way... I'd suggest...

$dosNewRestults->removeDuplicates('URLSegment');

Barry

p.s. I'd really appreciate it if you had a go and posted a working version back as I'll update one of my sites using this bit of code :)

Avatar
stew

Community Member, 30 Posts

20 July 2010 at 1:10am

Thanks for the code Barry, can't get it to work though :(

Here is the full code as it stands just now:

    /////////////////////////////////////////////////////////////
    // Start Custom

    $arrSearchQuery = explode(' ',$form->getSearchQuery());
    $strSearchQuery = '%'.implode('%',$arrSearchQuery).'%';

    $dos = DataObject::get('DatabaseEntry',"Address LIKE '".$strSearchQuery."'"."OR ContactWeb LIKE '".$strSearchQuery."'"."OR ContactPhone LIKE '".$strSearchQuery."'"."OR ContactEmail LIKE '".$strSearchQuery."'"."OR Category LIKE '".$strSearchQuery."'"." OR OrganisationName LIKE '".$strSearchQuery."'" );
   

    //make our our result set
    $dosNewRestults = new DataObjectSet();

    if ($dos)
    {
      $arr = $dos->toArray();
      foreach ($arr as $do)
      {
         $p = new Page();
         $p->Title = $do->OrganisationName;
         $p->URLSegment = 'SearchForm?POSTVAR='.$do->Address;;
         $p->Content = $do->Description;;
         $p->Address = $do->Address;;
         $p->Latitude = $do->Latitude;;
         $p->Longitude = $do->Longitude;;
         $p->ContactPhone = $do->ContactPhone;;
         $p->ContactWeb = $do->ContactWeb;;
         $p->ContactEmail = $do->ContactEmail;;
         $p->Category = $do->Category;;
         $p->ID = $do->ID;;
         $p->Relevance = 1;
         $p->CanViewType = 'Anyone';

         $dosNewRestults->push($p);
      }
      }
      foreach ($arrSearchQuery as $strSearchQuery)
      {
       $strSearchQuery = '%'.$strSearchQuery.'%';

       //repeat code to do DataOBject::get
       //add to $dosNewResults
      }
      
    //strip out the html from the results and append them to the results
    //above - so that the ones with things to buy are first
    if ($data['Results']->Count() > 0)
    {
    $arr = $data['Results']->toArray();
    foreach ($arr as $do)
    {
    $do->Content = strip_tags($do->Content);
    $dosNewRestults->push($do);
         $dosNewRestults->removeDuplicates('URLSegment');
    }
    }
   

   

    $data['Results'] = $dosNewRestults;
    // End Custom
    /////////////////////////////////////////////////////////////

As an additional thing that has only just come up as I've shown the client a quick demo of the system, they want to be able to choose which records are searchable. So within the DataObjectManager have a dropdown (or checkbox) which will say "Public" and then if it's marked as public it'll be included in the results, is there a quick way of doing that? I had a quick play with adding it as a "'AND Public LIKE'".1. but it didn't work.

Thanks again Barry :)

Avatar
swaiba

Forum Moderator, 1805 Posts

20 July 2010 at 1:23am

for your public thing I'd do...

$dos = DataObject::get('DatabaseEntry',"(Address LIKE '".$strSearchQuery."'"."OR ContactWeb LIKE '".$strSearchQuery."'"."OR ContactPhone LIKE '".$strSearchQuery."'"."OR ContactEmail LIKE '".$strSearchQuery."'"."OR Category LIKE '".$strSearchQuery."'"." OR OrganisationName LIKE '".$strSearchQuery."') AND Public=1" );

(assuming public was an int field, if it was an enum or text then Public='Yes')

Avatar
stew

Community Member, 30 Posts

20 July 2010 at 1:25am

Thanks Barry, I was quite close with it, lol. Still getting my head around Silverstripe (and PHP beyond the basic templating stuff.)