Skip to content

Commit

Permalink
Implementing in-app filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
dominiquevienne committed May 30, 2022
1 parent c658b46 commit 573f51f
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 4 deletions.
49 changes: 45 additions & 4 deletions src/Http/Controllers/AbstractController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Dominiquevienne\LaravelMagic\Http\Controllers;

use Dominiquevienne\LaravelMagic\Http\Filters\GenericFilter;
use Dominiquevienne\LaravelMagic\Traits\ClassSuggestion;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
Expand Down Expand Up @@ -41,6 +42,7 @@ class AbstractController extends Controller
'destroy',
'update',
'store',
'validationRules',
];
private bool $usePublicationStatusTrait = false;

Expand Down Expand Up @@ -165,6 +167,15 @@ public function index(Request $request): Response

/** @var Builder $query */
$query = $modelName::query();

/** Apply in-app provided filters */
$filterClass = $this->getSuggestedClassName('filter');
if (class_exists($filterClass)) {
$query = $filterClass::applyFilter($query);
} else {
$query = GenericFilter::applyFilter($query);
}

if ($this->usePublicationStatusTrait) {
$query = $query->published();
}
Expand Down Expand Up @@ -232,6 +243,15 @@ public function show(Request $request, int $objectId): Response
$fields = $this->filterFields($fields);

$query = $modelName::query();

/** Apply in-app provided filters */
$filterClass = $this->getSuggestedClassName('filter');
if (class_exists($filterClass)) {
$query = $filterClass::applyFilter($query);
} else {
$query = GenericFilter::applyFilter($query);
}

foreach ($with as $relationshipName) {
$query = $query->with([$relationshipName => function($query) {
$query->take(self::PAGINATION_MAX_VALUE);
Expand Down Expand Up @@ -271,7 +291,7 @@ public function show(Request $request, int $objectId): Response
* @param int $objectId
* @return Response
* @throws ControllerAutomationException
* @todo Implement rights management
* @todo Implement PK usage
*/
public function destroy(int $objectId): Response
{
Expand All @@ -280,7 +300,16 @@ public function destroy(int $objectId): Response
/** @var AbstractModel $modelName */
$modelName = $this->modelName;
try {
$item = $modelName::findOrFail($objectId);
$query = $modelName::query();

/** Apply in-app provided filters */
$filterClass = $this->getSuggestedClassName('filter');
if (class_exists($filterClass)) {
$query = $filterClass::applyFilter($query);
} else {
$query = GenericFilter::applyFilter($query);
}
$item = $query->where('id', '=', $objectId)->firstOrFail();

if ($item->delete()) {
$meta = [
Expand Down Expand Up @@ -314,15 +343,26 @@ public function destroy(int $objectId): Response
* @param int $objectId
* @return Response
* @throws ControllerAutomationException
* @todo Implement PK usage
*/
public function update(BootstrapRequest $request, int $objectId): Response
{
$this->recordCall(__METHOD__);

/** @var AbstractModel $object */
$object = new $this->modelName;
$modelName = new $this->modelName;
try {
$object = $object->findOrFail($objectId);
$query = $modelName::query();

/** Apply in-app provided filters */
$filterClass = $this->getSuggestedClassName('filter');
if (class_exists($filterClass)) {
$query = $filterClass::applyFilter($query);
} else {
$query = GenericFilter::applyFilter($query);
}
$object = $query->where('id', '=', $objectId)->firstOrFail();

$meta = $this->saveByFillable($object, $request);
} catch (ModelNotFoundException $exception) {
$meta = [
Expand Down Expand Up @@ -424,6 +464,7 @@ private function filterFields(?string $fields): array
*/
public function validationRules(): Response
{
$this->recordCall(__METHOD__);
$requestClass = $this->getSuggestedClassName('request');
if (class_exists($requestClass)) {
$requestObject = new $requestClass;
Expand Down
23 changes: 23 additions & 0 deletions src/Http/Filters/GenericFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Dominiquevienne\LaravelMagic\Http\Filters;

use Dominiquevienne\LaravelMagic\Exceptions\ControllerAutomationException;
use Illuminate\Database\Eloquent\Builder;

class GenericFilter
{
/**
* @param Builder $query
* @return Builder
* @throws ControllerAutomationException
*/
static public function applyFilter(Builder $query): Builder
{
if (strtolower(env('LARAVEL_MAGIC_FILTER_MODE')) === 'paranoid') {
throw new ControllerAutomationException('Laravel Magic filtering mode is set to paranoid, please create a filter class for your model');
}

return $query;
}
}
3 changes: 3 additions & 0 deletions src/Traits/ClassSuggestion.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ private function getSuggestedClassName(string $type = 'model', ?object $controll
$availableTypes = [
'model' => 'Models',
'request' => 'Http\\Requests',
'filter' => 'Http\\Filters',
];
if (!array_key_exists($type, $availableTypes)) {
throw new ControllerAutomationException('The class type ' . $type . ' is not supported');
Expand All @@ -45,6 +46,8 @@ private function getSuggestedClassName(string $type = 'model', ?object $controll
$suggestedModelBaseClassName = preg_replace($this->regexController, '', $controllerBaseClassName);
if ($type === 'request') {
$suggestedModelBaseClassName .= 'Request';
} elseif ($type === 'filter') {
$suggestedModelBaseClassName .= 'Filter';
}

return $suggestedNameSpace . '\\' . $suggestedModelBaseClassName;
Expand Down

0 comments on commit 573f51f

Please sign in to comment.