diff --git a/_config/config.yml b/_config/config.yml index 50ea2b3..11eea88 100644 --- a/_config/config.yml +++ b/_config/config.yml @@ -4,3 +4,6 @@ Name: fulltextsearchconfig SilverStripe\ORM\DataObject: extensions: - SilverStripe\FullTextSearch\Search\Extensions\SearchUpdater_ObjectHandler +SilverStripe\CMS\Controllers\ContentController: + extensions: + - SilverStripe\FullTextSearch\Solr\Control\ContentControllerExtension diff --git a/docs/en/index.md b/docs/en/index.md index fab1dfb..072399e 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -46,7 +46,13 @@ SilverStripe\FullTextSearch\Search\Updaters\SearchUpdater: ## Basic usage -Basic usage is a four step process: +If you have the [CMS module](https://github.com/silverstripe/silverstripe-cms) installed, you will be able to simply add `$SearchForm` to your template to add a Solr search form. Default configuration is added via the [`ContentControllerExtension`](/src/Solr/Control/ContentControllerExtension.php) and alternative [`SearchForm`](/src/Solr/Forms/SearchForm.php). + +Ensure that you _don't_ have `SilverStripe\ORM\Search\FulltextSearchable::enable()` set in `_config.php`, as the `SearchForm` action provided by that class will conflict. + +You can override the default template with a new one at `templates/Layout/Page_results_solr.ss`. + +Otherwise, basic usage is a four step process: 1). Define an index in SilverStripe (Note: The specific connector index instance - that's what defines which engine gets used) diff --git a/src/Search/Updaters/SearchUpdater.php b/src/Search/Updaters/SearchUpdater.php index 5d3d614..f4e7ca3 100644 --- a/src/Search/Updaters/SearchUpdater.php +++ b/src/Search/Updaters/SearchUpdater.php @@ -105,8 +105,8 @@ class SearchUpdater 'command' => $command, 'fields' => array() ); - } // Otherwise update the class label if it's more specific than the currently recorded one - elseif (is_subclass_of($class, $writes[$key]['class'])) { + // Otherwise update the class label if it's more specific than the currently recorded one + } elseif (is_subclass_of($class, $writes[$key]['class'])) { $writes[$key]['class'] = $class; } diff --git a/src/Solr/Control/ContentControllerExtension.php b/src/Solr/Control/ContentControllerExtension.php new file mode 100644 index 0000000..25fdef2 --- /dev/null +++ b/src/Solr/Control/ContentControllerExtension.php @@ -0,0 +1,60 @@ +owner->getRequest(); + + if ($currentRequest && $currentRequest->getVar('Search')) { + $searchText = $currentRequest->getVar('Search'); + } + + $fields = FieldList::create( + TextField::create('Search', false, $searchText) + ); + $actions = FieldList::create( + FormAction::create('results', _t('SilverStripe\\CMS\\Search\\SearchForm.GO', 'Go')) + ); + return SearchForm::create($this->owner, 'SearchForm', $fields, $actions); + } + + /** + * Process and render search results. + * + * @param array $data The raw request data submitted by user + * @param SearchForm $form The form instance that was submitted + * @param HTTPRequest $request Request generated for this action + */ + public function results($data, $form, $request) + { + $data = [ + 'Results' => $form->getResults(), + 'Query' => DBField::create_field('Text', $form->getSearchQuery()), + 'Title' => _t('SilverStripe\\CMS\\Search\\SearchForm.SearchResults', 'Search Results') + ]; + return $this->owner->customise($data)->renderWith(['Page_results_solr', 'Page_results', 'Page']); + } +} diff --git a/src/Solr/Forms/SearchForm.php b/src/Solr/Forms/SearchForm.php new file mode 100644 index 0000000..a5a2a91 --- /dev/null +++ b/src/Solr/Forms/SearchForm.php @@ -0,0 +1,102 @@ + 'Text' + ); + + /** + * @param RequestHandler $controller + * @param string $name The name of the form (used in URL addressing) + * @param FieldList $fields Optional, defaults to a single field named "Search". Search logic needs to be customized + * if fields are added to the form. + * @param FieldList $actions Optional, defaults to a single field named "Go". + */ + public function __construct( + RequestHandler $controller = null, + $name = 'SearchForm', + FieldList $fields = null, + FieldList $actions = null + ) { + if (!$fields) { + $fields = FieldList::create( + TextField::create('Search', _t(__CLASS__.'.SEARCH', 'Search')) + ); + } + + if (!$actions) { + $actions = FieldList::create( + FormAction::create("results", _t(__CLASS__.'.GO', 'Go')) + ); + } + + parent::__construct($controller, $name, $fields, $actions); + + $this->setFormMethod('get'); + + $this->disableSecurityToken(); + } + + /** + * Return dataObjectSet of the results using current request to get info from form. + * Simplest implementation loops over all Solr indexes + * + * @return ArrayData + */ + public function getResults() + { + // Get request data from request handler + $request = $this->getRequestHandler()->getRequest(); + + $searchTerms = $request->requestVar('Search'); + $query = SearchQuery::create()->addSearchTerm($searchTerms); + + $params = [ + 'spellcheck' => 'true', + 'spellcheck.collate' => 'true', + ]; + + // Get the first index + $indexClasses = FullTextSearch::get_indexes(SolrIndex::class); + $indexClass = reset($indexClasses); + + /** @var SolrIndex $index */ + $index = $indexClass::singleton(); + $results = $index->search($query, -1, -1, $params); + + // filter by permission + if ($results) { + foreach ($results->Matches as $match) { + /** @var DataObject $match */ + if (!$match->canView()) { + $results->Matches->remove($match); + } + } + } + return $results; + } + + /** + * Get the search query for display in a "You searched for ..." sentence. + * + * @return string + */ + public function getSearchQuery() + { + return $this->getRequestHandler()->getRequest()->requestVar('Search'); + } +} diff --git a/templates/Layout/Page_results_solr.ss b/templates/Layout/Page_results_solr.ss new file mode 100644 index 0000000..d573908 --- /dev/null +++ b/templates/Layout/Page_results_solr.ss @@ -0,0 +1,56 @@ +
+

$Title

+ + <% if $Query %> +

You searched for "{$Query}"

+ <% end_if %> + + <% if $Results.Suggestion %> +

Did you mean $Results.SuggestionNice?

+ <% end_if %> + + <% if $Results.Matches %> + + <% else %> +

Sorry, your search query did not return any results.

+ <% end_if %> + + <% if $Results.Matches.MoreThanOnePage %> +
+ +

Page $Results.Matches.CurrentPage of $Results.Matches.TotalPages

+
+ <% end_if %> +