From 62c153b5a7c7970bdd073ee1970e7f3c2aeef86b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 11:24:34 +0800 Subject: [PATCH 001/322] Enhance export function to match what is displayed in UI. Enhance datatables service stub. Add option to set id as exportable and printable. --- src/Generators/stubs/datatables.stub | 49 ++++---- src/Html/Builder.php | 17 +++ src/Html/Column.php | 2 + src/Services/DataTable.php | 161 +++++++++++++++++++-------- 4 files changed, 156 insertions(+), 73 deletions(-) diff --git a/src/Generators/stubs/datatables.stub b/src/Generators/stubs/datatables.stub index 374d3961..43975b7b 100644 --- a/src/Generators/stubs/datatables.stub +++ b/src/Generators/stubs/datatables.stub @@ -1,14 +1,13 @@ builder() - ->columns([ - 'id', - // add columns to display - 'created_at', - 'updated_at', - ]) - ->addAction(['width' => '50px']) - ->ajax('') - ->parameters([ - 'buttons' => [ - 'create', - [ - 'extend' => 'collection', - 'text' => ' Export', - 'buttons' => [ - 'csv', - 'excel', - 'pdf', - ], - ], - 'print', - 'reset', - 'reload', - ], - ]); + ->columns($this->getColumns()) + ->ajax('') + ->addAction(['width' => '80px']) + ->parameters($this->getBuilderParameters()); + } + + /** + * Get columns. + * + * @return array + */ + private function getColumns() + { + return [ + 'id', + // add your columns + 'created_at', + 'updated_at', + ]; } } diff --git a/src/Html/Builder.php b/src/Html/Builder.php index cb300268..eed8081a 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -137,6 +137,9 @@ public function parameterize($attributes = []) $column_functions = []; foreach ($parameters['columns'] as $i => $column) { + unset($parameters['columns'][$i]['exportable']); + unset($parameters['columns'][$i]['printable']); + if (isset($column['render'])) { $column_functions[$i] = $column['render']; $parameters['columns'][$i]['render'] = "#column_function.{$i}#"; @@ -258,6 +261,8 @@ public function addCheckbox(array $attributes = []) 'name' => 'checkbox', 'orderable' => false, 'searchable' => false, + 'exportable' => false, + 'printable' => false, 'width' => '10px', ], $attributes ); @@ -283,6 +288,8 @@ public function addAction(array $attributes = []) 'render' => null, 'orderable' => false, 'searchable' => false, + 'exportable' => false, + 'printable' => false, ], $attributes ); $this->collection->push(new Column($attributes)); @@ -341,4 +348,14 @@ public function setTemplate($template) return $this; } + + /** + * Get collection of columns. + * + * @return Collection + */ + public function getColumns() + { + return $this->collection; + } } diff --git a/src/Html/Column.php b/src/Html/Column.php index b39cc83c..606d976a 100644 --- a/src/Html/Column.php +++ b/src/Html/Column.php @@ -19,6 +19,8 @@ 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; // Allow methods override attribute value foreach ($attributes as $attribute => $value) { diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index d1a0a66e..d513be0c 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -3,10 +3,13 @@ namespace Yajra\Datatables\Services; use Illuminate\Contracts\View\Factory; +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\Html\Column; abstract class DataTable implements DataTableContract, DataTableButtonsContract { @@ -44,7 +47,7 @@ abstract class DataTable implements DataTableContract, DataTableButtonsContract /** * Query scopes. * - * @var array + * @var \Yajra\Datatables\Contracts\DataTableScopeContract[] */ protected $scopes = []; @@ -68,7 +71,7 @@ public function __construct(Datatables $datatables, Factory $viewFactory) */ public function render($view, $data = [], $mergeData = []) { - if ($this->request()->ajax() && $this->request()->wantsJson()) { + if ($this->request()->ajax() && $this->request()->wantsJson()) { return $this->ajax(); } @@ -90,6 +93,16 @@ public function render($view, $data = [], $mergeData = []) } } + /** + * Get Datatables Request instance. + * + * @return \Yajra\Datatables\Request + */ + public function request() + { + return $this->datatables->getRequest(); + } + /** * Export results to Excel file. * @@ -107,8 +120,8 @@ public function excel() */ protected function buildExcelFile() { - return app('excel')->create($this->filename(), function ($excel) { - $excel->sheet('exported-data', function ($sheet) { + return app('excel')->create($this->filename(), function (LaravelExcelWriter $excel) { + $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) { $sheet->fromArray($this->getDataForExport()); }); }); @@ -134,8 +147,8 @@ protected function getDataForExport() $decoratedData = $this->getAjaxResponseData(); return array_map(function ($row) { - if (is_array($this->exportColumns)) { - return array_only($row, $this->exportColumns); + if ($columns = $this->exportColumns()) { + return $this->buildExportColumn($row, $columns); } return $row; @@ -143,36 +156,79 @@ protected function getDataForExport() } /** - * Get mapped columns versus final decorated output. + * Get decorated data as defined in datatables ajax response. * - * @return array + * @return mixed */ - protected function getDataForPrint() + protected function getAjaxResponseData() { - $decoratedData = $this->getAjaxResponseData(); + $this->datatables->getRequest()->merge(['length' => -1]); - return array_map(function ($row) { - if (is_array($this->printColumns)) { - return array_only($row, $this->printColumns); - } + $response = $this->ajax(); + $data = $response->getData(true); - return $row; - }, $decoratedData); + return $data['data']; } /** - * Get decorated data as defined in datatables ajax response. + * Get export columns definition. * - * @return mixed + * @return array|string */ - protected function getAjaxResponseData() + private function exportColumns() { - $this->datatables->getRequest()->merge(['length' => -1]); + return is_array($this->exportColumns) ? $this->exportColumns : $this->getColumnsFromBuilder(); + } - $response = $this->ajax(); - $data = $response->getData(true); + /** + * Get columns definition from html builder. + * + * @return array + */ + private function getColumnsFromBuilder() + { + return $this->html()->getColumns()->all(); + } - return $data['data']; + /** + * 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(); + } + + /** + * @param array $row + * @param array|Column[] $columns + * @return array + */ + protected function buildExportColumn(array $row, array $columns) + { + $results = []; + foreach ($columns as $column) { + if ($column instanceof Column) { + if (! isset($column['exportable']) || $column['exportable']) { + $results[$column['title']] = strip_tags(array_get($row, $column['name'])); + } + } else { + $results[] = array_get($row, $column); + } + } + + return $results; } /** @@ -209,33 +265,21 @@ public function printPreview() } /** - * Optional method if you want to use html builder. + * Get mapped columns versus final decorated output. * - * @return mixed + * @return array */ - public function html() + protected function getDataForPrint() { - return $this->builder(); - } + $decoratedData = $this->getAjaxResponseData(); - /** - * Get Datatables Html Builder instance. - * - * @return \Yajra\Datatables\Html\Builder - */ - public function builder() - { - return $this->datatables->getHtmlBuilder(); - } + return array_map(function ($row) { + if (is_array($this->printColumns)) { + return array_only($row, $this->printColumns); + } - /** - * Get Datatables Request instance. - * - * @return \Yajra\Datatables\Request - */ - public function request() - { - return $this->datatables->getRequest(); + return $row; + }, $decoratedData); } /** @@ -265,4 +309,31 @@ public function applyScopes($query) return $query; } + + /** + * Get default builder parameters. + * + * @return array + */ + protected function getBuilderParameters() + { + return [ + 'order' => [[0, 'desc']], + 'buttons' => [ + 'create', + [ + 'extend' => 'collection', + 'text' => ' Export', + 'buttons' => [ + 'csv', + 'excel', + 'pdf', + ], + ], + 'print', + 'reset', + 'reload', + ], + ]; + } } From 1d95b5f4d012a2e42e1f3c9313bcf516b4777576 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 12:03:37 +0800 Subject: [PATCH 002/322] Enhance printing function to match what is displayed in UI. --- src/Generators/stubs/datatables.stub | 1 - src/Services/DataTable.php | 39 +++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/Generators/stubs/datatables.stub b/src/Generators/stubs/datatables.stub index 43975b7b..d1a6c253 100644 --- a/src/Generators/stubs/datatables.stub +++ b/src/Generators/stubs/datatables.stub @@ -8,7 +8,6 @@ use Yajra\Datatables\Services\DataTable; class PoliciesDataTable extends DataTable { // protected $printPreview = 'path.to.print.preview.view'; - // protected $printColumns = '*'; /** * Display ajax response. diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index d513be0c..631aef3c 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -220,7 +220,7 @@ protected function buildExportColumn(array $row, array $columns) $results = []; foreach ($columns as $column) { if ($column instanceof Column) { - if (! isset($column['exportable']) || $column['exportable']) { + if ($column['exportable']) { $results[$column['title']] = strip_tags(array_get($row, $column['name'])); } } else { @@ -274,14 +274,47 @@ protected function getDataForPrint() $decoratedData = $this->getAjaxResponseData(); return array_map(function ($row) { - if (is_array($this->printColumns)) { - return array_only($row, $this->printColumns); + if ($columns = $this->printColumns()) { + return $this->buildPrintColumn($row, $columns); } return $row; }, $decoratedData); } + /** + * Get printable columns. + * + * @return array|string + */ + protected function printColumns() + { + return is_array($this->printColumns) ? $this->printColumns : $this->getColumnsFromBuilder(); + } + + /** + * Build printable column. + * + * @param array $row + * @param array|Column[] $columns + * @return array + */ + protected function buildPrintColumn(array $row, array $columns) + { + $results = []; + foreach ($columns as $column) { + if ($column instanceof Column) { + if ($column['printable']) { + $results[$column['title']] = array_get($row, $column['name']); + } + } else { + $results[] = array_get($row, $column); + } + } + + return $results; + } + /** * Add basic array query scopes. * From 30f8c225140f93c4840373e4988dfb892d601e59 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 12:12:30 +0800 Subject: [PATCH 003/322] Update method accessor. --- src/Services/DataTable.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 631aef3c..37701ac4 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -185,7 +185,7 @@ private function exportColumns() * * @return array */ - private function getColumnsFromBuilder() + protected function getColumnsFromBuilder() { return $this->html()->getColumns()->all(); } @@ -334,7 +334,7 @@ public function addScope(DataTableScopeContract $scope) * @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query * @return mixed */ - public function applyScopes($query) + protected function applyScopes($query) { foreach ($this->scopes as $scope) { $scope->apply($query); From 3a3ca0e5038bed9b140a0c7d6c15509b7b130a42 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 12:16:24 +0800 Subject: [PATCH 004/322] Set action column as printable by default. --- src/Html/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index eed8081a..f2189181 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -289,7 +289,7 @@ public function addAction(array $attributes = []) 'orderable' => false, 'searchable' => false, 'exportable' => false, - 'printable' => false, + 'printable' => true, ], $attributes ); $this->collection->push(new Column($attributes)); From 91009ce3e09cf2be158d69a4c599a4bde5962b70 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 12:17:35 +0800 Subject: [PATCH 005/322] Set checkbox as printable by default. --- src/Html/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index f2189181..9cfb63fb 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -262,7 +262,7 @@ public function addCheckbox(array $attributes = []) 'orderable' => false, 'searchable' => false, 'exportable' => false, - 'printable' => false, + 'printable' => true, 'width' => '10px', ], $attributes ); From 4e6a5725bf4b5c84953747dfa1e71d35752d0b1c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 12:18:53 +0800 Subject: [PATCH 006/322] Bump v6.2.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1fb4b6d..ad5773a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,14 @@ ##Change Log +###v6.2.0 + - Enhance printing function to match what is displayed in UI. + - Enhance export function to match what is displayed in UI. + - Enhance datatables service stub. + - Address issue #310. + - Add option to set column as exportable and/or printable. + - Action and checkbox column is not exportable but printable by default. + ###v6.1.3 - Fix logical bug with totalRecords and filteredRecords. Fix #333 From f1a49be3d2e6df318c3a34eee98bfa99b1cc1877 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 13:47:20 +0800 Subject: [PATCH 007/322] Fix data when exporting with html tags. Add filename method in stub. --- src/Generators/stubs/datatables.stub | 10 ++++++++++ src/Services/DataTable.php | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Generators/stubs/datatables.stub b/src/Generators/stubs/datatables.stub index d1a6c253..ce7d59c7 100644 --- a/src/Generators/stubs/datatables.stub +++ b/src/Generators/stubs/datatables.stub @@ -62,4 +62,14 @@ class PoliciesDataTable extends DataTable 'updated_at', ]; } + + /** + * Get filename for export. + * + * @return string + */ + protected function filename() + { + return 'users'; + } } diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 37701ac4..b6bfeaba 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -221,7 +221,7 @@ protected function buildExportColumn(array $row, array $columns) foreach ($columns as $column) { if ($column instanceof Column) { if ($column['exportable']) { - $results[$column['title']] = strip_tags(array_get($row, $column['name'])); + $results[$column['title']] = strip_tags(array_get($row, $column['data'])); } } else { $results[] = array_get($row, $column); From c66ef3779dab855e35388e6385fcc27552f2f977 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 14:33:04 +0800 Subject: [PATCH 008/322] Refactor DataTable class. --- src/Services/DataTable.php | 92 +++++++++++++++++++++++++++----------- 1 file changed, 67 insertions(+), 25 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index b6bfeaba..b8d72161 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -3,13 +3,13 @@ namespace Yajra\Datatables\Services; use Illuminate\Contracts\View\Factory; +use Illuminate\Support\Collection; 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\Html\Column; abstract class DataTable implements DataTableContract, DataTableButtonsContract { @@ -187,7 +187,7 @@ private function exportColumns() */ protected function getColumnsFromBuilder() { - return $this->html()->getColumns()->all(); + return $this->html()->getColumns(); } /** @@ -212,19 +212,47 @@ public function builder() /** * @param array $row - * @param array|Column[] $columns + * @param array|\Illuminate\Support\Collection $columns * @return array */ - protected function buildExportColumn(array $row, array $columns) + protected function buildExportColumn(array $row, $columns) + { + return $this->buildColumn($row, $columns, 'exportable'); + } + + /** + * Build printable and exportable column. + * + * @param array $row + * @param array|\Illuminate\Support\Collection $columns + * @param string $type + * @return array + */ + protected function buildColumn(array $row, $columns, $type) + { + if ($columns instanceof Collection) { + return $this->buildColumnByCollection($row, $columns, $type); + } + + return array_only($row, $columns); + } + + /** + * Build column from collection. + * + * @param array $row + * @param \Illuminate\Support\Collection $columns + * @param string $type + * @return array + */ + protected function buildColumnByCollection(array $row, Collection $columns, $type) { $results = []; - foreach ($columns as $column) { - if ($column instanceof Column) { - if ($column['exportable']) { - $results[$column['title']] = strip_tags(array_get($row, $column['data'])); - } - } else { - $results[] = array_get($row, $column); + foreach ($columns->all() as $column) { + if ($column[$type]) { + $data = array_get($row, $column['data']); + + $results[$column['title']] = $type == 'exportable' ? strip_tags($data) : $data; } } @@ -296,23 +324,12 @@ protected function printColumns() * Build printable column. * * @param array $row - * @param array|Column[] $columns + * @param array|\Illuminate\Support\Collection $columns * @return array */ - protected function buildPrintColumn(array $row, array $columns) + protected function buildPrintColumn(array $row, $columns) { - $results = []; - foreach ($columns as $column) { - if ($column instanceof Column) { - if ($column['printable']) { - $results[$column['title']] = array_get($row, $column['name']); - } - } else { - $results[] = array_get($row, $column); - } - } - - return $results; + return $this->buildColumn($row, $columns, 'printable'); } /** @@ -328,6 +345,31 @@ public function addScope(DataTableScopeContract $scope) return $this; } + /** + * @param array $row + * @param $type + * @param $column + * @param $results + * @return mixed + */ + protected function getRowColumnData(array $row, $type, $column, $results) + { + if ($column[$type]) { + $data = array_get($row, $column['data']); + if ($type == 'exportable') { + $results[$column['title']] = strip_tags($data); + + return $results; + } else { + $results[$column['title']] = $data; + + return $results; + } + } + + return $results; + } + /** * Apply query scopes. * From 9f50badc421a85623187786318b21d995e956065 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 14:33:16 +0800 Subject: [PATCH 009/322] Fix doc blocks. --- src/Html/Column.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Html/Column.php b/src/Html/Column.php index 606d976a..3cb99431 100644 --- a/src/Html/Column.php +++ b/src/Html/Column.php @@ -41,6 +41,7 @@ public function __construct($attributes = []) */ public function parseRender($value) { + /** @var \Illuminate\Contracts\View\Factory $view */ $view = app('view'); if (is_callable($value)) { @@ -55,7 +56,7 @@ public function parseRender($value) /** * Display render value as is. * - * @param string $value + * @param mixed $value * @return string */ private function parseRenderAsString($value) From 1f3c1ac8c52f320f524be8663fc5524c8f08fe1d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 14:40:09 +0800 Subject: [PATCH 010/322] Scrutinizer type check? --- src/Html/Column.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Html/Column.php b/src/Html/Column.php index 3cb99431..528715fb 100644 --- a/src/Html/Column.php +++ b/src/Html/Column.php @@ -36,7 +36,7 @@ public function __construct($attributes = []) /** * Parse render attribute. * - * @param \Closure|string $value + * @param mixed $value * @return string|null */ public function parseRender($value) From 03bd60c8ec77240f45101c565c0ebae8cc01312b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 14:41:48 +0800 Subject: [PATCH 011/322] Remove unused method. --- src/Services/DataTable.php | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index b8d72161..aad960bc 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -345,31 +345,6 @@ public function addScope(DataTableScopeContract $scope) return $this; } - /** - * @param array $row - * @param $type - * @param $column - * @param $results - * @return mixed - */ - protected function getRowColumnData(array $row, $type, $column, $results) - { - if ($column[$type]) { - $data = array_get($row, $column['data']); - if ($type == 'exportable') { - $results[$column['title']] = strip_tags($data); - - return $results; - } else { - $results[$column['title']] = $data; - - return $results; - } - } - - return $results; - } - /** * Apply query scopes. * From 9d7db67dab5e76f1fcf1828abe80892423d34252 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 14:48:27 +0800 Subject: [PATCH 012/322] Fix duplicate code scrutinizer. --- src/Services/DataTable.php | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index aad960bc..ecbc412f 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -144,15 +144,13 @@ protected function filename() */ protected function getDataForExport() { - $decoratedData = $this->getAjaxResponseData(); - return array_map(function ($row) { if ($columns = $this->exportColumns()) { return $this->buildExportColumn($row, $columns); } return $row; - }, $decoratedData); + }, $this->getAjaxResponseData()); } /** @@ -299,15 +297,13 @@ public function printPreview() */ protected function getDataForPrint() { - $decoratedData = $this->getAjaxResponseData(); - return array_map(function ($row) { if ($columns = $this->printColumns()) { return $this->buildPrintColumn($row, $columns); } return $row; - }, $decoratedData); + }, $this->getAjaxResponseData()); } /** From 862f227079b1521c667215176822c702d2fd30c3 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 14:51:04 +0800 Subject: [PATCH 013/322] Fix scrutinizer type check? --- src/Processors/DataProcessor.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Processors/DataProcessor.php b/src/Processors/DataProcessor.php index 7fff8e53..4bd0a088 100644 --- a/src/Processors/DataProcessor.php +++ b/src/Processors/DataProcessor.php @@ -90,11 +90,11 @@ public function process($object = false) /** * Process add columns. * - * @param array $data + * @param mixed $data * @param mixed $row * @return array */ - protected function addColumns(array $data, $row) + protected function addColumns($data, $row) { foreach ($this->appendColumns as $key => $value) { $value['content'] = Helper::compileContent($value['content'], $data, $row); @@ -107,11 +107,11 @@ protected function addColumns(array $data, $row) /** * Process edit columns. * - * @param array $data + * @param mixed $data * @param mixed $row * @return array */ - protected function editColumns(array $data, $row) + protected function editColumns($data, $row) { foreach ($this->editColumns as $key => $value) { $value['content'] = Helper::compileContent($value['content'], $data, $row); From ff0fc5f9d11e6d02948c2bd5943e545d50b36ec0 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 14:55:03 +0800 Subject: [PATCH 014/322] Bump v6.2.1 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad5773a9..763ccd0f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +###v6.2.1 + - Fix data when exporting with html tags. + - Add filename method in stub. + - Fix some doc blocks. + - Scrutinizer refactoring. + ###v6.2.0 - Enhance printing function to match what is displayed in UI. - Enhance export function to match what is displayed in UI. From 9ccddf1225bc492dae965cbe91288be6fb0c981b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 14:58:24 +0800 Subject: [PATCH 015/322] Update Licence to 2016. --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index 7414309d..600ba57e 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ (The MIT License) -Copyright (c) 2013-2015 Arjay Angeles +Copyright (c) 2013-2016 Arjay Angeles Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the From 3175f90dbc145bca140035e1b96fd85cca38c31f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 15:23:07 +0800 Subject: [PATCH 016/322] Extract data transformation task to own class. --- src/Services/DataTable.php | 81 ++++------------------------ src/Transformers/DataTransformer.php | 50 +++++++++++++++++ 2 files changed, 60 insertions(+), 71 deletions(-) create mode 100644 src/Transformers/DataTransformer.php diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index ecbc412f..172aa942 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -3,13 +3,13 @@ namespace Yajra\Datatables\Services; use Illuminate\Contracts\View\Factory; -use Illuminate\Support\Collection; 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; abstract class DataTable implements DataTableContract, DataTableButtonsContract { @@ -146,28 +146,13 @@ protected function getDataForExport() { return array_map(function ($row) { if ($columns = $this->exportColumns()) { - return $this->buildExportColumn($row, $columns); + return (new DataTransformer())->transform($row, $columns, 'exportable'); } return $row; }, $this->getAjaxResponseData()); } - /** - * Get decorated data as defined in datatables ajax response. - * - * @return mixed - */ - protected function getAjaxResponseData() - { - $this->datatables->getRequest()->merge(['length' => -1]); - - $response = $this->ajax(); - $data = $response->getData(true); - - return $data['data']; - } - /** * Get export columns definition. * @@ -209,52 +194,18 @@ public function builder() } /** - * @param array $row - * @param array|\Illuminate\Support\Collection $columns - * @return array - */ - protected function buildExportColumn(array $row, $columns) - { - return $this->buildColumn($row, $columns, 'exportable'); - } - - /** - * Build printable and exportable column. - * - * @param array $row - * @param array|\Illuminate\Support\Collection $columns - * @param string $type - * @return array - */ - protected function buildColumn(array $row, $columns, $type) - { - if ($columns instanceof Collection) { - return $this->buildColumnByCollection($row, $columns, $type); - } - - return array_only($row, $columns); - } - - /** - * Build column from collection. + * Get decorated data as defined in datatables ajax response. * - * @param array $row - * @param \Illuminate\Support\Collection $columns - * @param string $type - * @return array + * @return mixed */ - protected function buildColumnByCollection(array $row, Collection $columns, $type) + protected function getAjaxResponseData() { - $results = []; - foreach ($columns->all() as $column) { - if ($column[$type]) { - $data = array_get($row, $column['data']); + $this->datatables->getRequest()->merge(['length' => -1]); - $results[$column['title']] = $type == 'exportable' ? strip_tags($data) : $data; - } - } + $response = $this->ajax(); + $data = $response->getData(true); - return $results; + return $data['data']; } /** @@ -299,7 +250,7 @@ protected function getDataForPrint() { return array_map(function ($row) { if ($columns = $this->printColumns()) { - return $this->buildPrintColumn($row, $columns); + return (new DataTransformer())->transform($row, $columns, 'printable'); } return $row; @@ -316,18 +267,6 @@ protected function printColumns() return is_array($this->printColumns) ? $this->printColumns : $this->getColumnsFromBuilder(); } - /** - * Build printable column. - * - * @param array $row - * @param array|\Illuminate\Support\Collection $columns - * @return array - */ - protected function buildPrintColumn(array $row, $columns) - { - return $this->buildColumn($row, $columns, 'printable'); - } - /** * Add basic array query scopes. * diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php new file mode 100644 index 00000000..692b82f5 --- /dev/null +++ b/src/Transformers/DataTransformer.php @@ -0,0 +1,50 @@ +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]) { + $data = array_get($row, $column['data']); + + $results[$column['title']] = $type == 'exportable' ? strip_tags($data) : $data; + } + } + + return $results; + } +} From 4c4075c19ea1fbedb65013b4d95d665e98056b29 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 15:36:14 +0800 Subject: [PATCH 017/322] Refactor duplicate mapping of response. --- src/Services/DataTable.php | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 172aa942..da563986 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -144,13 +144,9 @@ protected function filename() */ protected function getDataForExport() { - return array_map(function ($row) { - if ($columns = $this->exportColumns()) { - return (new DataTransformer())->transform($row, $columns, 'exportable'); - } + $columns = $this->exportColumns(); - return $row; - }, $this->getAjaxResponseData()); + return $this->mapResponseToColumns($columns, 'exportable'); } /** @@ -193,6 +189,24 @@ 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. * @@ -248,13 +262,9 @@ public function printPreview() */ protected function getDataForPrint() { - return array_map(function ($row) { - if ($columns = $this->printColumns()) { - return (new DataTransformer())->transform($row, $columns, 'printable'); - } + $columns = $this->printColumns(); - return $row; - }, $this->getAjaxResponseData()); + return $this->mapResponseToColumns($columns, 'printable'); } /** From 64f43c64a341d4fb7d6d89660a93516b83e9f1aa Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 15:42:07 +0800 Subject: [PATCH 018/322] Bump v6.2.2 --- CHANGELOG.md | 5 +++++ src/Transformers/DataTransformer.php | 2 ++ 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 763ccd0f..0aebf465 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ ##Change Log +###v6.2.2 + - Extract data transformation task to own class. + - Refactor duplicate response mapping code. + - Increase scrutinizer score. + ###v6.2.1 - Fix data when exporting with html tags. - Add filename method in stub. diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index 692b82f5..d99f30bb 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -12,6 +12,8 @@ class DataTransformer { /** + * Transform row data by columns definition. + * * @param array $row * @param mixed $columns * @param string $type From f3a3e1343c995f437a6c192ab8b04ee60c54665c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 18 Jan 2016 12:08:17 +0800 Subject: [PATCH 019/322] Add htmlentities when exporting data. Fix issue #341. --- src/Transformers/DataTransformer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index d99f30bb..4079bee2 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -43,7 +43,7 @@ protected function buildColumnByCollection(array $row, Collection $columns, $ty if ($column[$type]) { $data = array_get($row, $column['data']); - $results[$column['title']] = $type == 'exportable' ? strip_tags($data) : $data; + $results[$column['title']] = $type == 'exportable' ? e(strip_tags($data)) : $data; } } From 94c94c5c7d31d4d4da87695a23c7baee8e2a1c61 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 18 Jan 2016 12:14:18 +0800 Subject: [PATCH 020/322] Strip tags column title when exporting. --- src/Transformers/DataTransformer.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index 4079bee2..c890103b 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -41,9 +41,14 @@ protected function buildColumnByCollection(array $row, Collection $columns, $ty $results = []; foreach ($columns->all() as $column) { if ($column[$type]) { - $data = array_get($row, $column['data']); + $title = $column['title']; + $data = array_get($row, $column['data']); + if ($type == 'exportable') { + $data = e(strip_tags($data)); + $title = e(strip_tags($title)); + } - $results[$column['title']] = $type == 'exportable' ? e(strip_tags($data)) : $data; + $results[$title] = $data; } } From 7d139981771ebda1f64dbd02d73c4dc65c497848 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 18 Jan 2016 12:17:24 +0800 Subject: [PATCH 021/322] Use html_entity_decode instead of htmlentities. --- src/Transformers/DataTransformer.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index c890103b..50a56c0b 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -44,8 +44,8 @@ protected function buildColumnByCollection(array $row, Collection $columns, $ty $title = $column['title']; $data = array_get($row, $column['data']); if ($type == 'exportable') { - $data = e(strip_tags($data)); - $title = e(strip_tags($title)); + $data = html_entity_decode(strip_tags($data), ENT_QUOTES, 'UTF-8'); + $title = html_entity_decode(strip_tags($title), ENT_QUOTES, 'UTF-8'); } $results[$title] = $data; From 9dab9c19a053fe273485e055274a7cd6aa752ed4 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 18 Jan 2016 14:10:10 +0800 Subject: [PATCH 022/322] Add method to set export filename during runtime. --- src/Services/DataTable.php | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index da563986..a6d81643 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -51,6 +51,13 @@ abstract class DataTable implements DataTableContract, DataTableButtonsContract */ protected $scopes = []; + /** + * Export filename. + * + * @var string + */ + protected $filename = ''; + /** * @param \Yajra\Datatables\Datatables $datatables * @param \Illuminate\Contracts\View\Factory $viewFactory @@ -120,7 +127,7 @@ public function excel() */ protected function buildExcelFile() { - return app('excel')->create($this->filename(), function (LaravelExcelWriter $excel) { + return app('excel')->create($this->getFilename(), function (LaravelExcelWriter $excel) { $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) { $sheet->fromArray($this->getDataForExport()); }); @@ -290,6 +297,29 @@ public function addScope(DataTableScopeContract $scope) return $this; } + /** + * 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; + } + /** * Apply query scopes. * From 29b04b28379077116897d7762b7d177b0486b9a3 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 18 Jan 2016 14:43:03 +0800 Subject: [PATCH 023/322] Refactor decode method and replace   to space. --- src/Transformers/DataTransformer.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index 50a56c0b..46f4758b 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -44,8 +44,8 @@ protected function buildColumnByCollection(array $row, Collection $columns, $ty $title = $column['title']; $data = array_get($row, $column['data']); if ($type == 'exportable') { - $data = html_entity_decode(strip_tags($data), ENT_QUOTES, 'UTF-8'); - $title = html_entity_decode(strip_tags($title), ENT_QUOTES, 'UTF-8'); + $data = $this->decodeContent($data); + $title = $this->decodeContent($title); } $results[$title] = $data; @@ -54,4 +54,17 @@ protected function buildColumnByCollection(array $row, Collection $columns, $ty return $results; } + + /** + * Decode content to a readable text value. + * + * @param string $data + * @return string + */ + protected function decodeContent($data) + { + $decoded = html_entity_decode(strip_tags($data), ENT_QUOTES, 'UTF-8'); + + return str_replace("\xc2\xa0", ' ', $decoded); + } } From 6f76b92a6ebc43daa36a40232260ea4c1bdf841e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 18 Jan 2016 15:31:46 +0800 Subject: [PATCH 024/322] Bump v6.2.3 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0aebf465..19e5a781 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ ##Change Log +###v6.2.3 + - Add setter/getter for filename. + - Add html_entity_decode when exporting file. + - Decode column title when exporting. + ###v6.2.2 - Extract data transformation task to own class. - Refactor duplicate response mapping code. From a85551152357c643dc6f5bd660c29be19d497c4f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 18 Jan 2016 17:25:34 +0800 Subject: [PATCH 025/322] Add git attributes. --- .gitattributes | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..0878fe2a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +* text=auto + +/tests export-ignore +.gitattributes export-ignore +.gitignore export-ignore +.php_cs export-ignore +.scrutinizer.yml export-ignore +.travis.yml export-ignore +phpunit.xml export-ignore From bb6a5a7b51ef1131e96e034e5b49848170432180 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 18 Jan 2016 17:36:04 +0800 Subject: [PATCH 026/322] Bump v6.2.4 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19e5a781..4a89643f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +###v6.2.4 + - Add git attributes. + ###v6.2.3 - Add setter/getter for filename. - Add html_entity_decode when exporting file. From 47254183641fe410dc27a8241edcc402594ff66a Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 19 Jan 2016 07:55:31 +0800 Subject: [PATCH 027/322] Add some new features docs. Remove Laravel 4.2 documentation. --- readme.md | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index 796a5156..0961e7d0 100644 --- a/readme.md +++ b/readme.md @@ -14,9 +14,9 @@ This package is created to handle [server-side](https://www.datatables.net/manua - **Eloquent ORM** - **Fluent Query Builder** - **Collection** [available on v5.x and later] -- [DataTable Service Implementation (v6.x)](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md). +- [DataTable Service Implementation (v6.x)](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md#v600---datatable-service-implementation). - Adding or editing content of columns and removing columns -- Templating new or current columns via Blade Template Engine or by using Closure +- Modify column values via Blade Template Engine or by using Closure - Works with **ALL the DATABASE** supported by Laravel - Works with **Oracle Database** using [Laravel-OCI8](https://github.com/yajra/laravel-oci8) package - Works with [DataTables](http://datatables.net) v1.10++. @@ -31,10 +31,16 @@ This package is created to handle [server-side](https://www.datatables.net/manua - Provides a [DataTable Html Builder](http://datatables.yajrabox.com/html) to help you use the package with less code. - Provides XSS filtering function to optionally escape all or specified column values using `escapeColumns('*'\['column'])` method. - Provides Query Logging when application is in debug state. **Important: Make sure that debug is set to false when your code is in production** +- Easily attach a resource on json response via `->with()` +- Built-in support for exporting to CSV, EXCEL and PDF using [Laravel-Excel](https://github.com/Maatwebsite/Laravel-Excel). +- Built-in printer friendly view or create your own by overriding `printPreview()` method. +- Provides an artisan command for generating a DataTable service and scope. +- See [change logs](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md) for more details. ## Requirements: - PHP 5.5.9 or later. - Laravel 5.0 or later. +- [DataTables jQuery Plugin](http://datatables.net/) v1.10.x ## Laravel 4.2 & DataTables v1.9.x Users Most of the latest updates/features are not available on these versions. Please check [L4 Branch](https://github.com/yajra/laravel-datatables/tree/L4) and [L5 DT1.9](https://github.com/yajra/laravel-datatables/tree/L5-DT1.9) for old documentations of its features. @@ -48,24 +54,16 @@ Most of the latest updates/features are not available on these versions. Please - [Demo Application](http://datatables.yajrabox.com) is available for artisan's reference. ## Quick Installation -**Laravel 5:** `composer require yajra/laravel-datatables-oracle:~6.0` - -**Laravel 4:** `composer require yajra/laravel-datatables-oracle:~3.0` +`composer require yajra/laravel-datatables-oracle:~6.0` #### Service Provider `Yajra\Datatables\DatatablesServiceProvider` #### Facade -**Laravel 4** -`'Datatables' => 'yajra\Datatables\Facades\Datatables',` - -**Laravel 5++** `Datatables` facade are automatically registered as an alias for `Yajra\Datatables\Datatables` class. #### Configuration -**Laravel 5:** `$ php artisan vendor:publish --tag=datatables` - -**Laravel 4:** `$ php artisan config:publish yajra/laravel-datatables-oracle` +`$ php artisan vendor:publish --tag=datatables` And that's it! Start building out some awesome DataTables! @@ -92,4 +90,3 @@ If you discover any security related issues, please email [aqangeles@gmail.com]( ## License The MIT License (MIT). Please see [License File](https://github.com/yajra/laravel-datatables/blob/master/LICENSE.md) for more information. - From 7932da99dd0fbee6808dc9234890bfd4d4475884 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 19 Jan 2016 09:35:11 +0800 Subject: [PATCH 028/322] Add editor config. --- .editorconfig | 16 ++++++++++++++++ .gitattributes | 1 + 2 files changed, 17 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..8791d9f2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.yml] +indent_style = space +indent_size = 2 \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index 0878fe2a..a5707b0f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,7 @@ * text=auto /tests export-ignore +.editorconfig export-ignore .gitattributes export-ignore .gitignore export-ignore .php_cs export-ignore From 1e3c332bbc0f3ccf5140cda9ab6de9a222362be2 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 16:39:06 +0800 Subject: [PATCH 029/322] Add option to override default ordering via order method. Address #340 limitation. --- src/Engines/BaseEngine.php | 20 ++++++++++++++++++++ src/Engines/CollectionEngine.php | 4 ++++ src/Engines/QueryBuilderEngine.php | 4 ++++ 3 files changed, 28 insertions(+) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 3419393d..02273b84 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -167,6 +167,13 @@ abstract class BaseEngine implements DataTableEngineContract */ protected $serializer; + /** + * Custom ordering callback. + * + * @var \Closure + */ + protected $orderCallback; + /** * Array of data to append on json response. * @@ -835,4 +842,17 @@ public function with($key, $value = '') return $this; } + + /** + * Override default collection ordering. + * + * @param \Closure $closure + * @return CollectionEngine + */ + public function order(\Closure $closure) + { + $this->orderCallback = $closure; + + return $this; + } } diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 9269c202..506d2751 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -98,6 +98,10 @@ public function count() */ public function ordering() { + if ($this->orderCallback) { + return call_user_func($this->orderCallback, $this); + } + foreach ($this->request->orderableColumns() as $orderable) { $column = $this->getColumnName($orderable['column']); $this->collection = $this->collection->sortBy( diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index c95af096..ef394e13 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -259,6 +259,10 @@ private function getSearchKeyword($i) */ public function ordering() { + if ($this->orderCallback) { + return call_user_func($this->orderCallback, $this->getQueryBuilder()); + } + foreach ($this->request->orderableColumns() as $orderable) { $column = $this->setupOrderColumn($orderable); if (isset($this->columnDef['order'][$column])) { From fb6ca55075d1623911e8b8c5e89923ebc26a9975 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jan 2016 18:46:42 +0800 Subject: [PATCH 030/322] Return void on ordering method. --- src/Engines/CollectionEngine.php | 4 +++- src/Engines/QueryBuilderEngine.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 506d2751..06d4271a 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -99,7 +99,9 @@ public function count() public function ordering() { if ($this->orderCallback) { - return call_user_func($this->orderCallback, $this); + call_user_func($this->orderCallback, $this); + + return; } foreach ($this->request->orderableColumns() as $orderable) { diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index ef394e13..966c5904 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -260,7 +260,9 @@ private function getSearchKeyword($i) public function ordering() { if ($this->orderCallback) { - return call_user_func($this->orderCallback, $this->getQueryBuilder()); + call_user_func($this->orderCallback, $this->getQueryBuilder()); + + return; } foreach ($this->request->orderableColumns() as $orderable) { From e3352911705ec163b03e4539b4af6c7bdc3c3b0d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 19 Jan 2016 10:06:58 +0800 Subject: [PATCH 031/322] Fix doc block. --- src/Engines/BaseEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 02273b84..26fa1f01 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -844,10 +844,10 @@ public function with($key, $value = '') } /** - * Override default collection ordering. + * Override default ordering method with a closure callback. * * @param \Closure $closure - * @return CollectionEngine + * @return $this */ public function order(\Closure $closure) { From d505a7290a0745fe5053a67443205dde91413a3c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 19 Jan 2016 10:15:38 +0800 Subject: [PATCH 032/322] Bump v6.3.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a89643f..f2c18ee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +###v6.3.0 + - Add option to override default ordering via `->order(\Closure $callback)` method. + - Add editor config. + - Add some new features docs. + - Remove Laravel 4.2 documentation on 6.0 branch. + ###v6.2.4 - Add git attributes. From 4c0d780286120966e8457e490131297ae916d9f1 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 19 Jan 2016 11:21:31 +0800 Subject: [PATCH 033/322] Update service provider and some wordings. --- readme.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 0961e7d0..cad874f1 100644 --- a/readme.md +++ b/readme.md @@ -30,8 +30,9 @@ This package is created to handle [server-side](https://www.datatables.net/manua - Works with Laravel Dependency Injection and IoC Container. - Provides a [DataTable Html Builder](http://datatables.yajrabox.com/html) to help you use the package with less code. - Provides XSS filtering function to optionally escape all or specified column values using `escapeColumns('*'\['column'])` method. -- Provides Query Logging when application is in debug state. **Important: Make sure that debug is set to false when your code is in production** -- Easily attach a resource on json response via `->with()` +- Provides Query Logging when application is in debug state. + **Important: Make sure that debug is set to false when your code is in production** +- Easily attach a resource on json response via `->with()` method. - Built-in support for exporting to CSV, EXCEL and PDF using [Laravel-Excel](https://github.com/Maatwebsite/Laravel-Excel). - Built-in printer friendly view or create your own by overriding `printPreview()` method. - Provides an artisan command for generating a DataTable service and scope. @@ -57,12 +58,12 @@ Most of the latest updates/features are not available on these versions. Please `composer require yajra/laravel-datatables-oracle:~6.0` #### Service Provider -`Yajra\Datatables\DatatablesServiceProvider` +`Yajra\Datatables\DatatablesServiceProvider::class` #### Facade `Datatables` facade are automatically registered as an alias for `Yajra\Datatables\Datatables` class. -#### Configuration +#### Configuration and Assets `$ php artisan vendor:publish --tag=datatables` And that's it! Start building out some awesome DataTables! From c717de511f5f8fca3bb28ebb8a5472fd1c1009bc Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 21 Jan 2016 09:26:34 +0800 Subject: [PATCH 034/322] Fix datatables service stub. --- CHANGELOG.md | 3 +++ src/Generators/stubs/datatables.stub | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2c18ee3..b87b49f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +###v6.3.1 + - Fix artisan datatables:make service stub. + ###v6.3.0 - Add option to override default ordering via `->order(\Closure $callback)` method. - Add editor config. diff --git a/src/Generators/stubs/datatables.stub b/src/Generators/stubs/datatables.stub index ce7d59c7..817b8cf1 100644 --- a/src/Generators/stubs/datatables.stub +++ b/src/Generators/stubs/datatables.stub @@ -1,11 +1,11 @@ Date: Wed, 27 Jan 2016 12:05:31 +0100 Subject: [PATCH 035/322] Change how regex code is generated after a column search. Before this change, regex statements were generated with the MySQL operator 'REGEXP', which were leading to a Oracle error. Now it uses the Oracle Database SQL function 'REGEXP_LIKE', as written in the Oracle Database Online Documentation, 10g Release 2 (10.2) . --- src/Engines/QueryBuilderEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 966c5904..793174f8 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -220,14 +220,14 @@ public function columnSearch() $column = $this->castColumn($column); if ($this->isCaseInsensitive()) { if ($this->request->isRegex($i)) { - $this->query->whereRaw('LOWER(' . $column . ') REGEXP ?', [Str::lower($keyword)]); + $this->query->whereRaw(' REGEXP_LIKE( LOWER('.$column.') , ?, \'i\' )', [$keyword]); } else { $this->query->whereRaw('LOWER(' . $column . ') LIKE ?', [Str::lower($keyword)]); } } else { $col = strstr($column, '(') ? $this->connection->raw($column) : $column; if ($this->request->isRegex($i)) { - $this->query->whereRaw($col . ' REGEXP ?', [$keyword]); + $this->query->whereRaw(' REGEXP_LIKE( '.$col.' , ? )', [$keyword]); } else { $this->query->whereRaw($col . ' LIKE ?', [$keyword]); } From 0e5adb94ee94f12f664ee8658a0b1caae77fb643 Mon Sep 17 00:00:00 2001 From: ansient Date: Wed, 3 Feb 2016 11:44:25 +0100 Subject: [PATCH 036/322] Now the QueryBuilderEngine checks if the language is Mysql or Oracle based when building Regex statements. Mysql Sql syntax is assumed by default. To change this behaviour a toggle has been added in the config file. --- src/Engines/BaseEngine.php | 10 ++++++++++ src/Engines/QueryBuilderEngine.php | 12 ++++++++++-- src/config/config.php | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 26fa1f01..85da2b88 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -855,4 +855,14 @@ public function order(\Closure $closure) return $this; } + + /** + * Check if the current sql language is based on oracle syntax. + * + * @return bool + */ + public function isOracleSql() + { + return Config::get('datatables.oracle_sql', false); + } } diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 793174f8..b5993487 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -220,14 +220,22 @@ public function columnSearch() $column = $this->castColumn($column); if ($this->isCaseInsensitive()) { if ($this->request->isRegex($i)) { - $this->query->whereRaw(' REGEXP_LIKE( LOWER('.$column.') , ?, \'i\' )', [$keyword]); + if($this->isOracleSql()){ + $this->query->whereRaw(' REGEXP_LIKE( LOWER('.$column.') , ?, \'i\' )', [$keyword]); + }else{ + $this->query->whereRaw('LOWER(' . $column . ') REGEXP ?', [Str::lower($keyword)]); + } } else { $this->query->whereRaw('LOWER(' . $column . ') LIKE ?', [Str::lower($keyword)]); } } else { $col = strstr($column, '(') ? $this->connection->raw($column) : $column; if ($this->request->isRegex($i)) { - $this->query->whereRaw(' REGEXP_LIKE( '.$col.' , ? )', [$keyword]); + if($this->isOracleSql()){ + $this->query->whereRaw(' REGEXP_LIKE( '.$col.' , ? )', [$keyword]); + }else{ + $this->query->whereRaw($col . ' REGEXP ?', [$keyword]); + } } else { $this->query->whereRaw($col . ' LIKE ?', [$keyword]); } diff --git a/src/config/config.php b/src/config/config.php index bce2fc82..91a489bc 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -2,6 +2,8 @@ return [ + 'oracle_sql' => false, + 'search' => [ 'case_insensitive' => true, 'use_wildcards' => false, From 8c7f94eb6a3e0004c912758c9b14b1ff87216ff8 Mon Sep 17 00:00:00 2001 From: Worm Date: Wed, 3 Feb 2016 23:04:48 +0500 Subject: [PATCH 037/322] Update QueryBuilderEngine.php public function count(). If I use in SELECT same custom values, for example (count(samevalue)/count(other_same_value) as `3value`) and use in "group by" or "order by" this value, I have error: Column not found: 1054 Unknown column '3value' in 'order clause' :( --- src/Engines/QueryBuilderEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 966c5904..10d695b8 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -85,7 +85,7 @@ 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'])) { + if (! Str::contains(Str::lower($myQuery->toSql()), ['union', 'having', 'distinct', 'as', 'order by', 'group by'])) { $row_count = $this->connection->getQueryGrammar()->wrap('row_count'); $myQuery->select($this->connection->raw("'1' as {$row_count}")); } From 1e7a2b3d217478b74a12a8098f65e2e3ea9cdce6 Mon Sep 17 00:00:00 2001 From: Viktoras Varnauskas Date: Wed, 3 Feb 2016 22:46:53 +0200 Subject: [PATCH 038/322] Global search on eager loaded models --- src/Engines/QueryBuilderEngine.php | 36 ++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 966c5904..f11e6159 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -99,8 +99,10 @@ public function count() */ public function filtering() { + $eagerLoads = array_keys($this->query->getEagerLoads()); + $this->query->where( - function ($query) { + function ($query) use ($eagerLoads) { $keyword = $this->setupKeyword($this->request->keyword()); foreach ($this->request->searchableColumnIndex() as $index) { $columnName = $this->setupColumnName($index); @@ -112,7 +114,19 @@ function ($query) { $this->getQueryBuilder($query), $method, $parameters, $columnName, $keyword ); } else { - $this->compileGlobalSearch($this->getQueryBuilder($query), $columnName, $keyword); + if (count(explode('.', $columnName)) > 1) { + $parts = explode('.', $columnName); + $columnName = array_pop($parts); + $relation = implode('.', $parts); + + if (in_array($relation, $eagerLoads)) { + $this->CompileRelationSearch($this->getQueryBuilder($query), $relation, $columnName, $keyword); + } else { + $this->compileGlobalSearch($this->getQueryBuilder($query), $columnName, $keyword); + } + } else { + $this->compileGlobalSearch($this->getQueryBuilder($query), $columnName, $keyword); + } } $this->isFilterApplied = true; @@ -185,6 +199,24 @@ protected function compileGlobalSearch($query, $column, $keyword) $query->orWhereRaw($sql, [$keyword]); } + /** + * Add relation query on global search + * + * @param mixed $query + * @param string $column + * @param string $keyword + */ + protected function CompileRelationSearch($query, $relation, $column, $keyword) + { + $myQuery = clone $this->query; + $myQuery->orWhereHas($relation, function($q) use ($column, $keyword, $query) { + $q->where($column, 'like', $keyword); + $sql = $q->toSql(); + $sql = "($sql) >= 1"; + $query->orWhereRaw($sql, [$keyword]); + }); + } + /** * Wrap a column and cast in pgsql * From 58fa9ebbf142f9660a3886375616383663730c64 Mon Sep 17 00:00:00 2001 From: Worm Date: Thu, 4 Feb 2016 11:21:30 +0500 Subject: [PATCH 039/322] Update QueryBuilderEngine.php --- src/Engines/QueryBuilderEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 10d695b8..cb8907e1 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -85,7 +85,7 @@ 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', 'as', 'order by', 'group by'])) { + if (! Str::contains(Str::lower($myQuery->toSql()), ['union', 'having', 'distinct', 'order by', 'group by'])) { $row_count = $this->connection->getQueryGrammar()->wrap('row_count'); $myQuery->select($this->connection->raw("'1' as {$row_count}")); } From 129599c9f40ac399687234f06e2ebadccf6121dd Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 4 Feb 2016 15:49:10 +0800 Subject: [PATCH 040/322] Bump v6.3.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b87b49f1..fb90f291 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.3.2 - 2016-02-04 + - Add order by and group by on count sql optimization exceptions. + - Date will now be added on each released version using Y-m-d format. + ###v6.3.1 - Fix artisan datatables:make service stub. From b0ba84d6921526ada826154c14969526d21613ce Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 10 Feb 2016 09:52:58 +0800 Subject: [PATCH 041/322] Extract getEagerLoads and handle error when using a builder. --- src/Engines/QueryBuilderEngine.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 5e4c234f..0762bf0d 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -99,7 +99,7 @@ public function count() */ public function filtering() { - $eagerLoads = array_keys($this->query->getEagerLoads()); + $eagerLoads = $this->getEagerLoads(); $this->query->where( function ($query) use ($eagerLoads) { @@ -135,6 +135,20 @@ function ($query) use ($eagerLoads) { ); } + /** + * Get eager loads keys if eloquent. + * + * @return array + */ + private function getEagerLoads() + { + if ($this->query_type == 'eloquent') { + return array_keys($this->query->getEagerLoads()); + } + + return []; + } + /** * Perform filter column on selected field. * From 915bf901a5a38def798bfbd36548dbace39af07e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 10 Feb 2016 09:53:27 +0800 Subject: [PATCH 042/322] Fix method name, cs and docblocks. --- src/Engines/QueryBuilderEngine.php | 47 +++++++++++++++--------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 0762bf0d..e84f8da2 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -115,12 +115,13 @@ function ($query) use ($eagerLoads) { ); } else { if (count(explode('.', $columnName)) > 1) { - $parts = explode('.', $columnName); + $parts = explode('.', $columnName); $columnName = array_pop($parts); - $relation = implode('.', $parts); - + $relation = implode('.', $parts); + if (in_array($relation, $eagerLoads)) { - $this->CompileRelationSearch($this->getQueryBuilder($query), $relation, $columnName, $keyword); + $this->compileRelationSearch($this->getQueryBuilder($query), $relation, $columnName, + $keyword); } else { $this->compileGlobalSearch($this->getQueryBuilder($query), $columnName, $keyword); } @@ -194,6 +195,24 @@ protected function parameterize() return $parameters; } + /** + * Add relation query on global search. + * + * @param mixed $query + * @param string $column + * @param string $keyword + */ + protected function compileRelationSearch($query, $relation, $column, $keyword) + { + $myQuery = clone $this->query; + $myQuery->orWhereHas($relation, function ($q) use ($column, $keyword, $query) { + $q->where($column, 'like', $keyword); + $sql = $q->toSql(); + $sql = "($sql) >= 1"; + $query->orWhereRaw($sql, [$keyword]); + }); + } + /** * Add a query on global search. * @@ -214,25 +233,7 @@ protected function compileGlobalSearch($query, $column, $keyword) } /** - * Add relation query on global search - * - * @param mixed $query - * @param string $column - * @param string $keyword - */ - protected function CompileRelationSearch($query, $relation, $column, $keyword) - { - $myQuery = clone $this->query; - $myQuery->orWhereHas($relation, function($q) use ($column, $keyword, $query) { - $q->where($column, 'like', $keyword); - $sql = $q->toSql(); - $sql = "($sql) >= 1"; - $query->orWhereRaw($sql, [$keyword]); - }); - } - - /** - * Wrap a column and cast in pgsql + * Wrap a column and cast in pgsql. * * @param string $column * @return string From 5e82aa8424b7d6c3498dc37156302e70cfca402d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 10 Feb 2016 10:09:46 +0800 Subject: [PATCH 043/322] Fix columnName conflict when using join statements. --- src/Engines/QueryBuilderEngine.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index e84f8da2..35564c4b 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -116,10 +116,9 @@ function ($query) use ($eagerLoads) { } else { if (count(explode('.', $columnName)) > 1) { $parts = explode('.', $columnName); - $columnName = array_pop($parts); - $relation = implode('.', $parts); - + $relation = $parts[0]; if (in_array($relation, $eagerLoads)) { + $columnName = array_pop($parts); $this->compileRelationSearch($this->getQueryBuilder($query), $relation, $columnName, $keyword); } else { From 13da9b2f727bc7082219de912138c61140872c68 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 10 Feb 2016 10:38:08 +0800 Subject: [PATCH 044/322] Bump v6.4.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb90f291..0f20da6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +###v6.4.0 - 2016-02-10 + - Add feature to support global search on eager loaded models. + - PR #381. Credits to @ikerasLT. + - Fix implementation conflicts when using builder and join statements. + - Fix cs and doc blocks. + ###v6.3.2 - 2016-02-04 - Add order by and group by on count sql optimization exceptions. - Date will now be added on each released version using Y-m-d format. From d01324ceb32015aa98e1c7be8e1bb86aafc08ccb Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 10 Feb 2016 11:12:28 +0800 Subject: [PATCH 045/322] Fix nested eager loaded column name. --- src/Engines/QueryBuilderEngine.php | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 35564c4b..1c8d8ab2 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -115,12 +115,16 @@ function ($query) use ($eagerLoads) { ); } else { if (count(explode('.', $columnName)) > 1) { - $parts = explode('.', $columnName); - $relation = $parts[0]; + $parts = explode('.', $columnName); + $relationColumn = array_pop($parts); + $relation = implode('.', $parts); if (in_array($relation, $eagerLoads)) { - $columnName = array_pop($parts); - $this->compileRelationSearch($this->getQueryBuilder($query), $relation, $columnName, - $keyword); + $this->compileRelationSearch( + $this->getQueryBuilder($query), + $relation, + $relationColumn, + $keyword + ); } else { $this->compileGlobalSearch($this->getQueryBuilder($query), $columnName, $keyword); } From a794d7904139c4928785f6129373639682a17e24 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 10 Feb 2016 11:13:45 +0800 Subject: [PATCH 046/322] Bump v6.4.1 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f20da6a..64325266 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +###v6.4.1 - 2016-02-10 + - Fix nested eager loaded relations and column name. + ###v6.4.0 - 2016-02-10 - Add feature to support global search on eager loaded models. - PR #381. Credits to @ikerasLT. From 181cb91691b94edc8c4e0367fd3ec7edad4616eb Mon Sep 17 00:00:00 2001 From: Patrick Way Date: Wed, 10 Feb 2016 17:28:31 -0500 Subject: [PATCH 047/322] Fix addColumn fails when order falls at end of array yajra/laravel-datatables#385 --- src/Helper.php | 2 +- tests/HelperTest.php | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Helper.php b/src/Helper.php index 7f37303f..5705f083 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -19,7 +19,7 @@ class Helper */ public static function includeInArray($item, $array) { - if ($item['order'] === false) { + if ($item['order'] === false || $item['order'] >= count($array)) { return array_merge($array, [$item['name'] => $item['content']]); } else { $count = 0; diff --git a/tests/HelperTest.php b/tests/HelperTest.php index c7289445..6ab97bd5 100644 --- a/tests/HelperTest.php +++ b/tests/HelperTest.php @@ -44,6 +44,27 @@ public function test_include_in_array_with_order() $this->assertEquals($expected, $data); } + public function test_include_in_array_with_order_outside_of_array_length() + { + $data = [ + 'id' => 1, + 'foo' => 'bar', + ]; + $item = [ + 'name' => 'user', + 'content' => 'John', + 'order' => 2, + ]; + + $data = Helper::includeInArray($item, $data); + $expected = [ + 'id' => 1, + 'foo' => 'bar', + 'user' => 'John', + ]; + $this->assertEquals($expected, $data); + } + public function test_compile_content_blade() { $content = '{!! $id !!}'; From 04d8d3d98c8d12a6aed5315400256ea2cb8fedce Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 08:34:56 +0800 Subject: [PATCH 048/322] Bump v6.4.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64325266..6a1b0265 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.4.2 - 2016-02-11 + - Change how regex code is generated after a column search. #358 + - Fix addColumn fails when order falls at end of array #386 + ###v6.4.1 - 2016-02-10 - Fix nested eager loaded relations and column name. From 7cb59cfdaad3f000545cf3ad89415b295a20ee14 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 10:37:18 +0800 Subject: [PATCH 049/322] Fix cs. --- src/Engines/BaseEngine.php | 4 ++-- src/Engines/QueryBuilderEngine.php | 20 ++++++++++---------- src/config/config.php | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 85da2b88..39857211 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -855,8 +855,8 @@ public function order(\Closure $closure) return $this; } - - /** + + /** * Check if the current sql language is based on oracle syntax. * * @return bool diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index a79b07ec..79cadbb8 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -270,22 +270,22 @@ public function columnSearch() $column = $this->castColumn($column); if ($this->isCaseInsensitive()) { if ($this->request->isRegex($i)) { - if($this->isOracleSql()){ - $this->query->whereRaw(' REGEXP_LIKE( LOWER('.$column.') , ?, \'i\' )', [$keyword]); - }else{ - $this->query->whereRaw('LOWER(' . $column . ') REGEXP ?', [Str::lower($keyword)]); - } + if ($this->isOracleSql()) { + $this->query->whereRaw(' REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )', [$keyword]); + } else { + $this->query->whereRaw('LOWER(' . $column . ') REGEXP ?', [Str::lower($keyword)]); + } } else { $this->query->whereRaw('LOWER(' . $column . ') LIKE ?', [Str::lower($keyword)]); } } else { $col = strstr($column, '(') ? $this->connection->raw($column) : $column; if ($this->request->isRegex($i)) { - if($this->isOracleSql()){ - $this->query->whereRaw(' REGEXP_LIKE( '.$col.' , ? )', [$keyword]); - }else{ - $this->query->whereRaw($col . ' REGEXP ?', [$keyword]); - } + if ($this->isOracleSql()) { + $this->query->whereRaw(' REGEXP_LIKE( ' . $col . ' , ? )', [$keyword]); + } else { + $this->query->whereRaw($col . ' REGEXP ?', [$keyword]); + } } else { $this->query->whereRaw($col . ' LIKE ?', [$keyword]); } diff --git a/src/config/config.php b/src/config/config.php index 91a489bc..00ace925 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -2,14 +2,14 @@ return [ - 'oracle_sql' => false, + 'oracle_sql' => false, - 'search' => [ + 'search' => [ 'case_insensitive' => true, 'use_wildcards' => false, ], - 'fractal' => [ + 'fractal' => [ 'serializer' => 'League\Fractal\Serializer\DataArraySerializer', ], From 4c331b9140265e3cdc0509247234677db80d060f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 10:41:37 +0800 Subject: [PATCH 050/322] Extract isItemOrderInvalid. --- src/Helper.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/Helper.php b/src/Helper.php index 5705f083..4cf1d8eb 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -19,7 +19,7 @@ class Helper */ public static function includeInArray($item, $array) { - if ($item['order'] === false || $item['order'] >= count($array)) { + if (self::isItemOrderInvalid($item, $array)) { return array_merge($array, [$item['name'] => $item['content']]); } else { $count = 0; @@ -38,6 +38,18 @@ public static function includeInArray($item, $array) } } + /** + * Check if item order is valid. + * + * @param array $item + * @param array $array + * @return bool + */ + protected static function isItemOrderInvalid($item, $array) + { + return $item['order'] === false || $item['order'] >= count($array); + } + /** * Determines if content is callable or blade string, processes and returns. * From 0970951afd6f893391510bbdaffbb735e9c952c2 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 11:04:18 +0800 Subject: [PATCH 051/322] Update doc blocks. --- src/Engines/QueryBuilderEngine.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 79cadbb8..012feaf3 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -95,7 +95,9 @@ public function count() } /** - * @inheritdoc + * Perform global search. + * + * @return void */ public function filtering() { @@ -202,6 +204,7 @@ protected function parameterize() * Add relation query on global search. * * @param mixed $query + * @param string $relation * @param string $column * @param string $keyword */ @@ -252,7 +255,9 @@ public function castColumn($column) } /** - * @inheritdoc + * Perform column search. + * + * @return void */ public function columnSearch() { From e6362c054787ba9d7b95f18855e8c5948b3e4df0 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 11:06:57 +0800 Subject: [PATCH 052/322] Fix cs. --- src/Engines/QueryBuilderEngine.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 012feaf3..c804411d 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -113,7 +113,11 @@ function ($query) use ($eagerLoads) { $method = Helper::getOrMethod($this->columnDef['filter'][$columnName]['method']); $parameters = $this->columnDef['filter'][$columnName]['parameters']; $this->compileColumnQuery( - $this->getQueryBuilder($query), $method, $parameters, $columnName, $keyword + $this->getQueryBuilder($query), + $method, + $parameters, + $columnName, + $keyword ); } else { if (count(explode('.', $columnName)) > 1) { From a3f97dfe253fd7f0fd0a4181a70536ad1c4bce66 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 11:08:10 +0800 Subject: [PATCH 053/322] Refactor column search to reduce complexity. --- src/Engines/QueryBuilderEngine.php | 60 +++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index c804411d..8a7a476c 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -278,26 +278,10 @@ public function columnSearch() } else { $column = $this->castColumn($column); if ($this->isCaseInsensitive()) { - if ($this->request->isRegex($i)) { - if ($this->isOracleSql()) { - $this->query->whereRaw(' REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )', [$keyword]); - } else { - $this->query->whereRaw('LOWER(' . $column . ') REGEXP ?', [Str::lower($keyword)]); - } - } else { - $this->query->whereRaw('LOWER(' . $column . ') LIKE ?', [Str::lower($keyword)]); - } + $this->caseInsensitiveColumnSearch($i, $column, $keyword); } else { $col = strstr($column, '(') ? $this->connection->raw($column) : $column; - if ($this->request->isRegex($i)) { - if ($this->isOracleSql()) { - $this->query->whereRaw(' REGEXP_LIKE( ' . $col . ' , ? )', [$keyword]); - } else { - $this->query->whereRaw($col . ' REGEXP ?', [$keyword]); - } - } else { - $this->query->whereRaw($col . ' LIKE ?', [$keyword]); - } + $this->caseSensitiveColumnSearch($i, $col, $keyword); } } @@ -321,6 +305,46 @@ private function getSearchKeyword($i) return $this->setupKeyword($this->request->columnKeyword($i)); } + /** + * Perform case insensitive column search. + * + * @param int $i + * @param string $column + * @param string $keyword + */ + protected function caseInsensitiveColumnSearch($i, $column, $keyword) + { + if ($this->request->isRegex($i)) { + if ($this->isOracleSql()) { + $this->query->whereRaw('REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )', [$keyword]); + } else { + $this->query->whereRaw('LOWER(' . $column . ') REGEXP ?', [Str::lower($keyword)]); + } + } else { + $this->query->whereRaw('LOWER(' . $column . ') LIKE ?', [Str::lower($keyword)]); + } + } + + /** + * Perform case sensitive column search. + * + * @param int $i + * @param string $column + * @param string $keyword + */ + protected function caseSensitiveColumnSearch($i, $column, $keyword) + { + if ($this->request->isRegex($i)) { + if ($this->isOracleSql()) { + $this->query->whereRaw('REGEXP_LIKE( ' . $column . ' , ? )', [$keyword]); + } else { + $this->query->whereRaw($column . ' REGEXP ?', [$keyword]); + } + } else { + $this->query->whereRaw($column . ' LIKE ?', [$keyword]); + } + } + /** * @inheritdoc */ From 46b375b9f9187c6d4aab037ddf4d264435665d8d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 13:01:05 +0800 Subject: [PATCH 054/322] Extract regex search to own method. --- src/Engines/QueryBuilderEngine.php | 45 ++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 8a7a476c..820131cf 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -309,42 +309,63 @@ private function getSearchKeyword($i) * Perform case insensitive column search. * * @param int $i - * @param string $column + * @param mixed $column * @param string $keyword */ protected function caseInsensitiveColumnSearch($i, $column, $keyword) { if ($this->request->isRegex($i)) { - if ($this->isOracleSql()) { - $this->query->whereRaw('REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )', [$keyword]); - } else { - $this->query->whereRaw('LOWER(' . $column . ') REGEXP ?', [Str::lower($keyword)]); - } + $this->regexCaseInsensitiveColumnSearch($column, $keyword); } else { $this->query->whereRaw('LOWER(' . $column . ') LIKE ?', [Str::lower($keyword)]); } } + /** + * Perform regex case insensitive column search. + * + * @param mixed $column + * @param string $keyword + */ + protected function regexCaseInsensitiveColumnSearch($column, $keyword) + { + if ($this->isOracleSql()) { + $this->query->whereRaw('REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )', [$keyword]); + } else { + $this->query->whereRaw('LOWER(' . $column . ') REGEXP ?', [Str::lower($keyword)]); + } + } + /** * Perform case sensitive column search. * * @param int $i - * @param string $column + * @param mixed $column * @param string $keyword */ protected function caseSensitiveColumnSearch($i, $column, $keyword) { if ($this->request->isRegex($i)) { - if ($this->isOracleSql()) { - $this->query->whereRaw('REGEXP_LIKE( ' . $column . ' , ? )', [$keyword]); - } else { - $this->query->whereRaw($column . ' REGEXP ?', [$keyword]); - } + $this->regexCaseSensitiveColumnSearch($column, $keyword); } else { $this->query->whereRaw($column . ' LIKE ?', [$keyword]); } } + /** + * Perform regex case insensitive column search. + * @param mixed $column + * @param string $keyword + */ + protected function regexCaseSensitiveColumnSearch($column, $keyword) + { + if ($this->isOracleSql()) { + $this->query->whereRaw('REGEXP_LIKE( ' . $column . ' , ? )', [$keyword]); + } else { + $this->query->whereRaw($column . ' REGEXP ?', [$keyword]); + } + } + /** * @inheritdoc */ From f63a90f6c54f8c3872f8b31542dd1871e5baa2a6 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 13:17:13 +0800 Subject: [PATCH 055/322] Refactor column and regex search duplicate codes. --- src/Engines/QueryBuilderEngine.php | 52 ++++++++---------------------- 1 file changed, 14 insertions(+), 38 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 820131cf..61797ec9 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -278,10 +278,10 @@ public function columnSearch() } else { $column = $this->castColumn($column); if ($this->isCaseInsensitive()) { - $this->caseInsensitiveColumnSearch($i, $column, $keyword); + $this->compileColumnSearch($i, $column, $keyword, true); } else { $col = strstr($column, '(') ? $this->connection->raw($column) : $column; - $this->caseSensitiveColumnSearch($i, $col, $keyword); + $this->compileColumnSearch($i, $col, $keyword, false); } } @@ -311,13 +311,16 @@ private function getSearchKeyword($i) * @param int $i * @param mixed $column * @param string $keyword + * @param bool $caseSensitive */ - protected function caseInsensitiveColumnSearch($i, $column, $keyword) + protected function compileColumnSearch($i, $column, $keyword, $caseSensitive = true) { if ($this->request->isRegex($i)) { - $this->regexCaseInsensitiveColumnSearch($column, $keyword); + $this->regexColumnSearch($column, $keyword, $caseSensitive); } else { - $this->query->whereRaw('LOWER(' . $column . ') LIKE ?', [Str::lower($keyword)]); + $sql = $caseSensitive ? $column . ' LIKE ?' : 'LOWER(' . $column . ') LIKE ?'; + $keyword = $caseSensitive ? $keyword : Str::lower($keyword); + $this->query->whereRaw($sql, [$keyword]); } } @@ -326,43 +329,16 @@ protected function caseInsensitiveColumnSearch($i, $column, $keyword) * * @param mixed $column * @param string $keyword + * @param bool $caseSensitive */ - protected function regexCaseInsensitiveColumnSearch($column, $keyword) + protected function regexColumnSearch($column, $keyword, $caseSensitive = true) { if ($this->isOracleSql()) { - $this->query->whereRaw('REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )', [$keyword]); + $sql = $caseSensitive ? 'REGEXP_LIKE( ' . $column . ' , ? )' : 'REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )'; + $this->query->whereRaw($sql, [$keyword]); } else { - $this->query->whereRaw('LOWER(' . $column . ') REGEXP ?', [Str::lower($keyword)]); - } - } - - /** - * Perform case sensitive column search. - * - * @param int $i - * @param mixed $column - * @param string $keyword - */ - protected function caseSensitiveColumnSearch($i, $column, $keyword) - { - if ($this->request->isRegex($i)) { - $this->regexCaseSensitiveColumnSearch($column, $keyword); - } else { - $this->query->whereRaw($column . ' LIKE ?', [$keyword]); - } - } - - /** - * Perform regex case insensitive column search. - * @param mixed $column - * @param string $keyword - */ - protected function regexCaseSensitiveColumnSearch($column, $keyword) - { - if ($this->isOracleSql()) { - $this->query->whereRaw('REGEXP_LIKE( ' . $column . ' , ? )', [$keyword]); - } else { - $this->query->whereRaw($column . ' REGEXP ?', [$keyword]); + $sql = $caseSensitive ? $column . ' REGEXP ?' : 'LOWER(' . $column . ') REGEXP ?'; + $this->query->whereRaw($sql, [Str::lower($keyword)]); } } From 0d65c35d8664583162c2a05731f165d4db62fda7 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 14:09:27 +0800 Subject: [PATCH 056/322] Update doc blocks. --- src/Engines/QueryBuilderEngine.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 61797ec9..93b2f80a 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -306,7 +306,7 @@ private function getSearchKeyword($i) } /** - * Perform case insensitive column search. + * Compile queries for column search. * * @param int $i * @param mixed $column @@ -325,7 +325,7 @@ protected function compileColumnSearch($i, $column, $keyword, $caseSensitive = t } /** - * Perform regex case insensitive column search. + * Compile regex query column search. * * @param mixed $column * @param string $keyword @@ -343,7 +343,9 @@ protected function regexColumnSearch($column, $keyword, $caseSensitive = true) } /** - * @inheritdoc + * Perform sorting of columns. + * + * @return void */ public function ordering() { From ef33c84abcd41312335fdc80efcd555cc3451c89 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 11 Feb 2016 14:14:41 +0800 Subject: [PATCH 057/322] Bump v6.4.3 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a1b0265..b556725e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.4.3 - 2016-02-11 + - Random cs and doc block fix. + - Code refactoring to reduce complexity. + ###v6.4.2 - 2016-02-11 - Change how regex code is generated after a column search. #358 - Fix addColumn fails when order falls at end of array #386 From bdf8e466e92010d8bc36e5eec884fef1fb5b9be8 Mon Sep 17 00:00:00 2001 From: Fabrizio Bottino Date: Thu, 11 Feb 2016 14:08:16 +0100 Subject: [PATCH 058/322] Fix filtering in nested columns of Collections --- src/Engines/CollectionEngine.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 06d4271a..9ef91878 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -167,10 +167,13 @@ public function columnSearch() $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($data[$column]), Str::lower($keyword)) !== false; + return strpos(Str::lower($value), Str::lower($keyword)) !== false; } else { - return strpos($data[$column], $keyword) !== false; + return strpos($value, $keyword) !== false; } } ); From a72637f0cfc9957502d7c9998dc759c2fbe2ea8d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 13 Feb 2016 09:56:56 +0800 Subject: [PATCH 059/322] Bump v6.4.4 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b556725e..193f51d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +###v6.4.4 - 2016-02-13 + - Fix filtering in nested columns of Collections. PR #392 + ###v6.4.3 - 2016-02-11 - Random cs and doc block fix. - Code refactoring to reduce complexity. From d9533fb4377e5d905cf9baf03e1704f3d2ea20e4 Mon Sep 17 00:00:00 2001 From: ramil Date: Wed, 17 Feb 2016 16:26:55 +0300 Subject: [PATCH 060/322] Allow edit columns for nested arrays --- src/Processors/DataProcessor.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Processors/DataProcessor.php b/src/Processors/DataProcessor.php index 4bd0a088..4d8295ed 100644 --- a/src/Processors/DataProcessor.php +++ b/src/Processors/DataProcessor.php @@ -2,6 +2,7 @@ namespace Yajra\Datatables\Processors; +use Illuminate\Support\Arr; use Yajra\Datatables\Helper; /** @@ -115,7 +116,7 @@ protected function editColumns($data, $row) { foreach ($this->editColumns as $key => $value) { $value['content'] = Helper::compileContent($value['content'], $data, $row); - $data[$value['name']] = $value['content']; + Arr::set($data, $value['name'], $value['content']); } return $data; From 46d3b41164bd2d648dbf9a458ecf57fe318e5200 Mon Sep 17 00:00:00 2001 From: Ansient Date: Wed, 17 Feb 2016 15:51:21 +0100 Subject: [PATCH 061/322] In the refactoring process, of the column search system, an error related to case-sensitivity check led to a wrong interpretation and therefore to an incorrect behaviour of the logic. If the isCaseInsensitive function is true, the compileColumnSearch function is called with the flag caseSensitive set to true, clearly wrong. The same issue occurs if the isCaseInsensitive function is false. Now the boolean flag caseSensitive is set correctly for both if-else blocks. --- src/Engines/QueryBuilderEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 93b2f80a..935358dd 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -278,10 +278,10 @@ public function columnSearch() } else { $column = $this->castColumn($column); if ($this->isCaseInsensitive()) { - $this->compileColumnSearch($i, $column, $keyword, true); + $this->compileColumnSearch($i, $column, $keyword, false); } else { $col = strstr($column, '(') ? $this->connection->raw($column) : $column; - $this->compileColumnSearch($i, $col, $keyword, false); + $this->compileColumnSearch($i, $col, $keyword, true); } } From d114d2631c304fc34f1bc46ca44753da045059d5 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 18 Feb 2016 07:59:39 +0800 Subject: [PATCH 062/322] Bump v6.4.5 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 193f51d9..5b2922e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.4.5 - 2016-02-18 + - Allow edit columns for nested arrays. PR #399 - credits to @ramilexe + - Fix flag for case insensitive search. PR #400 - credits to @ansient + ###v6.4.4 - 2016-02-13 - Fix filtering in nested columns of Collections. PR #392 From 38b3066e8e9fab5f13ccd604b436899568675186 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 18 Feb 2016 09:17:44 +0800 Subject: [PATCH 063/322] Add support for DataTables valid callbacks. Fix #401 Fix #307 --- src/Html/Builder.php | 60 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 9cfb63fb..691dc893 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -67,6 +67,29 @@ class Builder */ 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 @@ -133,28 +156,57 @@ public function generateScripts() */ public function parameterize($attributes = []) { - $parameters = (new Parameters($attributes))->toArray(); - $column_functions = []; + $parameters = (new Parameters($attributes))->toArray(); + $columnFunctions = []; + $callbackFunctions = []; foreach ($parameters['columns'] as $i => $column) { unset($parameters['columns'][$i]['exportable']); unset($parameters['columns'][$i]['printable']); if (isset($column['render'])) { - $column_functions[$i] = $column['render']; + $columnFunctions[$i] = $column['render']; $parameters['columns'][$i]['render'] = "#column_function.{$i}#"; } } + foreach ($parameters as $key => $callback) { + if (in_array($key, $this->validCallbacks)) { + $callbackFunctions[$key] = $this->compileCallback($callback); + $parameters[$key] = "#callback_function.{$key}#"; + } + } + $json = json_encode($parameters); - foreach ($column_functions as $i => $function) { + foreach ($columnFunctions as $i => $function) { $json = str_replace("\"#column_function.{$i}#\"", $function, $json); } + foreach ($callbackFunctions as $i => $function) { + $json = str_replace("\"#callback_function.{$i}#\"", $function, $json); + } + return $json; } + /** + * 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; + } + /** * Get javascript template to use. * From ae9531ae0aa3d44d8976c5cc253c8a6b18657cad Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 18 Feb 2016 09:23:25 +0800 Subject: [PATCH 064/322] Fix cs. --- src/Html/Builder.php | 48 ++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 691dc893..4d5712bc 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -305,19 +305,17 @@ public function getQualifiedTitle($title) */ public function addCheckbox(array $attributes = []) { - $attributes = array_merge( - [ - 'defaultContent' => '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 - ); + $attributes = array_merge([ + 'defaultContent' => '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; @@ -331,19 +329,17 @@ public function addCheckbox(array $attributes = []) */ 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, - ], $attributes - ); + $attributes = array_merge([ + 'defaultContent' => '', + 'data' => 'action', + 'name' => 'action', + 'title' => 'Action', + 'render' => null, + 'orderable' => false, + 'searchable' => false, + 'exportable' => false, + 'printable' => true, + ], $attributes); $this->collection->push(new Column($attributes)); return $this; From bdd2987f71dfb0c3e949fc174190ff1ca70a61db Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 18 Feb 2016 09:27:55 +0800 Subject: [PATCH 065/322] Bump v6.5.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b2922e5..8d344de6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.5.0 - 2016-02-18 + - Add support for DataTables valid callbacks. + - Fix issue #387 & #401. + ###v6.4.5 - 2016-02-18 - Allow edit columns for nested arrays. PR #399 - credits to @ramilexe - Fix flag for case insensitive search. PR #400 - credits to @ansient From 41b7e01ffbb3386a86221b59650cde6e45c9bf87 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 18 Feb 2016 11:46:34 +0800 Subject: [PATCH 066/322] Refactor parameterize method. --- src/Html/Builder.php | 82 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 4d5712bc..d9d66e2e 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -149,17 +149,35 @@ public function generateScripts() } /** - * Generate datatable js parameters. + * Generate DataTables js parameters. * * @param array $attributes * @return string */ public function parameterize($attributes = []) { - $parameters = (new Parameters($attributes))->toArray(); - $columnFunctions = []; - $callbackFunctions = []; + $parameters = (new Parameters($attributes))->toArray(); + + list($columnFunctions, $parameters) = $this->encodeColumnFunctions($parameters); + list($callbackFunctions, $parameters) = $this->encodeCallbackFunctions($parameters); + + $json = json_encode($parameters); + + $json = $this->decodeColumnFunctions($columnFunctions, $json); + $json = $this->decodeCallbackFunctions($callbackFunctions, $json); + + return $json; + } + /** + * 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']); @@ -170,6 +188,18 @@ public function parameterize($attributes = []) } } + 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); @@ -177,17 +207,7 @@ public function parameterize($attributes = []) } } - $json = json_encode($parameters); - - foreach ($columnFunctions as $i => $function) { - $json = str_replace("\"#column_function.{$i}#\"", $function, $json); - } - - foreach ($callbackFunctions as $i => $function) { - $json = str_replace("\"#callback_function.{$i}#\"", $function, $json); - } - - return $json; + return [$callbackFunctions, $parameters]; } /** @@ -207,6 +227,38 @@ private function compileCallback($callback) return $callback; } + /** + * 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. * From 3d14cf5eab093a9180ff8dd28fa9347e48fb160f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 18 Feb 2016 13:58:35 +0800 Subject: [PATCH 067/322] Fix ordering column name detection. Fix #339. --- src/Engines/QueryBuilderEngine.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 935358dd..dbb7caca 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -364,15 +364,6 @@ public function ordering() $this->getQueryBuilder(), $method, $parameters, $column, $orderable['direction'] ); } else { - /** - * If we perform a select("*"), the ORDER BY clause will look like this: - * ORDER BY * ASC - * which causes a query exception - * The temporary fix is modify `*` column to `id` column - */ - if ($column === '*') { - $column = 'id'; - } $this->getQueryBuilder()->orderBy($column, $orderable['direction']); } } @@ -387,8 +378,8 @@ public function ordering() private function setupOrderColumn(array $orderable) { $r_column = $this->request->input('columns')[$orderable['column']]; - $column = isset($r_column['name']) ? $r_column['name'] : $r_column['data']; - if ($column >= 0) { + $column = isset($r_column['name']) && $r_column['name'] <> '' ? $r_column['name'] : $r_column['data']; + if (is_int($column)) { $column = $this->setupColumnName($orderable['column'], true); return $column; From 368b40d9e34203346dc15790e6861a74b5337f23 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 18 Feb 2016 13:58:53 +0800 Subject: [PATCH 068/322] Update paging docblock. --- src/Engines/QueryBuilderEngine.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index dbb7caca..9379d125 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -389,7 +389,9 @@ private function setupOrderColumn(array $orderable) } /** - * @inheritdoc + * Perform pagination + * + * @return void */ public function paging() { From 671a1414ceda2600ba785eb40bb59a099e7397af Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 09:07:04 +0800 Subject: [PATCH 069/322] Bump v6.5.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d344de6..4430815c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.5.1 - 2016-02-19 + - Fix ordering column name detection. Issue #339. + - Refactor Builder parameterize method. + ###v6.5.0 - 2016-02-18 - Add support for DataTables valid callbacks. - Fix issue #387 & #401. From 05d41af22fdc108c9bbaac9116d59962b513307e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 10:16:44 +0800 Subject: [PATCH 070/322] Add totalCount on contact. Remove excess new line. --- src/Contracts/DataTableEngineContract.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Contracts/DataTableEngineContract.php b/src/Contracts/DataTableEngineContract.php index 33f03db0..8d6d31a1 100644 --- a/src/Contracts/DataTableEngineContract.php +++ b/src/Contracts/DataTableEngineContract.php @@ -18,6 +18,13 @@ public function results(); */ public function count(); + /** + * Count total items. + * + * @return integer + */ + public function totalCount(); + /** * Set auto filter off and run your own filter. * Overrides global search @@ -55,7 +62,6 @@ public function paging(); */ public function ordering(); - /** * Organizes works * From 425f65bf260d56ebe23d5cba3256113e12018e78 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 10:49:06 +0800 Subject: [PATCH 071/322] Improve ordering and filtering column name detection. --- src/Engines/BaseEngine.php | 157 +++++++++++++++++++---------- src/Engines/CollectionEngine.php | 10 +- src/Engines/QueryBuilderEngine.php | 25 +---- 3 files changed, 109 insertions(+), 83 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 39857211..b97b0cd3 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -232,62 +232,6 @@ public function wildcardLikeString($str, $lowercase = true) return $wild; } - /** - * Setup column name to be use for filtering. - * - * @param integer $i - * @param bool $wantsAlias - * @return string - */ - public function setupColumnName($i, $wantsAlias = false) - { - $column = $this->getColumnName($i); - if (Str::contains(Str::upper($column), ' AS ')) { - $column = $this->extractColumnName($column, $wantsAlias); - } - - return $column; - } - - /** - * Get column name by order column index. - * - * @param int $column - * @return mixed - */ - protected function getColumnName($column) - { - $name = $this->request->columnName($column) ?: (isset($this->columns[$column]) ? $this->columns[$column] : $this->columns[0]); - - return in_array($name, $this->extraColumns, true) ? $this->columns[0] : $name; - } - - /** - * Get column name from string. - * - * @param string $str - * @param bool $wantsAlias - * @return string - */ - public 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; - } - /** * Will prefix column if needed. * @@ -421,6 +365,7 @@ public function escapeColumns($columns = '*') /** * 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 $name * @param $arguments @@ -865,4 +810,104 @@ public function isOracleSql() { return Config::get('datatables.oracle_sql', false); } + + /** + * Get column name to be use for filtering. + * + * @param integer $index + * @param bool $wantsAlias + * @return string + */ + protected function getColumnName($index, $wantsAlias = false) + { + $column = $this->getColumnNameFromRequest($index); + + // DataTables is using make(false) + if (is_int($column)) { + $column = $this->getColumnNameByIndex($index); + } + + if (Str::contains(Str::upper($column), ' AS ')) { + $column = $this->extractColumnName($column, $wantsAlias); + } + + return $column; + } + + /** + * Get column name from request. + * + * @param int $index + * @return string + */ + protected function getColumnNameFromRequest($index) + { + $r_column = $this->request->input('columns')[$index]; + $column = isset($r_column['name']) && $r_column['name'] <> '' ? $r_column['name'] : $r_column['data']; + + 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->getFallbackColumnName(); + + return in_array($name, $this->extraColumns, true) ? $this->getFallbackColumnName() : $name; + } + + /** + * If query uses select *, then get the primary key column as default name. + * + * @return string + */ + protected function getFallbackColumnName() + { + if ($this->isEloquent()) { + return $this->getQueryBuilder()->getModel()->getKeyName(); + } + + return 'id'; + } + + /** + * Check if the engine use is 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; + } } diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 9ef91878..ac369791 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -105,7 +105,7 @@ public function ordering() } foreach ($this->request->orderableColumns() as $orderable) { - $column = $this->getColumnName($orderable['column']); + $column = $this->getColumnNameByIndex($orderable['column']); $this->collection = $this->collection->sortBy( function ($row) use ($column) { $data = $this->serialize($row); @@ -134,7 +134,7 @@ function ($row) use ($columns) { $keyword = $this->request->keyword(); foreach ($this->request->searchableColumnIndex() as $index) { - $column = $this->getColumnName($index); + $column = $this->getColumnNameByIndex($index); if (! $value = Arr::get($data, $column)) { continue; } @@ -161,15 +161,15 @@ public function columnSearch() if ($this->request->isColumnSearchable($i)) { $this->isFilterApplied = true; - $column = $this->getColumnName($i); + $column = $this->getColumnNameByIndex($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 { diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 9379d125..c283c04a 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -107,7 +107,7 @@ public function filtering() function ($query) use ($eagerLoads) { $keyword = $this->setupKeyword($this->request->keyword()); foreach ($this->request->searchableColumnIndex() as $index) { - $columnName = $this->setupColumnName($index); + $columnName = $this->getColumnName($index); if (isset($this->columnDef['filter'][$columnName])) { $method = Helper::getOrMethod($this->columnDef['filter'][$columnName]['method']); @@ -268,7 +268,7 @@ public function columnSearch() $columns = $this->request->get('columns'); for ($i = 0, $c = count($columns); $i < $c; $i++) { if ($this->request->isColumnSearchable($i)) { - $column = $this->setupColumnName($i); + $column = $this->getColumnName($i); $keyword = $this->getSearchKeyword($i); if (isset($this->columnDef['filter'][$column])) { @@ -356,7 +356,7 @@ public function ordering() } foreach ($this->request->orderableColumns() as $orderable) { - $column = $this->setupOrderColumn($orderable); + $column = $this->getColumnName($orderable['column'], true); if (isset($this->columnDef['order'][$column])) { $method = $this->columnDef['order'][$column]['method']; $parameters = $this->columnDef['order'][$column]['parameters']; @@ -369,25 +369,6 @@ public function ordering() } } - /** - * Get order by column name. - * - * @param array $orderable - * @return string - */ - private function setupOrderColumn(array $orderable) - { - $r_column = $this->request->input('columns')[$orderable['column']]; - $column = isset($r_column['name']) && $r_column['name'] <> '' ? $r_column['name'] : $r_column['data']; - if (is_int($column)) { - $column = $this->setupColumnName($orderable['column'], true); - - return $column; - } - - return $column; - } - /** * Perform pagination * From be94e69a25d499c16932337c481f52b0fbb9912f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 10:52:36 +0800 Subject: [PATCH 072/322] Remove unnecessary abstract function since we have a contract. --- src/Engines/BaseEngine.php | 58 -------------------------------------- 1 file changed, 58 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index b97b0cd3..381e5faf 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -548,13 +548,6 @@ public function make($mDataSupport = false, $orderFirst = false) return $this->render($mDataSupport); } - /** - * Count total items. - * - * @return integer - */ - abstract public function totalCount(); - /** * Sort records. * @@ -568,13 +561,6 @@ public function orderRecords($skip) } } - /** - * Perform sorting of columns. - * - * @return void - */ - abstract public function ordering(); - /** * Perform necessary filters. * @@ -594,27 +580,6 @@ public function filterRecords() $this->filteredRecords = $this->isFilterApplied ? $this->count() : $this->totalRecords; } - /** - * Perform global search. - * - * @return void - */ - abstract public function filtering(); - - /** - * Perform column search. - * - * @return void - */ - abstract public function columnSearch(); - - /** - * Count results. - * - * @return integer - */ - abstract public function count(); - /** * Apply pagination. * @@ -627,13 +592,6 @@ public function paginate() } } - /** - * Perform pagination - * - * @return void - */ - abstract public function paging(); - /** * Render json response. * @@ -686,13 +644,6 @@ public function render($object = false) return new JsonResponse($output); } - /** - * Get results - * - * @return array - */ - abstract public function results(); - /** * Get processed data * @@ -734,15 +685,6 @@ public function showDebugger(array $output) return $output; } - /** - * Set auto filter off and run your own filter. - * Overrides global search - * - * @param \Closure $callback - * @return $this - */ - abstract public function filter(\Closure $callback); - /** * Update flags to disable global search * From 798ad97f5832cfd951859908686b4e5a85a298cd Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 11:00:12 +0800 Subject: [PATCH 073/322] Remove implementation of contract since BaseEngine already requires it. --- src/Engines/CollectionEngine.php | 3 +-- src/Engines/EloquentEngine.php | 3 +-- src/Engines/QueryBuilderEngine.php | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index ac369791..d8c188e2 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -15,10 +15,9 @@ use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Str; -use Yajra\Datatables\Contracts\DataTableEngineContract; use Yajra\Datatables\Request; -class CollectionEngine extends BaseEngine implements DataTableEngineContract +class CollectionEngine extends BaseEngine { /** * Collection object diff --git a/src/Engines/EloquentEngine.php b/src/Engines/EloquentEngine.php index 7de02a05..ef4e2359 100644 --- a/src/Engines/EloquentEngine.php +++ b/src/Engines/EloquentEngine.php @@ -11,10 +11,9 @@ */ use Illuminate\Database\Eloquent\Builder; -use Yajra\Datatables\Contracts\DataTableEngineContract; use Yajra\Datatables\Request; -class EloquentEngine extends QueryBuilderEngine implements DataTableEngineContract +class EloquentEngine extends QueryBuilderEngine { /** * @param mixed $model diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index c283c04a..d75db3a7 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -13,11 +13,10 @@ use Closure; use Illuminate\Database\Query\Builder; use Illuminate\Support\Str; -use Yajra\Datatables\Contracts\DataTableEngineContract; use Yajra\Datatables\Helper; use Yajra\Datatables\Request; -class QueryBuilderEngine extends BaseEngine implements DataTableEngineContract +class QueryBuilderEngine extends BaseEngine { /** * @param \Illuminate\Database\Query\Builder $builder From 45af076cfeb15a3b2d434ec3f62e61760db4a88f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 11:06:46 +0800 Subject: [PATCH 074/322] Update docblock. --- src/Engines/BaseEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 381e5faf..7aa1017c 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -754,7 +754,7 @@ public function isOracleSql() } /** - * Get column name to be use for filtering. + * Get column name to be use for filtering and sorting. * * @param integer $index * @param bool $wantsAlias From 3a097b0f09880b863bc308578d811a8d4bc2d390 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 11:10:00 +0800 Subject: [PATCH 075/322] Fix grammar. --- src/Engines/BaseEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 7aa1017c..e0511695 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -818,7 +818,7 @@ protected function getFallbackColumnName() } /** - * Check if the engine use is eloquent. + * Check if the engine used was eloquent. * * @return bool */ From faaa504e4f62d97d3f3bb464949350a8ccacb98c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 11:33:45 +0800 Subject: [PATCH 076/322] Use primary key column name if select * was used. --- src/Engines/BaseEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index e0511695..4b22b58c 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -798,7 +798,7 @@ protected function getColumnNameFromRequest($index) */ protected function getColumnNameByIndex($index) { - $name = isset($this->columns[$index]) ? $this->columns[$index] : $this->getFallbackColumnName(); + $name = isset($this->columns[$index]) && $this->columns[$index] <> '*' ? $this->columns[$index] : $this->getFallbackColumnName(); return in_array($name, $this->extraColumns, true) ? $this->getFallbackColumnName() : $name; } From 2a1b91f6836d3ca59052fa9e60857836ed12967b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 11:36:14 +0800 Subject: [PATCH 077/322] Improve get primary key name method. --- src/Engines/BaseEngine.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 4b22b58c..82893d2e 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -798,17 +798,17 @@ protected function getColumnNameFromRequest($index) */ protected function getColumnNameByIndex($index) { - $name = isset($this->columns[$index]) && $this->columns[$index] <> '*' ? $this->columns[$index] : $this->getFallbackColumnName(); + $name = isset($this->columns[$index]) && $this->columns[$index] <> '*' ? $this->columns[$index] : $this->getPrimaryKeyName(); - return in_array($name, $this->extraColumns, true) ? $this->getFallbackColumnName() : $name; + return in_array($name, $this->extraColumns, true) ? $this->getPrimaryKeyName() : $name; } /** - * If query uses select *, then get the primary key column as default name. + * If column name could not be resolved then use primary key. * * @return string */ - protected function getFallbackColumnName() + protected function getPrimaryKeyName() { if ($this->isEloquent()) { return $this->getQueryBuilder()->getModel()->getKeyName(); From e8e113f924c787273086dc182851d654c824e324 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 12:50:33 +0800 Subject: [PATCH 078/322] Use is_numeric to properly check if value is an int. --- src/Engines/BaseEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 82893d2e..5014e175 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -765,7 +765,7 @@ protected function getColumnName($index, $wantsAlias = false) $column = $this->getColumnNameFromRequest($index); // DataTables is using make(false) - if (is_int($column)) { + if (is_numeric($column)) { $column = $this->getColumnNameByIndex($index); } From 3c0e46449c539a1f404f5d3707ca24b58281ea84 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 13:02:29 +0800 Subject: [PATCH 079/322] Fix eloquent get primary key name. --- src/Engines/BaseEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 5014e175..d6cd0944 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -811,7 +811,7 @@ protected function getColumnNameByIndex($index) protected function getPrimaryKeyName() { if ($this->isEloquent()) { - return $this->getQueryBuilder()->getModel()->getKeyName(); + return $this->query->getModel()->getKeyName(); } return 'id'; From 770b9011e29edcb41689ae8622d330975d330b09 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 14:02:53 +0800 Subject: [PATCH 080/322] Extract get column name function to request object. --- src/Engines/BaseEngine.php | 16 +--------------- src/Request.php | 4 +++- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index d6cd0944..b57eeb6e 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -762,7 +762,7 @@ public function isOracleSql() */ protected function getColumnName($index, $wantsAlias = false) { - $column = $this->getColumnNameFromRequest($index); + $column = $this->request->columnName($index); // DataTables is using make(false) if (is_numeric($column)) { @@ -776,20 +776,6 @@ protected function getColumnName($index, $wantsAlias = false) return $column; } - /** - * Get column name from request. - * - * @param int $index - * @return string - */ - protected function getColumnNameFromRequest($index) - { - $r_column = $this->request->input('columns')[$index]; - $column = isset($r_column['name']) && $r_column['name'] <> '' ? $r_column['name'] : $r_column['data']; - - return $column; - } - /** * Get column name by order column index. * diff --git a/src/Request.php b/src/Request.php index 02754b94..afb61c1d 100644 --- a/src/Request.php +++ b/src/Request.php @@ -152,7 +152,9 @@ public function keyword() */ public function columnName($i) { - return $this->get('columns')[$i]['name']; + $column = $this->get('columns')[$i]; + + return isset($column['name']) && $column['name'] <> '' ? $column['name'] : $column['data']; } /** From 941487fd0d985ea533f44adbc6836d7d8a28052e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 14:19:17 +0800 Subject: [PATCH 081/322] Dynamically determine if oracle depending on connection used. --- src/Engines/BaseEngine.php | 10 ---------- src/Engines/QueryBuilderEngine.php | 10 ++++++++++ src/config/config.php | 3 --- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index b57eeb6e..4dc448b3 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -743,16 +743,6 @@ public function order(\Closure $closure) return $this; } - /** - * Check if the current sql language is based on oracle syntax. - * - * @return bool - */ - public function isOracleSql() - { - return Config::get('datatables.oracle_sql', false); - } - /** * Get column name to be use for filtering and sorting. * diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index d75db3a7..d8536585 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -341,6 +341,16 @@ protected function regexColumnSearch($column, $keyword, $caseSensitive = true) } } + /** + * Check if the current sql language is based on oracle syntax. + * + * @return bool + */ + protected function isOracleSql() + { + return $this->database === 'oracle'; + } + /** * Perform sorting of columns. * diff --git a/src/config/config.php b/src/config/config.php index 00ace925..91da5166 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -1,9 +1,6 @@ false, - 'search' => [ 'case_insensitive' => true, 'use_wildcards' => false, From 683ecc879feae710a9ef94aa0dcde91a5f2c996b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 14:26:21 +0800 Subject: [PATCH 082/322] Log unreleased changes. --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4430815c..b76dc0c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,15 @@ ##Change Log +###Unreleased + - Add totalCount on contact and remove excess new line. + - Remove unnecessary abstract function on BaseEngine since we have a contract. + - Remove engine implementation of contract since BaseEngine already requires it. + - Improve column name detection for filtering and sorting. + - Dynamically determine if oracle depending on connection used. + - Automatic detection of primary key when using Eloquent engine. + - Use primary key when column name could not be resolve. + ###v6.5.1 - 2016-02-19 - Fix ordering column name detection. Issue #339. - Refactor Builder parameterize method. From 80427e7dd1bb219d56ce5ae10b82e2de625c6106 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 19 Feb 2016 14:56:30 +0800 Subject: [PATCH 083/322] Update DataTable service docblocks and refactor render method. --- src/Services/DataTable.php | 168 ++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 85 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index a6d81643..49450963 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -59,6 +59,8 @@ abstract class DataTable implements DataTableContract, DataTableButtonsContract protected $filename = ''; /** + * DataTable constructor. + * * @param \Yajra\Datatables\Datatables $datatables * @param \Illuminate\Contracts\View\Factory $viewFactory */ @@ -69,9 +71,9 @@ public function __construct(Datatables $datatables, Factory $viewFactory) } /** - * Render view. + * Process dataTables needed render output. * - * @param $view + * @param string $view * @param array $data * @param array $mergeData * @return \Illuminate\Http\JsonResponse|\Illuminate\View\View @@ -82,22 +84,15 @@ public function render($view, $data = [], $mergeData = []) return $this->ajax(); } - switch ($this->datatables->getRequest()->get('action')) { - case 'excel': - return $this->excel(); - - case 'csv': - return $this->csv(); - - case 'pdf': - return $this->pdf(); - - case 'print': + if ($action = $this->request()->get('action')) { + if ($action == 'print') { return $this->printPreview(); + } - default: - return $this->viewFactory->make($view, $data, $mergeData)->with('dataTable', $this->html()); + return call_user_func_array([$this, $action], []); } + + return $this->viewFactory->make($view, $data, $mergeData)->with('dataTable', $this->html()); } /** @@ -111,37 +106,16 @@ public function request() } /** - * Export results to Excel file. - * - * @return mixed - */ - public function excel() - { - return $this->buildExcelFile()->download('xls'); - } - - /** - * Build excel file and prepare for export. + * Display printable view of datatables. * - * @return mixed + * @return \Illuminate\Contracts\View\View */ - protected function buildExcelFile() + public function printPreview() { - return app('excel')->create($this->getFilename(), function (LaravelExcelWriter $excel) { - $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) { - $sheet->fromArray($this->getDataForExport()); - }); - }); - } + $data = $this->getDataForPrint(); + $view = $this->printPreview ?: 'datatables::print'; - /** - * Get filename for export. - * - * @return string - */ - protected function filename() - { - return 'export_' . time(); + return $this->viewFactory->make($view, compact('data')); } /** @@ -149,21 +123,21 @@ protected function filename() * * @return array */ - protected function getDataForExport() + protected function getDataForPrint() { - $columns = $this->exportColumns(); + $columns = $this->printColumns(); - return $this->mapResponseToColumns($columns, 'exportable'); + return $this->mapResponseToColumns($columns, 'printable'); } /** - * Get export columns definition. + * Get printable columns. * * @return array|string */ - private function exportColumns() + protected function printColumns() { - return is_array($this->exportColumns) ? $this->exportColumns : $this->getColumnsFromBuilder(); + return is_array($this->printColumns) ? $this->printColumns : $this->getColumnsFromBuilder(); } /** @@ -217,7 +191,7 @@ protected function mapResponseToColumns($columns, $type) /** * Get decorated data as defined in datatables ajax response. * - * @return mixed + * @return array */ protected function getAjaxResponseData() { @@ -230,36 +204,63 @@ protected function getAjaxResponseData() } /** - * Export results to CSV file. + * Export results to Excel file. * - * @return mixed + * @return void */ - public function csv() + public function excel() { - return $this->buildExcelFile()->download('csv'); + $this->buildExcelFile()->download('xls'); } /** - * Export results to PDF file. + * Build excel file and prepare for export. * - * @return mixed + * @return \Maatwebsite\Excel\Writers\LaravelExcelWriter */ - public function pdf() + protected function buildExcelFile() { - return $this->buildExcelFile()->download('pdf'); + /** @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()); + }); + }); } /** - * Display printable view of datatables. + * Get export filename. * - * @return \Illuminate\Contracts\View\View + * @return string */ - public function printPreview() + public function getFilename() { - $data = $this->getDataForPrint(); - $view = $this->printPreview ?: 'datatables::print'; + return $this->filename ?: $this->filename(); + } - return $this->viewFactory->make($view, compact('data')); + /** + * 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(); } /** @@ -267,55 +268,52 @@ public function printPreview() * * @return array */ - protected function getDataForPrint() + protected function getDataForExport() { - $columns = $this->printColumns(); + $columns = $this->exportColumns(); - return $this->mapResponseToColumns($columns, 'printable'); + return $this->mapResponseToColumns($columns, 'exportable'); } /** - * Get printable columns. + * Get export columns definition. * * @return array|string */ - protected function printColumns() + private function exportColumns() { - return is_array($this->printColumns) ? $this->printColumns : $this->getColumnsFromBuilder(); + return is_array($this->exportColumns) ? $this->exportColumns : $this->getColumnsFromBuilder(); } /** - * Add basic array query scopes. + * Export results to CSV file. * - * @param \Yajra\Datatables\Contracts\DataTableScopeContract $scope - * @return $this + * @return void */ - public function addScope(DataTableScopeContract $scope) + public function csv() { - $this->scopes[] = $scope; - - return $this; + $this->buildExcelFile()->download('csv'); } /** - * Get export filename. + * Export results to PDF file. * - * @return string + * @return void */ - public function getFilename() + public function pdf() { - return $this->filename ?: $this->filename(); + $this->buildExcelFile()->download('pdf'); } /** - * Set export filename. + * Add basic array query scopes. * - * @param string $filename - * @return DataTable + * @param \Yajra\Datatables\Contracts\DataTableScopeContract $scope + * @return $this */ - public function setFilename($filename) + public function addScope(DataTableScopeContract $scope) { - $this->filename = $filename; + $this->scopes[] = $scope; return $this; } From 1531d30bb571981fde4763953d96a0e0a7d2dd6d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 20 Feb 2016 10:47:49 +0800 Subject: [PATCH 084/322] Bump v6.6.0 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b76dc0c7..f2feda18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ##Change Log -###Unreleased +###v6.6.0 - 2016-02-20 - Add totalCount on contact and remove excess new line. - Remove unnecessary abstract function on BaseEngine since we have a contract. - Remove engine implementation of contract since BaseEngine already requires it. @@ -16,6 +16,7 @@ - Dynamically determine if oracle depending on connection used. - Automatic detection of primary key when using Eloquent engine. - Use primary key when column name could not be resolve. + - Update DataTable service doc blocks and refactor render method. ###v6.5.1 - 2016-02-19 - Fix ordering column name detection. Issue #339. From df8b82590490ed08d301835c2326e3a46948278c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 20 Feb 2016 15:12:28 +0800 Subject: [PATCH 085/322] Fix eager loading search (SQLSTATE[21000]: Cardinality violation:). Issue #403. --- CHANGELOG.md | 3 +++ src/Engines/QueryBuilderEngine.php | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2feda18..7fcb1fc3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +###v6.6.1 - 2016-02-20 + - Fix eager loading search (SQLSTATE[21000]: Cardinality violation:). Issue #403. + ###v6.6.0 - 2016-02-20 - Add totalCount on contact and remove excess new line. - Remove unnecessary abstract function on BaseEngine since we have a contract. diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index d8536585..e460848a 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -215,8 +215,9 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) { $myQuery = clone $this->query; $myQuery->orWhereHas($relation, function ($q) use ($column, $keyword, $query) { - $q->where($column, 'like', $keyword); - $sql = $q->toSql(); + $sql = $q->select($this->connection->raw('count(1)')) + ->where($column, 'like', $keyword) + ->toSql(); $sql = "($sql) >= 1"; $query->orWhereRaw($sql, [$keyword]); }); From a3ab7ab8cfba35f807f3676c2df276fe02d20b0a Mon Sep 17 00:00:00 2001 From: Viktoras Varnauskas Date: Thu, 25 Feb 2016 19:56:15 +0200 Subject: [PATCH 086/322] Sorting on eager loaded models --- src/Engines/QueryBuilderEngine.php | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index e460848a..401bcd62 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -365,16 +365,39 @@ public function ordering() return; } + $eagerLoads = $this->getEagerLoads(); + foreach ($this->request->orderableColumns() as $orderable) { $column = $this->getColumnName($orderable['column'], true); 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'] + $this->getQueryBuilder(), + $method, + $parameters, + $column, + $orderable['direction'] ); } else { - $this->getQueryBuilder()->orderBy($column, $orderable['direction']); + if (count(explode('.', $column)) > 1) { + $parts = explode('.', $column); + $relationColumn = array_pop($parts); + $relation = implode('.', $parts); + + if (in_array($relation, $eagerLoads)) { + $table = $this->query->getRelation($relation)->getRelated()->getTable(); + $foreign = $this->query->getRelation($relation)->getQualifiedForeignKey(); + $other = $this->query->getRelation($relation)->getQualifiedOtherKeyName(); + $orderBy = $table . '.' . $relationColumn; + + $this->getQueryBuilder()->leftJoin($table, $foreign, '=', $other)->orderBy($orderBy, $orderable['direction']); + } else { + $this->getQueryBuilder()->orderBy($column, $orderable['direction']); + } + } else { + $this->getQueryBuilder()->orderBy($column, $orderable['direction']); + } } } } From 88e4cfd446d240054f754d4aa315a720bcdce781 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 26 Feb 2016 11:31:50 +0800 Subject: [PATCH 087/322] Update docblocks. --- src/Engines/BaseEngine.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 4dc448b3..0665fea7 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -39,7 +39,7 @@ abstract class BaseEngine implements DataTableEngineContract /** * Builder object. * - * @var mixed + * @var \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder */ protected $query; @@ -367,9 +367,9 @@ public function escapeColumns($columns = '*') * Will convert a camelCase API call to a snake_case call. * Allow query builder method to be used by the engine. * - * @param $name - * @param $arguments - * @return $this|mixed + * @param string $name + * @param array $arguments + * @return mixed */ public function __call($name, $arguments) { @@ -386,7 +386,7 @@ public function __call($name, $arguments) } /** - * Sets DT_RowClass template + * Sets DT_RowClass template. * result: . * * @param string|callable $content @@ -400,7 +400,7 @@ public function setRowClass($content) } /** - * Sets DT_RowId template + * Sets DT_RowId template. * result: . * * @param string|callable $content @@ -441,7 +441,7 @@ public function addRowData($key, $value) } /** - * Set DT_RowAttr templates + * Set DT_RowAttr templates. * result: . * * @param array $data From 933d6d98117755304bd00af54b95adce34205a2d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 26 Feb 2016 11:33:04 +0800 Subject: [PATCH 088/322] Fix cs. --- src/Engines/QueryBuilderEngine.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 401bcd62..3a62bee9 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -386,12 +386,14 @@ public function ordering() $relation = implode('.', $parts); if (in_array($relation, $eagerLoads)) { - $table = $this->query->getRelation($relation)->getRelated()->getTable(); + $table = $this->query->getRelation($relation)->getRelated()->getTable(); $foreign = $this->query->getRelation($relation)->getQualifiedForeignKey(); - $other = $this->query->getRelation($relation)->getQualifiedOtherKeyName(); + $other = $this->query->getRelation($relation)->getQualifiedOtherKeyName(); $orderBy = $table . '.' . $relationColumn; - $this->getQueryBuilder()->leftJoin($table, $foreign, '=', $other)->orderBy($orderBy, $orderable['direction']); + $this->getQueryBuilder() + ->leftJoin($table, $foreign, '=', $other) + ->orderBy($orderBy, $orderable['direction']); } else { $this->getQueryBuilder()->orderBy($column, $orderable['direction']); } From 15c18e4b99bafa0510d020f86c9457cafb95d882 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 26 Feb 2016 12:24:27 +0800 Subject: [PATCH 089/322] Bump v6.7.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fcb1fc3..93291a46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.7.0 - 2016-02-26 + - Add support for sorting on eager loaded models. + - PR #409 - Credits to @ikerasLT. + ###v6.6.1 - 2016-02-20 - Fix eager loading search (SQLSTATE[21000]: Cardinality violation:). Issue #403. From 789c389869ce0254a8eefdd169899fa6d7564f11 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 26 Feb 2016 14:00:00 +0800 Subject: [PATCH 090/322] Fix multiple column sorting when using eager loaded models. Fix #410 --- CHANGELOG.md | 3 +++ src/Engines/QueryBuilderEngine.php | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 93291a46..c3a0babf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +###v6.7.1 - 2016-02-26 + - Fix multiple column sorting when using eager loaded models. Fix #410 + ###v6.7.0 - 2016-02-26 - Add support for sorting on eager loaded models. - PR #409 - Credits to @ikerasLT. diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 3a62bee9..1ab8b8fa 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -391,9 +391,15 @@ public function ordering() $other = $this->query->getRelation($relation)->getQualifiedOtherKeyName(); $orderBy = $table . '.' . $relationColumn; - $this->getQueryBuilder() - ->leftJoin($table, $foreign, '=', $other) - ->orderBy($orderBy, $orderable['direction']); + $joins = []; + foreach ((array) $this->getQueryBuilder()->joins as $key => $join) { + $joins[] = $join->table; + } + if (! in_array($table, $joins)) { + $this->getQueryBuilder() + ->leftJoin($table, $foreign, '=', $other) + ->orderBy($orderBy, $orderable['direction']); + } } else { $this->getQueryBuilder()->orderBy($column, $orderable['direction']); } From ceb5be0cdac89885063010993b17d43aff82a392 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sun, 28 Feb 2016 00:34:18 +0800 Subject: [PATCH 091/322] Fix collection engine sorting and sorting function. Fix #413 and #415. --- src/Engines/CollectionEngine.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index d8c188e2..5254bd49 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -104,7 +104,7 @@ public function ordering() } foreach ($this->request->orderableColumns() as $orderable) { - $column = $this->getColumnNameByIndex($orderable['column']); + $column = $this->getColumnName($orderable['column']); $this->collection = $this->collection->sortBy( function ($row) use ($column) { $data = $this->serialize($row); @@ -133,7 +133,7 @@ function ($row) use ($columns) { $keyword = $this->request->keyword(); foreach ($this->request->searchableColumnIndex() as $index) { - $column = $this->getColumnNameByIndex($index); + $column = $this->getColumnName($index); if (! $value = Arr::get($data, $column)) { continue; } @@ -160,7 +160,7 @@ public function columnSearch() if ($this->request->isColumnSearchable($i)) { $this->isFilterApplied = true; - $column = $this->getColumnNameByIndex($i); + $column = $this->getColumnName($i); $keyword = $this->request->columnKeyword($i); $this->collection = $this->collection->filter( From 5f4c96659cc28e82f8523a7f6e8f1a73f927a238 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sun, 28 Feb 2016 15:31:50 +0800 Subject: [PATCH 092/322] Bump v6.7.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3a0babf..d54cde28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.7.2 - 2016-02-28 + - Fix collection engine sorting and sorting function. + - Fix #413 and #415. + ###v6.7.1 - 2016-02-26 - Fix multiple column sorting when using eager loaded models. Fix #410 From 7f0fc15baa573ead87bc08e90f4a02127fba5dad Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sun, 28 Feb 2016 16:19:00 +0800 Subject: [PATCH 093/322] Fix eager load multiple column sorting where other columns are being ignored when join statement already exists. --- src/Engines/QueryBuilderEngine.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 1ab8b8fa..5dd8f852 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -397,9 +397,10 @@ public function ordering() } if (! in_array($table, $joins)) { $this->getQueryBuilder() - ->leftJoin($table, $foreign, '=', $other) - ->orderBy($orderBy, $orderable['direction']); + ->leftJoin($table, $foreign, '=', $other); } + + $this->getQueryBuilder()->orderBy($orderBy, $orderable['direction']); } else { $this->getQueryBuilder()->orderBy($column, $orderable['direction']); } From be8d90095b4f8f42275e1cc669759960867bd6ef Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sun, 28 Feb 2016 16:23:20 +0800 Subject: [PATCH 094/322] Refactor redundant else order by statement. --- src/Engines/QueryBuilderEngine.php | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 5dd8f852..8da28812 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -389,7 +389,7 @@ public function ordering() $table = $this->query->getRelation($relation)->getRelated()->getTable(); $foreign = $this->query->getRelation($relation)->getQualifiedForeignKey(); $other = $this->query->getRelation($relation)->getQualifiedOtherKeyName(); - $orderBy = $table . '.' . $relationColumn; + $column = $table . '.' . $relationColumn; $joins = []; foreach ((array) $this->getQueryBuilder()->joins as $key => $join) { @@ -399,14 +399,10 @@ public function ordering() $this->getQueryBuilder() ->leftJoin($table, $foreign, '=', $other); } - - $this->getQueryBuilder()->orderBy($orderBy, $orderable['direction']); - } else { - $this->getQueryBuilder()->orderBy($column, $orderable['direction']); } - } else { - $this->getQueryBuilder()->orderBy($column, $orderable['direction']); } + + $this->getQueryBuilder()->orderBy($column, $orderable['direction']); } } } From 8474608087c0237d0c54e674093ccb8305acc67b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sun, 28 Feb 2016 16:24:26 +0800 Subject: [PATCH 095/322] Call eager loads only when required. --- src/Engines/QueryBuilderEngine.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 8da28812..4470c70c 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -365,8 +365,6 @@ public function ordering() return; } - $eagerLoads = $this->getEagerLoads(); - foreach ($this->request->orderableColumns() as $orderable) { $column = $this->getColumnName($orderable['column'], true); if (isset($this->columnDef['order'][$column])) { @@ -381,6 +379,7 @@ public function ordering() ); } else { if (count(explode('.', $column)) > 1) { + $eagerLoads = $this->getEagerLoads(); $parts = explode('.', $column); $relationColumn = array_pop($parts); $relation = implode('.', $parts); From bad9e6cf5fa542e16459eb08d7a849575cdb3a60 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sun, 28 Feb 2016 16:29:58 +0800 Subject: [PATCH 096/322] Extract eager loaded column join statement handler. --- src/Engines/QueryBuilderEngine.php | 41 ++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 4470c70c..8c6cbe71 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -385,19 +385,7 @@ public function ordering() $relation = implode('.', $parts); if (in_array($relation, $eagerLoads)) { - $table = $this->query->getRelation($relation)->getRelated()->getTable(); - $foreign = $this->query->getRelation($relation)->getQualifiedForeignKey(); - $other = $this->query->getRelation($relation)->getQualifiedOtherKeyName(); - $column = $table . '.' . $relationColumn; - - $joins = []; - foreach ((array) $this->getQueryBuilder()->joins as $key => $join) { - $joins[] = $join->table; - } - if (! in_array($table, $joins)) { - $this->getQueryBuilder() - ->leftJoin($table, $foreign, '=', $other); - } + $column = $this->joinEagerLoadedColumn($relation, $relationColumn); } } @@ -406,6 +394,33 @@ public function ordering() } } + /** + * Join eager loaded relation and get the related column name. + * + * @param string $relation + * @param string $relationColumn + * @return string + */ + protected function joinEagerLoadedColumn($relation, $relationColumn) + { + $table = $this->query->getRelation($relation)->getRelated()->getTable(); + $foreign = $this->query->getRelation($relation)->getQualifiedForeignKey(); + $other = $this->query->getRelation($relation)->getQualifiedOtherKeyName(); + $column = $table . '.' . $relationColumn; + + $joins = []; + foreach ((array) $this->getQueryBuilder()->joins as $key => $join) { + $joins[] = $join->table; + } + + if (! in_array($table, $joins)) { + $this->getQueryBuilder() + ->leftJoin($table, $foreign, '=', $other); + } + + return $column; + } + /** * Perform pagination * From e9788e3b0f79ba6754ccbcd426bdb473f6a1b5ed Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sun, 28 Feb 2016 16:43:54 +0800 Subject: [PATCH 097/322] Call eager loads on filtering only when required. Change accessor from private to protected. --- src/Engines/QueryBuilderEngine.php | 33 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 8c6cbe71..8b471deb 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -100,10 +100,8 @@ public function count() */ public function filtering() { - $eagerLoads = $this->getEagerLoads(); - $this->query->where( - function ($query) use ($eagerLoads) { + function ($query) { $keyword = $this->setupKeyword($this->request->keyword()); foreach ($this->request->searchableColumnIndex() as $index) { $columnName = $this->getColumnName($index); @@ -120,6 +118,7 @@ function ($query) use ($eagerLoads) { ); } else { if (count(explode('.', $columnName)) > 1) { + $eagerLoads = $this->getEagerLoads(); $parts = explode('.', $columnName); $relationColumn = array_pop($parts); $relation = implode('.', $parts); @@ -144,20 +143,6 @@ function ($query) use ($eagerLoads) { ); } - /** - * Get eager loads keys if eloquent. - * - * @return array - */ - private function getEagerLoads() - { - if ($this->query_type == 'eloquent') { - return array_keys($this->query->getEagerLoads()); - } - - return []; - } - /** * Perform filter column on selected field. * @@ -203,6 +188,20 @@ protected function parameterize() 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. * From 1b884fb425418dd837a5139f92cc7e7f9e43e739 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sun, 28 Feb 2016 16:45:20 +0800 Subject: [PATCH 098/322] Log unreleased changes. --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d54cde28..a3f012e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +###UNRELEASED + - Fix eager load multiple column sorting where other columns are being ignored when join statement already exists. + - Refactor redundant else order by statement. + - Call eager loads only when required when filtering and ordering. + - Extract eager loaded column join statement handler. + ###v6.7.2 - 2016-02-28 - Fix collection engine sorting and sorting function. - Fix #413 and #415. From da17c40fbbf69490dd7ed6b5d70c0612565eba5f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 2 Mar 2016 23:14:56 +0800 Subject: [PATCH 099/322] Bump v6.7.3 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3f012e7..34fa2321 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ##Change Log -###UNRELEASED +###v6.7.3 - 2016-03-02 - Fix eager load multiple column sorting where other columns are being ignored when join statement already exists. - Refactor redundant else order by statement. - Call eager loads only when required when filtering and ordering. From 99db0fb94e95453718eab1f99a004b6c6b5acec6 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 11 Mar 2016 09:08:52 +0800 Subject: [PATCH 100/322] Re-implement facade. --- src/DatatablesServiceProvider.php | 6 +++--- src/Facades/Datatables.php | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 src/Facades/Datatables.php diff --git a/src/DatatablesServiceProvider.php b/src/DatatablesServiceProvider.php index 3f1d1da8..373ddc2f 100644 --- a/src/DatatablesServiceProvider.php +++ b/src/DatatablesServiceProvider.php @@ -71,8 +71,8 @@ public function register() $this->registerRequiredProviders(); - $this->app->singleton('datatables', function ($app) { - return new Datatables($app->make(Request::class)); + $this->app->singleton('datatables', function () { + return new Datatables($this->app->make(Request::class)); }); $this->registerAliases(); @@ -104,7 +104,7 @@ private function registerAliases() { if (class_exists('Illuminate\Foundation\AliasLoader')) { $loader = \Illuminate\Foundation\AliasLoader::getInstance(); - $loader->alias('Datatables', \Yajra\Datatables\Datatables::class); + $loader->alias('Datatables', \Yajra\Datatables\Facades\Datatables::class); } } diff --git a/src/Facades/Datatables.php b/src/Facades/Datatables.php new file mode 100644 index 00000000..b23d15d6 --- /dev/null +++ b/src/Facades/Datatables.php @@ -0,0 +1,18 @@ + Date: Tue, 8 Mar 2016 14:56:09 +0200 Subject: [PATCH 101/322] Added Closure support for filterColumn method --- src/Engines/BaseEngine.php | 2 +- src/Engines/QueryBuilderEngine.php | 107 +++++++++++++++++++---------- 2 files changed, 71 insertions(+), 38 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 0665fea7..c1c2707e 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -472,7 +472,7 @@ public function addRowAttr($key, $value) * Override default column filter search. * * @param string $column - * @param string $method + * @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. diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 8b471deb..31aa7d7a 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -102,20 +102,33 @@ public function filtering() { $this->query->where( function ($query) { - $keyword = $this->setupKeyword($this->request->keyword()); + $globalKeyword = $this->setupKeyword($this->request->keyword()); + $queryBuilder = $this->getQueryBuilder($query); + foreach ($this->request->searchableColumnIndex() as $index) { $columnName = $this->getColumnName($index); - + // check if custom column filtering is applied if (isset($this->columnDef['filter'][$columnName])) { - $method = Helper::getOrMethod($this->columnDef['filter'][$columnName]['method']); - $parameters = $this->columnDef['filter'][$columnName]['parameters']; - $this->compileColumnQuery( - $this->getQueryBuilder($query), - $method, - $parameters, - $columnName, - $keyword - ); + $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, $this->request->keyword()]); + $queryBuilder->addNestedWhereQuery($whereQuery, 'or'); + } else { + $this->compileColumnQuery( + $queryBuilder, + Helper::getOrMethod($columnDef['method']), + $columnDef['parameters'], + $columnName, + $this->request->keyword() + ); + } } else { if (count(explode('.', $columnName)) > 1) { $eagerLoads = $this->getEagerLoads(); @@ -124,16 +137,16 @@ function ($query) { $relation = implode('.', $parts); if (in_array($relation, $eagerLoads)) { $this->compileRelationSearch( - $this->getQueryBuilder($query), + $queryBuilder, $relation, $relationColumn, - $keyword + $globalKeyword ); } else { - $this->compileGlobalSearch($this->getQueryBuilder($query), $columnName, $keyword); + $this->compileGlobalSearch($queryBuilder, $columnName, $globalKeyword); } } else { - $this->compileGlobalSearch($this->getQueryBuilder($query), $columnName, $keyword); + $this->compileGlobalSearch($queryBuilder, $columnName, $globalKeyword); } } @@ -147,7 +160,7 @@ function ($query) { * Perform filter column on selected field. * * @param mixed $query - * @param string $method + * @param string|Closure $method * @param mixed $parameters * @param string $column * @param string $keyword @@ -265,27 +278,46 @@ public function castColumn($column) public function columnSearch() { $columns = $this->request->get('columns'); - for ($i = 0, $c = count($columns); $i < $c; $i++) { - if ($this->request->isColumnSearchable($i)) { - $column = $this->getColumnName($i); - $keyword = $this->getSearchKeyword($i); - - if (isset($this->columnDef['filter'][$column])) { - $method = $this->columnDef['filter'][$column]['method']; - $parameters = $this->columnDef['filter'][$column]['parameters']; - $this->compileColumnQuery($this->getQueryBuilder(), $method, $parameters, $column, $keyword); + + 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 { - $column = $this->castColumn($column); - if ($this->isCaseInsensitive()) { - $this->compileColumnSearch($i, $column, $keyword, false); - } else { - $col = strstr($column, '(') ? $this->connection->raw($column) : $column; - $this->compileColumnSearch($i, $col, $keyword, true); - } + $this->compileColumnQuery( + $builder, + $columnDef['method'], + $columnDef['parameters'], + $column, + $keyword + ); } + } else { + $column = $this->castColumn($column); + $keyword = $this->getSearchKeyword($index); - $this->isFilterApplied = true; + if ($this->isCaseInsensitive()) { + $this->compileColumnSearch($index, $column, $keyword, false); + } else { + $col = strstr($column, '(') ? $this->connection->raw($column) : $column; + $this->compileColumnSearch($index, $col, $keyword, true); + } } + + $this->isFilterApplied = true; } } @@ -295,13 +327,14 @@ public function columnSearch() * @param int $i * @return string */ - private function getSearchKeyword($i) + private function getSearchKeyword($i, $raw = false) { - if ($this->request->isRegex($i)) { - return $this->request->columnKeyword($i); + $keyword = $this->request->columnKeyword($i); + if ($raw || $this->request->isRegex($i)) { + return $keyword; } - return $this->setupKeyword($this->request->columnKeyword($i)); + return $this->setupKeyword($keyword); } /** From 53e254be3869af5ba26170e73a70146db81ac360 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 11 Mar 2016 21:10:35 +0800 Subject: [PATCH 102/322] Fix cs. --- src/Engines/QueryBuilderEngine.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 31aa7d7a..91b314fb 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -103,7 +103,7 @@ public function filtering() $this->query->where( function ($query) { $globalKeyword = $this->setupKeyword($this->request->keyword()); - $queryBuilder = $this->getQueryBuilder($query); + $queryBuilder = $this->getQueryBuilder($query); foreach ($this->request->searchableColumnIndex() as $index) { $columnName = $this->getColumnName($index); @@ -112,7 +112,7 @@ function ($query) { $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) { + if (! $applyGlobalSearch) { continue; } @@ -280,7 +280,7 @@ public function columnSearch() $columns = $this->request->get('columns'); foreach ($columns as $index => $column) { - if (!$this->request->isColumnSearchable($index)) { + if (! $this->request->isColumnSearchable($index)) { continue; } @@ -306,7 +306,7 @@ public function columnSearch() ); } } else { - $column = $this->castColumn($column); + $column = $this->castColumn($column); $keyword = $this->getSearchKeyword($index); if ($this->isCaseInsensitive()) { From 3a135f111c85e1c0fb7166307d11fbdbbd343476 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 11 Mar 2016 21:14:00 +0800 Subject: [PATCH 103/322] Bump v6.8.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34fa2321..82a538e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.8.0 - 2016-03-11 + - Added Closure support for filterColumn method. + - PR #440. Credits to @codewizz. + ###v6.7.3 - 2016-03-02 - Fix eager load multiple column sorting where other columns are being ignored when join statement already exists. - Refactor redundant else order by statement. From 051726db6e4c0a7ca6f9d59633464bf72ead409b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 12 Mar 2016 08:25:20 +0800 Subject: [PATCH 104/322] Add blacklist and whitelist feature. --- src/Engines/BaseEngine.php | 59 +++++++++++++++++++++++++++--- src/Engines/QueryBuilderEngine.php | 9 +++++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index c1c2707e..0e698914 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -63,12 +63,14 @@ abstract class BaseEngine implements DataTableEngineContract * @var array */ protected $columnDef = [ - 'append' => [], - 'edit' => [], - 'excess' => ['rn', 'row_num'], - 'filter' => [], - 'order' => [], - 'escape' => [], + 'append' => [], + 'edit' => [], + 'excess' => ['rn', 'row_num'], + 'filter' => [], + 'order' => [], + 'escape' => [], + 'blacklist' => ['password', 'remember_token'], + 'whitelist' => '*', ]; /** @@ -743,6 +745,51 @@ public function order(\Closure $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; + } + + /** + * 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. * diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 91b314fb..ccdceab0 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -107,6 +107,10 @@ function ($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]; @@ -399,6 +403,11 @@ public function ordering() 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']; From 10cb7d4ec7efd65e2cff462c955e2e467d136319 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 12 Mar 2016 08:26:45 +0800 Subject: [PATCH 105/322] Fix string casting for object values. --- src/Helper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Helper.php b/src/Helper.php index 4cf1d8eb..540b5f55 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -238,7 +238,7 @@ protected static function transformRow($row) if ($value instanceof DateTime) { $row[$key] = $value->format('Y-m-d H:i:s'); } else { - if (is_string($value)) { + if (is_object($value)) { $row[$key] = (string) $value; } else { $row[$key] = $value; From a4ff28d0465637b252d2291ddf595394ad5d68ce Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 12 Mar 2016 08:40:52 +0800 Subject: [PATCH 106/322] Add missing doc block. --- src/Engines/QueryBuilderEngine.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 91b314fb..783b19f3 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -325,6 +325,7 @@ public function columnSearch() * Get proper keyword to use for search. * * @param int $i + * @param bool $raw * @return string */ private function getSearchKeyword($i, $raw = false) From 69fb34433e4dfebfb536fa99fabcfdfed9852c9f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 12 Mar 2016 09:09:54 +0800 Subject: [PATCH 107/322] Update docs and log unreleased changes. --- CHANGELOG.md | 6 ++++++ readme.md | 27 +++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82a538e6..d5d732d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +###UNRELEASED + - Re-implement facade. + - Add blacklist and whitelist feature. + - Fix string casting for object values. + - Add missing doc block for getSearchKeyword. + ###v6.8.0 - 2016-03-11 - Added Closure support for filterColumn method. - PR #440. Credits to @codewizz. diff --git a/readme.md b/readme.md index cad874f1..5dd0cf6f 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -# Datatables Package for Laravel 4|5 +# jQuery DataTables API for Laravel 4|5 [![Laravel 4.2|5.0|5.1|5.2](https://img.shields.io/badge/Laravel-4.2|5.0|5.1|5.2-orange.svg)](http://laravel.com) [![Latest Stable Version](https://poser.pugx.org/yajra/laravel-datatables-oracle/v/stable)](https://packagist.org/packages/yajra/laravel-datatables-oracle) @@ -9,6 +9,24 @@ This package is created to handle [server-side](https://www.datatables.net/manual/server-side) works of [DataTables](http://datatables.net) jQuery Plugin via [AJAX option](https://datatables.net/reference/option/ajax) by using Eloquent ORM, Fluent Query Builder or Collection. +```php +use Yajra\Datatables\Facades\Datatables; + +// Using Eloquent +return Datatables::eloquent(User::query())->make(true); + +// Using Query Builder +return Datatables::queryBuilder(DB::table('users'))->make(true); + +// Using Collection +return Datatables::collection(User::all())->make(true); + +// Using the Engine Factory +return Datatables::of(User::query())->make(true); +return Datatables::of(DB::table('users'))->make(true); +return Datatables::of(User::all())->make(true); +``` + ## Feature Overview - Supports the following data source - **Eloquent ORM** @@ -23,8 +41,8 @@ This package is created to handle [server-side](https://www.datatables.net/manua - **Note:** DT Legacy code is not supported on v5.x - Works with [DataTables](http://datatables.net) v1.9 and v1.10 legacy code. - **Note:** Use [v4.x](https://github.com/yajra/laravel-datatables-oracle/tree/v4.3.2) for Laravel 5 and [v3.x](https://github.com/yajra/laravel-datatables-oracle/tree/L4) for Laravel 4 -- Extended column filtering via [`filterColumn`](http://yajra.github.io/laravel-datatables/api/source-class-yajra.Datatables.Engines.BaseEngine.html#489-503) API. -- Extended column ordering via [`orderColumn`](http://yajra.github.io/laravel-datatables/api/source-class-yajra.Datatables.Engines.BaseEngine.html#505-519) API. +- Extended column filtering via `filterColumn` API. +- Extended column ordering via `orderColumn` API. - Extended Query Builder functionality allowing you to filter using Datatables class directly. - Decorate your data output using [`league\fractal`](https://github.com/thephpleague/fractal) Transformer with Serializer support. - Works with Laravel Dependency Injection and IoC Container. @@ -36,6 +54,7 @@ This package is created to handle [server-side](https://www.datatables.net/manua - Built-in support for exporting to CSV, EXCEL and PDF using [Laravel-Excel](https://github.com/Maatwebsite/Laravel-Excel). - Built-in printer friendly view or create your own by overriding `printPreview()` method. - Provides an artisan command for generating a DataTable service and scope. +- Provides **WHITELIST** and **BLACKLIST** feature to explicitly allow/deny columns from searching/sorting. - See [change logs](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md) for more details. ## Requirements: @@ -61,7 +80,7 @@ Most of the latest updates/features are not available on these versions. Please `Yajra\Datatables\DatatablesServiceProvider::class` #### Facade -`Datatables` facade are automatically registered as an alias for `Yajra\Datatables\Datatables` class. +`Datatables` facade are automatically registered as an alias for `Yajra\Datatables\Facades\Datatables` class. #### Configuration and Assets `$ php artisan vendor:publish --tag=datatables` From 2670483cd19b5f76321ff16c08b1f4e4d25f008b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 12 Mar 2016 09:44:14 +0800 Subject: [PATCH 108/322] Fix eloquent engine missing parent constructor. --- CHANGELOG.md | 1 + src/Engines/EloquentEngine.php | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5d732d3..69e01b13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Add blacklist and whitelist feature. - Fix string casting for object values. - Add missing doc block for getSearchKeyword. + - Fix eloquent engine missing parent constructor. ###v6.8.0 - 2016-03-11 - Added Closure support for filterColumn method. diff --git a/src/Engines/EloquentEngine.php b/src/Engines/EloquentEngine.php index ef4e2359..1e187068 100644 --- a/src/Engines/EloquentEngine.php +++ b/src/Engines/EloquentEngine.php @@ -21,7 +21,10 @@ class EloquentEngine extends QueryBuilderEngine */ public function __construct($model, Request $request) { - $this->query = $model instanceof Builder ? $model : $model->getQuery(); - $this->init($request, $this->query->getQuery(), 'eloquent'); + $builder = $model instanceof Builder ? $model : $model->getQuery(); + parent::__construct($builder->getQuery(), $request); + + $this->query = $builder; + $this->query_type = 'eloquent'; } } From ff85e0e6c6f793de91ffbd554c4fb9ce53e13e8a Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 12 Mar 2016 09:53:38 +0800 Subject: [PATCH 109/322] Update and fix doc blocks. --- src/Contracts/DataTableEngineContract.php | 19 ++++--- src/Engines/CollectionEngine.php | 68 ++++++++++++++++------- src/Engines/EloquentEngine.php | 7 +-- src/Engines/QueryBuilderEngine.php | 29 ++++++---- 4 files changed, 79 insertions(+), 44 deletions(-) diff --git a/src/Contracts/DataTableEngineContract.php b/src/Contracts/DataTableEngineContract.php index 8d6d31a1..04ea6079 100644 --- a/src/Contracts/DataTableEngineContract.php +++ b/src/Contracts/DataTableEngineContract.php @@ -5,14 +5,14 @@ interface DataTableEngineContract { /** - * Get results + * Get results. * * @return mixed */ public function results(); /** - * Count results + * Count results. * * @return integer */ @@ -27,7 +27,7 @@ public function totalCount(); /** * Set auto filter off and run your own filter. - * Overrides global search + * Overrides global search. * * @param \Closure $callback * @return $this @@ -35,38 +35,39 @@ public function totalCount(); public function filter(\Closure $callback); /** - * Perform global search + * Perform global search. * * @return void */ public function filtering(); /** - * Perform column search + * Perform column search. * * @return void */ public function columnSearch(); /** - * Perform pagination + * Perform pagination. * * @return void */ public function paging(); /** - * Perform sorting of columns + * Perform sorting of columns. * * @return void */ public function ordering(); /** - * Organizes works + * Organizes works. * * @param bool $mDataSupport + * @param bool $orderFirst * @return \Illuminate\Http\JsonResponse */ - public function make($mDataSupport = false); + public function make($mDataSupport = false, $orderFirst = false); } diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 5254bd49..80762a1f 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -2,14 +2,6 @@ namespace Yajra\Datatables\Engines; -/** - * Laravel Datatables Collection Engine - * - * @package Laravel - * @category Package - * @author Arjay Angeles - */ - use Closure; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Support\Arr; @@ -17,24 +9,33 @@ use Illuminate\Support\Str; use Yajra\Datatables\Request; +/** + * Laravel Datatables Collection Engine + * + * @package Laravel + * @category Package + * @author Arjay Angeles + */ class CollectionEngine extends BaseEngine { /** * Collection object * - * @var Collection + * @var \Illuminate\Support\Collection */ public $collection; /** * Collection object * - * @var Collection + * @var \Illuminate\Support\Collection */ public $original_collection; /** - * @param Collection $collection + * CollectionEngine constructor. + * + * @param \Illuminate\Support\Collection $collection * @param \Yajra\Datatables\Request $request */ public function __construct(Collection $collection, Request $request) @@ -57,7 +58,11 @@ protected function serialize($collection) } /** - * @inheritdoc + * Set auto filter off and run your own filter. + * Overrides global search. + * + * @param \Closure $callback + * @return $this */ public function filter(Closure $callback) { @@ -67,7 +72,10 @@ public function filter(Closure $callback) } /** - * @inheritdoc + * Append debug parameters on output. + * + * @param array $output + * @return array */ public function showDebugger(array $output) { @@ -77,7 +85,9 @@ public function showDebugger(array $output) } /** - * @inheritdoc + * Count total items. + * + * @return integer */ public function totalCount() { @@ -85,7 +95,9 @@ public function totalCount() } /** - * @inheritdoc + * Count results. + * + * @return integer */ public function count() { @@ -93,7 +105,9 @@ public function count() } /** - * @inheritdoc + * Perform sorting of columns. + * + * @return void */ public function ordering() { @@ -120,7 +134,9 @@ function ($row) use ($column) { } /** - * @inheritdoc + * Perform global search. + * + * @return void */ public function filtering() { @@ -151,7 +167,9 @@ function ($row) use ($columns) { } /** - * @inheritdoc + * Perform column search. + * + * @return void */ public function columnSearch() { @@ -181,7 +199,9 @@ function ($row) use ($column, $keyword) { } /** - * @inheritdoc + * Perform pagination. + * + * @return void */ public function paging() { @@ -192,7 +212,9 @@ public function paging() } /** - * @inheritdoc + * Get results. + * + * @return mixed */ public function results() { @@ -200,7 +222,11 @@ public function results() } /** - * @inheritdoc + * Organizes works. + * + * @param bool $mDataSupport + * @param bool $orderFirst + * @return \Illuminate\Http\JsonResponse */ public function make($mDataSupport = false, $orderFirst = true) { diff --git a/src/Engines/EloquentEngine.php b/src/Engines/EloquentEngine.php index 1e187068..4986a3c5 100644 --- a/src/Engines/EloquentEngine.php +++ b/src/Engines/EloquentEngine.php @@ -2,6 +2,9 @@ namespace Yajra\Datatables\Engines; +use Illuminate\Database\Eloquent\Builder; +use Yajra\Datatables\Request; + /** * Laravel Datatables Eloquent Engine * @@ -9,10 +12,6 @@ * @category Package * @author Arjay Angeles */ - -use Illuminate\Database\Eloquent\Builder; -use Yajra\Datatables\Request; - class EloquentEngine extends QueryBuilderEngine { /** diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index b6ea5cb5..b4b8f2d3 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -2,6 +2,12 @@ namespace Yajra\Datatables\Engines; +use Closure; +use Illuminate\Database\Query\Builder; +use Illuminate\Support\Str; +use Yajra\Datatables\Helper; +use Yajra\Datatables\Request; + /** * Laravel Datatables Query Builder Engine * @@ -9,13 +15,6 @@ * @category Package * @author Arjay Angeles */ - -use Closure; -use Illuminate\Database\Query\Builder; -use Illuminate\Support\Str; -use Yajra\Datatables\Helper; -use Yajra\Datatables\Request; - class QueryBuilderEngine extends BaseEngine { /** @@ -49,7 +48,11 @@ protected function init($request, $builder, $type = 'builder') } /** - * @inheritdoc + * Set auto filter off and run your own filter. + * Overrides global search + * + * @param \Closure $callback + * @return $this */ public function filter(Closure $callback) { @@ -59,7 +62,11 @@ public function filter(Closure $callback) } /** - * @inheritdoc + * Organizes works + * + * @param bool $mDataSupport + * @param bool $orderFirst + * @return \Illuminate\Http\JsonResponse */ public function make($mDataSupport = false, $orderFirst = false) { @@ -67,7 +74,9 @@ public function make($mDataSupport = false, $orderFirst = false) } /** - * @inheritdoc + * Count total items. + * + * @return integer */ public function totalCount() { From 1b9a436f9fc34f771dd197cdbb452ce88e0b9255 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 12 Mar 2016 10:04:54 +0800 Subject: [PATCH 110/322] Add class docblocks. --- src/Contracts/DataTableButtonsContract.php | 6 ++++ src/Contracts/DataTableContract.php | 6 ++++ src/Contracts/DataTableEngineContract.php | 6 ++++ src/Contracts/DataTableScopeContract.php | 6 ++++ src/Datatables.php | 38 +++++++++------------- src/DatatablesServiceProvider.php | 6 ++++ src/Engines/BaseEngine.php | 14 ++++---- src/Engines/CollectionEngine.php | 7 ++-- src/Engines/EloquentEngine.php | 7 ++-- src/Engines/QueryBuilderEngine.php | 7 ++-- src/Facades/Datatables.php | 6 ++++ src/Generators/DataTablesMakeCommand.php | 6 ++++ src/Generators/DataTablesScopeCommand.php | 6 ++++ src/Helper.php | 6 ++++ src/Html/Builder.php | 3 +- src/Html/Column.php | 3 +- src/Html/Parameters.php | 3 +- src/Processors/DataProcessor.php | 3 +- src/Processors/RowProcessor.php | 3 +- src/Request.php | 4 +++ src/Services/DataTable.php | 6 ++++ src/Transformers/DataTransformer.php | 3 +- 22 files changed, 106 insertions(+), 49 deletions(-) diff --git a/src/Contracts/DataTableButtonsContract.php b/src/Contracts/DataTableButtonsContract.php index 084d1f75..040f6e63 100644 --- a/src/Contracts/DataTableButtonsContract.php +++ b/src/Contracts/DataTableButtonsContract.php @@ -2,6 +2,12 @@ namespace Yajra\Datatables\Contracts; +/** + * Interface DataTableButtonsContract. + * + * @package Yajra\Datatables\Contracts + * @author Arjay Angeles + */ interface DataTableButtonsContract { /** diff --git a/src/Contracts/DataTableContract.php b/src/Contracts/DataTableContract.php index e692c67d..a044d2b0 100644 --- a/src/Contracts/DataTableContract.php +++ b/src/Contracts/DataTableContract.php @@ -2,6 +2,12 @@ namespace Yajra\Datatables\Contracts; +/** + * Interface DataTableContract + * + * @package Yajra\Datatables\Contracts + * @author Arjay Angeles + */ interface DataTableContract { /** diff --git a/src/Contracts/DataTableEngineContract.php b/src/Contracts/DataTableEngineContract.php index 04ea6079..000e2ac8 100644 --- a/src/Contracts/DataTableEngineContract.php +++ b/src/Contracts/DataTableEngineContract.php @@ -2,6 +2,12 @@ namespace Yajra\Datatables\Contracts; +/** + * Interface DataTableEngineContract + * + * @package Yajra\Datatables\Contracts + * @author Arjay Angeles + */ interface DataTableEngineContract { /** diff --git a/src/Contracts/DataTableScopeContract.php b/src/Contracts/DataTableScopeContract.php index 12451f63..4ceaeea8 100644 --- a/src/Contracts/DataTableScopeContract.php +++ b/src/Contracts/DataTableScopeContract.php @@ -2,6 +2,12 @@ namespace Yajra\Datatables\Contracts; +/** + * Interface DataTableScopeContract. + * + * @package Yajra\Datatables\Contracts + * @author Arjay Angeles + */ interface DataTableScopeContract { /** diff --git a/src/Datatables.php b/src/Datatables.php index ec640a23..bed0fd43 100644 --- a/src/Datatables.php +++ b/src/Datatables.php @@ -2,15 +2,6 @@ namespace Yajra\Datatables; -/** - * Laravel Datatables Package - * This Package is created to handle server-side works of DataTables Jquery Plugin (http://datatables.net) - * - * @package Laravel - * @category Package - * @author Arjay Angeles - */ - use Illuminate\Database\Query\Builder as QueryBuilder; use Illuminate\Support\Collection; use Yajra\Datatables\Engines\CollectionEngine; @@ -18,12 +9,13 @@ use Yajra\Datatables\Engines\QueryBuilderEngine; /** - * Class Datatables + * Class Datatables. * * @package Yajra\Datatables * @method EloquentEngine eloquent($builder) * @method CollectionEngine collection(Collection $builder) * @method QueryBuilderEngine queryBuilder(QueryBuilder $builder) + * @author Arjay Angeles */ class Datatables { @@ -42,7 +34,7 @@ class Datatables public $builder; /** - * Class Constructor + * Datatables constructor. * * @param \Yajra\Datatables\Request $request */ @@ -52,7 +44,7 @@ public function __construct(Request $request) } /** - * Gets query and returns instance of class + * Gets query and returns instance of class. * * @param mixed $builder * @return mixed @@ -93,6 +85,17 @@ 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. * @@ -111,17 +114,6 @@ public function __call($name, $arguments) return trigger_error('Call to undefined method ' . __CLASS__ . '::' . $name . '()', E_USER_ERROR); } - /** - * Datatables using Eloquent - * - * @param mixed $builder - * @return \Yajra\Datatables\Engines\EloquentEngine - */ - public function usingEloquent($builder) - { - return new EloquentEngine($builder, $this->request); - } - /** * Get html builder class. * diff --git a/src/DatatablesServiceProvider.php b/src/DatatablesServiceProvider.php index 373ddc2f..50237485 100644 --- a/src/DatatablesServiceProvider.php +++ b/src/DatatablesServiceProvider.php @@ -8,6 +8,12 @@ use Yajra\Datatables\Generators\DataTablesMakeCommand; use Yajra\Datatables\Generators\DataTablesScopeCommand; +/** + * Class DatatablesServiceProvider. + * + * @package Yajra\Datatables + * @author Arjay Angeles + */ class DatatablesServiceProvider extends ServiceProvider { /** diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 0e698914..68428d39 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -2,14 +2,6 @@ namespace Yajra\Datatables\Engines; -/* - * Laravel Datatables Base Engine - * - * @package Laravel - * @category Package - * @author Arjay Angeles - */ - use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Config; use Illuminate\Support\Str; @@ -20,6 +12,12 @@ use Yajra\Datatables\Helper; use Yajra\Datatables\Processors\DataProcessor; +/** + * Class BaseEngine. + * + * @package Yajra\Datatables\Engines + * @author Arjay Angeles + */ abstract class BaseEngine implements DataTableEngineContract { /** diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 80762a1f..5d9a6a0b 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -10,11 +10,10 @@ use Yajra\Datatables\Request; /** - * Laravel Datatables Collection Engine + * Class CollectionEngine. * - * @package Laravel - * @category Package - * @author Arjay Angeles + * @package Yajra\Datatables\Engines + * @author Arjay Angeles */ class CollectionEngine extends BaseEngine { diff --git a/src/Engines/EloquentEngine.php b/src/Engines/EloquentEngine.php index 4986a3c5..abcdaa85 100644 --- a/src/Engines/EloquentEngine.php +++ b/src/Engines/EloquentEngine.php @@ -6,11 +6,10 @@ use Yajra\Datatables\Request; /** - * Laravel Datatables Eloquent Engine + * Class EloquentEngine. * - * @package Laravel - * @category Package - * @author Arjay Angeles + * @package Yajra\Datatables\Engines + * @author Arjay Angeles */ class EloquentEngine extends QueryBuilderEngine { diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index b4b8f2d3..cc733c89 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -9,11 +9,10 @@ use Yajra\Datatables\Request; /** - * Laravel Datatables Query Builder Engine + * Class QueryBuilderEngine. * - * @package Laravel - * @category Package - * @author Arjay Angeles + * @package Yajra\Datatables\Engines + * @author Arjay Angeles */ class QueryBuilderEngine extends BaseEngine { diff --git a/src/Facades/Datatables.php b/src/Facades/Datatables.php index b23d15d6..695cb3f7 100644 --- a/src/Facades/Datatables.php +++ b/src/Facades/Datatables.php @@ -4,6 +4,12 @@ use Illuminate\Support\Facades\Facade; +/** + * Class Datatables. + * + * @package Yajra\Datatables\Facades + * @author Arjay Angeles + */ class Datatables extends Facade { /** diff --git a/src/Generators/DataTablesMakeCommand.php b/src/Generators/DataTablesMakeCommand.php index ece2fda5..b5175eb5 100644 --- a/src/Generators/DataTablesMakeCommand.php +++ b/src/Generators/DataTablesMakeCommand.php @@ -4,6 +4,12 @@ use Illuminate\Console\GeneratorCommand; +/** + * Class DataTablesMakeCommand. + * + * @package Yajra\Datatables\Generators + * @author Arjay Angeles + */ class DataTablesMakeCommand extends GeneratorCommand { /** diff --git a/src/Generators/DataTablesScopeCommand.php b/src/Generators/DataTablesScopeCommand.php index 478f6913..537c4575 100644 --- a/src/Generators/DataTablesScopeCommand.php +++ b/src/Generators/DataTablesScopeCommand.php @@ -4,6 +4,12 @@ use Illuminate\Console\GeneratorCommand; +/** + * Class DataTablesScopeCommand. + * + * @package Yajra\Datatables\Generators + * @author Arjay Angeles + */ class DataTablesScopeCommand extends GeneratorCommand { /** diff --git a/src/Helper.php b/src/Helper.php index 540b5f55..db6a661b 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -8,6 +8,12 @@ use Illuminate\Support\Str; use Illuminate\View\Compilers\BladeCompiler; +/** + * Class Helper. + * + * @package Yajra\Datatables + * @author Arjay Angeles + */ class Helper { /** diff --git a/src/Html/Builder.php b/src/Html/Builder.php index d9d66e2e..5b934db1 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -11,9 +11,10 @@ use Illuminate\Support\Str; /** - * Class Builder + * Class Builder. * * @package Yajra\Datatables\Html + * @author Arjay Angeles */ class Builder { diff --git a/src/Html/Column.php b/src/Html/Column.php index 528715fb..6f3c6285 100644 --- a/src/Html/Column.php +++ b/src/Html/Column.php @@ -5,10 +5,11 @@ use Illuminate\Support\Fluent; /** - * Class Column + * Class Column. * * @package Yajra\Datatables\Html * @see https://datatables.net/reference/option/ for possible columns option + * @author Arjay Angeles */ class Column extends Fluent { diff --git a/src/Html/Parameters.php b/src/Html/Parameters.php index 38bfe21c..a462a44c 100644 --- a/src/Html/Parameters.php +++ b/src/Html/Parameters.php @@ -5,10 +5,11 @@ use Illuminate\Support\Fluent; /** - * Class Parameters + * Class Parameters. * * @package Yajra\Datatables\Html * @see https://datatables.net/reference/option/ for possible columns option + * @author Arjay Angeles */ class Parameters extends Fluent { diff --git a/src/Processors/DataProcessor.php b/src/Processors/DataProcessor.php index 4d8295ed..f6f70564 100644 --- a/src/Processors/DataProcessor.php +++ b/src/Processors/DataProcessor.php @@ -6,9 +6,10 @@ use Yajra\Datatables\Helper; /** - * Class DataProcessor + * Class DataProcessor. * * @package Yajra\Datatables + * @author Arjay Angeles */ class DataProcessor { diff --git a/src/Processors/RowProcessor.php b/src/Processors/RowProcessor.php index bdc229d3..3b55af77 100644 --- a/src/Processors/RowProcessor.php +++ b/src/Processors/RowProcessor.php @@ -6,9 +6,10 @@ use Yajra\Datatables\Helper; /** - * Class RowProcessor + * Class RowProcessor. * * @package Yajra\Datatables + * @author Arjay Angeles */ class RowProcessor { diff --git a/src/Request.php b/src/Request.php index afb61c1d..3b8550ca 100644 --- a/src/Request.php +++ b/src/Request.php @@ -6,7 +6,11 @@ use Illuminate\Http\Request as IlluminateRequest; /** + * Class Request. + * * @property array columns + * @package Yajra\Datatables + * @author Arjay Angeles */ class Request extends IlluminateRequest { diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 49450963..5e9348cc 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -11,6 +11,12 @@ use Yajra\Datatables\Datatables; use Yajra\Datatables\Transformers\DataTransformer; +/** + * Class DataTable. + * + * @package Yajra\Datatables\Services + * @author Arjay Angeles + */ abstract class DataTable implements DataTableContract, DataTableButtonsContract { /** diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index 46f4758b..ec87415a 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -5,9 +5,10 @@ use Illuminate\Support\Collection; /** - * Class DataTransformer + * Class DataTransformer. * * @package Yajra\Datatables\Transformers + * @author Arjay Angeles */ class DataTransformer { From e966f9185bc2b633ed9a7ee07473cf5b06766251 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 12 Mar 2016 10:09:17 +0800 Subject: [PATCH 111/322] Bump v6.9.0 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69e01b13..267d94db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,12 +8,13 @@ ##Change Log -###UNRELEASED +###v6.9.0 - 2016-03-11 - Re-implement facade. - Add blacklist and whitelist feature. - Fix string casting for object values. - Add missing doc block for getSearchKeyword. - Fix eloquent engine missing parent constructor. + - Add/Update class doc blocks. ###v6.8.0 - 2016-03-11 - Added Closure support for filterColumn method. From 89c4c41ca02aeed18dac98fb1128f2f03ff17e46 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 12 Mar 2016 17:48:43 +0800 Subject: [PATCH 112/322] Add default array value when getting columns. Fix #448 --- CHANGELOG.md | 3 +++ src/Engines/QueryBuilderEngine.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 267d94db..13c7e403 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +###v6.9.1 - 2016-03-11 + - Add default array value when getting columns. Fix #448 + ###v6.9.0 - 2016-03-11 - Re-implement facade. - Add blacklist and whitelist feature. diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index cc733c89..499734b3 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -289,7 +289,7 @@ public function castColumn($column) */ public function columnSearch() { - $columns = $this->request->get('columns'); + $columns = $this->request->get('columns', []); foreach ($columns as $index => $column) { if (! $this->request->isColumnSearchable($index)) { From 06f0fd7abf93b43f7aee89a7d9d5d23e1437fd4f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 14:58:44 +0800 Subject: [PATCH 113/322] Add github templates. --- CONTRIBUTING.md => .github/CONTRIBUTING.md | 0 .github/ISSUE_TEMPLATE.md | 31 ++++++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 10 +++++++ readme.md | 2 +- 4 files changed, 42 insertions(+), 1 deletion(-) rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING.md rename to .github/CONTRIBUTING.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..7e0746cd --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,31 @@ + +### Summary of problem or feature request + + + + +### Code snippet of problem + + + +### System details + + + +- Operating System +- PHP Version +- Laravel Version +- Laravel-Datatables Version diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..7f8e07d9 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,10 @@ + diff --git a/readme.md b/readme.md index 5dd0cf6f..a6e5bf52 100644 --- a/readme.md +++ b/readme.md @@ -96,7 +96,7 @@ And that's it! Start building out some awesome DataTables! ## Contributing -Please see [CONTRIBUTING](https://github.com/yajra/laravel-datatables/blob/master/CONTRIBUTING.md) for details. +Please see [CONTRIBUTING](https://github.com/yajra/laravel-datatables/blob/master/.github/CONTRIBUTING.md) for details. ## Security From de3df979fc2c5da743c6bc04ddd24335d70d6f40 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 14:59:58 +0800 Subject: [PATCH 114/322] Remove readme. --- readme.md | 112 ------------------------------------------------------ 1 file changed, 112 deletions(-) delete mode 100644 readme.md diff --git a/readme.md b/readme.md deleted file mode 100644 index a6e5bf52..00000000 --- a/readme.md +++ /dev/null @@ -1,112 +0,0 @@ -# jQuery DataTables API for Laravel 4|5 - -[![Laravel 4.2|5.0|5.1|5.2](https://img.shields.io/badge/Laravel-4.2|5.0|5.1|5.2-orange.svg)](http://laravel.com) -[![Latest Stable Version](https://poser.pugx.org/yajra/laravel-datatables-oracle/v/stable)](https://packagist.org/packages/yajra/laravel-datatables-oracle) -[![Build Status](https://travis-ci.org/yajra/laravel-datatables.svg?branch=master)](https://travis-ci.org/yajra/laravel-datatables) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/yajra/laravel-datatables/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/yajra/laravel-datatables/?branch=master) -[![Total Downloads](https://poser.pugx.org/yajra/laravel-datatables-oracle/downloads)](https://packagist.org/packages/yajra/laravel-datatables-oracle) -[![License](https://poser.pugx.org/yajra/laravel-datatables-oracle/license)](https://packagist.org/packages/yajra/laravel-datatables-oracle) - -This package is created to handle [server-side](https://www.datatables.net/manual/server-side) works of [DataTables](http://datatables.net) jQuery Plugin via [AJAX option](https://datatables.net/reference/option/ajax) by using Eloquent ORM, Fluent Query Builder or Collection. - -```php -use Yajra\Datatables\Facades\Datatables; - -// Using Eloquent -return Datatables::eloquent(User::query())->make(true); - -// Using Query Builder -return Datatables::queryBuilder(DB::table('users'))->make(true); - -// Using Collection -return Datatables::collection(User::all())->make(true); - -// Using the Engine Factory -return Datatables::of(User::query())->make(true); -return Datatables::of(DB::table('users'))->make(true); -return Datatables::of(User::all())->make(true); -``` - -## Feature Overview -- Supports the following data source - - **Eloquent ORM** - - **Fluent Query Builder** - - **Collection** [available on v5.x and later] -- [DataTable Service Implementation (v6.x)](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md#v600---datatable-service-implementation). -- Adding or editing content of columns and removing columns -- Modify column values via Blade Template Engine or by using Closure -- Works with **ALL the DATABASE** supported by Laravel -- Works with **Oracle Database** using [Laravel-OCI8](https://github.com/yajra/laravel-oci8) package -- Works with [DataTables](http://datatables.net) v1.10++. - - **Note:** DT Legacy code is not supported on v5.x -- Works with [DataTables](http://datatables.net) v1.9 and v1.10 legacy code. - - **Note:** Use [v4.x](https://github.com/yajra/laravel-datatables-oracle/tree/v4.3.2) for Laravel 5 and [v3.x](https://github.com/yajra/laravel-datatables-oracle/tree/L4) for Laravel 4 -- Extended column filtering via `filterColumn` API. -- Extended column ordering via `orderColumn` API. -- Extended Query Builder functionality allowing you to filter using Datatables class directly. -- Decorate your data output using [`league\fractal`](https://github.com/thephpleague/fractal) Transformer with Serializer support. -- Works with Laravel Dependency Injection and IoC Container. -- Provides a [DataTable Html Builder](http://datatables.yajrabox.com/html) to help you use the package with less code. -- Provides XSS filtering function to optionally escape all or specified column values using `escapeColumns('*'\['column'])` method. -- Provides Query Logging when application is in debug state. - **Important: Make sure that debug is set to false when your code is in production** -- Easily attach a resource on json response via `->with()` method. -- Built-in support for exporting to CSV, EXCEL and PDF using [Laravel-Excel](https://github.com/Maatwebsite/Laravel-Excel). -- Built-in printer friendly view or create your own by overriding `printPreview()` method. -- Provides an artisan command for generating a DataTable service and scope. -- Provides **WHITELIST** and **BLACKLIST** feature to explicitly allow/deny columns from searching/sorting. -- See [change logs](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md) for more details. - -## Requirements: -- PHP 5.5.9 or later. -- Laravel 5.0 or later. -- [DataTables jQuery Plugin](http://datatables.net/) v1.10.x - -## Laravel 4.2 & DataTables v1.9.x Users -Most of the latest updates/features are not available on these versions. Please check [L4 Branch](https://github.com/yajra/laravel-datatables/tree/L4) and [L5 DT1.9](https://github.com/yajra/laravel-datatables/tree/L5-DT1.9) for old documentations of its features. - -## Buy me a beer -Click here to lend your support to: Laravel Datatables and make a donation at pledgie.com ! - -## Documentations -- You will find user friendly and updated documentation in the wiki here: [Laravel Datatables Wiki](https://github.com/yajra/laravel-datatables/wiki) -- You will find the API Documentation here: [Laravel Datatables API](http://yajra.github.io/laravel-datatables/api/) -- [Demo Application](http://datatables.yajrabox.com) is available for artisan's reference. - -## Quick Installation -`composer require yajra/laravel-datatables-oracle:~6.0` - -#### Service Provider -`Yajra\Datatables\DatatablesServiceProvider::class` - -#### Facade -`Datatables` facade are automatically registered as an alias for `Yajra\Datatables\Facades\Datatables` class. - -#### Configuration and Assets -`$ php artisan vendor:publish --tag=datatables` - -And that's it! Start building out some awesome DataTables! - -## Upgrading from v5.x to v6.x - - Change all occurrences of `yajra\Datatables` to `Yajra\Datatables`. (Use Sublime's find and replace all for faster update). - - Remove `Datatables` facade registration. - - Temporarily comment out `Yajra\Datatables\DatatablesServiceProvider`. - - Update package version on your composer.json and use `yajra/laravel-datatables-oracle: ~6.0` - - Uncomment the provider `Yajra\Datatables\DatatablesServiceProvider`. - -## Contributing - -Please see [CONTRIBUTING](https://github.com/yajra/laravel-datatables/blob/master/.github/CONTRIBUTING.md) for details. - -## Security - -If you discover any security related issues, please email [aqangeles@gmail.com](mailto:aqangeles@gmail.com) instead of using the issue tracker. - -## Credits - -- This project is used to be a fork from [bllim/laravel4-datatables-package](https://github.com/bllim/laravel4-datatables-package). -- [All Contributors](https://github.com/yajra/laravel-datatables/graphs/contributors) - -## License - -The MIT License (MIT). Please see [License File](https://github.com/yajra/laravel-datatables/blob/master/LICENSE.md) for more information. From 6be231ee9ada2cfaf4c115e82354c62999d9312b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 15:00:29 +0800 Subject: [PATCH 115/322] Add README.md --- README.md | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..a6e5bf52 --- /dev/null +++ b/README.md @@ -0,0 +1,112 @@ +# jQuery DataTables API for Laravel 4|5 + +[![Laravel 4.2|5.0|5.1|5.2](https://img.shields.io/badge/Laravel-4.2|5.0|5.1|5.2-orange.svg)](http://laravel.com) +[![Latest Stable Version](https://poser.pugx.org/yajra/laravel-datatables-oracle/v/stable)](https://packagist.org/packages/yajra/laravel-datatables-oracle) +[![Build Status](https://travis-ci.org/yajra/laravel-datatables.svg?branch=master)](https://travis-ci.org/yajra/laravel-datatables) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/yajra/laravel-datatables/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/yajra/laravel-datatables/?branch=master) +[![Total Downloads](https://poser.pugx.org/yajra/laravel-datatables-oracle/downloads)](https://packagist.org/packages/yajra/laravel-datatables-oracle) +[![License](https://poser.pugx.org/yajra/laravel-datatables-oracle/license)](https://packagist.org/packages/yajra/laravel-datatables-oracle) + +This package is created to handle [server-side](https://www.datatables.net/manual/server-side) works of [DataTables](http://datatables.net) jQuery Plugin via [AJAX option](https://datatables.net/reference/option/ajax) by using Eloquent ORM, Fluent Query Builder or Collection. + +```php +use Yajra\Datatables\Facades\Datatables; + +// Using Eloquent +return Datatables::eloquent(User::query())->make(true); + +// Using Query Builder +return Datatables::queryBuilder(DB::table('users'))->make(true); + +// Using Collection +return Datatables::collection(User::all())->make(true); + +// Using the Engine Factory +return Datatables::of(User::query())->make(true); +return Datatables::of(DB::table('users'))->make(true); +return Datatables::of(User::all())->make(true); +``` + +## Feature Overview +- Supports the following data source + - **Eloquent ORM** + - **Fluent Query Builder** + - **Collection** [available on v5.x and later] +- [DataTable Service Implementation (v6.x)](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md#v600---datatable-service-implementation). +- Adding or editing content of columns and removing columns +- Modify column values via Blade Template Engine or by using Closure +- Works with **ALL the DATABASE** supported by Laravel +- Works with **Oracle Database** using [Laravel-OCI8](https://github.com/yajra/laravel-oci8) package +- Works with [DataTables](http://datatables.net) v1.10++. + - **Note:** DT Legacy code is not supported on v5.x +- Works with [DataTables](http://datatables.net) v1.9 and v1.10 legacy code. + - **Note:** Use [v4.x](https://github.com/yajra/laravel-datatables-oracle/tree/v4.3.2) for Laravel 5 and [v3.x](https://github.com/yajra/laravel-datatables-oracle/tree/L4) for Laravel 4 +- Extended column filtering via `filterColumn` API. +- Extended column ordering via `orderColumn` API. +- Extended Query Builder functionality allowing you to filter using Datatables class directly. +- Decorate your data output using [`league\fractal`](https://github.com/thephpleague/fractal) Transformer with Serializer support. +- Works with Laravel Dependency Injection and IoC Container. +- Provides a [DataTable Html Builder](http://datatables.yajrabox.com/html) to help you use the package with less code. +- Provides XSS filtering function to optionally escape all or specified column values using `escapeColumns('*'\['column'])` method. +- Provides Query Logging when application is in debug state. + **Important: Make sure that debug is set to false when your code is in production** +- Easily attach a resource on json response via `->with()` method. +- Built-in support for exporting to CSV, EXCEL and PDF using [Laravel-Excel](https://github.com/Maatwebsite/Laravel-Excel). +- Built-in printer friendly view or create your own by overriding `printPreview()` method. +- Provides an artisan command for generating a DataTable service and scope. +- Provides **WHITELIST** and **BLACKLIST** feature to explicitly allow/deny columns from searching/sorting. +- See [change logs](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md) for more details. + +## Requirements: +- PHP 5.5.9 or later. +- Laravel 5.0 or later. +- [DataTables jQuery Plugin](http://datatables.net/) v1.10.x + +## Laravel 4.2 & DataTables v1.9.x Users +Most of the latest updates/features are not available on these versions. Please check [L4 Branch](https://github.com/yajra/laravel-datatables/tree/L4) and [L5 DT1.9](https://github.com/yajra/laravel-datatables/tree/L5-DT1.9) for old documentations of its features. + +## Buy me a beer +Click here to lend your support to: Laravel Datatables and make a donation at pledgie.com ! + +## Documentations +- You will find user friendly and updated documentation in the wiki here: [Laravel Datatables Wiki](https://github.com/yajra/laravel-datatables/wiki) +- You will find the API Documentation here: [Laravel Datatables API](http://yajra.github.io/laravel-datatables/api/) +- [Demo Application](http://datatables.yajrabox.com) is available for artisan's reference. + +## Quick Installation +`composer require yajra/laravel-datatables-oracle:~6.0` + +#### Service Provider +`Yajra\Datatables\DatatablesServiceProvider::class` + +#### Facade +`Datatables` facade are automatically registered as an alias for `Yajra\Datatables\Facades\Datatables` class. + +#### Configuration and Assets +`$ php artisan vendor:publish --tag=datatables` + +And that's it! Start building out some awesome DataTables! + +## Upgrading from v5.x to v6.x + - Change all occurrences of `yajra\Datatables` to `Yajra\Datatables`. (Use Sublime's find and replace all for faster update). + - Remove `Datatables` facade registration. + - Temporarily comment out `Yajra\Datatables\DatatablesServiceProvider`. + - Update package version on your composer.json and use `yajra/laravel-datatables-oracle: ~6.0` + - Uncomment the provider `Yajra\Datatables\DatatablesServiceProvider`. + +## Contributing + +Please see [CONTRIBUTING](https://github.com/yajra/laravel-datatables/blob/master/.github/CONTRIBUTING.md) for details. + +## Security + +If you discover any security related issues, please email [aqangeles@gmail.com](mailto:aqangeles@gmail.com) instead of using the issue tracker. + +## Credits + +- This project is used to be a fork from [bllim/laravel4-datatables-package](https://github.com/bllim/laravel4-datatables-package). +- [All Contributors](https://github.com/yajra/laravel-datatables/graphs/contributors) + +## License + +The MIT License (MIT). Please see [License File](https://github.com/yajra/laravel-datatables/blob/master/LICENSE.md) for more information. From 3f4e28ea3c470af7715f838d7bd64648fbf7d323 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 15:03:20 +0800 Subject: [PATCH 116/322] Export ignore .github templates. --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index a5707b0f..1185e157 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,7 @@ * text=auto /tests export-ignore +.github/ export-ignore .editorconfig export-ignore .gitattributes export-ignore .gitignore export-ignore From d98c28b9d4aca6661e24228f6fe180fb2636c8dc Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 15:10:09 +0800 Subject: [PATCH 117/322] Add repo standard credits format. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a6e5bf52..6e1cb867 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,8 @@ If you discover any security related issues, please email [aqangeles@gmail.com]( ## Credits -- This project is used to be a fork from [bllim/laravel4-datatables-package](https://github.com/bllim/laravel4-datatables-package). +- [Arjay Angeles](https://github.com/yajra). +- [bllim/laravel4-datatables-package](https://github.com/bllim/laravel4-datatables-package). - [All Contributors](https://github.com/yajra/laravel-datatables/graphs/contributors) ## License From 791a778deb69f4cfc0aeb1b6ce233cc03862fd80 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 15:22:07 +0800 Subject: [PATCH 118/322] Remove feature overview. --- README.md | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 6e1cb867..4d0f0db4 100644 --- a/README.md +++ b/README.md @@ -27,36 +27,6 @@ return Datatables::of(DB::table('users'))->make(true); return Datatables::of(User::all())->make(true); ``` -## Feature Overview -- Supports the following data source - - **Eloquent ORM** - - **Fluent Query Builder** - - **Collection** [available on v5.x and later] -- [DataTable Service Implementation (v6.x)](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md#v600---datatable-service-implementation). -- Adding or editing content of columns and removing columns -- Modify column values via Blade Template Engine or by using Closure -- Works with **ALL the DATABASE** supported by Laravel -- Works with **Oracle Database** using [Laravel-OCI8](https://github.com/yajra/laravel-oci8) package -- Works with [DataTables](http://datatables.net) v1.10++. - - **Note:** DT Legacy code is not supported on v5.x -- Works with [DataTables](http://datatables.net) v1.9 and v1.10 legacy code. - - **Note:** Use [v4.x](https://github.com/yajra/laravel-datatables-oracle/tree/v4.3.2) for Laravel 5 and [v3.x](https://github.com/yajra/laravel-datatables-oracle/tree/L4) for Laravel 4 -- Extended column filtering via `filterColumn` API. -- Extended column ordering via `orderColumn` API. -- Extended Query Builder functionality allowing you to filter using Datatables class directly. -- Decorate your data output using [`league\fractal`](https://github.com/thephpleague/fractal) Transformer with Serializer support. -- Works with Laravel Dependency Injection and IoC Container. -- Provides a [DataTable Html Builder](http://datatables.yajrabox.com/html) to help you use the package with less code. -- Provides XSS filtering function to optionally escape all or specified column values using `escapeColumns('*'\['column'])` method. -- Provides Query Logging when application is in debug state. - **Important: Make sure that debug is set to false when your code is in production** -- Easily attach a resource on json response via `->with()` method. -- Built-in support for exporting to CSV, EXCEL and PDF using [Laravel-Excel](https://github.com/Maatwebsite/Laravel-Excel). -- Built-in printer friendly view or create your own by overriding `printPreview()` method. -- Provides an artisan command for generating a DataTable service and scope. -- Provides **WHITELIST** and **BLACKLIST** feature to explicitly allow/deny columns from searching/sorting. -- See [change logs](https://github.com/yajra/laravel-datatables/blob/6.0/CHANGELOG.md) for more details. - ## Requirements: - PHP 5.5.9 or later. - Laravel 5.0 or later. @@ -104,8 +74,8 @@ If you discover any security related issues, please email [aqangeles@gmail.com]( ## Credits -- [Arjay Angeles](https://github.com/yajra). -- [bllim/laravel4-datatables-package](https://github.com/bllim/laravel4-datatables-package). +- [Arjay Angeles](https://github.com/yajra) +- [bllim/laravel4-datatables-package](https://github.com/bllim/laravel4-datatables-package) - [All Contributors](https://github.com/yajra/laravel-datatables/graphs/contributors) ## License From dd1ea82908c6c15e26d8ef22d34311ff8290c062 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 15:27:28 +0800 Subject: [PATCH 119/322] Remove notes for Laravel 4 & fix grammar. --- README.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 4d0f0db4..c7623079 100644 --- a/README.md +++ b/README.md @@ -32,12 +32,6 @@ return Datatables::of(User::all())->make(true); - Laravel 5.0 or later. - [DataTables jQuery Plugin](http://datatables.net/) v1.10.x -## Laravel 4.2 & DataTables v1.9.x Users -Most of the latest updates/features are not available on these versions. Please check [L4 Branch](https://github.com/yajra/laravel-datatables/tree/L4) and [L5 DT1.9](https://github.com/yajra/laravel-datatables/tree/L5-DT1.9) for old documentations of its features. - -## Buy me a beer -Click here to lend your support to: Laravel Datatables and make a donation at pledgie.com ! - ## Documentations - You will find user friendly and updated documentation in the wiki here: [Laravel Datatables Wiki](https://github.com/yajra/laravel-datatables/wiki) - You will find the API Documentation here: [Laravel Datatables API](http://yajra.github.io/laravel-datatables/api/) @@ -50,7 +44,7 @@ Most of the latest updates/features are not available on these versions. Please `Yajra\Datatables\DatatablesServiceProvider::class` #### Facade -`Datatables` facade are automatically registered as an alias for `Yajra\Datatables\Facades\Datatables` class. +`Datatables` facade is automatically registered as an alias for `Yajra\Datatables\Facades\Datatables` class. #### Configuration and Assets `$ php artisan vendor:publish --tag=datatables` @@ -81,3 +75,6 @@ If you discover any security related issues, please email [aqangeles@gmail.com]( ## License The MIT License (MIT). Please see [License File](https://github.com/yajra/laravel-datatables/blob/master/LICENSE.md) for more information. + +## Buy me a beer +Click here to lend your support to: Laravel Datatables and make a donation at pledgie.com ! From 5094e344e04de6f567bc2d661947d66f86782ea9 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 15:30:50 +0800 Subject: [PATCH 120/322] Exclude .github. Remove colon. --- .scrutinizer.yml | 1 + README.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 9a20c997..85add7e0 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -7,3 +7,4 @@ filter: excluded_paths: - 'tests/*' - 'vendor/*' + - '.github/*' diff --git a/README.md b/README.md index c7623079..524f42c2 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ return Datatables::of(DB::table('users'))->make(true); return Datatables::of(User::all())->make(true); ``` -## Requirements: +## Requirements - PHP 5.5.9 or later. - Laravel 5.0 or later. - [DataTables jQuery Plugin](http://datatables.net/) v1.10.x From 99db3839792ba6a828e6e929343ea77e3713f62d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 15:34:36 +0800 Subject: [PATCH 121/322] Arrange gitignore. --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ae89308a..df0e1ea8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /vendor +/coverage composer.phar composer.lock -/coverage From f841acd26eb859fdf64f37ec846ff886739f3ba2 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 15:36:23 +0800 Subject: [PATCH 122/322] Update requirements. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 524f42c2..9db88bb4 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,8 @@ return Datatables::of(User::all())->make(true); ``` ## Requirements -- PHP 5.5.9 or later. -- Laravel 5.0 or later. +- [PHP 5.5.9 or later](http://php.net/) +- [Laravel 5.0 or later](https://github.com/laravel/framework) - [DataTables jQuery Plugin](http://datatables.net/) v1.10.x ## Documentations From 3770f7836ea1d1729b7e23a75c0bd8998ffc5a2e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 15:55:44 +0800 Subject: [PATCH 123/322] Add emphasis on DT version. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9db88bb4..0dbbc690 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ return Datatables::of(User::all())->make(true); ## Requirements - [PHP 5.5.9 or later](http://php.net/) - [Laravel 5.0 or later](https://github.com/laravel/framework) -- [DataTables jQuery Plugin](http://datatables.net/) v1.10.x +- [DataTables jQuery Plugin](http://datatables.net/) **Version 1.10.xx** ## Documentations - You will find user friendly and updated documentation in the wiki here: [Laravel Datatables Wiki](https://github.com/yajra/laravel-datatables/wiki) From 53227e592ced3087cbed9a699f37aeb28bd69f91 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 14 Mar 2016 17:01:06 +0800 Subject: [PATCH 124/322] [Proposal] Add smart search config option. Fix #423 --- src/Engines/BaseEngine.php | 39 +++++++++++++++++++++++++----- src/Engines/QueryBuilderEngine.php | 36 +++++++++++++++------------ src/config/config.php | 1 + 3 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 68428d39..f3801183 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -189,14 +189,28 @@ abstract class BaseEngine implements DataTableEngineContract */ public function setupKeyword($value) { - $keyword = '%' . $value . '%'; - if ($this->isWildcard()) { - $keyword = $this->wildcardLikeString($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; } - // 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); } /** @@ -769,6 +783,19 @@ public function 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. * diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 499734b3..a43875ef 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -256,14 +256,18 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) */ protected function compileGlobalSearch($query, $column, $keyword) { - $column = $this->castColumn($column); - $sql = $column . ' LIKE ?'; - if ($this->isCaseInsensitive()) { - $sql = 'LOWER(' . $column . ') LIKE ?'; - $keyword = Str::lower($keyword); - } + if ($this->isSmartSearch()) { + $column = $this->castColumn($column); + $sql = $column . ' LIKE ?'; + if ($this->isCaseInsensitive()) { + $sql = 'LOWER(' . $column . ') LIKE ?'; + $keyword = Str::lower($keyword); + } - $query->orWhereRaw($sql, [$keyword]); + $query->orWhereRaw($sql, [$keyword]); + } else { + $query->orWhere($column, 'like', $keyword); + } } /** @@ -318,15 +322,15 @@ public function columnSearch() ); } } else { - $column = $this->castColumn($column); - $keyword = $this->getSearchKeyword($index); + $column = $this->castColumn($column); + $keyword = $this->getSearchKeyword($index); + $caseInsensitive = $this->isCaseInsensitive(); - if ($this->isCaseInsensitive()) { - $this->compileColumnSearch($index, $column, $keyword, false); - } else { - $col = strstr($column, '(') ? $this->connection->raw($column) : $column; - $this->compileColumnSearch($index, $col, $keyword, true); + if (! $caseInsensitive) { + $column = strstr($column, '(') ? $this->connection->raw($column) : $column; } + + $this->compileColumnSearch($index, $column, $keyword, $caseInsensitive); } $this->isFilterApplied = true; @@ -362,10 +366,12 @@ protected function compileColumnSearch($i, $column, $keyword, $caseSensitive = t { if ($this->request->isRegex($i)) { $this->regexColumnSearch($column, $keyword, $caseSensitive); - } else { + } elseif ($this->isSmartSearch()) { $sql = $caseSensitive ? $column . ' LIKE ?' : 'LOWER(' . $column . ') LIKE ?'; $keyword = $caseSensitive ? $keyword : Str::lower($keyword); $this->query->whereRaw($sql, [$keyword]); + } else { + $this->query->where($column, 'like', $keyword); } } diff --git a/src/config/config.php b/src/config/config.php index 91da5166..8c08646e 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -2,6 +2,7 @@ return [ 'search' => [ + 'smart' => true, 'case_insensitive' => true, 'use_wildcards' => false, ], From 0563f6bfd3e71a2c1e406793ed6eac95f0b88599 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 16 Mar 2016 21:38:38 +0800 Subject: [PATCH 125/322] Pull-up isOracleSQL and fix condition using oci8. --- CHANGELOG.md | 3 +++ src/Engines/BaseEngine.php | 10 ++++++++++ src/Engines/QueryBuilderEngine.php | 10 ---------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13c7e403..95e295b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +###v6.9.2 - 2016-03-16 + - Pull-up isOracleSQL and fix condition using oci8. + ###v6.9.1 - 2016-03-11 - Add default array value when getting columns. Fix #448 diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 68428d39..a827e4bd 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -873,4 +873,14 @@ protected function extractColumnName($str, $wantsAlias) 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']); + } } diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 499734b3..a3c9fb07 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -387,16 +387,6 @@ protected function regexColumnSearch($column, $keyword, $caseSensitive = true) } } - /** - * Check if the current sql language is based on oracle syntax. - * - * @return bool - */ - protected function isOracleSql() - { - return $this->database === 'oracle'; - } - /** * Perform sorting of columns. * From 091aae65fa073f2467b7275180c6112f3bf186ba Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 16 Mar 2016 21:52:55 +0800 Subject: [PATCH 126/322] Fix exact match search backtick issue. --- src/Engines/QueryBuilderEngine.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index a43875ef..7cc18d2b 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -265,8 +265,8 @@ protected function compileGlobalSearch($query, $column, $keyword) } $query->orWhereRaw($sql, [$keyword]); - } else { - $query->orWhere($column, 'like', $keyword); + } else { // exact match + $query->orWhereRaw("$column like ?", $keyword); } } @@ -370,8 +370,8 @@ protected function compileColumnSearch($i, $column, $keyword, $caseSensitive = t $sql = $caseSensitive ? $column . ' LIKE ?' : 'LOWER(' . $column . ') LIKE ?'; $keyword = $caseSensitive ? $keyword : Str::lower($keyword); $this->query->whereRaw($sql, [$keyword]); - } else { - $this->query->where($column, 'like', $keyword); + } else { // exact match + $this->query->whereRaw("$column LIKE ?", $keyword); } } From e7b08a8d5ae664a0178f3fcd285319fd7663bf84 Mon Sep 17 00:00:00 2001 From: Vlad Kucherov Date: Wed, 16 Mar 2016 20:19:08 +0200 Subject: [PATCH 127/322] Allows passing instance of Column into Builder columns --- src/Html/Builder.php | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 5b934db1..6f8c39ba 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -307,17 +307,21 @@ public function add(Column $column) public function columns(array $columns) { foreach ($columns as $key => $value) { - if (is_array($value)) { - $attributes = array_merge(['name' => $key, 'data' => $key], $this->setTitle($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 { - $attributes = [ - 'name' => $value, - 'data' => $value, - 'title' => $this->getQualifiedTitle($value), - ]; + $this->collection->push($value); } - - $this->collection->push(new Column($attributes)); } return $this; From f493c0249330c3017ac672c0e457aec0dc6626cb Mon Sep 17 00:00:00 2001 From: Vlad Kucherov Date: Wed, 16 Mar 2016 20:51:20 +0200 Subject: [PATCH 128/322] Adds an option to pass parameters to column render --- src/Html/Column.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Html/Column.php b/src/Html/Column.php index 6f3c6285..703b6a93 100644 --- a/src/Html/Column.php +++ b/src/Html/Column.php @@ -44,11 +44,17 @@ 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($value); + return $value($parameters); } elseif ($view->exists($value)) { - return $view->make($value)->render(); + return $view->make($value)->with($parameters)->render(); } return $value ? $this->parseRenderAsString($value) : null; From 30cc247a1409d3188d940c44e08563b9d57349ef Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 17 Mar 2016 06:44:32 +0800 Subject: [PATCH 129/322] Fix missing brackets. --- src/Engines/QueryBuilderEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 7cc18d2b..c79a8187 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -266,7 +266,7 @@ protected function compileGlobalSearch($query, $column, $keyword) $query->orWhereRaw($sql, [$keyword]); } else { // exact match - $query->orWhereRaw("$column like ?", $keyword); + $query->orWhereRaw("$column like ?", [$keyword]); } } @@ -371,7 +371,7 @@ protected function compileColumnSearch($i, $column, $keyword, $caseSensitive = t $keyword = $caseSensitive ? $keyword : Str::lower($keyword); $this->query->whereRaw($sql, [$keyword]); } else { // exact match - $this->query->whereRaw("$column LIKE ?", $keyword); + $this->query->whereRaw("$column LIKE ?", [$keyword]); } } From ab634409838fda57810421b9ab471065e6de1111 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 17 Mar 2016 06:47:12 +0800 Subject: [PATCH 130/322] Fix security issue as reported in #460. --- src/Services/DataTable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 5e9348cc..eedc350d 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -90,7 +90,7 @@ public function render($view, $data = [], $mergeData = []) return $this->ajax(); } - if ($action = $this->request()->get('action')) { + if ($action = $this->request()->get('action') AND in_array($action, ['print', 'csv', 'excel', 'pdf'])) { if ($action == 'print') { return $this->printPreview(); } From cc1234828c302c59534368e35fdd1fda80d9528e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 17 Mar 2016 06:55:39 +0800 Subject: [PATCH 131/322] Fix cs. --- src/Html/Builder.php | 2 +- src/Html/Column.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 6f8c39ba..de2d5552 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -307,7 +307,7 @@ public function add(Column $column) public function columns(array $columns) { foreach ($columns as $key => $value) { - if(!is_a($value, Column::class)) { + if (! is_a($value, Column::class)) { if (is_array($value)) { $attributes = array_merge(['name' => $key, 'data' => $key], $this->setTitle($key, $value)); } else { diff --git a/src/Html/Column.php b/src/Html/Column.php index 703b6a93..4694f858 100644 --- a/src/Html/Column.php +++ b/src/Html/Column.php @@ -43,12 +43,12 @@ public function __construct($attributes = []) public function parseRender($value) { /** @var \Illuminate\Contracts\View\Factory $view */ - $view = app('view'); + $view = app('view'); $parameters = []; - if(is_array($value)) { + if (is_array($value)) { $parameters = array_except($value, 0); - $value = $value[0]; + $value = $value[0]; } if (is_callable($value)) { From 1504b8d9e1f51cf00676fe957c1777c221d1e872 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 17 Mar 2016 06:57:09 +0800 Subject: [PATCH 132/322] Bump v6.9.3 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 95e295b7..04a1ca9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +###v6.9.3 - 2016-03-17 + - Adds an option to pass parameters to column render. + - Allows passing instance of Column into Builder columns. + - Fix security issue as reported in #460. + - Credits to @vladkucherov for this changes. + ###v6.9.2 - 2016-03-16 - Pull-up isOracleSQL and fix condition using oci8. From f13f26804879b2b366aa593b6b576ce9e8b2caa4 Mon Sep 17 00:00:00 2001 From: Maxime Freschard Date: Thu, 17 Mar 2016 15:58:04 +0100 Subject: [PATCH 133/322] Use detailed namespace in app() helper Fix namespace conflict that can occur when using other packages having their own implementation of DataTables (like the pragmarx/tracker package). Fixes Issue #464 --- src/Datatables.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Datatables.php b/src/Datatables.php index bed0fd43..90bb5623 100644 --- a/src/Datatables.php +++ b/src/Datatables.php @@ -51,7 +51,7 @@ public function __construct(Request $request) */ public static function of($builder) { - $datatables = app('datatables'); + $datatables = app('Yajra\Datatables\Datatables'); $datatables->builder = $builder; if ($builder instanceof QueryBuilder) { From 22bc8c0f0ecb221ff4af3b51e812ddf369a3f1a8 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 18 Mar 2016 08:05:08 +0800 Subject: [PATCH 134/322] Bump v6.9.4 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04a1ca9d..021e346a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.9.4 - 2016-03-18 + - Use full namespace in app() helper. + - PR #465, credits to @ligne13. + ###v6.9.3 - 2016-03-17 - Adds an option to pass parameters to column render. - Allows passing instance of Column into Builder columns. From eb87d591eedbde1bf4dc34c5aba8c335447ad261 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 18 Mar 2016 21:17:14 +0800 Subject: [PATCH 135/322] Fix eager loading column search. Fix issue #443 --- src/Engines/QueryBuilderEngine.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index a3c9fb07..23f6c9de 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -318,6 +318,16 @@ public function columnSearch() ); } } 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); + } + } + $column = $this->castColumn($column); $keyword = $this->getSearchKeyword($index); From 45067ad4d48a13ed7b46b6111d7952d7bc1ae248 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 18 Mar 2016 21:40:34 +0800 Subject: [PATCH 136/322] Add option to create a table footer from builder defined via column info. --- src/Html/Builder.php | 18 ++++++++++++++++-- src/Html/Column.php | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index de2d5552..36a84622 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -182,6 +182,7 @@ protected function encodeColumnFunctions(array $parameters) 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']; @@ -396,6 +397,7 @@ public function addAction(array $attributes = []) 'searchable' => false, 'exportable' => false, 'printable' => true, + 'footer' => ' ', ], $attributes); $this->collection->push(new Column($attributes)); @@ -419,13 +421,25 @@ public function ajax($attributes) * Generate DataTable's table html. * * @param array $attributes + * @param bool $footer * @return string */ - public function table(array $attributes = []) + public function table(array $attributes = [], $footer = false) { $this->tableAttributes = array_merge($this->tableAttributes, $attributes); - return 'html->attributes($this->tableAttributes) . '>
'; + $footerHtml = ''; + if ($footer) { + $footerHtml = ''; + $footerHtml .= ''; + foreach ($this->collection->all() as $column) { + $footerHtml .= '' . $column->footer . ''; + } + $footerHtml .= ''; + $footerHtml .= ''; + } + + return 'html->attributes($this->tableAttributes) . '>' . $footerHtml . '
'; } /** diff --git a/src/Html/Column.php b/src/Html/Column.php index 4694f858..fce85236 100644 --- a/src/Html/Column.php +++ b/src/Html/Column.php @@ -22,6 +22,7 @@ public function __construct($attributes = []) $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) { From 4e6ac630caf8df60ffcb8a2926deeaf45578504c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 19 Mar 2016 10:09:54 +0800 Subject: [PATCH 137/322] Bump v6.10.0. --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 021e346a..584db55d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,12 @@ ##Change Log +###v6.10.0 - 2016-03-19 + - Add feature to enable/disable smart search via config or during runtime. Fix #423 + - See PR #452 for details. + ###v6.9.4 - 2016-03-18 - - Use full namespace in app() helper. + - Use full namespace in app() helper. - PR #465, credits to @ligne13. ###v6.9.3 - 2016-03-17 From 3660c338b389037e1ec48b0a83a4e698422c0342 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 22 Mar 2016 12:29:19 +0800 Subject: [PATCH 138/322] Bump v6.10.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 584db55d..15e63491 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.10.1 - 2016-03-22 + - Fix eager loading column search. PR #469. + - Fix issue #443. + ###v6.10.0 - 2016-03-19 - Add feature to enable/disable smart search via config or during runtime. Fix #423 - See PR #452 for details. From 7fb40fac249694f7368accec1dc8731d7c9238cb Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 30 Mar 2016 14:13:00 +0800 Subject: [PATCH 139/322] Fix eager loading ordering for belongsToMany relationship. Fix #461 --- src/Engines/QueryBuilderEngine.php | 36 +++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 1c3e6064..33a7249a 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -3,6 +3,7 @@ namespace Yajra\Datatables\Engines; use Closure; +use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Query\Builder; use Illuminate\Support\Str; use Yajra\Datatables\Helper; @@ -459,21 +460,40 @@ public function ordering() */ protected function joinEagerLoadedColumn($relation, $relationColumn) { - $table = $this->query->getRelation($relation)->getRelated()->getTable(); - $foreign = $this->query->getRelation($relation)->getQualifiedForeignKey(); - $other = $this->query->getRelation($relation)->getQualifiedOtherKeyName(); - $column = $table . '.' . $relationColumn; - $joins = []; foreach ((array) $this->getQueryBuilder()->joins as $key => $join) { $joins[] = $join->table; } - if (! in_array($table, $joins)) { - $this->getQueryBuilder() - ->leftJoin($table, $foreign, '=', $other); + $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(); + $foreign = $model->getQualifiedForeignKey(); + $other = $model->getQualifiedOtherKeyName(); + if (! in_array($table, $joins)) { + $this->getQueryBuilder()->leftJoin($table, $foreign, '=', $other); + } } + $column = $table . '.' . $relationColumn; + return $column; } From d753ff5479d163481704f673fbbf73fe5905418e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 28 Apr 2016 10:27:20 +0800 Subject: [PATCH 140/322] Add support for responsive extension. Fix #526 --- src/Html/Builder.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index de2d5552..7a6b2572 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -425,7 +425,14 @@ public function table(array $attributes = []) { $this->tableAttributes = array_merge($this->tableAttributes, $attributes); - return 'html->attributes($this->tableAttributes) . '>
'; + $th = []; + foreach ($this->collection->only(['class', 'id', 'width', 'style']) as $row) { + $th[] = 'html->attributes($row) . '">' . $row['title'] . ''; + } + + $htmlAttr = $this->html->attributes($this->tableAttributes); + + return '' . implode('', $th) . '
'; } /** From 3ce0e6cda663dede3d5dcf4a9d9566aa572972be Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 28 Apr 2016 10:38:29 +0800 Subject: [PATCH 141/322] Fix test and th attributes. --- src/Html/Builder.php | 5 +++-- tests/HtmlBuilderTest.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 7a6b2572..4086f54d 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -426,8 +426,9 @@ public function table(array $attributes = []) $this->tableAttributes = array_merge($this->tableAttributes, $attributes); $th = []; - foreach ($this->collection->only(['class', 'id', 'width', 'style']) as $row) { - $th[] = 'html->attributes($row) . '">' . $row['title'] . ''; + foreach ($this->collection->toArray() as $row) { + $thAttr = $this->html->attributes(array_only($row, ['class', 'id', 'width', 'style'])); + $th[] = '' . $row['title'] . ''; } $htmlAttr = $this->html->attributes($this->tableAttributes); diff --git a/tests/HtmlBuilderTest.php b/tests/HtmlBuilderTest.php index 50916b25..7ec9d453 100644 --- a/tests/HtmlBuilderTest.php +++ b/tests/HtmlBuilderTest.php @@ -12,7 +12,7 @@ class HtmlBuilderTest extends PHPUnit_Framework_TestCase public function test_generate_table_html() { $builder = app(Builder::class); - $builder->html->shouldReceive('attributes')->times(2)->andReturn('id="foo"'); + $builder->html->shouldReceive('attributes')->times(8)->andReturn('id="foo"'); $builder->form->shouldReceive('checkbox') ->once() ->andReturn(''); @@ -25,7 +25,8 @@ public function test_generate_table_html() ->ajax('ajax-url') ->parameters(['bFilter' => false]); $table = $builder->table(['id' => 'foo']); - $this->assertEquals('
', $table); + $expected = '
FooBarIdAOptions
'; + $this->assertEquals($expected, $table); $builder->view->shouldReceive('make')->times(2)->andReturn($builder->view); $builder->config->shouldReceive('get')->times(2)->andReturn('datatables::script'); From 1f7733f3e56d5f82881710884ef59ec29144bb36 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 28 Apr 2016 10:42:27 +0800 Subject: [PATCH 142/322] Patch phpdoc to fix #531 --- src/Engines/BaseEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 0b65af2b..42e6cb17 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -323,7 +323,7 @@ public function isQueryBuilder() * Add column in collection. * * @param string $name - * @param string $content + * @param string|callable $content * @param bool|int $order * @return $this */ @@ -340,7 +340,7 @@ public function addColumn($name, $content, $order = false) * Edit column's content. * * @param string $name - * @param string $content + * @param string|callable $content * @return $this */ public function editColumn($name, $content) From 2329f4596295b02fc2e7c06e3441aa71a194804e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 28 Apr 2016 12:14:29 +0800 Subject: [PATCH 143/322] Allow data-class and data-hide attribute. --- src/Html/Builder.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 4086f54d..7f1d3c2c 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -427,7 +427,9 @@ public function table(array $attributes = []) $th = []; foreach ($this->collection->toArray() as $row) { - $thAttr = $this->html->attributes(array_only($row, ['class', 'id', 'width', 'style'])); + $thAttr = $this->html->attributes( + array_only($row, ['class', 'id', 'width', 'style', 'data-class', 'data-hide']) + ); $th[] = '' . $row['title'] . ''; } From 7a2c830c13a3fcf51282a16c6f6f26d6e463a226 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 29 Apr 2016 12:15:07 +0800 Subject: [PATCH 144/322] Remove excess quote. --- src/Html/Builder.php | 2 +- tests/HtmlBuilderTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 7f1d3c2c..ab276409 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -430,7 +430,7 @@ public function table(array $attributes = []) $thAttr = $this->html->attributes( array_only($row, ['class', 'id', 'width', 'style', 'data-class', 'data-hide']) ); - $th[] = '' . $row['title'] . ''; + $th[] = '' . $row['title'] . ''; } $htmlAttr = $this->html->attributes($this->tableAttributes); diff --git a/tests/HtmlBuilderTest.php b/tests/HtmlBuilderTest.php index 7ec9d453..205f6686 100644 --- a/tests/HtmlBuilderTest.php +++ b/tests/HtmlBuilderTest.php @@ -25,7 +25,7 @@ public function test_generate_table_html() ->ajax('ajax-url') ->parameters(['bFilter' => false]); $table = $builder->table(['id' => 'foo']); - $expected = '
FooBarIdAOptions
'; + $expected = '
FooBarIdAOptions
'; $this->assertEquals($expected, $table); $builder->view->shouldReceive('make')->times(2)->andReturn($builder->view); From 7d722a8973177659f3eaf5afec63d37f7810c48a Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 29 Apr 2016 12:19:18 +0800 Subject: [PATCH 145/322] Refactor table headers compiler. --- src/Html/Builder.php | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index ab276409..89ebea93 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -425,6 +425,19 @@ public function table(array $attributes = []) { $this->tableAttributes = array_merge($this->tableAttributes, $attributes); + $th = $this->compileTableHeaders(); + $htmlAttr = $this->html->attributes($this->tableAttributes); + + return '' . implode('', $th) . '
'; + } + + /** + * Compile table headers and to support responsive extension. + * + * @return array + */ + private function compileTableHeaders() + { $th = []; foreach ($this->collection->toArray() as $row) { $thAttr = $this->html->attributes( @@ -433,9 +446,7 @@ public function table(array $attributes = []) $th[] = '' . $row['title'] . ''; } - $htmlAttr = $this->html->attributes($this->tableAttributes); - - return '' . implode('', $th) . '
'; + return $th; } /** From 212fbcd34aa26d29a40b33d8261011537649be7c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 29 Apr 2016 12:47:35 +0800 Subject: [PATCH 146/322] Use   as default footer content. --- src/Html/Column.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Html/Column.php b/src/Html/Column.php index fce85236..b7977550 100644 --- a/src/Html/Column.php +++ b/src/Html/Column.php @@ -22,7 +22,7 @@ public function __construct($attributes = []) $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'] : ''; + $attributes['footer'] = isset($attributes['footer']) ? $attributes['footer'] : ' '; // Allow methods override attribute value foreach ($attributes as $attribute => $value) { From bfe007ff908ea346720d1ca41912853aa1695c33 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 29 Apr 2016 12:50:17 +0800 Subject: [PATCH 147/322] Use th instead of td. Like what is used on this example: https://datatables.net/examples/advanced_init/footer_callback.html --- src/Html/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 1f3245be..42c77488 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -469,7 +469,7 @@ private function compileTableFooter() { $footer = []; foreach ($this->collection->toArray() as $row) { - $footer[] = '' . $row['footer'] . ''; + $footer[] = '' . $row['footer'] . ''; } return $footer; From e210d9224b254ef1738a5fc41d8f97696f59c94c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 29 Apr 2016 12:51:31 +0800 Subject: [PATCH 148/322] Use empty string as default content as seen on callback demo. --- src/Html/Builder.php | 2 +- src/Html/Column.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 42c77488..b885c295 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -397,7 +397,7 @@ public function addAction(array $attributes = []) 'searchable' => false, 'exportable' => false, 'printable' => true, - 'footer' => ' ', + 'footer' => '', ], $attributes); $this->collection->push(new Column($attributes)); diff --git a/src/Html/Column.php b/src/Html/Column.php index b7977550..fce85236 100644 --- a/src/Html/Column.php +++ b/src/Html/Column.php @@ -22,7 +22,7 @@ public function __construct($attributes = []) $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'] : ' '; + $attributes['footer'] = isset($attributes['footer']) ? $attributes['footer'] : ''; // Allow methods override attribute value foreach ($attributes as $attribute => $value) { From faf2a4f593a49e47699bd330feb8576745f08a7e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 29 Apr 2016 12:53:12 +0800 Subject: [PATCH 149/322] Add test for footer content option. --- tests/HtmlBuilderTest.php | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/HtmlBuilderTest.php b/tests/HtmlBuilderTest.php index 205f6686..d9fc73df 100644 --- a/tests/HtmlBuilderTest.php +++ b/tests/HtmlBuilderTest.php @@ -42,6 +42,71 @@ public function test_generate_table_html() $this->assertEquals($expected, $builder->generateScripts()); } + public function test_generate_table_html_with_empty_footer() + { + $builder = app(Builder::class); + $builder->html->shouldReceive('attributes')->times(8)->andReturn('id="foo"'); + $builder->form->shouldReceive('checkbox') + ->once() + ->andReturn(''); + + $builder->addCheckbox(['id' => 'foo']) + ->columns(['foo', 'bar' => ['data' => 'foo']]) + ->addColumn(['name' => 'id', 'data' => 'id', 'title' => 'Id']) + ->add(new Column(['name' => 'a', 'data' => 'a', 'title' => 'A'])) + ->addAction(['title' => 'Options']) + ->ajax('ajax-url') + ->parameters(['bFilter' => false]); + $table = $builder->table(['id' => 'foo'], true); + $expected = '
FooBarIdAOptions
'; + $this->assertEquals($expected, $table); + + $builder->view->shouldReceive('make')->times(2)->andReturn($builder->view); + $builder->config->shouldReceive('get')->times(2)->andReturn('datatables::script'); + $template = file_get_contents(__DIR__ . '/../src/resources/views/script.blade.php'); + $builder->view->shouldReceive('render')->times(2)->andReturn(trim($template)); + $builder->html->shouldReceive('attributes')->once()->andReturn(); + + $script = $builder->scripts(); + $expected = '' . PHP_EOL; + $this->assertEquals($expected, $script); + + $expected = '(function(window,$){window.LaravelDataTables=window.LaravelDataTables||{};window.LaravelDataTables["foo"]=$("#foo").DataTable({"serverSide":true,"processing":true,"ajax":"ajax-url","columns":[{"defaultContent":"","title":"","data":"checkbox","name":"checkbox","orderable":false,"searchable":false,"width":"10px","id":"foo"},{"name":"foo","data":"foo","title":"Foo","orderable":true,"searchable":true},{"name":"bar","data":"foo","title":"Bar","orderable":true,"searchable":true},{"name":"id","data":"id","title":"Id","orderable":true,"searchable":true},{"name":"a","data":"a","title":"A","orderable":true,"searchable":true},{"defaultContent":"","data":"action","name":"action","title":"Options","render":null,"orderable":false,"searchable":false}],"bFilter":false});})(window,jQuery);'; + $this->assertEquals($expected, $builder->generateScripts()); + } + public function test_generate_table_html_with_footer_content() + { + $builder = app(Builder::class); + $builder->html->shouldReceive('attributes')->times(8)->andReturn('id="foo"'); + $builder->form->shouldReceive('checkbox') + ->once() + ->andReturn(''); + + $builder->addCheckbox(['id' => 'foo', 'footer' => 'test']) + ->columns(['foo', 'bar' => ['data' => 'foo']]) + ->addColumn(['name' => 'id', 'data' => 'id', 'title' => 'Id']) + ->add(new Column(['name' => 'a', 'data' => 'a', 'title' => 'A'])) + ->addAction(['title' => 'Options']) + ->ajax('ajax-url') + ->parameters(['bFilter' => false]); + $table = $builder->table(['id' => 'foo'], true); + $expected = '
FooBarIdAOptions
test
'; + $this->assertEquals($expected, $table); + + $builder->view->shouldReceive('make')->times(2)->andReturn($builder->view); + $builder->config->shouldReceive('get')->times(2)->andReturn('datatables::script'); + $template = file_get_contents(__DIR__ . '/../src/resources/views/script.blade.php'); + $builder->view->shouldReceive('render')->times(2)->andReturn(trim($template)); + $builder->html->shouldReceive('attributes')->once()->andReturn(); + + $script = $builder->scripts(); + $expected = '' . PHP_EOL; + $this->assertEquals($expected, $script); + + $expected = '(function(window,$){window.LaravelDataTables=window.LaravelDataTables||{};window.LaravelDataTables["foo"]=$("#foo").DataTable({"serverSide":true,"processing":true,"ajax":"ajax-url","columns":[{"defaultContent":"","title":"","data":"checkbox","name":"checkbox","orderable":false,"searchable":false,"width":"10px","id":"foo"},{"name":"foo","data":"foo","title":"Foo","orderable":true,"searchable":true},{"name":"bar","data":"foo","title":"Bar","orderable":true,"searchable":true},{"name":"id","data":"id","title":"Id","orderable":true,"searchable":true},{"name":"a","data":"a","title":"A","orderable":true,"searchable":true},{"defaultContent":"","data":"action","name":"action","title":"Options","render":null,"orderable":false,"searchable":false}],"bFilter":false});})(window,jQuery);'; + $this->assertEquals($expected, $builder->generateScripts()); + } + /** * @return \Yajra\Datatables\Datatables */ From df280d882a3bf4af5b585acb623f0d9a6d89fa6b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 29 Apr 2016 12:54:19 +0800 Subject: [PATCH 150/322] Add new line after function. --- tests/HtmlBuilderTest.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/HtmlBuilderTest.php b/tests/HtmlBuilderTest.php index d9fc73df..cfb227be 100644 --- a/tests/HtmlBuilderTest.php +++ b/tests/HtmlBuilderTest.php @@ -74,6 +74,7 @@ public function test_generate_table_html_with_empty_footer() $expected = '(function(window,$){window.LaravelDataTables=window.LaravelDataTables||{};window.LaravelDataTables["foo"]=$("#foo").DataTable({"serverSide":true,"processing":true,"ajax":"ajax-url","columns":[{"defaultContent":"","title":"","data":"checkbox","name":"checkbox","orderable":false,"searchable":false,"width":"10px","id":"foo"},{"name":"foo","data":"foo","title":"Foo","orderable":true,"searchable":true},{"name":"bar","data":"foo","title":"Bar","orderable":true,"searchable":true},{"name":"id","data":"id","title":"Id","orderable":true,"searchable":true},{"name":"a","data":"a","title":"A","orderable":true,"searchable":true},{"defaultContent":"","data":"action","name":"action","title":"Options","render":null,"orderable":false,"searchable":false}],"bFilter":false});})(window,jQuery);'; $this->assertEquals($expected, $builder->generateScripts()); } + public function test_generate_table_html_with_footer_content() { $builder = app(Builder::class); From 7e35c8359c00bb17c64eefcab3d72dca6b10cbed Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 30 Apr 2016 09:52:38 +0800 Subject: [PATCH 151/322] Bump v6.11.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15e63491..2d2a3d92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +###v6.11.0 - 2016-04-30 + - Patch phpdoc to fix #531. PR #534 + - Fix eager loading ordering for belongsToMany relationship. Fix #461, PR #490 + - Add support for responsive extension. Fix #526, PR #533 + - Add option to create a table footer from builder defined via column def. PR #471 + ###v6.10.1 - 2016-03-22 - Fix eager loading column search. PR #469. - Fix issue #443. From 41f55103d8addce82e70e852db6e727225d888a3 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 3 May 2016 10:51:41 +0800 Subject: [PATCH 152/322] Use Str class helper instead of strlen. --- src/Engines/BaseEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 42e6cb17..ff002f80 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -233,7 +233,7 @@ public function isWildcard() public function wildcardLikeString($str, $lowercase = true) { $wild = '%'; - $length = strlen($str); + $length = Str::length($str); if ($length) { for ($i = 0; $i < $length; $i++) { $wild .= $str[$i] . '%'; From 52246797e7c86a7aebc7b91bcfcb62986fa6bf07 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 11 May 2016 13:41:22 +0800 Subject: [PATCH 153/322] Change method from private to protected as requested on #544. --- src/DatatablesServiceProvider.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/DatatablesServiceProvider.php b/src/DatatablesServiceProvider.php index 50237485..d32a9020 100644 --- a/src/DatatablesServiceProvider.php +++ b/src/DatatablesServiceProvider.php @@ -40,7 +40,7 @@ public function boot() /** * Publish datatables assets. */ - private function publishAssets() + protected function publishAssets() { $this->publishes([ __DIR__ . '/config/config.php' => config_path('datatables.php'), @@ -58,7 +58,7 @@ private function publishAssets() /** * Register datatables commands. */ - private function registerCommands() + protected function registerCommands() { $this->commands(DataTablesMakeCommand::class); $this->commands(DataTablesScopeCommand::class); @@ -89,7 +89,7 @@ public function register() * * @return bool */ - private function isLumen() + protected function isLumen() { return str_contains($this->app->version(), 'Lumen'); } @@ -97,7 +97,7 @@ private function isLumen() /** * Register 3rd party providers. */ - private function registerRequiredProviders() + protected function registerRequiredProviders() { $this->app->register(HtmlServiceProvider::class); $this->app->register(ExcelServiceProvider::class); @@ -106,7 +106,7 @@ private function registerRequiredProviders() /** * Create aliases for the dependency. */ - private function registerAliases() + protected function registerAliases() { if (class_exists('Illuminate\Foundation\AliasLoader')) { $loader = \Illuminate\Foundation\AliasLoader::getInstance(); From 2644e5bc5f1df692c1a09f668e8bbf3eca08c05c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 11 May 2016 14:37:01 +0800 Subject: [PATCH 154/322] Bump v6.11.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d2a3d92..9769f71e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.11.1 - 2016-05-11 + - Use Str class helper instead of strlen for better unicode support. + - Change method from private to protected as requested on #544. + ###v6.11.0 - 2016-04-30 - Patch phpdoc to fix #531. PR #534 - Fix eager loading ordering for belongsToMany relationship. Fix #461, PR #490 From a3b33bbdf0b648601f74c703690bc244ae0b835e Mon Sep 17 00:00:00 2001 From: Donny Kurnia Date: Fri, 13 May 2016 09:56:00 +0700 Subject: [PATCH 155/322] Add CAST for Firebird Reference: http://tracker.firebirdsql.org/browse/CORE-3559 --- src/Engines/QueryBuilderEngine.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 33a7249a..8510a57b 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -283,6 +283,9 @@ public function castColumn($column) if ($this->database === 'pgsql') { $column = 'CAST(' . $column . ' as TEXT)'; } + elseif ($this->database === 'firebird') { + $column = 'CAST(' . $column . ' as VARCHAR(255))'; + } return $column; } From aa95adb5822add6f7f0e7085aca66541a5d9aa73 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 18 May 2016 13:58:50 +0800 Subject: [PATCH 156/322] Fix CS and Bump v6.11.2. --- CHANGELOG.md | 3 +++ src/Engines/QueryBuilderEngine.php | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9769f71e..7de2ad5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +###v6.11.2 - 2016-05-18 + - Add CAST for Firebird #552. + ###v6.11.1 - 2016-05-11 - Use Str class helper instead of strlen for better unicode support. - Change method from private to protected as requested on #544. diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 8510a57b..511434f7 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -282,8 +282,7 @@ public function castColumn($column) $column = $this->connection->getQueryGrammar()->wrap($column); if ($this->database === 'pgsql') { $column = 'CAST(' . $column . ' as TEXT)'; - } - elseif ($this->database === 'firebird') { + } elseif ($this->database === 'firebird') { $column = 'CAST(' . $column . ' as VARCHAR(255))'; } From 7c84f6e7c09ac60f0981f7d518a0c4b311f655b5 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 20 May 2016 13:26:55 +0800 Subject: [PATCH 157/322] Add export button collection. --- src/Services/DataTable.php | 10 +--------- src/resources/assets/buttons.server-side.js | 12 ++++++++++++ 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index eedc350d..8e47c2f9 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -350,15 +350,7 @@ protected function getBuilderParameters() 'order' => [[0, 'desc']], 'buttons' => [ 'create', - [ - 'extend' => 'collection', - 'text' => ' Export', - 'buttons' => [ - 'csv', - 'excel', - 'pdf', - ], - ], + 'export', 'print', 'reset', 'reload', diff --git a/src/resources/assets/buttons.server-side.js b/src/resources/assets/buttons.server-side.js index 5665c0b5..50ffa174 100644 --- a/src/resources/assets/buttons.server-side.js +++ b/src/resources/assets/buttons.server-side.js @@ -22,6 +22,18 @@ } }; + DataTable.ext.buttons.export = { + extend: 'collection', + + className: 'buttons-export', + + text: function (dt) { + return ' ' + dt.i18n('buttons.export', 'Export') + ' '; + }, + + buttons: ['csv', 'excel', 'pdf'] + }; + DataTable.ext.buttons.csv = { className: 'buttons-csv', From f91806c6a6fabab74e079aefaf5a6d1d6256b0e4 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 20 May 2016 22:23:57 +0800 Subject: [PATCH 158/322] Fix default print preview view path. --- src/Services/DataTable.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index eedc350d..9b2fcbdc 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -34,7 +34,7 @@ abstract class DataTable implements DataTableContract, DataTableButtonsContract * * @var string */ - protected $printPreview; + protected $printPreview = 'datatables::print'; /** * List of columns to be exported. @@ -119,9 +119,8 @@ public function request() public function printPreview() { $data = $this->getDataForPrint(); - $view = $this->printPreview ?: 'datatables::print'; - return $this->viewFactory->make($view, compact('data')); + return $this->viewFactory->make($this->printPreview, compact('data')); } /** From e7c0aa99b66ce690ec034c10f2db565f89ca8698 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 20 May 2016 22:32:45 +0800 Subject: [PATCH 159/322] Bump v6.11.3 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7de2ad5c..c151f572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +###v6.11.3 - 2016-05-20 + - Add export button collection. #568 + - Fix default print preview view path. #569 + ###v6.11.2 - 2016-05-18 - Add CAST for Firebird #552. From f9483d29a82d315ddc96478020c5fbc9d66b7760 Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Sat, 28 May 2016 04:48:01 +0000 Subject: [PATCH 160/322] Add Gitter badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0dbbc690..929281c8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # jQuery DataTables API for Laravel 4|5 +[![Join the chat at https://gitter.im/yajra/laravel-datatables](https://badges.gitter.im/yajra/laravel-datatables.svg)](https://gitter.im/yajra/laravel-datatables?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + [![Laravel 4.2|5.0|5.1|5.2](https://img.shields.io/badge/Laravel-4.2|5.0|5.1|5.2-orange.svg)](http://laravel.com) [![Latest Stable Version](https://poser.pugx.org/yajra/laravel-datatables-oracle/v/stable)](https://packagist.org/packages/yajra/laravel-datatables-oracle) [![Build Status](https://travis-ci.org/yajra/laravel-datatables.svg?branch=master)](https://travis-ci.org/yajra/laravel-datatables) From 22923b09e37de944151f15f302ea939fde823060 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 30 May 2016 15:25:38 +0800 Subject: [PATCH 161/322] Remove media screen to fix styles when printing. --- src/resources/views/print.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/resources/views/print.blade.php b/src/resources/views/print.blade.php index a7565609..e41af76f 100644 --- a/src/resources/views/print.blade.php +++ b/src/resources/views/print.blade.php @@ -6,7 +6,7 @@ - + - +
@foreach($data as $row) @if ($row == reset($data)) From 45eb8fcb667516a55033bebff2161d4302481eb6 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 2 Jul 2016 13:50:01 +0800 Subject: [PATCH 189/322] Add default config generator value for better backward compatibility. --- src/Services/DataTable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 0108bc1c..71625c2c 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -308,7 +308,7 @@ public function csv() */ public function pdf() { - if ('snappy' == Config::get('datatables.pdf_generator')) { + if ('snappy' == Config::get('datatables.pdf_generator', 'excel')) { return $this->snappyPdf(); } else { $this->buildExcelFile()->download('pdf'); From 32bd3cdbdb8437ab15026b2ae5568538b473b6f4 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 2 Jul 2016 14:15:46 +0800 Subject: [PATCH 190/322] Add laravel-snappy on suggested packages. --- composer.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/composer.json b/composer.json index e98e42f8..4c9ac28b 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,9 @@ "mockery/mockery": "~0.9", "phpunit/phpunit": "~4.0" }, + "suggest": { + "barryvdh/laravel-snappy": "Allows exporting of dataTable to PDF using the print view." + }, "autoload": { "psr-4": { "Yajra\\Datatables\\": "src/" From c1bbfc01434f1ebe808f75a339a6ded5557d3664 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 5 Jul 2016 09:37:34 +0800 Subject: [PATCH 191/322] Bump v6.15.0 --- CHANGELOG.md | 484 ++++++++++++++++++++++++++------------------------- 1 file changed, 246 insertions(+), 238 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82513464..0b5a7466 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,450 +8,458 @@ ##Change Log +### v6.15.0 - 2016-07-05 +- Add support for snappy pdf via config. +- Add laravel-snappy on suggested packages. +- Add table stripes style. +- Fix printing template when value is an array. +- Fix issue when exporting pdf and data can't be decoded. +- ErrorException in DataTransformer.php line 67: strip_tags() expects parameter 1 to be string, array given + ### v6.14.0 - 2016-07-01 - - Add model option to dataTable command. #620 - - Make generator namespace configurable. - - Add filename in generator with timestamps. +- Add model option to dataTable command. #620 +- Make generator namespace configurable. +- Add filename in generator with timestamps. ### v6.13.1 - 2016-06-23 - - Add option to manually set the total records. - -New method: ->setTotalRecords(int total) - - Addresses count queries performance issue like #578. +- Add option to manually set the total records. + -New method: ->setTotalRecords(int total) +- Addresses count queries performance issue like #578. ### v6.13.0 - 2016-06-23 - - Add Auto-Index Column. #597 - - Add method 'addIndexColumn()' to compliment PR#597. - - Note: addIndexColumn can be used without the builder. - - Add config file descriptions for reference. +- Add Auto-Index Column. #597 +- Add method 'addIndexColumn()' to compliment PR#597. + - Note: addIndexColumn can be used without the builder. +- Add config file descriptions for reference. ### v6.12.0 - 2016-06-23 - - Add support for ajax data function. #613 - - Update dataTable service query return docblock and stub. +- Add support for ajax data function. #613 +- Update dataTable service query return docblock and stub. ### v6.11.5 - 2016-06-01 - - Fix HasOne relation which uses different methods to get foreign and other key. #585 +- Fix HasOne relation which uses different methods to get foreign and other key. #585 ###v6.11.4 - 2016-05-30 - - Remove media screen to fix styles when printing. #583 +- Remove media screen to fix styles when printing. #583 ###v6.11.3 - 2016-05-20 - - Add export button collection. #568 - - Fix default print preview view path. #569 +- Add export button collection. #568 +- Fix default print preview view path. #569 ###v6.11.2 - 2016-05-18 - - Add CAST for Firebird #552. +- Add CAST for Firebird #552. ###v6.11.1 - 2016-05-11 - - Use Str class helper instead of strlen for better unicode support. - - Change method from private to protected as requested on #544. +- Use Str class helper instead of strlen for better unicode support. +- Change method from private to protected as requested on #544. ###v6.11.0 - 2016-04-30 - - Patch phpdoc to fix #531. PR #534 - - Fix eager loading ordering for belongsToMany relationship. Fix #461, PR #490 - - Add support for responsive extension. Fix #526, PR #533 - - Add option to create a table footer from builder defined via column def. PR #471 +- Patch phpdoc to fix #531. PR #534 +- Fix eager loading ordering for belongsToMany relationship. Fix #461, PR #490 +- Add support for responsive extension. Fix #526, PR #533 +- Add option to create a table footer from builder defined via column def. PR #471 ###v6.10.1 - 2016-03-22 - - Fix eager loading column search. PR #469. - - Fix issue #443. +- Fix eager loading column search. PR #469. +- Fix issue #443. ###v6.10.0 - 2016-03-19 - - Add feature to enable/disable smart search via config or during runtime. Fix #423 - - See PR #452 for details. +- Add feature to enable/disable smart search via config or during runtime. Fix #423 +- See PR #452 for details. ###v6.9.4 - 2016-03-18 - - Use full namespace in app() helper. - - PR #465, credits to @ligne13. +- Use full namespace in app() helper. +- PR #465, credits to @ligne13. ###v6.9.3 - 2016-03-17 - - Adds an option to pass parameters to column render. - - Allows passing instance of Column into Builder columns. - - Fix security issue as reported in #460. - - Credits to @vladkucherov for this changes. +- Adds an option to pass parameters to column render. +- Allows passing instance of Column into Builder columns. +- Fix security issue as reported in #460. +- Credits to @vladkucherov for this changes. ###v6.9.2 - 2016-03-16 - - Pull-up isOracleSQL and fix condition using oci8. +- Pull-up isOracleSQL and fix condition using oci8. ###v6.9.1 - 2016-03-11 - - Add default array value when getting columns. Fix #448 +- Add default array value when getting columns. Fix #448 ###v6.9.0 - 2016-03-11 - - Re-implement facade. - - Add blacklist and whitelist feature. - - Fix string casting for object values. - - Add missing doc block for getSearchKeyword. - - Fix eloquent engine missing parent constructor. - - Add/Update class doc blocks. +- Re-implement facade. +- Add blacklist and whitelist feature. +- Fix string casting for object values. +- Add missing doc block for getSearchKeyword. +- Fix eloquent engine missing parent constructor. +- Add/Update class doc blocks. ###v6.8.0 - 2016-03-11 - - Added Closure support for filterColumn method. - - PR #440. Credits to @codewizz. +- Added Closure support for filterColumn method. +- PR #440. Credits to @codewizz. ###v6.7.3 - 2016-03-02 - - Fix eager load multiple column sorting where other columns are being ignored when join statement already exists. - - Refactor redundant else order by statement. - - Call eager loads only when required when filtering and ordering. - - Extract eager loaded column join statement handler. +- Fix eager load multiple column sorting where other columns are being ignored when join statement already exists. +- Refactor redundant else order by statement. +- Call eager loads only when required when filtering and ordering. +- Extract eager loaded column join statement handler. ###v6.7.2 - 2016-02-28 - - Fix collection engine sorting and sorting function. - - Fix #413 and #415. +- Fix collection engine sorting and sorting function. +- Fix #413 and #415. ###v6.7.1 - 2016-02-26 - - Fix multiple column sorting when using eager loaded models. Fix #410 +- Fix multiple column sorting when using eager loaded models. Fix #410 ###v6.7.0 - 2016-02-26 - - Add support for sorting on eager loaded models. - - PR #409 - Credits to @ikerasLT. +- Add support for sorting on eager loaded models. +- PR #409 - Credits to @ikerasLT. ###v6.6.1 - 2016-02-20 - - Fix eager loading search (SQLSTATE[21000]: Cardinality violation:). Issue #403. +- Fix eager loading search (SQLSTATE[21000]: Cardinality violation:). Issue #403. ###v6.6.0 - 2016-02-20 - - Add totalCount on contact and remove excess new line. - - Remove unnecessary abstract function on BaseEngine since we have a contract. - - Remove engine implementation of contract since BaseEngine already requires it. - - Improve column name detection for filtering and sorting. - - Dynamically determine if oracle depending on connection used. - - Automatic detection of primary key when using Eloquent engine. - - Use primary key when column name could not be resolve. - - Update DataTable service doc blocks and refactor render method. +- Add totalCount on contact and remove excess new line. +- Remove unnecessary abstract function on BaseEngine since we have a contract. +- Remove engine implementation of contract since BaseEngine already requires it. +- Improve column name detection for filtering and sorting. +- Dynamically determine if oracle depending on connection used. +- Automatic detection of primary key when using Eloquent engine. +- Use primary key when column name could not be resolve. +- Update DataTable service doc blocks and refactor render method. ###v6.5.1 - 2016-02-19 - - Fix ordering column name detection. Issue #339. - - Refactor Builder parameterize method. +- Fix ordering column name detection. Issue #339. +- Refactor Builder parameterize method. ###v6.5.0 - 2016-02-18 - - Add support for DataTables valid callbacks. - - Fix issue #387 & #401. +- Add support for DataTables valid callbacks. +- Fix issue #387 & #401. ###v6.4.5 - 2016-02-18 - - Allow edit columns for nested arrays. PR #399 - credits to @ramilexe - - Fix flag for case insensitive search. PR #400 - credits to @ansient +- Allow edit columns for nested arrays. PR #399 - credits to @ramilexe +- Fix flag for case insensitive search. PR #400 - credits to @ansient ###v6.4.4 - 2016-02-13 - - Fix filtering in nested columns of Collections. PR #392 +- Fix filtering in nested columns of Collections. PR #392 ###v6.4.3 - 2016-02-11 - - Random cs and doc block fix. - - Code refactoring to reduce complexity. +- Random cs and doc block fix. +- Code refactoring to reduce complexity. ###v6.4.2 - 2016-02-11 - - Change how regex code is generated after a column search. #358 - - Fix addColumn fails when order falls at end of array #386 +- Change how regex code is generated after a column search. #358 +- Fix addColumn fails when order falls at end of array #386 ###v6.4.1 - 2016-02-10 - - Fix nested eager loaded relations and column name. +- Fix nested eager loaded relations and column name. ###v6.4.0 - 2016-02-10 - - Add feature to support global search on eager loaded models. - - PR #381. Credits to @ikerasLT. - - Fix implementation conflicts when using builder and join statements. - - Fix cs and doc blocks. +- Add feature to support global search on eager loaded models. +- PR #381. Credits to @ikerasLT. +- Fix implementation conflicts when using builder and join statements. +- Fix cs and doc blocks. ###v6.3.2 - 2016-02-04 - - Add order by and group by on count sql optimization exceptions. - - Date will now be added on each released version using Y-m-d format. +- Add order by and group by on count sql optimization exceptions. +- Date will now be added on each released version using Y-m-d format. ###v6.3.1 - - Fix artisan datatables:make service stub. +- Fix artisan datatables:make service stub. ###v6.3.0 - - Add option to override default ordering via `->order(\Closure $callback)` method. - - Add editor config. - - Add some new features docs. - - Remove Laravel 4.2 documentation on 6.0 branch. +- Add option to override default ordering via `->order(\Closure $callback)` method. +- Add editor config. +- Add some new features docs. +- Remove Laravel 4.2 documentation on 6.0 branch. ###v6.2.4 - - Add git attributes. +- Add git attributes. ###v6.2.3 - - Add setter/getter for filename. - - Add html_entity_decode when exporting file. - - Decode column title when exporting. +- Add setter/getter for filename. +- Add html_entity_decode when exporting file. +- Decode column title when exporting. ###v6.2.2 - - Extract data transformation task to own class. - - Refactor duplicate response mapping code. - - Increase scrutinizer score. +- Extract data transformation task to own class. +- Refactor duplicate response mapping code. +- Increase scrutinizer score. ###v6.2.1 - - Fix data when exporting with html tags. - - Add filename method in stub. - - Fix some doc blocks. - - Scrutinizer refactoring. +- Fix data when exporting with html tags. +- Add filename method in stub. +- Fix some doc blocks. +- Scrutinizer refactoring. ###v6.2.0 - - Enhance printing function to match what is displayed in UI. - - Enhance export function to match what is displayed in UI. - - Enhance datatables service stub. - - Address issue #310. - - Add option to set column as exportable and/or printable. - - Action and checkbox column is not exportable but printable by default. +- Enhance printing function to match what is displayed in UI. +- Enhance export function to match what is displayed in UI. +- Enhance datatables service stub. +- Address issue #310. +- Add option to set column as exportable and/or printable. +- Action and checkbox column is not exportable but printable by default. ###v6.1.3 - - Fix logical bug with totalRecords and filteredRecords. Fix #333 +- Fix logical bug with totalRecords and filteredRecords. Fix #333 ###v6.1.2 - - Fix possible conflict with Laravel helpers.php file auto-loading. Fix #330. - - Update dataTable service class stub. +- Fix possible conflict with Laravel helpers.php file auto-loading. Fix #330. +- Update dataTable service class stub. ###v6.1.1 - - Fix ordering when using basic array response. Fix #322. +- Fix ordering when using basic array response. Fix #322. ###v6.1.0 - - Add support for Lumen. - - Fixes #317, #318. +- Add support for Lumen. +- Fixes #317, #318. ###v6.0.0 - DataTable Service implementation. - - Provides DataTable Service. - - Provides artisan command for creating a service. php artisan datatables:make UsersDataTable - - Provides artisan command for creating a DataTable scope. php artisan datatables:scope ActiveUserScope - - Provides built-in support for server-side buttons. (Formerly TableTools). - - Available buttons are csv, excel, pdf, print. - - Built-in support for exporting to CSV, EXCEL and PDF using Laravel-Excel. - - Built-in printer friendly view or create your own by overriding printPreview() method. - - Change of namespace from yajra\Datatables to Yajra\Datatables. - - Deprecated of() method when using DataTable service. - - Automatic registration of required 3rd party providers. - - [Laravel Excel](https://github.com/Maatwebsite/Laravel-Excel) - - [Laravel Collective HTML & Forms](https://github.com/LaravelCollective/html) - - Automatic registration of Datatables facade. - - HTML Builder with javascript from template. #298 - Credits to @vladkucherov. - - HTML Builder column render now accepts a string, view or closure. #300 - Credits to @vladkucherov - - Add resource on json response by using `->with('key', 'value')` method. #277 +- Provides DataTable Service. +- Provides artisan command for creating a service. php artisan datatables:make UsersDataTable +- Provides artisan command for creating a DataTable scope. php artisan datatables:scope ActiveUserScope +- Provides built-in support for server-side buttons. (Formerly TableTools). +- Available buttons are csv, excel, pdf, print. +- Built-in support for exporting to CSV, EXCEL and PDF using Laravel-Excel. +- Built-in printer friendly view or create your own by overriding printPreview() method. +- Change of namespace from yajra\Datatables to Yajra\Datatables. +- Deprecated of() method when using DataTable service. +- Automatic registration of required 3rd party providers. + - [Laravel Excel](https://github.com/Maatwebsite/Laravel-Excel) + - [Laravel Collective HTML & Forms](https://github.com/LaravelCollective/html) +- Automatic registration of Datatables facade. +- HTML Builder with javascript from template. #298 - Credits to @vladkucherov. +- HTML Builder column render now accepts a string, view or closure. #300 - Credits to @vladkucherov +- Add resource on json response by using `->with('key', 'value')` method. #277 ###v5.12.5 - - Get order column name from the request. Fix #307. +- Get order column name from the request. Fix #307. ###v5.12.4 - - Fix searching when aliasing a column. Fix #274. +- Fix searching when aliasing a column. Fix #274. ###v5.12.3 - - Remove checking of columns - name index and let setupColumnName method to identify the proper column name. +- Remove checking of columns - name index and let setupColumnName method to identify the proper column name. ###v5.12.2 - - Fix double prefix when using join queries. Fix #272, #273 +- Fix double prefix when using join queries. Fix #272, #273 ###v5.12.1 - - Fix support for PHP5.4. +- Fix support for PHP5.4. ###v5.12.0 - - Added support for Fractal Serializer. - - Added config for default serializer. - - Note: Should be used along with setTransformer method. - - Usage: +- Added support for Fractal Serializer. +- Added config for default serializer. +- Note: Should be used along with setTransformer method. +- Usage: return Datatables::of($model) - ->setTransformer(ModelTransformer::class) - ->setSerializer(ModelSerializer::class) - ->make(true); + ->setTransformer(ModelTransformer::class) + ->setSerializer(ModelSerializer::class) + ->make(true); ###v5.11.14 - - Sort by a multi-line 'select as' query. PR #245 +- Sort by a multi-line 'select as' query. PR #245 ###v5.11.13 - - Allow fractal v0.12 and up. Fix #237. +- Allow fractal v0.12 and up. Fix #237. ###v5.11.12 - - Use connection grammar to wrap columns and table name. +- Use connection grammar to wrap columns and table name. ###v5.11.11 - - Parse includes in fractal. Fix #225. +- Parse includes in fractal. Fix #225. ###v5.11.10 - - CollectionEngine: fix sorting of relation columns by using seralize (like filtering). PR #197. +- CollectionEngine: fix sorting of relation columns by using seralize (like filtering). PR #197. ###v5.11.9 - - Add fix for QueryBuilder: ORDER BY *. PR #194. +- Add fix for QueryBuilder: ORDER BY *. PR #194. ###v5.11.8 - - Skip search, order and pagination on empty records. - - Fix #149 and #176 empty collection error when using make(false). - - Fix credits to @gabrielwelsche. +- Skip search, order and pagination on empty records. +- Fix #149 and #176 empty collection error when using make(false). +- Fix credits to @gabrielwelsche. ###v5.11.7 - - Fix escaping of row when using eager loading. Fix #164 - - Add support for escaping rows using array dot notation when declaring escapeColumns. +- Fix escaping of row when using eager loading. Fix #164 +- Add support for escaping rows using array dot notation when declaring escapeColumns. Example: `->escapeColumns(['name', 'post.title'])` ###v5.11.6 - - Refactor eloquent and query builder engine duplicate codes. +- Refactor eloquent and query builder engine duplicate codes. ###v5.11.5 - - Fix issues on database prefix. #161 and #162 - - Fix database prefix value when using Eloquent. +- Fix issues on database prefix. #161 and #162 +- Fix database prefix value when using Eloquent. ###v5.11.4 - - Fix Undefined offset issue when using addColumn. - - Credits to @openvast for PR #158 +- Fix Undefined offset issue when using addColumn. +- Credits to @openvast for PR #158 ###v5.11.3 - - Pass object or array to transformer. PR #155 +- Pass object or array to transformer. PR #155 ###v5.11.2 - - Add support for regular expressions search on column. +- Add support for regular expressions search on column. ###v5.11.1 - - Collection engine enhancement. - - Add support for filtering compound key PR #146. - - Add support for ordering using compound key. +- Collection engine enhancement. +- Add support for filtering compound key PR #146. +- Add support for ordering using compound key. ###v5.11.0 - - Add support for rendering view directly on addColumn and editColumn. +- Add support for rendering view directly on addColumn and editColumn. ###v5.10.0 - - Add LaravelDataTables on js window namespace. Issue #129. Credits to @greabock. +- Add LaravelDataTables on js window namespace. Issue #129. Credits to @greabock. ###v5.9.2 - - Fix possible error when rendering table and overriding the attributes. - - Merge DT parameters. +- Fix possible error when rendering table and overriding the attributes. +- Merge DT parameters. ###v5.9.1 - - Fix default ajax value causing js data null error. +- Fix default ajax value causing js data null error. ###v5.9.0 - - Added escapeColumns feature to escape the values. - - Addresses XSS filtering issue #128. +- Added escapeColumns feature to escape the values. +- Addresses XSS filtering issue #128. ###v5.8.6 - - Fix DT_Row options when returning a flatten array response. - - Fix PR #126. +- Fix DT_Row options when returning a flatten array response. +- Fix PR #126. ###v5.8.5 - - Revert try-catch when compiling blade. - - Fix html builder unit test. +- Revert try-catch when compiling blade. +- Fix html builder unit test. ###v5.8.4 - - Fix html builder merging of column attributes. +- Fix html builder merging of column attributes. ###v5.8.3 - - Added space when setting html builder table attributes. - - Set a default data value when adding a column. - - Removed unnecessary slash when getting html builder. - - Added html builder unit test. - - Improved test coverage. +- Added space when setting html builder table attributes. +- Set a default data value when adding a column. +- Removed unnecessary slash when getting html builder. +- Added html builder unit test. +- Improved test coverage. ###v5.8.2 - - Fix count when using DISTINCT query. Fix #125 +- Fix count when using DISTINCT query. Fix #125 ###v5.8.1 - - Fix compatiblity with PHP 5.4. +- Fix compatiblity with PHP 5.4. ###v5.8.0 - - Enhanced html builder class. - - Added function to load html builder `columns` via mixed array. - - Automatic resolution of qualified title based on field name. - - Overriding of column attributes. - - Added html builder and request object getter from main Datatables class. - - Added more unit tests. +- Enhanced html builder class. +- Added function to load html builder `columns` via mixed array. + - Automatic resolution of qualified title based on field name. + - Overriding of column attributes. +- Added html builder and request object getter from main Datatables class. +- Added more unit tests. ###v5.7.0 - - Added orderColumn feature. +- Added orderColumn feature. ###v5.6.1 - - Make BaseEngine $request property public. - - Fix global searching when search value is zero (0). - - Refactor methods from v5.6.0. +- Make BaseEngine $request property public. +- Fix global searching when search value is zero (0). +- Refactor methods from v5.6.0. ###v5.6.0 - - Re-implement filterColumn function with special variable $1. - - Fix filterColumn not getting included on OR statements within global search. - - Fix #115. +- Re-implement filterColumn function with special variable $1. +- Fix filterColumn not getting included on OR statements within global search. +- Fix #115. ###v5.5.11 - - Fix ordering for when using column alias and make(false). Fix #103. +- Fix ordering for when using column alias and make(false). Fix #103. ###v5.5.10 - - Fix casting specific to stdClass only. Fix #114. +- Fix casting specific to stdClass only. Fix #114. ###v5.5.9 - - Fix ordering of collection when data is stdClass. +- Fix ordering of collection when data is stdClass. ###v5.5.8 - - Fix issue when converting object to array. Fix #108. +- Fix issue when converting object to array. Fix #108. ###v5.5.7 - - Fix and enhance support when passing object variables using blade templating approach. - - Random code clean-up. +- Fix and enhance support when passing object variables using blade templating approach. +- Random code clean-up. ###v5.5.6 - - Fix eager loading of hasOne and hasMany relationships. Issue #105. +- Fix eager loading of hasOne and hasMany relationships. Issue #105. ###v5.5.5 - - Fix collection engine sorting when columns is not defined +- Fix collection engine sorting when columns is not defined ###v5.5.4 - - Fix support for collection of objects +- Fix support for collection of objects ###v5.5.3 - - Fix total filtered records count when overriding global search. - - Fix implementation of PR #95 on Collection Engine. +- Fix total filtered records count when overriding global search. +- Fix implementation of PR #95 on Collection Engine. ###v5.5.2 - - Fix database driver detection on Eloquent Engine. +- Fix database driver detection on Eloquent Engine. ###v5.5.1 - - Fix missing import of Helper class. +- Fix missing import of Helper class. ###v5.5.0 - - Refactor classes to improve code quality. - - Implemented PR #95. +- Refactor classes to improve code quality. +- Implemented PR #95. ###v5.4.4 - - Added column wrapper for SQLITE. +- Added column wrapper for SQLITE. ###v5.4.3 - - Added column wrapper for Postgres. Bugfix #82. +- Added column wrapper for Postgres. Bugfix #82. ###v5.4.2 - - Throws Exception when using DataTable's legacy code. - - Fixed CS - PSR2. +- Throws Exception when using DataTable's legacy code. +- Fixed CS - PSR2. ###v5.4.1 - - Fixed Builder generateScript method. +- Fixed Builder generateScript method. ###v5.4 - - Added Html Builder. - - Added magic methods to call enginges without the "using" word. - - Minor Bugfixes. +- Added Html Builder. +- Added magic methods to call enginges without the "using" word. +- Minor Bugfixes. ###v5.3 - - Added scrutinizer. - - Code refactor/cleanup based on scrutinizers suggestions. - - Bugfix #75. +- Added scrutinizer. +- Code refactor/cleanup based on scrutinizers suggestions. +- Bugfix #75. ###v5.2 - - Datatables can now be used via Laravel IOC container `app('datatables')`. - - Datatables Engine can now be used directly along with Laravel IOC. - - Available Engines: - - Query Builder Engine. `app('datatables')->usingQueryBuilder($builder)->make()`. - - Eloquent Engine. `app('datatables')->usingEloquent($model)->make()`. - - Collection Engine. `app('datatables')->usingCollection($collection)->make()`. - - Datatables is now more testable and works with https://github.com/laracasts/integrated. - - Bugfix #56. +- Datatables can now be used via Laravel IOC container `app('datatables')`. +- Datatables Engine can now be used directly along with Laravel IOC. + - Available Engines: + - Query Builder Engine. `app('datatables')->usingQueryBuilder($builder)->make()`. + - Eloquent Engine. `app('datatables')->usingEloquent($model)->make()`. + - Collection Engine. `app('datatables')->usingCollection($collection)->make()`. +- Datatables is now more testable and works with https://github.com/laracasts/integrated. +- Bugfix #56. ###v5.1 - - Added filterColumn function to override default global search in each column. - - Datatables class extending Query Builder's functionality along with global search. - - Restore queries on result when app is in debug mode. - - Added input on result when app is in debug mode. - - Force enable query log when app is in debug mode. - - Convert string search from preg_match to Str::contains to improve performance. - - Added support for having clause queries. - - Added support for `league/fractal` for transforming data API output. +- Added filterColumn function to override default global search in each column. +- Datatables class extending Query Builder's functionality along with global search. +- Restore queries on result when app is in debug mode. +- Added input on result when app is in debug mode. +- Force enable query log when app is in debug mode. +- Convert string search from preg_match to Str::contains to improve performance. +- Added support for having clause queries. +- Added support for `league/fractal` for transforming data API output. ###v5.0 - - Strictly for Laravel 5++. - - Drop support for DT1.9 and below. - - Strict implmentation of DT1.10 script pattern. - - Added support for Collection as data source. +- Strictly for Laravel 5++. +- Drop support for DT1.9 and below. +- Strict implmentation of DT1.10 script pattern. +- Added support for Collection as data source. ###v4.3.x - - Stable version for Laravel 5 with support for DT1.9. - - Collection Engine not available. +- Stable version for Laravel 5 with support for DT1.9. +- Collection Engine not available. ###v3.6.x - - Stable version for Laravel 4.2. +- Stable version for Laravel 4.2. ###v2.x - - Stable version for Laravel 4.0 and 4.1 +- Stable version for Laravel 4.0 and 4.1 From 6e55327df569d062520144e4f6730edda66fa6f6 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 12 Jul 2016 09:59:54 +0800 Subject: [PATCH 192/322] Decouple fractal for better integration. Help address issue like #633. --- src/DatatablesServiceProvider.php | 18 ++++++++++++++++++ src/Engines/BaseEngine.php | 14 ++++++-------- src/config/config.php | 12 ++++++++++-- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/DatatablesServiceProvider.php b/src/DatatablesServiceProvider.php index d32a9020..02de59cb 100644 --- a/src/DatatablesServiceProvider.php +++ b/src/DatatablesServiceProvider.php @@ -4,6 +4,8 @@ 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; @@ -81,6 +83,22 @@ public function register() 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(); } diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 6fdc6572..a77e4a58 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -164,9 +164,9 @@ abstract class BaseEngine implements DataTableEngineContract /** * Fractal serializer class. * - * @var string + * @var string|null */ - protected $serializer; + protected $serializer = null; /** * Custom ordering callback. @@ -634,13 +634,11 @@ public function render($object = false) ], $this->appends); if (isset($this->transformer)) { - $fractal = new Manager(); - if ($this->request->get('include')) { - $fractal->parseIncludes($this->request->get('include')); - } + $fractal = app('datatables.fractal'); - $serializer = $this->serializer ?: Config::get('datatables.fractal.serializer', DataArraySerializer::class); - $fractal->setSerializer(new $serializer); + if ($this->serializer) { + $fractal->setSerializer(new $this->serializer); + } //Get transformer reflection //Firs method parameter should be data/object to transform diff --git a/src/config/config.php b/src/config/config.php index d706f8e1..89000cac 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -25,9 +25,17 @@ ], /** - * DataTables default fractal serializer. + * DataTables fractal configurations. */ 'fractal' => [ + /** + * Request key name to parse includes on fractal. + */ + 'includes' => 'include', + + /** + * Default fractal serializer. + */ 'serializer' => 'League\Fractal\Serializer\DataArraySerializer', ], @@ -74,5 +82,5 @@ * Snappy package: barryvdh/laravel-snappy * Excel package: maatwebsite/excel */ - 'pdf_generator' => 'excel' + 'pdf_generator' => 'excel', ]; From 514c671b3de1a0e0e59dc9e1e7f987eb3d67fef3 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 13 Jul 2016 13:33:46 +0800 Subject: [PATCH 193/322] Bump v6.15.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b5a7466..13a5a240 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.15.1 - 2016-07-13 +- Decouple fractal for better integration. #636 +- Fractal manager instance can be accessed via app('datatables.fractal'). + ### v6.15.0 - 2016-07-05 - Add support for snappy pdf via config. - Add laravel-snappy on suggested packages. From 977160cd816a2f692a7a71e1ea979635f5320c96 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 14 Jul 2016 10:49:52 +0800 Subject: [PATCH 194/322] Fix issue where a record is being deleted. Fix #565 and #640. --- src/Helper.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Helper.php b/src/Helper.php index db6a661b..38945416 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -138,6 +138,10 @@ public static function castToArray($param) return $param; } + if ($param instanceof Arrayable) { + return $param->toArray(); + } + return $param; } From b05be54799156d44b449823c10d9042d33a7c1fc Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 14 Jul 2016 10:50:29 +0800 Subject: [PATCH 195/322] Fix doc blocks. --- src/Helper.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Helper.php b/src/Helper.php index 38945416..cb80bd07 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -19,8 +19,8 @@ class Helper /** * Places item of extra columns into results by care of their order. * - * @param $item - * @param $array + * @param array $item + * @param array $array * @return array */ public static function includeInArray($item, $array) @@ -109,6 +109,8 @@ public static function compileBlade($str, $data = []) } /** + * Get a mixed value of custom data and the parameters. + * * @param array $data * @param mixed $param * @return array @@ -127,7 +129,9 @@ public static function getMixedValue(array $data, $param) } /** - * @param $param + * Cast the parameter into an array. + * + * @param mixed $param * @return array */ public static function castToArray($param) @@ -179,7 +183,7 @@ public static function wrapDatabaseValue($database, $value) } /** - * Database column wrapper + * Database column wrapper. * * @param string $database * @param string $key @@ -239,8 +243,10 @@ public static function transform(array $data) } /** - * @param $row - * @return mixed + * Transform row data into an array. + * + * @param mixed $row + * @return array */ protected static function transformRow($row) { From 613c4a2a657eb31b6ee8b8b18abd06611cf7266c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 14 Jul 2016 10:58:20 +0800 Subject: [PATCH 196/322] Allow failures on HHVM. HHVM mostly fail due to execution timestamp. --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3925bae8..99505ffc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,10 @@ php: - 7.0 - hhvm +matrix: + allow_failures: + - php: hhvm + env: global: - setup=basic From 2af423095de1a68514361e7826b187b92b15bb24 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 14 Jul 2016 11:04:52 +0800 Subject: [PATCH 197/322] Bump v6.15.2 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13a5a240..81ed38ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +### v6.15.2 - 2016-07-14 +- Fix the issue where a record is being deleted by LDT when column name used is delete. +- Fix helper doc blocks. +- Fix #565 and #640. +- Allow travis-ci failure on HHVM. Mostly due to execution timestamp. + ### v6.15.1 - 2016-07-13 - Decouple fractal for better integration. #636 - Fractal manager instance can be accessed via app('datatables.fractal'). From 398d0e300423dec5c26c9d607d1bf6922a56b588 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 14 Jul 2016 13:33:57 +0800 Subject: [PATCH 198/322] Add debugging notes. Fix #603 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 929281c8..029bf449 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,11 @@ And that's it! Start building out some awesome DataTables! - Update package version on your composer.json and use `yajra/laravel-datatables-oracle: ~6.0` - Uncomment the provider `Yajra\Datatables\DatatablesServiceProvider`. +## Debugging Mode +To enable debugging mode, just set `APP_DEBUG=true` and the package will include the queries and inputs used when processing the table. + +**IMPORTANT:** Please make sure that APP_DEBUG is set to false when your app is on production. + ## Contributing Please see [CONTRIBUTING](https://github.com/yajra/laravel-datatables/blob/master/.github/CONTRIBUTING.md) for details. From a8d80bb183032e8a504ca5a9bf94a8d0275e2169 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 15 Jul 2016 15:47:50 +0800 Subject: [PATCH 199/322] Allow global search to work with custom filter callback. --- src/Contracts/DataTableEngineContract.php | 3 ++- src/Engines/BaseEngine.php | 14 +++++++------- src/Engines/CollectionEngine.php | 5 +++-- src/Engines/QueryBuilderEngine.php | 5 +++-- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Contracts/DataTableEngineContract.php b/src/Contracts/DataTableEngineContract.php index 000e2ac8..31c673f7 100644 --- a/src/Contracts/DataTableEngineContract.php +++ b/src/Contracts/DataTableEngineContract.php @@ -36,9 +36,10 @@ public function totalCount(); * Overrides global search. * * @param \Closure $callback + * @param bool $globalSearch * @return $this */ - public function filter(\Closure $callback); + public function filter(\Closure $callback, $globalSearch = false); /** * Perform global search. diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index a77e4a58..ad5d12a3 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -597,10 +597,10 @@ public function filterRecords() { if ($this->autoFilter && $this->request->isSearchable()) { $this->filtering(); - } else { - if (is_callable($this->filterCallback)) { - call_user_func($this->filterCallback, $this->filterCallbackParameters); - } + } + + if (is_callable($this->filterCallback)) { + call_user_func($this->filterCallback, $this->filterCallbackParameters); } $this->columnSearch(); @@ -716,11 +716,11 @@ public function showDebugger(array $output) * * @param \Closure $callback * @param mixed $parameters - * @return void + * @param bool $autoFilter */ - public function overrideGlobalSearch(\Closure $callback, $parameters) + public function overrideGlobalSearch(\Closure $callback, $parameters, $autoFilter = false) { - $this->autoFilter = false; + $this->autoFilter = $autoFilter; $this->isFilterApplied = true; $this->filterCallback = $callback; $this->filterCallbackParameters = $parameters; diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 5d9a6a0b..39db45ad 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -61,11 +61,12 @@ protected function serialize($collection) * Overrides global search. * * @param \Closure $callback + * @param bool $globalSearch * @return $this */ - public function filter(Closure $callback) + public function filter(Closure $callback, $globalSearch = false) { - $this->overrideGlobalSearch($callback, $this); + $this->overrideGlobalSearch($callback, $this, $globalSearch); return $this; } diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 4ac5cb9f..66c1bd58 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -53,11 +53,12 @@ protected function init($request, $builder, $type = 'builder') * Overrides global search * * @param \Closure $callback + * @param bool $globalSearch * @return $this */ - public function filter(Closure $callback) + public function filter(Closure $callback, $globalSearch = false) { - $this->overrideGlobalSearch($callback, $this->query); + $this->overrideGlobalSearch($callback, $this->query, $globalSearch); return $this; } From a3e09bcad64e8e17a131cd0cb76bf15e9bdf913e Mon Sep 17 00:00:00 2001 From: Sebastian Sipos Date: Mon, 18 Jul 2016 12:59:55 +0300 Subject: [PATCH 200/322] Transformer instance is kept, otherwise new instance is created. --- src/Engines/BaseEngine.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index a77e4a58..07197b36 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -648,11 +648,11 @@ public function render($object = false) //If parameter is class assuming it requires object //Else just pass array by default if ($parameter->getClass()) { - $resource = new Collection($this->results(), new $this->transformer()); + $resource = new Collection($this->results(), $this->createTransformer()); } else { $resource = new Collection( $this->getProcessedData($object), - new $this->transformer() + $this->createTransformer() ); } @@ -669,6 +669,20 @@ public function render($object = false) 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 * From 21b989c360d06bbde168ff905f5db42b6219b746 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 19 Jul 2016 13:41:39 +0800 Subject: [PATCH 201/322] Remove unused import and fix cs. --- src/Engines/BaseEngine.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 1ef33e45..38509a9a 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -5,9 +5,7 @@ use Illuminate\Http\JsonResponse; use Illuminate\Support\Facades\Config; use Illuminate\Support\Str; -use League\Fractal\Manager; use League\Fractal\Resource\Collection; -use League\Fractal\Serializer\DataArraySerializer; use Yajra\Datatables\Contracts\DataTableEngineContract; use Yajra\Datatables\Helper; use Yajra\Datatables\Processors\DataProcessor; @@ -670,7 +668,7 @@ public function render($object = false) } /** - * Get or create transformer instance + * Get or create transformer instance. * * @return \League\Fractal\TransformerAbstract */ From 733e7051d9aef7ed8adcd94528ee6ea53b1d6d69 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 19 Jul 2016 13:43:32 +0800 Subject: [PATCH 202/322] Bump v6.16.0 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81ed38ce..babb7b0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ ##Change Log +### v6.16.0 - 2016-07-19 +- Allow global search to work with custom filter callback. #644 +- Transformer instance is kept, otherwise new instance is created. #649 +- Remove unused import and fix cs. + ### v6.15.2 - 2016-07-14 - Fix the issue where a record is being deleted by LDT when column name used is delete. - Fix helper doc blocks. From b87fa5b94d8004d949dd33474d19e7963eaccfa7 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 3 Aug 2016 10:26:29 +0800 Subject: [PATCH 203/322] Fix double percent sign in query. Fix #665 --- src/Engines/QueryBuilderEngine.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 66c1bd58..b3fcefa0 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -123,7 +123,7 @@ public function filtering() { $this->query->where( function ($query) { - $globalKeyword = $this->setupKeyword($this->request->keyword()); + $globalKeyword = $this->request->keyword(); $queryBuilder = $this->getQueryBuilder($query); foreach ($this->request->searchableColumnIndex() as $index) { @@ -143,7 +143,7 @@ function ($query) { if ($columnDef['method'] instanceof Closure) { $whereQuery = $queryBuilder->newQuery(); - call_user_func_array($columnDef['method'], [$whereQuery, $this->request->keyword()]); + call_user_func_array($columnDef['method'], [$whereQuery, $globalKeyword]); $queryBuilder->addNestedWhereQuery($whereQuery, 'or'); } else { $this->compileColumnQuery( @@ -151,7 +151,7 @@ function ($query) { Helper::getOrMethod($columnDef['method']), $columnDef['parameters'], $columnName, - $this->request->keyword() + $globalKeyword ); } } else { From cea65abc98ff84b43296907d43365fc3866c3d30 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 3 Aug 2016 11:24:42 +0800 Subject: [PATCH 204/322] Add orderColumns api helper. --- src/Engines/BaseEngine.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 38509a9a..a256c186 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -510,6 +510,23 @@ public function filterColumn($column, $method) 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. * From 5336e9a686125a69ba12decc4d62e7c854776ad6 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 3 Aug 2016 12:22:20 +0800 Subject: [PATCH 205/322] Bump v6.16.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index babb7b0d..91e3146d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.16.1 - 2016-08-03 +- Add orderColumns api helper. PR #679 +- Fix double percent sign in query. PR #678 + ### v6.16.0 - 2016-07-19 - Allow global search to work with custom filter callback. #644 - Transformer instance is kept, otherwise new instance is created. #649 From e4fb39dae26a065d6bf85b1f4519897db5a9ae0c Mon Sep 17 00:00:00 2001 From: Sebastian Sipos Date: Mon, 8 Aug 2016 14:31:39 +0300 Subject: [PATCH 206/322] Add setter and getter for table attributes. --- src/Html/Builder.php | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 8a1f53fd..608d14d2 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -128,6 +128,59 @@ public function scripts($script = null, array $attributes = ['type' => 'text/jav return 'html->attributes($attributes) . '>' . $script . '' . PHP_EOL; } + /** + * 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; + } + + /** + * 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]; + } + + /** + * Sets multiple HTML table at once. + * + * @param array $attributes + * + * @return $this + */ + public function setTableAttributes(array $attributes) + { + foreach ($attributes as $attribute => $value) { + $this->setTableAttribute($attribute, $value); + } + + return $this; + } + + /** * Get generated raw scripts. * From 4b4eb15bd37ebd8dbff35c16eb511ddf15f56ac5 Mon Sep 17 00:00:00 2001 From: Sebastian Sipos Date: Mon, 8 Aug 2016 14:49:31 +0300 Subject: [PATCH 207/322] Tests for setter and getter for table attributes. --- tests/HtmlBuilderTest.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/HtmlBuilderTest.php b/tests/HtmlBuilderTest.php index cfb227be..58dede9e 100644 --- a/tests/HtmlBuilderTest.php +++ b/tests/HtmlBuilderTest.php @@ -108,6 +108,34 @@ public function test_generate_table_html_with_footer_content() $this->assertEquals($expected, $builder->generateScripts()); } + public function test_setting_table_attribute() + { + $builder = app(Builder::class); + + $builder->setTableAttribute('attr', 'val'); + + $this->assertEquals('val', $builder->getTableAttribute('attr')); + } + + public function test_settings_multiple_table_attributes() + { + $builder = app(Builder::class); + + $builder->setTableAttribute(['prop1' => 'val1', 'prop2' => 'val2']); + + $this->assertEquals('val1', $builder->getTableAttribute('prop1')); + $this->assertEquals('val2', $builder->getTableAttribute('prop2')); + } + + public function test_getting_inexistent_table_attribute_throws() + { + $this->setExpectedExceptionRegExp(\Exception::class, '/Table attribute \'.+?\' does not exist\./'); + + $builder = app(Builder::class); + + $builder->getTableAttribute('boohoo'); + } + /** * @return \Yajra\Datatables\Datatables */ From 94ee4885ab41e2a52614f80c9c7462ed32f7dd4f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 10 Aug 2016 08:28:56 +0800 Subject: [PATCH 208/322] Fix cs and docblocks. --- src/Html/Builder.php | 102 +++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 53 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 608d14d2..3279a5a4 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -128,59 +128,6 @@ public function scripts($script = null, array $attributes = ['type' => 'text/jav return 'html->attributes($attributes) . '>' . $script . '' . PHP_EOL; } - /** - * 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; - } - - /** - * 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]; - } - - /** - * Sets multiple HTML table at once. - * - * @param array $attributes - * - * @return $this - */ - public function setTableAttributes(array $attributes) - { - foreach ($attributes as $attribute => $value) { - $this->setTableAttribute($attribute, $value); - } - - return $this; - } - - /** * Get generated raw scripts. * @@ -358,6 +305,55 @@ protected function template() )->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. * From 66186a1275156b922e5968a4d65bbc5966bbee5d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 10 Aug 2016 08:30:44 +0800 Subject: [PATCH 209/322] Bump v6.17.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91e3146d..4798c297 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.17.0 - 2016-08-10 +- Add setter and getter for table attributes. +- PR #688, credits to @ssipos90. + ### v6.16.1 - 2016-08-03 - Add orderColumns api helper. PR #679 - Fix double percent sign in query. PR #678 From aa9ac49405f9c8b13c85f964fb281af2876e90fa Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 23 Aug 2016 08:17:52 +0800 Subject: [PATCH 210/322] Implement setTotalRecords on collection engine. Addresses #702 and #703. --- src/Engines/CollectionEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 39db45ad..82c85003 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -91,7 +91,7 @@ public function showDebugger(array $output) */ public function totalCount() { - return $this->count(); + return $this->totalRecords ? $this->totalRecords : $this->count(); } /** From 53dffc82de3b4a8b9c022d49dab6d27a8c86b434 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 23 Aug 2016 13:28:49 +0800 Subject: [PATCH 211/322] Use dompdf v0.7.x. Fix #496 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 4c9ac28b..ec9f6a56 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "league/fractal": "~0.12", "laravelcollective/html": "~5.0", "maatwebsite/excel": "^2.0", - "dompdf/dompdf": "^0.6.1" + "dompdf/dompdf": "^0.7" }, "require-dev": { "mockery/mockery": "~0.9", From ebf51c74bbc0efcb5904fa146da6a5a4d6b82a01 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 23 Aug 2016 13:51:56 +0800 Subject: [PATCH 212/322] Bump v6.17.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4798c297..d97782bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.17.1 - 2016-08-23 +- Use dompdf v0.7.x. +- Implement/fix setTotalRecords on collection engine. + ### v6.17.0 - 2016-08-10 - Add setter and getter for table attributes. - PR #688, credits to @ssipos90. From 174129d7e063626e90200b1f49d4eb33d32ef5e1 Mon Sep 17 00:00:00 2001 From: Nakukryskin Date: Tue, 23 Aug 2016 02:14:56 +0300 Subject: [PATCH 213/322] Issue #706: Fix paging --- src/Engines/BaseEngine.php | 9 +++++++++ src/Engines/CollectionEngine.php | 10 ++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index a256c186..600367a7 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -173,6 +173,13 @@ abstract class BaseEngine implements DataTableEngineContract */ protected $orderCallback; + /** + * Custom rewriting totals + * + * @var bool + */ + protected $rewriteTotals = false; + /** * Array of data to append on json response. * @@ -960,6 +967,8 @@ protected function isOracleSql() */ public function setTotalRecords($total) { + $this->rewriteTotals = true; + $this->totalRecords = $total; return $this; diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 82c85003..2260a057 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -205,10 +205,12 @@ function ($row) use ($column, $keyword) { */ public function paging() { - $this->collection = $this->collection->slice( - $this->request['start'], - (int) $this->request['length'] > 0 ? $this->request['length'] : 10 - ); + if(!$this->rewriteTotals) { + $this->collection = $this->collection->slice( + $this->request['start'], + (int)$this->request['length'] > 0 ? $this->request['length'] : 10 + ); + } } /** From b6fe245b41d9db2cb401e958ccd807e5e134c826 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 23 Aug 2016 18:24:27 +0800 Subject: [PATCH 214/322] If filtered total > total records, use total records. --- src/Engines/CollectionEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 82c85003..a5766ac4 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -91,7 +91,7 @@ public function showDebugger(array $output) */ public function totalCount() { - return $this->totalRecords ? $this->totalRecords : $this->count(); + return $this->totalRecords ? $this->totalRecords : $this->collection->count(); } /** @@ -101,7 +101,7 @@ public function totalCount() */ public function count() { - return $this->collection->count(); + return $this->collection->count() > $this->totalRecords ? $this->totalRecords : $this->collection->count(); } /** From 29128d477f8cde473b374ba79853368cdc97a586 Mon Sep 17 00:00:00 2001 From: Nakukryskin Date: Wed, 24 Aug 2016 21:31:25 +0300 Subject: [PATCH 215/322] Implementing skipPaging() method --- src/Engines/BaseEngine.php | 17 ++++++++++++----- src/Engines/CollectionEngine.php | 10 ++++------ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 600367a7..405e1476 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -174,11 +174,11 @@ abstract class BaseEngine implements DataTableEngineContract protected $orderCallback; /** - * Custom rewriting totals + * Skip paginate when it need. * * @var bool */ - protected $rewriteTotals = false; + protected $skipPaging = false; /** * Array of data to append on json response. @@ -636,7 +636,7 @@ public function filterRecords() */ public function paginate() { - if ($this->request->isPaginationable()) { + if ($this->request->isPaginationable() && !$this->skipPaging) { $this->paging(); } } @@ -967,10 +967,17 @@ protected function isOracleSql() */ public function setTotalRecords($total) { - $this->rewriteTotals = true; - $this->totalRecords = $total; return $this; } + + /** + * Skipping paging when we need + */ + public function skipPaging(){ + $this->skipPaging = true; + + return $this; + } } diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index b65e10d0..e16d8f05 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -205,12 +205,10 @@ function ($row) use ($column, $keyword) { */ public function paging() { - if(!$this->rewriteTotals) { - $this->collection = $this->collection->slice( - $this->request['start'], - (int)$this->request['length'] > 0 ? $this->request['length'] : 10 - ); - } + $this->collection = $this->collection->slice( + $this->request['start'], + (int)$this->request['length'] > 0 ? $this->request['length'] : 10 + ); } /** From de002fa2f5a5a93f546c579b862c177ac3dbe0c3 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 25 Aug 2016 22:34:01 +0800 Subject: [PATCH 216/322] Fix eager loaded model searching function. Fix #698 --- src/Engines/QueryBuilderEngine.php | 145 ++++++++++++++++------------- 1 file changed, 80 insertions(+), 65 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index b3fcefa0..044c9fcb 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -110,7 +110,8 @@ public function count() * @param string $column * @return string */ - protected function wrap($column) { + protected function wrap($column) + { return $this->connection->getQueryGrammar()->wrap($column); } @@ -256,7 +257,7 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) $this->compileQuerySearch($builder, $column, $keyword, ''); $builder = "({$builder->toSql()}) >= 1"; - $query->orWhereRaw($builder, [$keyword]); + $query->orWhereRaw($builder, [$this->prepareKeyword($keyword)]); }); } @@ -275,19 +276,10 @@ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or $sql = $column . ' LIKE ?'; if ($this->isCaseInsensitive()) { - $sql = 'LOWER(' . $column . ') LIKE ?'; - $keyword = Str::lower($keyword); + $sql = 'LOWER(' . $column . ') LIKE ?'; } - if ($this->isWildcard()) { - $keyword = $this->wildcardLikeString($keyword); - } - - if ($this->isSmartSearch()) { - $keyword = "%$keyword%"; - } - - $query->{$relation .'WhereRaw'}($sql, [$keyword]); + $query->{$relation . 'WhereRaw'}($sql, [$this->prepareKeyword($keyword)]); } /** @@ -308,6 +300,29 @@ public function castColumn($column) return $column; } + /** + * Prepare search keyword based on configurations. + * + * @param string $keyword + * @return string + */ + protected function prepareKeyword($keyword) + { + if ($this->isCaseInsensitive()) { + $keyword = Str::lower($keyword); + } + + if ($this->isWildcard()) { + $keyword = $this->wildcardLikeString($keyword); + } + + if ($this->isSmartSearch()) { + $keyword = "%$keyword%"; + } + + return $keyword; + } + /** * Perform column search. * @@ -379,6 +394,58 @@ private function getSearchKeyword($i, $raw = false) return $this->setupKeyword($keyword); } + /** + * 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; + } + /** * Compile queries for column search. * @@ -460,58 +527,6 @@ public function ordering() } } - /** - * 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 * From 4dbb71f7c3b3c8e5e7d2a4b3a73f6bf3f95f3cd6 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 25 Aug 2016 22:49:08 +0800 Subject: [PATCH 217/322] Fix cs and doc blocks. --- src/Engines/BaseEngine.php | 49 +++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 405e1476..2fadb8cb 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -174,7 +174,7 @@ abstract class BaseEngine implements DataTableEngineContract protected $orderCallback; /** - * Skip paginate when it need. + * Skip paginate as needed. * * @var bool */ @@ -636,7 +636,7 @@ public function filterRecords() */ public function paginate() { - if ($this->request->isPaginationable() && !$this->skipPaging) { + if ($this->request->isPaginationable() && ! $this->skipPaging) { $this->paging(); } } @@ -844,6 +844,29 @@ public function smart($bool = true) return $this; } + /** + * Set total records manually. + * + * @param int $total + * @return $this + */ + public function setTotalRecords($total) + { + $this->totalRecords = $total; + + return $this; + } + + /** + * Skip pagination as needed. + */ + public function skipPaging() + { + $this->skipPaging = true; + + return $this; + } + /** * Check if column is blacklisted. * @@ -958,26 +981,4 @@ 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; - } - - /** - * Skipping paging when we need - */ - public function skipPaging(){ - $this->skipPaging = true; - - return $this; - } } From 4d883b3fa1bb940b2c3bf55d61ae5bc5f2244746 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 25 Aug 2016 23:57:15 +0800 Subject: [PATCH 218/322] Bump v6.18.0 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d97782bf..6b758c0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ ##Change Log +### v6.18.0 - 2016-08-25 +- Fix eager loaded model searching function. Fix #698 and #710. +- Add method to skip pagination. Credits to @Nks PR #707 +- Fix collection filtered total records. If filtered total > total records, use total records. + ### v6.17.1 - 2016-08-23 - Use dompdf v0.7.x. - Implement/fix setTotalRecords on collection engine. From ab941c967badffb7c1170324a3e2876d335d25f8 Mon Sep 17 00:00:00 2001 From: Sebastian Rautila Date: Sun, 4 Sep 2016 18:05:32 +0200 Subject: [PATCH 219/322] Fix to allow join of eager loaded column based on a HasMany-relationship --- src/Engines/QueryBuilderEngine.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 044c9fcb..57a3c9ff 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -5,6 +5,7 @@ use Closure; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasOne; +use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Query\Builder; use Illuminate\Support\Str; use Yajra\Datatables\Helper; @@ -428,7 +429,7 @@ protected function joinEagerLoadedColumn($relation, $relationColumn) } } else { $table = $model->getRelated()->getTable(); - if ($model instanceof HasOne) { + if ($model instanceof HasOne || $model instanceof HasMany) { $foreign = $model->getForeignKey(); $other = $model->getQualifiedParentKeyName(); } else { From 979415e6cb437b89ad5f5242aa4050bb3859c726 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 5 Sep 2016 17:52:31 +0800 Subject: [PATCH 220/322] Bump v6.18.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b758c0c..2843ecfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.18.1 - 2016-09-05 +- Fix to allow join of eager loaded column based on a HasMany-relationship. +- Fix #732, PR #733 credits to @SRautila. + ### v6.18.0 - 2016-08-25 - Fix eager loaded model searching function. Fix #698 and #710. - Add method to skip pagination. Credits to @Nks PR #707 From ed9eb48f39ffe8e0aa9a929b563a5075a7755081 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 13 Sep 2016 15:18:43 +0800 Subject: [PATCH 221/322] Make snappy pdf generation configurable via datatables config file. Fix loading on printPreview using loadHTML. --- src/Services/DataTable.php | 13 +++++++++---- src/config/config.php | 16 ++++++++++++++-- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 71625c2c..7a7f7f74 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -322,17 +322,22 @@ public function pdf() */ public function snappyPdf() { - $data = $this->getDataForPrint(); + /** @var \Barryvdh\Snappy\PdfWrapper $snappy */ $snappy = app('snappy.pdf.wrapper'); - $snappy->setOptions([ + + $options = Config::get('datatables.snappy.options', [ 'no-outline' => true, 'margin-left' => '0', 'margin-right' => '0', 'margin-top' => '10mm', 'margin-bottom' => '10mm', - ])->setOrientation('landscape'); + ]); + $orientation = Config::get('datatables.snappy.orientation', 'landscape'); + + $snappy->setOptions($options) + ->setOrientation($orientation); - return $snappy->loadView($this->printPreview, compact('data')) + return $snappy->loadHTML($this->printPreview()) ->download($this->getFilename() . ".pdf"); } diff --git a/src/config/config.php b/src/config/config.php index 89000cac..f5cc2b3b 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -56,7 +56,6 @@ /** * 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) @@ -67,7 +66,6 @@ /** * 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 @@ -83,4 +81,18 @@ * Excel package: maatwebsite/excel */ 'pdf_generator' => 'excel', + + /** + * Snappy PDF options. + */ + 'snappy' => [ + 'options' => [ + 'no-outline' => true, + 'margin-left' => '0', + 'margin-right' => '0', + 'margin-top' => '10mm', + 'margin-bottom' => '10mm', + ], + 'orientation' => 'landscape', + ], ]; From 1b8c50b9e33a738ecc630e2cbf65138a32932ba7 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 13 Sep 2016 15:59:37 +0800 Subject: [PATCH 222/322] Bump v6.18.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2843ecfb..a16b976f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.18.2 - 2016-09-13 +- Make snappy pdf generation configurable via datatables config file. +- Fix loading of printPreview using loadHTML. + ### v6.18.1 - 2016-09-05 - Fix to allow join of eager loaded column based on a HasMany-relationship. - Fix #732, PR #733 credits to @SRautila. From 2eb45ce9114f047b5fff27891248fd8ded22647c Mon Sep 17 00:00:00 2001 From: root Date: Thu, 22 Sep 2016 23:23:06 -0500 Subject: [PATCH 223/322] Support regex column searches when using CollectionEngine --- src/Engines/CollectionEngine.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index e16d8f05..6fbd558f 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -177,20 +177,29 @@ public function columnSearch() for ($i = 0, $c = count($columns); $i < $c; $i++) { if ($this->request->isColumnSearchable($i)) { $this->isFilterApplied = true; + $regex = $this->request->isRegex($i); $column = $this->getColumnName($i); $keyword = $this->request->columnKeyword($i); $this->collection = $this->collection->filter( - function ($row) use ($column, $keyword) { + function ($row) use ($column, $keyword, $regex) { $data = $this->serialize($row); $value = Arr::get($data, $column); if ($this->isCaseInsensitive()) { - return strpos(Str::lower($value), Str::lower($keyword)) !== false; + if($regex) { + return preg_match('/' . Str::lower($keyword) . '/', Str::lower($value)) == 1; + } else { + return strpos(Str::lower($value), Str::lower($keyword)) !== false; + } } else { - return strpos($value, $keyword) !== false; + if($regex) { + return preg_match('/' . $keyword . '/', $value) == 1; + } else { + return strpos($value, $keyword) !== false; + } } } ); From 4fd4f41a31dda556a3dab670312faab5afaec785 Mon Sep 17 00:00:00 2001 From: Jonathan Brownell Date: Fri, 23 Sep 2016 21:01:45 -0500 Subject: [PATCH 224/322] Refinements to regex handling of column searches --- src/Engines/CollectionEngine.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 6fbd558f..98e2e859 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -189,13 +189,13 @@ function ($row) use ($column, $keyword, $regex) { $value = Arr::get($data, $column); if ($this->isCaseInsensitive()) { - if($regex) { - return preg_match('/' . Str::lower($keyword) . '/', Str::lower($value)) == 1; + if ($regex) { + return preg_match('/' . $keyword . '/i', $value) == 1; } else { return strpos(Str::lower($value), Str::lower($keyword)) !== false; } } else { - if($regex) { + if ($regex) { return preg_match('/' . $keyword . '/', $value) == 1; } else { return strpos($value, $keyword) !== false; From 818c2fc6186ad081c5ad3a8956acce8c39fb08c2 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 24 Sep 2016 10:58:13 +0800 Subject: [PATCH 225/322] Bump v6.19.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a16b976f..697c8374 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.19.0 - 2016-09-24 +- Support regex column searches when using CollectionEngine. +- PR #765, credits to @cadenzajon. + ### v6.18.2 - 2016-09-13 - Make snappy pdf generation configurable via datatables config file. - Fix loading of printPreview using loadHTML. From 98ae8adacefeab3065b713b845a0401fd5159cb3 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 10 Oct 2016 15:08:26 +0800 Subject: [PATCH 226/322] Update fractal to ~0.14. Fix #738. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ec9f6a56..da74cba2 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ "illuminate/view": "~5.0", "illuminate/http": "~5.0", "illuminate/filesystem": "~5.0", - "league/fractal": "~0.12", + "league/fractal": "~0.14", "laravelcollective/html": "~5.0", "maatwebsite/excel": "^2.0", "dompdf/dompdf": "^0.7" From c9a1dc137993a80f844e8370ea5642d2bf1cbb75 Mon Sep 17 00:00:00 2001 From: DDiimmkkaass Date: Wed, 12 Oct 2016 01:01:43 +0300 Subject: [PATCH 227/322] support of using soft deletes trait in models --- src/Engines/BaseEngine.php | 21 +++++++++++++++++++++ src/Engines/QueryBuilderEngine.php | 28 +++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 2fadb8cb..38757715 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -104,6 +104,14 @@ abstract class BaseEngine implements DataTableEngineContract * @var bool */ protected $autoFilter = true; + + /** + * Select trashed records in count function for models with soft deletes trait. + * By default we do not select soft deleted records + * + * @var bool + */ + protected $withTrashed = false; /** * Callback to override global search. @@ -393,6 +401,19 @@ public function escapeColumns($columns = '*') return $this; } + + /** + * Change withTrashed flag value. + * + * @param bool $withTrashed + * @return $this + */ + public function withTrashed($withTrashed = true) + { + $this->withTrashed = $withTrashed; + + return $this; + } /** * Allows previous API calls where the methods were snake_case. diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 57a3c9ff..1acfeeb1 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -100,6 +100,11 @@ public function count() $row_count = $this->wrap('row_count'); $myQuery->select($this->connection->raw("'1' as {$row_count}")); } + + // check for select soft deleted records + if (!$this->withTrashed && $this->modelUseSoftDeletes()) { + $myQuery->whereNull($myQuery->getModel()->getTable().'.deleted_at'); + } return $this->connection->table($this->connection->raw('(' . $myQuery->toSql() . ') count_row_table')) ->setBindings($myQuery->getBindings())->count(); @@ -394,7 +399,28 @@ private function getSearchKeyword($i, $raw = false) return $this->setupKeyword($keyword); } - + + /** + * Check if model use SoftDeletes trait + * + * @return boolean + */ + private function modelUseSoftDeletes() + { + $app = app(); + + //check for laravel version + //in 4 and 5 versions SoftDeletes trait has a different names + //we can check only first number + if (strpos($app::VERSION, '5') === 0) { + $class = 'Illuminate\Database\Eloquent\SoftDeletes'; + } else { + $class = 'Illuminate\Database\Eloquent\SoftDeletingTrait'; + } + + return in_array($class, class_uses($this->query->getModel())); + } + /** * Join eager loaded relation and get the related column name. * From d48467ece15998c6679f8a9c52091c05da3a2058 Mon Sep 17 00:00:00 2001 From: DDiimmkkaass Date: Wed, 12 Oct 2016 11:02:10 +0300 Subject: [PATCH 228/322] fix code formating, remove L4 support --- src/Engines/QueryBuilderEngine.php | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 1acfeeb1..98657eb2 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -102,7 +102,7 @@ public function count() } // check for select soft deleted records - if (!$this->withTrashed && $this->modelUseSoftDeletes()) { + if (! $this->withTrashed && $this->modelUseSoftDeletes()) { $myQuery->whereNull($myQuery->getModel()->getTable().'.deleted_at'); } @@ -407,18 +407,7 @@ private function getSearchKeyword($i, $raw = false) */ private function modelUseSoftDeletes() { - $app = app(); - - //check for laravel version - //in 4 and 5 versions SoftDeletes trait has a different names - //we can check only first number - if (strpos($app::VERSION, '5') === 0) { - $class = 'Illuminate\Database\Eloquent\SoftDeletes'; - } else { - $class = 'Illuminate\Database\Eloquent\SoftDeletingTrait'; - } - - return in_array($class, class_uses($this->query->getModel())); + return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this->query->getModel())); } /** From 475aa5acaa1e07a888286cf873dafc46cbe98c60 Mon Sep 17 00:00:00 2001 From: DDiimmkkaass Date: Wed, 12 Oct 2016 11:37:50 +0300 Subject: [PATCH 229/322] add the check if the used query type is an eloquent query --- src/Engines/QueryBuilderEngine.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 98657eb2..475304f4 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -407,7 +407,11 @@ private function getSearchKeyword($i, $raw = false) */ private function modelUseSoftDeletes() { - return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this->query->getModel())); + if ($this->query_type == 'eloquent') { + return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this->query->getModel())); + } + + return false; } /** From 233141e11129ba4729b3e719d5769126bed83834 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 13 Oct 2016 08:10:14 +0800 Subject: [PATCH 230/322] Bump v6.20.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 697c8374..ba023187 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.20.0 - 2016-10-13 +- Support of using soft deletes trait in models. +- PR #786, credits to @DDiimmkkaass. + ### v6.19.0 - 2016-09-24 - Support regex column searches when using CollectionEngine. - PR #765, credits to @cadenzajon. From c6a056cf30def6302d24840b1d819a842749159e Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 14 Oct 2016 08:46:49 +0800 Subject: [PATCH 231/322] Refactor HasOneOrMany. Fix cs and rearrange methods. --- src/Engines/QueryBuilderEngine.php | 39 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 475304f4..c6fbda65 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -4,8 +4,7 @@ use Closure; use Illuminate\Database\Eloquent\Relations\BelongsToMany; -use Illuminate\Database\Eloquent\Relations\HasOne; -use Illuminate\Database\Eloquent\Relations\HasMany; +use Illuminate\Database\Eloquent\Relations\HasOneOrMany; use Illuminate\Database\Query\Builder; use Illuminate\Support\Str; use Yajra\Datatables\Helper; @@ -100,10 +99,10 @@ public function count() $row_count = $this->wrap('row_count'); $myQuery->select($this->connection->raw("'1' as {$row_count}")); } - + // check for select soft deleted records if (! $this->withTrashed && $this->modelUseSoftDeletes()) { - $myQuery->whereNull($myQuery->getModel()->getTable().'.deleted_at'); + $myQuery->whereNull($myQuery->getModel()->getTable() . '.deleted_at'); } return $this->connection->table($this->connection->raw('(' . $myQuery->toSql() . ') count_row_table')) @@ -121,6 +120,20 @@ protected function wrap($column) return $this->connection->getQueryGrammar()->wrap($column); } + /** + * Check if model use SoftDeletes trait + * + * @return boolean + */ + private function modelUseSoftDeletes() + { + if ($this->query_type == 'eloquent') { + return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this->query->getModel())); + } + + return false; + } + /** * Perform global search. * @@ -399,21 +412,7 @@ private function getSearchKeyword($i, $raw = false) return $this->setupKeyword($keyword); } - - /** - * Check if model use SoftDeletes trait - * - * @return boolean - */ - private function modelUseSoftDeletes() - { - if ($this->query_type == 'eloquent') { - return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this->query->getModel())); - } - - return false; - } - + /** * Join eager loaded relation and get the related column name. * @@ -448,7 +447,7 @@ protected function joinEagerLoadedColumn($relation, $relationColumn) } } else { $table = $model->getRelated()->getTable(); - if ($model instanceof HasOne || $model instanceof HasMany) { + if ($model instanceof HasOneOrMany) { $foreign = $model->getForeignKey(); $other = $model->getQualifiedParentKeyName(); } else { From 1e92e9ee9f76df3186b9344893b3a8e9493137fc Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 14 Oct 2016 09:02:19 +0800 Subject: [PATCH 232/322] Update badge and add Laravel 5.3 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 029bf449..7678cbe9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Join the chat at https://gitter.im/yajra/laravel-datatables](https://badges.gitter.im/yajra/laravel-datatables.svg)](https://gitter.im/yajra/laravel-datatables?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Laravel 4.2|5.0|5.1|5.2](https://img.shields.io/badge/Laravel-4.2|5.0|5.1|5.2-orange.svg)](http://laravel.com) +[![Laravel 4.2|5.0|5.1|5.2|5.3](https://img.shields.io/badge/Laravel-4.2|5.0|5.1|5.2|5.3-orange.svg)](http://laravel.com) [![Latest Stable Version](https://poser.pugx.org/yajra/laravel-datatables-oracle/v/stable)](https://packagist.org/packages/yajra/laravel-datatables-oracle) [![Build Status](https://travis-ci.org/yajra/laravel-datatables.svg?branch=master)](https://travis-ci.org/yajra/laravel-datatables) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/yajra/laravel-datatables/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/yajra/laravel-datatables/?branch=master) From d05efa707428a42dbaf9693724cfc98c5740e23c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 14 Oct 2016 15:48:50 +0800 Subject: [PATCH 233/322] Use 5.x badge. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7678cbe9..8d193637 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Join the chat at https://gitter.im/yajra/laravel-datatables](https://badges.gitter.im/yajra/laravel-datatables.svg)](https://gitter.im/yajra/laravel-datatables?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Laravel 4.2|5.0|5.1|5.2|5.3](https://img.shields.io/badge/Laravel-4.2|5.0|5.1|5.2|5.3-orange.svg)](http://laravel.com) +[![Laravel 4.2|5.x](https://img.shields.io/badge/Laravel-4.2|5.x-orange.svg)](http://laravel.com) [![Latest Stable Version](https://poser.pugx.org/yajra/laravel-datatables-oracle/v/stable)](https://packagist.org/packages/yajra/laravel-datatables-oracle) [![Build Status](https://travis-ci.org/yajra/laravel-datatables.svg?branch=master)](https://travis-ci.org/yajra/laravel-datatables) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/yajra/laravel-datatables/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/yajra/laravel-datatables/?branch=master) From 6475c6b8f3e2286b326334e22a61c859761c88cb Mon Sep 17 00:00:00 2001 From: pcastrotigre Date: Thu, 20 Oct 2016 16:28:56 -0500 Subject: [PATCH 234/322] support to morphToMany Adding support for morphToMany to search/sort --- src/Engines/QueryBuilderEngine.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index c6fbda65..dea5974a 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -3,6 +3,7 @@ namespace Yajra\Datatables\Engines; use Closure; +use Illuminate\Database\Eloquent\Relations\MorphToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasOneOrMany; use Illuminate\Database\Query\Builder; @@ -271,12 +272,18 @@ protected function getEagerLoads() protected function compileRelationSearch($query, $relation, $column, $keyword) { $myQuery = clone $this->query; + $relationType = $myQuery->getModel()->{$relation}(); $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, [$this->prepareKeyword($keyword)]); + if($relationType instanceof MorphToMany){ + $query->orWhereRaw($builder, [$relationType->getMorphClass(),$this->prepareKeyword($keyword)]); + } + else{ + $query->orWhereRaw($builder, [$this->prepareKeyword($keyword)]); + } }); } From 281eb9be4102ea3db16ee5d89829d25eb292b207 Mon Sep 17 00:00:00 2001 From: pcastrotigre Date: Thu, 20 Oct 2016 16:38:17 -0500 Subject: [PATCH 235/322] sending var to closure --- src/Engines/QueryBuilderEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index dea5974a..d8c24a98 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -273,7 +273,7 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) { $myQuery = clone $this->query; $relationType = $myQuery->getModel()->{$relation}(); - $myQuery->orWhereHas($relation, function ($builder) use ($column, $keyword, $query) { + $myQuery->orWhereHas($relation, function ($builder) use ($column, $keyword, $query, $relationType) { $builder->select($this->connection->raw('count(1)')); $this->compileQuerySearch($builder, $column, $keyword, ''); $builder = "({$builder->toSql()}) >= 1"; From a9929184dd5d40a7bf1f1cba2e954508182bc384 Mon Sep 17 00:00:00 2001 From: pcastrotigre Date: Fri, 21 Oct 2016 15:56:57 -0500 Subject: [PATCH 236/322] Do not sort in morphToMany morphToMany sort will do nothing --- src/Engines/QueryBuilderEngine.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index d8c24a98..e11307a4 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -537,6 +537,7 @@ public function ordering() $orderable['direction'] ); } else { + $valid = 1; if (count(explode('.', $column)) > 1) { $eagerLoads = $this->getEagerLoads(); $parts = explode('.', $column); @@ -544,11 +545,18 @@ public function ordering() $relation = implode('.', $parts); if (in_array($relation, $eagerLoads)) { - $column = $this->joinEagerLoadedColumn($relation, $relationColumn); + $relationship = $this->query->getRelation($relation); + if(!($relationship instanceof MorphToMany)){ + $column = $this->joinEagerLoadedColumn($relation, $relationColumn); + } else { + $valid = 0; + } } } - $this->getQueryBuilder()->orderBy($column, $orderable['direction']); + if($valid == 1){ + $this->getQueryBuilder()->orderBy($column, $orderable['direction']); + } } } } From ca1ef963730540e3d5ada494d85a79df3c1fa42f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 22 Oct 2016 09:21:55 +0800 Subject: [PATCH 237/322] Fix cs. --- src/Engines/QueryBuilderEngine.php | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index e11307a4..bf3f07a9 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -3,9 +3,9 @@ namespace Yajra\Datatables\Engines; use Closure; -use Illuminate\Database\Eloquent\Relations\MorphToMany; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasOneOrMany; +use Illuminate\Database\Eloquent\Relations\MorphToMany; use Illuminate\Database\Query\Builder; use Illuminate\Support\Str; use Yajra\Datatables\Helper; @@ -271,17 +271,16 @@ protected function getEagerLoads() */ protected function compileRelationSearch($query, $relation, $column, $keyword) { - $myQuery = clone $this->query; + $myQuery = clone $this->query; $relationType = $myQuery->getModel()->{$relation}(); $myQuery->orWhereHas($relation, function ($builder) use ($column, $keyword, $query, $relationType) { $builder->select($this->connection->raw('count(1)')); $this->compileQuerySearch($builder, $column, $keyword, ''); $builder = "({$builder->toSql()}) >= 1"; - if($relationType instanceof MorphToMany){ - $query->orWhereRaw($builder, [$relationType->getMorphClass(),$this->prepareKeyword($keyword)]); - } - else{ + if ($relationType instanceof MorphToMany) { + $query->orWhereRaw($builder, [$relationType->getMorphClass(), $this->prepareKeyword($keyword)]); + } else { $query->orWhereRaw($builder, [$this->prepareKeyword($keyword)]); } }); @@ -546,7 +545,7 @@ public function ordering() if (in_array($relation, $eagerLoads)) { $relationship = $this->query->getRelation($relation); - if(!($relationship instanceof MorphToMany)){ + if (! ($relationship instanceof MorphToMany)) { $column = $this->joinEagerLoadedColumn($relation, $relationColumn); } else { $valid = 0; @@ -554,7 +553,7 @@ public function ordering() } } - if($valid == 1){ + if ($valid == 1) { $this->getQueryBuilder()->orderBy($column, $orderable['direction']); } } From 899014480a8c7d7fe8d135425d85b791c5fcf687 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 22 Oct 2016 09:24:42 +0800 Subject: [PATCH 238/322] Bump v6.21.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba023187..7b8821b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +### v6.21.0 - 2016-10-22 +- Support to morphToMany. PR #804, credits to @pcastrotigre +- Update fractal to ~0.14. Credits to @tyloo +- Refactor HasOneOrMany as suggested in #733 +- Fix CS. + ### v6.20.0 - 2016-10-13 - Support of using soft deletes trait in models. - PR #786, credits to @DDiimmkkaass. From ab568c726a13ce46c31c5d56e47bf1c91fe9d434 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 25 Oct 2016 08:48:34 +0800 Subject: [PATCH 239/322] Do not convert column to raw statement. Use Laravel's Expression or DB::raw, for raw statements. --- src/Engines/QueryBuilderEngine.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index bf3f07a9..646b2c42 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -296,7 +296,6 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) */ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or') { - $column = strstr($column, '(') ? $this->connection->raw($column) : $column; $column = $this->castColumn($column); $sql = $column . ' LIKE ?'; From baef845c998fd08f5315db17d96604382109bfcd Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 25 Oct 2016 09:00:07 +0800 Subject: [PATCH 240/322] Bump v6.21.1 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b8821b8..d125e1da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +### v6.21.1 - 2016-10-25 +- Do not convert column to raw statement. Thanks to Nick Howell for pointing the issue. + ### v6.21.0 - 2016-10-22 - Support to morphToMany. PR #804, credits to @pcastrotigre - Update fractal to ~0.14. Credits to @tyloo From 8a4f672ce8c705368745d4e65a4475025a3e753d Mon Sep 17 00:00:00 2001 From: shibby Date: Thu, 27 Oct 2016 15:48:03 +0300 Subject: [PATCH 241/322] better resolution for class names --- src/Datatables.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Datatables.php b/src/Datatables.php index 90bb5623..c1be1f8d 100644 --- a/src/Datatables.php +++ b/src/Datatables.php @@ -51,7 +51,7 @@ public function __construct(Request $request) */ public static function of($builder) { - $datatables = app('Yajra\Datatables\Datatables'); + $datatables = app(\Yajra\Datatables\Datatables::class); $datatables->builder = $builder; if ($builder instanceof QueryBuilder) { @@ -121,7 +121,7 @@ public function __call($name, $arguments) */ public function getHtmlBuilder() { - return app('Yajra\Datatables\Html\Builder'); + return app(\Yajra\Datatables\Html\Builder::class); } /** From 93023628fff4dbe123a9cc906ba24daca093ee56 Mon Sep 17 00:00:00 2001 From: Elf Sundae Date: Wed, 16 Nov 2016 15:24:35 +0800 Subject: [PATCH 242/322] Fix html builder instance, close #830 --- src/Services/DataTable.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 7a7f7f74..3d5a53de 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -58,6 +58,13 @@ abstract class DataTable implements DataTableContract, DataTableButtonsContract */ protected $scopes = []; + /** + * Html builder. + * + * @var \Yajra\Datatables\Html\Builder + */ + protected $htmlBuilder; + /** * Export filename. * @@ -173,7 +180,7 @@ public function html() */ public function builder() { - return $this->datatables->getHtmlBuilder(); + return $this->htmlBuilder ?: $this->htmlBuilder = $this->datatables->getHtmlBuilder(); } /** From a9386ea2aac063dd0f0fa5affc5f5cd77b6e0727 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 16 Nov 2016 15:36:32 +0800 Subject: [PATCH 243/322] Bump v6.21.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d125e1da..e780b63b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.21.2 - 2016-11-16 +- Fix html builder instance, close #830. PR #833, credits to @ElfSundae. +- Class name resolution updated. PR #812, credits to @shibby. + ### v6.21.1 - 2016-10-25 - Do not convert column to raw statement. Thanks to Nick Howell for pointing the issue. From 0512715dd179744810bb926fdee2a8c42ace2adc Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 17 Nov 2016 11:24:56 +0800 Subject: [PATCH 244/322] Update doc links. --- README.md | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8d193637..c8e9506a 100644 --- a/README.md +++ b/README.md @@ -30,13 +30,13 @@ return Datatables::of(User::all())->make(true); ``` ## Requirements -- [PHP 5.5.9 or later](http://php.net/) -- [Laravel 5.0 or later](https://github.com/laravel/framework) -- [DataTables jQuery Plugin](http://datatables.net/) **Version 1.10.xx** +- [PHP >=5.5.9](http://php.net/) +- [Laravel 5.x](https://github.com/laravel/framework) +- [jQuery DataTables v1.10.x](http://datatables.net/) ## Documentations -- You will find user friendly and updated documentation in the wiki here: [Laravel Datatables Wiki](https://github.com/yajra/laravel-datatables/wiki) -- You will find the API Documentation here: [Laravel Datatables API](http://yajra.github.io/laravel-datatables/api/) +- [Laravel Datatables Documentation](https://yajrabox.com/docs/laravel-datatables/6.0) +- [Laravel Datatables API](http://yajra.github.io/laravel-datatables/api/6.0) - [Demo Application](http://datatables.yajrabox.com) is available for artisan's reference. ## Quick Installation @@ -46,20 +46,13 @@ return Datatables::of(User::all())->make(true); `Yajra\Datatables\DatatablesServiceProvider::class` #### Facade -`Datatables` facade is automatically registered as an alias for `Yajra\Datatables\Facades\Datatables` class. +`Datatables` facade is automatically registered as an alias for `Yajra\Datatables\Facades\Datatables` class. #### Configuration and Assets `$ php artisan vendor:publish --tag=datatables` And that's it! Start building out some awesome DataTables! -## Upgrading from v5.x to v6.x - - Change all occurrences of `yajra\Datatables` to `Yajra\Datatables`. (Use Sublime's find and replace all for faster update). - - Remove `Datatables` facade registration. - - Temporarily comment out `Yajra\Datatables\DatatablesServiceProvider`. - - Update package version on your composer.json and use `yajra/laravel-datatables-oracle: ~6.0` - - Uncomment the provider `Yajra\Datatables\DatatablesServiceProvider`. - ## Debugging Mode To enable debugging mode, just set `APP_DEBUG=true` and the package will include the queries and inputs used when processing the table. From 9fb497368c8b56f76717e83ce17e0e3fea9395a0 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 17 Nov 2016 16:01:43 +0800 Subject: [PATCH 245/322] Add method to get or create a transformer serializer. --- src/Engines/BaseEngine.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 38757715..9afd3f6d 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -680,7 +680,7 @@ public function render($object = false) $fractal = app('datatables.fractal'); if ($this->serializer) { - $fractal->setSerializer(new $this->serializer); + $fractal->setSerializer($this->createSerializer()); } //Get transformer reflection @@ -712,6 +712,20 @@ public function render($object = false) return new JsonResponse($output); } + /** + * Get or create transformer serializer instance. + * + * @return \League\Fractal\Serializer\SerializerAbstract + */ + protected function createSerializer() + { + if ($this->serializer instanceof \League\Fractal\Serializer\SerializerAbstract) { + return $this->serializer; + } + + return new $this->serializer(); + } + /** * Get or create transformer instance. * From 615eb98a2aa42773a2a7e571bc3bf75e39078b28 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 17 Nov 2016 16:02:01 +0800 Subject: [PATCH 246/322] Use callable type hint. --- src/Engines/BaseEngine.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 38757715..4c6ade05 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -116,7 +116,7 @@ abstract class BaseEngine implements DataTableEngineContract /** * Callback to override global search. * - * @var \Closure + * @var callable */ protected $filterCallback; @@ -177,7 +177,7 @@ abstract class BaseEngine implements DataTableEngineContract /** * Custom ordering callback. * - * @var \Closure + * @var callable */ protected $orderCallback; @@ -771,11 +771,11 @@ public function showDebugger(array $output) /** * Update flags to disable global search * - * @param \Closure $callback + * @param callable $callback * @param mixed $parameters * @param bool $autoFilter */ - public function overrideGlobalSearch(\Closure $callback, $parameters, $autoFilter = false) + public function overrideGlobalSearch(callable $callback, $parameters, $autoFilter = false) { $this->autoFilter = $autoFilter; $this->isFilterApplied = true; @@ -816,10 +816,10 @@ public function with($key, $value = '') /** * Override default ordering method with a closure callback. * - * @param \Closure $closure + * @param callable $closure * @return $this */ - public function order(\Closure $closure) + public function order(callable $closure) { $this->orderCallback = $closure; From cd91bd31ab2b768a9ba24fa1c136775cd9c516a1 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 17 Nov 2016 16:23:54 +0800 Subject: [PATCH 247/322] Fix callable doc block. --- src/Engines/BaseEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index 4c6ade05..b9a97078 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -525,7 +525,7 @@ public function addRowAttr($key, $value) * Override default column filter search. * * @param string $column - * @param string|Closure $method + * @param string|callable $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. From 7fa350f343957f3ebb15eb872641a87908e9a9e3 Mon Sep 17 00:00:00 2001 From: Nimit Suwannagate Date: Fri, 18 Nov 2016 14:29:58 +0700 Subject: [PATCH 248/322] Make compileRelationSearch can support nested relations. Tested on Laravel5.2 with Datatables v6.21.1. This will make search on nested relation can work properly. Reference issue: Filter/search within nested relations #696 --- src/Engines/QueryBuilderEngine.php | 93 +++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 7 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 646b2c42..d0386f0e 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -272,18 +272,97 @@ protected function getEagerLoads() protected function compileRelationSearch($query, $relation, $column, $keyword) { $myQuery = clone $this->query; - $relationType = $myQuery->getModel()->{$relation}(); - $myQuery->orWhereHas($relation, function ($builder) use ($column, $keyword, $query, $relationType) { - $builder->select($this->connection->raw('count(1)')); - $this->compileQuerySearch($builder, $column, $keyword, ''); + + /** + * For compile nested relation, we need store all nested relation as array + * and reverse order to apply where query. + * + * With this method we can create nested sub query with properly relation. + */ + + /** + * Store all relation data that require in next step + */ + $relationChunk = []; + + /** + * Store last eloquent query builder for get next relation. + */ + $lastQuery = $query; + + $relations = explode('.', $relation); + $lastRelation = end($relations); + foreach ($relations as $relation) { + $relationType = $myQuery->getModel()->{$relation}(); + $myQuery->orWhereHas($relation, function ($builder) use ( + $column, + $keyword, + $query, + $relationType, + $relation, + $lastRelation, + &$relationChunk, + &$lastQuery + ) { + $builder->select($this->connection->raw('count(1)')); + + // We will perform search on last relation only. + if ($relation == $lastRelation) { + $this->compileQuerySearch($builder, $column, $keyword, ''); + } + + // Put require object to next step!! + $relationChunk[$relation] = [ + 'builder' => $builder, + 'relationType' => $relationType, + 'query' => $lastQuery + ]; + + // This is trick make sub query. + $lastQuery = $builder; + }); + + // This is trick to make nested relation by pass previous relation to be next query eloquent builder + $myQuery = $relationType; + } + + /** + * Reverse them all + */ + $relationChunk = array_reverse($relationChunk, true); + + /** + * Create valuable for use in check last relation (reverse order) + */ + $totalRelation = count($relationChunk); + $processed = 1; + + /** + * Walking ... + */ + foreach ($relationChunk as $relation => $chunk) { + // Prepare variables + $builder = $chunk['builder']; + $relationType = $chunk['relationType']; + $query = $chunk['query']; $builder = "({$builder->toSql()}) >= 1"; + // Check if it last relation we will use orWhereRaw + if ($totalRelation === $processed) { + $relationMethod = "orWhereRaw"; + } else { + // For case parent relation of nested relation. + // We must use and for properly query and get correct result + $relationMethod = "whereRaw"; + } + if ($relationType instanceof MorphToMany) { - $query->orWhereRaw($builder, [$relationType->getMorphClass(), $this->prepareKeyword($keyword)]); + $query->{$relationMethod}($builder, [$relationType->getMorphClass(), $this->prepareKeyword($keyword)]); } else { - $query->orWhereRaw($builder, [$this->prepareKeyword($keyword)]); + $query->{$relationMethod}($builder, [$this->prepareKeyword($keyword)]); } - }); + $processed++; + } } /** From 00c8d37e51f7c66ac15828e75796bd5f6d9a7cc3 Mon Sep 17 00:00:00 2001 From: Nimit Suwannagate Date: Fri, 18 Nov 2016 14:52:20 +0700 Subject: [PATCH 249/322] Fix comment and refactor foreach. --- src/Engines/QueryBuilderEngine.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index d0386f0e..2a0f3be2 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -332,10 +332,11 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) $relationChunk = array_reverse($relationChunk, true); /** - * Create valuable for use in check last relation (reverse order) + * Create valuable for use in check last relation */ - $totalRelation = count($relationChunk); - $processed = 1; + end($relationChunk); + $lastRelation = key($relationChunk); + reset($relationChunk); /** * Walking ... @@ -348,7 +349,7 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) $builder = "({$builder->toSql()}) >= 1"; // Check if it last relation we will use orWhereRaw - if ($totalRelation === $processed) { + if ($lastRelation == $relation) { $relationMethod = "orWhereRaw"; } else { // For case parent relation of nested relation. @@ -361,7 +362,6 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) } else { $query->{$relationMethod}($builder, [$this->prepareKeyword($keyword)]); } - $processed++; } } From 067994638d831872ca7a6ec9d016e07765723cf9 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 19 Nov 2016 15:57:18 +0800 Subject: [PATCH 250/322] Bump v6.22.0 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e780b63b..2df5c7c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ ##Change Log +### v6.22.0 - 2016-11-19 +- Add support for searching of nested relationships. +- PR #841 & #844. Credits to @ethaizone +- Fix #696, #789, #771, #509, #441. + ### v6.21.2 - 2016-11-16 - Fix html builder instance, close #830. PR #833, credits to @ElfSundae. - Class name resolution updated. PR #812, credits to @shibby. From 08cafa66eab4b87390f928476963cf022299ea19 Mon Sep 17 00:00:00 2001 From: Nimit Suwannagate Date: Tue, 22 Nov 2016 23:45:27 +0700 Subject: [PATCH 251/322] Patch for fix ambiguous field error for nested relation, Ambiguous field error will appear when search and join nested relation together. This patch will only get table from builder class and push it before column name. --- src/Engines/QueryBuilderEngine.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 2a0f3be2..797836c3 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -378,6 +378,33 @@ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or $column = $this->castColumn($column); $sql = $column . ' LIKE ?'; + /** + * Patch for fix about ambiguous field + * + * Ambiguous field error will appear + * when query use join table and search with keyword. + */ + $column = str_replace('`', '', $column); + + // check . in field name for protect don't add table again + // but as far as I tested, this function has single field name only. + if (strpos($column, '.') === false) { + // Alternative method to check + // instanceof \Illuminate\Database\Eloquent\Builder + if (method_exists($query, 'getQuery')) { + $q = $query->getQuery(); + } else { + $q = $query; + } + + // get table from query and add it. + $column = $q->from.'.'.$column; + } + // Add ` cover table and field name. + $column = '`' . str_replace('.', '`.`', $column) . '`'; + + /* end fix */ + if ($this->isCaseInsensitive()) { $sql = 'LOWER(' . $column . ') LIKE ?'; } From cbe28ea4477bcd78b91e0748d1cfe56a1d43bd23 Mon Sep 17 00:00:00 2001 From: Nimit Suwannagate Date: Wed, 23 Nov 2016 00:21:41 +0700 Subject: [PATCH 252/322] Add support ordering when search in nested relations. I did it!! --- src/Engines/QueryBuilderEngine.php | 74 +++++++++++++++++++----------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 2a0f3be2..3d9bfa71 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -511,37 +511,43 @@ protected function joinEagerLoadedColumn($relation, $relationColumn) $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); - } + /** + * Add support nested relations. + */ + $lastQuery = $this->query; - $related = $model->getRelated(); - $table = $related->getTable(); - $tablePK = $related->getForeignKey(); - $tableFK = $related->getQualifiedKeyName(); + foreach (explode('.', $relation) as $eachRelation) { + $model = $lastQuery->getRelation($eachRelation); - if (! in_array($table, $joins)) { - $this->getQueryBuilder()->leftJoin($table, $pivot . '.' . $tablePK, '=', $tableFK); - } - } else { - $table = $model->getRelated()->getTable(); - if ($model instanceof HasOneOrMany) { - $foreign = $model->getForeignKey(); - $other = $model->getQualifiedParentKeyName(); + 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 { - $foreign = $model->getQualifiedForeignKey(); - $other = $model->getQualifiedOtherKeyName(); + $table = $model->getRelated()->getTable(); + if ($model instanceof HasOneOrMany) { + $foreign = $model->getForeignKey(); + $other = $model->getQualifiedParentKeyName(); + } else { + $foreign = $model->getQualifiedForeignKey(); + $other = $model->getQualifiedOtherKeyName(); + } + if (! in_array($table, $joins)) { + $this->getQueryBuilder()->leftJoin($table, $foreign, '=', $other); + } } - if (! in_array($table, $joins)) { - $this->getQueryBuilder()->leftJoin($table, $foreign, '=', $other); - } + $lastQuery = $model->getQuery(); } $column = $table . '.' . $relationColumn; @@ -622,8 +628,20 @@ public function ordering() $relation = implode('.', $parts); if (in_array($relation, $eagerLoads)) { - $relationship = $this->query->getRelation($relation); - if (! ($relationship instanceof MorphToMany)) { + // Loop for nested relations + // This code is check morph many or not. + // If one of nested relation is MorphToMany + // we will call joinEagerLoadedColumn. + $lastQuery = $this->query; + $isMorphToMany = false; + foreach (explode('.', $relation) as $eachRelation) { + $relationship = $lastQuery->getRelation($eachRelation); + if (! ($relationship instanceof MorphToMany)) { + $isMorphToMany = true; + } + $lastQuery = $relationship; + } + if ($isMorphToMany) { $column = $this->joinEagerLoadedColumn($relation, $relationColumn); } else { $valid = 0; From 5fe1e7fe22407a4bba527bb04294d61801b25f47 Mon Sep 17 00:00:00 2001 From: Nimit Suwannagate Date: Thu, 24 Nov 2016 20:31:17 +0700 Subject: [PATCH 253/322] Add wrap to column name. --- src/Engines/QueryBuilderEngine.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 797836c3..b6be9b31 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -384,6 +384,7 @@ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or * Ambiguous field error will appear * when query use join table and search with keyword. */ + // Remove backtick that appear from MYSQL query. $column = str_replace('`', '', $column); // check . in field name for protect don't add table again @@ -400,8 +401,8 @@ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or // get table from query and add it. $column = $q->from.'.'.$column; } - // Add ` cover table and field name. - $column = '`' . str_replace('.', '`.`', $column) . '`'; + // Add wrap cover table and field name. + $column = $this->wrap($column); /* end fix */ From af87ef0b409755e364f90e879ce9a057c71c5b84 Mon Sep 17 00:00:00 2001 From: Nimit Suwannagate Date: Fri, 25 Nov 2016 13:45:40 +0700 Subject: [PATCH 254/322] Update QueryBuilderEngine.php --- src/Engines/QueryBuilderEngine.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index b6be9b31..a6d16dc2 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -384,8 +384,9 @@ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or * Ambiguous field error will appear * when query use join table and search with keyword. */ - // Remove backtick that appear from MYSQL query. - $column = str_replace('`', '', $column); + // Remove delimiter of column that appear from MYSQL query. + $column = str_replace(['`', '"', '[', ']'], '', $column); + // check . in field name for protect don't add table again // but as far as I tested, this function has single field name only. From 68daa435cc383e5a1cf56ee4834e2b915a1792d2 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 30 Nov 2016 15:58:35 +0800 Subject: [PATCH 255/322] Add patreon page link. --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c8e9506a..b47a6cc8 100644 --- a/README.md +++ b/README.md @@ -77,4 +77,5 @@ If you discover any security related issues, please email [aqangeles@gmail.com]( The MIT License (MIT). Please see [License File](https://github.com/yajra/laravel-datatables/blob/master/LICENSE.md) for more information. ## Buy me a beer -Click here to lend your support to: Laravel Datatables and make a donation at pledgie.com ! +- Click here to lend your support to: Laravel Datatables and make a donation at pledgie.com ! +- [Become a patron](https://www.patreon.com/bePatron?u=4521203) From e556901e26b2e0949f70a06d6c527a681acb2b02 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 1 Dec 2016 09:35:56 +0800 Subject: [PATCH 256/322] Patch request class and use input array access to get the values. Fix #857, #657, #395 --- src/Request.php | 55 ++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/Request.php b/src/Request.php index 3b8550ca..3c821c6b 100644 --- a/src/Request.php +++ b/src/Request.php @@ -8,7 +8,6 @@ /** * Class Request. * - * @property array columns * @package Yajra\Datatables * @author Arjay Angeles */ @@ -21,9 +20,9 @@ class Request extends IlluminateRequest */ public function checkLegacyCode() { - if (! $this->get('draw') && $this->get('sEcho')) { + if (! $this->input('draw') && $this->input('sEcho')) { throw new Exception('DataTables legacy code is not supported! Please use DataTables 1.10++ coding convention.'); - } elseif (! $this->get('draw') && ! $this->get('columns')) { + } elseif (! $this->input('draw') && ! $this->input('columns')) { throw new Exception('Insufficient parameters'); } } @@ -35,18 +34,7 @@ public function checkLegacyCode() */ 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']; + return $this->input('search.value') != ''; } /** @@ -57,7 +45,7 @@ public function columnKeyword($index) */ public function isRegex($index) { - return $this->columns[$index]['search']['regex'] === 'true'; + return $this->input("columns.$index.search.regex") === 'true'; } /** @@ -72,9 +60,9 @@ public function orderableColumns() } $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']; + for ($i = 0, $c = count($this->input('order')); $i < $c; $i++) { + $order_col = $this->input("order.$i.column"); + $order_dir = $this->input("order.$i.dir"); if ($this->isColumnOrderable($order_col)) { $orderable[] = ['column' => $order_col, 'direction' => $order_dir]; } @@ -90,7 +78,7 @@ public function orderableColumns() */ public function isOrderable() { - return $this->get('order') && count($this->get('order')) > 0; + return $this->input('order') && count($this->input('order')) > 0; } /** @@ -101,7 +89,7 @@ public function isOrderable() */ public function isColumnOrderable($index) { - return $this->get('columns')[$index]['orderable'] == 'true'; + return $this->input("columns.$index.orderable") == 'true'; } /** @@ -112,7 +100,7 @@ public function isColumnOrderable($index) public function searchableColumnIndex() { $searchable = []; - for ($i = 0, $c = count($this->get('columns')); $i < $c; $i++) { + for ($i = 0, $c = count($this->input('columns')); $i < $c; $i++) { if ($this->isColumnSearchable($i, false)) { $searchable[] = $i; } @@ -130,12 +118,23 @@ public function searchableColumnIndex() */ public function isColumnSearchable($i, $column_search = true) { - $columns = $this->get('columns'); + $columns = $this->input('columns'); if ($column_search) { - return $columns[$i]['searchable'] == 'true' && $columns[$i]['search']['value'] != ''; + return $this->input("columns.$i.searchable") === 'true' && $this->columnKeyword($i) != ''; } - return $columns[$i]['searchable'] == 'true'; + return $this->input("columns.$i.searchable") === 'true'; + } + + /** + * Get column's search value. + * + * @param integer $index + * @return string + */ + public function columnKeyword($index) + { + return $this->input("columns.$index.search.value"); } /** @@ -145,7 +144,7 @@ public function isColumnSearchable($i, $column_search = true) */ public function keyword() { - return $this->get('search')['value']; + return $this->input('search.value'); } /** @@ -156,7 +155,7 @@ public function keyword() */ public function columnName($i) { - $column = $this->get('columns')[$i]; + $column = $this->input("columns.$i"); return isset($column['name']) && $column['name'] <> '' ? $column['name'] : $column['data']; } @@ -168,6 +167,6 @@ public function columnName($i) */ public function isPaginationable() { - return ! is_null($this->get('start')) && ! is_null($this->get('length')) && $this->get('length') != -1; + return ! is_null($this->input('start')) && ! is_null($this->input('length')) && $this->input('length') != -1; } } From 632aa32ff95ee013bbc49666b03327590c1310a6 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 1 Dec 2016 09:46:59 +0800 Subject: [PATCH 257/322] Use input and cast columns to array to avoid foreach error. --- src/Engines/QueryBuilderEngine.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 2a0f3be2..317d1cc1 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -433,7 +433,7 @@ protected function prepareKeyword($keyword) */ public function columnSearch() { - $columns = $this->request->get('columns', []); + $columns = (array) $this->request->input('columns'); foreach ($columns as $index => $column) { if (! $this->request->isColumnSearchable($index)) { @@ -645,8 +645,8 @@ public function ordering() */ public function paging() { - $this->query->skip($this->request['start']) - ->take((int) $this->request['length'] > 0 ? $this->request['length'] : 10); + $this->query->skip($this->request->input('start')) + ->take((int) $this->request->input('length') > 0 ? $this->request->input('length') : 10); } /** From e105df4eac82c7a49bd27729959086c3f703db0f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 1 Dec 2016 09:53:46 +0800 Subject: [PATCH 258/322] Bump v6.22.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2df5c7c5..3eefbca5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.22.1 - 2016-12-01 +- Patch request class and use input array access to get the values. #868 +- Fix Error 500 Illegal string offset issues: #857, #657, #395. + ### v6.22.0 - 2016-11-19 - Add support for searching of nested relationships. - PR #841 & #844. Credits to @ethaizone From 65434e6de6c3f223ea05c5825d4900352b906d6f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 1 Dec 2016 10:02:55 +0800 Subject: [PATCH 259/322] Add patreon image. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b47a6cc8..b5284e1f 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,6 @@ If you discover any security related issues, please email [aqangeles@gmail.com]( The MIT License (MIT). Please see [License File](https://github.com/yajra/laravel-datatables/blob/master/LICENSE.md) for more information. -## Buy me a beer +## Buy me a coffee - Click here to lend your support to: Laravel Datatables and make a donation at pledgie.com ! -- [Become a patron](https://www.patreon.com/bePatron?u=4521203) +- Become a Patron From 76de1230b1336b19b6f196aac9dbb007eb0ee658 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 1 Dec 2016 10:04:21 +0800 Subject: [PATCH 260/322] Add patreon image width. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b5284e1f..655f2102 100644 --- a/README.md +++ b/README.md @@ -78,4 +78,4 @@ The MIT License (MIT). Please see [License File](https://github.com/yajra/larave ## Buy me a coffee - Click here to lend your support to: Laravel Datatables and make a donation at pledgie.com ! -- Become a Patron +- Become a Patron From a6319c3c3738a387824712c1262b872bab132a13 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 1 Dec 2016 10:15:26 +0800 Subject: [PATCH 261/322] Remove unused code. --- src/Request.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Request.php b/src/Request.php index 3c821c6b..e072eada 100644 --- a/src/Request.php +++ b/src/Request.php @@ -118,7 +118,6 @@ public function searchableColumnIndex() */ public function isColumnSearchable($i, $column_search = true) { - $columns = $this->input('columns'); if ($column_search) { return $this->input("columns.$i.searchable") === 'true' && $this->columnKeyword($i) != ''; } From 4936c83f1ca2f42dc57972c9e8041f2f95d5eb20 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 1 Dec 2016 10:15:41 +0800 Subject: [PATCH 262/322] Cast to int. --- src/Request.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Request.php b/src/Request.php index e072eada..5504380d 100644 --- a/src/Request.php +++ b/src/Request.php @@ -61,7 +61,7 @@ public function orderableColumns() $orderable = []; for ($i = 0, $c = count($this->input('order')); $i < $c; $i++) { - $order_col = $this->input("order.$i.column"); + $order_col = (int) $this->input("order.$i.column"); $order_dir = $this->input("order.$i.dir"); if ($this->isColumnOrderable($order_col)) { $orderable[] = ['column' => $order_col, 'direction' => $order_dir]; From 64ef1e7a2bc9ef09925ea38332e98983da1ef0eb Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 1 Dec 2016 10:54:46 +0800 Subject: [PATCH 263/322] Fix cs. --- src/Engines/QueryBuilderEngine.php | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index c6f3f297..5833a419 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -271,12 +271,11 @@ protected function getEagerLoads() */ protected function compileRelationSearch($query, $relation, $column, $keyword) { - $myQuery = clone $this->query; + $myQuery = clone $this->query; /** * For compile nested relation, we need store all nested relation as array * and reverse order to apply where query. - * * With this method we can create nested sub query with properly relation. */ @@ -290,7 +289,7 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) */ $lastQuery = $query; - $relations = explode('.', $relation); + $relations = explode('.', $relation); $lastRelation = end($relations); foreach ($relations as $relation) { $relationType = $myQuery->getModel()->{$relation}(); @@ -313,9 +312,9 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) // Put require object to next step!! $relationChunk[$relation] = [ - 'builder' => $builder, + 'builder' => $builder, 'relationType' => $relationType, - 'query' => $lastQuery + 'query' => $lastQuery, ]; // This is trick make sub query. @@ -343,10 +342,10 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) */ foreach ($relationChunk as $relation => $chunk) { // Prepare variables - $builder = $chunk['builder']; + $builder = $chunk['builder']; $relationType = $chunk['relationType']; - $query = $chunk['query']; - $builder = "({$builder->toSql()}) >= 1"; + $query = $chunk['query']; + $builder = "({$builder->toSql()}) >= 1"; // Check if it last relation we will use orWhereRaw if ($lastRelation == $relation) { @@ -380,14 +379,12 @@ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or /** * Patch for fix about ambiguous field - * * Ambiguous field error will appear * when query use join table and search with keyword. */ // Remove delimiter of column that appear from MYSQL query. $column = str_replace(['`', '"', '[', ']'], '', $column); - // check . in field name for protect don't add table again // but as far as I tested, this function has single field name only. if (strpos($column, '.') === false) { @@ -400,13 +397,13 @@ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or } // get table from query and add it. - $column = $q->from.'.'.$column; + $column = $q->from . '.' . $column; } // Add wrap cover table and field name. $column = $this->wrap($column); /* end fix */ - + if ($this->isCaseInsensitive()) { $sql = 'LOWER(' . $column . ') LIKE ?'; } From 18aeddbb091d27d84e4c855d59f0362d2da9f97b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 1 Dec 2016 10:54:52 +0800 Subject: [PATCH 264/322] Bump v6.22.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3eefbca5..be97d9b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.22.2 - 2016-12-01 +- Patch for ambiguous field error for relations issues. +- PR #849, credits to @ethaizone. + ### v6.22.1 - 2016-12-01 - Patch request class and use input array access to get the values. #868 - Fix Error 500 Illegal string offset issues: #857, #657, #395. From 1622a77ee93886377580f405d9aa641abbb7e9c9 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 6 Dec 2016 09:35:23 +0800 Subject: [PATCH 265/322] Fix adding of table prefix. Fix #871, #873 --- src/Engines/QueryBuilderEngine.php | 44 +++++++++++++++++------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 5833a419..83fe369d 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -374,41 +374,47 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) */ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or') { + $column = $this->addTablePrefix($query, $column); $column = $this->castColumn($column); $sql = $column . ' LIKE ?'; - /** - * Patch for fix about ambiguous field - * Ambiguous field error will appear - * when query use join table and search with keyword. - */ - // Remove delimiter of column that appear from MYSQL query. + if ($this->isCaseInsensitive()) { + $sql = 'LOWER(' . $column . ') LIKE ?'; + } + + $query->{$relation . '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) + { + // Remove column delimiters that appear from DB query. $column = str_replace(['`', '"', '[', ']'], '', $column); - // check . in field name for protect don't add table again - // but as far as I tested, this function has single field name only. + // Check if field does not have a table prefix if (strpos($column, '.') === false) { - // Alternative method to check - // instanceof \Illuminate\Database\Eloquent\Builder + // Alternative method to check instanceof \Illuminate\Database\Eloquent\Builder if (method_exists($query, 'getQuery')) { $q = $query->getQuery(); } else { $q = $query; } - // get table from query and add it. + // Get table from query and add it. $column = $q->from . '.' . $column; } + // Add wrap cover table and field name. $column = $this->wrap($column); - /* end fix */ - - if ($this->isCaseInsensitive()) { - $sql = 'LOWER(' . $column . ') LIKE ?'; - } - - $query->{$relation . 'WhereRaw'}($sql, [$this->prepareKeyword($keyword)]); + return $column; } /** @@ -417,7 +423,7 @@ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or * @param string $column * @return string */ - public function castColumn($column) + protected function castColumn($column) { $column = $this->wrap($column); if ($this->database === 'pgsql') { From 107b45fc79a214e1d7e4a9832e82f462b3ca661e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pinto?= Date: Tue, 6 Dec 2016 10:03:58 -0500 Subject: [PATCH 266/322] Custom soft delete column support Get the right column for soft delete via Laravel model method. --- src/Engines/QueryBuilderEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 5833a419..3b0117f4 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -103,7 +103,7 @@ public function count() // check for select soft deleted records if (! $this->withTrashed && $this->modelUseSoftDeletes()) { - $myQuery->whereNull($myQuery->getModel()->getTable() . '.deleted_at'); + $myQuery->whereNull($myQuery->getModel()->getQualifiedDeletedAtColumn()); } return $this->connection->table($this->connection->raw('(' . $myQuery->toSql() . ') count_row_table')) From 2027b6be1b77b877ab9dee5bb392712bcc741a10 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 7 Dec 2016 13:51:26 +0800 Subject: [PATCH 267/322] Bump v6.22.3 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be97d9b5..97c0a4b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ ##Change Log +### v6.22.3 - 2016-12-07 +- Fix adding of table prefix before casting the column. PR #876 +- Fix #871, #873 +- Custom soft delete column support. PR #878, credits to @Huracan88 +- Fix #875 + ### v6.22.2 - 2016-12-01 - Patch for ambiguous field error for relations issues. - PR #849, credits to @ethaizone. From 7d6dce269f58d0a9d8c3b49c84cf81b21f3cb43b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 7 Dec 2016 16:56:12 +0800 Subject: [PATCH 268/322] Fix double wrapping of column name. --- src/Engines/QueryBuilderEngine.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index dca12877..0f253266 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -395,9 +395,6 @@ protected function compileQuerySearch($query, $column, $keyword, $relation = 'or */ protected function addTablePrefix($query, $column) { - // Remove column delimiters that appear from DB query. - $column = str_replace(['`', '"', '[', ']'], '', $column); - // Check if field does not have a table prefix if (strpos($column, '.') === false) { // Alternative method to check instanceof \Illuminate\Database\Eloquent\Builder @@ -411,10 +408,7 @@ protected function addTablePrefix($query, $column) $column = $q->from . '.' . $column; } - // Add wrap cover table and field name. - $column = $this->wrap($column); - - return $column; + return $this->wrap($column); } /** @@ -425,7 +419,6 @@ protected function addTablePrefix($query, $column) */ protected function castColumn($column) { - $column = $this->wrap($column); if ($this->database === 'pgsql') { $column = 'CAST(' . $column . ' as TEXT)'; } elseif ($this->database === 'firebird') { From 3f3f353f010542e5360d1412bb846189ebc6d342 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 7 Dec 2016 16:59:09 +0800 Subject: [PATCH 269/322] Bump v6.22.5 :rocket: --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97c0a4b1..d566d80e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +### v6.22.4 - 2016-12-07 +- Fix double wrapping of column name. + ### v6.22.3 - 2016-12-07 - Fix adding of table prefix before casting the column. PR #876 - Fix #871, #873 From 17375774367c9833498df538d04ea9957f92f548 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 7 Dec 2016 19:28:33 +0800 Subject: [PATCH 270/322] Fix badges. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 655f2102..2e536d56 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,11 @@ [![Join the chat at https://gitter.im/yajra/laravel-datatables](https://badges.gitter.im/yajra/laravel-datatables.svg)](https://gitter.im/yajra/laravel-datatables?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Laravel 4.2|5.x](https://img.shields.io/badge/Laravel-4.2|5.x-orange.svg)](http://laravel.com) -[![Latest Stable Version](https://poser.pugx.org/yajra/laravel-datatables-oracle/v/stable)](https://packagist.org/packages/yajra/laravel-datatables-oracle) +[![Latest Stable Version](https://img.shields.io/packagist/v/yajra/laravel-datatables-oracle.svg)](https://packagist.org/packages/yajra/laravel-datatables-oracle) [![Build Status](https://travis-ci.org/yajra/laravel-datatables.svg?branch=master)](https://travis-ci.org/yajra/laravel-datatables) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/yajra/laravel-datatables/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/yajra/laravel-datatables/?branch=master) -[![Total Downloads](https://poser.pugx.org/yajra/laravel-datatables-oracle/downloads)](https://packagist.org/packages/yajra/laravel-datatables-oracle) -[![License](https://poser.pugx.org/yajra/laravel-datatables-oracle/license)](https://packagist.org/packages/yajra/laravel-datatables-oracle) +[![Total Downloads](https://img.shields.io/packagist/dt/yajra/laravel-datatables-oracle.svg)](https://packagist.org/packages/yajra/laravel-datatables-oracle) +[![License](https://img.shields.io/github/license/mashape/apistatus.svg)](https://packagist.org/packages/yajra/laravel-datatables-oracle) This package is created to handle [server-side](https://www.datatables.net/manual/server-side) works of [DataTables](http://datatables.net) jQuery Plugin via [AJAX option](https://datatables.net/reference/option/ajax) by using Eloquent ORM, Fluent Query Builder or Collection. From c6bb750d8cd901e8f641af06b7274ec274ff9b20 Mon Sep 17 00:00:00 2001 From: Elf Sundae Date: Thu, 22 Dec 2016 22:49:57 +0800 Subject: [PATCH 271/322] class name --- src/Datatables.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Datatables.php b/src/Datatables.php index c1be1f8d..e3a3cbd0 100644 --- a/src/Datatables.php +++ b/src/Datatables.php @@ -51,7 +51,7 @@ public function __construct(Request $request) */ public static function of($builder) { - $datatables = app(\Yajra\Datatables\Datatables::class); + $datatables = app(static::class); $datatables->builder = $builder; if ($builder instanceof QueryBuilder) { From 2e78769de894be48effc1d2e8bca9c8a1ca6476f Mon Sep 17 00:00:00 2001 From: Elf Sundae Date: Thu, 22 Dec 2016 22:55:29 +0800 Subject: [PATCH 272/322] Fix singleton --- src/DatatablesServiceProvider.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/DatatablesServiceProvider.php b/src/DatatablesServiceProvider.php index 02de59cb..e4f9cac8 100644 --- a/src/DatatablesServiceProvider.php +++ b/src/DatatablesServiceProvider.php @@ -83,6 +83,8 @@ public function register() return new Datatables($this->app->make(Request::class)); }); + $this->app->alias('datatables', Datatables::class); + $this->app->singleton('datatables.fractal', function () { $fractal = new Manager; $config = $this->app['config']; From 520e7ecebc1d3e4cbe3065215d82b62bac8c4097 Mon Sep 17 00:00:00 2001 From: Dinesh Rabara Date: Sat, 31 Dec 2016 11:43:37 +0530 Subject: [PATCH 273/322] solve print header issue when two row are same value --- src/resources/views/print.blade.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/resources/views/print.blade.php b/src/resources/views/print.blade.php index d9767b7d..1960a7d3 100644 --- a/src/resources/views/print.blade.php +++ b/src/resources/views/print.blade.php @@ -14,12 +14,14 @@
+ @php ($flag = true) @foreach($data as $row) - @if ($row == reset($data)) + @if ($row == reset($data) && $flag) @foreach($row as $key => $value) @endforeach + @php ($flag = false) @endif From 8dff014e8c79658123d9e4118c4a2f168b0dd688 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 4 Jan 2017 09:54:06 +0800 Subject: [PATCH 274/322] Bump v6.22.6 --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d566d80e..9d3aaa74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,9 +8,15 @@ ##Change Log -### v6.22.4 - 2016-12-07 +### v6.22.6 - 2017-01-04 +- Fix print header issue when two row are same value. +- PR #913, credits to @dineshrabara. + +### v6.22.5 - 2016-12-07 - Fix double wrapping of column name. +### v6.22.4 - Skipped (Sorry!) + ### v6.22.3 - 2016-12-07 - Fix adding of table prefix before casting the column. PR #876 - Fix #871, #873 From 6bb9595bdcc68bfe3dd5e995e6fd155caa290e1d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 4 Jan 2017 09:57:16 +0800 Subject: [PATCH 275/322] Update license to 2017. --- LICENSE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE.md b/LICENSE.md index 600ba57e..8cfbdf84 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ (The MIT License) -Copyright (c) 2013-2016 Arjay Angeles +Copyright (c) 2013-2017 Arjay Angeles Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the From 8408b5c13ddc4ae66686ebc2a2f51750cb0108ed Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 4 Jan 2017 10:12:39 +0800 Subject: [PATCH 276/322] Bump v6.22.7 :rocket: --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9d3aaa74..9bf64bb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ ##Change Log +### v6.22.7 - 2017-01-04 +- Add datatables alias to fix singleton. PR #903, credits to @ElfSundae +- Use static class name instead FQCN. PR #902, credits to @ElfSundae +- Update license to 2017. + ### v6.22.6 - 2017-01-04 - Fix print header issue when two row are same value. - PR #913, credits to @dineshrabara. From 94f834916f354bd8219b80c72caa6f6942b27df8 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 5 Jan 2017 11:02:41 +0800 Subject: [PATCH 277/322] Add code of conduct. --- CONDUCT.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 CONDUCT.md diff --git a/CONDUCT.md b/CONDUCT.md new file mode 100644 index 00000000..6ff94ca3 --- /dev/null +++ b/CONDUCT.md @@ -0,0 +1,22 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery +* Personal attacks +* Trolling or insulting/derogatory comments +* Public or private harassment +* Publishing other's private information, such as physical or electronic addresses, without explicit permission +* Other unethical or unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. + +This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community in a direct capacity. Personal views, beliefs and values of individuals do not necessarily reflect those of the organisation or affiliated individuals and organisations. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. + +This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) From e94ff6009f7b5d0d83d80881c4f3ed057cca2668 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 5 Jan 2017 11:04:34 +0800 Subject: [PATCH 278/322] Update repo link. --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 5589f354..89e4aa5c 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -2,7 +2,7 @@ Contributions are **welcome** and will be fully **credited**. -We accept contributions via Pull Requests on [Github](https://github.com/yajra/laravel-datatables-oracle). +We accept contributions via Pull Requests on [Github](https://github.com/yajra/laravel-datatables). ## Pull Requests From 80526f0f465942e5655d68672db4730cc79d93ac Mon Sep 17 00:00:00 2001 From: WhaleShark Date: Mon, 16 Jan 2017 15:02:11 +0300 Subject: [PATCH 279/322] Support for UTF8 characters when creating wildcard query. Implement PR #926 --- src/Engines/BaseEngine.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index d2af29d3..c1ffcbf2 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -247,12 +247,14 @@ public function isWildcard() public function wildcardLikeString($str, $lowercase = true) { $wild = '%'; - $length = Str::length($str); - if ($length) { - for ($i = 0; $i < $length; $i++) { - $wild .= $str[$i] . '%'; + $chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY); + + if (count($chars) > 0) { + foreach ($chars as $char) { + $wild .= $char . '%'; } } + if ($lowercase) { $wild = Str::lower($wild); } From 5d8ba13925321aea233ecaa56017ae8b19d48343 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 19 Jan 2017 09:45:36 +0800 Subject: [PATCH 280/322] Bump v6.22.8 :rocket:. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bf64bb9..63cb2d81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.22.8 - 2017-01-19 +- Support for UTF8 characters when creating wildcard query. +- PR #926, credits to @Rhincodon. + ### v6.22.7 - 2017-01-04 - Add datatables alias to fix singleton. PR #903, credits to @ElfSundae - Use static class name instead FQCN. PR #902, credits to @ElfSundae From 06e1c6dbfa0a207c5b6338c5f4b4091c737141d2 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 20 Jan 2017 19:41:17 +0800 Subject: [PATCH 281/322] Do not append table name if instance is expression. Fix #927. --- src/Engines/QueryBuilderEngine.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 0f253266..8091fa83 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Relations\HasOneOrMany; use Illuminate\Database\Eloquent\Relations\MorphToMany; use Illuminate\Database\Query\Builder; +use Illuminate\Database\Query\Expression; use Illuminate\Support\Str; use Yajra\Datatables\Helper; use Yajra\Datatables\Request; @@ -404,8 +405,10 @@ protected function addTablePrefix($query, $column) $q = $query; } - // Get table from query and add it. - $column = $q->from . '.' . $column; + if (! $q->from instanceof Expression) { + // Get table from query and add it. + $column = $q->from . '.' . $column; + } } return $this->wrap($column); From 82595924b679ffdcd5420144bdee3001e806ce64 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 20 Jan 2017 19:58:02 +0800 Subject: [PATCH 282/322] Bump v6.22.9 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63cb2d81..ca673f52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.22.9 - 2017-01-20 +- Do not append table name if instance is expression. #933 +- Fix #927 and possible fix for #873. + ### v6.22.8 - 2017-01-19 - Support for UTF8 characters when creating wildcard query. - PR #926, credits to @Rhincodon. From 841ee71f9e2536f4558ebd7d721dd46163664a8f Mon Sep 17 00:00:00 2001 From: Alfa Adhitya Date: Fri, 20 Jan 2017 21:06:48 +0700 Subject: [PATCH 283/322] fix regex query for pgsql --- src/Engines/QueryBuilderEngine.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 8091fa83..4bd8d3d5 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -605,6 +605,9 @@ protected function regexColumnSearch($column, $keyword) if ($this->isOracleSql()) { $sql = ! $this->isCaseInsensitive() ? 'REGEXP_LIKE( ' . $column . ' , ? )' : 'REGEXP_LIKE( LOWER(' . $column . ') , ?, \'i\' )'; $this->query->whereRaw($sql, [$keyword]); + } elseif ($this->database == 'pgsql') { + $sql = ! $this->isCaseInsensitive() ? $column . ' ~ ?' : $column . ' ~* ? '; + $this->query->whereRaw($sql, [$keyword]); } else { $sql = ! $this->isCaseInsensitive() ? $column . ' REGEXP ?' : 'LOWER(' . $column . ') REGEXP ?'; $this->query->whereRaw($sql, [Str::lower($keyword)]); From ea5bf0dc0e7e171c7d96fb6bd09d2131d6e07e7f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 21 Jan 2017 14:14:17 +0800 Subject: [PATCH 284/322] Add support for onlyTrashed model scope. Fix #928 Move withTrashed method to Eloquent engine. --- src/Engines/BaseEngine.php | 21 -------- src/Engines/EloquentEngine.php | 85 ++++++++++++++++++++++++++++++ src/Engines/QueryBuilderEngine.php | 19 ------- 3 files changed, 85 insertions(+), 40 deletions(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index c1ffcbf2..def107e5 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -104,14 +104,6 @@ abstract class BaseEngine implements DataTableEngineContract * @var bool */ protected $autoFilter = true; - - /** - * Select trashed records in count function for models with soft deletes trait. - * By default we do not select soft deleted records - * - * @var bool - */ - protected $withTrashed = false; /** * Callback to override global search. @@ -403,19 +395,6 @@ public function escapeColumns($columns = '*') return $this; } - - /** - * Change withTrashed flag value. - * - * @param bool $withTrashed - * @return $this - */ - public function withTrashed($withTrashed = true) - { - $this->withTrashed = $withTrashed; - - return $this; - } /** * Allows previous API calls where the methods were snake_case. diff --git a/src/Engines/EloquentEngine.php b/src/Engines/EloquentEngine.php index abcdaa85..dde4ab64 100644 --- a/src/Engines/EloquentEngine.php +++ b/src/Engines/EloquentEngine.php @@ -3,6 +3,7 @@ namespace Yajra\Datatables\Engines; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Support\Str; use Yajra\Datatables\Request; /** @@ -13,6 +14,22 @@ */ class EloquentEngine extends QueryBuilderEngine { + /** + * Select trashed records in count function for models with soft deletes trait. + * By default we do not select soft deleted records + * + * @var bool + */ + protected $withTrashed = false; + + /** + * Select only trashed records in count function for models with soft deletes trait. + * By default we do not select soft deleted records + * + * @var bool + */ + protected $onlyTrashed = false; + /** * @param mixed $model * @param \Yajra\Datatables\Request $request @@ -25,4 +42,72 @@ public function __construct($model, Request $request) $this->query = $builder; $this->query_type = 'eloquent'; } + + /** + * 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}")); + } + + // check for select soft deleted records + if (! $this->withTrashed && ! $this->onlyTrashed && $this->modelUseSoftDeletes()) { + $myQuery->whereNull($myQuery->getModel()->getQualifiedDeletedAtColumn()); + } + + if ($this->onlyTrashed && $this->modelUseSoftDeletes()) { + $myQuery->whereNotNull($myQuery->getModel()->getQualifiedDeletedAtColumn()); + } + + return $this->connection->table($this->connection->raw('(' . $myQuery->toSql() . ') count_row_table')) + ->setBindings($myQuery->getBindings())->count(); + } + + /** + * Check if model use SoftDeletes trait + * + * @return boolean + */ + protected function modelUseSoftDeletes() + { + if ($this->query_type == 'eloquent') { + return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this->query->getModel())); + } + + return false; + } + + /** + * Change withTrashed flag value. + * + * @param bool $withTrashed + * @return $this + */ + public function withTrashed($withTrashed = true) + { + $this->withTrashed = $withTrashed; + + return $this; + } + + /** + * Change onlyTrashed flag value. + * + * @param bool $onlyTrashed + * @return $this + */ + public function onlyTrashed($onlyTrashed = true) + { + $this->onlyTrashed = $onlyTrashed; + + return $this; + } } diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 8091fa83..fa75e852 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -102,11 +102,6 @@ public function count() $myQuery->select($this->connection->raw("'1' as {$row_count}")); } - // check for select soft deleted records - if (! $this->withTrashed && $this->modelUseSoftDeletes()) { - $myQuery->whereNull($myQuery->getModel()->getQualifiedDeletedAtColumn()); - } - return $this->connection->table($this->connection->raw('(' . $myQuery->toSql() . ') count_row_table')) ->setBindings($myQuery->getBindings())->count(); } @@ -122,20 +117,6 @@ protected function wrap($column) return $this->connection->getQueryGrammar()->wrap($column); } - /** - * Check if model use SoftDeletes trait - * - * @return boolean - */ - private function modelUseSoftDeletes() - { - if ($this->query_type == 'eloquent') { - return in_array('Illuminate\Database\Eloquent\SoftDeletes', class_uses($this->query->getModel())); - } - - return false; - } - /** * Perform global search. * From a7029901adf79a4bf1ab463e63d83d8b7408fef8 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 21 Jan 2017 14:23:59 +0800 Subject: [PATCH 285/322] Bump v6.23.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca673f52..2b4129fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.23.0 - 2017-01-21 +- Add support for onlyTrashed model scope. Fix #928 +- Move withTrashed method to Eloquent engine. + ### v6.22.9 - 2017-01-20 - Do not append table name if instance is expression. #933 - Fix #927 and possible fix for #873. From 1840d10836dfc08d6ecb7260e1ede9ed98593ac9 Mon Sep 17 00:00:00 2001 From: Ozan Kurt Date: Mon, 23 Jan 2017 21:10:07 +0100 Subject: [PATCH 286/322] Datatables Pipeline Plugin support (Basic) It allows me to use `->pipeline('url/to/ajax', 5)`. --- src/Html/Builder.php | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 3279a5a4..c8da34bc 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -160,12 +160,30 @@ public function parameterize($attributes = []) { $parameters = (new Parameters($attributes))->toArray(); + $values = []; + $replacements = []; + foreach($parameters as $key => &$value){ + if (!is_array($value)) { + if (strpos($value, '$.') === 0) + { + // Store function string. + $values[] = $value; + // Replace function string in $foo with a 'unique' special key. + $value = '%' . $key . '%'; + // Later on, we'll look for the value, and replace it. + $replacements[] = '"' . $value . '"'; + } + } + } + list($ajaxDataFunction, $parameters) = $this->encodeAjaxDataFunction($parameters); list($columnFunctions, $parameters) = $this->encodeColumnFunctions($parameters); list($callbackFunctions, $parameters) = $this->encodeCallbackFunctions($parameters); $json = json_encode($parameters); + $json = str_replace($replacements, $values, $json); + $json = $this->decodeAjaxDataFunction($ajaxDataFunction, $json); $json = $this->decodeColumnFunctions($columnFunctions, $json); $json = $this->decodeCallbackFunctions($callbackFunctions, $json); @@ -511,6 +529,20 @@ public function addIndex(array $attributes = []) return $this; } + /** + * Setup ajax parameter for datatables pipeline plugin + * + * @param string $url + * @param string $pages + * @return $this + */ + public function pipeline($url, $pages) + { + $this->ajax = "$.fn.dataTable.pipeline({ url: '{$url}', pages: {$pages} })"; + + return $this; + } + /** * Setup ajax parameter * From 32a76ed14e96cc7358efd2774e5aac53075de2ec Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 24 Jan 2017 10:41:08 +0800 Subject: [PATCH 287/322] Add missing period. --- src/Html/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index c8da34bc..15f76d98 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -530,7 +530,7 @@ public function addIndex(array $attributes = []) } /** - * Setup ajax parameter for datatables pipeline plugin + * Setup ajax parameter for datatables pipeline plugin. * * @param string $url * @param string $pages From f57d99060ba2ca19f872bb194f0384422ef5b2fb Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 24 Jan 2017 10:42:22 +0800 Subject: [PATCH 288/322] Bump v6.24.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b4129fd..fc281eec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.24.0 - 2017-01-24 +- Datatables Pipeline Plugin support (Basic). +- PR #938, credits to @OzanKurt. + ### v6.23.0 - 2017-01-21 - Add support for onlyTrashed model scope. Fix #928 - Move withTrashed method to Eloquent engine. From 593a9205c7d9816d2d8b639ca08000ae5c5f378c Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 24 Jan 2017 10:46:52 +0800 Subject: [PATCH 289/322] Bump v6.24.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc281eec..5979c49a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.24.1 - 2017-01-24 +- Fix regex query for pgsql. +- PR #934, credits to @alfa6661. + ### v6.24.0 - 2017-01-24 - Datatables Pipeline Plugin support (Basic). - PR #938, credits to @OzanKurt. From 6c18205a5ecf868a367e87ea50e863e3a4ba5775 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 26 Jan 2017 08:52:35 +0800 Subject: [PATCH 290/322] Lock v6.x to support Laravel 5.0 - 5.3 only. Fix #942 - v7 should be used. --- composer.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index da74cba2..03c70337 100644 --- a/composer.json +++ b/composer.json @@ -11,13 +11,13 @@ ], "require": { "php": ">=5.5.9", - "illuminate/support": "~5.0", - "illuminate/database": "~5.0", - "illuminate/view": "~5.0", - "illuminate/http": "~5.0", - "illuminate/filesystem": "~5.0", + "illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*", + "illuminate/database": "5.0.*|5.1.*|5.2.*|5.3.*", + "illuminate/view": "5.0.*|5.1.*|5.2.*|5.3.*", + "illuminate/http": "5.0.*|5.1.*|5.2.*|5.3.*", + "illuminate/filesystem": "5.0.*|5.1.*|5.2.*|5.3.*", "league/fractal": "~0.14", - "laravelcollective/html": "~5.0", + "laravelcollective/html": "5.0.*|5.1.*|5.2.*|5.3.*", "maatwebsite/excel": "^2.0", "dompdf/dompdf": "^0.7" }, From af5ec905e0716e7cf6957dfcb0e63d540d731e52 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 26 Jan 2017 10:09:52 +0800 Subject: [PATCH 291/322] Bump v6.24.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5979c49a..8239bb81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.24.2 - 2017-01-26 +- Lock v6.x to support Laravel 5.0 - 5.3 only. +- Fix #942. + ### v6.24.1 - 2017-01-24 - Fix regex query for pgsql. - PR #934, credits to @alfa6661. From 4030d6e14f14c980ac753b3f1a419288870daaf4 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Mon, 6 Feb 2017 16:21:57 +0800 Subject: [PATCH 292/322] Add bindings from relations. Implementation from PR #962. --- src/Engines/QueryBuilderEngine.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Engines/QueryBuilderEngine.php b/src/Engines/QueryBuilderEngine.php index 373837ea..ebcb4cd2 100644 --- a/src/Engines/QueryBuilderEngine.php +++ b/src/Engines/QueryBuilderEngine.php @@ -324,10 +324,10 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) */ foreach ($relationChunk as $relation => $chunk) { // Prepare variables - $builder = $chunk['builder']; - $relationType = $chunk['relationType']; - $query = $chunk['query']; - $builder = "({$builder->toSql()}) >= 1"; + $builder = $chunk['builder']; + $query = $chunk['query']; + $bindings = $builder->getBindings(); + $sql = "({$builder->toSql()}) >= 1"; // Check if it last relation we will use orWhereRaw if ($lastRelation == $relation) { @@ -338,11 +338,7 @@ protected function compileRelationSearch($query, $relation, $column, $keyword) $relationMethod = "whereRaw"; } - if ($relationType instanceof MorphToMany) { - $query->{$relationMethod}($builder, [$relationType->getMorphClass(), $this->prepareKeyword($keyword)]); - } else { - $query->{$relationMethod}($builder, [$this->prepareKeyword($keyword)]); - } + $query->{$relationMethod}($sql, $bindings); } } From 744086996ae8f9c786872f16679b1920c804bebd Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 8 Feb 2017 09:27:18 +0800 Subject: [PATCH 293/322] Bump v6.24.3 :rocket: --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8239bb81..ede24425 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.24.3 - 2017-02-08 +- Add bindings from relations. #981 +- Implementation from PR #962 to fix #960. + ### v6.24.2 - 2017-01-26 - Lock v6.x to support Laravel 5.0 - 5.3 only. - Fix #942. From eb41c337e1dfed61cfbbcc2d7c9f85ae2440d2c1 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 8 Feb 2017 09:21:56 +0800 Subject: [PATCH 294/322] Add SORT_FLAG_CASE when ordering collection. Fix #945. --- src/Engines/CollectionEngine.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 98e2e859..f9869d55 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -118,14 +118,18 @@ public function ordering() } foreach ($this->request->orderableColumns() as $orderable) { - $column = $this->getColumnName($orderable['column']); - $this->collection = $this->collection->sortBy( - function ($row) use ($column) { - $data = $this->serialize($row); + $column = $this->getColumnName($orderable['column']); - return Arr::get($data, $column); - } - ); + $options = SORT_REGULAR; + if ($this->isCaseInsensitive()) { + $options = SORT_REGULAR | SORT_FLAG_CASE; + } + + $this->collection = $this->collection->sortBy(function ($row) use ($column) { + $data = $this->serialize($row); + + return Arr::get($data, $column); + }, $options); if ($orderable['direction'] == 'desc') { $this->collection = $this->collection->reverse(); From a9dcd2462466b5b32326fbce24038594989772e4 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 9 Feb 2017 13:09:21 +0800 Subject: [PATCH 295/322] Use SORT_NATURAL instead of SORT_REGULAR. --- src/Engines/CollectionEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index f9869d55..57515332 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -120,9 +120,9 @@ public function ordering() foreach ($this->request->orderableColumns() as $orderable) { $column = $this->getColumnName($orderable['column']); - $options = SORT_REGULAR; + $options = SORT_NATURAL; if ($this->isCaseInsensitive()) { - $options = SORT_REGULAR | SORT_FLAG_CASE; + $options = SORT_NATURAL | SORT_FLAG_CASE; } $this->collection = $this->collection->sortBy(function ($row) use ($column) { From 3b27e3ee11253d003b03155d3df403c69bd6f4a4 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 9 Feb 2017 13:15:31 +0800 Subject: [PATCH 296/322] Bump v6.24.4 :rocket: --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ede24425..59730c4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.24.4 - 2017-02-09 +- Fix collection case insensitive ordering. +- Fix [#945](https://github.com/yajra/laravel-datatables/issues/945). + ### v6.24.3 - 2017-02-08 - Add bindings from relations. #981 - Implementation from PR #962 to fix #960. From aace263324cebcb78fd59048c1d27000f3514389 Mon Sep 17 00:00:00 2001 From: Master Bratac Date: Tue, 21 Feb 2017 21:30:17 -0700 Subject: [PATCH 297/322] bump to 0.8 dompdf for compatability with barryvdh/dompdf --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 03c70337..7f284c8a 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "league/fractal": "~0.14", "laravelcollective/html": "5.0.*|5.1.*|5.2.*|5.3.*", "maatwebsite/excel": "^2.0", - "dompdf/dompdf": "^0.7" + "dompdf/dompdf": "^0.8" }, "require-dev": { "mockery/mockery": "~0.9", From f97b3e99c4ec91d60194c78a6ec88983f28139d5 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 23 Feb 2017 11:15:23 +0800 Subject: [PATCH 298/322] Bump v6.25.0 :rocket: --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59730c4a..fbaac5e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.25.0 - 2017-02-23 +- Add support ordering when search in nested relations. #850 +- Credits to @ethaizone. + ### v6.24.4 - 2017-02-09 - Fix collection case insensitive ordering. - Fix [#945](https://github.com/yajra/laravel-datatables/issues/945). From 5f48b9fd682e189ce7435072f4e036268420739b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 3 Mar 2017 09:53:09 +0800 Subject: [PATCH 299/322] Add branch alias. --- composer.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/composer.json b/composer.json index 03c70337..021b654e 100644 --- a/composer.json +++ b/composer.json @@ -33,5 +33,10 @@ "Yajra\\Datatables\\": "src/" } }, + "extra": { + "branch-alias": { + "dev-master": "6.0-dev" + } + }, "minimum-stability": "stable" } From c4da1e325f9898fd8c1797c69511301cccef8a04 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 3 Mar 2017 11:02:27 +0800 Subject: [PATCH 300/322] Remove dompdf dependency :exclamation:. Let developers decide on the version they want to use. --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8b24dddb..33c281b5 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,7 @@ "illuminate/filesystem": "5.0.*|5.1.*|5.2.*|5.3.*", "league/fractal": "~0.14", "laravelcollective/html": "5.0.*|5.1.*|5.2.*|5.3.*", - "maatwebsite/excel": "^2.0", - "dompdf/dompdf": "^0.8" + "maatwebsite/excel": "^2.0" }, "require-dev": { "mockery/mockery": "~0.9", From 613598f145e6f5fa277a4dfa2b65e7ac0440f61b Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 3 Mar 2017 11:50:27 +0800 Subject: [PATCH 301/322] Bump v6.26.0 :rocket: :exclamation:. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fbaac5e7..f4554433 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.26.0 - 2017-03-03 +- Remove dompdf dependency and let the developers decide on which version they want to use. +> Note: This is possible breaking change for some users but needed to move forward. See https://github.com/yajra/laravel-datatables/pull/1026 for details. Thanks! + ### v6.25.0 - 2017-02-23 - Add support ordering when search in nested relations. #850 - Credits to @ethaizone. From 5b8f51bdad6cf13889419abe1330f63fbf5dbcbc Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 18 Mar 2017 09:57:37 +0800 Subject: [PATCH 302/322] Add a fluent way to send route variables to DataTable service class. Fix #1069. --- src/Services/DataTable.php | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 3d5a53de..5a3e8e85 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -72,6 +72,13 @@ abstract class DataTable implements DataTableContract, DataTableButtonsContract */ protected $filename = ''; + /** + * Custom attributes set on the class. + * + * @var array + */ + protected $attributes = []; + /** * DataTable constructor. * @@ -361,6 +368,39 @@ public function addScope(DataTableScopeContract $scope) return $this; } + /** + * Set a custom class attribute. + * + * @param mixed $key + * @param mixed|null $value + * @return $this + */ + public function with($key, $value = null) + { + if (is_array($key)) { + $this->attributes = array_merge($this->attributes, $key); + } else { + $this->attributes[$key] = $value; + } + + return $this; + } + + /** + * Dynamically retrieve the value of an attribute. + * + * @param string $key + * @return mixed|null + */ + public function __get($key) + { + if (array_key_exists($key, $this->attributes)) { + return $this->attributes[$key]; + } + + return null; + } + /** * Apply query scopes. * From 42c948a965f2da12b8455d2798f3dcffc5efb04a Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 18 Mar 2017 09:59:22 +0800 Subject: [PATCH 303/322] Fix doc blocks. --- src/Datatables.php | 2 +- src/Services/DataTable.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Datatables.php b/src/Datatables.php index e3a3cbd0..aa389281 100644 --- a/src/Datatables.php +++ b/src/Datatables.php @@ -127,7 +127,7 @@ public function getHtmlBuilder() /** * Get request object. * - * @return \Yajra\Datatables\Request|static + * @return \Yajra\Datatables\Request */ public function getRequest() { diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 5a3e8e85..220a50d6 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -97,7 +97,7 @@ public function __construct(Datatables $datatables, Factory $viewFactory) * @param string $view * @param array $data * @param array $mergeData - * @return \Illuminate\Http\JsonResponse|\Illuminate\View\View + * @return \Illuminate\Contracts\View\View|\Illuminate\Http\JsonResponse|\Illuminate\View\View */ public function render($view, $data = [], $mergeData = []) { @@ -163,7 +163,7 @@ protected function printColumns() /** * Get columns definition from html builder. * - * @return array + * @return \Illuminate\Support\Collection */ protected function getColumnsFromBuilder() { From 8fae58aacac3c86880c29251f9795c7fc846a3ae Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Sat, 18 Mar 2017 10:06:20 +0800 Subject: [PATCH 304/322] Bump v6.27.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4554433..a03d8efe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.27.0 - 2017-03-08 +- Add a fluent way to send route variables to DataTable service class. PR #1071. +- Fix #1069. + ### v6.26.0 - 2017-03-03 - Remove dompdf dependency and let the developers decide on which version they want to use. > Note: This is possible breaking change for some users but needed to move forward. See https://github.com/yajra/laravel-datatables/pull/1026 for details. Thanks! From 3f86440de7624817f600d127f9f73401eb25648a Mon Sep 17 00:00:00 2001 From: Julian Date: Sat, 18 Mar 2017 14:13:13 +0700 Subject: [PATCH 305/322] Return url from A balise in decodeContent function --- src/Transformers/DataTransformer.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index 0ca22856..dd6dc230 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -64,6 +64,11 @@ protected function buildColumnByCollection(array $row, Collection $columns, $ty */ protected function decodeContent($data) { + preg_match_all('/]+href=([\'"])(.+?)\1[^>]*>/i', $data, $result); + if ($result[2] && $result[2][0]) { + return $result[2][0]; + } + try { $decoded = html_entity_decode(strip_tags($data), ENT_QUOTES, 'UTF-8'); From 9dbfdfc3bc7addfede3f356c986fe92705c57b98 Mon Sep 17 00:00:00 2001 From: Julian Date: Sat, 18 Mar 2017 14:16:05 +0700 Subject: [PATCH 306/322] transform-urls-into-Excel-hyperlink --- src/Services/DataTable.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 220a50d6..7fd1becc 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -246,6 +246,20 @@ protected function buildExcelFile() return $excel->create($this->getFilename(), function (LaravelExcelWriter $excel) { $excel->sheet('exported-data', function (LaravelExcelWorksheet $sheet) { $sheet->fromArray($this->getDataForExport()); + $highestColumn = $sheet->getHighestColumn(); + + for($row = 1; $row <= sizeof($sheet->data); $row++) { + foreach (range('A', $highestColumn) as $column) { + $cell = $sheet->getCell($column.$row); + $cellValue = $cell->getValue(); + + if(filter_var($cellValue, FILTER_VALIDATE_URL)) { + $cell->setValue($cellValue) + ->getHyperlink() + ->setUrl($cellValue); + } + } + } }); }); } From b9b4b83cb150021dd67656252284bd76dd92fe26 Mon Sep 17 00:00:00 2001 From: Julian Date: Mon, 3 Apr 2017 19:13:55 +0200 Subject: [PATCH 307/322] Use balise a text as value if not html in excel file --- src/Services/DataTable.php | 15 +++++++++++---- src/Transformers/DataTransformer.php | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Services/DataTable.php b/src/Services/DataTable.php index 7fd1becc..4fac8758 100644 --- a/src/Services/DataTable.php +++ b/src/Services/DataTable.php @@ -12,6 +12,8 @@ use Yajra\Datatables\Datatables; use Yajra\Datatables\Transformers\DataTransformer; +use SimpleXMLElement; + /** * Class DataTable. * @@ -253,10 +255,15 @@ protected function buildExcelFile() $cell = $sheet->getCell($column.$row); $cellValue = $cell->getValue(); - if(filter_var($cellValue, FILTER_VALIDATE_URL)) { - $cell->setValue($cellValue) - ->getHyperlink() - ->setUrl($cellValue); + if($cellValue != strip_tags($cellValue)) { + $tag = new SimpleXMLElement($cellValue); + + if($tag['href'] && filter_var($tag['href'], FILTER_VALIDATE_URL)) { + $value = $tag->__toString() ? $tag->__toString() : $tag['href']; + $cell->setValue($value) + ->getHyperlink() + ->setUrl($tag['href']); + } } } } diff --git a/src/Transformers/DataTransformer.php b/src/Transformers/DataTransformer.php index dd6dc230..67dddc62 100644 --- a/src/Transformers/DataTransformer.php +++ b/src/Transformers/DataTransformer.php @@ -66,7 +66,7 @@ protected function decodeContent($data) { preg_match_all('/]+href=([\'"])(.+?)\1[^>]*>/i', $data, $result); if ($result[2] && $result[2][0]) { - return $result[2][0]; + return $data; } try { From 3ffac86b3ce82b7e4e5539958697f96c43247e67 Mon Sep 17 00:00:00 2001 From: Karmendra Suthar Date: Sat, 15 Apr 2017 13:24:16 +0530 Subject: [PATCH 308/322] Formatting the attributes for Editor buttons. --- src/Html/Builder.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 15f76d98..62c05ede 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -188,6 +188,12 @@ public function parameterize($attributes = []) $json = $this->decodeColumnFunctions($columnFunctions, $json); $json = $this->decodeCallbackFunctions($callbackFunctions, $json); + /* + * Formatting the attributes for Editor buttons. json_encode wraps the key and value both in double qoutes, + * remove the additional quotes around "editor" string + */ + $json = preg_replace('/"(editor)"/','$1',$json); + return $json; } From 5658edba36c5975eaeea8a4313eacbe649182fb2 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 19 Apr 2017 09:44:36 +0800 Subject: [PATCH 309/322] Bump v6.28.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a03d8efe..b176bf16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ ##Change Log +### v6.28.0 - 2017-04-19 +- Display url and A balise as hyperlink in excel export. +- PR #1074, credits to @julianfox. + ### v6.27.0 - 2017-03-08 - Add a fluent way to send route variables to DataTable service class. PR #1071. - Fix #1069. From 1adcd39c2e4d689e63993574b8ca58eca04b9161 Mon Sep 17 00:00:00 2001 From: Karmendra Suthar Date: Sat, 22 Apr 2017 20:59:33 +0530 Subject: [PATCH 310/322] Editor Button variables are formatted in the generated javascript --- src/Html/Builder.php | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 62c05ede..2267a6e3 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -179,6 +179,7 @@ public function parameterize($attributes = []) list($ajaxDataFunction, $parameters) = $this->encodeAjaxDataFunction($parameters); list($columnFunctions, $parameters) = $this->encodeColumnFunctions($parameters); list($callbackFunctions, $parameters) = $this->encodeCallbackFunctions($parameters); + list($editorButtons, $parameters) = $this->encodeEditorButtons($parameters); $json = json_encode($parameters); @@ -187,12 +188,7 @@ public function parameterize($attributes = []) $json = $this->decodeAjaxDataFunction($ajaxDataFunction, $json); $json = $this->decodeColumnFunctions($columnFunctions, $json); $json = $this->decodeCallbackFunctions($callbackFunctions, $json); - - /* - * Formatting the attributes for Editor buttons. json_encode wraps the key and value both in double qoutes, - * remove the additional quotes around "editor" string - */ - $json = preg_replace('/"(editor)"/','$1',$json); + $json = $this->decodeEditorButtons($editorButtons, $json); return $json; } @@ -255,6 +251,25 @@ protected function encodeCallbackFunctions(array $parameters) return [$callbackFunctions, $parameters]; } + + /** + * Encode DataTables editor buttons. + * + * @param array $parameters + * @return array + */ + protected function encodeEditorButtons(array $parameters) + { + $editorButtons = []; + foreach ($parameters['buttons'] as $i => $button) { + if (isset($button['editor'])) { + $editorButtons[$i] = $this->compileCallback($button['editor']); + $parameters['buttons'][$i]['editor'] = "#editor_button.{$i}#"; + } + } + + return [$editorButtons, $parameters]; + } /** * Compile DataTable callback value. @@ -316,6 +331,22 @@ protected function decodeCallbackFunctions(array $callbackFunctions, $json) return $json; } + + /** + * Decode DataTables Editor buttons. + * + * @param array $editorButtons + * @param string $json + * @return string + */ + protected function decodeEditorButtons(array $editorButtons, $json) + { + foreach ($editorButtons as $i => $function) { + $json = str_replace("\"#editor_button.{$i}#\"", $function, $json); + } + + return $json; + } /** * Get javascript template to use. From 7d8d171ba62f20cec127a6e1b473bfc0eee587c2 Mon Sep 17 00:00:00 2001 From: Karmendra Suthar Date: Sat, 22 Apr 2017 22:51:21 +0530 Subject: [PATCH 311/322] Fixed a bug, when buttons parameter are not defined --- src/Html/Builder.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Html/Builder.php b/src/Html/Builder.php index 2267a6e3..cc4833cf 100644 --- a/src/Html/Builder.php +++ b/src/Html/Builder.php @@ -261,13 +261,16 @@ protected function encodeCallbackFunctions(array $parameters) protected function encodeEditorButtons(array $parameters) { $editorButtons = []; - foreach ($parameters['buttons'] as $i => $button) { - if (isset($button['editor'])) { - $editorButtons[$i] = $this->compileCallback($button['editor']); - $parameters['buttons'][$i]['editor'] = "#editor_button.{$i}#"; + if (isset($parameters['buttons'])) { + foreach ($parameters['buttons'] as $i => $button) { + if (isset($button['editor'])) { + $editorButtons[$i] = $this->compileCallback($button['editor']); + $parameters['buttons'][$i]['editor'] = "#editor_button.{$i}#"; + } } } + return [$editorButtons, $parameters]; } From c4ee9651b3d67d7175c48cb29c05a5c588badc17 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 5 May 2017 14:58:45 +0800 Subject: [PATCH 312/322] Bump v6.28.1 :rocket:. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b176bf16..6cb724b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +### v6.28.1 - 2017-05-05 +- Fixed: Formatting the attributes for Editor buttons. #1105, credits to @karmendra. + ### v6.28.0 - 2017-04-19 - Display url and A balise as hyperlink in excel export. - PR #1074, credits to @julianfox. From c33f5f4fcd53a3a2da31c7ad68b4a5ab2b9f6dff Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 31 May 2017 18:16:08 +0800 Subject: [PATCH 313/322] Add config for setting the default JsonResponse header and options. Fix #1034 --- src/Engines/BaseEngine.php | 2 +- src/config/config.php | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Engines/BaseEngine.php b/src/Engines/BaseEngine.php index def107e5..b4dda368 100644 --- a/src/Engines/BaseEngine.php +++ b/src/Engines/BaseEngine.php @@ -690,7 +690,7 @@ public function render($object = false) $output = $this->showDebugger($output); } - return new JsonResponse($output); + return new JsonResponse($output, 200, Config::get('datatables.json.header', []), Config::get('datatables.json.options', 0)); } /** diff --git a/src/config/config.php b/src/config/config.php index f5cc2b3b..7c657d8d 100644 --- a/src/config/config.php +++ b/src/config/config.php @@ -95,4 +95,12 @@ ], 'orientation' => 'landscape', ], + + /** + * JsonResponse header and options config. + */ + 'json' => [ + 'header' => [], + 'options' => 0, + ], ]; From 74d9e69fc3ec717fe558900f9785da0976d6d8df Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Wed, 7 Jun 2017 13:24:00 +0800 Subject: [PATCH 314/322] Bump v6.29.0 :rocket: --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cb724b8..399ffdf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ ##Change Log +### v6.29.0 - 2017-06-07 +- Add config for setting the default JsonResponse header and options. #1179 +- Fix #1034 +- TODO: Need to update tests. + ### v6.28.1 - 2017-05-05 - Fixed: Formatting the attributes for Editor buttons. #1105, credits to @karmendra. From b4ad7e05be202404eac00f3c6d86e846b11a00db Mon Sep 17 00:00:00 2001 From: Rajender Joshi Date: Sat, 16 Sep 2017 07:32:11 +0530 Subject: [PATCH 315/322] Return true for true, true(string) and 1 in isColumnSearchable method --- src/Request.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Request.php b/src/Request.php index 5504380d..dfcd2e11 100644 --- a/src/Request.php +++ b/src/Request.php @@ -119,10 +119,10 @@ public function searchableColumnIndex() public function isColumnSearchable($i, $column_search = true) { if ($column_search) { - return $this->input("columns.$i.searchable") === 'true' && $this->columnKeyword($i) != ''; + return in_array($this->input("columns.$i.searchable"), [true, 'true', 1]) && $this->columnKeyword($i) != ''; } - return $this->input("columns.$i.searchable") === 'true'; + return in_array($this->input("columns.$i.searchable"), [true, 'true', 1]); } /** From ef9201e0f27f22b60e674071f5a2c95807f72c00 Mon Sep 17 00:00:00 2001 From: Rajender Joshi Date: Sat, 23 Sep 2017 17:04:10 +0530 Subject: [PATCH 316/322] Updated evaluation logic in isColumnSearchable method to validate all possible true values i.e. true, yes, 1, on regardless of data types --- src/Request.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Request.php b/src/Request.php index dfcd2e11..3de2f376 100644 --- a/src/Request.php +++ b/src/Request.php @@ -119,10 +119,10 @@ public function searchableColumnIndex() public function isColumnSearchable($i, $column_search = true) { if ($column_search) { - return in_array($this->input("columns.$i.searchable"), [true, 'true', 1]) && $this->columnKeyword($i) != ''; + return filter_var($this->input("columns.$i.searchable"), FILTER_VALIDATE_BOOLEAN) && $this->columnKeyword($i) != ''; } - return in_array($this->input("columns.$i.searchable"), [true, 'true', 1]); + return filter_var($this->input("columns.$i.searchable"), FILTER_VALIDATE_BOOLEAN); } /** From dee2fc1ad2caad4a5a6fe80307598a2eb1baeee0 Mon Sep 17 00:00:00 2001 From: Rajender Joshi Date: Sat, 23 Sep 2017 19:18:28 +0530 Subject: [PATCH 317/322] Swap Config facade in test cases with Repository instance instead of mocking it which causes render method in BaseEngine class to fail because Config facade always returned null --- tests/CollectionEngineTest.php | 3 +-- tests/QueryBuilderEngineTest.php | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/CollectionEngineTest.php b/tests/CollectionEngineTest.php index 424cb0f3..4fdd54a0 100644 --- a/tests/CollectionEngineTest.php +++ b/tests/CollectionEngineTest.php @@ -17,7 +17,7 @@ public function setUp() $app->shouldReceive('instance')->once()->andReturn($app); Illuminate\Support\Facades\Facade::setFacadeApplication($app); - Config::swap($config = m::mock('ConfigMock')); + Config::swap(new \Illuminate\Config\Repository); } public function tearDown() @@ -59,7 +59,6 @@ public function test_datatables_make_with_data() protected function setupBuilder() { - Config::shouldReceive('get'); $data = [ ['id' => 1, 'name' => 'foo'], ['id' => 2, 'name' => 'bar'], diff --git a/tests/QueryBuilderEngineTest.php b/tests/QueryBuilderEngineTest.php index 21c504fe..64349160 100644 --- a/tests/QueryBuilderEngineTest.php +++ b/tests/QueryBuilderEngineTest.php @@ -17,7 +17,7 @@ public function setUp() $app->shouldReceive('instance')->once()->andReturn($app); Illuminate\Support\Facades\Facade::setFacadeApplication($app); - Config::swap($config = m::mock('ConfigMock')); + Config::swap(new \Illuminate\Config\Repository); } public function tearDown() @@ -76,8 +76,6 @@ public function test_datatables_make_with_data_using_alias() protected function setupBuilder($showAllRecords = false) { - Config::shouldReceive('get'); - $cache = m::mock('stdClass'); $driver = m::mock('stdClass'); $data = [ From 651422e982a2021a487520c5e23497b77182342f Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Tue, 26 Sep 2017 09:09:08 +0800 Subject: [PATCH 318/322] Bump v6.29.1 :rocket: --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 399ffdf6..eec1cc54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +### v6.29.1 - 2017-09-26 +- Return true for true, true(string) and 1 in isColumnSearchable method #1395, credits to @joeshee. + ### v6.29.0 - 2017-06-07 - Add config for setting the default JsonResponse header and options. #1179 - Fix #1034 From 37e90e86e6941b7536649c00dd29e0665c60e74a Mon Sep 17 00:00:00 2001 From: i_am_invisible Date: Fri, 8 Dec 2017 11:24:00 +0100 Subject: [PATCH 319/322] fix issue 932 --- src/Engines/CollectionEngine.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Engines/CollectionEngine.php b/src/Engines/CollectionEngine.php index 57515332..d27f0674 100644 --- a/src/Engines/CollectionEngine.php +++ b/src/Engines/CollectionEngine.php @@ -159,7 +159,15 @@ function ($row) use ($columns) { } if ($this->isCaseInsensitive()) { - $found[] = Str::contains(Str::lower($value), Str::lower($keyword)); + + if(is_array($value)){ + foreach ($value as $v) { + $found[] = Str::contains(Str::lower($v), Str::lower($keyword)); + }; + } else{ + $found[] = Str::contains(Str::lower($value), Str::lower($keyword)); + } + } else { $found[] = Str::contains($value, $keyword); } From 483a9998a1bc883e269e4cee61ceb24cfcbbb895 Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Fri, 8 Dec 2017 20:26:21 +0800 Subject: [PATCH 320/322] Bump v6.29.2 :rocket: --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eec1cc54..0b6b57e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +### v6.29.2 - 2017-12-08 +- Fix issue #932. #1543, credits to @abiodunjames. + ### v6.29.1 - 2017-09-26 - Return true for true, true(string) and 1 in isColumnSearchable method #1395, credits to @joeshee. @@ -73,7 +76,7 @@ - Update license to 2017. ### v6.22.6 - 2017-01-04 -- Fix print header issue when two row are same value. +- Fix print header issue when two row are same value. - PR #913, credits to @dineshrabara. ### v6.22.5 - 2016-12-07 From ca1aacc12dd9afe2133d5903710f20ddf5cb17ca Mon Sep 17 00:00:00 2001 From: Ronald Edelschaap Date: Tue, 27 Mar 2018 16:24:53 +0200 Subject: [PATCH 321/322] Update Helper.php Fixed a bug for "undefined index" errors --- src/Helper.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Helper.php b/src/Helper.php index cb80bd07..43133814 100644 --- a/src/Helper.php +++ b/src/Helper.php @@ -222,10 +222,12 @@ public static function wrapDatabaseColumn($database, $key, $column) public static function convertToArray($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; From 5ccbe38affa0a9930a2add19684e012bed09f62d Mon Sep 17 00:00:00 2001 From: Arjay Angeles Date: Thu, 5 Apr 2018 23:24:20 +0800 Subject: [PATCH 322/322] Bump v6.29.3 :rocket: --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b6b57e3..2bcff071 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ ##Change Log +### v6.29.3 - 2018-04-05 +- Fixed a bug for "undefined index" errors. #1675, credits to @redelschaap. + ### v6.29.2 - 2017-12-08 - Fix issue #932. #1543, credits to @abiodunjames.
{!! $key !!}