From c7cfff18f724a68e226d7e9209d55fbc07959d56 Mon Sep 17 00:00:00 2001 From: Mohammad Alavi Date: Mon, 3 Mar 2025 17:29:04 +0330 Subject: [PATCH] feat: remove ability to transform data in controllers --- src/Core/Controllers/ApiController.php | 143 ------------------ .../Core/Controllers/ApiControllerTest.php | 97 ------------ 2 files changed, 240 deletions(-) delete mode 100644 tests/Unit/Core/Controllers/ApiControllerTest.php diff --git a/src/Core/Controllers/ApiController.php b/src/Core/Controllers/ApiController.php index 36abfdee..bf5b7c0b 100644 --- a/src/Core/Controllers/ApiController.php +++ b/src/Core/Controllers/ApiController.php @@ -11,147 +11,4 @@ abstract class ApiController extends Controller { - protected array $metaData = []; - - /** - * @param class-string|Transformer $transformerName - * @param string[] $includes - * @param string $resourceKey - * - * @return array|null - */ - public function transform( - $data, - $transformerName = null, - array $includes = [], - array $meta = [], - $resourceKey = null, - ) { - $transformer = match (true) { - $transformerName instanceof Transformer => $transformerName, - default => new $transformerName(), - }; - - if (!$transformer instanceof Transformer) { - throw new \RuntimeException('Invalid transformer.'); - } - - // add specific meta information to the response message - $this->metaData = array_merge($this->metaData, [ - 'include' => $transformer->getAvailableIncludes(), - 'custom' => $meta, - ]); - - // no resource key was set - if (!$resourceKey) { - // get the resource key from the model - $obj = null; - if ($data instanceof AbstractPaginator) { - $obj = $data->getCollection()->first(); - } elseif ($data instanceof Collection) { - $obj = $data->first(); - } elseif (is_array($data) && [] !== $data) { - $obj = $data[0]; - } else { - $obj = $data; - } - - // if we have an object, try to get its resourceKey - if ($obj) { - $resourceKey = $obj->getResourceKey(); - } - } - - $fractal = Fractal::create($data, $transformer)->withResourceName($resourceKey)->addMeta($this->metaData); - - // read includes passed via query params in url - $requestIncludes = $this->parseRequestedIncludes(); - - // merge the requested includes with the one added by the transform() method itself - $requestIncludes = array_unique(array_merge($includes, $requestIncludes)); - - // and let fractal include everything - $fractal->parseIncludes($requestIncludes); - - // apply request filters if available in the request - if ($requestFilters = request()?->input(config('apiato.requests.params.filter', 'filter'))) { - $result = $this->filterResponse($fractal->toArray(), explode(';', (string) $requestFilters)); - } else { - $result = $fractal->toArray(); - } - - return $result; - } - - protected function parseRequestedIncludes(): array - { - return explode(',', request()?->input('include') ?? ''); - } - - private function filterResponse(array $responseArray, array $filters): array - { - foreach ($responseArray as $k => $v) { - if (in_array($k, $filters, true)) { - // we have found our element - so continue with the next one - continue; - } - - if (is_array($v)) { - // it is an array - so go one step deeper - $v = $this->filterResponse($v, $filters); - if ([] === $v) { - // it is an empty array - delete the key as well - unset($responseArray[$k]); - } else { - $responseArray[$k] = $v; - } - } elseif (!in_array($k, $filters)) { - // check if the array is not in our filter-list - unset($responseArray[$k]); - } - } - - return $responseArray; - } - - public function withMeta($data): self - { - $this->metaData = $data; - - return $this; - } - - public function json($data, $status = 200, array $headers = [], $options = 0): JsonResponse - { - return new JsonResponse($data, $status, $headers, $options); - } - - public function created($data = null, $status = 201, array $headers = [], $options = 0): JsonResponse - { - return new JsonResponse($data, $status, $headers, $options); - } - - public function deleted(Model|null $deletedModel = null): JsonResponse - { - if (!$deletedModel instanceof Model) { - return $this->accepted(); - } - - $id = $deletedModel->getHashedKey(); - $className = (new \ReflectionClass($deletedModel))->getShortName(); - - return $this->accepted([ - 'message' => "$className ($id) Deleted Successfully.", - ]); - } - - public function accepted($data = null, $status = 202, array $headers = [], $options = 0): JsonResponse - { - return new JsonResponse($data, $status, $headers, $options); - } - - public function noContent($status = 204): JsonResponse - { - return new JsonResponse(null, $status); - } } diff --git a/tests/Unit/Core/Controllers/ApiControllerTest.php b/tests/Unit/Core/Controllers/ApiControllerTest.php deleted file mode 100644 index caf5c468..00000000 --- a/tests/Unit/Core/Controllers/ApiControllerTest.php +++ /dev/null @@ -1,97 +0,0 @@ -customMetadata = [ - 'key' => 'value', - ]; - $this->metadata = [ - 'something' => $this->customMetadata, - ]; - - $this->sut = new class extends ApiController {}; - - $this->transformer = new UserTransformer(); - }); - - it('can transform data', function (): void { - $user = User::factory()->withParent()->makeOne(); - $result = $this->sut - ->withMeta($this->metadata) - ->transform( - data: $user, - transformerName: $this->transformer, - meta: $this->customMetadata, - ); - - expect($result)->toBeArray() - ->and($result)->toHaveKey('data') - ->and($result['data'])->toHaveKey('type') - ->and($result['data']['type'])->toBe($user->getResourceKey()) - ->and($result['data'])->not->toHaveKey('parent'); - assertMetadata($result); - }); - - it('can include requested includes', function (): void { - $include = 'parent'; - - $result = $this->sut - ->withMeta($this->metadata) - ->transform( - data: User::factory()->withParent()->makeOne(), - transformerName: $this->transformer, - includes: [$include], - meta: $this->customMetadata, - ); - - $this->assertArrayHasKey('parent', $result['data']); - $this->assertNotNull($result['data']['parent']); - assertMetadata($result); - $this->assertContains($include, $result['meta']['include']); - }); - - it('can override resource key', function (bool|string|array|null $resourceKey, string $expected): void { - $result = $this->sut - ->withMeta($this->metadata) - ->transform( - data: User::factory()->withParent()->makeOne(), - transformerName: $this->transformer, - meta: $this->customMetadata, - resourceKey: $resourceKey, - ); - - $this->assertEquals($expected, $result['data']['type']); - })->with([ - 'null' => [ - 'resourceKey' => null, - 'expected' => 'User', - ], - 'false' => [ - 'resourceKey' => false, - 'expected' => 'User', - ], - 'empty string' => [ - 'resourceKey' => '', - 'expected' => 'User', - ], - 'empty array' => [ - 'resourceKey' => [], - 'expected' => 'User', - ], - ]); - - function assertMetadata(array $result): void - { - expect($result)->toHaveKey('meta') - ->and($result['meta'])->toContainEqual(test()->metadata['something']) - ->and($result['meta'])->toHaveKey('include') - ->and($result['meta'])->toHaveKey('custom') - ->and($result['meta']['custom'])->toBe(test()->customMetadata); - } -})->covers(ApiController::class);