|
|
@@ -2,11 +2,165 @@
|
|
|
|
|
|
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;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @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 . '_txt'],
|
|
|
+ '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 = DB::table(($model)->getTable())
|
|
|
+ ->select($column)
|
|
|
+ ->distinct()
|
|
|
+ ->get()
|
|
|
+ ->pluck($column)
|
|
|
+ ->toArray();
|
|
|
+ $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)
|
|
|
+ {
|
|
|
+ // ------- 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';
|
|
|
+ }
|
|
|
+
|
|
|
+ // set order
|
|
|
+ $this->data['orderBy'] = (!empty($request->order)) ? 'desc' : 'asc';
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param Builder $query
|
|
|
+ * @param Request $request
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ protected function acceptFilters(Builder $query, Request $request)
|
|
|
+ {
|
|
|
+ // accept filters
|
|
|
+ if(!empty($request->filters) && is_array($request->filters)) {
|
|
|
+ foreach ($request->filters as $filterName => $filterValue) {
|
|
|
+ if(!$filterValue) continue;
|
|
|
+
|
|
|
+ if(Str::contains($filterName, 'price')) {
|
|
|
+ $filterValue = $filterValue * 100;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(Str::endsWith($filterName, '_from')) {
|
|
|
+ if(is_string($filterValue) && DateHelper::isDate($filterValue)) {
|
|
|
+ $filterValue .= ' 00:00:00';
|
|
|
+ }
|
|
|
+ $query->where(Str::replace('_from', '', $filterName), '>=', $filterValue);
|
|
|
+ } elseif(Str::endsWith($filterName, '_to')) {
|
|
|
+ if(is_string($filterValue) && DateHelper::isDate($filterValue)) {
|
|
|
+ $filterValue .= ' 23:59:59';
|
|
|
+ }
|
|
|
+ $query->where(Str::replace('_to', '', $filterName), '<=', $filterValue);
|
|
|
+ } else {
|
|
|
+ $query->where($filterName, '=', $filterValue);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param Builder $query
|
|
|
+ * @param Request $request
|
|
|
+ * @return void
|
|
|
+ */
|
|
|
+ protected function acceptSearch(Builder $query, Request $request)
|
|
|
+ {
|
|
|
+ // accept search
|
|
|
+ if(!empty($request->s)) {
|
|
|
+ $s = $request->s;
|
|
|
+ $searchFields = $this->data['searchFields'];
|
|
|
+ $query->where(function ($query) use ($searchFields, $s) {
|
|
|
+ foreach ($searchFields as $searchField) {
|
|
|
+ $query->orWhere($searchField, 'LIKE', '%' . $s . '%');
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|