@@ -117,6 +117,16 @@ abstract class Field implements Arrayable, JsonSerializable
117117 */
118118 protected bool |Closure $ searchable = false ;
119119
120+ /**
121+ * The filter query resolver callback.
122+ */
123+ protected ?Closure $ searchQueryResolver = null ;
124+
125+ /**
126+ * Indicates if the field is filterable.
127+ */
128+ protected bool |Closure $ filterable = false ;
129+
120130 /**
121131 * The filter query resolver callback.
122132 */
@@ -317,25 +327,37 @@ public function isSortable(): bool
317327 */
318328 public function searchable (bool |Closure $ value = true , ?Closure $ callback = null ): static
319329 {
320- $ callback ??= function (Request $ request , Builder $ query , mixed $ value , string $ attribute ): Builder {
330+ $ this ->searchable = $ value ;
331+
332+ $ this ->searchQueryResolver = $ callback ?: function (Request $ request , Builder $ query , mixed $ value , string $ attribute ): Builder {
321333 return $ query ->where ($ query ->qualifyColumn ($ attribute ), 'like ' , "% {$ value }% " , 'or ' );
322334 };
323335
324- return $ this -> filterable ( $ callback , $ value ) ;
336+ return $ this ;
325337 }
326338
327339 /**
328340 * Determine if the field is searchable.
329341 */
330342 public function isSearchable (): bool
331343 {
332- if (! $ this ->isFilterable () ) {
344+ if ($ this ->computed ) {
333345 return false ;
334346 }
335347
336348 return $ this ->searchable instanceof Closure ? call_user_func ($ this ->searchable ) : $ this ->searchable ;
337349 }
338350
351+ /**
352+ * Resolve the search query.
353+ */
354+ public function resolveSearchQuery (Request $ request , Builder $ query , mixed $ value ): Builder
355+ {
356+ return $ this ->isSearchable ()
357+ ? call_user_func_array ($ this ->searchQueryResolver , [$ request , $ query , $ value , $ this ->getModelAttribute ()])
358+ : $ query ;
359+ }
360+
339361 /**
340362 * Set the translatable attribute.
341363 */
@@ -361,9 +383,9 @@ public function isTranslatable(): bool
361383 /**
362384 * Set the filterable attribute.
363385 */
364- public function filterable (? Closure $ callback = null , bool | Closure $ search = false ): static
386+ public function filterable (bool | Closure $ value = true , ? Closure $ callback = null ): static
365387 {
366- $ this ->searchable = $ search ;
388+ $ this ->filterable = $ value ;
367389
368390 $ this ->filterQueryResolver = $ callback ?: function (Request $ request , Builder $ query , mixed $ value , string $ attribute ): Builder {
369391 return $ query ->where ($ query ->qualifyColumn ($ attribute ), $ value );
@@ -377,7 +399,11 @@ public function filterable(?Closure $callback = null, bool|Closure $search = fal
377399 */
378400 public function isFilterable (): bool
379401 {
380- return ! $ this ->computed && $ this ->filterQueryResolver instanceof Closure;
402+ if ($ this ->computed ) {
403+ return false ;
404+ }
405+
406+ return $ this ->filterable instanceof Closure ? call_user_func ($ this ->filterable ) : $ this ->filterable ;
381407 }
382408
383409 /**
0 commit comments