Skip to content

Commit

Permalink
feat(PHPStan): Provide @template for JsonResource $resource for bette…
Browse files Browse the repository at this point in the history
…r type safe

BREAKING CHANGE: PHPStan will now throw an error if you pass incorrect value to __construct or Resource::collection

- made setContainer/getContainer/resourceArray/instance final
  • Loading branch information
pionl committed Aug 2, 2024
1 parent 209518b commit 03a174d
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 23 deletions.
2 changes: 1 addition & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
parameters:
ignoreErrors:
-
message: "#^Access to an undefined property LaraStrict\\\\Http\\\\Resources\\\\JsonResource\\:\\:\\$preserveKeys\\.$#"
message: "#^Access to an undefined property LaraStrict\\\\Http\\\\Resources\\\\JsonResource\\<TResource\\>\\:\\:\\$preserveKeys\\.$#"
count: 1
path: src/Http/Resources/JsonResource.php

Expand Down
30 changes: 26 additions & 4 deletions src/Http/Resources/JsonResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,42 @@

use Illuminate\Container\Container as LaravelContainer;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource as BaseJsonResource;
use Illuminate\Pagination\AbstractPaginator;
use Illuminate\Support\Collection as SupportCollection;

/**
* @template TResource
*
* @property TResource $resource
*/
abstract class JsonResource extends BaseJsonResource
{
private ?Container $container = null;

public function setContainer(Container $container): self
/**
* When created in your code base, it non-null, but Laravel for "collection" uses null.
*
* @param TResource $resource
*/
public function __construct($resource)
{
parent::__construct($resource);
}

final public function setContainer(Container $container): static
{
$this->container = $container;

return $this;
}

/**
* @param array<TResource>|Collection<array-key, TResource>|SupportCollection<array-key, TResource>|Paginator<TResource>|AbstractPaginator<TResource> $resource
*/
public static function collection($resource): JsonResourceCollection
{
return tap(
Expand All @@ -34,7 +56,7 @@ static function (JsonResourceCollection $collection) {
);
}

protected function getContainer(): Container
final protected function getContainer(): Container
{
if ($this->container === null) {
return LaravelContainer::getInstance();
Expand All @@ -49,7 +71,7 @@ protected function getContainer(): Container
*
* @return array<string|int, mixed>
*/
protected function resourceArray(Request $request, BaseJsonResource $resource): array
final protected function resourceArray(Request $request, BaseJsonResource $resource): array
{
if ($resource instanceof self || $resource instanceof JsonResourceCollection) {
$resource->setContainer($this->getContainer());
Expand All @@ -66,7 +88,7 @@ protected function resourceArray(Request $request, BaseJsonResource $resource):
*
* @return TInstance
*/
protected function instance(string $class, array $parameters = []): object
final protected function instance(string $class, array $parameters = []): object
{
return $this
->getContainer()
Expand Down
7 changes: 1 addition & 6 deletions src/Http/Resources/MessageResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,12 @@
use LaraStrict\Http\Enums\HttpMessage;

/**
* @property HttpMessage|string $resource
* @extends JsonResource<HttpMessage|string>
*/
class MessageResource extends JsonResource
{
public static $wrap = null;

public function __construct(HttpMessage|string|null $resource)
{
parent::__construct($resource);
}

/**
* @return array
*/
Expand Down
7 changes: 1 addition & 6 deletions tests/Feature/Http/Resources/LaraStrictResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,10 @@
use LaraStrict\Http\Resources\JsonResource;

/**
* @property TestEntity $resource
* @extends JsonResource<TestEntity>
*/
class LaraStrictResource extends JsonResource
{
public function __construct(?TestEntity $resource)
{
parent::__construct($resource);
}

public function toArray($request): array
{
return [
Expand Down
7 changes: 1 addition & 6 deletions tests/Unit/Http/Resources/ResourceArrayResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,10 @@
use LaraStrict\Http\Resources\JsonResource;

/**
* @property BaseJsonResource $resource
* @extends JsonResource<BaseJsonResource>
*/
class ResourceArrayResource extends JsonResource
{
public function __construct(?BaseJsonResource $resource)
{
parent::__construct($resource);
}

/**
* @return array<string, array<array<string, mixed>>>
*/
Expand Down

0 comments on commit 03a174d

Please sign in to comment.