Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix/2.0.1/improve results #38

Merged
merged 7 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions _config.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

namespace Werkbot\Search;

use SilverStripe\SiteConfig\SiteConfig;

SiteConfig::add_extension(SearchSiteConfigExtension::class);
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
"license": "MIT",
"homepage": "https://github.com/werkbot/silverstripe-module-search",
"require": {
"php": "^8.1",
"silverstripe/cms": "^5",
"silverstripe/framework": "^5",
"php": "^8.0",
"silverstripe/cms": "^4",
"silverstripe/framework": "^4",
"teamtnt/tntsearch": "v4.2.1",
"ext-sqlite3": "*",
"symbiote/silverstripe-queuedjobs": "^5.1"
"symbiote/silverstripe-queuedjobs": "^4.12"
},
"autoload": {
"psr-4": {
Expand Down
164 changes: 94 additions & 70 deletions src/SearchControllerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@

namespace Werkbot\Search;

use SilverStripe\CMS\Search\SearchForm;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\ORM\ArrayList;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FormAction;
use SilverStripe\Forms\RequiredFields;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\ArrayList;
use SilverStripe\Forms\FormAction;
use SilverStripe\ORM\DataExtension;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\ORM\PaginatedList;
use Werkbot\Search\TNTSearchHelper;
use SilverStripe\Control\HTTPRequest;
use SilverStripe\Forms\RequiredFields;
use SilverStripe\ORM\ValidationResult;
use SilverStripe\CMS\Search\SearchForm;
use SilverStripe\ORM\FieldType\DBField;
use SilverStripe\SiteConfig\SiteConfig;
use TeamTNT\TNTSearch\Exceptions\IndexNotFoundException;
use Werkbot\Search\TNTSearchHelper;

class SearchControllerExtension extends DataExtension
{
Expand All @@ -33,33 +34,33 @@ class SearchControllerExtension extends DataExtension
* Site search form
*
* @return SiteSearchForm
**/
**/
public function SiteSearchForm()
{
$searchText = '';
if ($this->owner->getRequest() && $this->owner->getRequest()->getVar('Search')) {
$searchText = $this->owner->getRequest()->getVar('Search');
}
$fields = new FieldList(
TextField::create('Search', _t("Search.INPUT_LABEL", "Search"), $searchText)
->setAttribute('placeholder', _t("Search.INPUT_PLACEHOLDER", "Enter search terms"))
->setAttribute('aria-label', _t("Search.INPUT_ARIALABEL", "Enter search terms"))
->setAttribute('title', _t("Search.INPUT_TITLE", "Search"))
);
$requried = new RequiredFields('Search');
$actions = new FieldList(
FormAction::create('SiteSearchFormResults', '')
->setUseButtonTag(true)
->setButtonContent(_t("Search.BUTTON_LABEL", 'Search'))
->setAttribute('aria-label', _t("Search.BUTTON_ARIALABEL", 'Search'))
);
$form = SearchForm::create($this->owner, 'SiteSearchForm', $fields, $actions, $requried);
$form->setTemplate('Forms\\SiteSearchForm');
$form->setFormAction('/home/SiteSearchForm');

$this->owner->extend("updateSiteSearchForm", $fields, $required, $actions, $form);

return $form;
$searchText = '';
if ($this->owner->getRequest() && $this->owner->getRequest()->getVar('Search')) {
$searchText = $this->owner->getRequest()->getVar('Search');
}
$fields = new FieldList(
TextField::create('Search', _t("Search.INPUT_LABEL", "Search"), $searchText)
->setAttribute('placeholder', _t("Search.INPUT_PLACEHOLDER", "Enter search terms"))
->setAttribute('aria-label', _t("Search.INPUT_ARIALABEL", "Enter search terms"))
->setAttribute('title', _t("Search.INPUT_TITLE", "Search"))
);
$requried = new RequiredFields('Search');
$actions = new FieldList(
FormAction::create('SiteSearchFormResults', '')
->setUseButtonTag(true)
->setButtonContent(_t("Search.BUTTON_LABEL", 'Search'))
->setAttribute('aria-label', _t("Search.BUTTON_ARIALABEL", 'Search'))
);
$form = SearchForm::create($this->owner, 'SiteSearchForm', $fields, $actions, $requried);
$form->setTemplate('Forms\\SiteSearchForm');
$form->setFormAction('/home/SiteSearchForm');

$this->owner->extend("updateSiteSearchForm", $fields, $required, $actions, $form);

return $form;
}

/**
Expand All @@ -68,43 +69,43 @@ public function SiteSearchForm()
* @param array $data The raw request data submitted by user
* @param SiteSearchForm $form The form instance that was submitted
* @param HTTPRequest $request Request generated for this action
**/
**/
public function SiteSearchFormResults($searchdata, $form)
{
$start = ($this->owner->getRequest()->getVar('start')) ? (int)$this->owner->getRequest()->getVar('start') : 0;
$Results = new ArrayList();
$ErrorMessge = "";

if (isset($searchdata['Search'])) {
try {
$Results = $this->getSearchResults($searchdata['Search']);
} catch (IndexNotFoundException $e) {
$validationResult = new ValidationResult();
$validationResult->addFieldError('Message', 'Search index not found');
$form->setSessionValidationResult($validationResult);
}
$start = ($this->owner->getRequest()->getVar('start')) ? (int)$this->owner->getRequest()->getVar('start') : 0;
$Results = new ArrayList();
$ErrorMessge = "";

if (isset($searchdata['Search'])) {
try {
$Results = $this->getSearchResults($searchdata['Search']);
} catch (IndexNotFoundException $e) {
$validationResult = new ValidationResult();
$validationResult->addFieldError('Message', 'Search index not found');
$form->setSessionValidationResult($validationResult);
}

if ($this->owner->config()->get('save_search_queries')) {
// Store the Search Query
$sq = SearchQuery::create();
$sq->Query = $searchdata['Search'];
$sq->write();
}
if ($this->owner->config()->get('save_search_queries')) {
// Store the Search Query
$sq = SearchQuery::create();
$sq->Query = $searchdata['Search'];
$sq->write();
}
}

$pageLength = 10;
$this->owner->extend("updateSiteSearchFormResults", $searchdata, $form, $Results, $pageLength);

// Pack up the results
$Paged = new PaginatedList($Results, $this->owner->getRequest());
$Paged->setPageLength($pageLength);
$Paged->setPageStart($start);
$data = array(
'Results' => $Paged,
'Query' => DBField::create_field('Text', $form->getSearchQuery()),
'Title' => _t('SilverStripe\\CMS\\Search\\SiteSearchForm.SearchResults', 'Search Results')
);
return $this->owner->customise($data)->renderWith(array('SearchableResultsPage', 'Page'));
$pageLength = 10;
$this->owner->extend("updateSiteSearchFormResults", $searchdata, $form, $Results, $pageLength);

// Pack up the results
$Paged = new PaginatedList($Results, $this->owner->getRequest());
$Paged->setPageLength($pageLength);
$Paged->setPageStart($start);
$data = array(
'Results' => $Paged,
'Query' => DBField::create_field('Text', $form->getSearchQuery()),
'Title' => _t('SilverStripe\\CMS\\Search\\SiteSearchForm.SearchResults', 'Search Results')
);
return $this->owner->customise($data)->renderWith(array('SearchableResultsPage', 'Page'));
}

/**
Expand All @@ -119,23 +120,46 @@ public function getSearchResults(string $search)

$tnt = TNTSearchHelper::Instance()->getTNTSearch();
$tnt->selectIndex('site.index');
$res = $tnt->search($search);
if (SiteConfig::current_site_config()->EnableBooleanSearch) {
$res = $tnt->searchBoolean($search);
//if no results with boolean search, do a regular search
if (empty($res['ids'])) {
$res = $tnt->search($search, 1000);
}
} else {
$res = $tnt->search($search, 1000);
}

$classlist = [];
$classes = ClassInfo::classesWithExtension(SearchableExtension::class);
foreach ($classes as $key => $value) {
$classlist[ClassInfo::shortName($value)] = $value;
$classlist[ClassInfo::shortName($value)] = $value;
}

foreach ($res['ids'] as $result) {
$parts = explode("_", $result);
if (isset($res["docScores"])) {
$docScores = $res['docScores'];
uasort($docScores, function ($a, $b) {
return abs($a) < abs($b) ? 1 : -1;
});
foreach ($docScores as $id => $score) {
$parts = explode("_", $id);
if ($obj = $classlist[$parts[0]]::get()->byID($parts[1])) {
$results->push($obj);
}
}
} else {
foreach ($res['ids'] as $result) {
if ($result) {
$parts = explode("_", $result);
if ($obj = $classlist[$parts[0]]::get()->byID($parts[1])) {
$results->push($obj);
}
}
}
}

$results->removeDuplicates('getSearchableID');

return $results;
}

}

24 changes: 24 additions & 0 deletions src/SearchSiteConfigExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Werkbot\Search;

use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\FieldGroup;
use SilverStripe\ORM\DataExtension;
use SilverStripe\Forms\CheckboxField;

class SearchSiteConfigExtension extends DataExtension
{
private static $db = [
'EnableBooleanSearch' => 'Boolean',
];

public function updateCMSFields(FieldList $fields)
{
$EnableBooleanSearchField = FieldGroup::create(
'Search Settings',
CheckboxField::create('EnableBooleanSearch', 'Enable boolean search?')
);
$fields->addFieldToTab("Root.Search", $EnableBooleanSearchField);
}
}
20 changes: 18 additions & 2 deletions src/SearchableExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@ public function getIndexQuery()
{
return false;
}
/**
* getSearchableID
* Returns the ID to be used in search results, for objects that are apart of a page this can be
* overridden to return the Page ID - which can then be used to remove duplicates from search results
*
* @return int
*/
public function getSearchableID()
{
return $this->owner->ClassName . "_" . $this->owner->ID;
}
/**
* getSearchableTitle
* Returns the title, to be used in search results
Expand Down Expand Up @@ -81,11 +92,16 @@ public function getSearchableTitleColumnName()
**/
public function getSearchableSummary()
{
$content = "";
if ($this->owner->SearchableExtension_Summary_ColumnName) {
return $this->owner->{$this->owner->SearchableExtension_Summary_ColumnName};
$content = $this->owner->{$this->owner->SearchableExtension_Summary_ColumnName};
} else {
return $this->owner->Content;
$content = $this->owner->Content;
}

$this->owner->extend('updateSearchableSummary', $content);

return $content;
}
/**
* getSearchableContent
Expand Down
Loading