From 0b3e9f793c39d662af388dbcc727ffd6847743b6 Mon Sep 17 00:00:00 2001 From: Eduard Lupacescu Date: Wed, 9 Sep 2020 12:20:53 +0300 Subject: [PATCH 1/3] Adding policy for attach/detach. --- .../RepositoryAttachController.php | 5 +- .../RepositoryDetachController.php | 3 +- src/Http/Requests/RepositoryAttachRequest.php | 17 +++ src/Http/Requests/RepositoryDetachRequest.php | 17 +++ src/Repositories/Repository.php | 74 ++++++---- src/Repositories/ValidatingTrait.php | 20 +++ src/Restify.php | 15 ++- src/Traits/AuthorizableModels.php | 40 +++++- .../RepositoryAttachControllerTest.php | 63 +++++++++ tests/Fixtures/Company/CompanyPolicy.php | 127 ++++++++++++++++++ 10 files changed, 345 insertions(+), 36 deletions(-) create mode 100644 tests/Fixtures/Company/CompanyPolicy.php diff --git a/src/Http/Controllers/RepositoryAttachController.php b/src/Http/Controllers/RepositoryAttachController.php index c25a5eefa..0f78ef2a5 100644 --- a/src/Http/Controllers/RepositoryAttachController.php +++ b/src/Http/Controllers/RepositoryAttachController.php @@ -14,7 +14,7 @@ class RepositoryAttachController extends RepositoryController public function __invoke(RepositoryAttachRequest $request) { $model = $request->findModelOrFail(); - $repository = $request->repository()->allowToUpdate($request); + $repository = $request->repository(); if (is_callable($method = $this->guessMethodName($request, $repository))) { return call_user_func($method, $request, $repository, $model); @@ -23,6 +23,7 @@ public function __invoke(RepositoryAttachRequest $request) return $repository->attach( $request, $request->repositoryId, collect(Arr::wrap($request->input($request->relatedRepository))) + ->filter(fn($relatedRepositoryId) => $request->repository()->allowToAttach($request, $request->attachRelatedModels())) ->map(fn ($relatedRepositoryId) => $this->initializePivot( $request, $model->{$request->viaRelationship ?? $request->relatedRepository}(), $relatedRepositoryId )) @@ -76,7 +77,7 @@ public function guessMethodName(RestifyRequest $request, Repository $repository) return $cb; } - $methodGuesser = 'attach'.Str::studly($request->relatedRepository); + $methodGuesser = 'attach' . Str::studly($request->relatedRepository); if (method_exists($repository, $methodGuesser)) { return [$repository, $methodGuesser]; diff --git a/src/Http/Controllers/RepositoryDetachController.php b/src/Http/Controllers/RepositoryDetachController.php index 1adeb4a1d..498aa6d3d 100644 --- a/src/Http/Controllers/RepositoryDetachController.php +++ b/src/Http/Controllers/RepositoryDetachController.php @@ -17,7 +17,8 @@ public function __invoke(RepositoryDetachRequest $request) return $repository->detach( $request, $request->repositoryId, collect(Arr::wrap($request->input($request->relatedRepository))) - ->map(fn ($relatedRepositoryId) => $this->initializePivot( + ->filter(fn($relatedRepositoryId) => $request->repository()->allowToDetach($request, $request->detachRelatedModels())) + ->map(fn ($relatedRepositoryId) => $this->initializePivot( $request, $model->{$request->viaRelationship ?? $request->relatedRepository}(), $relatedRepositoryId )) ); diff --git a/src/Http/Requests/RepositoryAttachRequest.php b/src/Http/Requests/RepositoryAttachRequest.php index 972af0822..6364821ac 100644 --- a/src/Http/Requests/RepositoryAttachRequest.php +++ b/src/Http/Requests/RepositoryAttachRequest.php @@ -2,6 +2,23 @@ namespace Binaryk\LaravelRestify\Http\Requests; +use Binaryk\LaravelRestify\Restify; +use Illuminate\Support\Arr; +use Illuminate\Support\Collection; + class RepositoryAttachRequest extends RestifyRequest { + public function attachRelatedModels(): Collection + { + $relatedRepository = $this->repository( + Restify::repositoryForTable($table = $this->relatedRepository)::uriKey() + ); + + if(is_null($relatedRepository)) { + abort(400, "Missing repository for the [$table] table"); + } + + return collect(Arr::wrap($this->input($this->relatedRepository))) + ->map(fn($id) => $relatedRepository->model()->newModelQuery()->whereKey($id)->first()); + } } diff --git a/src/Http/Requests/RepositoryDetachRequest.php b/src/Http/Requests/RepositoryDetachRequest.php index 15987806d..d4c1e9470 100644 --- a/src/Http/Requests/RepositoryDetachRequest.php +++ b/src/Http/Requests/RepositoryDetachRequest.php @@ -2,6 +2,23 @@ namespace Binaryk\LaravelRestify\Http\Requests; +use Binaryk\LaravelRestify\Restify; +use Illuminate\Support\Arr; +use Illuminate\Support\Collection; + class RepositoryDetachRequest extends RestifyRequest { + public function detachRelatedModels(): Collection + { + $relatedRepository = $this->repository( + Restify::repositoryForTable($table = $this->relatedRepository)::uriKey() + ); + + if (is_null($relatedRepository)) { + abort(400, "Missing repository for the [$table] table"); + } + + return collect(Arr::wrap($this->input($this->relatedRepository))) + ->map(fn($id) => $relatedRepository->model()->newModelQuery()->whereKey($id)->first()); + } } diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index 83b4cee33..8fa0b939a 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -214,7 +214,7 @@ public static function newModel(): Model public static function query(RestifyRequest $request) { - if (! $request->isViaRepository()) { + if (!$request->isViaRepository()) { return static::newModel()->query(); } @@ -279,8 +279,8 @@ public function collectFields(RestifyRequest $request) if ($this instanceof Mergeable) { $fillable = collect($this->resource->getFillable()) - ->filter(fn ($attribute) => $fields->contains('attribute', $attribute) === false) - ->map(fn ($attribute) => Field::new($attribute)); + ->filter(fn($attribute) => $fields->contains('attribute', $attribute) === false) + ->map(fn($attribute) => Field::new($attribute)); $fields = $fields->merge($fillable); } @@ -291,14 +291,14 @@ public function collectFields(RestifyRequest $request) private function indexFields(RestifyRequest $request): Collection { return $this->collectFields($request) - ->filter(fn (Field $field) => ! $field->isHiddenOnIndex($request, $this)) + ->filter(fn(Field $field) => !$field->isHiddenOnIndex($request, $this)) ->values(); } private function showFields(RestifyRequest $request): Collection { return $this->collectFields($request) - ->filter(fn (Field $field) => ! $field->isHiddenOnShow($request, $this)) + ->filter(fn(Field $field) => !$field->isHiddenOnShow($request, $this)) ->values(); } @@ -412,10 +412,10 @@ public static function routes(Router $router, $attributes, $wrap = false) public function resolveShowAttributes(RestifyRequest $request) { $fields = $this->showFields($request) - ->filter(fn (Field $field) => $field->authorize($request)) - ->each(fn (Field $field) => $field->resolveForShow($this)) - ->map(fn (Field $field) => $field->serializeToValue($request)) - ->mapWithKeys(fn ($value) => $value) + ->filter(fn(Field $field) => $field->authorize($request)) + ->each(fn(Field $field) => $field->resolveForShow($this)) + ->map(fn(Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn($value) => $value) ->all(); if ($this instanceof Mergeable) { @@ -433,7 +433,7 @@ public function resolveShowAttributes(RestifyRequest $request) return false; } - if (! $field->authorize($request)) { + if (!$field->authorize($request)) { return false; } @@ -454,10 +454,10 @@ public function resolveIndexAttributes($request) { // Resolve the show method, and attach the value to the array $fields = $this->indexFields($request) - ->filter(fn (Field $field) => $field->authorize($request)) - ->each(fn (Field $field) => $field->resolveForIndex($this)) - ->map(fn (Field $field) => $field->serializeToValue($request)) - ->mapWithKeys(fn ($value) => $value) + ->filter(fn(Field $field) => $field->authorize($request)) + ->each(fn(Field $field) => $field->resolveForIndex($this)) + ->map(fn(Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn($value) => $value) ->all(); if ($this instanceof Mergeable) { @@ -475,7 +475,7 @@ public function resolveIndexAttributes($request) return false; } - if (! $field->authorize($request)) { + if (!$field->authorize($request)) { return false; } @@ -542,7 +542,7 @@ public function resolveRelationships($request): array } $withs[$relation] = $paginator instanceof Collection - ? $paginator->map(fn (Model $item) => [ + ? $paginator->map(fn(Model $item) => [ 'attributes' => $item->toArray(), ]) : $paginator; @@ -599,10 +599,10 @@ public function index(RestifyRequest $request) return $this->response([ 'meta' => $this->resolveIndexMainMeta( - $request, $items->map(fn (self $repository) => $repository->resource), RepositoryCollection::meta($paginator->toArray()) + $request, $items->map(fn(self $repository) => $repository->resource), RepositoryCollection::meta($paginator->toArray()) ) ?? RepositoryCollection::meta($paginator->toArray()), 'links' => RepositoryCollection::paginationLinks($paginator->toArray()), - 'data' => $items->map(fn (self $repository) => $repository->serializeForIndex($request)), + 'data' => $items->map(fn(self $repository) => $repository->serializeForIndex($request)), ]); } @@ -641,7 +641,7 @@ public function store(RestifyRequest $request) } } - $this->storeFields($request)->each(fn (Field $field) => $field->invokeAfter($request, $this->resource)); + $this->storeFields($request)->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); }); static::stored($this->resource, $request); @@ -665,7 +665,7 @@ public function storeBulk(RepositoryStoreBulkRequest $request) $this->resource->save(); - $this->storeBulkFields($request)->each(fn (Field $field) => $field->invokeAfter($request, $this->resource)); + $this->storeBulkFields($request)->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); return $this->resource; }); @@ -690,6 +690,8 @@ public function update(RestifyRequest $request, $repositoryId) return $this->resource; }); + $this->updateFields($request)->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); + return $this->response() ->data($this->serializeForShow($request)) ->success(); @@ -712,8 +714,8 @@ public function updateBulk(RestifyRequest $request, $repositoryId, int $row) public function attach(RestifyRequest $request, $repositoryId, Collection $pivots) { DB::transaction(function () use ($request, $pivots) { - return $pivots->map(fn ($pivot) => $pivot->forceFill($request->except($request->relatedRepository))) - ->map(fn ($pivot) => $pivot->save()); + return $pivots->map(fn($pivot) => $pivot->forceFill($request->except($request->relatedRepository))) + ->map(fn($pivot) => $pivot->save()); }); return $this->response() @@ -724,7 +726,7 @@ public function attach(RestifyRequest $request, $repositoryId, Collection $pivot public function detach(RestifyRequest $request, $repositoryId, Collection $pivots) { $deleted = DB::transaction(function () use ($pivots) { - return $pivots->map(fn ($pivot) => $pivot->delete()); + return $pivots->map(fn($pivot) => $pivot->delete()); }); return $this->response() @@ -754,6 +756,24 @@ public function allowToUpdate(RestifyRequest $request, $payload = null): self return $this; } + public function allowToAttach(RestifyRequest $request, Collection $attachers): self + { + $methodGuesser = 'attach' . Str::studly($request->relatedRepository); + + $attachers->each(fn ($model) => $this->authorizeToAttach($request, $methodGuesser, $model)); + + return $this; + } + + public function allowToDetach(RestifyRequest $request, Collection $attachers): self + { + $methodGuesser = 'detach' . Str::studly($request->relatedRepository); + + $attachers->each(fn ($model) => $this->authorizeToDetach($request, $methodGuesser, $model)); + + return $this; + } + public function allowToUpdateBulk(RestifyRequest $request, $payload = null): self { $this->authorizeToUpdateBulk($request); @@ -834,7 +854,7 @@ public function response($content = '', $status = 200, array $headers = []): Res public function serializeForShow(RestifyRequest $request): array { return $this->filter([ - 'id' => $this->when($this->resource->id, fn () => $this->getShowId($request)), + 'id' => $this->when($this->resource->id, fn() => $this->getShowId($request)), 'type' => $this->when($type = $this->getType($request), $type), 'attributes' => $request->isShowRequest() ? $this->resolveShowAttributes($request) : $this->resolveIndexAttributes($request), 'relationships' => $this->when(value($related = $this->resolveRelationships($request)), $related), @@ -847,7 +867,7 @@ public function serializeForIndex(RestifyRequest $request): array return $this->filter([ 'id' => $this->when($id = $this->getShowId($request), $id), 'type' => $this->when($type = $this->getType($request), $type), - 'attributes' => $this->when((bool) $attrs = $this->resolveIndexAttributes($request), $attrs), + 'attributes' => $this->when((bool)$attrs = $this->resolveIndexAttributes($request), $attrs), 'relationships' => $this->when(value($related = $this->resolveRelationships($request)), $related), 'meta' => $this->when(value($meta = $this->resolveIndexMeta($request)), $meta), ]); @@ -897,12 +917,12 @@ protected static function fillBulkFields(RestifyRequest $request, Model $model, public static function uriTo(Model $model) { - return Restify::path().'/'.static::uriKey().'/'.$model->getKey(); + return Restify::path() . '/' . static::uriKey() . '/' . $model->getKey(); } public function availableFilters(RestifyRequest $request) { - return collect($this->filter($this->filters($request)))->each(fn (Filter $filter) => $filter->authorizedToSee($request)) + return collect($this->filter($this->filters($request)))->each(fn(Filter $filter) => $filter->authorizedToSee($request)) ->values(); } diff --git a/src/Repositories/ValidatingTrait.php b/src/Repositories/ValidatingTrait.php index 9dfb18eeb..64d193050 100644 --- a/src/Repositories/ValidatingTrait.php +++ b/src/Repositories/ValidatingTrait.php @@ -98,6 +98,26 @@ public static function validatorForUpdate(RestifyRequest $request, $resource = n }); } + public static function validatorForAttach(RestifyRequest $request, $resource = null, array $plainPayload = null) + { + /** * @var Repository $on */ + $on = $resource ?? static::resolveWith(static::newModel()); + + $messages = $on->collectFields($request)->flatMap(function ($k) { + $messages = []; + foreach ($k->messages as $ruleFor => $message) { + $messages[$k->attribute.'.'.$ruleFor] = $message; + } + + return $messages; + })->toArray(); + + return Validator::make($plainPayload ?? $request->all(), $on->getUpdatingRules($request), $messages)->after(function ($validator) use ($request) { + static::afterValidation($request, $validator); + static::afterUpdatingValidation($request, $validator); + }); + } + public static function validatorForUpdateBulk(RestifyRequest $request, $resource = null, array $plainPayload = null) { /** * @var Repository $on */ diff --git a/src/Restify.php b/src/Restify.php index 384085ac9..9eeae4469 100644 --- a/src/Restify.php +++ b/src/Restify.php @@ -52,7 +52,7 @@ public static function repositoryForKey($key) } /** - * Get the repository class name for a given key. + * Get the repository class name for a given model. * * @param string $model * @return string @@ -68,6 +68,19 @@ public static function repositoryForModel($model) }); } + /** + * Get the repository class name for a given table name. + * + * @param string $table + * @return string + */ + public static function repositoryForTable($table) + { + return collect(static::$repositories)->first(function ($value) use ($table) { + return app($value::$model)->getTable() === $table; + }); + } + /** * Register the given repositories. * diff --git a/src/Traits/AuthorizableModels.php b/src/Traits/AuthorizableModels.php index bbd9acf2b..4bde27e00 100644 --- a/src/Traits/AuthorizableModels.php +++ b/src/Traits/AuthorizableModels.php @@ -23,7 +23,7 @@ trait AuthorizableModels */ public static function authorizable() { - return ! is_null(Gate::getPolicyFor(static::newModel())); + return !is_null(Gate::getPolicyFor(static::newModel())); } /** @@ -35,7 +35,7 @@ public static function authorizable() */ public function authorizeToUseRepository(Request $request) { - if (! static::authorizable()) { + if (!static::authorizable()) { return; } @@ -52,7 +52,7 @@ public function authorizeToUseRepository(Request $request) */ public static function authorizedToUseRepository(Request $request) { - if (! static::authorizable()) { + if (!static::authorizable()) { return true; } @@ -93,14 +93,14 @@ public function authorizedToShow(Request $request) */ public static function authorizeToStore(Request $request) { - if (! static::authorizedToStore($request)) { + if (!static::authorizedToStore($request)) { throw new AuthorizationException('Unauthorized to store.'); } } public static function authorizeToStoreBulk(Request $request) { - if (! static::authorizedToStoreBulk($request)) { + if (!static::authorizedToStoreBulk($request)) { throw new AuthorizationException('Unauthorized to store bulk.'); } } @@ -142,6 +142,36 @@ public function authorizeToUpdate(Request $request) $this->authorizeTo($request, 'update'); } + public function authorizeToAttach(Request $request, $method, $model) + { + if (! static::authorizable()) { + return true; + } + + $authorized = method_exists(Gate::getPolicyFor($this->model()), $method) + ? Gate::check($method, [$this->model(), $model]) + : true; + + if (false === $authorized) { + throw new AuthorizationException(); + } + } + + public function authorizeToDetach(Request $request, $method, $model) + { + if (! static::authorizable()) { + return true; + } + + $authorized = method_exists(Gate::getPolicyFor($this->model()), $method) + ? Gate::check($method, [$this->model(), $model]) + : true; + + if (false === $authorized) { + throw new AuthorizationException(); + } + } + public function authorizeToUpdateBulk(Request $request) { $this->authorizeTo($request, 'updateBulk'); diff --git a/tests/Controllers/RepositoryAttachControllerTest.php b/tests/Controllers/RepositoryAttachControllerTest.php index 24e2ade68..07a1eadf3 100644 --- a/tests/Controllers/RepositoryAttachControllerTest.php +++ b/tests/Controllers/RepositoryAttachControllerTest.php @@ -3,7 +3,10 @@ namespace Binaryk\LaravelRestify\Tests\Controllers; use Binaryk\LaravelRestify\Tests\Fixtures\Company\Company; +use Binaryk\LaravelRestify\Tests\Fixtures\Company\CompanyPolicy; +use Binaryk\LaravelRestify\Tests\Fixtures\User\User; use Binaryk\LaravelRestify\Tests\IntegrationTest; +use Illuminate\Support\Facades\Gate; class RepositoryAttachControllerTest extends IntegrationTest { @@ -63,4 +66,64 @@ public function test_after_attach_a_user_to_company_number_of_users_increased() $usersFromCompany = $this->getJson('/restify-api/users?viaRepository=companies&viaRepositoryId=1&viaRelationship=users'); $this->assertCount(1, $usersFromCompany->json('data')); } + + public function test_policy_to_attach_a_user_to_a_company() + { + Gate::policy(Company::class, CompanyPolicy::class); + + $user = $this->mockUsers(2)->first(); + $company = factory(Company::class)->create(); + $this->authenticate( + factory(User::class)->create() + ); + + $_SERVER['allow_attach_users'] = false; + + $this->postJson('restify-api/companies/'.$company->id.'/attach/users', [ + 'users' => $user->id, + 'is_admin' => true, + ]) + ->assertForbidden(); + + $_SERVER['allow_attach_users'] = true; + + $this->postJson('restify-api/companies/'.$company->id.'/attach/users', [ + 'users' => $user->id, + 'is_admin' => true, + ]) + ->assertCreated(); + } + + public function test_policy_to_detach_a_user_to_a_company() + { + Gate::policy(Company::class, CompanyPolicy::class); + + $user = $this->mockUsers(2)->first(); + $company = factory(Company::class)->create(); + $this->authenticate( + factory(User::class)->create() + ); + + $this->postJson('restify-api/companies/'.$company->id.'/attach/users', [ + 'users' => $user->id, + 'is_admin' => true, + ]) + ->assertCreated(); + + $_SERVER['allow_detach_users'] = false; + + $this->postJson('restify-api/companies/'.$company->id.'/detach/users', [ + 'users' => $user->id, + 'is_admin' => true, + ]) + ->assertForbidden(); + + $_SERVER['allow_detach_users'] = true; + + $this->postJson('restify-api/companies/'.$company->id.'/detach/users', [ + 'users' => $user->id, + 'is_admin' => true, + ]) + ->assertNoContent(); + } } diff --git a/tests/Fixtures/Company/CompanyPolicy.php b/tests/Fixtures/Company/CompanyPolicy.php new file mode 100644 index 000000000..0a2e5c9f0 --- /dev/null +++ b/tests/Fixtures/Company/CompanyPolicy.php @@ -0,0 +1,127 @@ + Date: Wed, 9 Sep 2020 12:21:18 +0300 Subject: [PATCH 2/3] Apply fixes from StyleCI (#260) --- .../RepositoryAttachController.php | 4 +- .../RepositoryDetachController.php | 2 +- src/Http/Requests/RepositoryAttachRequest.php | 4 +- src/Http/Requests/RepositoryDetachRequest.php | 2 +- src/Repositories/Repository.php | 60 +++++++++---------- src/Traits/AuthorizableModels.php | 10 ++-- tests/Fixtures/Company/CompanyPolicy.php | 3 +- 7 files changed, 42 insertions(+), 43 deletions(-) diff --git a/src/Http/Controllers/RepositoryAttachController.php b/src/Http/Controllers/RepositoryAttachController.php index 0f78ef2a5..11299790e 100644 --- a/src/Http/Controllers/RepositoryAttachController.php +++ b/src/Http/Controllers/RepositoryAttachController.php @@ -23,7 +23,7 @@ public function __invoke(RepositoryAttachRequest $request) return $repository->attach( $request, $request->repositoryId, collect(Arr::wrap($request->input($request->relatedRepository))) - ->filter(fn($relatedRepositoryId) => $request->repository()->allowToAttach($request, $request->attachRelatedModels())) + ->filter(fn ($relatedRepositoryId) => $request->repository()->allowToAttach($request, $request->attachRelatedModels())) ->map(fn ($relatedRepositoryId) => $this->initializePivot( $request, $model->{$request->viaRelationship ?? $request->relatedRepository}(), $relatedRepositoryId )) @@ -77,7 +77,7 @@ public function guessMethodName(RestifyRequest $request, Repository $repository) return $cb; } - $methodGuesser = 'attach' . Str::studly($request->relatedRepository); + $methodGuesser = 'attach'.Str::studly($request->relatedRepository); if (method_exists($repository, $methodGuesser)) { return [$repository, $methodGuesser]; diff --git a/src/Http/Controllers/RepositoryDetachController.php b/src/Http/Controllers/RepositoryDetachController.php index 498aa6d3d..0feccd109 100644 --- a/src/Http/Controllers/RepositoryDetachController.php +++ b/src/Http/Controllers/RepositoryDetachController.php @@ -17,7 +17,7 @@ public function __invoke(RepositoryDetachRequest $request) return $repository->detach( $request, $request->repositoryId, collect(Arr::wrap($request->input($request->relatedRepository))) - ->filter(fn($relatedRepositoryId) => $request->repository()->allowToDetach($request, $request->detachRelatedModels())) + ->filter(fn ($relatedRepositoryId) => $request->repository()->allowToDetach($request, $request->detachRelatedModels())) ->map(fn ($relatedRepositoryId) => $this->initializePivot( $request, $model->{$request->viaRelationship ?? $request->relatedRepository}(), $relatedRepositoryId )) diff --git a/src/Http/Requests/RepositoryAttachRequest.php b/src/Http/Requests/RepositoryAttachRequest.php index 6364821ac..6490f8775 100644 --- a/src/Http/Requests/RepositoryAttachRequest.php +++ b/src/Http/Requests/RepositoryAttachRequest.php @@ -14,11 +14,11 @@ public function attachRelatedModels(): Collection Restify::repositoryForTable($table = $this->relatedRepository)::uriKey() ); - if(is_null($relatedRepository)) { + if (is_null($relatedRepository)) { abort(400, "Missing repository for the [$table] table"); } return collect(Arr::wrap($this->input($this->relatedRepository))) - ->map(fn($id) => $relatedRepository->model()->newModelQuery()->whereKey($id)->first()); + ->map(fn ($id) => $relatedRepository->model()->newModelQuery()->whereKey($id)->first()); } } diff --git a/src/Http/Requests/RepositoryDetachRequest.php b/src/Http/Requests/RepositoryDetachRequest.php index d4c1e9470..a7e29d1e5 100644 --- a/src/Http/Requests/RepositoryDetachRequest.php +++ b/src/Http/Requests/RepositoryDetachRequest.php @@ -19,6 +19,6 @@ public function detachRelatedModels(): Collection } return collect(Arr::wrap($this->input($this->relatedRepository))) - ->map(fn($id) => $relatedRepository->model()->newModelQuery()->whereKey($id)->first()); + ->map(fn ($id) => $relatedRepository->model()->newModelQuery()->whereKey($id)->first()); } } diff --git a/src/Repositories/Repository.php b/src/Repositories/Repository.php index 8fa0b939a..2a3ae52c5 100644 --- a/src/Repositories/Repository.php +++ b/src/Repositories/Repository.php @@ -214,7 +214,7 @@ public static function newModel(): Model public static function query(RestifyRequest $request) { - if (!$request->isViaRepository()) { + if (! $request->isViaRepository()) { return static::newModel()->query(); } @@ -279,8 +279,8 @@ public function collectFields(RestifyRequest $request) if ($this instanceof Mergeable) { $fillable = collect($this->resource->getFillable()) - ->filter(fn($attribute) => $fields->contains('attribute', $attribute) === false) - ->map(fn($attribute) => Field::new($attribute)); + ->filter(fn ($attribute) => $fields->contains('attribute', $attribute) === false) + ->map(fn ($attribute) => Field::new($attribute)); $fields = $fields->merge($fillable); } @@ -291,14 +291,14 @@ public function collectFields(RestifyRequest $request) private function indexFields(RestifyRequest $request): Collection { return $this->collectFields($request) - ->filter(fn(Field $field) => !$field->isHiddenOnIndex($request, $this)) + ->filter(fn (Field $field) => ! $field->isHiddenOnIndex($request, $this)) ->values(); } private function showFields(RestifyRequest $request): Collection { return $this->collectFields($request) - ->filter(fn(Field $field) => !$field->isHiddenOnShow($request, $this)) + ->filter(fn (Field $field) => ! $field->isHiddenOnShow($request, $this)) ->values(); } @@ -412,10 +412,10 @@ public static function routes(Router $router, $attributes, $wrap = false) public function resolveShowAttributes(RestifyRequest $request) { $fields = $this->showFields($request) - ->filter(fn(Field $field) => $field->authorize($request)) - ->each(fn(Field $field) => $field->resolveForShow($this)) - ->map(fn(Field $field) => $field->serializeToValue($request)) - ->mapWithKeys(fn($value) => $value) + ->filter(fn (Field $field) => $field->authorize($request)) + ->each(fn (Field $field) => $field->resolveForShow($this)) + ->map(fn (Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn ($value) => $value) ->all(); if ($this instanceof Mergeable) { @@ -433,7 +433,7 @@ public function resolveShowAttributes(RestifyRequest $request) return false; } - if (!$field->authorize($request)) { + if (! $field->authorize($request)) { return false; } @@ -454,10 +454,10 @@ public function resolveIndexAttributes($request) { // Resolve the show method, and attach the value to the array $fields = $this->indexFields($request) - ->filter(fn(Field $field) => $field->authorize($request)) - ->each(fn(Field $field) => $field->resolveForIndex($this)) - ->map(fn(Field $field) => $field->serializeToValue($request)) - ->mapWithKeys(fn($value) => $value) + ->filter(fn (Field $field) => $field->authorize($request)) + ->each(fn (Field $field) => $field->resolveForIndex($this)) + ->map(fn (Field $field) => $field->serializeToValue($request)) + ->mapWithKeys(fn ($value) => $value) ->all(); if ($this instanceof Mergeable) { @@ -475,7 +475,7 @@ public function resolveIndexAttributes($request) return false; } - if (!$field->authorize($request)) { + if (! $field->authorize($request)) { return false; } @@ -542,7 +542,7 @@ public function resolveRelationships($request): array } $withs[$relation] = $paginator instanceof Collection - ? $paginator->map(fn(Model $item) => [ + ? $paginator->map(fn (Model $item) => [ 'attributes' => $item->toArray(), ]) : $paginator; @@ -599,10 +599,10 @@ public function index(RestifyRequest $request) return $this->response([ 'meta' => $this->resolveIndexMainMeta( - $request, $items->map(fn(self $repository) => $repository->resource), RepositoryCollection::meta($paginator->toArray()) + $request, $items->map(fn (self $repository) => $repository->resource), RepositoryCollection::meta($paginator->toArray()) ) ?? RepositoryCollection::meta($paginator->toArray()), 'links' => RepositoryCollection::paginationLinks($paginator->toArray()), - 'data' => $items->map(fn(self $repository) => $repository->serializeForIndex($request)), + 'data' => $items->map(fn (self $repository) => $repository->serializeForIndex($request)), ]); } @@ -641,7 +641,7 @@ public function store(RestifyRequest $request) } } - $this->storeFields($request)->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); + $this->storeFields($request)->each(fn (Field $field) => $field->invokeAfter($request, $this->resource)); }); static::stored($this->resource, $request); @@ -665,7 +665,7 @@ public function storeBulk(RepositoryStoreBulkRequest $request) $this->resource->save(); - $this->storeBulkFields($request)->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); + $this->storeBulkFields($request)->each(fn (Field $field) => $field->invokeAfter($request, $this->resource)); return $this->resource; }); @@ -690,7 +690,7 @@ public function update(RestifyRequest $request, $repositoryId) return $this->resource; }); - $this->updateFields($request)->each(fn(Field $field) => $field->invokeAfter($request, $this->resource)); + $this->updateFields($request)->each(fn (Field $field) => $field->invokeAfter($request, $this->resource)); return $this->response() ->data($this->serializeForShow($request)) @@ -714,8 +714,8 @@ public function updateBulk(RestifyRequest $request, $repositoryId, int $row) public function attach(RestifyRequest $request, $repositoryId, Collection $pivots) { DB::transaction(function () use ($request, $pivots) { - return $pivots->map(fn($pivot) => $pivot->forceFill($request->except($request->relatedRepository))) - ->map(fn($pivot) => $pivot->save()); + return $pivots->map(fn ($pivot) => $pivot->forceFill($request->except($request->relatedRepository))) + ->map(fn ($pivot) => $pivot->save()); }); return $this->response() @@ -726,7 +726,7 @@ public function attach(RestifyRequest $request, $repositoryId, Collection $pivot public function detach(RestifyRequest $request, $repositoryId, Collection $pivots) { $deleted = DB::transaction(function () use ($pivots) { - return $pivots->map(fn($pivot) => $pivot->delete()); + return $pivots->map(fn ($pivot) => $pivot->delete()); }); return $this->response() @@ -758,7 +758,7 @@ public function allowToUpdate(RestifyRequest $request, $payload = null): self public function allowToAttach(RestifyRequest $request, Collection $attachers): self { - $methodGuesser = 'attach' . Str::studly($request->relatedRepository); + $methodGuesser = 'attach'.Str::studly($request->relatedRepository); $attachers->each(fn ($model) => $this->authorizeToAttach($request, $methodGuesser, $model)); @@ -767,7 +767,7 @@ public function allowToAttach(RestifyRequest $request, Collection $attachers): s public function allowToDetach(RestifyRequest $request, Collection $attachers): self { - $methodGuesser = 'detach' . Str::studly($request->relatedRepository); + $methodGuesser = 'detach'.Str::studly($request->relatedRepository); $attachers->each(fn ($model) => $this->authorizeToDetach($request, $methodGuesser, $model)); @@ -854,7 +854,7 @@ public function response($content = '', $status = 200, array $headers = []): Res public function serializeForShow(RestifyRequest $request): array { return $this->filter([ - 'id' => $this->when($this->resource->id, fn() => $this->getShowId($request)), + 'id' => $this->when($this->resource->id, fn () => $this->getShowId($request)), 'type' => $this->when($type = $this->getType($request), $type), 'attributes' => $request->isShowRequest() ? $this->resolveShowAttributes($request) : $this->resolveIndexAttributes($request), 'relationships' => $this->when(value($related = $this->resolveRelationships($request)), $related), @@ -867,7 +867,7 @@ public function serializeForIndex(RestifyRequest $request): array return $this->filter([ 'id' => $this->when($id = $this->getShowId($request), $id), 'type' => $this->when($type = $this->getType($request), $type), - 'attributes' => $this->when((bool)$attrs = $this->resolveIndexAttributes($request), $attrs), + 'attributes' => $this->when((bool) $attrs = $this->resolveIndexAttributes($request), $attrs), 'relationships' => $this->when(value($related = $this->resolveRelationships($request)), $related), 'meta' => $this->when(value($meta = $this->resolveIndexMeta($request)), $meta), ]); @@ -917,12 +917,12 @@ protected static function fillBulkFields(RestifyRequest $request, Model $model, public static function uriTo(Model $model) { - return Restify::path() . '/' . static::uriKey() . '/' . $model->getKey(); + return Restify::path().'/'.static::uriKey().'/'.$model->getKey(); } public function availableFilters(RestifyRequest $request) { - return collect($this->filter($this->filters($request)))->each(fn(Filter $filter) => $filter->authorizedToSee($request)) + return collect($this->filter($this->filters($request)))->each(fn (Filter $filter) => $filter->authorizedToSee($request)) ->values(); } diff --git a/src/Traits/AuthorizableModels.php b/src/Traits/AuthorizableModels.php index 4bde27e00..89e948fc1 100644 --- a/src/Traits/AuthorizableModels.php +++ b/src/Traits/AuthorizableModels.php @@ -23,7 +23,7 @@ trait AuthorizableModels */ public static function authorizable() { - return !is_null(Gate::getPolicyFor(static::newModel())); + return ! is_null(Gate::getPolicyFor(static::newModel())); } /** @@ -35,7 +35,7 @@ public static function authorizable() */ public function authorizeToUseRepository(Request $request) { - if (!static::authorizable()) { + if (! static::authorizable()) { return; } @@ -52,7 +52,7 @@ public function authorizeToUseRepository(Request $request) */ public static function authorizedToUseRepository(Request $request) { - if (!static::authorizable()) { + if (! static::authorizable()) { return true; } @@ -93,14 +93,14 @@ public function authorizedToShow(Request $request) */ public static function authorizeToStore(Request $request) { - if (!static::authorizedToStore($request)) { + if (! static::authorizedToStore($request)) { throw new AuthorizationException('Unauthorized to store.'); } } public static function authorizeToStoreBulk(Request $request) { - if (!static::authorizedToStoreBulk($request)) { + if (! static::authorizedToStoreBulk($request)) { throw new AuthorizationException('Unauthorized to store bulk.'); } } diff --git a/tests/Fixtures/Company/CompanyPolicy.php b/tests/Fixtures/Company/CompanyPolicy.php index 0a2e5c9f0..0b1b6a0f4 100644 --- a/tests/Fixtures/Company/CompanyPolicy.php +++ b/tests/Fixtures/Company/CompanyPolicy.php @@ -4,7 +4,6 @@ use Binaryk\LaravelRestify\Tests\Fixtures\User\User; use Illuminate\Auth\Access\HandlesAuthorization; -use Illuminate\Support\Collection; class CompanyPolicy { @@ -12,7 +11,7 @@ class CompanyPolicy /** * Determine whether the user can use restify feature for each CRUD operation. - * So if this is not allowed, all operations will be disabled + * So if this is not allowed, all operations will be disabled. * @param User $user * @return mixed */ From 0f048f9fbb4ab70e5bcd0968a6e7eea84d1bdc63 Mon Sep 17 00:00:00 2001 From: Eduard Lupacescu Date: Wed, 9 Sep 2020 12:23:27 +0300 Subject: [PATCH 3/3] Formatting. --- src/Fields/Field.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Fields/Field.php b/src/Fields/Field.php index e5c9f591d..949b0a613 100644 --- a/src/Fields/Field.php +++ b/src/Fields/Field.php @@ -226,7 +226,7 @@ public function fillAttribute(RestifyRequest $request, $model, int $bulkRow = nu } if ($request->isStoreRequest() && is_callable($this->storeCallback)) { - return $model->{$this->attribute} = call_user_func( + return call_user_func( $this->storeCallback, $request, $model, $this->attribute, $bulkRow ); } @@ -238,7 +238,7 @@ public function fillAttribute(RestifyRequest $request, $model, int $bulkRow = nu } if ($request->isUpdateRequest() && is_callable($this->updateCallback)) { - return $model->{$this->attribute} = call_user_func( + return call_user_func( $this->updateCallback, $request, $model, $this->attribute, $bulkRow ); }