Completed
Push — master ( 96cfd6...c1bbfc )
by Arjay
03:46
created

DataTable::builder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Yajra\Datatables\Services;
4
5
use Illuminate\Contracts\View\Factory;
6
use Illuminate\Support\Facades\Config;
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
use Yajra\Datatables\Transformers\DataTransformer;
14
15
/**
16
 * Class DataTable.
17
 *
18
 * @package Yajra\Datatables\Services
19
 * @author  Arjay Angeles <[email protected]>
20
 */
21
abstract class DataTable implements DataTableContract, DataTableButtonsContract
22
{
23
    /**
24
     * @var \Yajra\Datatables\Datatables
25
     */
26
    protected $datatables;
27
28
    /**
29
     * @var \Illuminate\Contracts\View\Factory
30
     */
31
    protected $viewFactory;
32
33
    /**
34
     * Datatables print preview view.
35
     *
36
     * @var string
37
     */
38
    protected $printPreview = 'datatables::print';
39
40
    /**
41
     * List of columns to be exported.
42
     *
43
     * @var string|array
44
     */
45
    protected $exportColumns = '*';
46
47
    /**
48
     * List of columns to be printed.
49
     *
50
     * @var string|array
51
     */
52
    protected $printColumns = '*';
53
54
    /**
55
     * Query scopes.
56
     *
57
     * @var \Yajra\Datatables\Contracts\DataTableScopeContract[]
58
     */
59
    protected $scopes = [];
60
61
    /**
62
     * Export filename.
63
     *
64
     * @var string
65
     */
66
    protected $filename = '';
67
68
    /**
69
     * DataTable constructor.
70
     *
71
     * @param \Yajra\Datatables\Datatables $datatables
72
     * @param \Illuminate\Contracts\View\Factory $viewFactory
73
     */
74
    public function __construct(Datatables $datatables, Factory $viewFactory)
75
    {
76
        $this->datatables  = $datatables;
77
        $this->viewFactory = $viewFactory;
78
    }
79
80
    /**
81
     * Process dataTables needed render output.
82
     *
83
     * @param string $view
84
     * @param array $data
85
     * @param array $mergeData
86
     * @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
87
     */
88
    public function render($view, $data = [], $mergeData = [])
89
    {
90
        if ($this->request()->ajax() && $this->request()->wantsJson()) {
91
            return $this->ajax();
92
        }
93
94
        if ($action = $this->request()->get('action') AND in_array($action, ['print', 'csv', 'excel', 'pdf'])) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as and instead of && is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
95
            if ($action == 'print') {
96
                return $this->printPreview();
97
            }
98
99
            return call_user_func_array([$this, $action], []);
100
        }
101
102
        return $this->viewFactory->make($view, $data, $mergeData)->with('dataTable', $this->html());
103
    }
104
105
    /**
106
     * Get Datatables Request instance.
107
     *
108
     * @return \Yajra\Datatables\Request
109
     */
110
    public function request()
111
    {
112
        return $this->datatables->getRequest();
113
    }
114
115
    /**
116
     * Display printable view of datatables.
117
     *
118
     * @return \Illuminate\Contracts\View\View
119
     */
120
    public function printPreview()
121
    {
122
        $data = $this->getDataForPrint();
123
124
        return $this->viewFactory->make($this->printPreview, compact('data'));
125
    }
126
127
    /**
128
     * Get mapped columns versus final decorated output.
129
     *
130
     * @return array
131
     */
132
    protected function getDataForPrint()
133
    {
134
        $columns = $this->printColumns();
135
136
        return $this->mapResponseToColumns($columns, 'printable');
137
    }
138
139
    /**
140
     * Get printable columns.
141
     *
142
     * @return array|string
143
     */
144
    protected function printColumns()
145
    {
146
        return is_array($this->printColumns) ? $this->printColumns : $this->getColumnsFromBuilder();
147
    }
148
149
    /**
150
     * Get columns definition from html builder.
151
     *
152
     * @return array
153
     */
154
    protected function getColumnsFromBuilder()
155
    {
156
        return $this->html()->getColumns();
157
    }
158
159
    /**
160
     * Optional method if you want to use html builder.
161
     *
162
     * @return \Yajra\Datatables\Html\Builder
163
     */
164
    public function html()
165
    {
166
        return $this->builder();
167
    }
168
169
    /**
170
     * Get Datatables Html Builder instance.
171
     *
172
     * @return \Yajra\Datatables\Html\Builder
173
     */
174
    public function builder()
175
    {
176
        return $this->datatables->getHtmlBuilder();
177
    }
178
179
    /**
180
     * Map ajax response to columns definition.
181
     *
182
     * @param mixed $columns
183
     * @param string $type
184
     * @return array
185
     */
186
    protected function mapResponseToColumns($columns, $type)
187
    {
188
        return array_map(function ($row) use ($columns, $type) {
189
            if ($columns) {
190
                return (new DataTransformer())->transform($row, $columns, $type);
191
            }
192
193
            return $row;
194
        }, $this->getAjaxResponseData());
195
    }
196
197
    /**
198
     * Get decorated data as defined in datatables ajax response.
199
     *
200
     * @return array
201
     */
202
    protected function getAjaxResponseData()
203
    {
204
        $this->datatables->getRequest()->merge(['length' => -1]);
205
206
        $response = $this->ajax();
207
        $data     = $response->getData(true);
208
209
        return $data['data'];
210
    }
211
212
    /**
213
     * Export results to Excel file.
214
     *
215
     * @return void
216
     */
217
    public function excel()
218
    {
219
        $this->buildExcelFile()->download('xls');
220
    }
221
222
    /**
223
     * Build excel file and prepare for export.
224
     *
225
     * @return \Maatwebsite\Excel\Writers\LaravelExcelWriter
226
     */
227
    protected function buildExcelFile()
228
    {
229
        /** @var \Maatwebsite\Excel\Excel $excel */
230
        $excel = app('excel');
231
232
        return $excel->create($this->getFilename(), function (LaravelExcelWriter $excel) {
233
            $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) {
234
                $sheet->fromArray($this->getDataForExport());
235
            });
236
        });
237
    }
238
239
    /**
240
     * Get export filename.
241
     *
242
     * @return string
243
     */
244
    public function getFilename()
245
    {
246
        return $this->filename ?: $this->filename();
247
    }
248
249
    /**
250
     * Set export filename.
251
     *
252
     * @param string $filename
253
     * @return DataTable
254
     */
255
    public function setFilename($filename)
256
    {
257
        $this->filename = $filename;
258
259
        return $this;
260
    }
261
262
    /**
263
     * Get filename for export.
264
     *
265
     * @return string
266
     */
267
    protected function filename()
268
    {
269
        return 'export_' . time();
270
    }
271
272
    /**
273
     * Get mapped columns versus final decorated output.
274
     *
275
     * @return array
276
     */
277
    protected function getDataForExport()
278
    {
279
        $columns = $this->exportColumns();
280
281
        return $this->mapResponseToColumns($columns, 'exportable');
282
    }
283
284
    /**
285
     * Get export columns definition.
286
     *
287
     * @return array|string
288
     */
289
    private function exportColumns()
290
    {
291
        return is_array($this->exportColumns) ? $this->exportColumns : $this->getColumnsFromBuilder();
292
    }
293
294
    /**
295
     * Export results to CSV file.
296
     *
297
     * @return void
298
     */
299
    public function csv()
300
    {
301
        $this->buildExcelFile()->download('csv');
302
    }
303
304
    /**
305
     * Export results to PDF file.
306
     *
307
     * @return mixed
308
     */
309
    public function pdf()
310
    {
311
        if ('snappy' == Config::get('datatables.pdf_generator', 'excel')) {
312
            return $this->snappyPdf();
313
        } else {
314
            $this->buildExcelFile()->download('pdf');
315
        }
316
    }
317
318
    /**
319
     * PDF version of the table using print preview blade template.
320
     *
321
     * @return mixed
322
     */
323
    public function snappyPdf()
324
    {
325
        $data   = $this->getDataForPrint();
326
        $snappy = app('snappy.pdf.wrapper');
327
        $snappy->setOptions([
328
            'no-outline'    => true,
329
            'margin-left'   => '0',
330
            'margin-right'  => '0',
331
            'margin-top'    => '10mm',
332
            'margin-bottom' => '10mm',
333
        ])->setOrientation('landscape');
334
335
        return $snappy->loadView($this->printPreview, compact('data'))
336
                      ->download($this->getFilename() . ".pdf");
337
    }
338
339
    /**
340
     * Add basic array query scopes.
341
     *
342
     * @param \Yajra\Datatables\Contracts\DataTableScopeContract $scope
343
     * @return $this
344
     */
345
    public function addScope(DataTableScopeContract $scope)
346
    {
347
        $this->scopes[] = $scope;
348
349
        return $this;
350
    }
351
352
    /**
353
     * Apply query scopes.
354
     *
355
     * @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
356
     * @return mixed
357
     */
358
    protected function applyScopes($query)
359
    {
360
        foreach ($this->scopes as $scope) {
361
            $scope->apply($query);
362
        }
363
364
        return $query;
365
    }
366
367
    /**
368
     * Get default builder parameters.
369
     *
370
     * @return array
371
     */
372
    protected function getBuilderParameters()
373
    {
374
        return [
375
            'order'   => [[0, 'desc']],
376
            'buttons' => [
377
                'create',
378
                'export',
379
                'print',
380
                'reset',
381
                'reload',
382
            ],
383
        ];
384
    }
385
}
386