mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
Added SearchForm::classesToSearch() to set the classes that you want it to search. Still limited to SiteTree and File but you can exclude one of those.
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.3@68598 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
25f9a20d29
commit
b3fbbf8881
@ -26,6 +26,11 @@ class SearchForm extends Form {
|
||||
*/
|
||||
protected $pageLength = 10;
|
||||
|
||||
/**
|
||||
* Classes to search
|
||||
*/
|
||||
protected $classesToSearch = array("SiteTree", "File");
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Controller $controller
|
||||
@ -64,6 +69,19 @@ class SearchForm extends Form {
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the classes to search.
|
||||
* Currently you can only choose from "SiteTree" and "File", but a future version might improve this.
|
||||
*/
|
||||
function classesToSearch($classes) {
|
||||
$illegalClasses = array_diff($classes, array('SiteTree', 'File'));
|
||||
if($illegalClasses) {
|
||||
user_error("SearchForm::classesToSearch() passed illegal classes '" . implode("', '", $illegalClasses) . "'. At this stage, only File and SiteTree are allowed", E_USER_WARNING);
|
||||
}
|
||||
$legalClasses = array_intersect($classes, array('SiteTree', 'File'));
|
||||
$this->classesToSearch = $legalClasses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return dataObjectSet of the results using $_REQUEST to get info from form.
|
||||
* Wraps around {@link searchEngine()}.
|
||||
@ -137,52 +155,62 @@ class SearchForm extends Form {
|
||||
if(!$pageLength) $pageLength = $this->pageLength;
|
||||
$fileFilter = '';
|
||||
$keywords = addslashes($keywords);
|
||||
|
||||
$extraFilters = array('SiteTree' => '', 'File' => '');
|
||||
|
||||
if($booleanSearch) $boolean = "IN BOOLEAN MODE";
|
||||
if($extraFilter) {
|
||||
$extraFilter = " AND $extraFilter";
|
||||
$extraFilters['SiteTree'] = " AND $extraFilter";
|
||||
|
||||
if($alternativeFileFilter) $fileFilter = " AND $alternativeFileFilter";
|
||||
else $fileFilter = $extraFilter;
|
||||
if($alternativeFileFilter) $extraFilters['File'] = " AND $alternativeFileFilter";
|
||||
else $extraFilters['File'] = $extraFilters['SiteTree'];
|
||||
}
|
||||
|
||||
if($this->showInSearchTurnOn) $extraFilter .= " AND showInSearch <> 0";
|
||||
if($this->showInSearchTurnOn) $extraFilters['SiteTree'] .= " AND showInSearch <> 0";
|
||||
|
||||
$start = isset($_GET['start']) ? (int)$_GET['start'] : 0;
|
||||
$limit = $start . ", " . (int) $pageLength;
|
||||
|
||||
$notMatch = $invertedMatch ? "NOT " : "";
|
||||
if($keywords) {
|
||||
$matchContent = "MATCH (Title, MenuTitle, Content, MetaTitle, MetaDescription, MetaKeywords) AGAINST ('$keywords' $boolean)";
|
||||
$matchFile = "MATCH (Filename, Title, Content) AGAINST ('$keywords' $boolean) AND ClassName = 'File'";
|
||||
$match['SiteTree'] = "MATCH (Title, MenuTitle, Content, MetaTitle, MetaDescription, MetaKeywords) AGAINST ('$keywords' $boolean)";
|
||||
$match['File'] = "MATCH (Filename, Title, Content) AGAINST ('$keywords' $boolean) AND ClassName = 'File'";
|
||||
|
||||
// We make the relevance search by converting a boolean mode search into a normal one
|
||||
$relevanceKeywords = str_replace(array('*','+','-'),'',$keywords);
|
||||
$relevanceContent = "MATCH (Title) AGAINST ('$relevanceKeywords') + MATCH (Title, MenuTitle, Content, MetaTitle, MetaDescription, MetaKeywords) AGAINST ('$relevanceKeywords')";
|
||||
$relevanceFile = "MATCH (Filename, Title, Content) AGAINST ('$relevanceKeywords')";
|
||||
$relevance['SiteTree'] = "MATCH (Title) AGAINST ('$relevanceKeywords') + MATCH (Title, MenuTitle, Content, MetaTitle, MetaDescription, MetaKeywords) AGAINST ('$relevanceKeywords')";
|
||||
$relevance['File'] = "MATCH (Filename, Title, Content) AGAINST ('$relevanceKeywords')";
|
||||
} else {
|
||||
$relevanceContent = $relevanceFile = 1;
|
||||
$matchContent = $matchFile = "1 = 1";
|
||||
$relevance['SiteTree'] = $relevance['File'] = 1;
|
||||
$match['SiteTree'] = $match['File'] = "1 = 1";
|
||||
}
|
||||
|
||||
$select = array(
|
||||
'SiteTree' => array("ClassName","`SiteTree`.ID","ParentID","Title","URLSegment","Content","LastEdited","Created","_utf8'' AS Filename", "_utf8'' AS Name", "$relevance[SiteTree] AS Relevance", "CanViewType"),
|
||||
'File' => array("ClassName","`File`.ID","_utf8'' AS ParentID","Title","_utf8'' AS URLSegment","Content","LastEdited","Created","Filename","Name","$relevance[File] AS Relevance","NULL AS CanViewType"),
|
||||
);
|
||||
|
||||
// Process queries
|
||||
foreach($this->classesToSearch as $class) {
|
||||
$queries[$class] = singleton($class)->extendedSQL($notMatch . $match[$class] . $extraFilters[$class], "");
|
||||
$baseClass = reset($queries[$class]->from);
|
||||
// There's no need to do all that joining
|
||||
$queries[$class]->from = array(str_replace('`','',$baseClass) => $baseClass);
|
||||
$queries[$class]->select = $select[$class];
|
||||
$queries[$class]->orderby = null;
|
||||
}
|
||||
|
||||
$queryContent = singleton('SiteTree')->extendedSQL($notMatch . $matchContent . $extraFilter, "");
|
||||
// Combine queries
|
||||
$querySQLs = array();
|
||||
$totalCount = 0;
|
||||
foreach($queries as $query) {
|
||||
$querySQLs[] = $query->sql();
|
||||
$totalCount += $query->unlimitedRowCount();
|
||||
}
|
||||
$fullQuery = implode(" UNION ", $querySQLs) . " ORDER BY $sortBy LIMIT $limit";
|
||||
Debug::message($fullQuery);
|
||||
|
||||
$baseClass = reset($queryContent->from);
|
||||
// There's no need to do all that joining
|
||||
$queryContent->from = array(str_replace('`','',$baseClass) => $baseClass);
|
||||
$queryContent->select = array("ClassName","$baseClass.ID","ParentID","Title","URLSegment","Content","LastEdited","Created","_utf8'' AS Filename", "_utf8'' AS Name", "$relevanceContent AS Relevance", "CanViewType");
|
||||
$queryContent->orderby = null;
|
||||
|
||||
$queryFiles = singleton('File')->extendedSQL($notMatch . $matchFile . $fileFilter, "");
|
||||
$baseClass = reset($queryFiles->from);
|
||||
// There's no need to do all that joining
|
||||
$queryFiles->from = array(str_replace('`','',$baseClass) => $baseClass);
|
||||
$queryFiles->select = array("ClassName","$baseClass.ID","_utf8'' AS ParentID","Title","_utf8'' AS URLSegment","Content","LastEdited","Created","Filename","Name","$relevanceFile AS Relevance","NULL AS CanViewType");
|
||||
$queryFiles->orderby = null;
|
||||
|
||||
$fullQuery = $queryContent->sql() . " UNION " . $queryFiles->sql() . " ORDER BY $sortBy LIMIT $limit";
|
||||
$totalCount = $queryContent->unlimitedRowCount() + $queryFiles->unlimitedRowCount();
|
||||
|
||||
// Get records
|
||||
$records = DB::query($fullQuery);
|
||||
|
||||
foreach($records as $record)
|
||||
|
Loading…
x
Reference in New Issue
Block a user