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've moved the forum!

Please use forum.silverstripe.org for any new questions (announcement).
The forum archive will stick around, but will be read only.

You can also use our Slack channel or StackOverflow to ask for help.
Check out our community overview for more options to contribute.

All other Modules /

Discuss all other Modules here.

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

CustomSearchForm snippet


Go to End


46 Posts   17730 Views

Avatar
UncleCheese

Forum Moderator, 4102 Posts

7 August 2010 at 2:00am

Hey, Aram,

Sorry for your frustration. I'll try to look into it today, but I haven't touched this code since the day I posted it, so I'm not sure how far I'll get. Can you post the code you're using? Models, along with your CustomSearchForm and its controller?

Avatar
Carbon Crayon

Community Member, 598 Posts

7 August 2010 at 3:03am

Hi UC,

thanks for your post :)

To keep things simple I have setup the code in your original example on 2.4, so the code is as follows:

Model: GlossaryTerm.php
Controller: Page.php
Form: CustomSearchForm.php (this is the same as the file attached to your post)

This is running locally using WAMP (PHP 5.2.6, Apache 2.2).

It simply behaves as the regular search in that I get results for SiteTree objects, but not Glossary Terms.

Thanks for looking into this for me

Aram

Avatar
UncleCheese

Forum Moderator, 4102 Posts

7 August 2010 at 7:18am

Hi, Aram,

This is really unfortunate. You'll notice there are some significant differences between the 2.3 SearchForm class and its 2.4 counterpart. The most obvious difference being that 2.4 SearchForm doesn't have a searchEngine() function, which means the key function we're overloading in CustomSearchForm is never called. That explains the lack of results.

Instead of using its own native searchEngine() function, SearchForm now hands the task off to MySQLDatabase (or whichever database you're using). Very smart... search is a function of a database, not a search form.

But here's where I get lost. There's all kinds of business logic placed in the MySQLDatabase::searchEngine() function, including many, many references to SiteTree and File (the two searchable classes that Sapphire rams down our throats). So, why, I'm wondering, would Silverstripe write a database class that is so tightly coupled with the SiteTree paradigm? It seems very half baked to me. They recognized that a database class should be responsible for searching, but they didn't take it all the way to the hoop and make it CMS agnostic.

This really pins us in a corner, I'm afraid. The MySQLDatabase class is not only not subclassable, but it's not really decoratable, either. They don't really give us any extend() methods to work our way in. And lastly, the icing on the cake is that searchEngine() doesn't return a MySQLQuery object. Rather, it returns a complete DOSet, so even if we wanted to customise the query, we don't have that opportunity. Another really surprising decision there, to make the a database class so aware of other, somewhat disparate, elements of the framework. IMO, a database class should not know what a DataObjectSet is. Further downstream in the ORM, of course, but not in something as fundamental as MySQLDatabase.

So, some strange code organization, there... bottom line is, we're SOL unless you want to create your own search form, which, really isn't too huge a task. I've been enamoured with the SearchContext object lately. Very useful.

Sorry, mate. Good luck, and let me know if you need any help building an alternative solution. I might be able to guide you in the right direction.

Avatar
Carbon Crayon

Community Member, 598 Posts

8 August 2010 at 3:09am

Hi UC,

Thank you so much for looking into it for me. Having understood it after reading your post I have created a mini-module to get your origonal code working in 2.4. Basically it does as you suggested, combining the SearchForm from 2.3 with the CustomSearchForm code and then added 2 decorators for SiteTree and File as in 2.4 they don't have the fulltext indexes that are required by the old search.

So effectively this module takes things back to how they were when you originally posted this code :)

Oh I did add one thing, the option to define the searchable fields using $frontend_searchable_fields, because I needed to have a different set of searchable fields for my model admin implementation to my front end. It will still pickup $searchable_fields if you don't set the frontend_searchable_fields

I also included an extended version of your example DataObject which includes the code for displaying the GlossaryTerm on the GlossaryPage.

Enjoy! I bloody well am!!

Thanks again UC :)

Attached Files
Avatar
vancouverWill

Community Member, 121 Posts

27 August 2010 at 10:50am

Edited: 27/08/2010 11:49am

Aram and UncleCheese. Thats awesome best solution I've seen so far. Sphinx may work with some hosting providers but HostGator which i use have categorically told me that I can not use it so need another way. Do you know is this will for extensions of the Page class the same way you have it working for DataObjects?

Thanks again

-edit- also for some weird reason I can't see at the moment I can get your forms to work and find a glossary term only if the glossaryPage to which they are attached is a child of another glossaryPage

-edit 2- @UncleCheese- You have mentioned a few times about searchcontext, this seems like a legitimate option for searching one dataObject but is there a way to adapt it to search through multiple dataobjects or a dataobjects a pagesubclass?

Avatar
Carbon Crayon

Community Member, 598 Posts

27 August 2010 at 12:19pm

Edited: 27/08/2010 12:21pm

Hi Will,

I recently tried to get this working with site tree objects but to no avail, I kep getting unknown column errors so I ended up using a dirty work around - basically hijacking the Metadata Description and populating it with an amalgamation of the text fields I wanted to be searchable, then replacing the Meta Description with a new field so the user is none the wiser and returning custom metatags to ensure the frankenstein text never makes it into the template.

It will make you feel dirty, but it works!

However if anyone can make this code work for sitetree object that would be much more awesome ;)

Not sure about ur problem....cant say I have come accross that one. Try posting your code in pastie, I'll take a look

Aram

Avatar
vancouverWill

Community Member, 121 Posts

27 August 2010 at 12:35pm

Thanks Aram

I'll double check my code before I post it. Your answer sounds like a good idea regardless of whether it is a bit dirty. To do that would you use onbefore write to save it into metadescription. and suppose you have a class called tripecolumnpage which extends page.php . Then I could use the onbefore write function in tripecolumnpage.php?

Also just to be sure you can set this to work with multiple dataobjects? Thanks

Avatar
Carbon Crayon

Community Member, 598 Posts

27 August 2010 at 10:25pm

Hi Will,

Yep, onBeforeWrite() does the trick, just build the text from your other fields then assign it to the MetaDescription field. And yes, you can create that in any page class you like, giving each class a custom onBeforeWrite, or a general one in Page.

And yes, you can add the CustomSearch to as many DO as you like :)

Aram