Implements API Sorting

You can now sort mod and user data by whitelisted attributes.
This commit is contained in:
Refringe 2024-08-08 18:18:05 -04:00
parent 3a334033fe
commit 23a9cabf99
Signed by: Refringe
SSH Key Fingerprint: SHA256:t865XsQpfTeqPRBMN2G6+N8wlDjkgUCZF3WGW6O9N/k
4 changed files with 71 additions and 6 deletions

View File

@ -7,9 +7,36 @@ use Illuminate\Support\Str;
class ModFilter extends QueryFilter class ModFilter extends QueryFilter
{ {
protected array $sortable = [
'name',
'slug',
'teaser',
'source_code_link',
'featured',
'contains_ads',
'contains_ai_content',
'created_at',
'updated_at',
'published_at',
];
// TODO: Many of these are repeated across UserFilter and ModFilter. Consider refactoring into a shared trait. // 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. // Also, consider using common filter types and making the field names dynamic.
public function id(string $value): Builder
{
$ids = array_map('trim', explode(',', $value));
return $this->builder->whereIn('id', $ids);
}
public function hub_id(string $value): Builder
{
$ids = array_map('trim', explode(',', $value));
return $this->builder->whereIn('hub_id', $ids);
}
public function name(string $value): Builder public function name(string $value): Builder
{ {
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%). // The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
@ -45,7 +72,7 @@ class ModFilter extends QueryFilter
public function created_at(string $value): Builder public function created_at(string $value): Builder
{ {
// The API allows for a range of dates to be passed as a comma-separated list. // The API allows for a range of dates to be passed as a comma-separated list.
$dates = explode(',', $value); $dates = array_map('trim', explode(',', $value));
if (count($dates) > 1) { if (count($dates) > 1) {
return $this->builder->whereBetween('created_at', $dates); return $this->builder->whereBetween('created_at', $dates);
} }
@ -56,7 +83,7 @@ class ModFilter extends QueryFilter
public function updated_at(string $value): Builder public function updated_at(string $value): Builder
{ {
// The API allows for a range of dates to be passed as a comma-separated list. // The API allows for a range of dates to be passed as a comma-separated list.
$dates = explode(',', $value); $dates = array_map('trim', explode(',', $value));
if (count($dates) > 1) { if (count($dates) > 1) {
return $this->builder->whereBetween('updated_at', $dates); return $this->builder->whereBetween('updated_at', $dates);
} }
@ -67,7 +94,7 @@ class ModFilter extends QueryFilter
public function published_at(string $value): Builder public function published_at(string $value): Builder
{ {
// The API allows for a range of dates to be passed as a comma-separated list. // The API allows for a range of dates to be passed as a comma-separated list.
$dates = explode(',', $value); $dates = array_map('trim', explode(',', $value));
if (count($dates) > 1) { if (count($dates) > 1) {
return $this->builder->whereBetween('published_at', $dates); return $this->builder->whereBetween('published_at', $dates);
} }

View File

@ -4,12 +4,20 @@ namespace App\Http\Filters\V1;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Str;
abstract class QueryFilter abstract class QueryFilter
{ {
protected Builder $builder; protected Builder $builder;
public function __construct(protected Request $request) {} protected Request $request;
protected array $sortable = [];
public function __construct(Request $request)
{
$this->request = $request;
}
public function apply(Builder $builder): Builder public function apply(Builder $builder): Builder
{ {
@ -34,4 +42,20 @@ abstract class QueryFilter
return $this->builder; return $this->builder;
} }
protected function sort(string $values): Builder
{
$sortables = array_map('trim', explode(',', $values));
foreach ($sortables as $sortable) {
$direction = Str::startsWith($sortable, '-') ? 'desc' : 'asc';
$column = Str::of($sortable)->remove('-')->value();
if (in_array($column, $this->sortable)) {
$this->builder->orderBy($column, $direction);
}
}
return $this->builder;
}
} }

View File

@ -7,9 +7,22 @@ use Illuminate\Support\Str;
class UserFilter extends QueryFilter class UserFilter extends QueryFilter
{ {
protected array $sortable = [
'name',
'created_at',
'updated_at',
];
// TODO: Many of these are repeated across UserFilter and ModFilter. Consider refactoring into a shared trait. // 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. // Also, consider using common filter types and making the field names dynamic.
public function id(string $value): Builder
{
$ids = array_map('trim', explode(',', $value));
return $this->builder->whereIn('id', $ids);
}
public function name(string $value): Builder public function name(string $value): Builder
{ {
// The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%). // The API handles the wildcard character as an asterisk (*), but the database uses the percentage sign (%).
@ -21,7 +34,7 @@ class UserFilter extends QueryFilter
public function created_at(string $value): Builder public function created_at(string $value): Builder
{ {
// The API allows for a range of dates to be passed as a comma-separated list. // The API allows for a range of dates to be passed as a comma-separated list.
$dates = explode(',', $value); $dates = array_map('trim', explode(',', $value));
if (count($dates) > 1) { if (count($dates) > 1) {
return $this->builder->whereBetween('created_at', $dates); return $this->builder->whereBetween('created_at', $dates);
} }
@ -32,7 +45,7 @@ class UserFilter extends QueryFilter
public function updated_at(string $value): Builder public function updated_at(string $value): Builder
{ {
// The API allows for a range of dates to be passed as a comma-separated list. // The API allows for a range of dates to be passed as a comma-separated list.
$dates = explode(',', $value); $dates = array_map('trim', explode(',', $value));
if (count($dates) > 1) { if (count($dates) > 1) {
return $this->builder->whereBetween('updated_at', $dates); return $this->builder->whereBetween('updated_at', $dates);
} }

View File

@ -19,6 +19,7 @@ class ModResource extends JsonResource
'type' => 'mod', 'type' => 'mod',
'id' => $this->id, 'id' => $this->id,
'attributes' => [ 'attributes' => [
'hub_id' => $this->hub_id,
'name' => $this->name, 'name' => $this->name,
'slug' => $this->slug, 'slug' => $this->slug,
'teaser' => $this->teaser, 'teaser' => $this->teaser,