1 <?php
2 3 4 5 6 7 8 9 10 11 12 13 14
15 class SearchForm extends Form {
16
17 private static $search_mode = 'morphy';
18
19 20 21 22 23 24 25 26
27 static function set_serch_mode($val) {
28 self::$search_mode = $val;
29 }
30
31 32 33 34
35 protected $pageLength = 10;
36
37 38 39
40 protected $classesToSearch = array(
41 "SiteTree", "File"
42 );
43
44 45 46 47 48 49 50 51
52 function __construct($controller, $name, $fields = null, $actions = null) {
53 if(!$fields) {
54 $fields = new FieldSet(
55 new TextField('Search', _t('SearchForm.SEARCH', 'Search')
56 ));
57 }
58
59 if(singleton('SiteTree')->hasExtension('Translatable')) {
60 $fields->push(new HiddenField('locale', 'locale', Translatable::get_current_locale()));
61 }
62
63 if(!$actions) {
64 $actions = new FieldSet(
65 new FormAction("getResults", _t('SearchForm.GO', 'Go'))
66 );
67 }
68
69 parent::__construct($controller, $name, $fields, $actions);
70
71 $this->setFormMethod('get');
72
73 $this->disableSecurityToken();
74 $this->getValidator()->setJavascriptValidationHandler('none');
75 }
76
77 public function forTemplate() {
78 return $this->renderWith(array(
79 $this->template,
80 'SearchForm',
81 'Form'
82 ));
83 }
84
85 86 87 88
89 function classesToSearch($classes) {
90 $illegalClasses = array_diff($classes, array('SiteTree', 'File'));
91 if($illegalClasses) {
92 user_error("SearchForm::classesToSearch() passed illegal classes '" . implode("', '", $illegalClasses) . "'. At this stage, only File and SiteTree are allowed", E_USER_WARNING);
93 }
94 $legalClasses = array_intersect($classes, array('SiteTree', 'File'));
95 $this->classesToSearch = $legalClasses;
96 }
97
98 99 100 101 102 103 104 105
106 public function getResults($pageLength = null, $data = null){
107
108 if(!isset($data) || !is_array($data)) $data = $_REQUEST;
109
110
111 if(singleton('SiteTree')->hasExtension('Translatable') && isset($data['locale'])) {
112 $origLocale = Translatable::get_current_locale();
113 Translatable::set_current_locale($data['locale']);
114 }
115
116 if (self::$search_mode == 'morphy' && class_exists('SSMorphy')) {
117
118 $keywords = trim(preg_replace('/[^a-zA-Zа-яА-Я0-9\s]+/u', ' ', $data['Search']));
119 $keywords = SSMorphy::createSearchCriteria($keywords);
120 }
121 elseif (self::$search_mode == 'extended') {
122
123 $keywords = trim(preg_replace('/[^a-zA-Zа-яА-Я0-9\s"+-]+/u', ' ', $data['Search']));
124
125 $keywords = preg_replace('/(\S)\+/u', '$1 +', $keywords);
126
127 $keywords = preg_replace('/(\w+)-(\w+)/u', '"$1-$2"', $keywords);
128
129 if (substr_count($keywords, '"') % 2 > 0) {
130 $keywords = $keywords . '"';
131 }
132
133 $keywords = $this->addStarsToKeywords($keywords);
134 }
135 else {
136
137 $keywords = trim(preg_replace('/[^a-zA-Zа-яА-Я0-9\s]+/u', ' ', $data['Search']));
138 }
139
140 if(!$pageLength) $pageLength = $this->pageLength;
141 $start = isset($_GET['start']) ? (int)$_GET['start'] : 0;
142
143 if(strpos($keywords, '"') !== false || strpos($keywords, '+') !== false || strpos($keywords, '-') !== false || strpos($keywords, '*') !== false) {
144 $results = DB::getConn()->searchEngine($this->classesToSearch, $keywords, $start, $pageLength, "Relevance DESC", "", true);
145 } else {
146 $results = DB::getConn()->searchEngine($this->classesToSearch, $keywords, $start, $pageLength);
147 }
148
149
150 if($results) foreach($results as $result) {
151 if(!$result->canView()) {
152 $results->remove($result);
153 }
154 else {
155
156
157
158 $results->replace($result, DataObject::get_by_id($result->ClassName, $result->ID));
159 }
160 }
161
162
163 if(singleton('SiteTree')->hasExtension('Translatable') && isset($data['locale'])) {
164 Translatable::set_current_locale($origLocale);
165 }
166
167 return $results;
168 }
169
170 171 172 173 174 175 176
177 protected function addStarsToKeywords($keywords) {
178 if (!$keywords) return "";
179 $splitWords = preg_split("/\s+/" , $keywords);
180 while (list($i, $word) = each($splitWords)) {
181 if ($word[0] == '"') {
182
183 while (list($i, $subword) = each($splitWords)) {
184 $word .= ' ' . $subword;
185 if (substr($subword,-1) == '"') break;
186 }
187 } elseif ($word[0] == '(') {
188
189 while (list($i, $subword) = each($splitWords)) {
190 $word .= ' ' . $subword;
191 if (substr($subword,-1) == ')') break;
192 }
193 } elseif ($word[0] != '+' && $word[0] != '-' && substr($word,-1) != '*') {
194 $word .= '*';
195 }
196 $newWords[] = $word;
197 }
198 return implode(" ", $newWords);
199 }
200
201 202 203 204 205 206
207 public function getSearchQuery($data = null) {
208
209 if(!isset($data)) $data = $_REQUEST;
210
211 return Convert::raw2xml($data['Search']);
212 }
213
214 215 216 217 218
219 public function setPageLength($length) {
220 $this->pageLength = $length;
221 }
222
223 224 225
226 public function getPageLength() {
227 return $this->pageLength;
228 }
229
230 }
231
232 ?>
233
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-