3
3
namespace Designbycode \Datatables \Http \Traits ;
4
4
5
5
use Exception ;
6
- use Illuminate \Contracts \Pagination \LengthAwarePaginator ;
7
6
use Illuminate \Database \Eloquent \Builder ;
8
7
use Illuminate \Http \Request ;
8
+ use Illuminate \Pagination \LengthAwarePaginator ;
9
+ use Illuminate \Support \Arr ;
10
+ use Illuminate \Support \Facades \Schema ;
11
+ use Illuminate \Support \Str ;
9
12
10
13
trait DatatableTrait
11
14
{
12
- private Builder $ builder ;
15
+ protected bool $ allowDeletion = true ;
13
16
17
+ protected bool $ allowCreation = true ;
18
+
19
+ protected bool $ createUsingDialog = false ;
20
+
21
+ protected bool $ allowSearching = true ;
22
+
23
+ protected int $ default_limit = 25 ;
24
+
25
+ public Builder $ builder ;
26
+
27
+ /**
28
+ * @throws Exception
29
+ */
14
30
public function __construct ()
15
31
{
16
32
$ builder = $ this ->builder ();
@@ -22,19 +38,197 @@ public function __construct()
22
38
$ this ->builder = $ builder ;
23
39
}
24
40
25
- abstract protected function builder (): Builder ;
41
+ /**
42
+ * Use Model::query() image model controller
43
+ */
44
+ abstract public function builder (): Builder ;
26
45
27
- protected function getData (Request $ request ): array
46
+ /**
47
+ * Get all response data to be added to index
48
+ *
49
+ * @return array[]
50
+ */
51
+ public function getResponse (Request $ request ): array
28
52
{
29
53
return [
30
54
'data ' => [
55
+ 'name ' => $ this ->getDataTableName (),
56
+ 'name_singular ' => Str::singular ($ this ->getDataTableName ()),
57
+ 'settings ' => [
58
+ 'allow ' => [
59
+ 'deletions ' => $ this ->allowDeletion ,
60
+ 'creation ' => $ this ->allowCreation ,
61
+ 'searching ' => $ this ->allowSearching ,
62
+ ],
63
+ 'create_with_dialog ' => $ this ->createUsingDialog ,
64
+ 'pagination_limit ' => $ this ->getLimit ($ request ),
65
+ ],
66
+ 'database ' => [
67
+ 'typings ' => $ this ->getModelDatabaseTypings (),
68
+ 'input_types ' => $ this ->getFormInputTypes (),
69
+ ],
70
+ 'columns ' => [
71
+ 'updatable ' => $ this ->getUpdatableColumns (),
72
+ 'creatable ' => $ this ->getCreatableColumns (),
73
+ 'displayable ' => $ this ->getDisplayableColumns (),
74
+ ],
31
75
'records ' => $ this ->getRecords ($ request ),
32
76
],
33
77
];
34
78
}
35
79
80
+ /**
81
+ * Get the name of the database table
82
+ */
83
+ protected function getDataTableName (): string
84
+ {
85
+ return $ this ->builder ->getModel ()->getTable ();
86
+ }
87
+
88
+ /**
89
+ * Get the paginated limit
90
+ */
91
+ private function getLimit (Request $ request ): int
92
+ {
93
+ return $ request ->limit ?? $ this ->default_limit ;
94
+ }
95
+
96
+ /**
97
+ * They will give the typing of the database field
98
+ */
99
+ private function getModelDatabaseTypings (): array
100
+ {
101
+ return array_intersect_key ($ this ->getTableColumns (), array_flip (array_values ($ this ->getCreatableColumns ())));
102
+ }
103
+
104
+ /**
105
+ * Get array of database columns
106
+ */
107
+ protected function getTableColumns (): array
108
+ {
109
+ $ table = $ this ->builder ->getModel ()->getTable ();
110
+ $ builder = $ this ->builder ->getModel ()->getConnection ()->getSchemaBuilder ();
111
+ $ columns = $ builder ->getColumnListing ($ table );
112
+ $ columnsWithType = collect ($ columns )->mapWithKeys (function ($ item , $ key ) use ($ builder , $ table ) {
113
+ $ key = $ builder ->getColumnType ($ table , $ item );
114
+
115
+ return [$ item => $ key ];
116
+ });
117
+
118
+ return $ columnsWithType ->toArray ();
119
+ }
120
+
121
+ /**
122
+ * Give array of fields that is fillable
123
+ */
124
+ protected function getCreatableColumns (): array
125
+ {
126
+ return $ this ->builder ->getModel ()->getFillable ();
127
+ }
128
+
129
+ /**
130
+ * Create form input types
131
+ */
132
+ abstract public function getFormInputTypes (): array ;
133
+
134
+ /**
135
+ * Only column field that can be updated
136
+ */
137
+ protected function getUpdatableColumns (): array
138
+ {
139
+ return $ this ->getDisplayableColumns ();
140
+ }
141
+
142
+ /**
143
+ * Give array of database columns
144
+ */
145
+ private function getDisplayableColumns (): array
146
+ {
147
+ return array_diff ($ this ->getDisplayableColumnNames (), $ this ->builder ->getModel ()->getHidden (), $ this ->builder ->getModel ()->getDates ());
148
+ }
149
+
150
+ /**
151
+ * Gives the names of database column
152
+ */
153
+ protected function getDisplayableColumnNames (): array
154
+ {
155
+ return Schema::getColumnListing ($ this ->builder ->getModel ()->getTable ());
156
+ }
157
+
158
+ /**
159
+ * Build query and return collection of data
160
+ */
36
161
private function getRecords (Request $ request ): LengthAwarePaginator
37
162
{
38
- return $ this ->builder ->orderBy ('id ' , 'asc ' )->paginate ();
163
+ $ builder = $ this ->builder ;
164
+
165
+ if ($ this ->hasSearchQuery ($ request )) {
166
+ $ builder = $ this ->buildSearch ($ builder , $ request );
167
+ }
168
+
169
+ return $ this ->builder ->orderBy ('id ' , 'asc ' )->paginate ($ this ->getLimit ($ request ))
170
+ ->through (function ($ model ) {
171
+ return Arr::only ($ model ->toArray (), $ this ->getDisplayableColumns ());
172
+ });
173
+ }
174
+
175
+ /**
176
+ * Check if search query is present
177
+ */
178
+ protected function hasSearchQuery (Request $ request ): bool
179
+ {
180
+ return count (array_filter ($ request ->only ('column ' , 'operator ' , 'value ' ))) === 3 ;
181
+ }
182
+
183
+ private function buildSearch (Builder $ builder , Request $ request ): Builder
184
+ {
185
+ $ queryParts = $ this ->resolveQueryParts ($ request ->operator , $ request ->value );
186
+
187
+ if (! $ this ->hasSearchQuery ($ request )) {
188
+ dd ('no ' );
189
+ }
190
+
191
+ return $ builder ->where ($ request ->column , $ queryParts ['operator ' ], $ queryParts ['value ' ]);
192
+ }
193
+
194
+ /**
195
+ * Query part for search builder.
196
+ */
197
+ private function resolveQueryParts ($ operator , $ value ): mixed
198
+ {
199
+ return Arr::get ([
200
+ 'equals ' => [
201
+ 'operator ' => '= ' ,
202
+ 'value ' => $ value ,
203
+ ],
204
+ 'contains ' => [
205
+ 'operator ' => 'LIKE ' ,
206
+ 'value ' => "% {$ value }% " ,
207
+ ],
208
+ 'starts_with ' => [
209
+ 'operator ' => 'LIKE ' ,
210
+ 'value ' => "{$ value }% " ,
211
+ ],
212
+ 'ends_with ' => [
213
+ 'operator ' => 'LIKE ' ,
214
+ 'value ' => "% {$ value }" ,
215
+ ],
216
+ 'greater_than ' => [
217
+ 'operator ' => '> ' ,
218
+ 'value ' => $ value ,
219
+ ],
220
+ 'greater_or_equal_than ' => [
221
+ 'operator ' => '>= ' ,
222
+ 'value ' => $ value ,
223
+ ],
224
+ 'less_than ' => [
225
+ 'operator ' => '< ' ,
226
+ 'value ' => $ value ,
227
+ ],
228
+ 'less_or_equal_than ' => [
229
+ 'operator ' => '<= ' ,
230
+ 'value ' => $ value ,
231
+ ],
232
+ ], $ operator );
39
233
}
40
234
}
0 commit comments