Introduction
In java, generic methods and classes enable programmers to specifiy, with a single method declaration, a set of related methods , or with a single class single class declaration , a set of related type, respectively.
However inside laravel , we can do some generic repositories to filter out based on business logic that we can imply . Such as to extract all data / find specific data of a member inside society.
Repository
public function filterBy($filter, $joins = NULL, $columns = array('*')) {
$repository_filter = new RepositoryFilter($this->model, $filter, $joins);
return $repository_filter->filter()->get($columns);
}
Repository Filter
class RepositoryFilter {
/**
* @var
*/
private $model;
/**
* @var
*/
private $filter;
/**
* @var
*/
private $join;
/**
* @param string $attribute
* @param int $operator
* @param mixed $value
*/
public function __construct($model, $filter, $join)
{
$this->setModel($model);
$this->setFilter($filter);
$this->setJoin($join);
}
public function setModel($model)
{
$this->model = $model;
}
public function setFilter($filter)
{
$filter = collect($filter);
$filtered = $filter->groupBy('group');
$this->filter = $filtered->all();
}
public function setJoin($join)
{
$this->join = $join;
}
/**
* @return \Illuminate\Database\Eloquent\Builder
* @throws RepositoryFilterException
*/
public function filter()
{
// Generate JOIN clause
$this->_join();
// Generate WHERE clause
$this->_filter();
return $this->model;
}
private function _join()
{
if (!empty($this->join)) {
foreach ($this->join as $class => $type) {
$model = new $class;
$join = ($type == TABLE_JOIN_LEFT) ? 'leftJoin' : 'join';
$this->model->$join($model->getTable(), $this->model->getQuery()->from . '.' . str_singular($model->getTable()) . '_id', '=', $model->getTable() . '.id');
}
}
}
private function _filter()
{
if (!empty($this->filter)) {
foreach ($this->filter as $group => $filters) {
if ($group > 0) {
$where = ($filters[0]->getLogic() == LOGICAL_OR) ? 'orWhere' : 'where';
$this->model->$where(function ($query) use ($filters){
foreach ($filters as $filter) {
$query = $this->_filterCriteria($filter, $query);
}
});
} else {
foreach ($filters as $filter) {
$this->model = $this->_filterCriteria($filter, $this->model);
}
}
}
}
}
private function _filterCriteria($filter, $model)
{
if (!$filter instanceof Filter) {
throw new RepositoryFilterException("Class {$this->model()} must be an instance of App\\Repositories\\Eloquent\\Filter");
}
if (!empty($filter->getValue()) || $filter->getValue() != '') {
$where = ($filter->getLogic() == LOGICAL_OR) ? 'orWhere' : 'where';
switch ($filter->getOperator()) {
case OPERATOR_EQUAL_TO:
if (is_array($filter->getValue())) {
$where .= 'In';
$model->$where($filter->getAttribute(), $filter->getValue());
} else {
$model->$where($filter->getAttribute(), '=', $filter->getValue());
}
break;
case OPERATOR_GREATER_THAN:
$model->$where($filter->getAttribute(), '>', $filter->getValue());
break;
case OPERATOR_LESS_THAN:
$model->$where($filter->getAttribute(), '<', $filter->getValue());
break;
case OPERATOR_GREATER_THAN_OR_EQUAL_TO:
$model->$where($filter->getAttribute(), '>=', $filter->getValue());
break;
case OPERATOR_LESS_THAN_OR_EQUAL_TO:
$model->$where($filter->getAttribute(), '<=', $filter->getValue());
break;
case OPERATOR_NOT_EQUAL_TO:
if (is_array($filter->getValue())) {
$where .= 'NotIn';
$model->$where($filter->getAttribute(), $filter->getValue());
} else {
$model->$where($filter->getAttribute(), '!=', $filter->getValue());
}
break;
case OPERATOR_CONTAIN_PHRASE:
$model->$where($filter->getAttribute(), 'like', '%' . $filter->getValue() . '%');
break;
case OPERATOR_START_WITH_PHRASE:
$model->$where($filter->getAttribute(), 'like', $filter->getValue() . '%');
break;
case OPERATOR_END_WITH_PHRASE:
$model->$where($filter->getAttribute(), 'like', '%' . $filter->getValue());
break;
case OPERATOR_IN_BETWEEN:
$where .= 'Between';
$model->$where($filter->getAttribute(), $filter->getValue());
break;
case OPERATOR_NOT_IN_BETWEEN:
$where .= 'NotBetween';
$model->$where($filter->getAttribute(), $filter->getValue());
break;
}
}
return $model;
}
Controller
public function postData(Request $request)
{
// Retrieve POST data(request) - to be use in the $filter array
$patron_name = $request->get('patron');
$filter = array(
Filter::create('patrons.name', OPERATOR_CONTAIN_PHRASE, $patron_name),
);
// Filter option with target column
$patron = $this->patron->filterBy($filter);
// Instantiate Datatable Entity
$datatables = Datatables::of($patron)
->addIndexColumn()
->add_column('namelink', function($patron){
return
'<a href="' . route('patron.show', $patron->id) .'">'.$patron->name.'</a>';
})
->add_column('statuselection', function($patron){
return
$patron->StatusName;
})
->add_column('studentselection', function($patron){
return
$patron->student->id_no;
})
->add_column('applicantselection', function($patron){
if((!empty($patron->libraryProfile->profile_name)) )
{
return $patron->libraryProfile->profile_name;
}
})
->add_column('action', function ($patron){
return
Form::iconUpdate(route('patron.edit', $patron->id))." ".
Form::iconDelete(route('patron.destroy', $patron->id))." ";
})
->rawColumns(['action','namelink','programselection','statuselection','applicantselection']);
return $datatables->make(true);
}
View
<script>
var table = $('#patron-table').DataTable({
{!! Config::get('datatable.setting') !!}
ajax: {
url: '{!! url("library/patron/data") !!}',
method: 'POST',
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
},
data: function (d) {
d.patron = $('input[name="patron"]').val();
// d.patron_applicant = $('#patron_applicant').val();
// d.patron_status = $('#patron_status').val();
},
error: function(data){
// Error...
var errors = data.responseJSON;
$('html').html(data.responseText);
console.log(data.responseText);
}
},
columns: [
{ sTitle: 'No' , data:'DT_Row_Index', width: '5%' },
{ sTitle: 'Name', data: 'namelink', name:'name' , width: '15%'}, //data is database name // name is modelName for relationship
{ sTitle: 'ID Number', data: 'studentselection' , width: '10%' }, //data is database name // name is modelName for relationship
{ sTitle: 'Profile', data: 'applicantselection' , width: '10%'}, //data is database name // name is modelName for relationship
{ sTitle: 'Status', data: 'statuselection' , width: '10%'},
{ sTitle: 'Action', data: 'action', width: '10%'},
]
});
$('#B3-filter-box').on('submit', function(e) {
table.draw();
e.preventDefault();
});
</script>
No comments:
Post a Comment