@@ -160,44 +160,46 @@ public function getShortName($length = 25)
160160 public function fullTextSearchQuery ($ fieldsToSearch , $ terms , $ wheres = [])
161161 {
162162 $ exactTerms = [];
163- if (count ($ terms ) === 0 ) {
164- $ search = $ this ;
165- $ orderBy = 'updated_at ' ;
166- } else {
167- foreach ($ terms as $ key => $ term ) {
168- $ term = htmlentities ($ term , ENT_QUOTES );
169- $ term = preg_replace ('/[+\-><\(\)~*\"@]+/ ' , ' ' , $ term );
170- if (preg_match ('/".*?"/ ' , $ term )) {
171- $ term = str_replace ('" ' , '' , $ term );
172- $ exactTerms [] = '% ' . $ term . '% ' ;
173- $ term = '" ' . $ term . '" ' ;
174- } else {
175- $ term = '' . $ term . '* ' ;
176- }
177- if ($ term !== '* ' ) $ terms [$ key ] = $ term ;
163+ $ fuzzyTerms = [];
164+ $ search = static ::newQuery ();
165+ foreach ($ terms as $ key => $ term ) {
166+ $ safeTerm = htmlentities ($ term , ENT_QUOTES );
167+ $ safeTerm = preg_replace ('/[+\-><\(\)~*\"@]+/ ' , ' ' , $ safeTerm );
168+ if (preg_match ('/".*?"/ ' , $ safeTerm ) || is_numeric ($ safeTerm )) {
169+ $ safeTerm = preg_replace ('/^"(.*?)"$/ ' , '$1 ' , $ term );
170+ $ exactTerms [] = '% ' . $ safeTerm . '% ' ;
171+ } else {
172+ $ safeTerm = '' . $ safeTerm . '* ' ;
173+ if (trim ($ safeTerm ) !== '* ' ) $ fuzzyTerms [] = $ safeTerm ;
178174 }
179- $ termString = implode (' ' , $ terms );
175+ }
176+ $ isFuzzy = count ($ exactTerms ) === 0 || count ($ fuzzyTerms ) > 0 ;
177+
178+ // Perform fulltext search if relevant terms exist.
179+ if ($ isFuzzy ) {
180+ $ termString = implode (' ' , $ fuzzyTerms );
180181 $ fields = implode (', ' , $ fieldsToSearch );
181- $ search = static :: selectRaw ('*, MATCH(name) AGAINST(? IN BOOLEAN MODE) AS title_relevance ' , [$ termString ]);
182+ $ search = $ search -> selectRaw ('*, MATCH(name) AGAINST(? IN BOOLEAN MODE) AS title_relevance ' , [$ termString ]);
182183 $ search = $ search ->whereRaw ('MATCH( ' . $ fields . ') AGAINST(? IN BOOLEAN MODE) ' , [$ termString ]);
184+ }
183185
184- // Ensure at least one exact term matches if in search
185- if (count ($ exactTerms ) > 0 ) {
186- $ search = $ search ->where (function ($ query ) use ($ exactTerms , $ fieldsToSearch ) {
187- foreach ($ exactTerms as $ exactTerm ) {
188- foreach ($ fieldsToSearch as $ field ) {
189- $ query ->orWhere ($ field , 'like ' , $ exactTerm );
190- }
186+ // Ensure at least one exact term matches if in search
187+ if (count ($ exactTerms ) > 0 ) {
188+ $ search = $ search ->where (function ($ query ) use ($ exactTerms , $ fieldsToSearch ) {
189+ foreach ($ exactTerms as $ exactTerm ) {
190+ foreach ($ fieldsToSearch as $ field ) {
191+ $ query ->orWhere ($ field , 'like ' , $ exactTerm );
191192 }
192- });
193- }
194- $ orderBy = ' title_relevance ' ;
195- } ;
193+ }
194+ });
195+ }
196+ $ orderBy = $ isFuzzy ? ' title_relevance ' : ' updated_at ' ;
196197
197198 // Add additional where terms
198199 foreach ($ wheres as $ whereTerm ) {
199200 $ search ->where ($ whereTerm [0 ], $ whereTerm [1 ], $ whereTerm [2 ]);
200201 }
202+
201203 // Load in relations
202204 if ($ this ->isA ('page ' )) {
203205 $ search = $ search ->with ('book ' , 'chapter ' , 'createdBy ' , 'updatedBy ' );
0 commit comments