Completed
Push — master ( 4e6a57...ff0fc5 )
by Arjay
02:27
created

DataTable::buildColumn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 3
1
<?php
2
3
namespace Yajra\Datatables\Services;
4
5
use Illuminate\Contracts\View\Factory;
6
use Illuminate\Support\Collection;
7
use Maatwebsite\Excel\Classes\LaravelExcelWorksheet;
8
use Maatwebsite\Excel\Writers\LaravelExcelWriter;
9
use Yajra\Datatables\Contracts\DataTableButtonsContract;
10
use Yajra\Datatables\Contracts\DataTableContract;
11
use Yajra\Datatables\Contracts\DataTableScopeContract;
12
use Yajra\Datatables\Datatables;
13
14
abstract class DataTable implements DataTableContract, DataTableButtonsContract
15
{
16
    /**
17
     * @var \Yajra\Datatables\Datatables
18
     */
19
    protected $datatables;
20
21
    /**
22
     * @var \Illuminate\Contracts\View\Factory
23
     */
24
    protected $viewFactory;
25
26
    /**
27
     * Datatables print preview view.
28
     *
29
     * @var string
30
     */
31
    protected $printPreview;
32
33
    /**
34
     * List of columns to be exported.
35
     *
36
     * @var string|array
37
     */
38
    protected $exportColumns = '*';
39
40
    /**
41
     * List of columns to be printed.
42
     *
43
     * @var string|array
44
     */
45
    protected $printColumns = '*';
46
47
    /**
48
     * Query scopes.
49
     *
50
     * @var \Yajra\Datatables\Contracts\DataTableScopeContract[]
51
     */
52
    protected $scopes = [];
53
54
    /**
55
     * @param \Yajra\Datatables\Datatables $datatables
56
     * @param \Illuminate\Contracts\View\Factory $viewFactory
57
     */
58
    public function __construct(Datatables $datatables, Factory $viewFactory)
59
    {
60
        $this->datatables  = $datatables;
61
        $this->viewFactory = $viewFactory;
62
    }
63
64
    /**
65
     * Render view.
66
     *
67
     * @param $view
68
     * @param array $data
69
     * @param array $mergeData
70
     * @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
71
     */
72
    public function render($view, $data = [], $mergeData = [])
73
    {
74
        if ($this->request()->ajax() && $this->request()->wantsJson()) {
75
            return $this->ajax();
76
        }
77
78
        switch ($this->datatables->getRequest()->get('action')) {
79
            case 'excel':
80
                return $this->excel();
81
82
            case 'csv':
83
                return $this->csv();
84
85
            case 'pdf':
86
                return $this->pdf();
87
88
            case 'print':
89
                return $this->printPreview();
90
91
            default:
92
                return $this->viewFactory->make($view, $data, $mergeData)->with('dataTable', $this->html());
93
        }
94
    }
95
96
    /**
97
     * Get Datatables Request instance.
98
     *
99
     * @return \Yajra\Datatables\Request
100
     */
101
    public function request()
102
    {
103
        return $this->datatables->getRequest();
104
    }
105
106
    /**
107
     * Export results to Excel file.
108
     *
109
     * @return mixed
110
     */
111
    public function excel()
112
    {
113
        return $this->buildExcelFile()->download('xls');
114
    }
115
116
    /**
117
     * Build excel file and prepare for export.
118
     *
119
     * @return mixed
120
     */
121
    protected function buildExcelFile()
122
    {
123
        return app('excel')->create($this->filename(), function (LaravelExcelWriter $excel) {
124
            $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) {
125
                $sheet->fromArray($this->getDataForExport());
126
            });
127
        });
128
    }
129
130
    /**
131
     * Get filename for export.
132
     *
133
     * @return string
134
     */
135
    protected function filename()
136
    {
137
        return 'export_' . time();
138
    }
139
140
    /**
141
     * Get mapped columns versus final decorated output.
142
     *
143
     * @return array
144
     */
145
    protected function getDataForExport()
146
    {
147
        return array_map(function ($row) {
148
            if ($columns = $this->exportColumns()) {
149
                return $this->buildExportColumn($row, $columns);
150
            }
151
152
            return $row;
153
        }, $this->getAjaxResponseData());
154
    }
155
156
    /**
157
     * Get decorated data as defined in datatables ajax response.
158
     *
159
     * @return mixed
160
     */
161
    protected function getAjaxResponseData()
162
    {
163
        $this->datatables->getRequest()->merge(['length' => -1]);
164
165
        $response = $this->ajax();
166
        $data     = $response->getData(true);
167
168
        return $data['data'];
169
    }
170
171
    /**
172
     * Get export columns definition.
173
     *
174
     * @return array|string
175
     */
176
    private function exportColumns()
177
    {
178
        return is_array($this->exportColumns) ? $this->exportColumns : $this->getColumnsFromBuilder();
179
    }
180
181
    /**
182
     * Get columns definition from html builder.
183
     *
184
     * @return array
185
     */
186
    protected function getColumnsFromBuilder()
187
    {
188
        return $this->html()->getColumns();
189
    }
190
191
    /**
192
     * Optional method if you want to use html builder.
193
     *
194
     * @return \Yajra\Datatables\Html\Builder
195
     */
196
    public function html()
197
    {
198
        return $this->builder();
199
    }
200
201
    /**
202
     * Get Datatables Html Builder instance.
203
     *
204
     * @return \Yajra\Datatables\Html\Builder
205
     */
206
    public function builder()
207
    {
208
        return $this->datatables->getHtmlBuilder();
209
    }
210
211
    /**
212
     * @param array $row
213
     * @param array|\Illuminate\Support\Collection $columns
214
     * @return array
215
     */
216
    protected function buildExportColumn(array $row, $columns)
217
    {
218
        return $this->buildColumn($row, $columns, 'exportable');
219
    }
220
221
    /**
222
     * Build printable and exportable column.
223
     *
224
     * @param array $row
225
     * @param array|\Illuminate\Support\Collection $columns
226
     * @param string $type
227
     * @return array
228
     */
229
    protected function buildColumn(array $row, $columns, $type)
230
    {
231
        if ($columns instanceof Collection) {
232
            return $this->buildColumnByCollection($row, $columns, $type);
233
        }
234
235
        return array_only($row, $columns);
236
    }
237
238
    /**
239
     * Build column from collection.
240
     *
241
     * @param array $row
242
     * @param \Illuminate\Support\Collection $columns
243
     * @param string $type
244
     * @return array
245
     */
246
    protected function buildColumnByCollection(array  $row, Collection $columns, $type)
247
    {
248
        $results = [];
249
        foreach ($columns->all() as $column) {
250
            if ($column[$type]) {
251
                $data = array_get($row, $column['data']);
252
253
                $results[$column['title']] = $type == 'exportable' ? strip_tags($data) : $data;
254
            }
255
        }
256
257
        return $results;
258
    }
259
260
    /**
261
     * Export results to CSV file.
262
     *
263
     * @return mixed
264
     */
265
    public function csv()
266
    {
267
        return $this->buildExcelFile()->download('csv');
268
    }
269
270
    /**
271
     * Export results to PDF file.
272
     *
273
     * @return mixed
274
     */
275
    public function pdf()
276
    {
277
        return $this->buildExcelFile()->download('pdf');
278
    }
279
280
    /**
281
     * Display printable view of datatables.
282
     *
283
     * @return \Illuminate\Contracts\View\View
284
     */
285
    public function printPreview()
286
    {
287
        $data = $this->getDataForPrint();
288
        $view = $this->printPreview ?: 'datatables::print';
289
290
        return $this->viewFactory->make($view, compact('data'));
291
    }
292
293
    /**
294
     * Get mapped columns versus final decorated output.
295
     *
296
     * @return array
297
     */
298
    protected function getDataForPrint()
299
    {
300
        return array_map(function ($row) {
301
            if ($columns = $this->printColumns()) {
302
                return $this->buildPrintColumn($row, $columns);
303
            }
304
305
            return $row;
306
        }, $this->getAjaxResponseData());
307
    }
308
309
    /**
310
     * Get printable columns.
311
     *
312
     * @return array|string
313
     */
314
    protected function printColumns()
315
    {
316
        return is_array($this->printColumns) ? $this->printColumns : $this->getColumnsFromBuilder();
317
    }
318
319
    /**
320
     * Build printable column.
321
     *
322
     * @param array $row
323
     * @param array|\Illuminate\Support\Collection $columns
324
     * @return array
325
     */
326
    protected function buildPrintColumn(array $row, $columns)
327
    {
328
        return $this->buildColumn($row, $columns, 'printable');
329
    }
330
331
    /**
332
     * Add basic array query scopes.
333
     *
334
     * @param \Yajra\Datatables\Contracts\DataTableScopeContract $scope
335
     * @return $this
336
     */
337
    public function addScope(DataTableScopeContract $scope)
338
    {
339
        $this->scopes[] = $scope;
340
341
        return $this;
342
    }
343
344
    /**
345
     * Apply query scopes.
346
     *
347
     * @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
348
     * @return mixed
349
     */
350
    protected function applyScopes($query)
351
    {
352
        foreach ($this->scopes as $scope) {
353
            $scope->apply($query);
354
        }
355
356
        return $query;
357
    }
358
359
    /**
360
     * Get default builder parameters.
361
     *
362
     * @return array
363
     */
364
    protected function getBuilderParameters()
365
    {
366
        return [
367
            'order'   => [[0, 'desc']],
368
            'buttons' => [
369
                'create',
370
                [
371
                    'extend'  => 'collection',
372
                    'text'    => '<i class="fa fa-download"></i> Export',
373
                    'buttons' => [
374
                        'csv',
375
                        'excel',
376
                        'pdf',
377
                    ],
378
                ],
379
                'print',
380
                'reset',
381
                'reload',
382
            ],
383
        ];
384
    }
385
}
386