| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- <?php
- namespace App\Http\Controllers;
- use App\Helpers\DateHelper;
- use Illuminate\Database\Eloquent\Builder;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
- use Illuminate\Foundation\Validation\ValidatesRequests;
- use Illuminate\Http\Request;
- use Illuminate\Routing\Controller as BaseController;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Str;
- class Controller extends BaseController
- {
- use AuthorizesRequests, ValidatesRequests;
- protected array $data = [
- 'filters' => [],
- 'ranges' => [],
- 'dates' => [],
- ];
- /**
- * @param Model $model
- * @param string ...$columnNames
- * @return void
- */
- protected function createDateFilters(Model $model, string ...$columnNames): void
- {
- foreach ($columnNames as $columnName) {
- $this->data['dates'][$columnName] = [
- 'title' => $this->data['header'][$columnName],
- 'min' => DateHelper::getDateForDB($model::query()->min($columnName) ?? ''),
- 'max' => DateHelper::getDateForDB($model::query()->max($columnName) ?? ''),
- ];
- }
- }
- /**
- * @param Model $model
- * @param array $columnNames
- * @return void
- */
- protected function createRangeFilters(Model $model, string ...$columnNames): void
- {
- foreach ($columnNames as $columnName) {
- if(str_ends_with($columnName, '_price')) {
- $this->data['ranges'][$columnName] = [
- 'title' => $this->data['header'][$columnName],
- 'min' => $model::query()->min($columnName) / 100,
- 'max' => $model::query()->max($columnName) / 100,
- ];
- } else {
- $this->data['ranges'][$columnName] = [
- 'title' => $this->data['header'][$columnName ],
- 'min' => $model::query()->min($columnName),
- 'max' => $model::query()->max($columnName),
- ];
- }
- }
- }
- /**
- * @param Model $model
- * @param array $columns
- * @return void
- */
- protected function createFilters(Model $model, string ...$columns): void
- {
- foreach ($columns as $column) {
- $uniqueValues = $model::query()->distinct()->get($column)->pluck($column)->toArray();
- foreach ($uniqueValues as $k => $v) {
- if(!$v) {
- $uniqueValues[$k] = '-пусто-';
- }
- }
- $result = [];
- foreach ($uniqueValues as $val){
- if(str_ends_with($column, '_id')) {
- $relation = Str::camel(str_replace('_id', '', $column));
- $result[$val] = $model::query()->where($column, '=', $val)->first()?->$relation->name;
- } else {
- $result[$val] = $val;
- }
- }
- $this->data['filters'][$column] = [
- 'title' => $this->data['header'][$column],
- 'values' => $result
- ];
- }
- }
- /**
- * @param Model $model
- * @param Request $request
- * @return void
- */
- protected function setSortAndOrderBy(Model $model, Request $request): void
- {
- // ------- setup sort and order --------------------------------------------------------------------------------
- $this->data['sortBy'] = (!empty($request->sortBy))
- ? Str::replace('_txt', '', $request->sortBy) // remove '_txt' fields modifier
- : $model::DEFAULT_SORT_BY ?? 'created_at';
- // check for sortBy is valid field
- $p = new $model();
- if(!in_array($this->data['sortBy'], array_merge(['id', 'created_at'], $p->getFillable()))) {
- $this->data['sortBy'] = $model::DEFAULT_SORT_BY ?? 'created_at';
- }
- if(!empty($request->per_page)) {
- $this->data['per_page'] = $request->per_page;
- } else {
- $this->data['per_page'] = config('pagination.per_page');
- }
- session(['per_page' => $request->per_page]);
- // set order
- $this->data['orderBy'] = (empty($request->order)) ? 'asc' : 'desc';
- }
- /**
- * @param Builder $query
- * @param Request $request
- * @return void
- */
- protected function acceptFilters(Builder $query, Request $request): void
- {
- // accept filters
- if(!empty($request->filters) && is_array($request->filters)) {
- foreach ($request->filters as $filterName => $filterValue) {
- if(!$filterValue) continue;
- if(Str::contains($filterValue, '||')) {
- $values = explode('||', $filterValue);
- foreach ($values as $v) {
- if($v == '-пусто-')
- $query->whereNull($filterName);
- }
- $query->orWhereIn($filterName, $values);
- } else {
- if($filterValue == '-пусто-') {
- $query->whereNull($filterName);
- } else {
- $query->where($filterName, $filterValue);
- }
- }
- }
- }
- }
- /**
- * @param Builder $query
- * @param Request $request
- * @return void
- */
- protected function acceptSearch(Builder $query, Request $request): void
- {
- // accept search
- if(!empty($request->s)) {
- $s = $request->s;
- $searchFields = $this->data['searchFields'];
- $query->where(function ($query) use ($searchFields, $s) {
- foreach ($searchFields as $searchField) {
- if(Str::contains($searchField, '-')) {
- list($relation, $column) = explode('-', $searchField);
- $query->orWhereHas($relation, function ($query) use ($s, $column) {
- $query->where($column, 'LIKE', "%{$s}%");
- });
- } else {
- $query->orWhere($searchField, 'LIKE', '%' . $s . '%');
- }
- }
- });
- }
- }
- }
|