Created
January 23, 2024 10:52
-
-
Save Alexisgt01/8485b1063dc5b300c6e877913ff160c8 to your computer and use it in GitHub Desktop.
Search and fill pattern
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
Route::controller(SupportController::class)->prefix('support')->group(function () { | |
Route::get('search', 'simple'); | |
Route::get('fill', 'fill'); | |
}); |
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\Models\Contracts; | |
interface IsSearchEntity | |
{ | |
public function getSearchIdentifier(): string|int; | |
public function getSearchLabel(): string|int; | |
public function getSearchDetails(): string|int|array; | |
public function getSearchType(): string; | |
} |
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\Http\Resources\Support; | |
use Illuminate\Http\Resources\Json\ResourceCollection; | |
class SearchCollection extends ResourceCollection | |
{ | |
/** | |
* @param $resource | |
*/ | |
public function __construct($resource) | |
{ | |
parent::__construct($resource); | |
} | |
} |
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\Support; | |
final readonly class SearchEntity | |
{ | |
public function __construct( | |
private \Closure $collectionCallback, | |
private \Closure $builderCallback, | |
private \Closure $authorizationCallback, | |
private \Closure $fillCallback, | |
){} | |
public function getCollectionCallback(): \Closure | |
{ | |
return $this->collectionCallback; | |
} | |
public function getBuilderCallback(): \Closure | |
{ | |
return $this->builderCallback; | |
} | |
public function getAuthorizationCallback(): \Closure | |
{ | |
return $this->authorizationCallback; | |
} | |
public function getFillCallback(): \Closure | |
{ | |
return $this->fillCallback; | |
} | |
} |
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\Http\Resources\Support; | |
use App\Models\Contracts\IsSearchEntity; | |
use Illuminate\Http\Request; | |
use Illuminate\Http\Resources\Json\JsonResource; | |
/** @mixin IsSearchEntity */ | |
class SearchResource extends JsonResource | |
{ | |
/** | |
* Transform the resource into an array. | |
* | |
* @return array<string, mixed> | |
*/ | |
public function toArray(Request $request): array | |
{ | |
return [ | |
'id' => $this->getSearchIdentifier(), | |
'label' => $this->getSearchLabel(), | |
'details' => $this->getSearchDetails(), | |
'type' => $this->getSearchType(), | |
]; | |
} | |
} |
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
// with pinia, works with vuex | |
import {defineStore} from 'pinia' | |
import Support from "@/api/Support"; | |
const api = new Support(); | |
export const useSupport = defineStore('domain', { | |
state: () => { | |
return { | |
loading: false as boolean, | |
} | |
}, | |
actions: { | |
fill(type: string) { | |
this.loading = true; | |
return api.fill(type) | |
.then((r) => { | |
this[type] = r.data.data; | |
return r.data; | |
}) | |
.catch((e) => { | |
alertStore.error(e); | |
throw e; | |
}) | |
.finally(() => { | |
this.loading = false; | |
}); | |
} | |
} | |
}); | |
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\Http\Controllers; | |
use App\Http\Resources\Support\SearchCollection; | |
use App\Models\User; | |
use App\Support\SearchEntity; | |
use Illuminate\Database\Eloquent\Builder; | |
use Illuminate\Database\Eloquent\Collection; | |
use Illuminate\Http\Request; | |
use Illuminate\Http\Resources\Json\ResourceCollection; | |
use Illuminate\Support\Arr; | |
class SupportController extends Controller | |
{ | |
protected array $searchEntities; | |
public function __construct() | |
{ | |
$this->searchEntities = [ | |
'user' => new SearchEntity( | |
fn(Collection $collection): ResourceCollection => new SearchCollection($collection), | |
fn(?string $label): Builder => User::where('name', 'like', "%$label%"), | |
fn() => $this->authorize('viewAny', User::class), // Based on UserPolicy, update as your wish | |
fn() => User::select(['id', 'name'])->scope()->get(), | |
), | |
]; | |
} | |
public function simple(Request $request) | |
{ | |
$request->validate([ | |
'search' => ['string', 'nullable'], | |
'type' => ['in:' . Arr::join(array_keys($this->searchEntities), ',')] | |
]); | |
$entity = $this->searchEntities[$request->type]; | |
$entity->getAuthorizationCallback()(); | |
$builder = $entity->getBuilderCallback()($request->search); | |
$data = $builder instanceof Builder ? $builder->limit(20)->get() : $builder; | |
return $entity->getCollectionCallback()($data); | |
} | |
public function fill(Request $request) | |
{ | |
$request->validate([ | |
'type' => ['in:' . Arr::join(array_keys($this->searchEntities), ',')] | |
]); | |
$entity = $this->searchEntities[$request->type]; | |
$entity->getAuthorizationCallback()(); | |
$data = $entity->getFillCallback()(); | |
return $entity->getCollectionCallback()($data); | |
} | |
} |
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\Models; | |
use App\Models\Contracts\IsSearchEntity; | |
use App\Models\Scope\TenantByUserScope; | |
use App\State\Tenant\From\From; | |
use App\State\Tenant\From\Undefined; | |
use Illuminate\Database\Eloquent\Builder; | |
use Illuminate\Database\Eloquent\Casts\Attribute; | |
use Illuminate\Database\Eloquent\Factories\HasFactory; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Support\Facades\App; | |
use Illuminate\Support\Facades\Auth; | |
class User extends Model implements IsSearchEntity | |
{ | |
public function getSearchIdentifier(): string|int | |
{ | |
return $this->id; | |
} | |
public function getSearchLabel(): string|int | |
{ | |
return $this->name; | |
} | |
public function getSearchDetails(): array|int|string | |
{ | |
return []; | |
} | |
public function getSearchType(): string | |
{ | |
return 'user'; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment