feat: filters for /api/users/private/list
This commit is contained in:
parent
27e21f0ad0
commit
ca1f629f05
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App\Facade\Filters;
|
||||
|
||||
class Filter
|
||||
{
|
||||
public FilterTypeEnum $type;
|
||||
public string $column;
|
||||
public string $filter;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Facade\Filters;
|
||||
|
||||
enum FilterTypeEnum: string
|
||||
{
|
||||
case Is = 'is';
|
||||
case Like = 'like';
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
namespace App\Facade\Filters;
|
||||
use App\Facade\Filters\Pagination;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Validation\Rule;
|
||||
use JsonMapper;
|
||||
|
||||
class Filters
|
||||
{
|
||||
|
||||
public const FILTERS_VALIDATION = [];
|
||||
// 'filters.*.column' => [ 'required', 'string' ],
|
||||
// 'filters.*.type' => [ 'required', Rule::enum(FilterTypeEnum::class) ],
|
||||
// 'filters.*.filter' => [ 'required', 'string' ],
|
||||
|
||||
// 'orders.*.by' => [ 'required', 'string' ],
|
||||
// 'orders.*.sort' => [ 'required', Rule::enum(OrderTypeEnum::class) ],
|
||||
|
||||
// 'pagination.size' => 'number',
|
||||
// 'pagination.page' => 'number',
|
||||
// ];
|
||||
|
||||
/**
|
||||
* @var Filter[]
|
||||
*/
|
||||
public array $filters;
|
||||
|
||||
/**
|
||||
* @var Order[]
|
||||
*/
|
||||
public array $orders;
|
||||
|
||||
public ?Pagination $pagination;
|
||||
|
||||
public static function fromArrayOrObject(array | object $data): Filters
|
||||
{
|
||||
$mapper = new JsonMapper();
|
||||
if (is_array($data)) {
|
||||
$data = json_decode(json_encode($data), false);
|
||||
}
|
||||
|
||||
$data->filters ??= [];
|
||||
$data->orders ??= [];
|
||||
$data->pagination ??= null;
|
||||
|
||||
return $mapper->map($data, \App\Facade\Filters\Filters::class);
|
||||
}
|
||||
|
||||
public function apply(Builder $builder)
|
||||
{
|
||||
foreach ($this->filters as $filter) {
|
||||
switch ($filter->type) {
|
||||
case FilterTypeEnum::Is:
|
||||
$builder->where($filter->column, $filter->filter);
|
||||
break;
|
||||
case FilterTypeEnum::Like:
|
||||
$builder->whereLike($filter->column, $filter->filter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->orders as $order) {
|
||||
$builder->orderBy($order->by, $order->sort->value);
|
||||
}
|
||||
|
||||
if (!is_null($this->pagination)) {
|
||||
$builder->paginate($this->pagination->size , ['*'], 'page', $this->pagination->page);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Facade\Filters;
|
||||
|
||||
class Order
|
||||
{
|
||||
public string $by;
|
||||
public OrderTypeEnum $sort;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Facade\Filters;
|
||||
|
||||
enum OrderTypeEnum: string
|
||||
{
|
||||
case Asc = 'asc';
|
||||
case Desc = 'desc';
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Facade\Filters;
|
||||
|
||||
class Pagination
|
||||
{
|
||||
public int $size;
|
||||
public int $page;
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Facade\Filters\Filters;
|
||||
use App\Http\Requests\AuthorizedRequest;
|
||||
use App\Http\Requests\UserEditRequest;
|
||||
use App\Services\UserService;
|
||||
|
@ -17,6 +18,12 @@ class PrivateUserController extends Controller
|
|||
return $this->userService->listAll();
|
||||
}
|
||||
|
||||
public function listFilters(AuthorizedRequest $request)
|
||||
{
|
||||
$filters = Filters::fromArrayOrObject($request->all());
|
||||
return $this->userService->listAll($filters);
|
||||
}
|
||||
|
||||
public function get(AuthorizedRequest $request, string $id)
|
||||
{
|
||||
return $this->userService->getOneById($id);
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
use App\Facade\Filters\Filters;
|
||||
|
||||
class AuthorizedFilterListRequest extends AuthorizedRequest
|
||||
{
|
||||
public function rules()
|
||||
{
|
||||
return Filters::FILTERS_VALIDATION;
|
||||
}
|
||||
}
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class AuthorizedRequest extends RestRequest
|
||||
{
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Facade\Filters\Filters;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Exceptions\HttpResponseException;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
@ -54,10 +55,15 @@ class UserService
|
|||
$user->save();
|
||||
}
|
||||
|
||||
public function listAll(): array
|
||||
public function listAll(?Filters $filters = null): array
|
||||
{
|
||||
if (is_null($filters)) {
|
||||
return User::all()->toArray();
|
||||
}
|
||||
$builder = User::query();
|
||||
$filters->apply($builder);
|
||||
return $builder->get()->toArray();
|
||||
}
|
||||
|
||||
public function getOneById(string $id): User | null
|
||||
{
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
"bjeavons/zxcvbn-php": "^1.3",
|
||||
"egulias/email-validator": "^4.0",
|
||||
"laravel/framework": "^11.9",
|
||||
"laravel/tinker": "^2.9"
|
||||
"laravel/tinker": "^2.9",
|
||||
"netresearch/jsonmapper": "^4.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "847793c6725e2d2fecbf33402e6d4c4d",
|
||||
"content-hash": "029c945e578ceadcd46c7f20984f1cd4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "bjeavons/zxcvbn-php",
|
||||
|
@ -2079,6 +2079,57 @@
|
|||
],
|
||||
"time": "2024-08-19T06:22:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "netresearch/jsonmapper",
|
||||
"version": "v4.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cweiske/jsonmapper.git",
|
||||
"reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/132c75c7dd83e45353ebb9c6c9f591952995bbf0",
|
||||
"reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-pcre": "*",
|
||||
"ext-reflection": "*",
|
||||
"ext-spl": "*",
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0",
|
||||
"squizlabs/php_codesniffer": "~3.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"JsonMapper": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"OSL-3.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Christian Weiske",
|
||||
"email": "cweiske@cweiske.de",
|
||||
"homepage": "http://github.com/cweiske/jsonmapper/",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Map nested JSON structures onto PHP classes",
|
||||
"support": {
|
||||
"email": "cweiske@cweiske.de",
|
||||
"issues": "https://github.com/cweiske/jsonmapper/issues",
|
||||
"source": "https://github.com/cweiske/jsonmapper/tree/v4.4.1"
|
||||
},
|
||||
"time": "2024-01-31T06:18:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nette/schema",
|
||||
"version": "v1.3.0",
|
||||
|
|
|
@ -148,6 +148,30 @@ paths:
|
|||
description: Auth failed
|
||||
403:
|
||||
description: Auth failed
|
||||
post:
|
||||
tags:
|
||||
- Private routes
|
||||
security:
|
||||
- session: []
|
||||
summary: List all users with filters
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Filters'
|
||||
responses:
|
||||
200:
|
||||
description: OK
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/User'
|
||||
401:
|
||||
description: Auth failed
|
||||
403:
|
||||
description: Auth failed
|
||||
/api/users/private/get/{id}:
|
||||
get:
|
||||
parameters:
|
||||
|
@ -424,6 +448,69 @@ components:
|
|||
items:
|
||||
type: string
|
||||
example: 'This field is invalid!'
|
||||
Filters:
|
||||
type: object
|
||||
properties:
|
||||
filters:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Filter'
|
||||
example: [
|
||||
{
|
||||
"column": "name",
|
||||
"type": "like",
|
||||
"filter": "%ad%"
|
||||
},
|
||||
{
|
||||
"column": "name",
|
||||
"type": "is",
|
||||
"filter": "jade"
|
||||
}
|
||||
]
|
||||
orders:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Order'
|
||||
example: [
|
||||
{
|
||||
"by": "id",
|
||||
"type": "asc"
|
||||
},
|
||||
{
|
||||
"by": "id",
|
||||
"type": "desc"
|
||||
}
|
||||
]
|
||||
pagination:
|
||||
type: object
|
||||
properties:
|
||||
size:
|
||||
type: number
|
||||
example: 100
|
||||
page:
|
||||
type: number
|
||||
example: 1
|
||||
Filter:
|
||||
type: object
|
||||
properties:
|
||||
column:
|
||||
type: string
|
||||
example: column_name
|
||||
type:
|
||||
type: string
|
||||
example: 'is'
|
||||
filter:
|
||||
type: string
|
||||
example: '123'
|
||||
Order:
|
||||
type: object
|
||||
properties:
|
||||
by:
|
||||
type: string
|
||||
example: column_name
|
||||
sort:
|
||||
type: string
|
||||
example: 'asc|desc'
|
||||
securitySchemes:
|
||||
session:
|
||||
type: http
|
||||
|
|
|
@ -17,6 +17,7 @@ Route::prefix('/api')->group(function() {
|
|||
});
|
||||
Route::controller(PrivateUserController::class)->prefix('/users/private')->group(function () {
|
||||
Route::get('/list', 'list');
|
||||
Route::post('/list', 'listFilters');
|
||||
Route::get('/get/{id}', 'get')->whereUuid('id');
|
||||
Route::put('/edit/{id}', 'edit')->whereUuid('id');
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue