Created
April 30, 2020 17:50
-
-
Save noamanahmed/8749a829294e250d5aca7f88971f8bfe to your computer and use it in GitHub Desktop.
A Datatable Class written for insanely fast generation of add and edit columns with the help of PHP Reflection methods.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Datatables; | |
| use Str; | |
| class BaseTable | |
| { | |
| use FiltersTrait; | |
| /** | |
| * Reflection Object for this class | |
| * | |
| * @var object | |
| */ | |
| public $dt_reflection; | |
| /** | |
| * Datatables | |
| * | |
| * @var object | |
| */ | |
| public $dt; | |
| /** | |
| * Eloquent Modal | |
| * | |
| * @var object | |
| */ | |
| public $modal; | |
| /** | |
| * Names of the columns to be displayed raw | |
| * | |
| * @var array | |
| */ | |
| public $raw_columns = ['actions']; | |
| /** | |
| * EagerLoad Relationships in query | |
| * | |
| * @var array | |
| */ | |
| public $with = []; | |
| /** | |
| * EagerLoad Relationships Count in query | |
| * | |
| * @var array | |
| */ | |
| public $with_count = []; | |
| /** | |
| * JSON Reponse | |
| * | |
| * @var boolean | |
| */ | |
| public $json = true; | |
| /** | |
| * Add DT_RowIndex in JSON Response | |
| * | |
| * @var boolean | |
| */ | |
| public $add_index_column = true; | |
| /** | |
| * Boot all pre-requistics | |
| * | |
| * @return void | |
| */ | |
| public function boot() | |
| { | |
| //Load Datatables | |
| $this->dt = datatables(); | |
| //Get Reflection object for this object | |
| $this->dt_reflection = new \ReflectionObject($this); | |
| } | |
| /** | |
| * Here all the magic happens | |
| * | |
| * @param Eloquent|Collection|QueryBuilder $query | |
| * @return void | |
| */ | |
| public function make($query) | |
| { | |
| //Get datatbles | |
| $dt = $this->dt; | |
| //Make datatables query | |
| $dt = $dt->of($query); | |
| //Add Columns | |
| foreach ($this->get_add_columns() as $key => $column) { | |
| $dt->addColumn($key, function ($data) use ($column) { | |
| return $this->$column($data); | |
| }); | |
| } | |
| //Edit Columns | |
| foreach ($this->get_edit_columns() as $key => $column) { | |
| $dt->editColumn($key, function ($data) use ($column) { | |
| return $this->$column($data); | |
| }); | |
| } | |
| //Raw Columns | |
| if (!empty($this->raw_columns)) { | |
| $dt->rawColumns($this->raw_columns); | |
| } | |
| //Remove Columns which are not required | |
| if (!empty($this->remove_columns)) { | |
| foreach ($this->remove_columns as $column) { | |
| $dt->removeColumns($column); | |
| } | |
| } | |
| //Add Index Columns | |
| if ($this->add_index_column) { | |
| $dt->addIndexColumn(); | |
| } | |
| //Save DT incase of reuse | |
| $this->dt = $dt; | |
| return $dt; | |
| } | |
| /** | |
| * Get all the methods for this class | |
| * | |
| * @return array | |
| */ | |
| public function get_methods() | |
| { | |
| return $this->dt_reflection->getMethods(); | |
| } | |
| /** | |
| * Get All Add Columns functions | |
| * | |
| * @return void | |
| */ | |
| public function get_add_columns() | |
| { | |
| //Get all methods | |
| $methods = $this->get_methods(); | |
| //Set default to empty | |
| $add_columns = []; | |
| foreach ($methods as $method) { | |
| //Only Add editColumn methods | |
| if (strpos($method->name, 'addColumn') === 0) { | |
| //Sanity Check | |
| //Check if there is an editColumn function | |
| if (strlen(substr($method->name, strlen('addColumn'))) == 0) { | |
| //Ignore this function | |
| continue; | |
| } | |
| //Convert Key to snake case and store the callback | |
| $add_columns[Str::snake(substr($method->name, strlen('addColumn')))] = $method->name; | |
| } | |
| } | |
| //Return the columns | |
| return $add_columns; | |
| } | |
| /** | |
| * Get all the edit column functions | |
| * | |
| * @return void | |
| */ | |
| public function get_edit_columns() | |
| { | |
| //Get all methods | |
| $methods = $this->get_methods(); | |
| //Set default to empty | |
| $edit_columns = []; | |
| foreach ($methods as $method) { | |
| //Only Add editColumn methods | |
| if (strpos($method->name, 'editColumn') === 0) { | |
| //Sanity Check | |
| //Check if there is an editColumn function | |
| if (strlen(substr($method->name, strlen('editColumn'))) == 0) { | |
| //Ignore this function | |
| continue; | |
| } | |
| //Convert Key to snake case and store the callback | |
| $edit_columns[Str::snake(substr($method->name, strlen('editColumn')))] = $method->name; | |
| } | |
| } | |
| //Return the columns | |
| return $edit_columns; | |
| } | |
| /** | |
| * Get all the apply filters functions | |
| * | |
| * @return void | |
| */ | |
| public function get_apply_filters() | |
| { | |
| //Get all methods | |
| $methods = $this->get_methods(); | |
| //Set default to empty | |
| $apply_filters = []; | |
| foreach ($methods as $method) { | |
| //Only Add applyFilter methods | |
| if (strpos($method->name, 'applyFilter') === 0) { | |
| //Sanity Check | |
| //Check if there is an applyFilter function | |
| if (strlen(substr($method->name, strlen('applyFilter'))) == 0) { | |
| //Ignore this function | |
| continue; | |
| } | |
| //Convert Key to snake case and store the callback | |
| $apply_filters[Str::snake(substr($method->name, strlen('applyFilter')))] = $method->name; | |
| } | |
| } | |
| //Return the columns | |
| return $apply_filters; | |
| } | |
| /** | |
| * Generate datatables and function to be called in controller | |
| * | |
| * @param Eloquent|Collection|QueryBuilder $query | |
| * @param Illuminate\Database\Eloquent\Model $modal | |
| * @return mixed | |
| */ | |
| public function datatables($query, $modal) | |
| { | |
| //Boot | |
| $this->boot(); | |
| //Store Modal | |
| $this->modal = $modal; | |
| //Apply Filters | |
| $filtered_query = $this->query($query); | |
| //Make Datatables from the query | |
| $datatables = $this->make($filtered_query); | |
| //Generate JSON if Set | |
| if ($this->json) { | |
| $datatables = $datatables->toJson(); | |
| } | |
| //Send table data back to controller | |
| return $datatables; | |
| } | |
| /** | |
| * Modify Query/Collection | |
| * | |
| * @param Eloquent|Collection|QueryBuilder $query | |
| * @return mixed Eloquent|Collection|QueryBuilder | |
| */ | |
| public function query($query) | |
| { | |
| if ($query instanceof \Illuminate\Database\Eloquent\Builder) { | |
| $query = $this->applyQueryFilters($query); | |
| } | |
| if (!empty($this->with)) { | |
| $query = $query->with($this->with); | |
| } | |
| if (!empty($this->with_count)) { | |
| $query = $query->withCount($this->with_count); | |
| } | |
| return $query; | |
| } | |
| /** | |
| * Apply filters for query | |
| * | |
| * @param Illuminate\Database\Eloquent\Builder $query | |
| * @return void | |
| */ | |
| public function applyQueryFilters($query) | |
| { | |
| $filters = $this->get_apply_filters(); | |
| foreach ($filters as $filter) { | |
| $query = $this->$filter($query); | |
| } | |
| return $query; | |
| } | |
| /** | |
| * Get Modal Short Name for Datatables | |
| * | |
| * @return void | |
| */ | |
| public function getModalShortName() | |
| { | |
| $this->modal_reflection = new \ReflectionObject($this->modal); | |
| return $this->modal_reflection->getShortName(); | |
| } | |
| public function getModalShortNameInLowerCase() | |
| { | |
| return strtolower($this->getModalShortName()); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Datatables; | |
| use App\Datatables\Filters\DateFilter; | |
| use App\Datatables\Filters\NameFilter; | |
| use Carbon\Carbon; | |
| class Brand extends BaseTable | |
| { | |
| use ActionsTrait; | |
| use NameFilter; | |
| use DateFilter; | |
| /** | |
| * EagerLoad Relationships in query | |
| * | |
| * @var array | |
| */ | |
| public $with = []; | |
| /** | |
| * EagerLoad Relationships Count in query | |
| * | |
| * @var array | |
| */ | |
| public $with_count = ['records']; | |
| /** | |
| * Names of the columns to be displayed raw | |
| * | |
| * @var array | |
| */ | |
| public $raw_columns = ['actions', 'status', 'records_count']; | |
| public function editColumnRecordsCount($data) | |
| { | |
| return '<span class="badge badge-primary text-white p-2">' . $data['records_count'] . '</span>'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Datatables\Filters; | |
| trait DateFilter | |
| { | |
| public function applyFilterDate($query) | |
| { | |
| if (!$this->has_filter('date')) { | |
| return $query; | |
| } | |
| $date = $this->get_filter('date'); | |
| if (empty($date)) { | |
| return $query; | |
| } | |
| $date = Carbon::parse($date); | |
| return $query->whereDate('date', $date); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| namespace App\Datatables; | |
| use Str; | |
| trait FiltersTrait | |
| { | |
| public function has_filter($key) | |
| { | |
| if (is_null(request()->filter)) { | |
| return false; | |
| } | |
| $filters = request()->filter; | |
| if (!is_array($filters)) { | |
| return false; | |
| } | |
| if (!array_key_exists($key, $filters)) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| public function get_filter($key) | |
| { | |
| if (!$this->has_filter($key)) { | |
| return false; | |
| } | |
| return request()->filter[$key]; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment