mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
MINOR Moved SearchForm, AdvancedSearchForm and ContentControllerSearchExtension to "cms" module
This commit is contained in:
parent
204fd2c4ce
commit
71f117b519
@ -1,137 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* More advanced search form
|
||||
* @package sapphire
|
||||
* @subpackage search
|
||||
*/
|
||||
class AdvancedSearchForm extends SearchForm {
|
||||
|
||||
/**
|
||||
* the constructor of a Simple/basic SearchForm
|
||||
*/
|
||||
function __construct($controller, $name, $fields = null, $actions = null) {
|
||||
if(!$fields) {
|
||||
$fields = new FieldSet(
|
||||
$searchBy = new CompositeField(
|
||||
new HeaderField('SearchByHeader',_t('AdvancedSearchForm.SEARCHBY', 'SEARCH BY')),
|
||||
new TextField("+", _t('AdvancedSearchForm.ALLWORDS', 'All Words')),
|
||||
new TextField("quote", _t('AdvancedSearchForm.EXACT', 'Exact Phrase')),
|
||||
new TextField("any", _t('AdvancedSearchForm.ATLEAST', 'At Least One Of the Words')),
|
||||
new TextField("-", _t('AdvancedSearchForm.WITHOUT', 'Without the Words'))
|
||||
),
|
||||
$sortBy = new CompositeField(
|
||||
new HeaderField('SortByHeader',_t('AdvancedSearchForm.SORTBY', 'SORT RESULTS BY')),
|
||||
new OptionsetField("sortby", "",
|
||||
array(
|
||||
'Relevance' => _t('AdvancedSearchForm.RELEVANCE', 'Relevance'),
|
||||
'LastUpdated' => _t('AdvancedSearchForm.LASTUPDATED', 'Last Updated'),
|
||||
'PageTitle' => _t('AdvancedSearchForm.PAGETITLE', 'Page Title'),
|
||||
),
|
||||
'Relevance'
|
||||
)
|
||||
),
|
||||
$chooseDate = new CompositeField(
|
||||
new HeaderField('LastUpdatedHeader',_t('AdvancedSearchForm.LASTUPDATEDHEADER', 'LAST UPDATED')),
|
||||
new DateField("From", _t('AdvancedSearchForm.FROM', 'From')),
|
||||
new DateField("To", _t('AdvancedSearchForm.TO', 'To'))
|
||||
)
|
||||
);
|
||||
|
||||
$searchBy->ID = "AdvancedSearchForm_SearchBy";
|
||||
$searchOnly->ID = "AdvancedSearchForm_SearchOnly";
|
||||
$sortBy->ID = "AdvancedSearchForm_SortBy";
|
||||
$chooseDate->ID = "AdvancedSearchForm_ChooseDate";
|
||||
}
|
||||
|
||||
if(!$actions) {
|
||||
$actions = new FieldSet(
|
||||
new FormAction("results", _t('AdvancedSearchForm.GO', 'Go'))
|
||||
);
|
||||
}
|
||||
parent::__construct($controller, $name, $fields, $actions);
|
||||
}
|
||||
|
||||
public function forTemplate(){
|
||||
return $this->renderWith(array("AdvancedSearchForm","Form"));
|
||||
}
|
||||
|
||||
/* Return dataObjectSet of the results, using the form data.
|
||||
*/
|
||||
public function getResults($numPerPage = 10) {
|
||||
$data = $this->getData();
|
||||
|
||||
if($data['+']) $keywords .= " +" . ereg_replace(" +", " +", trim($data['+']));
|
||||
if($data['quote']) $keywords .= ' "' . $data['quote'] . '"';
|
||||
if($data['any']) $keywords .= ' ' . $data['any'];
|
||||
if($data['-']) $keywords .= " -" . ereg_replace(" +", " -", trim($data['-']));
|
||||
$keywords = trim($keywords);
|
||||
|
||||
// This means that they want to just find pages where there's *no* match
|
||||
|
||||
if($keywords[0] == '-') {
|
||||
$keywords = $data['-'];
|
||||
$invertedMatch = true;
|
||||
}
|
||||
|
||||
|
||||
// Limit search to various sections
|
||||
if($_REQUEST['OnlyShow']) {
|
||||
$pageList = array();
|
||||
|
||||
// Find the associated pages
|
||||
foreach($_REQUEST['OnlyShow'] as $section => $checked) {
|
||||
$items = explode(",", $section);
|
||||
foreach($items as $item) {
|
||||
$page = DataObject::get_one('SiteTree', "\"URLSegment\" = '" . DB::getConn()->addslashes($item) . "'");
|
||||
$pageList[] = $page->ID;
|
||||
if(!$page) user_error("Can't find a page called '$item'", E_USER_WARNING);
|
||||
$page->loadDescendantIDListInto($pageList);
|
||||
}
|
||||
}
|
||||
$contentFilter = "\"ID\" IN (" . implode(",", $pageList) . ")";
|
||||
|
||||
// Find the files associated with those pages
|
||||
$fileList = DB::query("SELECT \"FileID\" FROM \"Page_ImageTracking\" WHERE \"PageID\" IN (" . implode(",", $pageList) . ")")->column();
|
||||
if($fileList) $fileFilter = "\"ID\" IN (" . implode(",", $fileList) . ")";
|
||||
else $fileFilter = " 1 = 2 ";
|
||||
}
|
||||
|
||||
if($data['From']) {
|
||||
$filter .= ($filter?" AND":"") . " \"LastEdited\" >= '$data[From]'";
|
||||
}
|
||||
if($data['To']) {
|
||||
$filter .= ($filter?" AND":"") . " \"LastEdited\" <= '$data[To]'";
|
||||
}
|
||||
|
||||
if($filter) {
|
||||
$contentFilter .= ($contentFilter?" AND":"") . $filter;
|
||||
$fileFilter .= ($fileFilter?" AND":"") . $filter;
|
||||
}
|
||||
|
||||
if($data['sortby']) {
|
||||
$sorts = array(
|
||||
'LastUpdated' => '"LastEdited" DESC',
|
||||
'PageTitle' => '"Title" ASC',
|
||||
'Relevance' => '"Relevance" DESC',
|
||||
);
|
||||
$sortBy = $sorts[$data['sortby']] ? $sorts[$data['sortby']] : $sorts['Relevance'];
|
||||
}
|
||||
|
||||
$keywords = $this->addStarsToKeywords($keywords);
|
||||
|
||||
return $this->searchEngine($keywords, $numPerPage, $sortBy, $contentFilter, true, $fileFilter, $invertedMatch);
|
||||
}
|
||||
|
||||
function getSearchQuery() {
|
||||
$data = $_REQUEST;
|
||||
if($data['+']) $keywords .= " +" . ereg_replace(" +", " +", trim($data['+']));
|
||||
if($data['quote']) $keywords .= ' "' . $data['quote'] . '"';
|
||||
if($data['any']) $keywords .= ' ' . $data['any'];
|
||||
if($data['-']) $keywords .= " -" . ereg_replace(" +", " -", trim($data['-']));
|
||||
|
||||
return trim($keywords);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -1,50 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Extension to provide a search interface when applied to ContentController
|
||||
*
|
||||
* @package sapphire
|
||||
* @subpackage search
|
||||
*/
|
||||
class ContentControllerSearchExtension extends Extension {
|
||||
static $allowed_actions = array(
|
||||
'SearchForm',
|
||||
'results',
|
||||
);
|
||||
|
||||
/**
|
||||
* Site search form
|
||||
*/
|
||||
function SearchForm() {
|
||||
$searchText = _t('SearchForm.SEARCH', 'Search');
|
||||
|
||||
if($this->owner->request && $this->owner->request->getVar('Search')) {
|
||||
$searchText = $this->owner->request->getVar('Search');
|
||||
}
|
||||
|
||||
$fields = new FieldSet(
|
||||
new TextField('Search', false, $searchText)
|
||||
);
|
||||
$actions = new FieldSet(
|
||||
new FormAction('results', _t('SearchForm.GO', 'Go'))
|
||||
);
|
||||
$form = new SearchForm($this->owner, 'SearchForm', $fields, $actions);
|
||||
$form->classesToSearch(FulltextSearchable::get_searchable_classes());
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 SS_HTTPRequest $request Request generated for this action
|
||||
*/
|
||||
function results($data, $form, $request) {
|
||||
$data = array(
|
||||
'Results' => $form->getResults(),
|
||||
'Query' => $form->getSearchQuery(),
|
||||
'Title' => _t('SearchForm.SearchResults', 'Search Results')
|
||||
);
|
||||
return $this->owner->customise($data)->renderWith(array('Page_results', 'Page'));
|
||||
}
|
||||
}
|
@ -1,196 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Standard basic search form which conducts a fulltext search on all {@link SiteTree}
|
||||
* objects.
|
||||
*
|
||||
* If multilingual content is enabled through the {@link Translatable} extension,
|
||||
* only pages the currently set language on the holder for this searchform are found.
|
||||
* The language is set through a hidden field in the form, which is prepoluated
|
||||
* with {@link Translatable::get_current_locale()} when then form is constructed.
|
||||
*
|
||||
* @see Use ModelController and SearchContext for a more generic search implementation based around DataObject
|
||||
* @package sapphire
|
||||
* @subpackage search
|
||||
*/
|
||||
class SearchForm extends Form {
|
||||
|
||||
/**
|
||||
* @var int $pageLength How many results are shown per page.
|
||||
* Relies on pagination being implemented in the search results template.
|
||||
*/
|
||||
protected $pageLength = 10;
|
||||
|
||||
/**
|
||||
* Classes to search
|
||||
*/
|
||||
protected $classesToSearch = array(
|
||||
"SiteTree", "File"
|
||||
);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Controller $controller
|
||||
* @param string $name The name of the form (used in URL addressing)
|
||||
* @param FieldSet $fields Optional, defaults to a single field named "Search". Search logic needs to be customized
|
||||
* if fields are added to the form.
|
||||
* @param FieldSet $actions Optional, defaults to a single field named "Go".
|
||||
*/
|
||||
function __construct($controller, $name, $fields = null, $actions = null) {
|
||||
if(!$fields) {
|
||||
$fields = new FieldSet(
|
||||
new TextField('Search', _t('SearchForm.SEARCH', 'Search')
|
||||
));
|
||||
}
|
||||
|
||||
if(singleton('SiteTree')->hasExtension('Translatable')) {
|
||||
$fields->push(new HiddenField('locale', 'locale', Translatable::get_current_locale()));
|
||||
}
|
||||
|
||||
if(!$actions) {
|
||||
$actions = new FieldSet(
|
||||
new FormAction("getResults", _t('SearchForm.GO', 'Go'))
|
||||
);
|
||||
}
|
||||
|
||||
parent::__construct($controller, $name, $fields, $actions);
|
||||
|
||||
$this->setFormMethod('get');
|
||||
|
||||
$this->disableSecurityToken();
|
||||
}
|
||||
|
||||
public function forTemplate() {
|
||||
return $this->renderWith(array(
|
||||
'SearchForm',
|
||||
'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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the classes to search
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function getClassesToSearch() {
|
||||
return $this->classesToSearch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return dataObjectSet of the results using $_REQUEST to get info from form.
|
||||
* Wraps around {@link searchEngine()}.
|
||||
*
|
||||
* @param int $pageLength DEPRECATED 2.3 Use SearchForm->pageLength
|
||||
* @param array $data Request data as an associative array. Should contain at least a key 'Search' with all searched keywords.
|
||||
* @return DataObjectSet
|
||||
*/
|
||||
public function getResults($pageLength = null, $data = null){
|
||||
// legacy usage: $data was defaulting to $_REQUEST, parameter not passed in doc.silverstripe.org tutorials
|
||||
if(!isset($data) || !is_array($data)) $data = $_REQUEST;
|
||||
|
||||
// set language (if present)
|
||||
if(singleton('SiteTree')->hasExtension('Translatable') && isset($data['locale'])) {
|
||||
$origLocale = Translatable::get_current_locale();
|
||||
Translatable::set_current_locale($data['locale']);
|
||||
}
|
||||
|
||||
$keywords = $data['Search'];
|
||||
|
||||
$andProcessor = create_function('$matches','
|
||||
return " +" . $matches[2] . " +" . $matches[4] . " ";
|
||||
');
|
||||
$notProcessor = create_function('$matches', '
|
||||
return " -" . $matches[3];
|
||||
');
|
||||
|
||||
$keywords = preg_replace_callback('/()("[^()"]+")( and )("[^"()]+")()/i', $andProcessor, $keywords);
|
||||
$keywords = preg_replace_callback('/(^| )([^() ]+)( and )([^ ()]+)( |$)/i', $andProcessor, $keywords);
|
||||
$keywords = preg_replace_callback('/(^| )(not )("[^"()]+")/i', $notProcessor, $keywords);
|
||||
$keywords = preg_replace_callback('/(^| )(not )([^() ]+)( |$)/i', $notProcessor, $keywords);
|
||||
|
||||
$keywords = $this->addStarsToKeywords($keywords);
|
||||
|
||||
if(!$pageLength) $pageLength = $this->pageLength;
|
||||
$start = isset($_GET['start']) ? (int)$_GET['start'] : 0;
|
||||
|
||||
if(strpos($keywords, '"') !== false || strpos($keywords, '+') !== false || strpos($keywords, '-') !== false || strpos($keywords, '*') !== false) {
|
||||
$results = DB::getConn()->searchEngine($this->classesToSearch, $keywords, $start, $pageLength, "\"Relevance\" DESC", "", true);
|
||||
} else {
|
||||
$results = DB::getConn()->searchEngine($this->classesToSearch, $keywords, $start, $pageLength);
|
||||
}
|
||||
|
||||
// filter by permission
|
||||
if($results) foreach($results as $result) {
|
||||
if(!$result->canView()) $results->remove($result);
|
||||
}
|
||||
|
||||
// reset locale
|
||||
if(singleton('SiteTree')->hasExtension('Translatable') && isset($data['locale'])) {
|
||||
Translatable::set_current_locale($origLocale);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
protected function addStarsToKeywords($keywords) {
|
||||
if(!trim($keywords)) return "";
|
||||
// Add * to each keyword
|
||||
$splitWords = preg_split("/ +/" , trim($keywords));
|
||||
while(list($i,$word) = each($splitWords)) {
|
||||
if($word[0] == '"') {
|
||||
while(list($i,$subword) = each($splitWords)) {
|
||||
$word .= ' ' . $subword;
|
||||
if(substr($subword,-1) == '"') break;
|
||||
}
|
||||
} else {
|
||||
$word .= '*';
|
||||
}
|
||||
$newWords[] = $word;
|
||||
}
|
||||
return implode(" ", $newWords);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the search query for display in a "You searched for ..." sentence.
|
||||
*
|
||||
* @param array $data
|
||||
* @return string
|
||||
*/
|
||||
public function getSearchQuery($data = null) {
|
||||
// legacy usage: $data was defaulting to $_REQUEST, parameter not passed in doc.silverstripe.org tutorials
|
||||
if(!isset($data)) $data = $_REQUEST;
|
||||
|
||||
return Convert::raw2xml($data['Search']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of records shown on each page.
|
||||
*
|
||||
* @param int $length
|
||||
*/
|
||||
public function setPageLength($length) {
|
||||
$this->pageLength = $length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPageLength() {
|
||||
return $this->pageLength;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
Loading…
Reference in New Issue
Block a user