updated-packages
This commit is contained in:
63
vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php
vendored
Normal file
63
vendor/yajra/laravel-datatables-oracle/src/ApiResourceDataTable.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
|
||||
class ApiResourceDataTable extends CollectionDataTable
|
||||
{
|
||||
/**
|
||||
* Collection object.
|
||||
*
|
||||
* @var \Illuminate\Http\Resources\Json\AnonymousResourceCollection
|
||||
*/
|
||||
public $collection;
|
||||
|
||||
/**
|
||||
* Collection object.
|
||||
*
|
||||
* @var \Illuminate\Http\Resources\Json\AnonymousResourceCollection
|
||||
*/
|
||||
public $original;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return $source instanceof AnonymousResourceCollection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method, create and return an instance for the DataTable engine.
|
||||
*
|
||||
* @param \Illuminate\Http\Resources\Json\AnonymousResourceCollection $source
|
||||
* @return ApiResourceDataTable|DataTableAbstract
|
||||
*/
|
||||
public static function create($source)
|
||||
{
|
||||
return parent::create($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* CollectionEngine constructor.
|
||||
*
|
||||
* @param \Illuminate\Http\Resources\Json\AnonymousResourceCollection $collection
|
||||
*/
|
||||
public function __construct(AnonymousResourceCollection $collection)
|
||||
{
|
||||
$this->request = app('datatables.request');
|
||||
$this->config = app('datatables.config');
|
||||
$this->collection = collect($collection->toArray($this->request));
|
||||
$this->original = $collection;
|
||||
$this->columns = array_keys($this->serialize(collect($collection->toArray($this->request))->first()));
|
||||
if ($collection->resource instanceof LengthAwarePaginator) {
|
||||
$this->isFilterApplied = true;
|
||||
}
|
||||
}
|
||||
}
|
338
vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php
vendored
Normal file
338
vendor/yajra/laravel-datatables-oracle/src/CollectionDataTable.php
vendored
Normal file
@@ -0,0 +1,338 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
class CollectionDataTable extends DataTableAbstract
|
||||
{
|
||||
/**
|
||||
* Collection object.
|
||||
*
|
||||
* @var \Illuminate\Support\Collection
|
||||
*/
|
||||
public $collection;
|
||||
|
||||
/**
|
||||
* Collection object.
|
||||
*
|
||||
* @var \Illuminate\Support\Collection
|
||||
*/
|
||||
public $original;
|
||||
|
||||
/**
|
||||
* The offset of the first record in the full dataset.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $offset = 0;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return is_array($source) || $source instanceof Collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method, create and return an instance for the DataTable engine.
|
||||
*
|
||||
* @param array|\Illuminate\Support\Collection $source
|
||||
* @return CollectionDataTable|DataTableAbstract
|
||||
*/
|
||||
public static function create($source)
|
||||
{
|
||||
if (is_array($source)) {
|
||||
$source = new Collection($source);
|
||||
}
|
||||
|
||||
return parent::create($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* CollectionEngine constructor.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $collection
|
||||
*/
|
||||
public function __construct(Collection $collection)
|
||||
{
|
||||
$this->request = app('datatables.request');
|
||||
$this->config = app('datatables.config');
|
||||
$this->collection = $collection;
|
||||
$this->original = $collection;
|
||||
$this->columns = array_keys($this->serialize($collection->first()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize collection.
|
||||
*
|
||||
* @param mixed $collection
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function serialize($collection)
|
||||
{
|
||||
return $collection instanceof Arrayable ? $collection->toArray() : (array) $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count results.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->collection->count() > $this->totalRecords ? $this->totalRecords : $this->collection->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform column search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function columnSearch()
|
||||
{
|
||||
$columns = $this->request->get('columns', []);
|
||||
for ($i = 0, $c = count($columns); $i < $c; $i++) {
|
||||
$column = $this->getColumnName($i);
|
||||
|
||||
if (! $this->request->isColumnSearchable($i) || $this->isBlacklisted($column)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
|
||||
$regex = $this->request->isRegex($i);
|
||||
$keyword = $this->request->columnKeyword($i);
|
||||
|
||||
$this->collection = $this->collection->filter(
|
||||
function ($row) use ($column, $keyword, $regex) {
|
||||
$data = $this->serialize($row);
|
||||
|
||||
$value = Arr::get($data, $column);
|
||||
|
||||
if ($this->config->isCaseInsensitive()) {
|
||||
if ($regex) {
|
||||
return preg_match('/' . $keyword . '/i', $value) == 1;
|
||||
}
|
||||
|
||||
return strpos(Str::lower($value), Str::lower($keyword)) !== false;
|
||||
}
|
||||
|
||||
if ($regex) {
|
||||
return preg_match('/' . $keyword . '/', $value) == 1;
|
||||
}
|
||||
|
||||
return strpos($value, $keyword) !== false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paging()
|
||||
{
|
||||
$this->collection = $this->collection->slice(
|
||||
$this->request->input('start') - $this->offset,
|
||||
(int) $this->request->input('length') > 0 ? $this->request->input('length') : 10
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = true)
|
||||
{
|
||||
try {
|
||||
$this->totalRecords = $this->totalCount();
|
||||
|
||||
if ($this->totalRecords) {
|
||||
$results = $this->results();
|
||||
$processed = $this->processResults($results, $mDataSupport);
|
||||
$output = $this->transform($results, $processed);
|
||||
|
||||
$this->collection = collect($output);
|
||||
$this->ordering();
|
||||
$this->filterRecords();
|
||||
$this->paginate();
|
||||
|
||||
$this->revertIndexColumn($mDataSupport);
|
||||
}
|
||||
|
||||
return $this->render($this->collection->values()->all());
|
||||
} catch (\Exception $exception) {
|
||||
return $this->errorResponse($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function totalCount()
|
||||
{
|
||||
return $this->totalRecords ? $this->totalRecords : $this->collection->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get results.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function results()
|
||||
{
|
||||
return $this->collection->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Revert transformed DT_RowIndex back to it's original values.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
*/
|
||||
private function revertIndexColumn($mDataSupport)
|
||||
{
|
||||
if ($this->columnDef['index']) {
|
||||
$index = $mDataSupport ? config('datatables.index_column', 'DT_RowIndex') : 0;
|
||||
$start = (int) $this->request->input('start');
|
||||
$this->collection->transform(function ($data) use ($index, &$start) {
|
||||
$data[$index] = ++$start;
|
||||
|
||||
return $data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search for the given keyword.
|
||||
*
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function globalSearch($keyword)
|
||||
{
|
||||
$keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword;
|
||||
|
||||
$this->collection = $this->collection->filter(function ($row) use ($keyword) {
|
||||
$this->isFilterApplied = true;
|
||||
|
||||
$data = $this->serialize($row);
|
||||
foreach ($this->request->searchableColumnIndex() as $index) {
|
||||
$column = $this->getColumnName($index);
|
||||
$value = Arr::get($data, $column);
|
||||
if (! $value || is_array($value)) {
|
||||
if (! is_numeric($value)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$value = (string) $value;
|
||||
}
|
||||
|
||||
$value = $this->config->isCaseInsensitive() ? Str::lower($value) : $value;
|
||||
if (Str::contains($value, $keyword)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform default query orderBy clause.
|
||||
*/
|
||||
protected function defaultOrdering()
|
||||
{
|
||||
$criteria = $this->request->orderableColumns();
|
||||
if (! empty($criteria)) {
|
||||
$sorter = $this->getSorter($criteria);
|
||||
|
||||
$this->collection = $this->collection
|
||||
->map(function ($data) {
|
||||
return Arr::dot($data);
|
||||
})
|
||||
->sort($sorter)
|
||||
->map(function ($data) {
|
||||
foreach ($data as $key => $value) {
|
||||
unset($data[$key]);
|
||||
Arr::set($data, $key, $value);
|
||||
}
|
||||
|
||||
return $data;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array sorter closure.
|
||||
*
|
||||
* @param array $criteria
|
||||
* @return \Closure
|
||||
*/
|
||||
protected function getSorter(array $criteria)
|
||||
{
|
||||
$sorter = function ($a, $b) use ($criteria) {
|
||||
foreach ($criteria as $orderable) {
|
||||
$column = $this->getColumnName($orderable['column']);
|
||||
$direction = $orderable['direction'];
|
||||
if ($direction === 'desc') {
|
||||
$first = $b;
|
||||
$second = $a;
|
||||
} else {
|
||||
$first = $a;
|
||||
$second = $b;
|
||||
}
|
||||
if ($this->config->isCaseInsensitive()) {
|
||||
$cmp = strnatcasecmp($first[$column], $second[$column]);
|
||||
} else {
|
||||
$cmp = strnatcmp($first[$column], $second[$column]);
|
||||
}
|
||||
if ($cmp != 0) {
|
||||
return $cmp;
|
||||
}
|
||||
}
|
||||
|
||||
// all elements were equal
|
||||
return 0;
|
||||
};
|
||||
|
||||
return $sorter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve callback parameter instance.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
protected function resolveCallbackParameter()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the offset of the first item of the collection with respect to
|
||||
* the FULL dataset the collection was sliced from. It effectively allows the
|
||||
* collection to be "pre-sliced".
|
||||
*
|
||||
* @param int $offset
|
||||
* @return $this
|
||||
*/
|
||||
public function setOffset(int $offset)
|
||||
{
|
||||
$this->offset = $offset;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,14 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Contracts;
|
||||
namespace Yajra\DataTables\Contracts;
|
||||
|
||||
/**
|
||||
* Interface DataTableEngineContract
|
||||
*
|
||||
* @package Yajra\Datatables\Contracts
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
interface DataTableEngineContract
|
||||
interface DataTable
|
||||
{
|
||||
/**
|
||||
* Get results.
|
||||
@@ -20,14 +14,14 @@ interface DataTableEngineContract
|
||||
/**
|
||||
* Count results.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function count();
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return integer
|
||||
* @return int
|
||||
*/
|
||||
public function totalCount();
|
||||
|
||||
@@ -35,11 +29,11 @@ interface DataTableEngineContract
|
||||
* Set auto filter off and run your own filter.
|
||||
* Overrides global search.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $globalSearch
|
||||
* @param callable $callback
|
||||
* @param bool $globalSearch
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(\Closure $callback, $globalSearch = false);
|
||||
public function filter(callable $callback, $globalSearch = false);
|
||||
|
||||
/**
|
||||
* Perform global search.
|
||||
@@ -73,8 +67,7 @@ interface DataTableEngineContract
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @param bool $orderFirst
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = false, $orderFirst = false);
|
||||
public function make($mDataSupport = true);
|
||||
}
|
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Contracts;
|
||||
|
||||
/**
|
||||
* Interface DataTableButtonsContract.
|
||||
*
|
||||
* @package Yajra\Datatables\Contracts
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
interface DataTableButtonsContract
|
||||
{
|
||||
/**
|
||||
* Export to excel file.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function excel();
|
||||
|
||||
/**
|
||||
* Export to CSV file.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function csv();
|
||||
|
||||
/**
|
||||
* Export to PDF file.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function pdf();
|
||||
|
||||
/**
|
||||
* Display printer friendly view.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function printPreview();
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Contracts;
|
||||
|
||||
/**
|
||||
* Interface DataTableContract
|
||||
*
|
||||
* @package Yajra\Datatables\Contracts
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
interface DataTableContract
|
||||
{
|
||||
/**
|
||||
* Render view.
|
||||
*
|
||||
* @param $view
|
||||
* @param array $data
|
||||
* @param array $mergeData
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function render($view, $data = [], $mergeData = []);
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function ajax();
|
||||
|
||||
/**
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function html();
|
||||
|
||||
/**
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function builder();
|
||||
|
||||
/**
|
||||
* @return \Yajra\Datatables\Request
|
||||
*/
|
||||
public function request();
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Support\Collection
|
||||
*/
|
||||
public function query();
|
||||
}
|
@@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Contracts;
|
||||
|
||||
/**
|
||||
* Interface DataTableScopeContract.
|
||||
*
|
||||
* @package Yajra\Datatables\Contracts
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
interface DataTableScopeContract
|
||||
{
|
||||
/**
|
||||
* Apply a query scope.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($query);
|
||||
}
|
927
vendor/yajra/laravel-datatables-oracle/src/DataTableAbstract.php
vendored
Normal file
927
vendor/yajra/laravel-datatables-oracle/src/DataTableAbstract.php
vendored
Normal file
@@ -0,0 +1,927 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Yajra\DataTables\Utilities\Helper;
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
use Yajra\DataTables\Contracts\DataTable;
|
||||
use Illuminate\Contracts\Support\Jsonable;
|
||||
use Yajra\DataTables\Exceptions\Exception;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Yajra\DataTables\Processors\DataProcessor;
|
||||
|
||||
/**
|
||||
* @method DataTableAbstract setTransformer($transformer)
|
||||
* @method DataTableAbstract setSerializer($transformer)
|
||||
* @property mixed transformer
|
||||
* @property mixed serializer
|
||||
* @see https://github.com/yajra/laravel-datatables-fractal for transformer related methods.
|
||||
*/
|
||||
abstract class DataTableAbstract implements DataTable, Arrayable, Jsonable
|
||||
{
|
||||
use Macroable;
|
||||
|
||||
/**
|
||||
* DataTables Request object.
|
||||
*
|
||||
* @var \Yajra\DataTables\Utilities\Request
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* @var \Psr\Log\LoggerInterface
|
||||
*/
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* Array of result columns/fields.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columns = [];
|
||||
|
||||
/**
|
||||
* DT columns definitions container (add/edit/remove/filter/order/escape).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columnDef = [
|
||||
'index' => false,
|
||||
'append' => [],
|
||||
'edit' => [],
|
||||
'filter' => [],
|
||||
'order' => [],
|
||||
'only' => null,
|
||||
'hidden' => [],
|
||||
'visible' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* Extra/Added columns.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraColumns = [];
|
||||
|
||||
/**
|
||||
* Total records.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $totalRecords = 0;
|
||||
|
||||
/**
|
||||
* Total filtered records.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $filteredRecords = 0;
|
||||
|
||||
/**
|
||||
* Auto-filter flag.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoFilter = true;
|
||||
|
||||
/**
|
||||
* Callback to override global search.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $filterCallback;
|
||||
|
||||
/**
|
||||
* DT row templates container.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $templates = [
|
||||
'DT_RowId' => '',
|
||||
'DT_RowClass' => '',
|
||||
'DT_RowData' => [],
|
||||
'DT_RowAttr' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* [internal] Track if any filter was applied for at least one column.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $isFilterApplied = false;
|
||||
|
||||
/**
|
||||
* Custom ordering callback.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $orderCallback;
|
||||
|
||||
/**
|
||||
* Skip paginate as needed.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $skipPaging = false;
|
||||
|
||||
/**
|
||||
* Array of data to append on json response.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $appends = [];
|
||||
|
||||
/**
|
||||
* @var \Yajra\DataTables\Utilities\Config
|
||||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $serializer;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method, create and return an instance for the DataTable engine.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return DataTableAbstract
|
||||
*/
|
||||
public static function create($source)
|
||||
{
|
||||
return new static($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add column in collection.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @param bool|int $order
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumn($name, $content, $order = false)
|
||||
{
|
||||
$this->extraColumns[] = $name;
|
||||
|
||||
$this->columnDef['append'][] = ['name' => $name, 'content' => $content, 'order' => $order];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT row index column on response.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addIndexColumn()
|
||||
{
|
||||
$this->columnDef['index'] = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit column's content.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function editColumn($name, $content)
|
||||
{
|
||||
$this->columnDef['edit'][] = ['name' => $name, 'content' => $content];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove column from collection.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeColumn()
|
||||
{
|
||||
$names = func_get_args();
|
||||
$this->columnDef['excess'] = array_merge($this->getColumnsDefinition()['excess'], $names);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get only selected columns in response.
|
||||
*
|
||||
* @param array $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function only(array $columns = [])
|
||||
{
|
||||
$this->columnDef['only'] = $columns;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare columns to escape values.
|
||||
*
|
||||
* @param string|array $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function escapeColumns($columns = '*')
|
||||
{
|
||||
$this->columnDef['escape'] = $columns;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a makeHidden() to the row object.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function makeHidden(array $attributes = [])
|
||||
{
|
||||
$this->columnDef['hidden'] = array_merge_recursive(Arr::get($this->columnDef, 'hidden', []), $attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a makeVisible() to the row object.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function makeVisible(array $attributes = [])
|
||||
{
|
||||
$this->columnDef['visible'] = array_merge_recursive(Arr::get($this->columnDef, 'visible', []), $attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set columns that should not be escaped.
|
||||
* Optionally merge the defaults from config.
|
||||
*
|
||||
* @param array $columns
|
||||
* @param bool $merge
|
||||
* @return $this
|
||||
*/
|
||||
public function rawColumns(array $columns, $merge = false)
|
||||
{
|
||||
if ($merge) {
|
||||
$config = $this->config->get('datatables.columns');
|
||||
|
||||
$this->columnDef['raw'] = array_merge($config['raw'], $columns);
|
||||
} else {
|
||||
$this->columnDef['raw'] = $columns;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets DT_RowClass template.
|
||||
* result: <tr class="output_from_your_template">.
|
||||
*
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowClass($content)
|
||||
{
|
||||
$this->templates['DT_RowClass'] = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets DT_RowId template.
|
||||
* result: <tr id="output_from_your_template">.
|
||||
*
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowId($content)
|
||||
{
|
||||
$this->templates['DT_RowId'] = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DT_RowData templates.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowData(array $data)
|
||||
{
|
||||
$this->templates['DT_RowData'] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT_RowData template.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function addRowData($key, $value)
|
||||
{
|
||||
$this->templates['DT_RowData'][$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DT_RowAttr templates.
|
||||
* result: <tr attr1="attr1" attr2="attr2">.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowAttr(array $data)
|
||||
{
|
||||
$this->templates['DT_RowAttr'] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT_RowAttr template.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function addRowAttr($key, $value)
|
||||
{
|
||||
$this->templates['DT_RowAttr'][$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data on json response.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function with($key, $value = '')
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$this->appends = $key;
|
||||
} elseif (is_callable($value)) {
|
||||
$this->appends[$key] = value($value);
|
||||
} else {
|
||||
$this->appends[$key] = value($value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add with query callback value on response.
|
||||
*
|
||||
* @param string $key
|
||||
* @param callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function withQuery($key, callable $value)
|
||||
{
|
||||
$this->appends[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default ordering method with a closure callback.
|
||||
*
|
||||
* @param callable $closure
|
||||
* @return $this
|
||||
*/
|
||||
public function order(callable $closure)
|
||||
{
|
||||
$this->orderCallback = $closure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update list of columns that is not allowed for search/sort.
|
||||
*
|
||||
* @param array $blacklist
|
||||
* @return $this
|
||||
*/
|
||||
public function blacklist(array $blacklist)
|
||||
{
|
||||
$this->columnDef['blacklist'] = $blacklist;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update list of columns that is allowed for search/sort.
|
||||
*
|
||||
* @param string|array $whitelist
|
||||
* @return $this
|
||||
*/
|
||||
public function whitelist($whitelist = '*')
|
||||
{
|
||||
$this->columnDef['whitelist'] = $whitelist;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set smart search config at runtime.
|
||||
*
|
||||
* @param bool $state
|
||||
* @return $this
|
||||
*/
|
||||
public function smart($state = true)
|
||||
{
|
||||
$this->config->set('datatables.search.smart', $state);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set starts_with search config at runtime.
|
||||
*
|
||||
* @param bool $state
|
||||
* @return $this
|
||||
*/
|
||||
public function startsWithSearch($state = true)
|
||||
{
|
||||
$this->config->set('datatables.search.starts_with', $state);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set total records manually.
|
||||
*
|
||||
* @param int $total
|
||||
* @return $this
|
||||
*/
|
||||
public function setTotalRecords($total)
|
||||
{
|
||||
$this->totalRecords = $total;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set filtered records manually.
|
||||
*
|
||||
* @param int $total
|
||||
* @return $this
|
||||
*/
|
||||
public function setFilteredRecords($total)
|
||||
{
|
||||
$this->filteredRecords = $total;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip pagination as needed.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function skipPaging()
|
||||
{
|
||||
$this->skipPaging = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a new column name to blacklist.
|
||||
*
|
||||
* @param string $column
|
||||
* @return $this
|
||||
*/
|
||||
public function pushToBlacklist($column)
|
||||
{
|
||||
if (! $this->isBlacklisted($column)) {
|
||||
$this->columnDef['blacklist'][] = $column;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if column is blacklisted.
|
||||
*
|
||||
* @param string $column
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBlacklisted($column)
|
||||
{
|
||||
$colDef = $this->getColumnsDefinition();
|
||||
|
||||
if (in_array($column, $colDef['blacklist'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($colDef['whitelist'] === '*' || in_array($column, $colDef['whitelist'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns definition.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getColumnsDefinition()
|
||||
{
|
||||
$config = $this->config->get('datatables.columns');
|
||||
$allowed = ['excess', 'escape', 'raw', 'blacklist', 'whitelist'];
|
||||
|
||||
return array_replace_recursive(Arr::only($config, $allowed), $this->columnDef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform sorting of columns.
|
||||
*/
|
||||
public function ordering()
|
||||
{
|
||||
if ($this->orderCallback) {
|
||||
return call_user_func($this->orderCallback, $this->resolveCallbackParameter());
|
||||
}
|
||||
|
||||
return $this->defaultOrdering();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve callback parameter instance.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function resolveCallbackParameter();
|
||||
|
||||
/**
|
||||
* Perform default query orderBy clause.
|
||||
*/
|
||||
abstract protected function defaultOrdering();
|
||||
|
||||
/**
|
||||
* Set auto filter off and run your own filter.
|
||||
* Overrides global search.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @param bool $globalSearch
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(callable $callback, $globalSearch = false)
|
||||
{
|
||||
$this->autoFilter = $globalSearch;
|
||||
$this->isFilterApplied = true;
|
||||
$this->filterCallback = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert instance to array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return $this->make()->getData(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the object to its JSON representation.
|
||||
*
|
||||
* @param int $options
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function toJson($options = 0)
|
||||
{
|
||||
if ($options) {
|
||||
$this->config->set('datatables.json.options', $options);
|
||||
}
|
||||
|
||||
return $this->make();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count filtered items.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function filteredCount()
|
||||
{
|
||||
return $this->filteredRecords ? $this->filteredRecords : $this->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform necessary filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function filterRecords()
|
||||
{
|
||||
if ($this->autoFilter && $this->request->isSearchable()) {
|
||||
$this->filtering();
|
||||
}
|
||||
|
||||
if (is_callable($this->filterCallback)) {
|
||||
call_user_func($this->filterCallback, $this->resolveCallbackParameter());
|
||||
}
|
||||
|
||||
$this->columnSearch();
|
||||
$this->filteredRecords = $this->isFilterApplied ? $this->filteredCount() : $this->totalRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filtering()
|
||||
{
|
||||
$keyword = $this->request->keyword();
|
||||
|
||||
if ($this->config->isMultiTerm()) {
|
||||
$this->smartGlobalSearch($keyword);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->globalSearch($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform multi-term search by splitting keyword into
|
||||
* individual words and searches for each of them.
|
||||
*
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function smartGlobalSearch($keyword)
|
||||
{
|
||||
collect(explode(' ', $keyword))
|
||||
->reject(function ($keyword) {
|
||||
return trim($keyword) === '';
|
||||
})
|
||||
->each(function ($keyword) {
|
||||
$this->globalSearch($keyword);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search for the given keyword.
|
||||
*
|
||||
* @param string $keyword
|
||||
*/
|
||||
abstract protected function globalSearch($keyword);
|
||||
|
||||
/**
|
||||
* Apply pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function paginate()
|
||||
{
|
||||
if ($this->request->isPaginationable() && ! $this->skipPaging) {
|
||||
$this->paging();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform output.
|
||||
*
|
||||
* @param mixed $results
|
||||
* @param mixed $processed
|
||||
* @return array
|
||||
*/
|
||||
protected function transform($results, $processed)
|
||||
{
|
||||
if (isset($this->transformer) && class_exists('Yajra\\DataTables\\Transformers\\FractalTransformer')) {
|
||||
return app('datatables.transformer')->transform(
|
||||
$results,
|
||||
$this->transformer,
|
||||
$this->serializer ?? null
|
||||
);
|
||||
}
|
||||
|
||||
return Helper::transform($processed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get processed data.
|
||||
*
|
||||
* @param mixed $results
|
||||
* @param bool $object
|
||||
* @return array
|
||||
*/
|
||||
protected function processResults($results, $object = false)
|
||||
{
|
||||
$processor = new DataProcessor(
|
||||
$results,
|
||||
$this->getColumnsDefinition(),
|
||||
$this->templates,
|
||||
$this->request->input('start')
|
||||
);
|
||||
|
||||
return $processor->process($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render json response.
|
||||
*
|
||||
* @param array $data
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
protected function render(array $data)
|
||||
{
|
||||
$output = $this->attachAppends([
|
||||
'draw' => (int) $this->request->input('draw'),
|
||||
'recordsTotal' => $this->totalRecords,
|
||||
'recordsFiltered' => $this->filteredRecords,
|
||||
'data' => $data,
|
||||
]);
|
||||
|
||||
if ($this->config->isDebugging()) {
|
||||
$output = $this->showDebugger($output);
|
||||
}
|
||||
|
||||
return new JsonResponse(
|
||||
$output,
|
||||
200,
|
||||
$this->config->get('datatables.json.header', []),
|
||||
$this->config->get('datatables.json.options', 0)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach custom with meta on response.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function attachAppends(array $data)
|
||||
{
|
||||
return array_merge($data, $this->appends);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append debug parameters on output.
|
||||
*
|
||||
* @param array $output
|
||||
* @return array
|
||||
*/
|
||||
protected function showDebugger(array $output)
|
||||
{
|
||||
$output['input'] = $this->request->all();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an error json response.
|
||||
*
|
||||
* @param \Exception $exception
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Yajra\DataTables\Exceptions\Exception
|
||||
*/
|
||||
protected function errorResponse(\Exception $exception)
|
||||
{
|
||||
$error = $this->config->get('datatables.error');
|
||||
$debug = $this->config->get('app.debug');
|
||||
|
||||
if ($error === 'throw' || (! $error && ! $debug)) {
|
||||
throw new Exception($exception->getMessage(), $code = 0, $exception);
|
||||
}
|
||||
|
||||
$this->getLogger()->error($exception);
|
||||
|
||||
return new JsonResponse([
|
||||
'draw' => (int) $this->request->input('draw'),
|
||||
'recordsTotal' => $this->totalRecords,
|
||||
'recordsFiltered' => 0,
|
||||
'data' => [],
|
||||
'error' => $error ? __($error) : "Exception Message:\n\n".$exception->getMessage(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get monolog/logger instance.
|
||||
*
|
||||
* @return \Psr\Log\LoggerInterface
|
||||
*/
|
||||
public function getLogger()
|
||||
{
|
||||
$this->logger = $this->logger ?: app(LoggerInterface::class);
|
||||
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set monolog/logger instance.
|
||||
*
|
||||
* @param \Psr\Log\LoggerInterface $logger
|
||||
* @return $this
|
||||
*/
|
||||
public function setLogger(LoggerInterface $logger)
|
||||
{
|
||||
$this->logger = $logger;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup search keyword.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
protected function setupKeyword($value)
|
||||
{
|
||||
if ($this->config->isSmartSearch()) {
|
||||
$keyword = '%'.$value.'%';
|
||||
if ($this->config->isWildcard()) {
|
||||
$keyword = Helper::wildcardLikeString($value);
|
||||
}
|
||||
// remove escaping slash added on js script request
|
||||
$keyword = str_replace('\\', '%', $keyword);
|
||||
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name to be use for filtering and sorting.
|
||||
*
|
||||
* @param int $index
|
||||
* @param bool $wantsAlias
|
||||
* @return string
|
||||
*/
|
||||
protected function getColumnName($index, $wantsAlias = false)
|
||||
{
|
||||
$column = $this->request->columnName($index);
|
||||
|
||||
// DataTables is using make(false)
|
||||
if (is_numeric($column)) {
|
||||
$column = $this->getColumnNameByIndex($index);
|
||||
}
|
||||
|
||||
if (Str::contains(Str::upper($column), ' AS ')) {
|
||||
$column = Helper::extractColumnName($column, $wantsAlias);
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name by order column index.
|
||||
*
|
||||
* @param int $index
|
||||
* @return string
|
||||
*/
|
||||
protected function getColumnNameByIndex($index)
|
||||
{
|
||||
$name = (isset($this->columns[$index]) && $this->columns[$index] != '*')
|
||||
? $this->columns[$index] : $this->getPrimaryKeyName();
|
||||
|
||||
return in_array($name, $this->extraColumns, true) ? $this->getPrimaryKeyName() : $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* If column name could not be resolved then use primary key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPrimaryKeyName()
|
||||
{
|
||||
return 'id';
|
||||
}
|
||||
}
|
154
vendor/yajra/laravel-datatables-oracle/src/DataTables.php
vendored
Normal file
154
vendor/yajra/laravel-datatables-oracle/src/DataTables.php
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Traits\Macroable;
|
||||
|
||||
class DataTables
|
||||
{
|
||||
use Macroable;
|
||||
|
||||
/**
|
||||
* DataTables request object.
|
||||
*
|
||||
* @var \Yajra\DataTables\Utilities\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* HTML builder instance.
|
||||
*
|
||||
* @var \Yajra\DataTables\Html\Builder
|
||||
*/
|
||||
protected $html;
|
||||
|
||||
/**
|
||||
* Make a DataTable instance from source.
|
||||
* Alias of make for backward compatibility.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function of($source)
|
||||
{
|
||||
return self::make($source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a DataTable instance from source.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function make($source)
|
||||
{
|
||||
$engines = config('datatables.engines');
|
||||
$builders = config('datatables.builders');
|
||||
|
||||
$args = func_get_args();
|
||||
foreach ($builders as $class => $engine) {
|
||||
if ($source instanceof $class) {
|
||||
return call_user_func_array([$engines[$engine], 'create'], $args);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($engines as $engine => $class) {
|
||||
if (call_user_func_array([$engines[$engine], 'canCreate'], $args)) {
|
||||
return call_user_func_array([$engines[$engine], 'create'], $args);
|
||||
}
|
||||
}
|
||||
|
||||
throw new \Exception('No available engine for ' . get_class($source));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request object.
|
||||
*
|
||||
* @return \Yajra\DataTables\Utilities\Request
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return app('datatables.request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config instance.
|
||||
*
|
||||
* @return \Yajra\DataTables\Utilities\Config
|
||||
*/
|
||||
public function getConfig()
|
||||
{
|
||||
return app('datatables.config');
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use query() instead, this method will be removed in a next version.
|
||||
* @param $builder
|
||||
* @return QueryDataTable
|
||||
*/
|
||||
public function queryBuilder($builder)
|
||||
{
|
||||
return $this->query($builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTables using Query.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder|mixed $builder
|
||||
* @return DataTableAbstract|QueryDataTable
|
||||
*/
|
||||
public function query($builder)
|
||||
{
|
||||
return QueryDataTable::create($builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTables using Eloquent Builder.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Builder|mixed $builder
|
||||
* @return DataTableAbstract|EloquentDataTable
|
||||
*/
|
||||
public function eloquent($builder)
|
||||
{
|
||||
return EloquentDataTable::create($builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTables using Collection.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection|array $collection
|
||||
* @return DataTableAbstract|CollectionDataTable
|
||||
*/
|
||||
public function collection($collection)
|
||||
{
|
||||
return CollectionDataTable::create($collection);
|
||||
}
|
||||
|
||||
/**
|
||||
* DataTables using Collection.
|
||||
*
|
||||
* @param \Illuminate\Http\Resources\Json\AnonymousResourceCollection|array $collection
|
||||
* @return DataTableAbstract|ApiResourceDataTable
|
||||
*/
|
||||
public function resource($resource)
|
||||
{
|
||||
return ApiResourceDataTable::create($resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get html builder instance.
|
||||
*
|
||||
* @return \Yajra\DataTables\Html\Builder
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getHtmlBuilder()
|
||||
{
|
||||
if (! class_exists('\Yajra\DataTables\Html\Builder')) {
|
||||
throw new \Exception('Please install yajra/laravel-datatables-html to be able to use this function.');
|
||||
}
|
||||
|
||||
return $this->html ?: $this->html = app('datatables.html');
|
||||
}
|
||||
}
|
83
vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php
vendored
Normal file
83
vendor/yajra/laravel-datatables-oracle/src/DataTablesServiceProvider.php
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Str;
|
||||
use Yajra\DataTables\Utilities\Config;
|
||||
use Yajra\DataTables\Utilities\Request;
|
||||
|
||||
class DataTablesServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
if ($this->isLumen()) {
|
||||
require_once 'lumen.php';
|
||||
}
|
||||
|
||||
$this->setupAssets();
|
||||
|
||||
$this->app->alias('datatables', DataTables::class);
|
||||
$this->app->singleton('datatables', function () {
|
||||
return new DataTables;
|
||||
});
|
||||
|
||||
$this->app->singleton('datatables.request', function () {
|
||||
return new Request;
|
||||
});
|
||||
|
||||
$this->app->singleton('datatables.config', Config::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Boot the instance, add macros for datatable engines.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$engines = (array) config('datatables.engines');
|
||||
foreach ($engines as $engine => $class) {
|
||||
$engine = Str::camel($engine);
|
||||
|
||||
if (! method_exists(DataTables::class, $engine) && ! DataTables::hasMacro($engine)) {
|
||||
DataTables::macro($engine, function () use ($class) {
|
||||
if (! call_user_func_array([$class, 'canCreate'], func_get_args())) {
|
||||
throw new \InvalidArgumentException();
|
||||
}
|
||||
|
||||
return call_user_func_array([$class, 'create'], func_get_args());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup package assets.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function setupAssets()
|
||||
{
|
||||
$this->mergeConfigFrom($config = __DIR__ . '/config/datatables.php', 'datatables');
|
||||
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->publishes([$config => config_path('datatables.php')], 'datatables');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if app uses Lumen.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isLumen()
|
||||
{
|
||||
return Str::contains($this->app->version(), 'Lumen');
|
||||
}
|
||||
}
|
@@ -1,136 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables;
|
||||
|
||||
use Illuminate\Database\Query\Builder as QueryBuilder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Yajra\Datatables\Engines\CollectionEngine;
|
||||
use Yajra\Datatables\Engines\EloquentEngine;
|
||||
use Yajra\Datatables\Engines\QueryBuilderEngine;
|
||||
|
||||
/**
|
||||
* Class Datatables.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @method EloquentEngine eloquent($builder)
|
||||
* @method CollectionEngine collection(Collection $builder)
|
||||
* @method QueryBuilderEngine queryBuilder(QueryBuilder $builder)
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Datatables
|
||||
{
|
||||
/**
|
||||
* Datatables request object.
|
||||
*
|
||||
* @var \Yajra\Datatables\Request
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* Datatables builder.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
public $builder;
|
||||
|
||||
/**
|
||||
* Datatables constructor.
|
||||
*
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
*/
|
||||
public function __construct(Request $request)
|
||||
{
|
||||
$this->request = $request->request->count() ? $request : Request::capture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets query and returns instance of class.
|
||||
*
|
||||
* @param mixed $builder
|
||||
* @return mixed
|
||||
*/
|
||||
public static function of($builder)
|
||||
{
|
||||
$datatables = app('Yajra\Datatables\Datatables');
|
||||
$datatables->builder = $builder;
|
||||
|
||||
if ($builder instanceof QueryBuilder) {
|
||||
$ins = $datatables->usingQueryBuilder($builder);
|
||||
} else {
|
||||
$ins = $builder instanceof Collection ? $datatables->usingCollection($builder) : $datatables->usingEloquent($builder);
|
||||
}
|
||||
|
||||
return $ins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Datatables using Query Builder.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
* @return \Yajra\Datatables\Engines\QueryBuilderEngine
|
||||
*/
|
||||
public function usingQueryBuilder(QueryBuilder $builder)
|
||||
{
|
||||
return new QueryBuilderEngine($builder, $this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Datatables using Collection.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $builder
|
||||
* @return \Yajra\Datatables\Engines\CollectionEngine
|
||||
*/
|
||||
public function usingCollection(Collection $builder)
|
||||
{
|
||||
return new CollectionEngine($builder, $this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Datatables using Eloquent.
|
||||
*
|
||||
* @param mixed $builder
|
||||
* @return \Yajra\Datatables\Engines\EloquentEngine
|
||||
*/
|
||||
public function usingEloquent($builder)
|
||||
{
|
||||
return new EloquentEngine($builder, $this->request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows api call without the "using" word.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $arguments
|
||||
* @return $this|mixed
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
$name = 'using' . ucfirst($name);
|
||||
|
||||
if (method_exists($this, $name)) {
|
||||
return call_user_func_array([$this, $name], $arguments);
|
||||
}
|
||||
|
||||
return trigger_error('Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get html builder class.
|
||||
*
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function getHtmlBuilder()
|
||||
{
|
||||
return app('Yajra\Datatables\Html\Builder');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get request object.
|
||||
*
|
||||
* @return \Yajra\Datatables\Request|static
|
||||
*/
|
||||
public function getRequest()
|
||||
{
|
||||
return $this->request;
|
||||
}
|
||||
}
|
@@ -1,144 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables;
|
||||
|
||||
use Collective\Html\HtmlServiceProvider;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use League\Fractal\Manager;
|
||||
use League\Fractal\Serializer\DataArraySerializer;
|
||||
use Maatwebsite\Excel\ExcelServiceProvider;
|
||||
use Yajra\Datatables\Generators\DataTablesMakeCommand;
|
||||
use Yajra\Datatables\Generators\DataTablesScopeCommand;
|
||||
|
||||
/**
|
||||
* Class DatatablesServiceProvider.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DatatablesServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Indicates if loading of the provider is deferred.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $defer = false;
|
||||
|
||||
/**
|
||||
* Bootstrap the application events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->loadViewsFrom(__DIR__ . '/resources/views', 'datatables');
|
||||
|
||||
$this->publishAssets();
|
||||
|
||||
$this->registerCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* Publish datatables assets.
|
||||
*/
|
||||
protected function publishAssets()
|
||||
{
|
||||
$this->publishes([
|
||||
__DIR__ . '/config/config.php' => config_path('datatables.php'),
|
||||
], 'datatables');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/resources/assets/buttons.server-side.js' => public_path('vendor/datatables/buttons.server-side.js'),
|
||||
], 'datatables');
|
||||
|
||||
$this->publishes([
|
||||
__DIR__ . '/resources/views' => base_path('/resources/views/vendor/datatables'),
|
||||
], 'datatables');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register datatables commands.
|
||||
*/
|
||||
protected function registerCommands()
|
||||
{
|
||||
$this->commands(DataTablesMakeCommand::class);
|
||||
$this->commands(DataTablesScopeCommand::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
if ($this->isLumen()) {
|
||||
require_once 'fallback.php';
|
||||
}
|
||||
|
||||
$this->registerRequiredProviders();
|
||||
|
||||
$this->app->singleton('datatables', function () {
|
||||
return new Datatables($this->app->make(Request::class));
|
||||
});
|
||||
|
||||
$this->app->singleton('datatables.fractal', function () {
|
||||
$fractal = new Manager;
|
||||
$config = $this->app['config'];
|
||||
$request = $this->app['request'];
|
||||
|
||||
$includesKey = $config->get('datatables.fractal.includes', 'include');
|
||||
if ($request->get($includesKey)) {
|
||||
$fractal->parseIncludes($request->get($includesKey));
|
||||
}
|
||||
|
||||
$serializer = $config->get('datatables.fractal.serializer', DataArraySerializer::class);
|
||||
$fractal->setSerializer(new $serializer);
|
||||
|
||||
return $fractal;
|
||||
});
|
||||
|
||||
$this->registerAliases();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if app uses Lumen.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isLumen()
|
||||
{
|
||||
return str_contains($this->app->version(), 'Lumen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Register 3rd party providers.
|
||||
*/
|
||||
protected function registerRequiredProviders()
|
||||
{
|
||||
$this->app->register(HtmlServiceProvider::class);
|
||||
$this->app->register(ExcelServiceProvider::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create aliases for the dependency.
|
||||
*/
|
||||
protected function registerAliases()
|
||||
{
|
||||
if (class_exists('Illuminate\Foundation\AliasLoader')) {
|
||||
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
|
||||
$loader->alias('Datatables', \Yajra\Datatables\Facades\Datatables::class);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function provides()
|
||||
{
|
||||
return ['datatables'];
|
||||
}
|
||||
}
|
218
vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php
vendored
Normal file
218
vendor/yajra/laravel-datatables-oracle/src/EloquentDataTable.php
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use Yajra\DataTables\Exceptions\Exception;
|
||||
|
||||
class EloquentDataTable extends QueryDataTable
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return $source instanceof Builder || $source instanceof Relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* EloquentEngine constructor.
|
||||
*
|
||||
* @param mixed $model
|
||||
*/
|
||||
public function __construct($model)
|
||||
{
|
||||
$builder = $model instanceof Builder ? $model : $model->getQuery();
|
||||
parent::__construct($builder->getQuery());
|
||||
|
||||
$this->query = $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add columns in collection.
|
||||
*
|
||||
* @param array $names
|
||||
* @param bool|int $order
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumns(array $names, $order = false)
|
||||
{
|
||||
foreach ($names as $name => $attribute) {
|
||||
if (is_int($name)) {
|
||||
$name = $attribute;
|
||||
}
|
||||
|
||||
$this->addColumn($name, function ($model) use ($attribute) {
|
||||
return $model->getAttribute($attribute);
|
||||
}, is_int($order) ? $order++ : $order);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If column name could not be resolved then use primary key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPrimaryKeyName()
|
||||
{
|
||||
return $this->query->getModel()->getKeyName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile query builder where clause depending on configurations.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $columnName
|
||||
* @param string $keyword
|
||||
* @param string $boolean
|
||||
*/
|
||||
protected function compileQuerySearch($query, $columnName, $keyword, $boolean = 'or')
|
||||
{
|
||||
$parts = explode('.', $columnName);
|
||||
$column = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
|
||||
if ($this->isNotEagerLoaded($relation)) {
|
||||
return parent::compileQuerySearch($query, $columnName, $keyword, $boolean);
|
||||
}
|
||||
|
||||
$query->{$boolean . 'WhereHas'}($relation, function (Builder $query) use ($column, $keyword) {
|
||||
parent::compileQuerySearch($query, $column, $keyword, '');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the proper column name be used.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function resolveRelationColumn($column)
|
||||
{
|
||||
$parts = explode('.', $column);
|
||||
$columnName = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
|
||||
if ($this->isNotEagerLoaded($relation)) {
|
||||
return $column;
|
||||
}
|
||||
|
||||
return $this->joinEagerLoadedColumn($relation, $columnName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a relation was not used on eager loading.
|
||||
*
|
||||
* @param string $relation
|
||||
* @return bool
|
||||
*/
|
||||
protected function isNotEagerLoaded($relation)
|
||||
{
|
||||
return ! $relation
|
||||
|| ! array_key_exists($relation, $this->query->getEagerLoads())
|
||||
|| $relation === $this->query->getModel()->getTable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join eager loaded relation and get the related column name.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param string $relationColumn
|
||||
* @return string
|
||||
* @throws \Yajra\DataTables\Exceptions\Exception
|
||||
*/
|
||||
protected function joinEagerLoadedColumn($relation, $relationColumn)
|
||||
{
|
||||
$table = '';
|
||||
$lastQuery = $this->query;
|
||||
foreach (explode('.', $relation) as $eachRelation) {
|
||||
$model = $lastQuery->getRelation($eachRelation);
|
||||
switch (true) {
|
||||
case $model instanceof BelongsToMany:
|
||||
$pivot = $model->getTable();
|
||||
$pivotPK = $model->getExistenceCompareKey();
|
||||
$pivotFK = $model->getQualifiedParentKeyName();
|
||||
$this->performJoin($pivot, $pivotPK, $pivotFK);
|
||||
|
||||
$related = $model->getRelated();
|
||||
$table = $related->getTable();
|
||||
$tablePK = $related->getForeignKey();
|
||||
$foreign = $pivot . '.' . $tablePK;
|
||||
$other = $related->getQualifiedKeyName();
|
||||
|
||||
$lastQuery->addSelect($table . '.' . $relationColumn);
|
||||
$this->performJoin($table, $foreign, $other);
|
||||
|
||||
break;
|
||||
|
||||
case $model instanceof HasOneThrough:
|
||||
$pivot = explode('.', $model->getQualifiedParentKeyName())[0]; // extract pivot table from key
|
||||
$pivotPK = $pivot . '.' . $model->getLocalKeyName();
|
||||
$pivotFK = $model->getQualifiedLocalKeyName();
|
||||
$this->performJoin($pivot, $pivotPK, $pivotFK);
|
||||
|
||||
$related = $model->getRelated();
|
||||
$table = $related->getTable();
|
||||
$tablePK = $related->getForeignKey();
|
||||
$foreign = $pivot . '.' . $tablePK;
|
||||
$other = $related->getQualifiedKeyName();
|
||||
|
||||
break;
|
||||
|
||||
case $model instanceof HasOneOrMany:
|
||||
$table = $model->getRelated()->getTable();
|
||||
$foreign = $model->getQualifiedForeignKeyName();
|
||||
$other = $model->getQualifiedParentKeyName();
|
||||
break;
|
||||
|
||||
case $model instanceof BelongsTo:
|
||||
$table = $model->getRelated()->getTable();
|
||||
$foreign = $model->getQualifiedForeignKeyName();
|
||||
$other = $model->getQualifiedOwnerKeyName();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception('Relation ' . get_class($model) . ' is not yet supported.');
|
||||
}
|
||||
$this->performJoin($table, $foreign, $other);
|
||||
$lastQuery = $model->getQuery();
|
||||
}
|
||||
|
||||
return $table . '.' . $relationColumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform join query.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $foreign
|
||||
* @param string $other
|
||||
* @param string $type
|
||||
*/
|
||||
protected function performJoin($table, $foreign, $other, $type = 'left')
|
||||
{
|
||||
$joins = [];
|
||||
foreach ((array) $this->getBaseQueryBuilder()->joins as $key => $join) {
|
||||
$joins[] = $join->table;
|
||||
}
|
||||
|
||||
if (! in_array($table, $joins)) {
|
||||
$this->getBaseQueryBuilder()->join($table, $foreign, '=', $other, $type);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,967 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Engines;
|
||||
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Str;
|
||||
use League\Fractal\Resource\Collection;
|
||||
use Yajra\Datatables\Contracts\DataTableEngineContract;
|
||||
use Yajra\Datatables\Helper;
|
||||
use Yajra\Datatables\Processors\DataProcessor;
|
||||
|
||||
/**
|
||||
* Class BaseEngine.
|
||||
*
|
||||
* @package Yajra\Datatables\Engines
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
abstract class BaseEngine implements DataTableEngineContract
|
||||
{
|
||||
/**
|
||||
* Datatables Request object.
|
||||
*
|
||||
* @var \Yajra\Datatables\Request
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* Database connection used.
|
||||
*
|
||||
* @var \Illuminate\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* Builder object.
|
||||
*
|
||||
* @var \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* Query builder object.
|
||||
*
|
||||
* @var \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected $builder;
|
||||
|
||||
/**
|
||||
* Array of result columns/fields.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columns = [];
|
||||
|
||||
/**
|
||||
* DT columns definitions container (add/edit/remove/filter/order/escape).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $columnDef = [
|
||||
'index' => false,
|
||||
'append' => [],
|
||||
'edit' => [],
|
||||
'excess' => ['rn', 'row_num'],
|
||||
'filter' => [],
|
||||
'order' => [],
|
||||
'escape' => [],
|
||||
'blacklist' => ['password', 'remember_token'],
|
||||
'whitelist' => '*',
|
||||
];
|
||||
|
||||
/**
|
||||
* Query type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $query_type;
|
||||
|
||||
/**
|
||||
* Extra/Added columns.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $extraColumns = [];
|
||||
|
||||
/**
|
||||
* Total records.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $totalRecords = 0;
|
||||
|
||||
/**
|
||||
* Total filtered records.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $filteredRecords = 0;
|
||||
|
||||
/**
|
||||
* Auto-filter flag.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoFilter = true;
|
||||
|
||||
/**
|
||||
* Callback to override global search.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $filterCallback;
|
||||
|
||||
/**
|
||||
* Parameters to passed on filterCallback.
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
protected $filterCallbackParameters;
|
||||
|
||||
/**
|
||||
* DT row templates container.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $templates = [
|
||||
'DT_RowId' => '',
|
||||
'DT_RowClass' => '',
|
||||
'DT_RowData' => [],
|
||||
'DT_RowAttr' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* Output transformer.
|
||||
*
|
||||
* @var \League\Fractal\TransformerAbstract
|
||||
*/
|
||||
protected $transformer = null;
|
||||
|
||||
/**
|
||||
* Database prefix
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $prefix;
|
||||
|
||||
/**
|
||||
* Database driver used.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $database;
|
||||
|
||||
/**
|
||||
* [internal] Track if any filter was applied for at least one column
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $isFilterApplied = false;
|
||||
|
||||
/**
|
||||
* Fractal serializer class.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $serializer = null;
|
||||
|
||||
/**
|
||||
* Custom ordering callback.
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
protected $orderCallback;
|
||||
|
||||
/**
|
||||
* Array of data to append on json response.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $appends = [];
|
||||
|
||||
/**
|
||||
* Setup search keyword.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function setupKeyword($value)
|
||||
{
|
||||
if ($this->isSmartSearch()) {
|
||||
$keyword = '%' . $value . '%';
|
||||
if ($this->isWildcard()) {
|
||||
$keyword = $this->wildcardLikeString($value);
|
||||
}
|
||||
// remove escaping slash added on js script request
|
||||
$keyword = str_replace('\\', '%', $keyword);
|
||||
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables uses smart search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isSmartSearch()
|
||||
{
|
||||
return Config::get('datatables.search.smart', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config use wild card status.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWildcard()
|
||||
{
|
||||
return Config::get('datatables.search.use_wildcards', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds % wildcards to the given string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param bool $lowercase
|
||||
* @return string
|
||||
*/
|
||||
public function wildcardLikeString($str, $lowercase = true)
|
||||
{
|
||||
$wild = '%';
|
||||
$length = Str::length($str);
|
||||
if ($length) {
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$wild .= $str[$i] . '%';
|
||||
}
|
||||
}
|
||||
if ($lowercase) {
|
||||
$wild = Str::lower($wild);
|
||||
}
|
||||
|
||||
return $wild;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will prefix column if needed.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public function prefixColumn($column)
|
||||
{
|
||||
$table_names = $this->tableNames();
|
||||
if (count(
|
||||
array_filter($table_names, function ($value) use (&$column) {
|
||||
return strpos($column, $value . '.') === 0;
|
||||
})
|
||||
)) {
|
||||
// the column starts with one of the table names
|
||||
$column = $this->prefix . $column;
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Will look through the query and all it's joins to determine the table names.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function tableNames()
|
||||
{
|
||||
$names = [];
|
||||
$query = $this->getQueryBuilder();
|
||||
$names[] = $query->from;
|
||||
$joins = $query->joins ?: [];
|
||||
$databasePrefix = $this->prefix;
|
||||
foreach ($joins as $join) {
|
||||
$table = preg_split('/ as /i', $join->table);
|
||||
$names[] = $table[0];
|
||||
if (isset($table[1]) && ! empty($databasePrefix) && strpos($table[1], $databasePrefix) == 0) {
|
||||
$names[] = preg_replace('/^' . $databasePrefix . '/', '', $table[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Query Builder object.
|
||||
*
|
||||
* @param mixed $instance
|
||||
* @return mixed
|
||||
*/
|
||||
public function getQueryBuilder($instance = null)
|
||||
{
|
||||
if (! $instance) {
|
||||
$instance = $this->query;
|
||||
}
|
||||
|
||||
if ($this->isQueryBuilder()) {
|
||||
return $instance;
|
||||
}
|
||||
|
||||
return $instance->getQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check query type is a builder.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isQueryBuilder()
|
||||
{
|
||||
return $this->query_type == 'builder';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add column in collection.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @param bool|int $order
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumn($name, $content, $order = false)
|
||||
{
|
||||
$this->extraColumns[] = $name;
|
||||
|
||||
$this->columnDef['append'][] = ['name' => $name, 'content' => $content, 'order' => $order];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT row index column on response.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addIndexColumn()
|
||||
{
|
||||
$this->columnDef['index'] = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit column's content.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function editColumn($name, $content)
|
||||
{
|
||||
$this->columnDef['edit'][] = ['name' => $name, 'content' => $content];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove column from collection.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function removeColumn()
|
||||
{
|
||||
$names = func_get_args();
|
||||
$this->columnDef['excess'] = array_merge($this->columnDef['excess'], $names);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Declare columns to escape values.
|
||||
*
|
||||
* @param string|array $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function escapeColumns($columns = '*')
|
||||
{
|
||||
$this->columnDef['escape'] = $columns;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows previous API calls where the methods were snake_case.
|
||||
* Will convert a camelCase API call to a snake_case call.
|
||||
* Allow query builder method to be used by the engine.
|
||||
*
|
||||
* @param string $name
|
||||
* @param array $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
$name = Str::camel(Str::lower($name));
|
||||
if (method_exists($this, $name)) {
|
||||
return call_user_func_array([$this, $name], $arguments);
|
||||
} elseif (method_exists($this->getQueryBuilder(), $name)) {
|
||||
call_user_func_array([$this->getQueryBuilder(), $name], $arguments);
|
||||
} else {
|
||||
trigger_error('Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets DT_RowClass template.
|
||||
* result: <tr class="output_from_your_template">.
|
||||
*
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowClass($content)
|
||||
{
|
||||
$this->templates['DT_RowClass'] = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets DT_RowId template.
|
||||
* result: <tr id="output_from_your_template">.
|
||||
*
|
||||
* @param string|callable $content
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowId($content)
|
||||
{
|
||||
$this->templates['DT_RowId'] = $content;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DT_RowData templates.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowData(array $data)
|
||||
{
|
||||
$this->templates['DT_RowData'] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT_RowData template.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function addRowData($key, $value)
|
||||
{
|
||||
$this->templates['DT_RowData'][$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set DT_RowAttr templates.
|
||||
* result: <tr attr1="attr1" attr2="attr2">.
|
||||
*
|
||||
* @param array $data
|
||||
* @return $this
|
||||
*/
|
||||
public function setRowAttr(array $data)
|
||||
{
|
||||
$this->templates['DT_RowAttr'] = $data;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add DT_RowAttr template.
|
||||
*
|
||||
* @param string $key
|
||||
* @param string|callable $value
|
||||
* @return $this
|
||||
*/
|
||||
public function addRowAttr($key, $value)
|
||||
{
|
||||
$this->templates['DT_RowAttr'][$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default column filter search.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string|Closure $method
|
||||
* @return $this
|
||||
* @internal param $mixed ...,... All the individual parameters required for specified $method
|
||||
* @internal string $1 Special variable that returns the requested search keyword.
|
||||
*/
|
||||
public function filterColumn($column, $method)
|
||||
{
|
||||
$params = func_get_args();
|
||||
$this->columnDef['filter'][$column] = ['method' => $method, 'parameters' => array_splice($params, 2)];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order each given columns versus the given custom sql.
|
||||
*
|
||||
* @param array $columns
|
||||
* @param string $sql
|
||||
* @param array $bindings
|
||||
* @return $this
|
||||
*/
|
||||
public function orderColumns(array $columns, $sql, $bindings = [])
|
||||
{
|
||||
foreach ($columns as $column) {
|
||||
$this->orderColumn($column, str_replace(':column', $column, $sql), $bindings);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default column ordering.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $sql
|
||||
* @param array $bindings
|
||||
* @return $this
|
||||
* @internal string $1 Special variable that returns the requested order direction of the column.
|
||||
*/
|
||||
public function orderColumn($column, $sql, $bindings = [])
|
||||
{
|
||||
$this->columnDef['order'][$column] = ['method' => 'orderByRaw', 'parameters' => [$sql, $bindings]];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data output transformer.
|
||||
*
|
||||
* @param \League\Fractal\TransformerAbstract $transformer
|
||||
* @return $this
|
||||
*/
|
||||
public function setTransformer($transformer)
|
||||
{
|
||||
$this->transformer = $transformer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set fractal serializer class.
|
||||
*
|
||||
* @param string $serializer
|
||||
* @return $this
|
||||
*/
|
||||
public function setSerializer($serializer)
|
||||
{
|
||||
$this->serializer = $serializer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @param bool $orderFirst
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = false, $orderFirst = false)
|
||||
{
|
||||
$this->totalRecords = $this->totalCount();
|
||||
|
||||
if ($this->totalRecords) {
|
||||
$this->orderRecords(! $orderFirst);
|
||||
$this->filterRecords();
|
||||
$this->orderRecords($orderFirst);
|
||||
$this->paginate();
|
||||
}
|
||||
|
||||
return $this->render($mDataSupport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort records.
|
||||
*
|
||||
* @param boolean $skip
|
||||
* @return void
|
||||
*/
|
||||
public function orderRecords($skip)
|
||||
{
|
||||
if (! $skip) {
|
||||
$this->ordering();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform necessary filters.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filterRecords()
|
||||
{
|
||||
if ($this->autoFilter && $this->request->isSearchable()) {
|
||||
$this->filtering();
|
||||
}
|
||||
|
||||
if (is_callable($this->filterCallback)) {
|
||||
call_user_func($this->filterCallback, $this->filterCallbackParameters);
|
||||
}
|
||||
|
||||
$this->columnSearch();
|
||||
$this->filteredRecords = $this->isFilterApplied ? $this->count() : $this->totalRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paginate()
|
||||
{
|
||||
if ($this->request->isPaginationable()) {
|
||||
$this->paging();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render json response.
|
||||
*
|
||||
* @param bool $object
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function render($object = false)
|
||||
{
|
||||
$output = array_merge([
|
||||
'draw' => (int) $this->request['draw'],
|
||||
'recordsTotal' => $this->totalRecords,
|
||||
'recordsFiltered' => $this->filteredRecords,
|
||||
], $this->appends);
|
||||
|
||||
if (isset($this->transformer)) {
|
||||
$fractal = app('datatables.fractal');
|
||||
|
||||
if ($this->serializer) {
|
||||
$fractal->setSerializer(new $this->serializer);
|
||||
}
|
||||
|
||||
//Get transformer reflection
|
||||
//Firs method parameter should be data/object to transform
|
||||
$reflection = new \ReflectionMethod($this->transformer, 'transform');
|
||||
$parameter = $reflection->getParameters()[0];
|
||||
|
||||
//If parameter is class assuming it requires object
|
||||
//Else just pass array by default
|
||||
if ($parameter->getClass()) {
|
||||
$resource = new Collection($this->results(), $this->createTransformer());
|
||||
} else {
|
||||
$resource = new Collection(
|
||||
$this->getProcessedData($object),
|
||||
$this->createTransformer()
|
||||
);
|
||||
}
|
||||
|
||||
$collection = $fractal->createData($resource)->toArray();
|
||||
$output['data'] = $collection['data'];
|
||||
} else {
|
||||
$output['data'] = Helper::transform($this->getProcessedData($object));
|
||||
}
|
||||
|
||||
if ($this->isDebugging()) {
|
||||
$output = $this->showDebugger($output);
|
||||
}
|
||||
|
||||
return new JsonResponse($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create transformer instance.
|
||||
*
|
||||
* @return \League\Fractal\TransformerAbstract
|
||||
*/
|
||||
protected function createTransformer()
|
||||
{
|
||||
if ($this->transformer instanceof \League\Fractal\TransformerAbstract) {
|
||||
return $this->transformer;
|
||||
}
|
||||
|
||||
return new $this->transformer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get processed data
|
||||
*
|
||||
* @param bool|false $object
|
||||
* @return array
|
||||
*/
|
||||
private function getProcessedData($object = false)
|
||||
{
|
||||
$processor = new DataProcessor(
|
||||
$this->results(),
|
||||
$this->columnDef,
|
||||
$this->templates,
|
||||
$this->request['start']
|
||||
);
|
||||
|
||||
return $processor->process($object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if app is in debug mode.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDebugging()
|
||||
{
|
||||
return Config::get('app.debug', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append debug parameters on output.
|
||||
*
|
||||
* @param array $output
|
||||
* @return array
|
||||
*/
|
||||
public function showDebugger(array $output)
|
||||
{
|
||||
$output['queries'] = $this->connection->getQueryLog();
|
||||
$output['input'] = $this->request->all();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update flags to disable global search
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param mixed $parameters
|
||||
* @param bool $autoFilter
|
||||
*/
|
||||
public function overrideGlobalSearch(\Closure $callback, $parameters, $autoFilter = false)
|
||||
{
|
||||
$this->autoFilter = $autoFilter;
|
||||
$this->isFilterApplied = true;
|
||||
$this->filterCallback = $callback;
|
||||
$this->filterCallbackParameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config is case insensitive status.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCaseInsensitive()
|
||||
{
|
||||
return Config::get('datatables.search.case_insensitive', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data on json response.
|
||||
*
|
||||
* @param mixed $key
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function with($key, $value = '')
|
||||
{
|
||||
if (is_array($key)) {
|
||||
$this->appends = $key;
|
||||
} elseif (is_callable($value)) {
|
||||
$this->appends[$key] = value($value);
|
||||
} else {
|
||||
$this->appends[$key] = value($value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default ordering method with a closure callback.
|
||||
*
|
||||
* @param \Closure $closure
|
||||
* @return $this
|
||||
*/
|
||||
public function order(\Closure $closure)
|
||||
{
|
||||
$this->orderCallback = $closure;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update list of columns that is not allowed for search/sort.
|
||||
*
|
||||
* @param array $blacklist
|
||||
* @return $this
|
||||
*/
|
||||
public function blacklist(array $blacklist)
|
||||
{
|
||||
$this->columnDef['blacklist'] = $blacklist;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update list of columns that is not allowed for search/sort.
|
||||
*
|
||||
* @param string|array $whitelist
|
||||
* @return $this
|
||||
*/
|
||||
public function whitelist($whitelist = '*')
|
||||
{
|
||||
$this->columnDef['whitelist'] = $whitelist;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set smart search config at runtime.
|
||||
*
|
||||
* @param bool $bool
|
||||
* @return $this
|
||||
*/
|
||||
public function smart($bool = true)
|
||||
{
|
||||
Config::set('datatables.search.smart', $bool);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if column is blacklisted.
|
||||
*
|
||||
* @param string $column
|
||||
* @return bool
|
||||
*/
|
||||
protected function isBlacklisted($column)
|
||||
{
|
||||
if (in_array($column, $this->columnDef['blacklist'])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->columnDef['whitelist'] === '*' || in_array($column, $this->columnDef['whitelist'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name to be use for filtering and sorting.
|
||||
*
|
||||
* @param integer $index
|
||||
* @param bool $wantsAlias
|
||||
* @return string
|
||||
*/
|
||||
protected function getColumnName($index, $wantsAlias = false)
|
||||
{
|
||||
$column = $this->request->columnName($index);
|
||||
|
||||
// DataTables is using make(false)
|
||||
if (is_numeric($column)) {
|
||||
$column = $this->getColumnNameByIndex($index);
|
||||
}
|
||||
|
||||
if (Str::contains(Str::upper($column), ' AS ')) {
|
||||
$column = $this->extractColumnName($column, $wantsAlias);
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name by order column index.
|
||||
*
|
||||
* @param int $index
|
||||
* @return mixed
|
||||
*/
|
||||
protected function getColumnNameByIndex($index)
|
||||
{
|
||||
$name = isset($this->columns[$index]) && $this->columns[$index] <> '*' ? $this->columns[$index] : $this->getPrimaryKeyName();
|
||||
|
||||
return in_array($name, $this->extraColumns, true) ? $this->getPrimaryKeyName() : $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* If column name could not be resolved then use primary key.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getPrimaryKeyName()
|
||||
{
|
||||
if ($this->isEloquent()) {
|
||||
return $this->query->getModel()->getKeyName();
|
||||
}
|
||||
|
||||
return 'id';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the engine used was eloquent.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isEloquent()
|
||||
{
|
||||
return $this->query_type === 'eloquent';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name from string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param bool $wantsAlias
|
||||
* @return string
|
||||
*/
|
||||
protected function extractColumnName($str, $wantsAlias)
|
||||
{
|
||||
$matches = explode(' as ', Str::lower($str));
|
||||
|
||||
if (! empty($matches)) {
|
||||
if ($wantsAlias) {
|
||||
return array_pop($matches);
|
||||
} else {
|
||||
return array_shift($matches);
|
||||
}
|
||||
} elseif (strpos($str, '.')) {
|
||||
$array = explode('.', $str);
|
||||
|
||||
return array_pop($array);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current sql language is based on oracle syntax.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function isOracleSql()
|
||||
{
|
||||
return in_array($this->database, ['oracle', 'oci8']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set total records manually.
|
||||
*
|
||||
* @param int $total
|
||||
* @return $this
|
||||
*/
|
||||
public function setTotalRecords($total)
|
||||
{
|
||||
$this->totalRecords = $total;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@@ -1,235 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Engines;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
use Yajra\Datatables\Request;
|
||||
|
||||
/**
|
||||
* Class CollectionEngine.
|
||||
*
|
||||
* @package Yajra\Datatables\Engines
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class CollectionEngine extends BaseEngine
|
||||
{
|
||||
/**
|
||||
* Collection object
|
||||
*
|
||||
* @var \Illuminate\Support\Collection
|
||||
*/
|
||||
public $collection;
|
||||
|
||||
/**
|
||||
* Collection object
|
||||
*
|
||||
* @var \Illuminate\Support\Collection
|
||||
*/
|
||||
public $original_collection;
|
||||
|
||||
/**
|
||||
* CollectionEngine constructor.
|
||||
*
|
||||
* @param \Illuminate\Support\Collection $collection
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
*/
|
||||
public function __construct(Collection $collection, Request $request)
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->collection = $collection;
|
||||
$this->original_collection = $collection;
|
||||
$this->columns = array_keys($this->serialize($collection->first()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize collection
|
||||
*
|
||||
* @param mixed $collection
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function serialize($collection)
|
||||
{
|
||||
return $collection instanceof Arrayable ? $collection->toArray() : (array) $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set auto filter off and run your own filter.
|
||||
* Overrides global search.
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $globalSearch
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(Closure $callback, $globalSearch = false)
|
||||
{
|
||||
$this->overrideGlobalSearch($callback, $this, $globalSearch);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append debug parameters on output.
|
||||
*
|
||||
* @param array $output
|
||||
* @return array
|
||||
*/
|
||||
public function showDebugger(array $output)
|
||||
{
|
||||
$output["input"] = $this->request->all();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function totalCount()
|
||||
{
|
||||
return $this->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count results.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return $this->collection->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform sorting of columns.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ordering()
|
||||
{
|
||||
if ($this->orderCallback) {
|
||||
call_user_func($this->orderCallback, $this);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->request->orderableColumns() as $orderable) {
|
||||
$column = $this->getColumnName($orderable['column']);
|
||||
$this->collection = $this->collection->sortBy(
|
||||
function ($row) use ($column) {
|
||||
$data = $this->serialize($row);
|
||||
|
||||
return Arr::get($data, $column);
|
||||
}
|
||||
);
|
||||
|
||||
if ($orderable['direction'] == 'desc') {
|
||||
$this->collection = $this->collection->reverse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filtering()
|
||||
{
|
||||
$columns = $this->request['columns'];
|
||||
$this->collection = $this->collection->filter(
|
||||
function ($row) use ($columns) {
|
||||
$data = $this->serialize($row);
|
||||
$this->isFilterApplied = true;
|
||||
$found = [];
|
||||
|
||||
$keyword = $this->request->keyword();
|
||||
foreach ($this->request->searchableColumnIndex() as $index) {
|
||||
$column = $this->getColumnName($index);
|
||||
if (! $value = Arr::get($data, $column)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->isCaseInsensitive()) {
|
||||
$found[] = Str::contains(Str::lower($value), Str::lower($keyword));
|
||||
} else {
|
||||
$found[] = Str::contains($value, $keyword);
|
||||
}
|
||||
}
|
||||
|
||||
return in_array(true, $found);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform column search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function columnSearch()
|
||||
{
|
||||
$columns = $this->request->get('columns');
|
||||
for ($i = 0, $c = count($columns); $i < $c; $i++) {
|
||||
if ($this->request->isColumnSearchable($i)) {
|
||||
$this->isFilterApplied = true;
|
||||
|
||||
$column = $this->getColumnName($i);
|
||||
$keyword = $this->request->columnKeyword($i);
|
||||
|
||||
$this->collection = $this->collection->filter(
|
||||
function ($row) use ($column, $keyword) {
|
||||
$data = $this->serialize($row);
|
||||
|
||||
$value = Arr::get($data, $column);
|
||||
|
||||
if ($this->isCaseInsensitive()) {
|
||||
return strpos(Str::lower($value), Str::lower($keyword)) !== false;
|
||||
} else {
|
||||
return strpos($value, $keyword) !== false;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paging()
|
||||
{
|
||||
$this->collection = $this->collection->slice(
|
||||
$this->request['start'],
|
||||
(int) $this->request['length'] > 0 ? $this->request['length'] : 10
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get results.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function results()
|
||||
{
|
||||
return $this->collection->all();
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @param bool $orderFirst
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = false, $orderFirst = true)
|
||||
{
|
||||
return parent::make($mDataSupport, $orderFirst);
|
||||
}
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Engines;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Yajra\Datatables\Request;
|
||||
|
||||
/**
|
||||
* Class EloquentEngine.
|
||||
*
|
||||
* @package Yajra\Datatables\Engines
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class EloquentEngine extends QueryBuilderEngine
|
||||
{
|
||||
/**
|
||||
* @param mixed $model
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
*/
|
||||
public function __construct($model, Request $request)
|
||||
{
|
||||
$builder = $model instanceof Builder ? $model : $model->getQuery();
|
||||
parent::__construct($builder->getQuery(), $request);
|
||||
|
||||
$this->query = $builder;
|
||||
$this->query_type = 'eloquent';
|
||||
}
|
||||
}
|
@@ -1,535 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Engines;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Str;
|
||||
use Yajra\Datatables\Helper;
|
||||
use Yajra\Datatables\Request;
|
||||
|
||||
/**
|
||||
* Class QueryBuilderEngine.
|
||||
*
|
||||
* @package Yajra\Datatables\Engines
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class QueryBuilderEngine extends BaseEngine
|
||||
{
|
||||
/**
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
*/
|
||||
public function __construct(Builder $builder, Request $request)
|
||||
{
|
||||
$this->query = $builder;
|
||||
$this->init($request, $builder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize attributes.
|
||||
*
|
||||
* @param \Yajra\Datatables\Request $request
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
* @param string $type
|
||||
*/
|
||||
protected function init($request, $builder, $type = 'builder')
|
||||
{
|
||||
$this->request = $request;
|
||||
$this->query_type = $type;
|
||||
$this->columns = $builder->columns;
|
||||
$this->connection = $builder->getConnection();
|
||||
$this->prefix = $this->connection->getTablePrefix();
|
||||
$this->database = $this->connection->getDriverName();
|
||||
if ($this->isDebugging()) {
|
||||
$this->connection->enableQueryLog();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set auto filter off and run your own filter.
|
||||
* Overrides global search
|
||||
*
|
||||
* @param \Closure $callback
|
||||
* @param bool $globalSearch
|
||||
* @return $this
|
||||
*/
|
||||
public function filter(Closure $callback, $globalSearch = false)
|
||||
{
|
||||
$this->overrideGlobalSearch($callback, $this->query, $globalSearch);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @param bool $orderFirst
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function make($mDataSupport = false, $orderFirst = false)
|
||||
{
|
||||
return parent::make($mDataSupport, $orderFirst);
|
||||
}
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function totalCount()
|
||||
{
|
||||
return $this->totalRecords ? $this->totalRecords : $this->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts current query.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$myQuery = clone $this->query;
|
||||
// if its a normal query ( no union, having and distinct word )
|
||||
// replace the select with static text to improve performance
|
||||
if (! Str::contains(Str::lower($myQuery->toSql()), ['union', 'having', 'distinct', 'order by', 'group by'])) {
|
||||
$row_count = $this->wrap('row_count');
|
||||
$myQuery->select($this->connection->raw("'1' as {$row_count}"));
|
||||
}
|
||||
|
||||
return $this->connection->table($this->connection->raw('(' . $myQuery->toSql() . ') count_row_table'))
|
||||
->setBindings($myQuery->getBindings())->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap column with DB grammar.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function wrap($column) {
|
||||
return $this->connection->getQueryGrammar()->wrap($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filtering()
|
||||
{
|
||||
$this->query->where(
|
||||
function ($query) {
|
||||
$globalKeyword = $this->request->keyword();
|
||||
$queryBuilder = $this->getQueryBuilder($query);
|
||||
|
||||
foreach ($this->request->searchableColumnIndex() as $index) {
|
||||
$columnName = $this->getColumnName($index);
|
||||
if ($this->isBlacklisted($columnName)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check if custom column filtering is applied
|
||||
if (isset($this->columnDef['filter'][$columnName])) {
|
||||
$columnDef = $this->columnDef['filter'][$columnName];
|
||||
// check if global search should be applied for the specific column
|
||||
$applyGlobalSearch = count($columnDef['parameters']) == 0 || end($columnDef['parameters']) !== false;
|
||||
if (! $applyGlobalSearch) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($columnDef['method'] instanceof Closure) {
|
||||
$whereQuery = $queryBuilder->newQuery();
|
||||
call_user_func_array($columnDef['method'], [$whereQuery, $globalKeyword]);
|
||||
$queryBuilder->addNestedWhereQuery($whereQuery, 'or');
|
||||
} else {
|
||||
$this->compileColumnQuery(
|
||||
$queryBuilder,
|
||||
Helper::getOrMethod($columnDef['method']),
|
||||
$columnDef['parameters'],
|
||||
$columnName,
|
||||
$globalKeyword
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (count(explode('.', $columnName)) > 1) {
|
||||
$eagerLoads = $this->getEagerLoads();
|
||||
$parts = explode('.', $columnName);
|
||||
$relationColumn = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
if (in_array($relation, $eagerLoads)) {
|
||||
$this->compileRelationSearch(
|
||||
$queryBuilder,
|
||||
$relation,
|
||||
$relationColumn,
|
||||
$globalKeyword
|
||||
);
|
||||
} else {
|
||||
$this->compileQuerySearch($queryBuilder, $columnName, $globalKeyword);
|
||||
}
|
||||
} else {
|
||||
$this->compileQuerySearch($queryBuilder, $columnName, $globalKeyword);
|
||||
}
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform filter column on selected field.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string|Closure $method
|
||||
* @param mixed $parameters
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function compileColumnQuery($query, $method, $parameters, $column, $keyword)
|
||||
{
|
||||
if (method_exists($query, $method)
|
||||
&& count($parameters) <= with(new \ReflectionMethod($query, $method))->getNumberOfParameters()
|
||||
) {
|
||||
if (Str::contains(Str::lower($method), 'raw')
|
||||
|| Str::contains(Str::lower($method), 'exists')
|
||||
) {
|
||||
call_user_func_array(
|
||||
[$query, $method],
|
||||
$this->parameterize($parameters, $keyword)
|
||||
);
|
||||
} else {
|
||||
call_user_func_array(
|
||||
[$query, $method],
|
||||
$this->parameterize($column, $parameters, $keyword)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Query Builder Parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function parameterize()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$keyword = count($args) > 2 ? $args[2] : $args[1];
|
||||
$parameters = Helper::buildParameters($args);
|
||||
$parameters = Helper::replacePatternWithKeyword($parameters, $keyword, '$1');
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get eager loads keys if eloquent.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getEagerLoads()
|
||||
{
|
||||
if ($this->query_type == 'eloquent') {
|
||||
return array_keys($this->query->getEagerLoads());
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add relation query on global search.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $relation
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function compileRelationSearch($query, $relation, $column, $keyword)
|
||||
{
|
||||
$myQuery = clone $this->query;
|
||||
$myQuery->orWhereHas($relation, function ($builder) use ($column, $keyword, $query) {
|
||||
$builder->select($this->connection->raw('count(1)'));
|
||||
$this->compileQuerySearch($builder, $column, $keyword, '');
|
||||
$builder = "({$builder->toSql()}) >= 1";
|
||||
|
||||
$query->orWhereRaw($builder, [$keyword]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile query builder where clause depending on configurations.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
* @param string $relation
|
||||
*/
|
||||
protected function compileQuerySearch($query, $column, $keyword, $relation = 'or')
|
||||
{
|
||||
$column = strstr($column, '(') ? $this->connection->raw($column) : $column;
|
||||
$column = $this->castColumn($column);
|
||||
$sql = $column . ' LIKE ?';
|
||||
|
||||
if ($this->isCaseInsensitive()) {
|
||||
$sql = 'LOWER(' . $column . ') LIKE ?';
|
||||
$keyword = Str::lower($keyword);
|
||||
}
|
||||
|
||||
if ($this->isWildcard()) {
|
||||
$keyword = $this->wildcardLikeString($keyword);
|
||||
}
|
||||
|
||||
if ($this->isSmartSearch()) {
|
||||
$keyword = "%$keyword%";
|
||||
}
|
||||
|
||||
$query->{$relation .'WhereRaw'}($sql, [$keyword]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a column and cast in pgsql.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public function castColumn($column)
|
||||
{
|
||||
$column = $this->wrap($column);
|
||||
if ($this->database === 'pgsql') {
|
||||
$column = 'CAST(' . $column . ' as TEXT)';
|
||||
} elseif ($this->database === 'firebird') {
|
||||
$column = 'CAST(' . $column . ' as VARCHAR(255))';
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform column search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function columnSearch()
|
||||
{
|
||||
$columns = $this->request->get('columns', []);
|
||||
|
||||
foreach ($columns as $index => $column) {
|
||||
if (! $this->request->isColumnSearchable($index)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$column = $this->getColumnName($index);
|
||||
|
||||
if (isset($this->columnDef['filter'][$column])) {
|
||||
$columnDef = $this->columnDef['filter'][$column];
|
||||
// get a raw keyword (without wildcards)
|
||||
$keyword = $this->getSearchKeyword($index, true);
|
||||
$builder = $this->getQueryBuilder();
|
||||
|
||||
if ($columnDef['method'] instanceof Closure) {
|
||||
$whereQuery = $builder->newQuery();
|
||||
call_user_func_array($columnDef['method'], [$whereQuery, $keyword]);
|
||||
$builder->addNestedWhereQuery($whereQuery);
|
||||
} else {
|
||||
$this->compileColumnQuery(
|
||||
$builder,
|
||||
$columnDef['method'],
|
||||
$columnDef['parameters'],
|
||||
$column,
|
||||
$keyword
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (count(explode('.', $column)) > 1) {
|
||||
$eagerLoads = $this->getEagerLoads();
|
||||
$parts = explode('.', $column);
|
||||
$relationColumn = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
if (in_array($relation, $eagerLoads)) {
|
||||
$column = $this->joinEagerLoadedColumn($relation, $relationColumn);
|
||||
}
|
||||
}
|
||||
|
||||
$keyword = $this->getSearchKeyword($index);
|
||||
$this->compileColumnSearch($index, $column, $keyword);
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get proper keyword to use for search.
|
||||
*
|
||||
* @param int $i
|
||||
* @param bool $raw
|
||||
* @return string
|
||||
*/
|
||||
private function getSearchKeyword($i, $raw = false)
|
||||
{
|
||||
$keyword = $this->request->columnKeyword($i);
|
||||
if ($raw || $this->request->isRegex($i)) {
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
return $this->setupKeyword($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile queries for column search.
|
||||
*
|
||||
* @param int $i
|
||||
* @param mixed $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function compileColumnSearch($i, $column, $keyword)
|
||||
{
|
||||
if ($this->request->isRegex($i)) {
|
||||
$column = strstr($column, '(') ? $this->connection->raw($column) : $column;
|
||||
$this->regexColumnSearch($column, $keyword);
|
||||
} else {
|
||||
$this->compileQuerySearch($this->query, $column, $keyword, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile regex query column search.
|
||||
*
|
||||
* @param mixed $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function regexColumnSearch($column, $keyword)
|
||||
{
|
||||
if ($this->isOracleSql()) {
|
||||
$sql = ! $this->isCaseInsensitive() ? 'REGEXP_LIKE( ' . $column . ' , ? )' : 'REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )';
|
||||
$this->query->whereRaw($sql, [$keyword]);
|
||||
} else {
|
||||
$sql = ! $this->isCaseInsensitive() ? $column . ' REGEXP ?' : 'LOWER(' . $column . ') REGEXP ?';
|
||||
$this->query->whereRaw($sql, [Str::lower($keyword)]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform sorting of columns.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ordering()
|
||||
{
|
||||
if ($this->orderCallback) {
|
||||
call_user_func($this->orderCallback, $this->getQueryBuilder());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($this->request->orderableColumns() as $orderable) {
|
||||
$column = $this->getColumnName($orderable['column'], true);
|
||||
|
||||
if ($this->isBlacklisted($column)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($this->columnDef['order'][$column])) {
|
||||
$method = $this->columnDef['order'][$column]['method'];
|
||||
$parameters = $this->columnDef['order'][$column]['parameters'];
|
||||
$this->compileColumnQuery(
|
||||
$this->getQueryBuilder(),
|
||||
$method,
|
||||
$parameters,
|
||||
$column,
|
||||
$orderable['direction']
|
||||
);
|
||||
} else {
|
||||
if (count(explode('.', $column)) > 1) {
|
||||
$eagerLoads = $this->getEagerLoads();
|
||||
$parts = explode('.', $column);
|
||||
$relationColumn = array_pop($parts);
|
||||
$relation = implode('.', $parts);
|
||||
|
||||
if (in_array($relation, $eagerLoads)) {
|
||||
$column = $this->joinEagerLoadedColumn($relation, $relationColumn);
|
||||
}
|
||||
}
|
||||
|
||||
$this->getQueryBuilder()->orderBy($column, $orderable['direction']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Join eager loaded relation and get the related column name.
|
||||
*
|
||||
* @param string $relation
|
||||
* @param string $relationColumn
|
||||
* @return string
|
||||
*/
|
||||
protected function joinEagerLoadedColumn($relation, $relationColumn)
|
||||
{
|
||||
$joins = [];
|
||||
foreach ((array) $this->getQueryBuilder()->joins as $key => $join) {
|
||||
$joins[] = $join->table;
|
||||
}
|
||||
|
||||
$model = $this->query->getRelation($relation);
|
||||
if ($model instanceof BelongsToMany) {
|
||||
$pivot = $model->getTable();
|
||||
$pivotPK = $model->getForeignKey();
|
||||
$pivotFK = $model->getQualifiedParentKeyName();
|
||||
|
||||
if (! in_array($pivot, $joins)) {
|
||||
$this->getQueryBuilder()->leftJoin($pivot, $pivotPK, '=', $pivotFK);
|
||||
}
|
||||
|
||||
$related = $model->getRelated();
|
||||
$table = $related->getTable();
|
||||
$tablePK = $related->getForeignKey();
|
||||
$tableFK = $related->getQualifiedKeyName();
|
||||
|
||||
if (! in_array($table, $joins)) {
|
||||
$this->getQueryBuilder()->leftJoin($table, $pivot . '.' . $tablePK, '=', $tableFK);
|
||||
}
|
||||
} else {
|
||||
$table = $model->getRelated()->getTable();
|
||||
if ($model instanceof HasOne) {
|
||||
$foreign = $model->getForeignKey();
|
||||
$other = $model->getQualifiedParentKeyName();
|
||||
} else {
|
||||
$foreign = $model->getQualifiedForeignKey();
|
||||
$other = $model->getQualifiedOtherKeyName();
|
||||
}
|
||||
|
||||
if (! in_array($table, $joins)) {
|
||||
$this->getQueryBuilder()->leftJoin($table, $foreign, '=', $other);
|
||||
}
|
||||
}
|
||||
|
||||
$column = $table . '.' . $relationColumn;
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pagination
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paging()
|
||||
{
|
||||
$this->query->skip($this->request['start'])
|
||||
->take((int) $this->request['length'] > 0 ? $this->request['length'] : 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get results
|
||||
*
|
||||
* @return array|static[]
|
||||
*/
|
||||
public function results()
|
||||
{
|
||||
return $this->query->get();
|
||||
}
|
||||
}
|
7
vendor/yajra/laravel-datatables-oracle/src/Exceptions/Exception.php
vendored
Normal file
7
vendor/yajra/laravel-datatables-oracle/src/Exceptions/Exception.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables\Exceptions;
|
||||
|
||||
class Exception extends \Exception
|
||||
{
|
||||
}
|
26
vendor/yajra/laravel-datatables-oracle/src/Facades/DataTables.php
vendored
Normal file
26
vendor/yajra/laravel-datatables-oracle/src/Facades/DataTables.php
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* @mixin \Yajra\DataTables\DataTables
|
||||
* @method static \Yajra\DataTables\EloquentDatatable eloquent($builder)
|
||||
* @method static \Yajra\DataTables\QueryDataTable query($builder)
|
||||
* @method static \Yajra\DataTables\CollectionDataTable collection($collection)
|
||||
*
|
||||
* @see \Yajra\DataTables\DataTables
|
||||
*/
|
||||
class DataTables extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'datatables';
|
||||
}
|
||||
}
|
@@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* Class Datatables.
|
||||
*
|
||||
* @package Yajra\Datatables\Facades
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Datatables extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'datatables';
|
||||
}
|
||||
}
|
@@ -1,208 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Generators;
|
||||
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
/**
|
||||
* Class DataTablesMakeCommand.
|
||||
*
|
||||
* @package Yajra\Datatables\Generators
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DataTablesMakeCommand extends GeneratorCommand
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'datatables:make';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a new DataTable service class.';
|
||||
|
||||
/**
|
||||
* The type of class being generated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = 'DataTable';
|
||||
|
||||
/**
|
||||
* The model class to be used by dataTable.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model;
|
||||
|
||||
/**
|
||||
* DataTable export filename.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filename;
|
||||
|
||||
/**
|
||||
* Build the class with the given name.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function buildClass($name)
|
||||
{
|
||||
$stub = $this->files->get($this->getStub());
|
||||
$stub = $this->replaceNamespace($stub, $name)->replaceClass($stub, $name);
|
||||
|
||||
return $this->replaceModelImport($stub)->replaceModel($stub)->replaceFilename($stub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stub file for the generator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStub()
|
||||
{
|
||||
return __DIR__ . '/stubs/datatables.stub';
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace model name.
|
||||
*
|
||||
* @param string $stub
|
||||
* @return mixed
|
||||
*/
|
||||
protected function replaceModel(&$stub)
|
||||
{
|
||||
$model = explode('\\', $this->model);
|
||||
$model = array_pop($model);
|
||||
$stub = str_replace('ModelName', $model, $stub);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace model import.
|
||||
*
|
||||
* @param string $stub
|
||||
* @return $this
|
||||
*/
|
||||
protected function replaceModelImport(&$stub)
|
||||
{
|
||||
$stub = str_replace(
|
||||
'DummyModel', str_replace('\\\\', '\\', $this->model), $stub
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the filename.
|
||||
*
|
||||
* @param string $stub
|
||||
* @return string
|
||||
*/
|
||||
protected function replaceFilename(&$stub)
|
||||
{
|
||||
$stub = str_replace(
|
||||
'DummyFilename', $this->filename, $stub
|
||||
);
|
||||
|
||||
return $stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the console command options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getOptions()
|
||||
{
|
||||
return [
|
||||
['model', null, InputOption::VALUE_NONE, 'Use the provided name as the model.', null],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the class already exists.
|
||||
*
|
||||
* @param string $rawName
|
||||
* @return bool
|
||||
*/
|
||||
protected function alreadyExists($rawName)
|
||||
{
|
||||
$name = $this->parseName($rawName);
|
||||
|
||||
$this->setModel($rawName);
|
||||
$this->setFilename($rawName);
|
||||
|
||||
return $this->files->exists($this->getPath($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the name and format according to the root namespace.
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function parseName($name)
|
||||
{
|
||||
$rootNamespace = $this->laravel->getNamespace();
|
||||
|
||||
if (Str::startsWith($name, $rootNamespace)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
if (Str::contains($name, '/')) {
|
||||
$name = str_replace('/', '\\', $name);
|
||||
}
|
||||
|
||||
if (! Str::contains(Str::lower($name), 'datatable')) {
|
||||
$name .= 'DataTable';
|
||||
}
|
||||
|
||||
return $this->parseName($this->getDefaultNamespace(trim($rootNamespace, '\\')) . '\\' . $name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default namespace for the class.
|
||||
*
|
||||
* @param string $rootNamespace
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultNamespace($rootNamespace)
|
||||
{
|
||||
return $rootNamespace . "\\" . $this->laravel['config']->get('datatables.namespace.base', 'DataTables');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the model to be used.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
protected function setModel($name)
|
||||
{
|
||||
$rootNamespace = $this->laravel->getNamespace();
|
||||
$modelNamespace = $this->laravel['config']->get('datatables.namespace.model');
|
||||
$this->model = $this->option('model')
|
||||
? $rootNamespace . "\\" . ($modelNamespace ? $modelNamespace . "\\" : "") . $name
|
||||
: $rootNamespace . "\\User";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filename for export.
|
||||
*
|
||||
* @param string $name
|
||||
*/
|
||||
protected function setFilename($name)
|
||||
{
|
||||
$this->filename = Str::lower(Str::plural($name));
|
||||
}
|
||||
}
|
@@ -1,56 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Generators;
|
||||
|
||||
use Illuminate\Console\GeneratorCommand;
|
||||
|
||||
/**
|
||||
* Class DataTablesScopeCommand.
|
||||
*
|
||||
* @package Yajra\Datatables\Generators
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DataTablesScopeCommand extends GeneratorCommand
|
||||
{
|
||||
/**
|
||||
* The console command name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name = 'datatables:scope';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a new DataTable Scope class.';
|
||||
|
||||
/**
|
||||
* The type of class being generated.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $type = 'DataTable Scope';
|
||||
|
||||
/**
|
||||
* Get the default namespace for the class.
|
||||
*
|
||||
* @param string $rootNamespace
|
||||
* @return string
|
||||
*/
|
||||
protected function getDefaultNamespace($rootNamespace)
|
||||
{
|
||||
return $rootNamespace . '\DataTables\Scopes';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stub file for the generator.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getStub()
|
||||
{
|
||||
return __DIR__ . '/stubs/scopes.stub';
|
||||
}
|
||||
}
|
@@ -1,73 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace DummyNamespace;
|
||||
|
||||
use DummyModel;
|
||||
use Yajra\Datatables\Services\DataTable;
|
||||
|
||||
class DummyClass extends DataTable
|
||||
{
|
||||
/**
|
||||
* Display ajax response.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function ajax()
|
||||
{
|
||||
return $this->datatables
|
||||
->eloquent($this->query())
|
||||
->addColumn('action', 'path.to.action.view')
|
||||
->make(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query object to be processed by dataTables.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Support\Collection
|
||||
*/
|
||||
public function query()
|
||||
{
|
||||
$query = ModelName::query();
|
||||
|
||||
return $this->applyScopes($query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional method if you want to use html builder.
|
||||
*
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function html()
|
||||
{
|
||||
return $this->builder()
|
||||
->columns($this->getColumns())
|
||||
->ajax('')
|
||||
->addAction(['width' => '80px'])
|
||||
->parameters($this->getBuilderParameters());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getColumns()
|
||||
{
|
||||
return [
|
||||
'id',
|
||||
// add your columns
|
||||
'created_at',
|
||||
'updated_at',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filename for export.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function filename()
|
||||
{
|
||||
return 'DummyFilename_' . time();
|
||||
}
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace DummyNamespace;
|
||||
|
||||
use Yajra\Datatables\Contracts\DataTableScopeContract;
|
||||
|
||||
class DummyClass implements DataTableScopeContract
|
||||
{
|
||||
/**
|
||||
* Apply a query scope.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
|
||||
* @return mixed
|
||||
*/
|
||||
public function apply($query)
|
||||
{
|
||||
// return $query->where('id', 1);
|
||||
}
|
||||
}
|
@@ -1,620 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Html;
|
||||
|
||||
use Collective\Html\FormBuilder;
|
||||
use Collective\Html\HtmlBuilder;
|
||||
use Illuminate\Contracts\Config\Repository;
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Class Builder.
|
||||
*
|
||||
* @package Yajra\Datatables\Html
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Builder
|
||||
{
|
||||
/**
|
||||
* @var Collection
|
||||
*/
|
||||
public $collection;
|
||||
|
||||
/**
|
||||
* @var Repository
|
||||
*/
|
||||
public $config;
|
||||
|
||||
/**
|
||||
* @var Factory
|
||||
*/
|
||||
public $view;
|
||||
|
||||
/**
|
||||
* @var HtmlBuilder
|
||||
*/
|
||||
public $html;
|
||||
|
||||
/**
|
||||
* @var UrlGenerator
|
||||
*/
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* @var FormBuilder
|
||||
*/
|
||||
public $form;
|
||||
|
||||
/**
|
||||
* @var string|array
|
||||
*/
|
||||
protected $ajax = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $tableAttributes = ['class' => 'table', 'id' => 'dataTableBuilder'];
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $template = '';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [];
|
||||
|
||||
/**
|
||||
* Lists of valid DataTables Callbacks.
|
||||
*
|
||||
* @link https://datatables.net/reference/option/.
|
||||
* @var array
|
||||
*/
|
||||
protected $validCallbacks = [
|
||||
'createdRow',
|
||||
'drawCallback',
|
||||
'footerCallback',
|
||||
'formatNumber',
|
||||
'headerCallback',
|
||||
'infoCallback',
|
||||
'initComplete',
|
||||
'preDrawCallback',
|
||||
'rowCallback',
|
||||
'stateLoadCallback',
|
||||
'stateLoaded',
|
||||
'stateLoadParams',
|
||||
'stateSaveCallback',
|
||||
'stateSaveParams',
|
||||
];
|
||||
|
||||
/**
|
||||
* @param Repository $config
|
||||
* @param Factory $view
|
||||
* @param HtmlBuilder $html
|
||||
* @param UrlGenerator $url
|
||||
* @param FormBuilder $form
|
||||
*/
|
||||
public function __construct(
|
||||
Repository $config,
|
||||
Factory $view,
|
||||
HtmlBuilder $html,
|
||||
UrlGenerator $url,
|
||||
FormBuilder $form
|
||||
) {
|
||||
$this->config = $config;
|
||||
$this->view = $view;
|
||||
$this->html = $html;
|
||||
$this->url = $url;
|
||||
$this->collection = new Collection;
|
||||
$this->form = $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DataTable javascript.
|
||||
*
|
||||
* @param null $script
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public function scripts($script = null, array $attributes = ['type' => 'text/javascript'])
|
||||
{
|
||||
$script = $script ?: $this->generateScripts();
|
||||
|
||||
return '<script' . $this->html->attributes($attributes) . '>' . $script . '</script>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get generated raw scripts.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function generateScripts()
|
||||
{
|
||||
$args = array_merge(
|
||||
$this->attributes, [
|
||||
'ajax' => $this->ajax,
|
||||
'columns' => $this->collection->toArray(),
|
||||
]
|
||||
);
|
||||
|
||||
$parameters = $this->parameterize($args);
|
||||
|
||||
return sprintf(
|
||||
$this->template(),
|
||||
$this->tableAttributes['id'], $parameters
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DataTables js parameters.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public function parameterize($attributes = [])
|
||||
{
|
||||
$parameters = (new Parameters($attributes))->toArray();
|
||||
|
||||
list($ajaxDataFunction, $parameters) = $this->encodeAjaxDataFunction($parameters);
|
||||
list($columnFunctions, $parameters) = $this->encodeColumnFunctions($parameters);
|
||||
list($callbackFunctions, $parameters) = $this->encodeCallbackFunctions($parameters);
|
||||
|
||||
$json = json_encode($parameters);
|
||||
|
||||
$json = $this->decodeAjaxDataFunction($ajaxDataFunction, $json);
|
||||
$json = $this->decodeColumnFunctions($columnFunctions, $json);
|
||||
$json = $this->decodeCallbackFunctions($callbackFunctions, $json);
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode ajax data function param.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return mixed
|
||||
*/
|
||||
protected function encodeAjaxDataFunction($parameters)
|
||||
{
|
||||
$ajaxData = '';
|
||||
if (isset($parameters['ajax']['data'])) {
|
||||
$ajaxData = $parameters['ajax']['data'];
|
||||
$parameters['ajax']['data'] = "#ajax_data#";
|
||||
}
|
||||
|
||||
return [$ajaxData, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode columns render function.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function encodeColumnFunctions(array $parameters)
|
||||
{
|
||||
$columnFunctions = [];
|
||||
foreach ($parameters['columns'] as $i => $column) {
|
||||
unset($parameters['columns'][$i]['exportable']);
|
||||
unset($parameters['columns'][$i]['printable']);
|
||||
unset($parameters['columns'][$i]['footer']);
|
||||
|
||||
if (isset($column['render'])) {
|
||||
$columnFunctions[$i] = $column['render'];
|
||||
$parameters['columns'][$i]['render'] = "#column_function.{$i}#";
|
||||
}
|
||||
}
|
||||
|
||||
return [$columnFunctions, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode DataTables callbacks function.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @return array
|
||||
*/
|
||||
protected function encodeCallbackFunctions(array $parameters)
|
||||
{
|
||||
$callbackFunctions = [];
|
||||
foreach ($parameters as $key => $callback) {
|
||||
if (in_array($key, $this->validCallbacks)) {
|
||||
$callbackFunctions[$key] = $this->compileCallback($callback);
|
||||
$parameters[$key] = "#callback_function.{$key}#";
|
||||
}
|
||||
}
|
||||
|
||||
return [$callbackFunctions, $parameters];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile DataTable callback value.
|
||||
*
|
||||
* @param mixed $callback
|
||||
* @return mixed|string
|
||||
*/
|
||||
private function compileCallback($callback)
|
||||
{
|
||||
if (is_callable($callback)) {
|
||||
return value($callback);
|
||||
} elseif ($this->view->exists($callback)) {
|
||||
return $this->view->make($callback)->render();
|
||||
}
|
||||
|
||||
return $callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode ajax data method.
|
||||
*
|
||||
* @param string $function
|
||||
* @param string $json
|
||||
* @return string
|
||||
*/
|
||||
protected function decodeAjaxDataFunction($function, $json)
|
||||
{
|
||||
return str_replace("\"#ajax_data#\"", $function, $json);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode columns render functions.
|
||||
*
|
||||
* @param array $columnFunctions
|
||||
* @param string $json
|
||||
* @return string
|
||||
*/
|
||||
protected function decodeColumnFunctions(array $columnFunctions, $json)
|
||||
{
|
||||
foreach ($columnFunctions as $i => $function) {
|
||||
$json = str_replace("\"#column_function.{$i}#\"", $function, $json);
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode DataTables callbacks function.
|
||||
*
|
||||
* @param array $callbackFunctions
|
||||
* @param string $json
|
||||
* @return string
|
||||
*/
|
||||
protected function decodeCallbackFunctions(array $callbackFunctions, $json)
|
||||
{
|
||||
foreach ($callbackFunctions as $i => $function) {
|
||||
$json = str_replace("\"#callback_function.{$i}#\"", $function, $json);
|
||||
}
|
||||
|
||||
return $json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get javascript template to use.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function template()
|
||||
{
|
||||
return $this->view->make(
|
||||
$this->template ?: $this->config->get('datatables.script_template', 'datatables::script')
|
||||
)->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets HTML table attribute(s).
|
||||
*
|
||||
* @param string|array $attribute
|
||||
* @param mixed $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setTableAttribute($attribute, $value = null)
|
||||
{
|
||||
if (is_array($attribute)) {
|
||||
$this->setTableAttributes($attribute);
|
||||
} else {
|
||||
$this->tableAttributes[$attribute] = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets multiple HTML table attributes at once.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function setTableAttributes(array $attributes)
|
||||
{
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
$this->setTableAttribute($attribute, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves HTML table attribute value.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getTableAttribute($attribute)
|
||||
{
|
||||
if (! array_key_exists($attribute, $this->tableAttributes)) {
|
||||
throw new \Exception("Table attribute '{$attribute}' does not exist.");
|
||||
}
|
||||
|
||||
return $this->tableAttributes[$attribute];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a column in collection using attributes.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumn(array $attributes)
|
||||
{
|
||||
$this->collection->push(new Column($attributes));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a Column object in collection.
|
||||
*
|
||||
* @param \Yajra\Datatables\Html\Column $column
|
||||
* @return $this
|
||||
*/
|
||||
public function add(Column $column)
|
||||
{
|
||||
$this->collection->push($column);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set datatables columns from array definition.
|
||||
*
|
||||
* @param array $columns
|
||||
* @return $this
|
||||
*/
|
||||
public function columns(array $columns)
|
||||
{
|
||||
foreach ($columns as $key => $value) {
|
||||
if (! is_a($value, Column::class)) {
|
||||
if (is_array($value)) {
|
||||
$attributes = array_merge(['name' => $key, 'data' => $key], $this->setTitle($key, $value));
|
||||
} else {
|
||||
$attributes = [
|
||||
'name' => $value,
|
||||
'data' => $value,
|
||||
'title' => $this->getQualifiedTitle($value),
|
||||
];
|
||||
}
|
||||
|
||||
$this->collection->push(new Column($attributes));
|
||||
} else {
|
||||
$this->collection->push($value);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set title attribute of an array if not set.
|
||||
*
|
||||
* @param string $title
|
||||
* @param array $attributes
|
||||
* @return array
|
||||
*/
|
||||
public function setTitle($title, array $attributes)
|
||||
{
|
||||
if (! isset($attributes['title'])) {
|
||||
$attributes['title'] = $this->getQualifiedTitle($title);
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string into a readable title.
|
||||
*
|
||||
* @param string $title
|
||||
* @return string
|
||||
*/
|
||||
public function getQualifiedTitle($title)
|
||||
{
|
||||
return Str::title(str_replace(['.', '_'], ' ', Str::snake($title)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a checkbox column.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function addCheckbox(array $attributes = [])
|
||||
{
|
||||
$attributes = array_merge([
|
||||
'defaultContent' => '<input type="checkbox" ' . $this->html->attributes($attributes) . '/>',
|
||||
'title' => $this->form->checkbox('', '', false, ['id' => 'dataTablesCheckbox']),
|
||||
'data' => 'checkbox',
|
||||
'name' => 'checkbox',
|
||||
'orderable' => false,
|
||||
'searchable' => false,
|
||||
'exportable' => false,
|
||||
'printable' => true,
|
||||
'width' => '10px',
|
||||
], $attributes);
|
||||
$this->collection->push(new Column($attributes));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a action column.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function addAction(array $attributes = [])
|
||||
{
|
||||
$attributes = array_merge([
|
||||
'defaultContent' => '',
|
||||
'data' => 'action',
|
||||
'name' => 'action',
|
||||
'title' => 'Action',
|
||||
'render' => null,
|
||||
'orderable' => false,
|
||||
'searchable' => false,
|
||||
'exportable' => false,
|
||||
'printable' => true,
|
||||
'footer' => '',
|
||||
], $attributes);
|
||||
$this->collection->push(new Column($attributes));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a index column.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function addIndex(array $attributes = [])
|
||||
{
|
||||
$indexColumn = Config::get('datatables.index_column', 'DT_Row_Index');
|
||||
$attributes = array_merge([
|
||||
'defaultContent' => '',
|
||||
'data' => $indexColumn,
|
||||
'name' => $indexColumn,
|
||||
'title' => '',
|
||||
'render' => null,
|
||||
'orderable' => false,
|
||||
'searchable' => false,
|
||||
'exportable' => false,
|
||||
'printable' => true,
|
||||
'footer' => '',
|
||||
], $attributes);
|
||||
$this->collection->push(new Column($attributes));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup ajax parameter
|
||||
*
|
||||
* @param string|array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function ajax($attributes)
|
||||
{
|
||||
$this->ajax = $attributes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate DataTable's table html.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @param bool $drawFooter
|
||||
* @return string
|
||||
*/
|
||||
public function table(array $attributes = [], $drawFooter = false)
|
||||
{
|
||||
$this->tableAttributes = array_merge($this->tableAttributes, $attributes);
|
||||
|
||||
$th = $this->compileTableHeaders();
|
||||
$htmlAttr = $this->html->attributes($this->tableAttributes);
|
||||
|
||||
$tableHtml = '<table ' . $htmlAttr . '>';
|
||||
$tableHtml .= '<thead><tr>' . implode('', $th) . '</tr></thead>';
|
||||
if ($drawFooter) {
|
||||
$tf = $this->compileTableFooter();
|
||||
$tableHtml .= '<tfoot><tr>' . implode('', $tf) . '</tr></tfoot>';
|
||||
}
|
||||
$tableHtml .= '</table>';
|
||||
|
||||
return $tableHtml;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile table headers and to support responsive extension.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function compileTableHeaders()
|
||||
{
|
||||
$th = [];
|
||||
foreach ($this->collection->toArray() as $row) {
|
||||
$thAttr = $this->html->attributes(
|
||||
array_only($row, ['class', 'id', 'width', 'style', 'data-class', 'data-hide'])
|
||||
);
|
||||
$th[] = '<th ' . $thAttr . '>' . $row['title'] . '</th>';
|
||||
}
|
||||
|
||||
return $th;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile table footer contents.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function compileTableFooter()
|
||||
{
|
||||
$footer = [];
|
||||
foreach ($this->collection->toArray() as $row) {
|
||||
$footer[] = '<th>' . $row['footer'] . '</th>';
|
||||
}
|
||||
|
||||
return $footer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure DataTable's parameters.
|
||||
*
|
||||
* @param array $attributes
|
||||
* @return $this
|
||||
*/
|
||||
public function parameters(array $attributes = [])
|
||||
{
|
||||
$this->attributes = array_merge($this->attributes, $attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set custom javascript template.
|
||||
*
|
||||
* @param string $template
|
||||
* @return $this
|
||||
*/
|
||||
public function setTemplate($template)
|
||||
{
|
||||
$this->template = $template;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get collection of columns.
|
||||
*
|
||||
* @return Collection
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return $this->collection;
|
||||
}
|
||||
}
|
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Html;
|
||||
|
||||
use Illuminate\Support\Fluent;
|
||||
|
||||
/**
|
||||
* Class Column.
|
||||
*
|
||||
* @package Yajra\Datatables\Html
|
||||
* @see https://datatables.net/reference/option/ for possible columns option
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Column extends Fluent
|
||||
{
|
||||
/**
|
||||
* @param array $attributes
|
||||
*/
|
||||
public function __construct($attributes = [])
|
||||
{
|
||||
$attributes['orderable'] = isset($attributes['orderable']) ? $attributes['orderable'] : true;
|
||||
$attributes['searchable'] = isset($attributes['searchable']) ? $attributes['searchable'] : true;
|
||||
$attributes['exportable'] = isset($attributes['exportable']) ? $attributes['exportable'] : true;
|
||||
$attributes['printable'] = isset($attributes['printable']) ? $attributes['printable'] : true;
|
||||
$attributes['footer'] = isset($attributes['footer']) ? $attributes['footer'] : '';
|
||||
|
||||
// Allow methods override attribute value
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
$method = 'parse' . ucfirst(strtolower($attribute));
|
||||
if (method_exists($this, $method)) {
|
||||
$attributes[$attribute] = $this->$method($value);
|
||||
}
|
||||
}
|
||||
|
||||
parent::__construct($attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse render attribute.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string|null
|
||||
*/
|
||||
public function parseRender($value)
|
||||
{
|
||||
/** @var \Illuminate\Contracts\View\Factory $view */
|
||||
$view = app('view');
|
||||
$parameters = [];
|
||||
|
||||
if (is_array($value)) {
|
||||
$parameters = array_except($value, 0);
|
||||
$value = $value[0];
|
||||
}
|
||||
|
||||
if (is_callable($value)) {
|
||||
return $value($parameters);
|
||||
} elseif ($view->exists($value)) {
|
||||
return $view->make($value)->with($parameters)->render();
|
||||
}
|
||||
|
||||
return $value ? $this->parseRenderAsString($value) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display render value as is.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @return string
|
||||
*/
|
||||
private function parseRenderAsString($value)
|
||||
{
|
||||
return "function(data,type,full,meta){return $value;}";
|
||||
}
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Html;
|
||||
|
||||
use Illuminate\Support\Fluent;
|
||||
|
||||
/**
|
||||
* Class Parameters.
|
||||
*
|
||||
* @package Yajra\Datatables\Html
|
||||
* @see https://datatables.net/reference/option/ for possible columns option
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Parameters extends Fluent
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $attributes = [
|
||||
'serverSide' => true,
|
||||
'processing' => true,
|
||||
'ajax' => '',
|
||||
'columns' => []
|
||||
];
|
||||
}
|
@@ -1,17 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Processors;
|
||||
namespace Yajra\DataTables\Processors;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Yajra\Datatables\Helper;
|
||||
use Yajra\DataTables\Utilities\Helper;
|
||||
|
||||
/**
|
||||
* Class DataProcessor.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DataProcessor
|
||||
{
|
||||
/**
|
||||
@@ -27,7 +20,7 @@ class DataProcessor
|
||||
protected $escapeColumns = [];
|
||||
|
||||
/**
|
||||
* Processed data output
|
||||
* Processed data output.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
@@ -63,11 +56,21 @@ class DataProcessor
|
||||
*/
|
||||
protected $includeIndex;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $rawColumns;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $exceptions = ['DT_RowId', 'DT_RowClass', 'DT_RowData', 'DT_RowAttr'];
|
||||
|
||||
/**
|
||||
* @param mixed $results
|
||||
* @param array $columnDef
|
||||
* @param array $templates
|
||||
* @param int $start
|
||||
* @param int $start
|
||||
*/
|
||||
public function __construct($results, array $columnDef, array $templates, $start)
|
||||
{
|
||||
@@ -75,14 +78,18 @@ class DataProcessor
|
||||
$this->appendColumns = $columnDef['append'];
|
||||
$this->editColumns = $columnDef['edit'];
|
||||
$this->excessColumns = $columnDef['excess'];
|
||||
$this->onlyColumns = $columnDef['only'];
|
||||
$this->escapeColumns = $columnDef['escape'];
|
||||
$this->includeIndex = $columnDef['index'];
|
||||
$this->rawColumns = $columnDef['raw'];
|
||||
$this->makeHidden = $columnDef['hidden'];
|
||||
$this->makeVisible = $columnDef['visible'];
|
||||
$this->templates = $templates;
|
||||
$this->start = $start;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process data to output on browser
|
||||
* Process data to output on browser.
|
||||
*
|
||||
* @param bool $object
|
||||
* @return array
|
||||
@@ -90,13 +97,14 @@ class DataProcessor
|
||||
public function process($object = false)
|
||||
{
|
||||
$this->output = [];
|
||||
$indexColumn = Config::get('datatables.index_column', 'DT_Row_Index');
|
||||
$indexColumn = config('datatables.index_column', 'DT_RowIndex');
|
||||
|
||||
foreach ($this->results as $row) {
|
||||
$data = Helper::convertToArray($row);
|
||||
$data = Helper::convertToArray($row, ['hidden' => $this->makeHidden, 'visible' => $this->makeVisible]);
|
||||
$value = $this->addColumns($data, $row);
|
||||
$value = $this->editColumns($value, $row);
|
||||
$value = $this->setupRowVariables($value, $row);
|
||||
$value = $this->selectOnlyNeededColumns($value);
|
||||
$value = $this->removeExcessColumns($value);
|
||||
|
||||
if ($this->includeIndex) {
|
||||
@@ -162,6 +170,31 @@ class DataProcessor
|
||||
->getData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get only needed columns.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function selectOnlyNeededColumns(array $data)
|
||||
{
|
||||
if (is_null($this->onlyColumns)) {
|
||||
return $data;
|
||||
} else {
|
||||
$results = [];
|
||||
foreach ($this->onlyColumns as $onlyColumn) {
|
||||
Arr::set($results, $onlyColumn, Arr::get($data, $onlyColumn));
|
||||
}
|
||||
foreach ($this->exceptions as $exception) {
|
||||
if ($column = Arr::get($data, $exception)) {
|
||||
Arr::set($results, $exception, $column);
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove declared hidden columns.
|
||||
*
|
||||
@@ -171,7 +204,7 @@ class DataProcessor
|
||||
protected function removeExcessColumns(array $data)
|
||||
{
|
||||
foreach ($this->excessColumns as $value) {
|
||||
unset($data[$value]);
|
||||
Arr::forget($data, $value);
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -185,11 +218,9 @@ class DataProcessor
|
||||
*/
|
||||
public function flatten(array $array)
|
||||
{
|
||||
$return = [];
|
||||
$exceptions = ['DT_RowId', 'DT_RowClass', 'DT_RowData', 'DT_RowAttr'];
|
||||
|
||||
$return = [];
|
||||
foreach ($array as $key => $value) {
|
||||
if (in_array($key, $exceptions)) {
|
||||
if (in_array($key, $this->exceptions)) {
|
||||
$return[$key] = $value;
|
||||
} else {
|
||||
$return[] = $value;
|
||||
@@ -209,12 +240,11 @@ class DataProcessor
|
||||
{
|
||||
return array_map(function ($row) {
|
||||
if ($this->escapeColumns == '*') {
|
||||
$row = $this->escapeRow($row, $this->escapeColumns);
|
||||
} else {
|
||||
foreach ($this->escapeColumns as $key) {
|
||||
if (array_get($row, $key)) {
|
||||
array_set($row, $key, e(array_get($row, $key)));
|
||||
}
|
||||
$row = $this->escapeRow($row);
|
||||
} elseif (is_array($this->escapeColumns)) {
|
||||
$columns = array_diff($this->escapeColumns, $this->rawColumns);
|
||||
foreach ($columns as $key) {
|
||||
Arr::set($row, $key, e(Arr::get($row, $key)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,19 +256,21 @@ class DataProcessor
|
||||
* Escape all values of row.
|
||||
*
|
||||
* @param array $row
|
||||
* @param string|array $escapeColumns
|
||||
* @return array
|
||||
*/
|
||||
protected function escapeRow(array $row, $escapeColumns)
|
||||
protected function escapeRow(array $row)
|
||||
{
|
||||
foreach ($row as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$row[$key] = $this->escapeRow($value, $escapeColumns);
|
||||
} else {
|
||||
$row[$key] = e($value);
|
||||
$arrayDot = array_filter(Arr::dot($row));
|
||||
foreach ($arrayDot as $key => $value) {
|
||||
if (! in_array($key, $this->rawColumns)) {
|
||||
$arrayDot[$key] = e($value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($arrayDot as $key => $value) {
|
||||
Arr::set($row, $key, $value);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}
|
||||
}
|
||||
|
@@ -1,16 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Processors;
|
||||
namespace Yajra\DataTables\Processors;
|
||||
|
||||
use Illuminate\Support\Arr;
|
||||
use Yajra\Datatables\Helper;
|
||||
use Yajra\DataTables\Utilities\Helper;
|
||||
|
||||
/**
|
||||
* Class RowProcessor.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class RowProcessor
|
||||
{
|
||||
/**
|
||||
@@ -36,7 +30,7 @@ class RowProcessor
|
||||
/**
|
||||
* Process DT RowId and Class value.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param string $attribute
|
||||
* @param string|callable $template
|
||||
* @return $this
|
||||
*/
|
||||
@@ -57,7 +51,7 @@ class RowProcessor
|
||||
* Process DT Row Data and Attr.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param array $template
|
||||
* @param array $template
|
||||
* @return $this
|
||||
*/
|
||||
public function rowData($attribute, array $template)
|
||||
|
771
vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php
vendored
Normal file
771
vendor/yajra/laravel-datatables-oracle/src/QueryDataTable.php
vendored
Normal file
@@ -0,0 +1,771 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Yajra\DataTables\Utilities\Helper;
|
||||
use Illuminate\Database\Query\Expression;
|
||||
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
|
||||
|
||||
class QueryDataTable extends DataTableAbstract
|
||||
{
|
||||
/**
|
||||
* Builder object.
|
||||
*
|
||||
* @var \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected $query;
|
||||
|
||||
/**
|
||||
* Database connection used.
|
||||
*
|
||||
* @var \Illuminate\Database\Connection
|
||||
*/
|
||||
protected $connection;
|
||||
|
||||
/**
|
||||
* Flag for ordering NULLS LAST option.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $nullsLast = false;
|
||||
|
||||
/**
|
||||
* Flag to check if query preparation was already done.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $prepared = false;
|
||||
|
||||
/**
|
||||
* Query callback for custom pagination using limit without offset.
|
||||
*
|
||||
* @var callable
|
||||
*/
|
||||
protected $limitCallback;
|
||||
|
||||
/**
|
||||
* Flag to skip total records count query.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $skipTotalRecords = false;
|
||||
|
||||
/**
|
||||
* Flag to keep the select bindings.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $keepSelectBindings = false;
|
||||
|
||||
/**
|
||||
* Can the DataTable engine be created with these parameters.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return bool
|
||||
*/
|
||||
public static function canCreate($source)
|
||||
{
|
||||
return $source instanceof Builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
*/
|
||||
public function __construct(Builder $builder)
|
||||
{
|
||||
$this->query = $builder;
|
||||
$this->request = app('datatables.request');
|
||||
$this->config = app('datatables.config');
|
||||
$this->columns = $builder->columns;
|
||||
$this->connection = $builder->getConnection();
|
||||
if ($this->config->isDebugging()) {
|
||||
$this->connection->enableQueryLog();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Organizes works.
|
||||
*
|
||||
* @param bool $mDataSupport
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function make($mDataSupport = true)
|
||||
{
|
||||
try {
|
||||
$this->prepareQuery();
|
||||
|
||||
$results = $this->results();
|
||||
$processed = $this->processResults($results, $mDataSupport);
|
||||
$data = $this->transform($results, $processed);
|
||||
|
||||
return $this->render($data);
|
||||
} catch (\Exception $exception) {
|
||||
return $this->errorResponse($exception);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare query by executing count, filter, order and paginate.
|
||||
*/
|
||||
protected function prepareQuery()
|
||||
{
|
||||
if (! $this->prepared) {
|
||||
$this->totalRecords = $this->totalCount();
|
||||
|
||||
if ($this->totalRecords) {
|
||||
$this->filterRecords();
|
||||
$this->ordering();
|
||||
$this->paginate();
|
||||
}
|
||||
}
|
||||
|
||||
$this->prepared = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip total records and set the recordsTotal equals to recordsFiltered.
|
||||
* This will improve the performance by skipping the total count query.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function skipTotalRecords()
|
||||
{
|
||||
$this->skipTotalRecords = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep the select bindings.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function keepSelectBindings()
|
||||
{
|
||||
$this->keepSelectBindings = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count total items.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function totalCount()
|
||||
{
|
||||
if ($this->skipTotalRecords) {
|
||||
$this->isFilterApplied = true;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return $this->totalRecords ? $this->totalRecords : $this->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Count filtered items.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function filteredCount()
|
||||
{
|
||||
$this->filteredRecords = $this->filteredRecords ?: $this->count();
|
||||
if ($this->skipTotalRecords) {
|
||||
$this->totalRecords = $this->filteredRecords;
|
||||
}
|
||||
|
||||
return $this->filteredRecords;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts current query.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
$builder = $this->prepareCountQuery();
|
||||
$table = $this->connection->raw('(' . $builder->toSql() . ') count_row_table');
|
||||
|
||||
return $this->connection->table($table)
|
||||
->setBindings($builder->getBindings())
|
||||
->count();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare count query builder.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected function prepareCountQuery()
|
||||
{
|
||||
$builder = clone $this->query;
|
||||
|
||||
if (! $this->isComplexQuery($builder)) {
|
||||
$row_count = $this->wrap('row_count');
|
||||
$builder->select($this->connection->raw("'1' as {$row_count}"));
|
||||
if (! $this->keepSelectBindings) {
|
||||
$builder->setBindings([], 'select');
|
||||
}
|
||||
}
|
||||
|
||||
return $builder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if builder query uses complex sql.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder $builder
|
||||
* @return bool
|
||||
*/
|
||||
protected function isComplexQuery($builder)
|
||||
{
|
||||
return Str::contains(Str::lower($builder->toSql()), ['union', 'having', 'distinct', 'order by', 'group by']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap column with DB grammar.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function wrap($column)
|
||||
{
|
||||
return $this->connection->getQueryGrammar()->wrap($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get paginated results.
|
||||
*
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
public function results()
|
||||
{
|
||||
return $this->query->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filtered, ordered and paginated query.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function getFilteredQuery()
|
||||
{
|
||||
$this->prepareQuery();
|
||||
|
||||
return $this->getQuery();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get query builder instance.
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder
|
||||
*/
|
||||
public function getQuery()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform column search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function columnSearch()
|
||||
{
|
||||
$columns = $this->request->columns();
|
||||
|
||||
foreach ($columns as $index => $column) {
|
||||
$column = $this->getColumnName($index);
|
||||
|
||||
if (! $this->request->isColumnSearchable($index) || $this->isBlacklisted($column) && ! $this->hasFilterColumn($column)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->hasFilterColumn($column)) {
|
||||
$keyword = $this->getColumnSearchKeyword($index, $raw = true);
|
||||
$this->applyFilterColumn($this->getBaseQueryBuilder(), $column, $keyword);
|
||||
} else {
|
||||
$column = $this->resolveRelationColumn($column);
|
||||
$keyword = $this->getColumnSearchKeyword($index);
|
||||
$this->compileColumnSearch($index, $column, $keyword);
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if column has custom filter handler.
|
||||
*
|
||||
* @param string $columnName
|
||||
* @return bool
|
||||
*/
|
||||
public function hasFilterColumn($columnName)
|
||||
{
|
||||
return isset($this->columnDef['filter'][$columnName]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column keyword to use for search.
|
||||
*
|
||||
* @param int $i
|
||||
* @param bool $raw
|
||||
* @return string
|
||||
*/
|
||||
protected function getColumnSearchKeyword($i, $raw = false)
|
||||
{
|
||||
$keyword = $this->request->columnKeyword($i);
|
||||
if ($raw || $this->request->isRegex($i)) {
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
return $this->setupKeyword($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply filterColumn api search.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $columnName
|
||||
* @param string $keyword
|
||||
* @param string $boolean
|
||||
*/
|
||||
protected function applyFilterColumn($query, $columnName, $keyword, $boolean = 'and')
|
||||
{
|
||||
$query = $this->getBaseQueryBuilder($query);
|
||||
$callback = $this->columnDef['filter'][$columnName]['method'];
|
||||
|
||||
if ($this->query instanceof EloquentBuilder) {
|
||||
$builder = $this->query->newModelInstance()->newQuery();
|
||||
} else {
|
||||
$builder = $this->query->newQuery();
|
||||
}
|
||||
|
||||
$callback($builder, $keyword);
|
||||
|
||||
$query->addNestedWhereQuery($this->getBaseQueryBuilder($builder), $boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base query builder instance.
|
||||
*
|
||||
* @param mixed $instance
|
||||
* @return \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected function getBaseQueryBuilder($instance = null)
|
||||
{
|
||||
if (! $instance) {
|
||||
$instance = $this->query;
|
||||
}
|
||||
|
||||
if ($instance instanceof EloquentBuilder) {
|
||||
return $instance->getQuery();
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the proper column name be used.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function resolveRelationColumn($column)
|
||||
{
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile queries for column search.
|
||||
*
|
||||
* @param int $i
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function compileColumnSearch($i, $column, $keyword)
|
||||
{
|
||||
if ($this->request->isRegex($i)) {
|
||||
$column = strstr($column, '(') ? $this->connection->raw($column) : $column;
|
||||
$this->regexColumnSearch($column, $keyword);
|
||||
} else {
|
||||
$this->compileQuerySearch($this->query, $column, $keyword, '');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile regex query column search.
|
||||
*
|
||||
* @param mixed $column
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function regexColumnSearch($column, $keyword)
|
||||
{
|
||||
switch ($this->connection->getDriverName()) {
|
||||
case 'oracle':
|
||||
$sql = ! $this->config->isCaseInsensitive()
|
||||
? 'REGEXP_LIKE( ' . $column . ' , ? )'
|
||||
: 'REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )';
|
||||
break;
|
||||
|
||||
case 'pgsql':
|
||||
$column = $this->castColumn($column);
|
||||
$sql = ! $this->config->isCaseInsensitive() ? $column . ' ~ ?' : $column . ' ~* ? ';
|
||||
break;
|
||||
|
||||
default:
|
||||
$sql = ! $this->config->isCaseInsensitive()
|
||||
? $column . ' REGEXP ?'
|
||||
: 'LOWER(' . $column . ') REGEXP ?';
|
||||
$keyword = Str::lower($keyword);
|
||||
}
|
||||
|
||||
$this->query->whereRaw($sql, [$keyword]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a column and cast based on database driver.
|
||||
*
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function castColumn($column)
|
||||
{
|
||||
switch ($this->connection->getDriverName()) {
|
||||
case 'pgsql':
|
||||
return 'CAST(' . $column . ' as TEXT)';
|
||||
case 'firebird':
|
||||
return 'CAST(' . $column . ' as VARCHAR(255))';
|
||||
default:
|
||||
return $column;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile query builder where clause depending on configurations.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $column
|
||||
* @param string $keyword
|
||||
* @param string $boolean
|
||||
*/
|
||||
protected function compileQuerySearch($query, $column, $keyword, $boolean = 'or')
|
||||
{
|
||||
$column = $this->addTablePrefix($query, $column);
|
||||
$column = $this->castColumn($column);
|
||||
$sql = $column . ' LIKE ?';
|
||||
|
||||
if ($this->config->isCaseInsensitive()) {
|
||||
$sql = 'LOWER(' . $column . ') LIKE ?';
|
||||
}
|
||||
|
||||
$query->{$boolean . 'WhereRaw'}($sql, [$this->prepareKeyword($keyword)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Patch for fix about ambiguous field.
|
||||
* Ambiguous field error will appear when query use join table and search with keyword.
|
||||
*
|
||||
* @param mixed $query
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
protected function addTablePrefix($query, $column)
|
||||
{
|
||||
if (strpos($column, '.') === false) {
|
||||
$q = $this->getBaseQueryBuilder($query);
|
||||
if (! $q->from instanceof Expression) {
|
||||
$column = $q->from . '.' . $column;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->wrap($column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare search keyword based on configurations.
|
||||
*
|
||||
* @param string $keyword
|
||||
* @return string
|
||||
*/
|
||||
protected function prepareKeyword($keyword)
|
||||
{
|
||||
if ($this->config->isStartsWithSearch()) {
|
||||
return "$keyword%";
|
||||
}
|
||||
|
||||
if ($this->config->isCaseInsensitive()) {
|
||||
$keyword = Str::lower($keyword);
|
||||
}
|
||||
|
||||
if ($this->config->isWildcard()) {
|
||||
$keyword = Helper::wildcardLikeString($keyword);
|
||||
}
|
||||
|
||||
if ($this->config->isSmartSearch()) {
|
||||
$keyword = "%$keyword%";
|
||||
}
|
||||
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom filter handler for the give column.
|
||||
*
|
||||
* @param string $column
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function filterColumn($column, callable $callback)
|
||||
{
|
||||
$this->columnDef['filter'][$column] = ['method' => $callback];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order each given columns versus the given custom sql.
|
||||
*
|
||||
* @param array $columns
|
||||
* @param string $sql
|
||||
* @param array $bindings
|
||||
* @return $this
|
||||
*/
|
||||
public function orderColumns(array $columns, $sql, $bindings = [])
|
||||
{
|
||||
foreach ($columns as $column) {
|
||||
$this->orderColumn($column, str_replace(':column', $column, $sql), $bindings);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override default column ordering.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $sql
|
||||
* @param array $bindings
|
||||
* @return $this
|
||||
* @internal string $1 Special variable that returns the requested order direction of the column.
|
||||
*/
|
||||
public function orderColumn($column, $sql, $bindings = [])
|
||||
{
|
||||
$this->columnDef['order'][$column] = compact('sql', 'bindings');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set datatables to do ordering with NULLS LAST option.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function orderByNullsLast()
|
||||
{
|
||||
$this->nullsLast = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate dataTable using limit without offset
|
||||
* with additional where clause via callback.
|
||||
*
|
||||
* @param callable $callback
|
||||
* @return $this
|
||||
*/
|
||||
public function limit(callable $callback)
|
||||
{
|
||||
$this->limitCallback = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform pagination.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function paging()
|
||||
{
|
||||
$limit = (int) $this->request->input('length') > 0 ? $this->request->input('length') : 10;
|
||||
if (is_callable($this->limitCallback)) {
|
||||
$this->query->limit($limit);
|
||||
call_user_func_array($this->limitCallback, [$this->query]);
|
||||
} else {
|
||||
$this->query->skip($this->request->input('start'))->take($limit);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add column in collection.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string|callable $content
|
||||
* @param bool|int $order
|
||||
* @return $this
|
||||
*/
|
||||
public function addColumn($name, $content, $order = false)
|
||||
{
|
||||
$this->pushToBlacklist($name);
|
||||
|
||||
return parent::addColumn($name, $content, $order);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve callback parameter instance.
|
||||
*
|
||||
* @return \Illuminate\Database\Query\Builder
|
||||
*/
|
||||
protected function resolveCallbackParameter()
|
||||
{
|
||||
return $this->query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform default query orderBy clause.
|
||||
*/
|
||||
protected function defaultOrdering()
|
||||
{
|
||||
collect($this->request->orderableColumns())
|
||||
->map(function ($orderable) {
|
||||
$orderable['name'] = $this->getColumnName($orderable['column'], true);
|
||||
|
||||
return $orderable;
|
||||
})
|
||||
->reject(function ($orderable) {
|
||||
return $this->isBlacklisted($orderable['name']) && ! $this->hasOrderColumn($orderable['name']);
|
||||
})
|
||||
->each(function ($orderable) {
|
||||
$column = $this->resolveRelationColumn($orderable['name']);
|
||||
|
||||
if ($this->hasOrderColumn($column)) {
|
||||
$this->applyOrderColumn($column, $orderable);
|
||||
} else {
|
||||
$nullsLastSql = $this->getNullsLastSql($column, $orderable['direction']);
|
||||
$normalSql = $this->wrap($column) . ' ' . $orderable['direction'];
|
||||
$sql = $this->nullsLast ? $nullsLastSql : $normalSql;
|
||||
$this->query->orderByRaw($sql);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if column has custom sort handler.
|
||||
*
|
||||
* @param string $column
|
||||
* @return bool
|
||||
*/
|
||||
protected function hasOrderColumn($column)
|
||||
{
|
||||
return isset($this->columnDef['order'][$column]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply orderColumn custom query.
|
||||
*
|
||||
* @param string $column
|
||||
* @param array $orderable
|
||||
*/
|
||||
protected function applyOrderColumn($column, $orderable)
|
||||
{
|
||||
$sql = $this->columnDef['order'][$column]['sql'];
|
||||
if (is_callable($sql)) {
|
||||
call_user_func($sql, $this->query, $orderable['direction']);
|
||||
} else {
|
||||
$sql = str_replace('$1', $orderable['direction'], $sql);
|
||||
$bindings = $this->columnDef['order'][$column]['bindings'];
|
||||
$this->query->orderByRaw($sql, $bindings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get NULLS LAST SQL.
|
||||
*
|
||||
* @param string $column
|
||||
* @param string $direction
|
||||
* @return string
|
||||
*/
|
||||
protected function getNullsLastSql($column, $direction)
|
||||
{
|
||||
$sql = $this->config->get('datatables.nulls_last_sql', '%s %s NULLS LAST');
|
||||
|
||||
return str_replace(
|
||||
[':column', ':direction'],
|
||||
[$column, $direction],
|
||||
sprintf($sql, $column, $direction)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform global search for the given keyword.
|
||||
*
|
||||
* @param string $keyword
|
||||
*/
|
||||
protected function globalSearch($keyword)
|
||||
{
|
||||
$this->query->where(function ($query) use ($keyword) {
|
||||
collect($this->request->searchableColumnIndex())
|
||||
->map(function ($index) {
|
||||
return $this->getColumnName($index);
|
||||
})
|
||||
->reject(function ($column) {
|
||||
return $this->isBlacklisted($column) && ! $this->hasFilterColumn($column);
|
||||
})
|
||||
->each(function ($column) use ($keyword, $query) {
|
||||
if ($this->hasFilterColumn($column)) {
|
||||
$this->applyFilterColumn($query, $column, $keyword, 'or');
|
||||
} else {
|
||||
$this->compileQuerySearch($query, $column, $keyword);
|
||||
}
|
||||
|
||||
$this->isFilterApplied = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Append debug parameters on output.
|
||||
*
|
||||
* @param array $output
|
||||
* @return array
|
||||
*/
|
||||
protected function showDebugger(array $output)
|
||||
{
|
||||
$query_log = $this->connection->getQueryLog();
|
||||
array_walk_recursive($query_log, function (&$item, $key) {
|
||||
$item = utf8_encode($item);
|
||||
});
|
||||
|
||||
$output['queries'] = $query_log;
|
||||
$output['input'] = $this->request->all();
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach custom with meta on response.
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
*/
|
||||
protected function attachAppends(array $data)
|
||||
{
|
||||
$appends = [];
|
||||
foreach ($this->appends as $key => $value) {
|
||||
if (is_callable($value)) {
|
||||
$appends[$key] = value($value($this->getFilteredQuery()));
|
||||
} else {
|
||||
$appends[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge($data, $appends);
|
||||
}
|
||||
}
|
@@ -1,173 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables;
|
||||
|
||||
use Exception;
|
||||
use Illuminate\Http\Request as IlluminateRequest;
|
||||
|
||||
/**
|
||||
* Class Request.
|
||||
*
|
||||
* @property array columns
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Request extends IlluminateRequest
|
||||
{
|
||||
/**
|
||||
* Check if request uses legacy code
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function checkLegacyCode()
|
||||
{
|
||||
if (! $this->get('draw') && $this->get('sEcho')) {
|
||||
throw new Exception('DataTables legacy code is not supported! Please use DataTables 1.10++ coding convention.');
|
||||
} elseif (! $this->get('draw') && ! $this->get('columns')) {
|
||||
throw new Exception('Insufficient parameters');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Datatables is searchable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSearchable()
|
||||
{
|
||||
return $this->get('search')['value'] != '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column's search value.
|
||||
*
|
||||
* @param integer $index
|
||||
* @return string
|
||||
*/
|
||||
public function columnKeyword($index)
|
||||
{
|
||||
return $this->columns[$index]['search']['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Datatables must uses regular expressions
|
||||
*
|
||||
* @param integer $index
|
||||
* @return string
|
||||
*/
|
||||
public function isRegex($index)
|
||||
{
|
||||
return $this->columns[$index]['search']['regex'] === 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get orderable columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function orderableColumns()
|
||||
{
|
||||
if (! $this->isOrderable()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$orderable = [];
|
||||
for ($i = 0, $c = count($this->get('order')); $i < $c; $i++) {
|
||||
$order_col = (int) $this->get('order')[$i]['column'];
|
||||
$order_dir = $this->get('order')[$i]['dir'];
|
||||
if ($this->isColumnOrderable($order_col)) {
|
||||
$orderable[] = ['column' => $order_col, 'direction' => $order_dir];
|
||||
}
|
||||
}
|
||||
|
||||
return $orderable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Datatables ordering is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOrderable()
|
||||
{
|
||||
return $this->get('order') && count($this->get('order')) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column is orderable.
|
||||
*
|
||||
* @param integer $index
|
||||
* @return bool
|
||||
*/
|
||||
public function isColumnOrderable($index)
|
||||
{
|
||||
return $this->get('columns')[$index]['orderable'] == 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get searchable column indexes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function searchableColumnIndex()
|
||||
{
|
||||
$searchable = [];
|
||||
for ($i = 0, $c = count($this->get('columns')); $i < $c; $i++) {
|
||||
if ($this->isColumnSearchable($i, false)) {
|
||||
$searchable[] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $searchable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column is searchable.
|
||||
*
|
||||
* @param integer $i
|
||||
* @param bool $column_search
|
||||
* @return bool
|
||||
*/
|
||||
public function isColumnSearchable($i, $column_search = true)
|
||||
{
|
||||
$columns = $this->get('columns');
|
||||
if ($column_search) {
|
||||
return $columns[$i]['searchable'] == 'true' && $columns[$i]['search']['value'] != '';
|
||||
}
|
||||
|
||||
return $columns[$i]['searchable'] == 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global search keyword
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function keyword()
|
||||
{
|
||||
return $this->get('search')['value'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column identity from input or database.
|
||||
*
|
||||
* @param integer $i
|
||||
* @return string
|
||||
*/
|
||||
public function columnName($i)
|
||||
{
|
||||
$column = $this->get('columns')[$i];
|
||||
|
||||
return isset($column['name']) && $column['name'] <> '' ? $column['name'] : $column['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if Datatables allow pagination.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPaginationable()
|
||||
{
|
||||
return ! is_null($this->get('start')) && ! is_null($this->get('length')) && $this->get('length') != -1;
|
||||
}
|
||||
}
|
@@ -1,385 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Services;
|
||||
|
||||
use Illuminate\Contracts\View\Factory;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Maatwebsite\Excel\Classes\LaravelExcelWorksheet;
|
||||
use Maatwebsite\Excel\Writers\LaravelExcelWriter;
|
||||
use Yajra\Datatables\Contracts\DataTableButtonsContract;
|
||||
use Yajra\Datatables\Contracts\DataTableContract;
|
||||
use Yajra\Datatables\Contracts\DataTableScopeContract;
|
||||
use Yajra\Datatables\Datatables;
|
||||
use Yajra\Datatables\Transformers\DataTransformer;
|
||||
|
||||
/**
|
||||
* Class DataTable.
|
||||
*
|
||||
* @package Yajra\Datatables\Services
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
abstract class DataTable implements DataTableContract, DataTableButtonsContract
|
||||
{
|
||||
/**
|
||||
* @var \Yajra\Datatables\Datatables
|
||||
*/
|
||||
protected $datatables;
|
||||
|
||||
/**
|
||||
* @var \Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
protected $viewFactory;
|
||||
|
||||
/**
|
||||
* Datatables print preview view.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $printPreview = 'datatables::print';
|
||||
|
||||
/**
|
||||
* List of columns to be exported.
|
||||
*
|
||||
* @var string|array
|
||||
*/
|
||||
protected $exportColumns = '*';
|
||||
|
||||
/**
|
||||
* List of columns to be printed.
|
||||
*
|
||||
* @var string|array
|
||||
*/
|
||||
protected $printColumns = '*';
|
||||
|
||||
/**
|
||||
* Query scopes.
|
||||
*
|
||||
* @var \Yajra\Datatables\Contracts\DataTableScopeContract[]
|
||||
*/
|
||||
protected $scopes = [];
|
||||
|
||||
/**
|
||||
* Export filename.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $filename = '';
|
||||
|
||||
/**
|
||||
* DataTable constructor.
|
||||
*
|
||||
* @param \Yajra\Datatables\Datatables $datatables
|
||||
* @param \Illuminate\Contracts\View\Factory $viewFactory
|
||||
*/
|
||||
public function __construct(Datatables $datatables, Factory $viewFactory)
|
||||
{
|
||||
$this->datatables = $datatables;
|
||||
$this->viewFactory = $viewFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process dataTables needed render output.
|
||||
*
|
||||
* @param string $view
|
||||
* @param array $data
|
||||
* @param array $mergeData
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\View\View
|
||||
*/
|
||||
public function render($view, $data = [], $mergeData = [])
|
||||
{
|
||||
if ($this->request()->ajax() && $this->request()->wantsJson()) {
|
||||
return $this->ajax();
|
||||
}
|
||||
|
||||
if ($action = $this->request()->get('action') AND in_array($action, ['print', 'csv', 'excel', 'pdf'])) {
|
||||
if ($action == 'print') {
|
||||
return $this->printPreview();
|
||||
}
|
||||
|
||||
return call_user_func_array([$this, $action], []);
|
||||
}
|
||||
|
||||
return $this->viewFactory->make($view, $data, $mergeData)->with('dataTable', $this->html());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Datatables Request instance.
|
||||
*
|
||||
* @return \Yajra\Datatables\Request
|
||||
*/
|
||||
public function request()
|
||||
{
|
||||
return $this->datatables->getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display printable view of datatables.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function printPreview()
|
||||
{
|
||||
$data = $this->getDataForPrint();
|
||||
|
||||
return $this->viewFactory->make($this->printPreview, compact('data'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped columns versus final decorated output.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDataForPrint()
|
||||
{
|
||||
$columns = $this->printColumns();
|
||||
|
||||
return $this->mapResponseToColumns($columns, 'printable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get printable columns.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
protected function printColumns()
|
||||
{
|
||||
return is_array($this->printColumns) ? $this->printColumns : $this->getColumnsFromBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns definition from html builder.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getColumnsFromBuilder()
|
||||
{
|
||||
return $this->html()->getColumns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Optional method if you want to use html builder.
|
||||
*
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function html()
|
||||
{
|
||||
return $this->builder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Datatables Html Builder instance.
|
||||
*
|
||||
* @return \Yajra\Datatables\Html\Builder
|
||||
*/
|
||||
public function builder()
|
||||
{
|
||||
return $this->datatables->getHtmlBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Map ajax response to columns definition.
|
||||
*
|
||||
* @param mixed $columns
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
protected function mapResponseToColumns($columns, $type)
|
||||
{
|
||||
return array_map(function ($row) use ($columns, $type) {
|
||||
if ($columns) {
|
||||
return (new DataTransformer())->transform($row, $columns, $type);
|
||||
}
|
||||
|
||||
return $row;
|
||||
}, $this->getAjaxResponseData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get decorated data as defined in datatables ajax response.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getAjaxResponseData()
|
||||
{
|
||||
$this->datatables->getRequest()->merge(['length' => -1]);
|
||||
|
||||
$response = $this->ajax();
|
||||
$data = $response->getData(true);
|
||||
|
||||
return $data['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Export results to Excel file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function excel()
|
||||
{
|
||||
$this->buildExcelFile()->download('xls');
|
||||
}
|
||||
|
||||
/**
|
||||
* Build excel file and prepare for export.
|
||||
*
|
||||
* @return \Maatwebsite\Excel\Writers\LaravelExcelWriter
|
||||
*/
|
||||
protected function buildExcelFile()
|
||||
{
|
||||
/** @var \Maatwebsite\Excel\Excel $excel */
|
||||
$excel = app('excel');
|
||||
|
||||
return $excel->create($this->getFilename(), function (LaravelExcelWriter $excel) {
|
||||
$excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) {
|
||||
$sheet->fromArray($this->getDataForExport());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get export filename.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename()
|
||||
{
|
||||
return $this->filename ?: $this->filename();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set export filename.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return DataTable
|
||||
*/
|
||||
public function setFilename($filename)
|
||||
{
|
||||
$this->filename = $filename;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filename for export.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function filename()
|
||||
{
|
||||
return 'export_' . time();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mapped columns versus final decorated output.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDataForExport()
|
||||
{
|
||||
$columns = $this->exportColumns();
|
||||
|
||||
return $this->mapResponseToColumns($columns, 'exportable');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get export columns definition.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
private function exportColumns()
|
||||
{
|
||||
return is_array($this->exportColumns) ? $this->exportColumns : $this->getColumnsFromBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* Export results to CSV file.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function csv()
|
||||
{
|
||||
$this->buildExcelFile()->download('csv');
|
||||
}
|
||||
|
||||
/**
|
||||
* Export results to PDF file.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function pdf()
|
||||
{
|
||||
if ('snappy' == Config::get('datatables.pdf_generator', 'excel')) {
|
||||
return $this->snappyPdf();
|
||||
} else {
|
||||
$this->buildExcelFile()->download('pdf');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PDF version of the table using print preview blade template.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function snappyPdf()
|
||||
{
|
||||
$data = $this->getDataForPrint();
|
||||
$snappy = app('snappy.pdf.wrapper');
|
||||
$snappy->setOptions([
|
||||
'no-outline' => true,
|
||||
'margin-left' => '0',
|
||||
'margin-right' => '0',
|
||||
'margin-top' => '10mm',
|
||||
'margin-bottom' => '10mm',
|
||||
])->setOrientation('landscape');
|
||||
|
||||
return $snappy->loadView($this->printPreview, compact('data'))
|
||||
->download($this->getFilename() . ".pdf");
|
||||
}
|
||||
|
||||
/**
|
||||
* Add basic array query scopes.
|
||||
*
|
||||
* @param \Yajra\Datatables\Contracts\DataTableScopeContract $scope
|
||||
* @return $this
|
||||
*/
|
||||
public function addScope(DataTableScopeContract $scope)
|
||||
{
|
||||
$this->scopes[] = $scope;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply query scopes.
|
||||
*
|
||||
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
|
||||
* @return mixed
|
||||
*/
|
||||
protected function applyScopes($query)
|
||||
{
|
||||
foreach ($this->scopes as $scope) {
|
||||
$scope->apply($query);
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default builder parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getBuilderParameters()
|
||||
{
|
||||
return [
|
||||
'order' => [[0, 'desc']],
|
||||
'buttons' => [
|
||||
'create',
|
||||
'export',
|
||||
'print',
|
||||
'reset',
|
||||
'reload',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables\Transformers;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class DataTransformer.
|
||||
*
|
||||
* @package Yajra\Datatables\Transformers
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class DataTransformer
|
||||
{
|
||||
/**
|
||||
* Transform row data by columns definition.
|
||||
*
|
||||
* @param array $row
|
||||
* @param mixed $columns
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
public function transform(array $row, $columns, $type = 'printable')
|
||||
{
|
||||
if ($columns instanceof Collection) {
|
||||
return $this->buildColumnByCollection($row, $columns, $type);
|
||||
}
|
||||
|
||||
return array_only($row, $columns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform row column by collection.
|
||||
*
|
||||
* @param array $row
|
||||
* @param \Illuminate\Support\Collection $columns
|
||||
* @param string $type
|
||||
* @return array
|
||||
*/
|
||||
protected function buildColumnByCollection(array $row, Collection $columns, $type = 'printable')
|
||||
{
|
||||
$results = [];
|
||||
foreach ($columns->all() as $column) {
|
||||
if ($column[$type]) {
|
||||
$title = $column['title'];
|
||||
$data = array_get($row, $column['data']);
|
||||
if ($type == 'exportable') {
|
||||
$data = $this->decodeContent($data);
|
||||
$title = $this->decodeContent($title);
|
||||
}
|
||||
|
||||
$results[$title] = $data;
|
||||
}
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode content to a readable text value.
|
||||
*
|
||||
* @param string $data
|
||||
* @return string
|
||||
*/
|
||||
protected function decodeContent($data)
|
||||
{
|
||||
try {
|
||||
$decoded = html_entity_decode(strip_tags($data), ENT_QUOTES, 'UTF-8');
|
||||
|
||||
return str_replace("\xc2\xa0", ' ', $decoded);
|
||||
} catch (\Exception $e) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
107
vendor/yajra/laravel-datatables-oracle/src/Utilities/Config.php
vendored
Normal file
107
vendor/yajra/laravel-datatables-oracle/src/Utilities/Config.php
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables\Utilities;
|
||||
|
||||
use Illuminate\Contracts\Config\Repository;
|
||||
|
||||
class Config
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Contracts\Config\Repository
|
||||
*/
|
||||
private $repository;
|
||||
|
||||
/**
|
||||
* Config constructor.
|
||||
*
|
||||
* @param \Illuminate\Contracts\Config\Repository $repository
|
||||
*/
|
||||
public function __construct(Repository $repository)
|
||||
{
|
||||
$this->repository = $repository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if config uses wild card search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWildcard()
|
||||
{
|
||||
return $this->repository->get('datatables.search.use_wildcards', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if config uses smart search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSmartSearch()
|
||||
{
|
||||
return $this->repository->get('datatables.search.smart', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if config uses case insensitive search.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCaseInsensitive()
|
||||
{
|
||||
return $this->repository->get('datatables.search.case_insensitive', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if app is in debug mode.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDebugging()
|
||||
{
|
||||
return $this->repository->get('app.debug', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specified configuration value.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
return $this->repository->get($key, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a given configuration value.
|
||||
*
|
||||
* @param array|string $key
|
||||
* @param mixed $value
|
||||
* @return void
|
||||
*/
|
||||
public function set($key, $value = null)
|
||||
{
|
||||
$this->repository->set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if dataTable config uses multi-term searching.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isMultiTerm()
|
||||
{
|
||||
return $this->repository->get('datatables.search.multi_term', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if dataTable config uses starts_with searching.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isStartsWithSearch()
|
||||
{
|
||||
return $this->repository->get('datatables.search.starts_with', false);
|
||||
}
|
||||
}
|
@@ -1,19 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\Datatables;
|
||||
namespace Yajra\DataTables\Utilities;
|
||||
|
||||
use DateTime;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\Compilers\BladeCompiler;
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
/**
|
||||
* Class Helper.
|
||||
*
|
||||
* @package Yajra\Datatables
|
||||
* @author Arjay Angeles <aqangeles@gmail.com>
|
||||
*/
|
||||
class Helper
|
||||
{
|
||||
/**
|
||||
@@ -27,20 +20,20 @@ class Helper
|
||||
{
|
||||
if (self::isItemOrderInvalid($item, $array)) {
|
||||
return array_merge($array, [$item['name'] => $item['content']]);
|
||||
} else {
|
||||
$count = 0;
|
||||
$last = $array;
|
||||
$first = [];
|
||||
foreach ($array as $key => $value) {
|
||||
if ($count == $item['order']) {
|
||||
return array_merge($first, [$item['name'] => $item['content']], $last);
|
||||
}
|
||||
}
|
||||
|
||||
unset($last[$key]);
|
||||
$first[$key] = $value;
|
||||
|
||||
$count++;
|
||||
$count = 0;
|
||||
$last = $array;
|
||||
$first = [];
|
||||
foreach ($array as $key => $value) {
|
||||
if ($count == $item['order']) {
|
||||
return array_merge($first, [$item['name'] => $item['content']], $last);
|
||||
}
|
||||
|
||||
unset($last[$key]);
|
||||
$first[$key] = $value;
|
||||
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,10 +52,10 @@ class Helper
|
||||
/**
|
||||
* Determines if content is callable or blade string, processes and returns.
|
||||
*
|
||||
* @param string|callable $content Pre-processed content
|
||||
* @param array $data data to use with blade template
|
||||
* @param mixed $param parameter to call with callable
|
||||
* @return string Processed content
|
||||
* @param mixed $content Pre-processed content
|
||||
* @param array $data data to use with blade template
|
||||
* @param mixed $param parameter to call with callable
|
||||
* @return mixed
|
||||
*/
|
||||
public static function compileContent($content, array $data, $param)
|
||||
{
|
||||
@@ -79,8 +72,8 @@ class Helper
|
||||
* Parses and compiles strings by using Blade Template System.
|
||||
*
|
||||
* @param string $str
|
||||
* @param array $data
|
||||
* @return string
|
||||
* @param array $data
|
||||
* @return mixed
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function compileBlade($str, $data = [])
|
||||
@@ -89,19 +82,8 @@ class Helper
|
||||
return view($str, $data)->render();
|
||||
}
|
||||
|
||||
$empty_filesystem_instance = new Filesystem();
|
||||
$blade = new BladeCompiler($empty_filesystem_instance, 'datatables');
|
||||
$parsed_string = $blade->compileString($str);
|
||||
|
||||
ob_start() && extract($data, EXTR_SKIP);
|
||||
|
||||
try {
|
||||
eval('?>' . $parsed_string);
|
||||
} catch (\Exception $e) {
|
||||
ob_end_clean();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
eval('?>' . app('blade.compiler')->compileString($str));
|
||||
$str = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
@@ -117,11 +99,13 @@ class Helper
|
||||
*/
|
||||
public static function getMixedValue(array $data, $param)
|
||||
{
|
||||
$param = self::castToArray($param);
|
||||
$casted = self::castToArray($param);
|
||||
|
||||
$data['model'] = $param;
|
||||
|
||||
foreach ($data as $key => $value) {
|
||||
if (isset($param[$key])) {
|
||||
$data[$key] = $param[$key];
|
||||
if (isset($casted[$key])) {
|
||||
$data[$key] = $casted[$key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,68 +148,25 @@ class Helper
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap value depending on database type.
|
||||
*
|
||||
* @param string $database
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public static function wrapDatabaseValue($database, $value)
|
||||
{
|
||||
$parts = explode('.', $value);
|
||||
$column = '';
|
||||
foreach ($parts as $key) {
|
||||
$column = static::wrapDatabaseColumn($database, $key, $column);
|
||||
}
|
||||
|
||||
return substr($column, 0, strlen($column) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Database column wrapper.
|
||||
*
|
||||
* @param string $database
|
||||
* @param string $key
|
||||
* @param string $column
|
||||
* @return string
|
||||
*/
|
||||
public static function wrapDatabaseColumn($database, $key, $column)
|
||||
{
|
||||
switch ($database) {
|
||||
case 'mysql':
|
||||
$column .= '`' . str_replace('`', '``', $key) . '`' . '.';
|
||||
break;
|
||||
|
||||
case 'sqlsrv':
|
||||
$column .= '[' . str_replace(']', ']]', $key) . ']' . '.';
|
||||
break;
|
||||
|
||||
case 'pgsql':
|
||||
case 'sqlite':
|
||||
$column .= '"' . str_replace('"', '""', $key) . '"' . '.';
|
||||
break;
|
||||
|
||||
default:
|
||||
$column .= $key . '.';
|
||||
}
|
||||
|
||||
return $column;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts array object values to associative array.
|
||||
*
|
||||
* @param mixed $row
|
||||
* @param array $filters
|
||||
* @return array
|
||||
*/
|
||||
public static function convertToArray($row)
|
||||
public static function convertToArray($row, $filters = [])
|
||||
{
|
||||
$row = method_exists($row, 'makeHidden') ? $row->makeHidden(Arr::get($filters, 'hidden', [])) : $row;
|
||||
$row = method_exists($row, 'makeVisible') ? $row->makeVisible(Arr::get($filters, 'visible', [])) : $row;
|
||||
$data = $row instanceof Arrayable ? $row->toArray() : (array) $row;
|
||||
foreach (array_keys($data) as $key) {
|
||||
if (is_object($data[$key]) || is_array($data[$key])) {
|
||||
$data[$key] = self::convertToArray($data[$key]);
|
||||
|
||||
foreach ($data as &$value) {
|
||||
if (is_object($value) || is_array($value)) {
|
||||
$value = self::convertToArray($value);
|
||||
}
|
||||
|
||||
unset($value);
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -290,9 +231,9 @@ class Helper
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace all pattern occurrences with keyword
|
||||
* Replace all pattern occurrences with keyword.
|
||||
*
|
||||
* @param array $subject
|
||||
* @param array $subject
|
||||
* @param string $keyword
|
||||
* @param string $pattern
|
||||
* @return array
|
||||
@@ -310,4 +251,68 @@ class Helper
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column name from string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param bool $wantsAlias
|
||||
* @return string
|
||||
*/
|
||||
public static function extractColumnName($str, $wantsAlias)
|
||||
{
|
||||
$matches = explode(' as ', Str::lower($str));
|
||||
|
||||
if (! empty($matches)) {
|
||||
if ($wantsAlias) {
|
||||
return array_pop($matches);
|
||||
}
|
||||
|
||||
return array_shift($matches);
|
||||
} elseif (strpos($str, '.')) {
|
||||
$array = explode('.', $str);
|
||||
|
||||
return array_pop($array);
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds % wildcards to the given string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param bool $lowercase
|
||||
* @return string
|
||||
*/
|
||||
public static function wildcardLikeString($str, $lowercase = true)
|
||||
{
|
||||
return static::wildcardString($str, '%', $lowercase);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds wildcards to the given string.
|
||||
*
|
||||
* @param string $str
|
||||
* @param string $wildcard
|
||||
* @param bool $lowercase
|
||||
* @return string
|
||||
*/
|
||||
public static function wildcardString($str, $wildcard, $lowercase = true)
|
||||
{
|
||||
$wild = $wildcard;
|
||||
$chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
if (count($chars) > 0) {
|
||||
foreach ($chars as $char) {
|
||||
$wild .= $char . $wildcard;
|
||||
}
|
||||
}
|
||||
|
||||
if ($lowercase) {
|
||||
$wild = Str::lower($wild);
|
||||
}
|
||||
|
||||
return $wild;
|
||||
}
|
||||
}
|
236
vendor/yajra/laravel-datatables-oracle/src/Utilities/Request.php
vendored
Normal file
236
vendor/yajra/laravel-datatables-oracle/src/Utilities/Request.php
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
<?php
|
||||
|
||||
namespace Yajra\DataTables\Utilities;
|
||||
|
||||
/**
|
||||
* @method mixed input($key, $default = null)
|
||||
* @method mixed get($key, $default = null)
|
||||
* @method mixed query($key, $default = null)
|
||||
* @method mixed has($key)
|
||||
* @method mixed merge(array $values)
|
||||
* @method bool wantsJson()
|
||||
* @method bool ajax()
|
||||
* @method array all()
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
/**
|
||||
* @var \Illuminate\Http\Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Request constructor.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->request = app('request');
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy non existing method calls to request class.
|
||||
*
|
||||
* @param mixed $name
|
||||
* @param mixed $arguments
|
||||
* @return mixed
|
||||
*/
|
||||
public function __call($name, $arguments)
|
||||
{
|
||||
if (method_exists($this->request, $name)) {
|
||||
return call_user_func_array([$this->request, $name], $arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attributes from request instance.
|
||||
*
|
||||
* @param string $name
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get($name)
|
||||
{
|
||||
return $this->request->__get($name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all columns request input.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function columns()
|
||||
{
|
||||
return (array) $this->request->input('columns');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables is searchable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSearchable()
|
||||
{
|
||||
return $this->request->input('search.value') != '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables must uses regular expressions.
|
||||
*
|
||||
* @param int $index
|
||||
* @return bool
|
||||
*/
|
||||
public function isRegex($index)
|
||||
{
|
||||
return $this->request->input("columns.$index.search.regex") === 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get orderable columns.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function orderableColumns()
|
||||
{
|
||||
if (! $this->isOrderable()) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$orderable = [];
|
||||
for ($i = 0, $c = count($this->request->input('order')); $i < $c; $i++) {
|
||||
$order_col = (int) $this->request->input("order.$i.column");
|
||||
$order_dir = strtolower($this->request->input("order.$i.dir")) === 'asc' ? 'asc' : 'desc';
|
||||
if ($this->isColumnOrderable($order_col)) {
|
||||
$orderable[] = ['column' => $order_col, 'direction' => $order_dir];
|
||||
}
|
||||
}
|
||||
|
||||
return $orderable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables ordering is enabled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOrderable()
|
||||
{
|
||||
return $this->request->input('order') && count($this->request->input('order')) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column is orderable.
|
||||
*
|
||||
* @param int $index
|
||||
* @return bool
|
||||
*/
|
||||
public function isColumnOrderable($index)
|
||||
{
|
||||
return $this->request->input("columns.$index.orderable", 'true') == 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get searchable column indexes.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function searchableColumnIndex()
|
||||
{
|
||||
$searchable = [];
|
||||
for ($i = 0, $c = count($this->request->input('columns')); $i < $c; $i++) {
|
||||
if ($this->isColumnSearchable($i, false)) {
|
||||
$searchable[] = $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $searchable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a column is searchable.
|
||||
*
|
||||
* @param int $i
|
||||
* @param bool $column_search
|
||||
* @return bool
|
||||
*/
|
||||
public function isColumnSearchable($i, $column_search = true)
|
||||
{
|
||||
if ($column_search) {
|
||||
return
|
||||
(
|
||||
$this->request->input("columns.$i.searchable", 'true') === 'true'
|
||||
||
|
||||
$this->request->input("columns.$i.searchable", 'true') === true
|
||||
)
|
||||
&& $this->columnKeyword($i) != '';
|
||||
}
|
||||
|
||||
return
|
||||
$this->request->input("columns.$i.searchable", 'true') === 'true'
|
||||
||
|
||||
$this->request->input("columns.$i.searchable", 'true') === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column's search value.
|
||||
*
|
||||
* @param int $index
|
||||
* @return string
|
||||
*/
|
||||
public function columnKeyword($index)
|
||||
{
|
||||
$keyword = $this->request->input("columns.$index.search.value");
|
||||
|
||||
return $this->prepareKeyword($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare keyword string value.
|
||||
*
|
||||
* @param string|array $keyword
|
||||
* @return string
|
||||
*/
|
||||
protected function prepareKeyword($keyword)
|
||||
{
|
||||
if (is_array($keyword)) {
|
||||
return implode(' ', $keyword);
|
||||
}
|
||||
|
||||
return $keyword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get global search keyword.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function keyword()
|
||||
{
|
||||
$keyword = $this->request->input('search.value');
|
||||
|
||||
return $this->prepareKeyword($keyword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column identity from input or database.
|
||||
*
|
||||
* @param int $i
|
||||
* @return string
|
||||
*/
|
||||
public function columnName($i)
|
||||
{
|
||||
$column = $this->request->input("columns.$i");
|
||||
|
||||
return isset($column['name']) && $column['name'] != '' ? $column['name'] : $column['data'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if DataTables allow pagination.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPaginationable()
|
||||
{
|
||||
return ! is_null($this->request->input('start')) &&
|
||||
! is_null($this->request->input('length')) &&
|
||||
$this->request->input('length') != -1;
|
||||
}
|
||||
}
|
@@ -1,86 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/**
|
||||
* DataTables search options.
|
||||
*/
|
||||
'search' => [
|
||||
/**
|
||||
* Smart search will enclose search keyword with wildcard string "%keyword%".
|
||||
* SQL: column LIKE "%keyword%"
|
||||
*/
|
||||
'smart' => true,
|
||||
|
||||
/**
|
||||
* Case insensitive will search the keyword in lower case format.
|
||||
* SQL: LOWER(column) LIKE LOWER(keyword)
|
||||
*/
|
||||
'case_insensitive' => true,
|
||||
|
||||
/**
|
||||
* Wild card will add "%" in between every characters of the keyword.
|
||||
* SQL: column LIKE "%k%e%y%w%o%r%d%"
|
||||
*/
|
||||
'use_wildcards' => false,
|
||||
],
|
||||
|
||||
/**
|
||||
* DataTables fractal configurations.
|
||||
*/
|
||||
'fractal' => [
|
||||
/**
|
||||
* Request key name to parse includes on fractal.
|
||||
*/
|
||||
'includes' => 'include',
|
||||
|
||||
/**
|
||||
* Default fractal serializer.
|
||||
*/
|
||||
'serializer' => 'League\Fractal\Serializer\DataArraySerializer',
|
||||
],
|
||||
|
||||
/**
|
||||
* DataTables script view template.
|
||||
*/
|
||||
'script_template' => 'datatables::script',
|
||||
|
||||
/**
|
||||
* DataTables internal index id response column name.
|
||||
*/
|
||||
'index_column' => 'DT_Row_Index',
|
||||
|
||||
/**
|
||||
* Namespaces used by the generator.
|
||||
*/
|
||||
'namespace' => [
|
||||
/**
|
||||
* Base namespace/directory to create the new file.
|
||||
* This is appended on default Laravel namespace.
|
||||
*
|
||||
* Usage: php artisan datatables:make User
|
||||
* Output: App\DataTables\UserDataTable
|
||||
* With Model: App\User (default model)
|
||||
* Export filename: users_timestamp
|
||||
*/
|
||||
'base' => 'DataTables',
|
||||
|
||||
/**
|
||||
* Base namespace/directory where your model's are located.
|
||||
* This is appended on default Laravel namespace.
|
||||
*
|
||||
* Usage: php artisan datatables:make Post --model
|
||||
* Output: App\DataTables\PostDataTable
|
||||
* With Model: App\Post
|
||||
* Export filename: posts_timestamp
|
||||
*/
|
||||
'model' => '',
|
||||
],
|
||||
|
||||
/**
|
||||
* PDF generator to be used when converting the table to pdf.
|
||||
* Available generators: excel, snappy
|
||||
* Snappy package: barryvdh/laravel-snappy
|
||||
* Excel package: maatwebsite/excel
|
||||
*/
|
||||
'pdf_generator' => 'excel',
|
||||
];
|
122
vendor/yajra/laravel-datatables-oracle/src/config/datatables.php
vendored
Normal file
122
vendor/yajra/laravel-datatables-oracle/src/config/datatables.php
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
/*
|
||||
* DataTables search options.
|
||||
*/
|
||||
'search' => [
|
||||
/*
|
||||
* Smart search will enclose search keyword with wildcard string "%keyword%".
|
||||
* SQL: column LIKE "%keyword%"
|
||||
*/
|
||||
'smart' => true,
|
||||
|
||||
/*
|
||||
* Multi-term search will explode search keyword using spaces resulting into multiple term search.
|
||||
*/
|
||||
'multi_term' => true,
|
||||
|
||||
/*
|
||||
* Case insensitive will search the keyword in lower case format.
|
||||
* SQL: LOWER(column) LIKE LOWER(keyword)
|
||||
*/
|
||||
'case_insensitive' => true,
|
||||
|
||||
/*
|
||||
* Wild card will add "%" in between every characters of the keyword.
|
||||
* SQL: column LIKE "%k%e%y%w%o%r%d%"
|
||||
*/
|
||||
'use_wildcards' => false,
|
||||
|
||||
/*
|
||||
* Perform a search which starts with the given keyword.
|
||||
* SQL: column LIKE "keyword%"
|
||||
*/
|
||||
'starts_with' => false,
|
||||
],
|
||||
|
||||
/*
|
||||
* DataTables internal index id response column name.
|
||||
*/
|
||||
'index_column' => 'DT_RowIndex',
|
||||
|
||||
/*
|
||||
* List of available builders for DataTables.
|
||||
* This is where you can register your custom dataTables builder.
|
||||
*/
|
||||
'engines' => [
|
||||
'eloquent' => Yajra\DataTables\EloquentDataTable::class,
|
||||
'query' => Yajra\DataTables\QueryDataTable::class,
|
||||
'collection' => Yajra\DataTables\CollectionDataTable::class,
|
||||
'resource' => Yajra\DataTables\ApiResourceDataTable::class,
|
||||
],
|
||||
|
||||
/*
|
||||
* DataTables accepted builder to engine mapping.
|
||||
* This is where you can override which engine a builder should use
|
||||
* Note, only change this if you know what you are doing!
|
||||
*/
|
||||
'builders' => [
|
||||
//Illuminate\Database\Eloquent\Relations\Relation::class => 'eloquent',
|
||||
//Illuminate\Database\Eloquent\Builder::class => 'eloquent',
|
||||
//Illuminate\Database\Query\Builder::class => 'query',
|
||||
//Illuminate\Support\Collection::class => 'collection',
|
||||
],
|
||||
|
||||
/*
|
||||
* Nulls last sql pattern for PostgreSQL & Oracle.
|
||||
* For MySQL, use 'CASE WHEN :column IS NULL THEN 1 ELSE 0 END, :column :direction'
|
||||
*/
|
||||
'nulls_last_sql' => ':column :direction NULLS LAST',
|
||||
|
||||
/*
|
||||
* User friendly message to be displayed on user if error occurs.
|
||||
* Possible values:
|
||||
* null - The exception message will be used on error response.
|
||||
* 'throw' - Throws a \Yajra\DataTables\Exceptions\Exception. Use your custom error handler if needed.
|
||||
* 'custom message' - Any friendly message to be displayed to the user. You can also use translation key.
|
||||
*/
|
||||
'error' => env('DATATABLES_ERROR', null),
|
||||
|
||||
/*
|
||||
* Default columns definition of dataTable utility functions.
|
||||
*/
|
||||
'columns' => [
|
||||
/*
|
||||
* List of columns hidden/removed on json response.
|
||||
*/
|
||||
'excess' => ['rn', 'row_num'],
|
||||
|
||||
/*
|
||||
* List of columns to be escaped. If set to *, all columns are escape.
|
||||
* Note: You can set the value to empty array to disable XSS protection.
|
||||
*/
|
||||
'escape' => '*',
|
||||
|
||||
/*
|
||||
* List of columns that are allowed to display html content.
|
||||
* Note: Adding columns to list will make us available to XSS attacks.
|
||||
*/
|
||||
'raw' => ['action'],
|
||||
|
||||
/*
|
||||
* List of columns are are forbidden from being searched/sorted.
|
||||
*/
|
||||
'blacklist' => ['password', 'remember_token'],
|
||||
|
||||
/*
|
||||
* List of columns that are only allowed fo search/sort.
|
||||
* If set to *, all columns are allowed.
|
||||
*/
|
||||
'whitelist' => '*',
|
||||
],
|
||||
|
||||
/*
|
||||
* JsonResponse header and options config.
|
||||
*/
|
||||
'json' => [
|
||||
'header' => [],
|
||||
'options' => 0,
|
||||
],
|
||||
|
||||
];
|
19
vendor/yajra/laravel-datatables-oracle/src/helper.php
vendored
Normal file
19
vendor/yajra/laravel-datatables-oracle/src/helper.php
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
if (! function_exists('datatables')) {
|
||||
/**
|
||||
* Helper to make a new DataTable instance from source.
|
||||
* Or return the factory if source is not set.
|
||||
*
|
||||
* @param mixed $source
|
||||
* @return \Yajra\DataTables\DataTableAbstract|\Yajra\DataTables\DataTables
|
||||
*/
|
||||
function datatables($source = null)
|
||||
{
|
||||
if (is_null($source)) {
|
||||
return app('datatables');
|
||||
}
|
||||
|
||||
return app('datatables')->make($source);
|
||||
}
|
||||
}
|
@@ -15,7 +15,7 @@ if (! function_exists('config_path')) {
|
||||
|
||||
if (! function_exists('public_path')) {
|
||||
/**
|
||||
* Return the path to public dir
|
||||
* Return the path to public dir.
|
||||
*
|
||||
* @param null $path
|
||||
* @return string
|
@@ -1,111 +0,0 @@
|
||||
(function ($, DataTable) {
|
||||
"use strict";
|
||||
|
||||
var _buildUrl = function(dt, action) {
|
||||
var url = dt.ajax.url() || '';
|
||||
var params = dt.ajax.params();
|
||||
params.action = action;
|
||||
|
||||
return url + '?' + $.param(params);
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.excel = {
|
||||
className: 'buttons-excel',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-file-excel-o"></i> ' + dt.i18n('buttons.excel', 'Excel');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
var url = _buildUrl(dt, 'excel');
|
||||
window.location = url;
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.export = {
|
||||
extend: 'collection',
|
||||
|
||||
className: 'buttons-export',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-download"></i> ' + dt.i18n('buttons.export', 'Export') + ' <span class="caret"/>';
|
||||
},
|
||||
|
||||
buttons: ['csv', 'excel', 'pdf']
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.csv = {
|
||||
className: 'buttons-csv',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-file-excel-o"></i> ' + dt.i18n('buttons.csv', 'CSV');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
var url = _buildUrl(dt, 'csv');
|
||||
window.location = url;
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.pdf = {
|
||||
className: 'buttons-pdf',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-file-pdf-o"></i> ' + dt.i18n('buttons.pdf', 'PDF');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
var url = _buildUrl(dt, 'pdf');
|
||||
window.location = url;
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.print = {
|
||||
className: 'buttons-print',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-print"></i> ' + dt.i18n('buttons.print', 'Print');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
var url = _buildUrl(dt, 'print');
|
||||
window.location = url;
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.reset = {
|
||||
className: 'buttons-reset',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-undo"></i> ' + dt.i18n('buttons.reset', 'Reset');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
dt.search('').draw();
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.reload = {
|
||||
className: 'buttons-reload',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-refresh"></i> ' + dt.i18n('buttons.reload', 'Reload');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
dt.draw(false);
|
||||
}
|
||||
};
|
||||
|
||||
DataTable.ext.buttons.create = {
|
||||
className: 'buttons-create',
|
||||
|
||||
text: function (dt) {
|
||||
return '<i class="fa fa-plus"></i> ' + dt.i18n('buttons.create', 'Create');
|
||||
},
|
||||
|
||||
action: function (e, dt, button, config) {
|
||||
window.location = window.location.href.replace(/\/+$/, "") + '/create';
|
||||
}
|
||||
};
|
||||
})(jQuery, jQuery.fn.dataTable);
|
@@ -1,37 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Print Table</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name=description content="">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
|
||||
<style>
|
||||
body {margin: 20px}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table class="table table-bordered table-condensed table-striped">
|
||||
@foreach($data as $row)
|
||||
@if ($row == reset($data))
|
||||
<tr>
|
||||
@foreach($row as $key => $value)
|
||||
<th>{!! $key !!}</th>
|
||||
@endforeach
|
||||
</tr>
|
||||
@endif
|
||||
<tr>
|
||||
@foreach($row as $key => $value)
|
||||
@if(is_string($value) || is_numeric($value))
|
||||
<td>{!! $value !!}</td>
|
||||
@else
|
||||
<td></td>
|
||||
@endif
|
||||
@endforeach
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@@ -1 +0,0 @@
|
||||
(function(window,$){window.LaravelDataTables=window.LaravelDataTables||{};window.LaravelDataTables["%1$s"]=$("#%1$s").DataTable(%2$s);})(window,jQuery);
|
Reference in New Issue
Block a user