22
33namespace Quest \Macros ;
44
5- use Illuminate \Database \Query \Builder ;
65use Quest \Matchers \ExactMatcher ;
76use Illuminate \Support \Facades \DB ;
87use Quest \Matchers \AcronymMatcher ;
98use Quest \Matchers \InStringMatcher ;
109use Quest \Matchers \StudlyCaseMatcher ;
10+ use Illuminate \Database \Query \Builder ;
1111use Quest \Matchers \StartOfWordsMatcher ;
1212use Quest \Matchers \StartOfStringMatcher ;
1313use Quest \Matchers \TimesInStringMatcher ;
1616
1717class WhereFuzzy
1818{
19-
2019 /**
2120 * The weights for the pattern matching classes.
2221 *
2322 **/
2423 protected static array $ matchers = [
25- ExactMatcher::class => 100 ,
26- StartOfStringMatcher::class => 50 ,
27- AcronymMatcher::class => 42 ,
24+ ExactMatcher::class => 100 ,
25+ StartOfStringMatcher::class => 50 ,
26+ AcronymMatcher::class => 42 ,
2827 ConsecutiveCharactersMatcher::class => 40 ,
29- StartOfWordsMatcher::class => 35 ,
30- StudlyCaseMatcher::class => 32 ,
31- InStringMatcher::class => 30 ,
32- TimesInStringMatcher::class => 8 ,
28+ StartOfWordsMatcher::class => 35 ,
29+ StudlyCaseMatcher::class => 32 ,
30+ InStringMatcher::class => 30 ,
31+ TimesInStringMatcher::class => 8 ,
3332 ];
3433
3534 /**
@@ -38,33 +37,35 @@ class WhereFuzzy
3837 **/
3938 public static function make (Builder $ builder , $ field , $ value ): Builder
4039 {
41- $ value = static ::escapeValue ($ value );
40+ $ value = static ::escapeValue ($ value );
4241 $ nativeField = '` ' . str_replace ('. ' , '`.` ' , trim ($ field , '` ' )) . '` ' ;
4342
44- if (!is_array ($ builder ->columns ) || empty ($ builder ->columns )) {
43+ if (! is_array ($ builder ->columns ) || empty ($ builder ->columns )) {
4544 $ builder ->columns = ['* ' ];
4645 }
46+
4747 $ builder
4848 ->addSelect ([static ::pipeline ($ field , $ nativeField , $ value )])
4949 ->having ('fuzzy_relevance_ ' . str_replace ('. ' , '_ ' , $ field ), '> ' , 0 );
5050
5151 static ::calculateTotalRelevanceColumn ($ builder );
52+
5253 return $ builder ;
5354 }
5455
5556 /**
56- * Construct a fuzzy search expression.
57+ * Construct a fuzzy OR search expression.
5758 *
5859 **/
5960 public static function makeOr (Builder $ builder , $ field , $ value ): Builder
6061 {
61-
62- $ value = static ::escapeValue ($ value );
62+ $ value = static ::escapeValue ($ value );
6363 $ nativeField = '` ' . str_replace ('. ' , '`.` ' , trim ($ field , '` ' )) . '` ' ;
6464
65- if (!is_array ($ builder ->columns ) || empty ($ builder ->columns )) {
65+ if (! is_array ($ builder ->columns ) || empty ($ builder ->columns )) {
6666 $ builder ->columns = ['* ' ];
6767 }
68+
6869 $ builder
6970 ->addSelect ([static ::pipeline ($ field , $ nativeField , $ value )])
7071 ->orHaving ('fuzzy_relevance_ ' . str_replace ('. ' , '_ ' , $ field ), '> ' , 0 );
@@ -75,74 +76,84 @@ public static function makeOr(Builder $builder, $field, $value): Builder
7576 }
7677
7778 /**
78- * Manage relevance columns SUM for total relevance ORDER
79- * Searches all relevance columns and parses the relevance expressions to create the total relevance column
80- * and creates the order statement for it
81- * @param $builder
82- * @return bool
79+ * Manage relevance columns SUM for total relevance ORDER.
80+ *
81+ * Searches all relevance columns and parses the relevance
82+ * expressions to create the total relevance column
83+ * and creates the order statement for it.
84+ *
8385 */
8486 protected static function calculateTotalRelevanceColumn ($ builder ): bool
8587 {
86- if (!empty ($ builder ->columns )) {
88+ if (! empty ($ builder ->columns )) {
8789 $ existingRelevanceColumns = [];
88- $ sumColumnIdx = null ;
90+ $ sumColumnIdx = null ;
91+
8992 // search for fuzzy_relevance_* columns and _fuzzy_relevance_ position
9093 foreach ($ builder ->columns as $ as => $ column ) {
9194 if ($ column instanceof Expression) {
9295 if (stripos ($ column ->getValue (), 'AS fuzzy_relevance_ ' )) {
9396 $ matches = [];
97+
9498 preg_match ('/AS (fuzzy_relevance_.*)$/ ' , $ column ->getValue (), $ matches );
95- if (!empty ($ matches [1 ])) {
99+
100+ if (! empty ($ matches [1 ])) {
96101 $ existingRelevanceColumns [$ as ] = $ matches [1 ];
97102 }
98103 } elseif (stripos ($ column ->getValue (), 'AS _fuzzy_relevance_ ' )) {
99104 $ sumColumnIdx = $ as ;
100105 }
101106 }
102107 }
108+
103109 // glue together all relevance expresions under _fuzzy_relevance_ column
104110 $ relevanceTotalColumn = '' ;
111+
105112 foreach ($ existingRelevanceColumns as $ as => $ column ) {
106- $ relevanceTotalColumn .= (!empty ($ relevanceTotalColumn ) ? ' + ' : '' )
113+ $ relevanceTotalColumn .= (! empty ($ relevanceTotalColumn ) ? ' + ' : '' )
107114 . '( '
108115 . str_ireplace (' AS ' . $ column , '' , $ builder ->columns [$ as ]->getValue ())
109116 . ') ' ;
110117 }
118+
111119 $ relevanceTotalColumn .= ' AS _fuzzy_relevance_ ' ;
112120
113121 if (is_null ($ sumColumnIdx )) {
114122 // no sum column yet, just add this one
115- $ builder
116- ->addSelect ([new Expression ($ relevanceTotalColumn )]);
123+ $ builder ->addSelect ([new Expression ($ relevanceTotalColumn )]);
117124 } else {
118125 // update the existing one
119126 $ builder ->columns [$ sumColumnIdx ] = new Expression ($ relevanceTotalColumn );
120127 }
128+
121129 // only add the _fuzzy_relevance_ ORDER once
122130 if (
123- !$ builder ->orders
124- || ($ builder ->orders
125- && array_search ('_fuzzy_relevance_ ' ,
131+ ! $ builder ->orders
132+ || (
133+ $ builder ->orders
134+ && array_search (
135+ '_fuzzy_relevance_ ' ,
126136 array_column ($ builder ->orders , 'column ' )
127137 ) === false
128138 )
129139 ) {
130140 $ builder ->orderBy ('_fuzzy_relevance_ ' , 'desc ' );
131141 }
142+
132143 return true ;
133144 }
145+
134146 return false ;
135147 }
136148
137149 /**
138- * Escape value input for fuzzy search
139- * @param $value
140- * @return false|string
150+ * Escape value input for fuzzy search.
141151 */
142152 protected static function escapeValue ($ value )
143153 {
144154 $ value = str_replace (['" ' , "' " , '` ' ], '' , $ value );
145155 $ value = substr (DB ::connection ()->getPdo ()->quote ($ value ), 1 , -1 );
156+
146157 return $ value ;
147158 }
148159
0 commit comments