diff --git a/app/Http/Filters/V1/ModFilter.php b/app/Http/Filters/V1/ModFilter.php index 722ba71..dd64b11 100644 --- a/app/Http/Filters/V1/ModFilter.php +++ b/app/Http/Filters/V1/ModFilter.php @@ -7,9 +7,36 @@ use Illuminate\Support\Str; 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. // 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 { // 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 { // 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) { return $this->builder->whereBetween('created_at', $dates); } @@ -56,7 +83,7 @@ class ModFilter extends QueryFilter 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); + $dates = array_map('trim', explode(',', $value)); if (count($dates) > 1) { return $this->builder->whereBetween('updated_at', $dates); } @@ -67,7 +94,7 @@ class ModFilter extends QueryFilter 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); + $dates = array_map('trim', explode(',', $value)); if (count($dates) > 1) { return $this->builder->whereBetween('published_at', $dates); } diff --git a/app/Http/Filters/V1/QueryFilter.php b/app/Http/Filters/V1/QueryFilter.php index 0e4b8e6..f636cd7 100644 --- a/app/Http/Filters/V1/QueryFilter.php +++ b/app/Http/Filters/V1/QueryFilter.php @@ -4,12 +4,20 @@ namespace App\Http\Filters\V1; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\Request; +use Illuminate\Support\Str; abstract class QueryFilter { 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 { @@ -34,4 +42,20 @@ abstract class QueryFilter 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; + } } diff --git a/app/Http/Filters/V1/UserFilter.php b/app/Http/Filters/V1/UserFilter.php index 9684150..1eec8fc 100644 --- a/app/Http/Filters/V1/UserFilter.php +++ b/app/Http/Filters/V1/UserFilter.php @@ -7,9 +7,22 @@ use Illuminate\Support\Str; 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. // 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 { // 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 { // 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) { return $this->builder->whereBetween('created_at', $dates); } @@ -32,7 +45,7 @@ class UserFilter extends QueryFilter 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); + $dates = array_map('trim', explode(',', $value)); if (count($dates) > 1) { return $this->builder->whereBetween('updated_at', $dates); } diff --git a/app/Http/Resources/Api/V0/ModResource.php b/app/Http/Resources/Api/V0/ModResource.php index 1737e26..d02762d 100644 --- a/app/Http/Resources/Api/V0/ModResource.php +++ b/app/Http/Resources/Api/V0/ModResource.php @@ -19,6 +19,7 @@ class ModResource extends JsonResource 'type' => 'mod', 'id' => $this->id, 'attributes' => [ + 'hub_id' => $this->hub_id, 'name' => $this->name, 'slug' => $this->slug, 'teaser' => $this->teaser,