Skip to content

Commit

Permalink
Fetch attributes from parent classes to allow reusability
Browse files Browse the repository at this point in the history
  • Loading branch information
bastien-phi committed Oct 9, 2023
1 parent f75afe2 commit dd921c0
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/Support/DataClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Spatie\LaravelData\Contracts\TransformableData;
use Spatie\LaravelData\Contracts\ValidateableData;
use Spatie\LaravelData\Contracts\WrappableData;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\Mappers\ProvidedNameMapper;
use Spatie\LaravelData\Resolvers\NameMappersResolver;
use Spatie\LaravelData\Support\Lazy\CachedLazy;
Expand Down Expand Up @@ -49,9 +50,7 @@ public function __construct(

public static function create(ReflectionClass $class): self
{
$attributes = collect($class->getAttributes())
->filter(fn (ReflectionAttribute $reflectionAttribute) => class_exists($reflectionAttribute->getName()))
->map(fn (ReflectionAttribute $reflectionAttribute) => $reflectionAttribute->newInstance());
$attributes = static::resolveAttributes($class);

$methods = collect($class->getMethods());

Expand Down Expand Up @@ -81,6 +80,21 @@ public static function create(ReflectionClass $class): self
);
}

protected static function resolveAttributes(
ReflectionClass $class
): Collection {
$attributes = collect($class->getAttributes())
->filter(fn (ReflectionAttribute $reflectionAttribute) => class_exists($reflectionAttribute->getName()))
->map(fn (ReflectionAttribute $reflectionAttribute) => $reflectionAttribute->newInstance());

$parent = $class->getParentClass();
if ($parent !== false && $class->getName() !== Data::class) {
$attributes = $attributes->merge(static::resolveAttributes($parent));
}

return $attributes;
}

protected static function resolveMethods(
ReflectionClass $reflectionClass,
): Collection {
Expand Down
31 changes: 31 additions & 0 deletions tests/Support/DataClassTest.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<?php

use Spatie\LaravelData\Attributes\MapName;
use Spatie\LaravelData\Attributes\WithCast;
use Spatie\LaravelData\Attributes\WithTransformer;
use Spatie\LaravelData\Casts\DateTimeInterfaceCast;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
use Spatie\LaravelData\Support\DataClass;
use Spatie\LaravelData\Support\DataMethod;
use Spatie\LaravelData\Tests\Fakes\DataWithMapper;
use Spatie\LaravelData\Tests\Fakes\Models\DummyModel;
use Spatie\LaravelData\Tests\Fakes\SimpleData;
use Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer;

it('keeps track of a global map from attribute', function () {
$dataClass = DataClass::create(new ReflectionClass(DataWithMapper::class));
Expand Down Expand Up @@ -85,6 +91,16 @@ public function __construct(
->mappedDataObjects->toBeEmpty();
});

it('resolves parent attributes', function () {
$dataClass = DataClass::create(new ReflectionClass(ChildData::class));

expect($dataClass->attributes)
->toHaveCount(3)
->contains(fn ($attribute) => $attribute instanceof MapName)->toBeTrue()
->contains(fn ($attribute) => $attribute instanceof WithTransformer)->toBeTrue()
->contains(fn ($attribute) => $attribute instanceof WithCast)->toBeTrue();
});

#[\JetBrains\PhpStorm\Immutable]
class PhpStormClassAttributeData extends Data
{
Expand Down Expand Up @@ -120,3 +136,18 @@ public static function fromDummyModel(DummyModel $model)
return new self($model->id);
}
}

#[MapName(SnakeCaseMapper::class)]
#[WithTransformer(DateTimeInterfaceTransformer::class, 'd-m-Y')]
#[WithCast(DateTimeInterfaceCast::class, format: 'Y-m-d')]
class ParentData extends Data
{
}

class ChildData extends ParentData
{
public function __construct(
public DateTimeInterface $dateTime
) {
}
}

0 comments on commit dd921c0

Please sign in to comment.