mirror of
https://github.com/sp-tarkov/forge.git
synced 2025-02-13 04:30:41 -05:00
API Updates
Brings the API in close sync to the rest of the site. - Adds resources for License, UserRole, and ModVersion models - Adds filtering on attribute data - The `includes` data is now disabled by default and available conditionally
This commit is contained in:
parent
65e416e4d9
commit
3a334033fe
@ -7,7 +7,11 @@ use Illuminate\Support\Str;
|
|||||||
|
|
||||||
class ApiController extends Controller
|
class ApiController extends Controller
|
||||||
{
|
{
|
||||||
public static function shouldInclude(string $relationship): bool
|
/**
|
||||||
|
* Determine if the given relationship should be included in the request. If more than one relationship is provided,
|
||||||
|
* only one needs to be present in the request for this method to return true.
|
||||||
|
*/
|
||||||
|
public static function shouldInclude(string|array $relationships): bool
|
||||||
{
|
{
|
||||||
$param = request()->get('include');
|
$param = request()->get('include');
|
||||||
|
|
||||||
@ -17,6 +21,16 @@ class ApiController extends Controller
|
|||||||
|
|
||||||
$includeValues = explode(',', Str::lower($param));
|
$includeValues = explode(',', Str::lower($param));
|
||||||
|
|
||||||
return in_array(Str::lower($relationship), $includeValues);
|
if (is_array($relationships)) {
|
||||||
|
foreach ($relationships as $relationship) {
|
||||||
|
if (in_array(Str::lower($relationship), $includeValues)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return in_array(Str::lower($relationships), $includeValues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api\V0;
|
namespace App\Http\Controllers\Api\V0;
|
||||||
|
|
||||||
|
use App\Http\Filters\V1\ModFilter;
|
||||||
use App\Http\Requests\Api\V0\StoreModRequest;
|
use App\Http\Requests\Api\V0\StoreModRequest;
|
||||||
use App\Http\Requests\Api\V0\UpdateModRequest;
|
use App\Http\Requests\Api\V0\UpdateModRequest;
|
||||||
use App\Http\Resources\Api\V0\ModResource;
|
use App\Http\Resources\Api\V0\ModResource;
|
||||||
@ -12,9 +13,9 @@ class ModController extends ApiController
|
|||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(ModFilter $filters)
|
||||||
{
|
{
|
||||||
return ModResource::collection(Mod::paginate());
|
return ModResource::collection(Mod::filter($filters)->paginate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers\Api\V0;
|
namespace App\Http\Controllers\Api\V0;
|
||||||
|
|
||||||
|
use App\Http\Filters\V1\UserFilter;
|
||||||
use App\Http\Requests\Api\V0\StoreUserRequest;
|
use App\Http\Requests\Api\V0\StoreUserRequest;
|
||||||
use App\Http\Requests\Api\V0\UpdateUserRequest;
|
use App\Http\Requests\Api\V0\UpdateUserRequest;
|
||||||
use App\Http\Resources\Api\V0\UserResource;
|
use App\Http\Resources\Api\V0\UserResource;
|
||||||
@ -12,9 +13,9 @@ class UsersController extends ApiController
|
|||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*/
|
*/
|
||||||
public function index()
|
public function index(UserFilter $filters)
|
||||||
{
|
{
|
||||||
return UserResource::collection(User::paginate());
|
return UserResource::collection(User::filter($filters)->paginate());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
116
app/Http/Filters/V1/ModFilter.php
Normal file
116
app/Http/Filters/V1/ModFilter.php
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Filters\V1;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class ModFilter extends QueryFilter
|
||||||
|
{
|
||||||
|
// TODO: Many of these are repeated across UserFilter and ModFilter. Consider refactoring into a shared trait.
|
||||||
|
// Also, consider using common filter types and making the field names dynamic.
|
||||||
|
|
||||||
|
public function name(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||||
|
$like = Str::replace('*', '%', $value);
|
||||||
|
|
||||||
|
return $this->builder->where('name', 'like', $like);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function slug(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||||
|
$like = Str::replace('*', '%', $value);
|
||||||
|
|
||||||
|
return $this->builder->where('slug', 'like', $like);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function teaser(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||||
|
$like = Str::replace('*', '%', $value);
|
||||||
|
|
||||||
|
return $this->builder->where('teaser', 'like', $like);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function source_code_link(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||||
|
$like = Str::replace('*', '%', $value);
|
||||||
|
|
||||||
|
return $this->builder->where('source_code_link', 'like', $like);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function created_at(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||||
|
$dates = explode(',', $value);
|
||||||
|
if (count($dates) > 1) {
|
||||||
|
return $this->builder->whereBetween('created_at', $dates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder->whereDate('created_at', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updated_at(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||||
|
$dates = explode(',', $value);
|
||||||
|
if (count($dates) > 1) {
|
||||||
|
return $this->builder->whereBetween('updated_at', $dates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder->whereDate('updated_at', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function published_at(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||||
|
$dates = explode(',', $value);
|
||||||
|
if (count($dates) > 1) {
|
||||||
|
return $this->builder->whereBetween('published_at', $dates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder->whereDate('published_at', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function featured(string $value): Builder
|
||||||
|
{
|
||||||
|
// We need to convert the string user input to a boolean, or null if it's not a valid "truthy/falsy" value.
|
||||||
|
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||||
|
|
||||||
|
// This column is not nullable.
|
||||||
|
if ($value === null) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder->where('featured', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function contains_ads(string $value): Builder
|
||||||
|
{
|
||||||
|
// We need to convert the string user input to a boolean, or null if it's not a valid "truthy/falsy" value.
|
||||||
|
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||||
|
|
||||||
|
// This column is not nullable.
|
||||||
|
if ($value === null) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder->where('contains_ads', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function contains_ai_content(string $value): Builder
|
||||||
|
{
|
||||||
|
// We need to convert the string user input to a boolean, or null if it's not a valid "truthy/falsy" value.
|
||||||
|
$value = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
|
||||||
|
|
||||||
|
// This column is not nullable.
|
||||||
|
if ($value === null) {
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder->where('contains_ai_content', $value);
|
||||||
|
}
|
||||||
|
}
|
37
app/Http/Filters/V1/QueryFilter.php
Normal file
37
app/Http/Filters/V1/QueryFilter.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Filters\V1;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
abstract class QueryFilter
|
||||||
|
{
|
||||||
|
protected Builder $builder;
|
||||||
|
|
||||||
|
public function __construct(protected Request $request) {}
|
||||||
|
|
||||||
|
public function apply(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
$this->builder = $builder;
|
||||||
|
|
||||||
|
foreach ($this->request->all() as $attribute => $value) {
|
||||||
|
if (method_exists($this, $attribute)) {
|
||||||
|
$this->$attribute($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function filter(array $filters): Builder
|
||||||
|
{
|
||||||
|
foreach ($filters as $attribute => $value) {
|
||||||
|
if (method_exists($this, $attribute)) {
|
||||||
|
$this->$attribute($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder;
|
||||||
|
}
|
||||||
|
}
|
42
app/Http/Filters/V1/UserFilter.php
Normal file
42
app/Http/Filters/V1/UserFilter.php
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Filters\V1;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class UserFilter extends QueryFilter
|
||||||
|
{
|
||||||
|
// TODO: Many of these are repeated across UserFilter and ModFilter. Consider refactoring into a shared trait.
|
||||||
|
// Also, consider using common filter types and making the field names dynamic.
|
||||||
|
|
||||||
|
public function name(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
|
||||||
|
$like = Str::replace('*', '%', $value);
|
||||||
|
|
||||||
|
return $this->builder->where('name', 'like', $like);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function created_at(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||||
|
$dates = explode(',', $value);
|
||||||
|
if (count($dates) > 1) {
|
||||||
|
return $this->builder->whereBetween('created_at', $dates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder->whereDate('created_at', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updated_at(string $value): Builder
|
||||||
|
{
|
||||||
|
// The API allows for a range of dates to be passed as a comma-separated list.
|
||||||
|
$dates = explode(',', $value);
|
||||||
|
if (count($dates) > 1) {
|
||||||
|
return $this->builder->whereBetween('updated_at', $dates);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->builder->whereDate('updated_at', $value);
|
||||||
|
}
|
||||||
|
}
|
25
app/Http/Resources/Api/V0/LicenseResource.php
Normal file
25
app/Http/Resources/Api/V0/LicenseResource.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources\Api\V0;
|
||||||
|
|
||||||
|
use App\Models\License;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
/** @mixin License */
|
||||||
|
class LicenseResource extends JsonResource
|
||||||
|
{
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => 'license',
|
||||||
|
'id' => $this->id,
|
||||||
|
'attributes' => [
|
||||||
|
'name' => $this->name,
|
||||||
|
'link' => $this->link,
|
||||||
|
'created_at' => $this->created_at,
|
||||||
|
'updated_at' => $this->updated_at,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -45,6 +45,19 @@ class ModResource extends JsonResource
|
|||||||
'self' => $user->profileUrl(),
|
'self' => $user->profileUrl(),
|
||||||
],
|
],
|
||||||
])->toArray(),
|
])->toArray(),
|
||||||
|
'versions' => $this->versions->map(fn ($version) => [
|
||||||
|
'data' => [
|
||||||
|
'type' => 'version',
|
||||||
|
'id' => $version->id,
|
||||||
|
],
|
||||||
|
|
||||||
|
// TODO: The download link to the version can be placed here, but I'd like to track the number of
|
||||||
|
// downloads that are made, so we'll need a new route/feature for that. #35
|
||||||
|
'links' => [
|
||||||
|
'self' => $version->link,
|
||||||
|
],
|
||||||
|
|
||||||
|
])->toArray(),
|
||||||
'license' => [
|
'license' => [
|
||||||
[
|
[
|
||||||
'data' => [
|
'data' => [
|
||||||
@ -54,15 +67,17 @@ class ModResource extends JsonResource
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
'includes' => $this->when(
|
'includes' => $this->when(
|
||||||
ApiController::shouldInclude('users'),
|
ApiController::shouldInclude(['users', 'license', 'versions']),
|
||||||
fn () => $this->users->map(fn ($user) => new UserResource($user))
|
fn () => collect([
|
||||||
|
'users' => $this->users->map(fn ($user) => new UserResource($user)),
|
||||||
|
'license' => new LicenseResource($this->license),
|
||||||
|
'versions' => $this->versions->map(fn ($version) => new ModVersionResource($version)),
|
||||||
|
])
|
||||||
|
->filter(fn ($value, $key) => ApiController::shouldInclude($key))
|
||||||
|
->flatten(1)
|
||||||
|
->values()
|
||||||
),
|
),
|
||||||
|
|
||||||
// TODO: Provide 'included' data for attached 'license':
|
|
||||||
//new LicenseResource($this->license)
|
|
||||||
|
|
||||||
'links' => [
|
'links' => [
|
||||||
'self' => route('mod.show', [
|
'self' => route('mod.show', [
|
||||||
'mod' => $this->id,
|
'mod' => $this->id,
|
||||||
|
54
app/Http/Resources/Api/V0/ModVersionResource.php
Normal file
54
app/Http/Resources/Api/V0/ModVersionResource.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources\Api\V0;
|
||||||
|
|
||||||
|
use App\Models\ModVersion;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
/** @mixin ModVersion */
|
||||||
|
class ModVersionResource extends JsonResource
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Transform the resource into an array.
|
||||||
|
*/
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => 'mod_version',
|
||||||
|
'id' => $this->id,
|
||||||
|
'attributes' => [
|
||||||
|
'hub_id' => $this->hub_id,
|
||||||
|
'mod_id' => $this->mod_id,
|
||||||
|
'version' => $this->version,
|
||||||
|
|
||||||
|
// TODO: This should only be visible on the mod version show route(?) which doesn't exist.
|
||||||
|
//'description' => $this->when(
|
||||||
|
// $request->routeIs('api.v0.modversion.show'),
|
||||||
|
// $this->description
|
||||||
|
//),
|
||||||
|
|
||||||
|
// TODO: The download link to the version can be placed here, but I'd like to track the number of
|
||||||
|
// downloads that are made, so we'll need a new route/feature for that. #35
|
||||||
|
'link' => $this->link,
|
||||||
|
|
||||||
|
'spt_version_id' => $this->spt_version_id,
|
||||||
|
'virus_total_link' => $this->virus_total_link,
|
||||||
|
'downloads' => $this->downloads,
|
||||||
|
'created_at' => $this->created_at,
|
||||||
|
'updated_at' => $this->updated_at,
|
||||||
|
'published_at' => $this->published_at,
|
||||||
|
],
|
||||||
|
'relationships' => [
|
||||||
|
'spt_version' => [
|
||||||
|
[
|
||||||
|
'data' => [
|
||||||
|
'type' => 'spt_version',
|
||||||
|
'id' => $this->spt_version_id,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Resources\Api\V0;
|
namespace App\Http\Resources\Api\V0;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Api\V0\ApiController;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\Resources\Json\JsonResource;
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
@ -9,9 +10,6 @@ use Illuminate\Http\Resources\Json\JsonResource;
|
|||||||
/** @mixin User */
|
/** @mixin User */
|
||||||
class UserResource extends JsonResource
|
class UserResource extends JsonResource
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Transform the resource into an array.
|
|
||||||
*/
|
|
||||||
public function toArray(Request $request): array
|
public function toArray(Request $request): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@ -21,6 +19,7 @@ class UserResource extends JsonResource
|
|||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'user_role_id' => $this->user_role_id,
|
'user_role_id' => $this->user_role_id,
|
||||||
'created_at' => $this->created_at,
|
'created_at' => $this->created_at,
|
||||||
|
'updated_at' => $this->updated_at,
|
||||||
],
|
],
|
||||||
'relationships' => [
|
'relationships' => [
|
||||||
'user_role' => [
|
'user_role' => [
|
||||||
@ -30,10 +29,10 @@ class UserResource extends JsonResource
|
|||||||
],
|
],
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
'includes' => $this->when(
|
||||||
// TODO: Provide 'included' data for attached 'user_role'
|
ApiController::shouldInclude('user_role'),
|
||||||
//'included' => [new UserRoleResource($this->role)],
|
new UserRoleResource($this->role)
|
||||||
|
),
|
||||||
'links' => [
|
'links' => [
|
||||||
'self' => $this->profileUrl(),
|
'self' => $this->profileUrl(),
|
||||||
],
|
],
|
||||||
|
25
app/Http/Resources/Api/V0/UserRoleResource.php
Normal file
25
app/Http/Resources/Api/V0/UserRoleResource.php
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources\Api\V0;
|
||||||
|
|
||||||
|
use App\Models\UserRole;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
/** @mixin UserRole */
|
||||||
|
class UserRoleResource extends JsonResource
|
||||||
|
{
|
||||||
|
public function toArray(Request $request): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'type' => 'user_role',
|
||||||
|
'id' => $this->id,
|
||||||
|
'attributes' => [
|
||||||
|
'name' => $this->name,
|
||||||
|
'short_name' => $this->short_name,
|
||||||
|
'description' => $this->description,
|
||||||
|
'color_class' => $this->color_class,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Http\Filters\V1\QueryFilter;
|
||||||
use App\Models\Scopes\DisabledScope;
|
use App\Models\Scopes\DisabledScope;
|
||||||
use App\Models\Scopes\PublishedScope;
|
use App\Models\Scopes\PublishedScope;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
@ -144,6 +146,14 @@ class Mod extends Model
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope a query by applying QueryFilter filters.
|
||||||
|
*/
|
||||||
|
public function scopeFilter(Builder $builder, QueryFilter $filters): Builder
|
||||||
|
{
|
||||||
|
return $filters->apply($builder);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that should be cast to native types.
|
* The attributes that should be cast to native types.
|
||||||
*/
|
*/
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Http\Filters\V1\QueryFilter;
|
||||||
use App\Notifications\ResetPassword;
|
use App\Notifications\ResetPassword;
|
||||||
use App\Notifications\VerifyEmail;
|
use App\Notifications\VerifyEmail;
|
||||||
use App\Traits\HasCoverPhoto;
|
use App\Traits\HasCoverPhoto;
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
@ -136,6 +138,14 @@ class User extends Authenticatable implements MustVerifyEmail
|
|||||||
return $this->belongsTo(UserRole::class, 'user_role_id');
|
return $this->belongsTo(UserRole::class, 'user_role_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope a query by applying QueryFilter filters.
|
||||||
|
*/
|
||||||
|
public function scopeFilter(Builder $builder, QueryFilter $filters): Builder
|
||||||
|
{
|
||||||
|
return $filters->apply($builder);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the disk that profile photos should be stored on.
|
* Get the disk that profile photos should be stored on.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user