Skip to content

Instantly share code, notes, and snippets.

@yajra
Last active October 18, 2018 07:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yajra/0163c0622de2c0ba306dedec3379cfda to your computer and use it in GitHub Desktop.
Save yajra/0163c0622de2c0ba306dedec3379cfda to your computer and use it in GitHub Desktop.
<?php
namespace Yajra\DataTables\Processors;
use Illuminate\Support\Arr;
use Yajra\DataTables\Utilities\Helper;
class DataProcessor
{
/**
* @var int
*/
protected $start;
/**
* Columns to escape value.
*
* @var array
*/
protected $escapeColumns = [];
/**
* Processed data output.
*
* @var array
*/
protected $output = [];
/**
* @var array
*/
protected $appendColumns = [];
/**
* @var array
*/
protected $editColumns = [];
/**
* @var array
*/
protected $excessColumns = [];
/**
* @var mixed
*/
protected $results;
/**
* @var array
*/
protected $templates;
/**
* @var bool
*/
protected $includeIndex;
/**
* @var string
*/
protected $indexColumn;
/**
* @var array
*/
protected $rawColumns;
/**
* @var array
*/
protected $exceptions = ['DT_RowId', 'DT_RowClass', 'DT_RowData', 'DT_RowAttr'];
/**
* @param mixed $results
* @param array $columnDef
* @param array $templates
* @param int $start
*/
public function __construct($results, array $columnDef, array $templates, $start)
{
$this->results = $results;
$this->appendColumns = $columnDef['append'];
$this->editColumns = $columnDef['edit'];
$this->excessColumns = $columnDef['excess'];
$this->onlyColumns = $columnDef['only'];
$this->escapeColumns = $columnDef['escape'];
$this->includeIndex = $columnDef['index'];
$this->rawColumns = $columnDef['raw'];
$this->templates = $templates;
$this->start = $start;
}
/**
* Process data to output on browser.
*
* @param bool $object
* @return array
*/
public function process($object = false)
{
$this->output = [];
$this->indexColumn = config('datatables.index_column', 'DT_Row_Index');
foreach ($this->results as $row) {
$data = Helper::convertToArray($row);
$value = $this->addColumns($data, $row);
$value = $this->editColumns($value, $row);
$value = $this->setupRowVariables($value, $row);
$value = $this->selectOnlyNeededColumns($value);
$value = $this->removeExcessColumns($value);
$value = $this->addIndexColumn($value);
$value = $this->escapeRow($value);
$this->output[] = $object ? $value : $this->flatten($value);
}
return $this->output;
}
/**
* Process add columns.
*
* @param mixed $data
* @param mixed $row
* @return array
*/
protected function addColumns($data, $row)
{
foreach ($this->appendColumns as $key => $value) {
$value['content'] = Helper::compileContent($value['content'], $data, $row, $this->shouldEscapeColumn($key));
$data = Helper::includeInArray($value, $data);
}
return $data;
}
/**
* Process add index column.
*
* @param mixed $data
* @return array
*/
protected function addIndexColumn($data)
{
if ($this->includeIndex) {
$data[$this->indexColumn] = ++$this->start;
}
return $data;
}
/**
* Process edit columns.
*
* @param mixed $data
* @param mixed $row
* @return array
*/
protected function editColumns($data, $row)
{
foreach ($this->editColumns as $key => $value) {
$value['content'] = Helper::compileContent($value['content'], $data, $row, $this->shouldEscapeColumn($key));
Arr::set($data, $value['name'], $value['content']);
}
return $data;
}
/**
* Setup additional DT row variables.
*
* @param mixed $data
* @param mixed $row
* @return array
*/
protected function setupRowVariables($data, $row)
{
$processor = new RowProcessor($data, $row);
return $processor
->rowValue('DT_RowId', $this->templates['DT_RowId'])
->rowValue('DT_RowClass', $this->templates['DT_RowClass'])
->rowData('DT_RowData', $this->templates['DT_RowData'])
->rowData('DT_RowAttr', $this->templates['DT_RowAttr'])
->getData();
}
/**
* Get only needed columns.
*
* @param array $data
* @return array
*/
protected function selectOnlyNeededColumns(array $data)
{
if (is_null($this->onlyColumns)) {
return $data;
} else {
return array_intersect_key($data, array_flip(array_merge($this->onlyColumns, $this->exceptions)));
}
}
/**
* Remove declared hidden columns.
*
* @param array $data
* @return array
*/
protected function removeExcessColumns(array $data)
{
foreach ($this->excessColumns as $value) {
unset($data[$value]);
}
return $data;
}
/**
* Flatten array with exceptions.
*
* @param array $array
* @return array
*/
public function flatten(array $array)
{
$return = [];
foreach ($array as $key => $value) {
if (in_array($key, $this->exceptions)) {
$return[$key] = $value;
} else {
$return[] = $value;
}
}
return $return;
}
/**
* Escape all values of row.
*
* @param array $row
* @return array
*/
protected function escapeRow(array $row)
{
$arrayDot = array_filter(array_dot($row));
foreach ($arrayDot as $key => $value) {
if ($this->shouldEscapeColumn($key)) {
$arrayDot[$key] = e($value);
}
}
foreach ($arrayDot as $key => $value) {
array_set($row, $key, $value);
}
return $row;
}
/**
* Whether to escape column or no.
*
* @param string $key
* @return bool
*/
protected function shouldEscapeColumn($key)
{
foreach ($this->appendColumns as $column) {
if ($column['name'] == $key && is_string($column['content'])) {
return false;
}
}
foreach ($this->editColumns as $column) {
if ($column['name'] == $key && is_string($column['content'])) {
return false;
}
}
if ($this->escapeColumns === '*') {
return ! in_array($key, $this->rawColumns); // escape if is not a raw column
} elseif (is_array($this->escapeColumns)) {
return in_array($key, array_diff($this->escapeColumns, $this->rawColumns));
} else {
return true;
}
}
}
<?php
namespace App\DataTables;
use App\Fax;
use App\Queries\RawFaxQuery;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Yajra\DataTables\Services\DataTable;
class RawFaxDataTable extends DataTable
{
/**
* Build DataTable class.
*
* @param mixed $query Results from query() method.
* @return \Yajra\DataTables\DataTableAbstract
*/
public function dataTable($query)
{
return datatables()->eloquent($query)
->addColumn('deleted_html', function (Fax $fax) {
return view('raw.partials.deleted', compact('fax'));
})
->addColumn('processed_html', function (Fax $fax) {
return view('raw.partials.processed', compact('fax'));
})
->addColumn('to', function (Fax $fax) {
return $fax->toCaller();
})
->addColumn('agent', function (Fax $fax) {
return $fax->lastname ? $fax->lastname . ', ' . $fax->firstname : "";
})
->addColumn('filename_html', function (Fax $fax) {
return view('raw.partials.filename', compact('fax'));
})
->filter(function (Builder $builder) {
if (request()->has('deleted')) {
$builder->where('fax.deleted', 'N');
}
if (request()->has('processed')) {
$builder->where('fax.processed', 'N');
}
if ($filename = request()->get('filename')) {
$builder->where('fax.filename', 'like', "%$filename%");
}
if ($filename = request()->get('from_fax')) {
$builder->where('fax.filename', 'like', "%$filename%");
}
if ($filename = request()->get('to_fax')) {
$builder->where('fax.filename', 'like', "%$filename%");
}
if ($agent = request()->get('agent')) {
$builder->whereRaw(
"(upper(agent.firstname) LIKE upper(?) or upper(agent.lastname) LIKE upper(?))",
["%$agent%", "%$agent%"]
);
}
if ($received_at = request()->get('received_at')) {
$builder->whereDate(
'fax.daterecieved',
Carbon::parse($received_at)->format('Y-m-d')
);
}
if ($recent_date = request()->get('recent_date')) {
$builder->whereRaw(
"fax.daterecieved >= trunc(sysdate) - ? AND daterecieved <= trunc(sysdate)+1",
[$recent_date]
);
}
})
->rawColumns(['filename_html', 'deleted_html', 'processed_html']);
}
/**
* @param \App\Queries\RawFaxQuery $rawFaxQuery
* @return \Illuminate\Database\Eloquent\Builder
*/
public function query(RawFaxQuery $rawFaxQuery)
{
$builder = $rawFaxQuery->handle();
return $builder;
}
/**
* Optional method if you want to use html builder.
*
* @return \Yajra\DataTables\Html\Builder
*/
public function html()
{
$script = <<<CDATA
var formData = $("#search-fax").find("input, select").serializeArray();
$.each(formData, function(i, obj){
data[obj.name] = obj.value;
});
CDATA;
return $this->builder()
->columns($this->getColumns())
->minifiedAjax('', $script)
->parameters([
'order' => [[2, 'desc']],
'searching' => false,
'lengthMenu' => [10, 20, 50, 100],
'pageLength' => 20,
'buttons' => [],
]);
}
/**
* Get columns.
*
* @return array
*/
protected function getColumns()
{
return [
'deleted' => [
'class' => 'text-center',
'data' => 'deleted_html',
'width' => '10px',
],
'processed' => [
'title' => 'Cooked',
'data' => 'processed_html',
'class' => 'text-center',
'width' => '10px',
],
'faxid' => [
'title' => 'Fax ID',
],
'filename' => [
'data' => 'filename_html',
'title' => 'File Name',
],
'callername' => [
'title' => 'Faxed From',
'orderable' => false,
'searchable' => false,
],
'to' => [
'title' => 'Faxed To',
'orderable' => false,
'searchable' => false,
],
'daterecieved' => [
'title' => 'Date Received',
],
'agent' => [
'name' => 'agent.lastname',
'title' => 'Agent',
],
];
}
/**
* Get filename for export.
*
* @return string
*/
protected function filename()
{
return 'raw-fax_' . time();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment