@@ -34,21 +34,26 @@ public abstract function setupFilter();
34
34
*/
35
35
public function scopeFilter (Builder $ builder , Request $ request = null , Filter $ filter = null )
36
36
{
37
- return $ this ->apply ($ builder , $ request );
37
+ $ filterRequest = FilterRequest::createFromRequest ($ request );
38
+
39
+ $ builder = $ this ->apply ($ builder , $ filterRequest );
40
+
41
+ $ builder = $ this ->applyGeneralSearch ($ builder , $ filterRequest );
42
+
43
+ return $ builder ;
38
44
}
39
45
40
46
/**
41
47
* Filter fields from request
42
48
*
43
49
* @param Builder $builder
44
- * @param $request
50
+ * @param FilterRequest $filterRequest
45
51
*
46
52
* @return Builder
47
53
* @throws UnsupportedDriverException
48
54
*/
49
- private function apply (Builder $ builder , $ request )
55
+ private function apply (Builder $ builder , FilterRequest $ filterRequest )
50
56
{
51
- $ filterRequest = FilterRequest::createFromRequest ($ request );
52
57
$ conjunction = $ filterRequest ->getConjunction ();
53
58
54
59
foreach ($ filterRequest ->getFilters () as $ filter ) {
@@ -62,48 +67,92 @@ private function apply(Builder $builder, $request)
62
67
continue ;
63
68
}
64
69
65
- // apply filter inside relation if the field from relation
66
- if ($ field ->isFromRelation ()) {
67
- // apply on custom scope if the relation has scope
68
- if ($ this ->modelHasScope ($ builder , $ field ->getScopeRelationFunctionName ())) {
69
- $ builder = $ builder ->{$ field ->getScopeRelationFunctionName ()}($ field , $ operator , $ value , $ conjunction );
70
- } else {
71
- if ($ builder ->getConnection ()->getName () == 'mongodb ' ) {
72
- throw new UnsupportedDriverException ('MongoDB ' , 'relational ' );
73
- }
74
-
75
- $ builder = $ builder ->has ($ field ->getRelation (), '>= ' , 1 , $ conjunction ,
76
- function (Builder $ builder ) use ($ field , $ value , $ operator ) {
77
- return $ this ->filterField ($ builder , $ field , $ operator , $ value );
78
- }
79
- );
80
- }
81
- } else {
82
- // apply on field
83
- $ builder = $ this ->filterField ($ builder , $ field , $ operator , $ value , $ conjunction );
84
- }
70
+ $ builder = $ this ->filterField ($ builder , $ field , $ operator , $ value , $ conjunction );
85
71
}
86
72
}
87
73
88
74
return $ builder ;
89
75
}
90
76
91
77
/**
92
- * Filter field
78
+ * Filter general search from the request
79
+ *
80
+ * @param Builder $builder
81
+ * @param FilterRequest $filterRequest
93
82
*
94
- * check if the field has a custom scope and apply it
83
+ * @return Builder
84
+ * @throws UnsupportedDriverException
85
+ */
86
+ private function applyGeneralSearch (Builder $ builder , FilterRequest $ filterRequest )
87
+ {
88
+ if (!empty ($ filterRequest ->getGeneralSearch ())) {
89
+ $ operator = $ this ->generalSearch ['operator ' ] ?: config ('advanced_filter.default_general_search_operator ' );
90
+
91
+ $ builder ->where (function (Builder $ builder ) use ($ filterRequest , $ operator ) {
92
+ foreach ($ this ->generalSearch ['fields ' ] as $ fieldName ) {
93
+ $ field = new Field ($ builder ->getModel (), $ fieldName );
94
+
95
+ $ this ->filterField ($ builder , $ field , $ operator , $ filterRequest ->getGeneralSearch ());
96
+ }
97
+ });
98
+ }
99
+
100
+ return $ builder ;
101
+ }
102
+
103
+ /**
104
+ * Filter a field
95
105
*
96
106
* @param Builder $builder
97
107
* @param Field $field
98
108
* @param $operator
99
109
* @param $value
100
110
* @param string $conjunction
101
111
*
102
- * @return mixed
112
+ * @return Builder
113
+ * @throws UnsupportedDriverException
103
114
*/
104
115
private function filterField (Builder $ builder , Field $ field , $ operator , $ value , $ conjunction = 'and ' )
105
116
{
106
- // apply on custom scope if the field has scope
117
+ // apply the filter inside the relation if the field from relation
118
+ if ($ field ->isFromRelation ()) {
119
+ // apply on custom scope if the relation has a scope
120
+ if ($ this ->modelHasScope ($ builder , $ field ->getScopeRelationFunctionName ())) {
121
+ return $ builder ->{$ field ->getScopeRelationFunctionName ()}($ field , $ operator , $ value , $ conjunction );
122
+ } else {
123
+ if ($ builder ->getConnection ()->getName () == 'mongodb ' ) {
124
+ throw new UnsupportedDriverException ('MongoDB ' , 'relational ' );
125
+ }
126
+
127
+ return $ builder ->has ($ field ->getRelation (), '>= ' , 1 , $ conjunction ,
128
+ function (Builder $ builder ) use ($ field , $ value , $ operator ) {
129
+ // consider as a non relation field inside the relation
130
+ return $ this ->filterNonRelationalField ($ builder , $ field , $ operator , $ value );
131
+ }
132
+ );
133
+ }
134
+ } else {
135
+ // a non relational field
136
+ return $ this ->filterNonRelationalField ($ builder , $ field , $ operator , $ value , $ conjunction );
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Filter a non relational field
142
+ *
143
+ * it checks if the field has a custom scope
144
+ *
145
+ * @param Builder $builder
146
+ * @param Field $field
147
+ * @param $operator
148
+ * @param $value
149
+ * @param string $conjunction
150
+ *
151
+ * @return mixed
152
+ */
153
+ private function filterNonRelationalField (Builder $ builder , Field $ field , $ operator , $ value , $ conjunction = 'and ' )
154
+ {
155
+ // apply on custom scope if the field has a scope
107
156
if ($ this ->modelHasScope ($ builder , $ field ->getScopeFunctionName ())) {
108
157
return $ builder ->{$ field ->getScopeFunctionName ()}($ field , $ operator , $ value , $ conjunction );
109
158
}
0 commit comments