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 'SearchForm',
80 'Form'
81 ));
82 }
83
84 85 86 87
88 function classesToSearch($classes) {
89 $illegalClasses = array_diff($classes, array('SiteTree', 'File'));
90 if($illegalClasses) {
91 user_error("SearchForm::classesToSearch() passed illegal classes '" . implode("', '", $illegalClasses) . "'. At this stage, only File and SiteTree are allowed", E_USER_WARNING);
92 }
93 $legalClasses = array_intersect($classes, array('SiteTree', 'File'));
94 $this->classesToSearch = $legalClasses;
95 }
96
97 98 99 100 101 102 103 104
105 public function getResults($pageLength = null, $data = null){
106
107 if(!isset($data) || !is_array($data)) $data = $_REQUEST;
108
109
110 if(singleton('SiteTree')->hasExtension('Translatable') && isset($data['locale'])) {
111 $origLocale = Translatable::get_current_locale();
112 Translatable::set_current_locale($data['locale']);
113 }
114
115 if (self::$search_mode == 'morphy' && class_exists('SSMorphy')) {
116
117 $keywords = trim(preg_replace('/[^a-zA-Zа-яА-Я0-9\s]+/u', ' ', $data['Search']));
118 $keywords = SSMorphy::createSearchCriteria($keywords);
119 }
120 elseif (self::$search_mode == 'extended') {
121
122 $keywords = trim(preg_replace('/[^a-zA-Zа-яА-Я0-9\s"+-]+/u', ' ', $data['Search']));
123
124 $keywords = preg_replace('/(\S)\+/u', '$1 +', $keywords);
125
126 $keywords = preg_replace('/(\w+)-(\w+)/u', '"$1-$2"', $keywords);
127
128 if (substr_count($keywords, '"') % 2 > 0) {
129 $keywords = $keywords . '"';
130 }
131
132 $keywords = $this->addStarsToKeywords($keywords);
133 }
134 else {
135
136 $keywords = trim(preg_replace('/[^a-zA-Zа-яА-Я0-9\s]+/u', ' ', $data['Search']));
137 }
138
139 if(!$pageLength) $pageLength = $this->pageLength;
140 $start = isset($_GET['start']) ? (int)$_GET['start'] : 0;
141
142 if(strpos($keywords, '"') !== false || strpos($keywords, '+') !== false || strpos($keywords, '-') !== false || strpos($keywords, '*') !== false) {
143 $results = DB::getConn()->searchEngine($this->classesToSearch, $keywords, $start, $pageLength, "Relevance DESC", "", true);
144 } else {
145 $results = DB::getConn()->searchEngine($this->classesToSearch, $keywords, $start, $pageLength);
146 }
147
148
149 if($results) foreach($results as $result) {
150 if(!$result->canView()) {
151 $results->remove($result);
152 }
153 else {
154
155
156
157 $results->replace($result, DataObject::get_by_id($result->ClassName, $result->ID));
158 }
159 }
160
161
162 if(singleton('SiteTree')->hasExtension('Translatable') && isset($data['locale'])) {
163 Translatable::set_current_locale($origLocale);
164 }
165
166 return $results;
167 }
168
169 170 171 172 173 174 175
176 protected function addStarsToKeywords($keywords) {
177 if (!$keywords) return "";
178 $splitWords = preg_split("/\s+/" , $keywords);
179 while (list($i, $word) = each($splitWords)) {
180 if ($word[0] == '"') {
181
182 while (list($i, $subword) = each($splitWords)) {
183 $word .= ' ' . $subword;
184 if (substr($subword,-1) == '"') break;
185 }
186 } elseif ($word[0] == '(') {
187
188 while (list($i, $subword) = each($splitWords)) {
189 $word .= ' ' . $subword;
190 if (substr($subword,-1) == ')') break;
191 }
192 } elseif ($word[0] != '+' && $word[0] != '-' && substr($word,-1) != '*') {
193 $word .= '*';
194 }
195 $newWords[] = $word;
196 }
197 return implode(" ", $newWords);
198 }
199
200 201 202 203 204 205
206 public function getSearchQuery($data = null) {
207
208 if(!isset($data)) $data = $_REQUEST;
209
210 return Convert::raw2xml($data['Search']);
211 }
212
213 214 215 216 217
218 public function setPageLength($length) {
219 $this->pageLength = $length;
220 }
221
222 223 224
225 public function getPageLength() {
226 return $this->pageLength;
227 }
228
229 }
230
231 ?>
232
[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.
-