From 18fe34a6e2ed9c7f50d2ccfe4b5c9438120f31ec Mon Sep 17 00:00:00 2001 From: Aleksei Zarubin <12220926+alexzarbn@users.noreply.github.com> Date: Mon, 31 Oct 2022 16:51:26 +0100 Subject: [PATCH] fix: relations specified in "alwaysIncluded" method were not included --- src/Drivers/Standard/ParamsValidator.php | 2 +- src/Drivers/Standard/QueryBuilder.php | 29 +++++++++---------- src/Drivers/Standard/RelationsResolver.php | 17 +++++++---- src/Http/Controllers/BaseController.php | 2 +- .../Http/Controllers/BaseControllerTest.php | 2 +- .../Controllers/RelationControllerTest.php | 2 +- 6 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/Drivers/Standard/ParamsValidator.php b/src/Drivers/Standard/ParamsValidator.php index 5fc54c4a..c7914050 100644 --- a/src/Drivers/Standard/ParamsValidator.php +++ b/src/Drivers/Standard/ParamsValidator.php @@ -213,7 +213,7 @@ public function validateIncludes(Request $request): void Validator::make( $request->query(), [ - 'includes' => ['sometimes', 'string', new WhitelistedQueryFields($this->includableBy)], + 'include' => ['sometimes', 'string', new WhitelistedQueryFields($this->includableBy)], ] )->validate(); } diff --git a/src/Drivers/Standard/QueryBuilder.php b/src/Drivers/Standard/QueryBuilder.php index 69ff434a..333d2e8a 100644 --- a/src/Drivers/Standard/QueryBuilder.php +++ b/src/Drivers/Standard/QueryBuilder.php @@ -41,11 +41,6 @@ class QueryBuilder implements \Orion\Contracts\QueryBuilder */ private $intermediateMode; - /** - * @var string $table - */ - private $table; - /** * @inheritDoc */ @@ -329,7 +324,8 @@ protected function buildPivotFilterNestedQueryWhereClause( */ public function getQualifiedFieldName(string $field): string { - $table = $this->table ?? (new $this->resourceModelClass)->getTable(); + $table = (new $this->resourceModelClass)->getTable(); + return "{$table}.{$field}"; } @@ -538,7 +534,7 @@ public function applyAggregatesToQuery($query, Request $request, array $aggregat ); } - $aggregateDescriptors = $aggregateDescriptors->merge($request->post('aggregates', [])); + $aggregateDescriptors = $aggregateDescriptors->merge($request->get('aggregates', [])); } foreach ($aggregateDescriptors as $aggregateDescriptor) { @@ -586,14 +582,17 @@ public function applyIncludesToQuery($query, Request $request, array $includeDes { if (!$includeDescriptors) { $this->paramsValidator->validateIncludes($request); - // Here we regroup query and post params on the same format - $includeDescriptors = - collect(explode(',', $request->query('include', ''))) - ->filter() - ->map(function ($include) { - return ['relation' => $include]; - }) - ->merge($request->post('includes', [])); + + $requestedIncludeDescriptors = collect($request->get('includes', [])); + + $includeDescriptors = collect($this->relationsResolver->requestedRelations($request)) + ->map(function ($include) use ($requestedIncludeDescriptors) { + $requestedIncludeDescriptor = $requestedIncludeDescriptors + ->where('relation', $include) + ->first(); + + return $requestedIncludeDescriptor ?? ['relation' => $include]; + })->toArray(); } foreach ($includeDescriptors as $includeDescriptor) { diff --git a/src/Drivers/Standard/RelationsResolver.php b/src/Drivers/Standard/RelationsResolver.php index 1713a101..c9decb1a 100644 --- a/src/Drivers/Standard/RelationsResolver.php +++ b/src/Drivers/Standard/RelationsResolver.php @@ -41,12 +41,17 @@ public function __construct(array $includableRelations, array $alwaysIncludedRel */ public function requestedRelations(Request $request): array { - $requestedIncludesQueryStr = $request->query('include', ''); - $requestedIncludesQuery = explode(',', $requestedIncludesQueryStr); - $requestedIncludesPost = collect($request->post('includes', []))->pluck('relation'); - $requestedIncludes = $requestedIncludesPost->merge($requestedIncludesQuery)->unique()->filter()->all(); + $requestedIncludesQuery = collect(explode(',', $request->query('include', ''))); + $requestedIncludesBody = collect($request->get('includes', []))->pluck('relation'); - $allowedIncludes = array_unique(array_merge($this->includableRelations, $this->alwaysIncludedRelations)); + $requestedIncludes = $requestedIncludesQuery + ->merge($requestedIncludesBody) + ->merge($this->alwaysIncludedRelations) + ->unique()->filter()->all(); + + $allowedIncludes = array_unique( + array_merge($this->includableRelations, $this->alwaysIncludedRelations) + ); $validatedIncludes = []; @@ -69,7 +74,7 @@ public function requestedRelations(Request $request): array } } - return array_unique(array_merge($validatedIncludes, $this->alwaysIncludedRelations)); + return $validatedIncludes; } /** diff --git a/src/Http/Controllers/BaseController.php b/src/Http/Controllers/BaseController.php index e419628d..3fbea9b1 100644 --- a/src/Http/Controllers/BaseController.php +++ b/src/Http/Controllers/BaseController.php @@ -113,7 +113,7 @@ public function __construct() 'filterableBy' => $this->filterableBy(), 'sortableBy' => $this->sortableBy(), 'aggregatableBy' => $this->aggregates(), - 'includableBy' => $this->includes(), + 'includableBy' => array_merge($this->includes(), $this->alwaysIncludes()), ] ); $this->relationsResolver = App::makeWith( diff --git a/tests/Unit/Http/Controllers/BaseControllerTest.php b/tests/Unit/Http/Controllers/BaseControllerTest.php index cc73e494..b023988a 100644 --- a/tests/Unit/Http/Controllers/BaseControllerTest.php +++ b/tests/Unit/Http/Controllers/BaseControllerTest.php @@ -59,7 +59,7 @@ public function dependencies_are_resolved_correctly() 'filterableBy' => ['test_filterable_field'], 'sortableBy' => ['test_sortable_field'], 'aggregatableBy' => ['test_aggregatable_field'], - 'includableBy' => ['testRelation'], + 'includableBy' => ['testRelation', 'testAlwaysIncludedRelation'], ] )->once()->andReturn($fakeParamsValidator); diff --git a/tests/Unit/Http/Controllers/RelationControllerTest.php b/tests/Unit/Http/Controllers/RelationControllerTest.php index cee82fa4..ba018e1a 100644 --- a/tests/Unit/Http/Controllers/RelationControllerTest.php +++ b/tests/Unit/Http/Controllers/RelationControllerTest.php @@ -53,7 +53,7 @@ public function dependencies_are_resolved_correctly() 'filterableBy' => ['test_filterable_field'], 'sortableBy' => ['test_sortable_field'], 'aggregatableBy' => ['test_aggregatable_field'], - 'includableBy' => ['testRelation'], + 'includableBy' => ['testRelation', 'testAlwaysIncludedRelation'], ] )->once()->andReturn($fakeParamsValidator);