Overview

Namespaces

  • None
  • Yajra
    • Datatables
      • Contracts
      • Engines
      • Facades
      • Generators
      • Html
      • Processors
      • Services
      • Transformers

Classes

  • Yajra\Datatables\Datatables
  • Yajra\Datatables\DatatablesServiceProvider
  • Yajra\Datatables\Engines\BaseEngine
  • Yajra\Datatables\Engines\CollectionEngine
  • Yajra\Datatables\Engines\EloquentEngine
  • Yajra\Datatables\Engines\QueryBuilderEngine
  • Yajra\Datatables\Facades\Datatables
  • Yajra\Datatables\Generators\DataTablesMakeCommand
  • Yajra\Datatables\Generators\DataTablesScopeCommand
  • Yajra\Datatables\Helper
  • Yajra\Datatables\Html\Builder
  • Yajra\Datatables\Html\Column
  • Yajra\Datatables\Html\Parameters
  • Yajra\Datatables\Processors\DataProcessor
  • Yajra\Datatables\Processors\RowProcessor
  • Yajra\Datatables\Request
  • Yajra\Datatables\Services\DataTable
  • Yajra\Datatables\Transformers\DataTransformer

Interfaces

  • Yajra\Datatables\Contracts\DataTableButtonsContract
  • Yajra\Datatables\Contracts\DataTableContract
  • Yajra\Datatables\Contracts\DataTableEngineContract
  • Yajra\Datatables\Contracts\DataTableScopeContract

Functions

  • config_path
  • public_path
  • Overview
  • Namespace
  • Class
   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 <aqangeles@gmail.com>
  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:      * Select trashed records in count function for models with soft deletes trait.
 110:      * By default we do not select soft deleted records
 111:      *
 112:      * @var bool
 113:      */
 114:     protected $withTrashed = false;
 115: 
 116:     /**
 117:      * Callback to override global search.
 118:      *
 119:      * @var \Closure
 120:      */
 121:     protected $filterCallback;
 122: 
 123:     /**
 124:      * Parameters to passed on filterCallback.
 125:      *
 126:      * @var mixed
 127:      */
 128:     protected $filterCallbackParameters;
 129: 
 130:     /**
 131:      * DT row templates container.
 132:      *
 133:      * @var array
 134:      */
 135:     protected $templates = [
 136:         'DT_RowId'    => '',
 137:         'DT_RowClass' => '',
 138:         'DT_RowData'  => [],
 139:         'DT_RowAttr'  => [],
 140:     ];
 141: 
 142:     /**
 143:      * Output transformer.
 144:      *
 145:      * @var \League\Fractal\TransformerAbstract
 146:      */
 147:     protected $transformer = null;
 148: 
 149:     /**
 150:      * Database prefix
 151:      *
 152:      * @var string
 153:      */
 154:     protected $prefix;
 155: 
 156:     /**
 157:      * Database driver used.
 158:      *
 159:      * @var string
 160:      */
 161:     protected $database;
 162: 
 163:     /**
 164:      * [internal] Track if any filter was applied for at least one column
 165:      *
 166:      * @var boolean
 167:      */
 168:     protected $isFilterApplied = false;
 169: 
 170:     /**
 171:      * Fractal serializer class.
 172:      *
 173:      * @var string|null
 174:      */
 175:     protected $serializer = null;
 176: 
 177:     /**
 178:      * Custom ordering callback.
 179:      *
 180:      * @var \Closure
 181:      */
 182:     protected $orderCallback;
 183: 
 184:     /**
 185:      * Skip paginate as needed.
 186:      *
 187:      * @var bool
 188:      */
 189:     protected $skipPaging = false;
 190: 
 191:     /**
 192:      * Array of data to append on json response.
 193:      *
 194:      * @var array
 195:      */
 196:     private $appends = [];
 197: 
 198:     /**
 199:      * Setup search keyword.
 200:      *
 201:      * @param  string $value
 202:      * @return string
 203:      */
 204:     public function setupKeyword($value)
 205:     {
 206:         if ($this->isSmartSearch()) {
 207:             $keyword = '%' . $value . '%';
 208:             if ($this->isWildcard()) {
 209:                 $keyword = $this->wildcardLikeString($value);
 210:             }
 211:             // remove escaping slash added on js script request
 212:             $keyword = str_replace('\\', '%', $keyword);
 213: 
 214:             return $keyword;
 215:         }
 216: 
 217:         return $value;
 218:     }
 219: 
 220:     /**
 221:      * Check if DataTables uses smart search.
 222:      *
 223:      * @return bool
 224:      */
 225:     protected function isSmartSearch()
 226:     {
 227:         return Config::get('datatables.search.smart', true);
 228:     }
 229: 
 230:     /**
 231:      * Get config use wild card status.
 232:      *
 233:      * @return bool
 234:      */
 235:     public function isWildcard()
 236:     {
 237:         return Config::get('datatables.search.use_wildcards', false);
 238:     }
 239: 
 240:     /**
 241:      * Adds % wildcards to the given string.
 242:      *
 243:      * @param string $str
 244:      * @param bool $lowercase
 245:      * @return string
 246:      */
 247:     public function wildcardLikeString($str, $lowercase = true)
 248:     {
 249:         $wild   = '%';
 250:         $length = Str::length($str);
 251:         if ($length) {
 252:             for ($i = 0; $i < $length; $i++) {
 253:                 $wild .= $str[$i] . '%';
 254:             }
 255:         }
 256:         if ($lowercase) {
 257:             $wild = Str::lower($wild);
 258:         }
 259: 
 260:         return $wild;
 261:     }
 262: 
 263:     /**
 264:      * Will prefix column if needed.
 265:      *
 266:      * @param string $column
 267:      * @return string
 268:      */
 269:     public function prefixColumn($column)
 270:     {
 271:         $table_names = $this->tableNames();
 272:         if (count(
 273:             array_filter($table_names, function ($value) use (&$column) {
 274:                 return strpos($column, $value . '.') === 0;
 275:             })
 276:         )) {
 277:             // the column starts with one of the table names
 278:             $column = $this->prefix . $column;
 279:         }
 280: 
 281:         return $column;
 282:     }
 283: 
 284:     /**
 285:      * Will look through the query and all it's joins to determine the table names.
 286:      *
 287:      * @return array
 288:      */
 289:     public function tableNames()
 290:     {
 291:         $names          = [];
 292:         $query          = $this->getQueryBuilder();
 293:         $names[]        = $query->from;
 294:         $joins          = $query->joins ?: [];
 295:         $databasePrefix = $this->prefix;
 296:         foreach ($joins as $join) {
 297:             $table   = preg_split('/ as /i', $join->table);
 298:             $names[] = $table[0];
 299:             if (isset($table[1]) && ! empty($databasePrefix) && strpos($table[1], $databasePrefix) == 0) {
 300:                 $names[] = preg_replace('/^' . $databasePrefix . '/', '', $table[1]);
 301:             }
 302:         }
 303: 
 304:         return $names;
 305:     }
 306: 
 307:     /**
 308:      * Get Query Builder object.
 309:      *
 310:      * @param mixed $instance
 311:      * @return mixed
 312:      */
 313:     public function getQueryBuilder($instance = null)
 314:     {
 315:         if (! $instance) {
 316:             $instance = $this->query;
 317:         }
 318: 
 319:         if ($this->isQueryBuilder()) {
 320:             return $instance;
 321:         }
 322: 
 323:         return $instance->getQuery();
 324:     }
 325: 
 326:     /**
 327:      * Check query type is a builder.
 328:      *
 329:      * @return bool
 330:      */
 331:     public function isQueryBuilder()
 332:     {
 333:         return $this->query_type == 'builder';
 334:     }
 335: 
 336:     /**
 337:      * Add column in collection.
 338:      *
 339:      * @param string $name
 340:      * @param string|callable $content
 341:      * @param bool|int $order
 342:      * @return $this
 343:      */
 344:     public function addColumn($name, $content, $order = false)
 345:     {
 346:         $this->extraColumns[] = $name;
 347: 
 348:         $this->columnDef['append'][] = ['name' => $name, 'content' => $content, 'order' => $order];
 349: 
 350:         return $this;
 351:     }
 352: 
 353:     /**
 354:      * Add DT row index column on response.
 355:      *
 356:      * @return $this
 357:      */
 358:     public function addIndexColumn()
 359:     {
 360:         $this->columnDef['index'] = true;
 361: 
 362:         return $this;
 363:     }
 364: 
 365:     /**
 366:      * Edit column's content.
 367:      *
 368:      * @param string $name
 369:      * @param string|callable $content
 370:      * @return $this
 371:      */
 372:     public function editColumn($name, $content)
 373:     {
 374:         $this->columnDef['edit'][] = ['name' => $name, 'content' => $content];
 375: 
 376:         return $this;
 377:     }
 378: 
 379:     /**
 380:      * Remove column from collection.
 381:      *
 382:      * @return $this
 383:      */
 384:     public function removeColumn()
 385:     {
 386:         $names                     = func_get_args();
 387:         $this->columnDef['excess'] = array_merge($this->columnDef['excess'], $names);
 388: 
 389:         return $this;
 390:     }
 391: 
 392:     /**
 393:      * Declare columns to escape values.
 394:      *
 395:      * @param string|array $columns
 396:      * @return $this
 397:      */
 398:     public function escapeColumns($columns = '*')
 399:     {
 400:         $this->columnDef['escape'] = $columns;
 401: 
 402:         return $this;
 403:     }
 404:     
 405:     /**
 406:      * Change withTrashed flag value.
 407:      *
 408:      * @param bool $withTrashed
 409:      * @return $this
 410:      */
 411:     public function withTrashed($withTrashed = true)
 412:     {
 413:         $this->withTrashed = $withTrashed;
 414:         
 415:         return $this;
 416:     }
 417: 
 418:     /**
 419:      * Allows previous API calls where the methods were snake_case.
 420:      * Will convert a camelCase API call to a snake_case call.
 421:      * Allow query builder method to be used by the engine.
 422:      *
 423:      * @param  string $name
 424:      * @param  array $arguments
 425:      * @return mixed
 426:      */
 427:     public function __call($name, $arguments)
 428:     {
 429:         $name = Str::camel(Str::lower($name));
 430:         if (method_exists($this, $name)) {
 431:             return call_user_func_array([$this, $name], $arguments);
 432:         } elseif (method_exists($this->getQueryBuilder(), $name)) {
 433:             call_user_func_array([$this->getQueryBuilder(), $name], $arguments);
 434:         } else {
 435:             trigger_error('Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR);
 436:         }
 437: 
 438:         return $this;
 439:     }
 440: 
 441:     /**
 442:      * Sets DT_RowClass template.
 443:      * result: <tr class="output_from_your_template">.
 444:      *
 445:      * @param string|callable $content
 446:      * @return $this
 447:      */
 448:     public function setRowClass($content)
 449:     {
 450:         $this->templates['DT_RowClass'] = $content;
 451: 
 452:         return $this;
 453:     }
 454: 
 455:     /**
 456:      * Sets DT_RowId template.
 457:      * result: <tr id="output_from_your_template">.
 458:      *
 459:      * @param string|callable $content
 460:      * @return $this
 461:      */
 462:     public function setRowId($content)
 463:     {
 464:         $this->templates['DT_RowId'] = $content;
 465: 
 466:         return $this;
 467:     }
 468: 
 469:     /**
 470:      * Set DT_RowData templates.
 471:      *
 472:      * @param array $data
 473:      * @return $this
 474:      */
 475:     public function setRowData(array $data)
 476:     {
 477:         $this->templates['DT_RowData'] = $data;
 478: 
 479:         return $this;
 480:     }
 481: 
 482:     /**
 483:      * Add DT_RowData template.
 484:      *
 485:      * @param string $key
 486:      * @param string|callable $value
 487:      * @return $this
 488:      */
 489:     public function addRowData($key, $value)
 490:     {
 491:         $this->templates['DT_RowData'][$key] = $value;
 492: 
 493:         return $this;
 494:     }
 495: 
 496:     /**
 497:      * Set DT_RowAttr templates.
 498:      * result: <tr attr1="attr1" attr2="attr2">.
 499:      *
 500:      * @param array $data
 501:      * @return $this
 502:      */
 503:     public function setRowAttr(array $data)
 504:     {
 505:         $this->templates['DT_RowAttr'] = $data;
 506: 
 507:         return $this;
 508:     }
 509: 
 510:     /**
 511:      * Add DT_RowAttr template.
 512:      *
 513:      * @param string $key
 514:      * @param string|callable $value
 515:      * @return $this
 516:      */
 517:     public function addRowAttr($key, $value)
 518:     {
 519:         $this->templates['DT_RowAttr'][$key] = $value;
 520: 
 521:         return $this;
 522:     }
 523: 
 524:     /**
 525:      * Override default column filter search.
 526:      *
 527:      * @param string $column
 528:      * @param string|Closure $method
 529:      * @return $this
 530:      * @internal param $mixed ...,... All the individual parameters required for specified $method
 531:      * @internal string $1 Special variable that returns the requested search keyword.
 532:      */
 533:     public function filterColumn($column, $method)
 534:     {
 535:         $params                             = func_get_args();
 536:         $this->columnDef['filter'][$column] = ['method' => $method, 'parameters' => array_splice($params, 2)];
 537: 
 538:         return $this;
 539:     }
 540: 
 541:     /**
 542:      * Order each given columns versus the given custom sql.
 543:      *
 544:      * @param array $columns
 545:      * @param string $sql
 546:      * @param array $bindings
 547:      * @return $this
 548:      */
 549:     public function orderColumns(array $columns, $sql, $bindings = [])
 550:     {
 551:         foreach ($columns as $column) {
 552:             $this->orderColumn($column, str_replace(':column', $column, $sql), $bindings);
 553:         }
 554: 
 555:         return $this;
 556:     }
 557: 
 558:     /**
 559:      * Override default column ordering.
 560:      *
 561:      * @param string $column
 562:      * @param string $sql
 563:      * @param array $bindings
 564:      * @return $this
 565:      * @internal string $1 Special variable that returns the requested order direction of the column.
 566:      */
 567:     public function orderColumn($column, $sql, $bindings = [])
 568:     {
 569:         $this->columnDef['order'][$column] = ['method' => 'orderByRaw', 'parameters' => [$sql, $bindings]];
 570: 
 571:         return $this;
 572:     }
 573: 
 574:     /**
 575:      * Set data output transformer.
 576:      *
 577:      * @param \League\Fractal\TransformerAbstract $transformer
 578:      * @return $this
 579:      */
 580:     public function setTransformer($transformer)
 581:     {
 582:         $this->transformer = $transformer;
 583: 
 584:         return $this;
 585:     }
 586: 
 587:     /**
 588:      * Set fractal serializer class.
 589:      *
 590:      * @param string $serializer
 591:      * @return $this
 592:      */
 593:     public function setSerializer($serializer)
 594:     {
 595:         $this->serializer = $serializer;
 596: 
 597:         return $this;
 598:     }
 599: 
 600:     /**
 601:      * Organizes works.
 602:      *
 603:      * @param bool $mDataSupport
 604:      * @param bool $orderFirst
 605:      * @return \Illuminate\Http\JsonResponse
 606:      */
 607:     public function make($mDataSupport = false, $orderFirst = false)
 608:     {
 609:         $this->totalRecords = $this->totalCount();
 610: 
 611:         if ($this->totalRecords) {
 612:             $this->orderRecords(! $orderFirst);
 613:             $this->filterRecords();
 614:             $this->orderRecords($orderFirst);
 615:             $this->paginate();
 616:         }
 617: 
 618:         return $this->render($mDataSupport);
 619:     }
 620: 
 621:     /**
 622:      * Sort records.
 623:      *
 624:      * @param  boolean $skip
 625:      * @return void
 626:      */
 627:     public function orderRecords($skip)
 628:     {
 629:         if (! $skip) {
 630:             $this->ordering();
 631:         }
 632:     }
 633: 
 634:     /**
 635:      * Perform necessary filters.
 636:      *
 637:      * @return void
 638:      */
 639:     public function filterRecords()
 640:     {
 641:         if ($this->autoFilter && $this->request->isSearchable()) {
 642:             $this->filtering();
 643:         }
 644: 
 645:         if (is_callable($this->filterCallback)) {
 646:             call_user_func($this->filterCallback, $this->filterCallbackParameters);
 647:         }
 648: 
 649:         $this->columnSearch();
 650:         $this->filteredRecords = $this->isFilterApplied ? $this->count() : $this->totalRecords;
 651:     }
 652: 
 653:     /**
 654:      * Apply pagination.
 655:      *
 656:      * @return void
 657:      */
 658:     public function paginate()
 659:     {
 660:         if ($this->request->isPaginationable() && ! $this->skipPaging) {
 661:             $this->paging();
 662:         }
 663:     }
 664: 
 665:     /**
 666:      * Render json response.
 667:      *
 668:      * @param bool $object
 669:      * @return \Illuminate\Http\JsonResponse
 670:      */
 671:     public function render($object = false)
 672:     {
 673:         $output = array_merge([
 674:             'draw'            => (int) $this->request['draw'],
 675:             'recordsTotal'    => $this->totalRecords,
 676:             'recordsFiltered' => $this->filteredRecords,
 677:         ], $this->appends);
 678: 
 679:         if (isset($this->transformer)) {
 680:             $fractal = app('datatables.fractal');
 681: 
 682:             if ($this->serializer) {
 683:                 $fractal->setSerializer(new $this->serializer);
 684:             }
 685: 
 686:             //Get transformer reflection
 687:             //Firs method parameter should be data/object to transform
 688:             $reflection = new \ReflectionMethod($this->transformer, 'transform');
 689:             $parameter  = $reflection->getParameters()[0];
 690: 
 691:             //If parameter is class assuming it requires object
 692:             //Else just pass array by default
 693:             if ($parameter->getClass()) {
 694:                 $resource = new Collection($this->results(), $this->createTransformer());
 695:             } else {
 696:                 $resource = new Collection(
 697:                     $this->getProcessedData($object),
 698:                     $this->createTransformer()
 699:                 );
 700:             }
 701: 
 702:             $collection     = $fractal->createData($resource)->toArray();
 703:             $output['data'] = $collection['data'];
 704:         } else {
 705:             $output['data'] = Helper::transform($this->getProcessedData($object));
 706:         }
 707: 
 708:         if ($this->isDebugging()) {
 709:             $output = $this->showDebugger($output);
 710:         }
 711: 
 712:         return new JsonResponse($output);
 713:     }
 714: 
 715:     /**
 716:      * Get or create transformer instance.
 717:      *
 718:      * @return \League\Fractal\TransformerAbstract
 719:      */
 720:     protected function createTransformer()
 721:     {
 722:         if ($this->transformer instanceof \League\Fractal\TransformerAbstract) {
 723:             return $this->transformer;
 724:         }
 725: 
 726:         return new $this->transformer();
 727:     }
 728: 
 729:     /**
 730:      * Get processed data
 731:      *
 732:      * @param bool|false $object
 733:      * @return array
 734:      */
 735:     private function getProcessedData($object = false)
 736:     {
 737:         $processor = new DataProcessor(
 738:             $this->results(),
 739:             $this->columnDef,
 740:             $this->templates,
 741:             $this->request['start']
 742:         );
 743: 
 744:         return $processor->process($object);
 745:     }
 746: 
 747:     /**
 748:      * Check if app is in debug mode.
 749:      *
 750:      * @return bool
 751:      */
 752:     public function isDebugging()
 753:     {
 754:         return Config::get('app.debug', false);
 755:     }
 756: 
 757:     /**
 758:      * Append debug parameters on output.
 759:      *
 760:      * @param  array $output
 761:      * @return array
 762:      */
 763:     public function showDebugger(array $output)
 764:     {
 765:         $output['queries'] = $this->connection->getQueryLog();
 766:         $output['input']   = $this->request->all();
 767: 
 768:         return $output;
 769:     }
 770: 
 771:     /**
 772:      * Update flags to disable global search
 773:      *
 774:      * @param  \Closure $callback
 775:      * @param  mixed $parameters
 776:      * @param  bool $autoFilter
 777:      */
 778:     public function overrideGlobalSearch(\Closure $callback, $parameters, $autoFilter = false)
 779:     {
 780:         $this->autoFilter               = $autoFilter;
 781:         $this->isFilterApplied          = true;
 782:         $this->filterCallback           = $callback;
 783:         $this->filterCallbackParameters = $parameters;
 784:     }
 785: 
 786:     /**
 787:      * Get config is case insensitive status.
 788:      *
 789:      * @return bool
 790:      */
 791:     public function isCaseInsensitive()
 792:     {
 793:         return Config::get('datatables.search.case_insensitive', false);
 794:     }
 795: 
 796:     /**
 797:      * Append data on json response.
 798:      *
 799:      * @param mixed $key
 800:      * @param mixed $value
 801:      * @return $this
 802:      */
 803:     public function with($key, $value = '')
 804:     {
 805:         if (is_array($key)) {
 806:             $this->appends = $key;
 807:         } elseif (is_callable($value)) {
 808:             $this->appends[$key] = value($value);
 809:         } else {
 810:             $this->appends[$key] = value($value);
 811:         }
 812: 
 813:         return $this;
 814:     }
 815: 
 816:     /**
 817:      * Override default ordering method with a closure callback.
 818:      *
 819:      * @param \Closure $closure
 820:      * @return $this
 821:      */
 822:     public function order(\Closure $closure)
 823:     {
 824:         $this->orderCallback = $closure;
 825: 
 826:         return $this;
 827:     }
 828: 
 829:     /**
 830:      * Update list of columns that is not allowed for search/sort.
 831:      *
 832:      * @param  array $blacklist
 833:      * @return $this
 834:      */
 835:     public function blacklist(array $blacklist)
 836:     {
 837:         $this->columnDef['blacklist'] = $blacklist;
 838: 
 839:         return $this;
 840:     }
 841: 
 842:     /**
 843:      * Update list of columns that is not allowed for search/sort.
 844:      *
 845:      * @param  string|array $whitelist
 846:      * @return $this
 847:      */
 848:     public function whitelist($whitelist = '*')
 849:     {
 850:         $this->columnDef['whitelist'] = $whitelist;
 851: 
 852:         return $this;
 853:     }
 854: 
 855:     /**
 856:      * Set smart search config at runtime.
 857:      *
 858:      * @param bool $bool
 859:      * @return $this
 860:      */
 861:     public function smart($bool = true)
 862:     {
 863:         Config::set('datatables.search.smart', $bool);
 864: 
 865:         return $this;
 866:     }
 867: 
 868:     /**
 869:      * Set total records manually.
 870:      *
 871:      * @param int $total
 872:      * @return $this
 873:      */
 874:     public function setTotalRecords($total)
 875:     {
 876:         $this->totalRecords = $total;
 877: 
 878:         return $this;
 879:     }
 880: 
 881:     /**
 882:      * Skip pagination as needed.
 883:      */
 884:     public function skipPaging()
 885:     {
 886:         $this->skipPaging = true;
 887: 
 888:         return $this;
 889:     }
 890: 
 891:     /**
 892:      * Check if column is blacklisted.
 893:      *
 894:      * @param string $column
 895:      * @return bool
 896:      */
 897:     protected function isBlacklisted($column)
 898:     {
 899:         if (in_array($column, $this->columnDef['blacklist'])) {
 900:             return true;
 901:         }
 902: 
 903:         if ($this->columnDef['whitelist'] === '*' || in_array($column, $this->columnDef['whitelist'])) {
 904:             return false;
 905:         }
 906: 
 907:         return true;
 908:     }
 909: 
 910:     /**
 911:      * Get column name to be use for filtering and sorting.
 912:      *
 913:      * @param integer $index
 914:      * @param bool $wantsAlias
 915:      * @return string
 916:      */
 917:     protected function getColumnName($index, $wantsAlias = false)
 918:     {
 919:         $column = $this->request->columnName($index);
 920: 
 921:         // DataTables is using make(false)
 922:         if (is_numeric($column)) {
 923:             $column = $this->getColumnNameByIndex($index);
 924:         }
 925: 
 926:         if (Str::contains(Str::upper($column), ' AS ')) {
 927:             $column = $this->extractColumnName($column, $wantsAlias);
 928:         }
 929: 
 930:         return $column;
 931:     }
 932: 
 933:     /**
 934:      * Get column name by order column index.
 935:      *
 936:      * @param int $index
 937:      * @return mixed
 938:      */
 939:     protected function getColumnNameByIndex($index)
 940:     {
 941:         $name = isset($this->columns[$index]) && $this->columns[$index] <> '*' ? $this->columns[$index] : $this->getPrimaryKeyName();
 942: 
 943:         return in_array($name, $this->extraColumns, true) ? $this->getPrimaryKeyName() : $name;
 944:     }
 945: 
 946:     /**
 947:      * If column name could not be resolved then use primary key.
 948:      *
 949:      * @return string
 950:      */
 951:     protected function getPrimaryKeyName()
 952:     {
 953:         if ($this->isEloquent()) {
 954:             return $this->query->getModel()->getKeyName();
 955:         }
 956: 
 957:         return 'id';
 958:     }
 959: 
 960:     /**
 961:      * Check if the engine used was eloquent.
 962:      *
 963:      * @return bool
 964:      */
 965:     protected function isEloquent()
 966:     {
 967:         return $this->query_type === 'eloquent';
 968:     }
 969: 
 970:     /**
 971:      * Get column name from string.
 972:      *
 973:      * @param string $str
 974:      * @param bool $wantsAlias
 975:      * @return string
 976:      */
 977:     protected function extractColumnName($str, $wantsAlias)
 978:     {
 979:         $matches = explode(' as ', Str::lower($str));
 980: 
 981:         if (! empty($matches)) {
 982:             if ($wantsAlias) {
 983:                 return array_pop($matches);
 984:             } else {
 985:                 return array_shift($matches);
 986:             }
 987:         } elseif (strpos($str, '.')) {
 988:             $array = explode('.', $str);
 989: 
 990:             return array_pop($array);
 991:         }
 992: 
 993:         return $str;
 994:     }
 995: 
 996:     /**
 997:      * Check if the current sql language is based on oracle syntax.
 998:      *
 999:      * @return bool
1000:      */
1001:     protected function isOracleSql()
1002:     {
1003:         return in_array($this->database, ['oracle', 'oci8']);
1004:     }
1005: }
1006: 
API documentation generated by ApiGen