Passed
Pull Request — master (#1114)
by Iman
04:37
created

Index::addActionButtons()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 4
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace crocodicstudio\crudbooster\CBCoreModule;
4
5
use crocodicstudio\crudbooster\CBCoreModule\Index\FilterIndexRows;
6
use crocodicstudio\crudbooster\CBCoreModule\Index\Order;
7
use crocodicstudio\crudbooster\CBCoreModule\Index\ValueCalculator;
8
use crocodicstudio\crudbooster\controllers\CBController;
9
use crocodicstudio\crudbooster\helpers\DbInspector;
10
use Illuminate\Support\Facades\Request;
11
use Illuminate\Support\Facades\DB;
12
use CRUDBooster;
0 ignored issues
show
Bug introduced by
The type CRUDBooster was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use CB;
14
use Schema;
15
16
class Index
17
{
18
    private $cb;
19
20
    private $table;
21
22
    public function index(CBController $CbCtrl)
23
    {
24
        $this->cb = $CbCtrl;
25
        $this->table = $CbCtrl->table;
26
27
        $data = [];
28
        if (request('parent_table')) {
29
            $data = $this->_handleParentTable();
30
        }
31
32
        $data['table'] = $CbCtrl->table;
33
        $data['table_pk'] = DbInspector::findPk($CbCtrl->table);
34
        $data['page_title'] = CRUDBooster::getCurrentModule()->name;
35
        $data['page_description'] = cbTrans('default_module_description');
36
        $data['date_candidate'] = $CbCtrl->date_candidate;
37
        $data['limit'] = $limit = request('limit', $CbCtrl->limit);
38
39
        $tablePK = $data['table_pk'];
40
41
        $result = $CbCtrl->table()->select(DB::raw($CbCtrl->table.".".$CbCtrl->primary_key));
42
43
        $this->_filterForParent($result);
44
45
        $CbCtrl->hookQueryIndex($result);
46
47
        $tableCols = DbInspector::getTableCols($CbCtrl->table);
48
        $this->_filterOutSoftDeleted($tableCols, $result);
49
        unset($tableCols);
50
51
        $table = $CbCtrl->table;
52
        $columns_table = $CbCtrl->columns_table;
53
        foreach ($columns_table as $index => $coltab) {
54
            $field = @$coltab['name'];
55
56
            if (strpos($field, '.')) {
57
                $columns_table = $this->addDotField($columns_table, $index, $field, $result);
58
            } else {
59
                $columns_table = $this->_addField($columns_table, $index, $field, $result, $table);
60
            }
61
        }
62
63
        $this->_applyWhereAndQfilters($result, $columns_table, $table);
64
65
        $filter_is_orderby = false;
66
        if (request('filter_column')) {
67
            $filter_is_orderby = app(FilterIndexRows::class)->filterIndexRows($result, request('filter_column'));
68
        }
69
70
        if ($filter_is_orderby === true) {
71
            (new Order($this->cb))->handle($result, $table);
72
        }
73
        $data['result'] = $result->paginate($limit);
74
75
        $data['columns'] = $columns_table;
76
77
        if ($CbCtrl->index_return) {
78
            return $data;
79
        }
80
81
        //LISTING INDEX HTML
82
        $addAction = $CbCtrl->data['addaction'];
83
84
        if ($CbCtrl->sub_module) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $CbCtrl->sub_module of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
85
            $addAction = $this->_handleSubModules($addAction);
86
        }
87
88
        //$mainpath = CRUDBooster::mainpath();
89
        //$orig_mainpath = $CbCtrl->data['mainpath'];
90
        //$title_field = $CbCtrl->title_field;
91
        $number = (request('page', 1) - 1) * $limit + 1;
92
        $html_contents = $this->htmlContents($CbCtrl, $data, $tablePK, $number, $columns_table, $table, $addAction); //end foreach data[result]
93
94
        $data['html_contents'] = ['html' => $html_contents, 'data' => $data['result']];
95
96
        return $data;
97
    }
98
    /**
99
     * @return array
100
     */
101
    private function _handleParentTable()
102
    {
103
        $data = [];
104
        $data['parent_table'] = DB::table(request('parent_table'))->where(DbInspector::findPk(request('parent_table')), request('parent_id'))->first();
0 ignored issues
show
Bug introduced by
It seems like request('parent_table') can also be of type array; however, parameter $table of Illuminate\Database\Connection::table() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

104
        $data['parent_table'] = DB::table(/** @scrutinizer ignore-type */ request('parent_table'))->where(DbInspector::findPk(request('parent_table')), request('parent_id'))->first();
Loading history...
105
        if (request('foreign_key')) {
106
            $data['parent_field'] = request('foreign_key');
107
        } else {
108
            $data['parent_field'] = CB::getTableForeignKey(request('parent_table'), $this->table);
109
        }
110
111
        if (! $data['parent_field']) {
112
            return $data;
113
        }
114
115
        foreach ($this->cb->columns_table as $i => $col) {
116
            if ($col['name'] == $data['parent_field']) {
117
                unset($this->cb->columns_table[$i]);
118
            }
119
        }
120
121
        return $data;
122
    }
123
124
    /**
125
     * @param $result
126
     */
127
    private function _filterForParent($result)
128
    {
129
        if (! request('parent_id')) {
130
            return null;
131
        }
132
133
        $table_parent = CRUDBooster::parseSqlTable($this->table)['table'];
134
        $result->where($table_parent.'.'.request('foreign_key'), request('parent_id'));
0 ignored issues
show
Bug introduced by
Are you sure request('foreign_key') of type Illuminate\Http\Request|string|array can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

134
        $result->where($table_parent.'.'./** @scrutinizer ignore-type */ request('foreign_key'), request('parent_id'));
Loading history...
135
    }
136
137
    /**
138
     * @param $table_columns
139
     * @param $result
140
     */
141
    private function _filterOutSoftDeleted($table_columns, $result)
142
    {
143
        if (! in_array('deleted_at', $table_columns)) {
144
            return;
145
        }
146
        $result->where($this->table.'.deleted_at', '=', null);
147
    }
148
149
    /**
150
     * @param $result
151
     * @param $field
152
     * @param $columns_table
153
     * @param $index
154
     * @return mixed
155
     */
156
    private function addDotField($columns_table, $index, $field, $result)
157
    {
158
        $result->addselect($field.' as '.str_slug($field, '_'));
159
        $tableField = substr($field, 0, strpos($field, '.'));
160
        $fieldOrign = substr($field, strpos($field, '.') + 1);
161
        $columns_table[$index]['type_data'] = DbInspector::getFieldTypes($tableField, $fieldOrign);
162
        $columns_table[$index]['field'] = str_slug($field, '_');
163
        $columns_table[$index]['field_raw'] = $field;
164
        $columns_table[$index]['field_with'] = $tableField.'.'.$fieldOrign;
165
166
        return $columns_table;
167
    }
168
169
    /**
170
     * @param $columns_table
171
     * @param $index
172
     * @param $field
173
     * @param $table
174
     * @param $result
175
     * @return mixed
176
     */
177
    private function _addField($columns_table, $index, $field, $result, $table)
178
    {
179
        $columns_table[$index]['type_data'] = 'varchar';
180
        $columns_table[$index]['field_with'] = null;
181
        $columns_table[$index]['field'] = $field;
182
        $columns_table[$index]['field_raw'] = $field;
183
184
        if (\Schema::hasColumn($table, $field)) {
185
            $result->addselect($table.'.'.$field);
186
            $columns_table[$index]['type_data'] = DbInspector::getFieldTypes($table, $field);
187
            $columns_table[$index]['field_with'] = $table.'.'.$field;
188
        }
189
190
        return $columns_table;
191
    }
192
193
    /**
194
     * @param $result
195
     * @param $columns_table
196
     * @param $table
197
     * @return mixed
198
     */
199
    private function _applyWhereAndQfilters($result, $columns_table, $table)
200
    {
201
        if (request('q')) {
202
            $result->where(function ($query) use ($columns_table) {
203
                foreach ($columns_table as $col) {
204
                    if (! $col['field_with']) {
205
                        continue;
206
                    }
207
                    $query->orwhere($col['field_with'], "like", "%".request("q")."%");
0 ignored issues
show
Bug introduced by
Are you sure request('q') of type Illuminate\Http\Request|string|array can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

207
                    $query->orwhere($col['field_with'], "like", "%"./** @scrutinizer ignore-type */ request("q")."%");
Loading history...
208
                }
209
            });
210
        }
211
212
        if (request('where')) {
213
            foreach (request('where') as $k => $v) {
214
                $result->where($table.'.'.$k, $v);
215
            }
216
        }
217
    }
218
219
    /**
220
     * @param $addAction
221
     * @return array
222
     */
223
    private function _handleSubModules($addAction)
224
    {
225
        foreach ($this->cb->sub_module as $module) {
226
            $table_parent = CRUDBooster::parseSqlTable($this->table)['table'];
227
            $addAction[] = [
228
                'label' => $module['label'],
229
                'icon' => $module['button_icon'],
230
                'url' => $this->subModuleUrl($module, $table_parent),
231
                'color' => $module['button_color'],
232
                'showIf' => $module['showIf'],
233
            ];
234
        }
235
236
        return $addAction;
237
    }
238
239
    /**
240
     * @param \crocodicstudio\crudbooster\controllers\CBController $CbCtrl
241
     * @param $data
242
     * @param $tablePK
243
     * @param $number
244
     * @param $columnsTable
245
     * @param $table
246
     * @param $addaction
247
     * @return array
248
     */
249
    private function htmlContents(CBController $CbCtrl, $data, $tablePK, $number, $columnsTable, $table, $addaction)
250
    {
251
        $htmlContents = [];
252
        foreach ($data['result'] as $row) {
253
            $htmlContent = [];
254
255
            $htmlContent = $this->addCheckBox($CbCtrl, $tablePK, $row, $htmlContent);
256
            $htmlContent = $this->addRowNumber($CbCtrl, $number, $htmlContent);
257
            $htmlContent = $this->addOtherColumns($columnsTable, $table, $row, $htmlContent);
258
            $htmlContent = $this->addActionButtons($CbCtrl, $addaction, $row, $htmlContent);
259
            $htmlContent = $this->performHookOnRow($CbCtrl, $htmlContent);
260
            $htmlContents[] = $htmlContent;
261
            $number++;
262
        }
263
264
        return $htmlContents;
265
    }
266
267
    /**
268
     * @param $module
269
     * @param $table_parent
270
     * @return string
271
     */
272
    private function subModuleUrl($module, $table_parent)
273
    {
274
        return CRUDBooster::adminPath($module['path']).'?parent_table='.$table_parent.'&parent_columns='
275
            .$module['parent_columns'].'&parent_columns_alias='
276
            .$module['parent_columns_alias'].'&parent_id=['
277
            .(! isset($module['custom_parent_id']) ? "id" : $module['custom_parent_id'])
278
            .']&return_url='.urlencode(Request::fullUrl()).'&foreign_key='
279
            .$module['foreign_key'].'&label='.urlencode($module['label']);
280
    }
281
282
    /**
283
     * @param \crocodicstudio\crudbooster\controllers\CBController $CbCtrl
284
     * @param $tablePK
285
     * @param $row
286
     * @param $htmlContent
287
     * @return array
288
     */
289
    private function addCheckBox(CBController $CbCtrl, $tablePK, $row, $htmlContent)
290
    {
291
        if ($CbCtrl->button_bulk_action) {
292
            $htmlContent[] = "<input type='checkbox' class='checkbox' name='checkbox[]' value='".$row->{$tablePK}."'/>";
293
        }
294
295
        return $htmlContent;
296
    }
297
298
    /**
299
     * @param \crocodicstudio\crudbooster\controllers\CBController $CbCtrl
300
     * @param $number
301
     * @param $htmlContent
302
     * @return array
303
     */
304
    private function addRowNumber(CBController $CbCtrl, $number, $htmlContent)
305
    {
306
        if ($CbCtrl->show_numbering) {
307
            $htmlContent[] = $number.'. ';
308
        }
309
310
        return $htmlContent;
311
    }
312
313
    /**
314
     * @param $columnsTable
315
     * @param $table
316
     * @param $row
317
     * @param $htmlContent
318
     * @return array
319
     */
320
    private function addOtherColumns($columnsTable, $table, $row, $htmlContent)
321
    {
322
        foreach ($columnsTable as $col) {
323
            if ($col['visible'] === false) {
324
                continue;
325
            }
326
            $htmlContent[] = (new ValueCalculator)->calculate($col, $row, $table, @$row->{$this->cb->title_field});
327
        }
328
329
        return $htmlContent;
330
    }
331
332
    /**
333
     * @param \crocodicstudio\crudbooster\controllers\CBController $CbCtrl
334
     * @param $htmlContent
335
     * @return mixed
336
     */
337
    private function performHookOnRow(CBController $CbCtrl, $htmlContent)
338
    {
339
        foreach ($htmlContent as $i => $v) {
340
            $CbCtrl->hookRowIndex($i, $v);
341
            $htmlContent[$i] = $v;
342
        }
343
344
        return $htmlContent;
345
    }
346
347
    /**
348
     * @param \crocodicstudio\crudbooster\controllers\CBController $CbCtrl
349
     * @param $addaction
350
     * @param $row
351
     * @param $parent_field
352
     * @param $htmlContent
353
     * @return array
354
     * @throws \Throwable
355
     */
356
    private function addActionButtons(CBController $CbCtrl, $addaction, $row, $htmlContent)
357
    {
358
        if ($CbCtrl->button_table_action) {
359
            $button_action_style = $CbCtrl->button_action_style;
360
            $htmlContent[] = "<div class='button_action' style='text-align:right'>".view('crudbooster::components.action', compact('addaction', 'row', 'button_action_style', 'parent_field'))->render()."</div>";
361
        }
362
363
        return $htmlContent;
364
    }
365
}