Completed
Push — master ( ebf51c...4d883b )
by Arjay
03:50
created

BaseEngine::skipPaging()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 9.4285
c 2
b 1
f 0
1
<?php
2
3
namespace Yajra\Datatables\Engines;
4
5
use Illuminate\Http\JsonResponse;
6
use Illuminate\Support\Facades\Config;
7
use Illuminate\Support\Str;
8
use League\Fractal\Resource\Collection;
9
use Yajra\Datatables\Contracts\DataTableEngineContract;
10
use Yajra\Datatables\Helper;
11
use Yajra\Datatables\Processors\DataProcessor;
12
13
/**
14
 * Class BaseEngine.
15
 *
16
 * @package Yajra\Datatables\Engines
17
 * @author  Arjay Angeles <[email protected]>
18
 */
19
abstract class BaseEngine implements DataTableEngineContract
20
{
21
    /**
22
     * Datatables Request object.
23
     *
24
     * @var \Yajra\Datatables\Request
25
     */
26
    public $request;
27
28
    /**
29
     * Database connection used.
30
     *
31
     * @var \Illuminate\Database\Connection
32
     */
33
    protected $connection;
34
35
    /**
36
     * Builder object.
37
     *
38
     * @var \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder
39
     */
40
    protected $query;
41
42
    /**
43
     * Query builder object.
44
     *
45
     * @var \Illuminate\Database\Query\Builder
46
     */
47
    protected $builder;
48
49
    /**
50
     * Array of result columns/fields.
51
     *
52
     * @var array
53
     */
54
    protected $columns = [];
55
56
    /**
57
     * DT columns definitions container (add/edit/remove/filter/order/escape).
58
     *
59
     * @var array
60
     */
61
    protected $columnDef = [
62
        'index'     => false,
63
        'append'    => [],
64
        'edit'      => [],
65
        'excess'    => ['rn', 'row_num'],
66
        'filter'    => [],
67
        'order'     => [],
68
        'escape'    => [],
69
        'blacklist' => ['password', 'remember_token'],
70
        'whitelist' => '*',
71
    ];
72
73
    /**
74
     * Query type.
75
     *
76
     * @var string
77
     */
78
    protected $query_type;
79
80
    /**
81
     * Extra/Added columns.
82
     *
83
     * @var array
84
     */
85
    protected $extraColumns = [];
86
87
    /**
88
     * Total records.
89
     *
90
     * @var int
91
     */
92
    protected $totalRecords = 0;
93
94
    /**
95
     * Total filtered records.
96
     *
97
     * @var int
98
     */
99
    protected $filteredRecords = 0;
100
101
    /**
102
     * Auto-filter flag.
103
     *
104
     * @var bool
105
     */
106
    protected $autoFilter = true;
107
108
    /**
109
     * Callback to override global search.
110
     *
111
     * @var \Closure
112
     */
113
    protected $filterCallback;
114
115
    /**
116
     * Parameters to passed on filterCallback.
117
     *
118
     * @var mixed
119
     */
120
    protected $filterCallbackParameters;
121
122
    /**
123
     * DT row templates container.
124
     *
125
     * @var array
126
     */
127
    protected $templates = [
128
        'DT_RowId'    => '',
129
        'DT_RowClass' => '',
130
        'DT_RowData'  => [],
131
        'DT_RowAttr'  => [],
132
    ];
133
134
    /**
135
     * Output transformer.
136
     *
137
     * @var \League\Fractal\TransformerAbstract
138
     */
139
    protected $transformer = null;
140
141
    /**
142
     * Database prefix
143
     *
144
     * @var string
145
     */
146
    protected $prefix;
147
148
    /**
149
     * Database driver used.
150
     *
151
     * @var string
152
     */
153
    protected $database;
154
155
    /**
156
     * [internal] Track if any filter was applied for at least one column
157
     *
158
     * @var boolean
159
     */
160
    protected $isFilterApplied = false;
161
162
    /**
163
     * Fractal serializer class.
164
     *
165
     * @var string|null
166
     */
167
    protected $serializer = null;
168
169
    /**
170
     * Custom ordering callback.
171
     *
172
     * @var \Closure
173
     */
174
    protected $orderCallback;
175
176
    /**
177
     * Skip paginate as needed.
178
     *
179
     * @var bool
180
     */
181
    protected $skipPaging = false;
182
183
    /**
184
     * Array of data to append on json response.
185
     *
186
     * @var array
187
     */
188
    private $appends = [];
189
190
    /**
191
     * Setup search keyword.
192
     *
193
     * @param  string $value
194
     * @return string
195
     */
196
    public function setupKeyword($value)
197
    {
198
        if ($this->isSmartSearch()) {
199
            $keyword = '%' . $value . '%';
200
            if ($this->isWildcard()) {
201
                $keyword = $this->wildcardLikeString($value);
202
            }
203
            // remove escaping slash added on js script request
204
            $keyword = str_replace('\\', '%', $keyword);
205
206
            return $keyword;
207
        }
208
209
        return $value;
210
    }
211
212
    /**
213
     * Check if DataTables uses smart search.
214
     *
215
     * @return bool
216
     */
217
    protected function isSmartSearch()
218
    {
219
        return Config::get('datatables.search.smart', true);
220
    }
221
222
    /**
223
     * Get config use wild card status.
224
     *
225
     * @return bool
226
     */
227
    public function isWildcard()
228
    {
229
        return Config::get('datatables.search.use_wildcards', false);
230
    }
231
232
    /**
233
     * Adds % wildcards to the given string.
234
     *
235
     * @param string $str
236
     * @param bool $lowercase
237
     * @return string
238
     */
239
    public function wildcardLikeString($str, $lowercase = true)
240
    {
241
        $wild   = '%';
242
        $length = Str::length($str);
243
        if ($length) {
244
            for ($i = 0; $i < $length; $i++) {
245
                $wild .= $str[$i] . '%';
246
            }
247
        }
248
        if ($lowercase) {
249
            $wild = Str::lower($wild);
250
        }
251
252
        return $wild;
253
    }
254
255
    /**
256
     * Will prefix column if needed.
257
     *
258
     * @param string $column
259
     * @return string
260
     */
261
    public function prefixColumn($column)
262
    {
263
        $table_names = $this->tableNames();
264
        if (count(
265
            array_filter($table_names, function ($value) use (&$column) {
266
                return strpos($column, $value . '.') === 0;
267
            })
268
        )) {
269
            // the column starts with one of the table names
270
            $column = $this->prefix . $column;
271
        }
272
273
        return $column;
274
    }
275
276
    /**
277
     * Will look through the query and all it's joins to determine the table names.
278
     *
279
     * @return array
280
     */
281
    public function tableNames()
282
    {
283
        $names          = [];
284
        $query          = $this->getQueryBuilder();
285
        $names[]        = $query->from;
286
        $joins          = $query->joins ?: [];
287
        $databasePrefix = $this->prefix;
288
        foreach ($joins as $join) {
289
            $table   = preg_split('/ as /i', $join->table);
290
            $names[] = $table[0];
291
            if (isset($table[1]) && ! empty($databasePrefix) && strpos($table[1], $databasePrefix) == 0) {
292
                $names[] = preg_replace('/^' . $databasePrefix . '/', '', $table[1]);
293
            }
294
        }
295
296
        return $names;
297
    }
298
299
    /**
300
     * Get Query Builder object.
301
     *
302
     * @param mixed $instance
303
     * @return mixed
304
     */
305
    public function getQueryBuilder($instance = null)
306
    {
307
        if (! $instance) {
308
            $instance = $this->query;
309
        }
310
311
        if ($this->isQueryBuilder()) {
312
            return $instance;
313
        }
314
315
        return $instance->getQuery();
316
    }
317
318
    /**
319
     * Check query type is a builder.
320
     *
321
     * @return bool
322
     */
323
    public function isQueryBuilder()
324
    {
325
        return $this->query_type == 'builder';
326
    }
327
328
    /**
329
     * Add column in collection.
330
     *
331
     * @param string $name
332
     * @param string|callable $content
333
     * @param bool|int $order
334
     * @return $this
335
     */
336
    public function addColumn($name, $content, $order = false)
337
    {
338
        $this->extraColumns[] = $name;
339
340
        $this->columnDef['append'][] = ['name' => $name, 'content' => $content, 'order' => $order];
341
342
        return $this;
343
    }
344
345
    /**
346
     * Add DT row index column on response.
347
     *
348
     * @return $this
349
     */
350
    public function addIndexColumn()
351
    {
352
        $this->columnDef['index'] = true;
353
354
        return $this;
355
    }
356
357
    /**
358
     * Edit column's content.
359
     *
360
     * @param string $name
361
     * @param string|callable $content
362
     * @return $this
363
     */
364
    public function editColumn($name, $content)
365
    {
366
        $this->columnDef['edit'][] = ['name' => $name, 'content' => $content];
367
368
        return $this;
369
    }
370
371
    /**
372
     * Remove column from collection.
373
     *
374
     * @return $this
375
     */
376
    public function removeColumn()
377
    {
378
        $names                     = func_get_args();
379
        $this->columnDef['excess'] = array_merge($this->columnDef['excess'], $names);
380
381
        return $this;
382
    }
383
384
    /**
385
     * Declare columns to escape values.
386
     *
387
     * @param string|array $columns
388
     * @return $this
389
     */
390
    public function escapeColumns($columns = '*')
391
    {
392
        $this->columnDef['escape'] = $columns;
393
394
        return $this;
395
    }
396
397
    /**
398
     * Allows previous API calls where the methods were snake_case.
399
     * Will convert a camelCase API call to a snake_case call.
400
     * Allow query builder method to be used by the engine.
401
     *
402
     * @param  string $name
403
     * @param  array $arguments
404
     * @return mixed
405
     */
406
    public function __call($name, $arguments)
407
    {
408
        $name = Str::camel(Str::lower($name));
409
        if (method_exists($this, $name)) {
410
            return call_user_func_array([$this, $name], $arguments);
411
        } elseif (method_exists($this->getQueryBuilder(), $name)) {
412
            call_user_func_array([$this->getQueryBuilder(), $name], $arguments);
413
        } else {
414
            trigger_error('Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR);
415
        }
416
417
        return $this;
418
    }
419
420
    /**
421
     * Sets DT_RowClass template.
422
     * result: <tr class="output_from_your_template">.
423
     *
424
     * @param string|callable $content
425
     * @return $this
426
     */
427
    public function setRowClass($content)
428
    {
429
        $this->templates['DT_RowClass'] = $content;
430
431
        return $this;
432
    }
433
434
    /**
435
     * Sets DT_RowId template.
436
     * result: <tr id="output_from_your_template">.
437
     *
438
     * @param string|callable $content
439
     * @return $this
440
     */
441
    public function setRowId($content)
442
    {
443
        $this->templates['DT_RowId'] = $content;
444
445
        return $this;
446
    }
447
448
    /**
449
     * Set DT_RowData templates.
450
     *
451
     * @param array $data
452
     * @return $this
453
     */
454
    public function setRowData(array $data)
455
    {
456
        $this->templates['DT_RowData'] = $data;
457
458
        return $this;
459
    }
460
461
    /**
462
     * Add DT_RowData template.
463
     *
464
     * @param string $key
465
     * @param string|callable $value
466
     * @return $this
467
     */
468
    public function addRowData($key, $value)
469
    {
470
        $this->templates['DT_RowData'][$key] = $value;
471
472
        return $this;
473
    }
474
475
    /**
476
     * Set DT_RowAttr templates.
477
     * result: <tr attr1="attr1" attr2="attr2">.
478
     *
479
     * @param array $data
480
     * @return $this
481
     */
482
    public function setRowAttr(array $data)
483
    {
484
        $this->templates['DT_RowAttr'] = $data;
485
486
        return $this;
487
    }
488
489
    /**
490
     * Add DT_RowAttr template.
491
     *
492
     * @param string $key
493
     * @param string|callable $value
494
     * @return $this
495
     */
496
    public function addRowAttr($key, $value)
497
    {
498
        $this->templates['DT_RowAttr'][$key] = $value;
499
500
        return $this;
501
    }
502
503
    /**
504
     * Override default column filter search.
505
     *
506
     * @param string $column
507
     * @param string|Closure $method
508
     * @return $this
509
     * @internal param $mixed ...,... All the individual parameters required for specified $method
510
     * @internal string $1 Special variable that returns the requested search keyword.
511
     */
512
    public function filterColumn($column, $method)
513
    {
514
        $params                             = func_get_args();
515
        $this->columnDef['filter'][$column] = ['method' => $method, 'parameters' => array_splice($params, 2)];
516
517
        return $this;
518
    }
519
520
    /**
521
     * Order each given columns versus the given custom sql.
522
     *
523
     * @param array $columns
524
     * @param string $sql
525
     * @param array $bindings
526
     * @return $this
527
     */
528
    public function orderColumns(array $columns, $sql, $bindings = [])
529
    {
530
        foreach ($columns as $column) {
531
            $this->orderColumn($column, str_replace(':column', $column, $sql), $bindings);
532
        }
533
534
        return $this;
535
    }
536
537
    /**
538
     * Override default column ordering.
539
     *
540
     * @param string $column
541
     * @param string $sql
542
     * @param array $bindings
543
     * @return $this
544
     * @internal string $1 Special variable that returns the requested order direction of the column.
545
     */
546
    public function orderColumn($column, $sql, $bindings = [])
547
    {
548
        $this->columnDef['order'][$column] = ['method' => 'orderByRaw', 'parameters' => [$sql, $bindings]];
549
550
        return $this;
551
    }
552
553
    /**
554
     * Set data output transformer.
555
     *
556
     * @param \League\Fractal\TransformerAbstract $transformer
557
     * @return $this
558
     */
559
    public function setTransformer($transformer)
560
    {
561
        $this->transformer = $transformer;
562
563
        return $this;
564
    }
565
566
    /**
567
     * Set fractal serializer class.
568
     *
569
     * @param string $serializer
570
     * @return $this
571
     */
572
    public function setSerializer($serializer)
573
    {
574
        $this->serializer = $serializer;
575
576
        return $this;
577
    }
578
579
    /**
580
     * Organizes works.
581
     *
582
     * @param bool $mDataSupport
583
     * @param bool $orderFirst
584
     * @return \Illuminate\Http\JsonResponse
585
     */
586
    public function make($mDataSupport = false, $orderFirst = false)
587
    {
588
        $this->totalRecords = $this->totalCount();
589
590
        if ($this->totalRecords) {
591
            $this->orderRecords(! $orderFirst);
592
            $this->filterRecords();
593
            $this->orderRecords($orderFirst);
594
            $this->paginate();
595
        }
596
597
        return $this->render($mDataSupport);
598
    }
599
600
    /**
601
     * Sort records.
602
     *
603
     * @param  boolean $skip
604
     * @return void
605
     */
606
    public function orderRecords($skip)
607
    {
608
        if (! $skip) {
609
            $this->ordering();
610
        }
611
    }
612
613
    /**
614
     * Perform necessary filters.
615
     *
616
     * @return void
617
     */
618
    public function filterRecords()
619
    {
620
        if ($this->autoFilter && $this->request->isSearchable()) {
621
            $this->filtering();
622
        }
623
624
        if (is_callable($this->filterCallback)) {
625
            call_user_func($this->filterCallback, $this->filterCallbackParameters);
626
        }
627
628
        $this->columnSearch();
629
        $this->filteredRecords = $this->isFilterApplied ? $this->count() : $this->totalRecords;
630
    }
631
632
    /**
633
     * Apply pagination.
634
     *
635
     * @return void
636
     */
637
    public function paginate()
638
    {
639
        if ($this->request->isPaginationable() && ! $this->skipPaging) {
640
            $this->paging();
641
        }
642
    }
643
644
    /**
645
     * Render json response.
646
     *
647
     * @param bool $object
648
     * @return \Illuminate\Http\JsonResponse
649
     */
650
    public function render($object = false)
651
    {
652
        $output = array_merge([
653
            'draw'            => (int) $this->request['draw'],
654
            'recordsTotal'    => $this->totalRecords,
655
            'recordsFiltered' => $this->filteredRecords,
656
        ], $this->appends);
657
658
        if (isset($this->transformer)) {
659
            $fractal = app('datatables.fractal');
660
661
            if ($this->serializer) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->serializer of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
662
                $fractal->setSerializer(new $this->serializer);
663
            }
664
665
            //Get transformer reflection
666
            //Firs method parameter should be data/object to transform
667
            $reflection = new \ReflectionMethod($this->transformer, 'transform');
668
            $parameter  = $reflection->getParameters()[0];
669
670
            //If parameter is class assuming it requires object
671
            //Else just pass array by default
672
            if ($parameter->getClass()) {
673
                $resource = new Collection($this->results(), $this->createTransformer());
674
            } else {
675
                $resource = new Collection(
676
                    $this->getProcessedData($object),
677
                    $this->createTransformer()
678
                );
679
            }
680
681
            $collection     = $fractal->createData($resource)->toArray();
682
            $output['data'] = $collection['data'];
683
        } else {
684
            $output['data'] = Helper::transform($this->getProcessedData($object));
685
        }
686
687
        if ($this->isDebugging()) {
688
            $output = $this->showDebugger($output);
689
        }
690
691
        return new JsonResponse($output);
692
    }
693
694
    /**
695
     * Get or create transformer instance.
696
     *
697
     * @return \League\Fractal\TransformerAbstract
698
     */
699
    protected function createTransformer()
700
    {
701
        if ($this->transformer instanceof \League\Fractal\TransformerAbstract) {
702
            return $this->transformer;
703
        }
704
705
        return new $this->transformer();
706
    }
707
708
    /**
709
     * Get processed data
710
     *
711
     * @param bool|false $object
712
     * @return array
713
     */
714
    private function getProcessedData($object = false)
715
    {
716
        $processor = new DataProcessor(
717
            $this->results(),
718
            $this->columnDef,
719
            $this->templates,
720
            $this->request['start']
721
        );
722
723
        return $processor->process($object);
724
    }
725
726
    /**
727
     * Check if app is in debug mode.
728
     *
729
     * @return bool
730
     */
731
    public function isDebugging()
732
    {
733
        return Config::get('app.debug', false);
734
    }
735
736
    /**
737
     * Append debug parameters on output.
738
     *
739
     * @param  array $output
740
     * @return array
741
     */
742
    public function showDebugger(array $output)
743
    {
744
        $output['queries'] = $this->connection->getQueryLog();
745
        $output['input']   = $this->request->all();
746
747
        return $output;
748
    }
749
750
    /**
751
     * Update flags to disable global search
752
     *
753
     * @param  \Closure $callback
754
     * @param  mixed $parameters
755
     * @param  bool $autoFilter
756
     */
757
    public function overrideGlobalSearch(\Closure $callback, $parameters, $autoFilter = false)
758
    {
759
        $this->autoFilter               = $autoFilter;
760
        $this->isFilterApplied          = true;
761
        $this->filterCallback           = $callback;
762
        $this->filterCallbackParameters = $parameters;
763
    }
764
765
    /**
766
     * Get config is case insensitive status.
767
     *
768
     * @return bool
769
     */
770
    public function isCaseInsensitive()
771
    {
772
        return Config::get('datatables.search.case_insensitive', false);
773
    }
774
775
    /**
776
     * Append data on json response.
777
     *
778
     * @param mixed $key
779
     * @param mixed $value
780
     * @return $this
781
     */
782
    public function with($key, $value = '')
783
    {
784
        if (is_array($key)) {
785
            $this->appends = $key;
786
        } elseif (is_callable($value)) {
787
            $this->appends[$key] = value($value);
788
        } else {
789
            $this->appends[$key] = value($value);
790
        }
791
792
        return $this;
793
    }
794
795
    /**
796
     * Override default ordering method with a closure callback.
797
     *
798
     * @param \Closure $closure
799
     * @return $this
800
     */
801
    public function order(\Closure $closure)
802
    {
803
        $this->orderCallback = $closure;
804
805
        return $this;
806
    }
807
808
    /**
809
     * Update list of columns that is not allowed for search/sort.
810
     *
811
     * @param  array $blacklist
812
     * @return $this
813
     */
814
    public function blacklist(array $blacklist)
815
    {
816
        $this->columnDef['blacklist'] = $blacklist;
817
818
        return $this;
819
    }
820
821
    /**
822
     * Update list of columns that is not allowed for search/sort.
823
     *
824
     * @param  string|array $whitelist
825
     * @return $this
826
     */
827
    public function whitelist($whitelist = '*')
828
    {
829
        $this->columnDef['whitelist'] = $whitelist;
830
831
        return $this;
832
    }
833
834
    /**
835
     * Set smart search config at runtime.
836
     *
837
     * @param bool $bool
838
     * @return $this
839
     */
840
    public function smart($bool = true)
841
    {
842
        Config::set('datatables.search.smart', $bool);
843
844
        return $this;
845
    }
846
847
    /**
848
     * Set total records manually.
849
     *
850
     * @param int $total
851
     * @return $this
852
     */
853
    public function setTotalRecords($total)
854
    {
855
        $this->totalRecords = $total;
856
857
        return $this;
858
    }
859
860
    /**
861
     * Skip pagination as needed.
862
     */
863
    public function skipPaging()
864
    {
865
        $this->skipPaging = true;
866
867
        return $this;
868
    }
869
870
    /**
871
     * Check if column is blacklisted.
872
     *
873
     * @param string $column
874
     * @return bool
875
     */
876
    protected function isBlacklisted($column)
877
    {
878
        if (in_array($column, $this->columnDef['blacklist'])) {
879
            return true;
880
        }
881
882
        if ($this->columnDef['whitelist'] === '*' || in_array($column, $this->columnDef['whitelist'])) {
883
            return false;
884
        }
885
886
        return true;
887
    }
888
889
    /**
890
     * Get column name to be use for filtering and sorting.
891
     *
892
     * @param integer $index
893
     * @param bool $wantsAlias
894
     * @return string
895
     */
896
    protected function getColumnName($index, $wantsAlias = false)
897
    {
898
        $column = $this->request->columnName($index);
899
900
        // DataTables is using make(false)
901
        if (is_numeric($column)) {
902
            $column = $this->getColumnNameByIndex($index);
903
        }
904
905
        if (Str::contains(Str::upper($column), ' AS ')) {
906
            $column = $this->extractColumnName($column, $wantsAlias);
907
        }
908
909
        return $column;
910
    }
911
912
    /**
913
     * Get column name by order column index.
914
     *
915
     * @param int $index
916
     * @return mixed
917
     */
918
    protected function getColumnNameByIndex($index)
919
    {
920
        $name = isset($this->columns[$index]) && $this->columns[$index] <> '*' ? $this->columns[$index] : $this->getPrimaryKeyName();
921
922
        return in_array($name, $this->extraColumns, true) ? $this->getPrimaryKeyName() : $name;
923
    }
924
925
    /**
926
     * If column name could not be resolved then use primary key.
927
     *
928
     * @return string
929
     */
930
    protected function getPrimaryKeyName()
931
    {
932
        if ($this->isEloquent()) {
933
            return $this->query->getModel()->getKeyName();
0 ignored issues
show
Bug introduced by
The method getModel does only exist in Illuminate\Database\Eloquent\Builder, but not in Illuminate\Database\Query\Builder.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
934
        }
935
936
        return 'id';
937
    }
938
939
    /**
940
     * Check if the engine used was eloquent.
941
     *
942
     * @return bool
943
     */
944
    protected function isEloquent()
945
    {
946
        return $this->query_type === 'eloquent';
947
    }
948
949
    /**
950
     * Get column name from string.
951
     *
952
     * @param string $str
953
     * @param bool $wantsAlias
954
     * @return string
955
     */
956
    protected function extractColumnName($str, $wantsAlias)
957
    {
958
        $matches = explode(' as ', Str::lower($str));
959
960
        if (! empty($matches)) {
961
            if ($wantsAlias) {
962
                return array_pop($matches);
963
            } else {
964
                return array_shift($matches);
965
            }
966
        } elseif (strpos($str, '.')) {
967
            $array = explode('.', $str);
968
969
            return array_pop($array);
970
        }
971
972
        return $str;
973
    }
974
975
    /**
976
     * Check if the current sql language is based on oracle syntax.
977
     *
978
     * @return bool
979
     */
980
    protected function isOracleSql()
981
    {
982
        return in_array($this->database, ['oracle', 'oci8']);
983
    }
984
}
985