Completed
Push — master ( b0ead7...bcf815 )
by Arjay
10s
created

DataTable::buildExcelFile()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
3
namespace Yajra\Datatables\Services;
4
5
use Illuminate\Contracts\View\Factory;
6
use Maatwebsite\Excel\Classes\LaravelExcelWorksheet;
7
use Maatwebsite\Excel\Writers\LaravelExcelWriter;
8
use Yajra\Datatables\Contracts\DataTableButtonsContract;
9
use Yajra\Datatables\Contracts\DataTableContract;
10
use Yajra\Datatables\Contracts\DataTableScopeContract;
11
use Yajra\Datatables\Datatables;
12
use Yajra\Datatables\Transformers\DataTransformer;
13
14
/**
15
 * Class DataTable.
16
 *
17
 * @package Yajra\Datatables\Services
18
 * @author  Arjay Angeles <[email protected]>
19
 */
20
abstract class DataTable implements DataTableContract, DataTableButtonsContract
21
{
22
    /**
23
     * @var \Yajra\Datatables\Datatables
24
     */
25
    protected $datatables;
26
27
    /**
28
     * @var \Illuminate\Contracts\View\Factory
29
     */
30
    protected $viewFactory;
31
32
    /**
33
     * Datatables print preview view.
34
     *
35
     * @var string
36
     */
37
    protected $printPreview = 'datatables::print';
38
39
    /**
40
     * List of columns to be exported.
41
     *
42
     * @var string|array
43
     */
44
    protected $exportColumns = '*';
45
46
    /**
47
     * List of columns to be printed.
48
     *
49
     * @var string|array
50
     */
51
    protected $printColumns = '*';
52
53
    /**
54
     * Query scopes.
55
     *
56
     * @var \Yajra\Datatables\Contracts\DataTableScopeContract[]
57
     */
58
    protected $scopes = [];
59
60
    /**
61
     * Html builder.
62
     *
63
     * @var \Yajra\Datatables\Html\Builder
64
     */
65
    protected $htmlBuilder;
66
67
    /**
68
     * Export filename.
69
     *
70
     * @var string
71
     */
72
    protected $filename = '';
73
74
    /**
75
     * Custom attributes set on the class.
76
     *
77
     * @var array
78
     */
79
    protected $attributes = [];
80
81
    /**
82
     * DataTable constructor.
83
     *
84
     * @param \Yajra\Datatables\Datatables $datatables
85
     * @param \Illuminate\Contracts\View\Factory $viewFactory
86
     */
87
    public function __construct(Datatables $datatables, Factory $viewFactory)
88
    {
89
        $this->datatables  = $datatables;
90
        $this->viewFactory = $viewFactory;
91
    }
92
93
    /**
94
     * Process dataTables needed render output.
95
     *
96
     * @param string $view
97
     * @param array $data
98
     * @param array $mergeData
99
     * @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
100
     */
101
    public function render($view, $data = [], $mergeData = [])
102
    {
103
        if ($this->request()->ajax() && $this->request()->wantsJson()) {
104
            return $this->ajax();
105
        }
106
107
        if ($action = $this->request()->get('action') AND in_array($action, ['print', 'csv', 'excel', 'pdf'])) {
108
            if ($action == 'print') {
109
                return $this->printPreview();
110
            }
111
112
            return call_user_func_array([$this, $action], []);
113
        }
114
115
        return $this->viewFactory->make($view, $data, $mergeData)->with('dataTable', $this->html());
116
    }
117
118
    /**
119
     * Get Datatables Request instance.
120
     *
121
     * @return \Yajra\Datatables\Request
122
     */
123
    public function request()
124
    {
125
        return $this->datatables->getRequest();
126
    }
127
128
    /**
129
     * Display printable view of datatables.
130
     *
131
     * @return \Illuminate\Contracts\View\View
132
     */
133
    public function printPreview()
134
    {
135
        $data = $this->getDataForPrint();
136
137
        return $this->viewFactory->make($this->printPreview, compact('data'));
138
    }
139
140
    /**
141
     * Get mapped columns versus final decorated output.
142
     *
143
     * @return array
144
     */
145
    protected function getDataForPrint()
146
    {
147
        $columns = $this->printColumns();
148
149
        return $this->mapResponseToColumns($columns, 'printable');
150
    }
151
152
    /**
153
     * Get printable columns.
154
     *
155
     * @return array|string
156
     */
157
    protected function printColumns()
158
    {
159
        return is_array($this->printColumns) ? $this->printColumns : $this->getColumnsFromBuilder();
160
    }
161
162
    /**
163
     * Get columns definition from html builder.
164
     *
165
     * @return array
166
     */
167
    protected function getColumnsFromBuilder()
168
    {
169
        return $this->html()->getColumns();
170
    }
171
172
    /**
173
     * Display ajax response.
174
     *
175
     * @return \Illuminate\Http\JsonResponse
176
     */
177
    public function ajax()
178
    {
179
        return $this->dataTable()->make(true);
0 ignored issues
show
Bug introduced by
The method dataTable() does not seem to exist on object<Yajra\Datatables\Services\DataTable>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
180
    }
181
182
    /**
183
     * Optional method if you want to use html builder.
184
     *
185
     * @return \Yajra\Datatables\Html\Builder
186
     */
187
    public function html()
188
    {
189
        return $this->builder();
190
    }
191
192
    /**
193
     * Get Datatables Html Builder instance.
194
     *
195
     * @return \Yajra\Datatables\Html\Builder
196
     */
197
    public function builder()
198
    {
199
        return $this->htmlBuilder ?: $this->htmlBuilder = app('datatables.html');
200
    }
201
202
    /**
203
     * Map ajax response to columns definition.
204
     *
205
     * @param mixed $columns
206
     * @param string $type
207
     * @return array
208
     */
209
    protected function mapResponseToColumns($columns, $type)
210
    {
211
        return array_map(function ($row) use ($columns, $type) {
212
            if ($columns) {
213
                return (new DataTransformer())->transform($row, $columns, $type);
214
            }
215
216
            return $row;
217
        }, $this->getAjaxResponseData());
218
    }
219
220
    /**
221
     * Get decorated data as defined in datatables ajax response.
222
     *
223
     * @return array
224
     */
225
    protected function getAjaxResponseData()
226
    {
227
        $this->datatables->getRequest()->merge(['length' => -1]);
228
229
        $response = $this->ajax();
230
        $data     = $response->getData(true);
231
232
        return $data['data'];
233
    }
234
235
    /**
236
     * Export results to Excel file.
237
     *
238
     * @return void
239
     */
240
    public function excel()
241
    {
242
        $this->buildExcelFile()->download('xls');
243
    }
244
245
    /**
246
     * Build excel file and prepare for export.
247
     *
248
     * @return \Maatwebsite\Excel\Writers\LaravelExcelWriter
249
     */
250
    protected function buildExcelFile()
251
    {
252
        /** @var \Maatwebsite\Excel\Excel $excel */
253
        $excel = app('excel');
254
255
        return $excel->create($this->getFilename(), function (LaravelExcelWriter $excel) {
256
            $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) {
257
                $sheet->fromArray($this->getDataForExport());
258
            });
259
        });
260
    }
261
262
    /**
263
     * Get export filename.
264
     *
265
     * @return string
266
     */
267
    public function getFilename()
268
    {
269
        return $this->filename ?: $this->filename();
270
    }
271
272
    /**
273
     * Set export filename.
274
     *
275
     * @param string $filename
276
     * @return DataTable
277
     */
278
    public function setFilename($filename)
279
    {
280
        $this->filename = $filename;
281
282
        return $this;
283
    }
284
285
    /**
286
     * Get filename for export.
287
     *
288
     * @return string
289
     */
290
    protected function filename()
291
    {
292
        return 'export_' . time();
293
    }
294
295
    /**
296
     * Get mapped columns versus final decorated output.
297
     *
298
     * @return array
299
     */
300
    protected function getDataForExport()
301
    {
302
        $columns = $this->exportColumns();
303
304
        return $this->mapResponseToColumns($columns, 'exportable');
305
    }
306
307
    /**
308
     * Get export columns definition.
309
     *
310
     * @return array|string
311
     */
312
    private function exportColumns()
313
    {
314
        return is_array($this->exportColumns) ? $this->exportColumns : $this->getColumnsFromBuilder();
315
    }
316
317
    /**
318
     * Export results to CSV file.
319
     *
320
     * @return void
321
     */
322
    public function csv()
323
    {
324
        $this->buildExcelFile()->download('csv');
325
    }
326
327
    /**
328
     * Export results to PDF file.
329
     *
330
     * @return mixed
331
     */
332
    public function pdf()
333
    {
334
        if ('snappy' == config('datatables-buttons.pdf_generator', 'excel')) {
335
            return $this->snappyPdf();
336
        } else {
337
            $this->buildExcelFile()->download('pdf');
338
        }
339
    }
340
341
    /**
342
     * PDF version of the table using print preview blade template.
343
     *
344
     * @return mixed
345
     */
346
    public function snappyPdf()
347
    {
348
        /** @var \Barryvdh\Snappy\PdfWrapper $snappy */
349
        $snappy = app('snappy.pdf.wrapper');
350
351
        $options     = config('datatables-buttons.snappy.options', [
352
            'no-outline'    => true,
353
            'margin-left'   => '0',
354
            'margin-right'  => '0',
355
            'margin-top'    => '10mm',
356
            'margin-bottom' => '10mm',
357
        ]);
358
        $orientation = config('datatables-buttons.snappy.orientation', 'landscape');
359
360
        $snappy->setOptions($options)
361
               ->setOrientation($orientation);
362
363
        return $snappy->loadHTML($this->printPreview())
364
                      ->download($this->getFilename() . ".pdf");
365
    }
366
367
    /**
368
     * Add basic array query scopes.
369
     *
370
     * @param \Yajra\Datatables\Contracts\DataTableScopeContract $scope
371
     * @return $this
372
     */
373
    public function addScope(DataTableScopeContract $scope)
374
    {
375
        $this->scopes[] = $scope;
376
377
        return $this;
378
    }
379
380
    /**
381
     * Set a custom class attribute.
382
     *
383
     * @param mixed $key
384
     * @param mixed|null $value
385
     * @return $this
386
     */
387
    public function with($key, $value = null)
388
    {
389
        if (is_array($key)) {
390
            $this->attributes = array_merge($this->attributes, $key);
391
        } else {
392
            $this->attributes[$key] = $value;
393
        }
394
395
        return $this;
396
    }
397
398
    /**
399
     * Dynamically retrieve the value of an attribute.
400
     *
401
     * @param string $key
402
     * @return mixed|null
403
     */
404
    public function __get($key)
405
    {
406
        if (array_key_exists($key, $this->attributes)) {
407
            return $this->attributes[$key];
408
        }
409
410
        return null;
411
    }
412
413
    /**
414
     * Apply query scopes.
415
     *
416
     * @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
417
     * @return mixed
418
     */
419
    protected function applyScopes($query)
420
    {
421
        foreach ($this->scopes as $scope) {
422
            $scope->apply($query);
423
        }
424
425
        return $query;
426
    }
427
428
    /**
429
     * Get default builder parameters.
430
     *
431
     * @return array
432
     */
433
    protected function getBuilderParameters()
434
    {
435
        return [
436
            'order'   => [[0, 'desc']],
437
            'buttons' => [
438
                'create',
439
                'export',
440
                'print',
441
                'reset',
442
                'reload',
443
            ],
444
        ];
445
    }
446
}
447