Skip to content

Commit 7cc6e0e

Browse files
wip
1 parent 82f1983 commit 7cc6e0e

File tree

10 files changed

+95
-13
lines changed

10 files changed

+95
-13
lines changed

UPGRADING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ The following things are required when upgrading:
2121
- If you have implemented a custom `Transformer`, update the `transform` method signature with the new `TransformationContext` parameter
2222
- If you have implemented a custom `Cast`
2323
- The `$castContext` parameter is renamed to `$properties` and changed it type from `array` to `collection`
24-
- A new `$creationContext` parameter is added of type `CreationContext`
24+
- A new `$context` parameter is added of type `CreationContext`
2525
- If you have implemented a custom DataPipe, update the `handle` method signature with the new `TransformationContext` parameter
2626
- If you manually created `ValidatePropertiesDataPipe` using the `allTypes` parameter, please now use the creation context for this
2727
- The `withoutMagicalCreationFrom` method was removed from data in favour for creation by factory
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Spatie\LaravelData\Attributes;
4+
5+
use Attribute;
6+
use Spatie\LaravelData\Casts\Cast;
7+
use Spatie\LaravelData\Exceptions\CannotCreateCastAttribute;
8+
use Spatie\LaravelData\Exceptions\CannotCreateTransformerAttribute;
9+
use Spatie\LaravelData\Transformers\Transformer;
10+
11+
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY)]
12+
class WithCastAndTransformer implements GetsCast
13+
{
14+
public array $arguments;
15+
16+
public function __construct(
17+
/** @var class-string<Transformer&Cast> $class */
18+
public string $class,
19+
mixed ...$arguments
20+
) {
21+
if (! is_a($this->class, Transformer::class, true)) {
22+
throw CannotCreateTransformerAttribute::notATransformer();
23+
}
24+
25+
if (! is_a($this->class, Cast::class, true)) {
26+
throw CannotCreateCastAttribute::notACast();
27+
}
28+
29+
$this->arguments = $arguments;
30+
}
31+
32+
public function get(): Cast&Transformer
33+
{
34+
return new ($this->class)(...$this->arguments);
35+
}
36+
}

src/Casts/Cast.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@
88

99
interface Cast
1010
{
11-
public function cast(DataProperty $property, mixed $value, Collection $properties, CreationContext $creationContext): mixed;
11+
public function cast(DataProperty $property, mixed $value, Collection $properties, CreationContext $context): mixed;
1212
}

src/Concerns/ResponsableData.php

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@
1212

1313
trait ResponsableData
1414
{
15-
/**
16-
* @param \Illuminate\Http\Request $request
17-
*
18-
* @return \Symfony\Component\HttpFoundation\Response
19-
*/
2015
public function toResponse($request)
2116
{
2217
$contextFactory = TransformationContextFactory::create()

src/Contracts/ResponsableData.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,18 @@
22

33
namespace Spatie\LaravelData\Contracts;
44

5-
interface ResponsableData
5+
use Illuminate\Contracts\Support\Responsable;
6+
use Symfony\Component\HttpFoundation\Response;
7+
8+
interface ResponsableData extends TransformableData, Responsable
69
{
10+
/**
11+
* @param \Illuminate\Http\Request $request
12+
*
13+
* @return \Symfony\Component\HttpFoundation\Response
14+
*/
15+
public function toResponse($request);
16+
717
public static function allowedRequestIncludes(): ?array;
818

919
public static function allowedRequestExcludes(): ?array;

src/CursorPaginatedDataCollection.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,11 @@ public function __construct(
4949
}
5050

5151
/**
52-
* @param Closure(TValue, TKey): TValue $through
52+
* @template TOtherValue
5353
*
54-
* @return static
54+
* @param Closure(TValue, TKey): TOtherValue $through
55+
*
56+
* @return static<TKey, TOtherValue>
5557
*/
5658
public function through(Closure $through): static
5759
{

src/PaginatedDataCollection.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,11 @@ public function __construct(
4848
}
4949

5050
/**
51-
* @param Closure(TValue, TKey): TValue $through
51+
* @template TOtherValue
5252
*
53-
* @return static
53+
* @param Closure(TValue, TKey): TOtherValue $through
54+
*
55+
* @return static<TKey, TOtherValue>
5456
*/
5557
public function through(Closure $through): static
5658
{

src/Support/DataProperty.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Spatie\LaravelData\Attributes\Computed;
99
use Spatie\LaravelData\Attributes\GetsCast;
1010
use Spatie\LaravelData\Attributes\Hidden;
11+
use Spatie\LaravelData\Attributes\WithCastAndTransformer;
1112
use Spatie\LaravelData\Attributes\WithoutValidation;
1213
use Spatie\LaravelData\Attributes\WithTransformer;
1314
use Spatie\LaravelData\Casts\Cast;
@@ -89,7 +90,7 @@ className: $property->class,
8990
hasDefaultValue: $property->isPromoted() ? $hasDefaultValue : $property->hasDefaultValue(),
9091
defaultValue: $property->isPromoted() ? $defaultValue : $property->getDefaultValue(),
9192
cast: $attributes->first(fn (object $attribute) => $attribute instanceof GetsCast)?->get(),
92-
transformer: $attributes->first(fn (object $attribute) => $attribute instanceof WithTransformer)?->get(),
93+
transformer: $attributes->first(fn (object $attribute) => $attribute instanceof WithTransformer || $attribute instanceof WithCastAndTransformer)?->get(),
9394
inputMappedName: $inputMappedName,
9495
outputMappedName: $outputMappedName,
9596
attributes: $attributes,
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Spatie\LaravelData\Tests\Fakes\CastTransformers;
4+
5+
use Illuminate\Support\Collection;
6+
use Spatie\LaravelData\Casts\Cast;
7+
use Spatie\LaravelData\Support\Creation\CreationContext;
8+
use Spatie\LaravelData\Support\DataProperty;
9+
use Spatie\LaravelData\Support\Transformation\TransformationContext;
10+
use Spatie\LaravelData\Transformers\Transformer;
11+
12+
class FakeCastTransformer implements Cast, Transformer
13+
{
14+
15+
public function cast(DataProperty $property, mixed $value, Collection $properties, CreationContext $context): mixed
16+
{
17+
return $value;
18+
}
19+
20+
public function transform(DataProperty $property, mixed $value, TransformationContext $context): mixed
21+
{
22+
return $value;
23+
}
24+
}

tests/Support/DataPropertyTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
use Spatie\LaravelData\Attributes\MapInputName;
77
use Spatie\LaravelData\Attributes\MapOutputName;
88
use Spatie\LaravelData\Attributes\WithCast;
9+
use Spatie\LaravelData\Attributes\WithCastAndTransformer;
910
use Spatie\LaravelData\Attributes\WithoutValidation;
1011
use Spatie\LaravelData\Attributes\WithTransformer;
1112
use Spatie\LaravelData\Casts\DateTimeInterfaceCast;
1213
use Spatie\LaravelData\Data;
1314
use Spatie\LaravelData\DataCollection;
1415
use Spatie\LaravelData\Support\DataProperty;
16+
use Spatie\LaravelData\Tests\Fakes\CastTransformers\FakeCastTransformer;
1517
use Spatie\LaravelData\Tests\Fakes\Models\DummyModel;
1618
use Spatie\LaravelData\Tests\Fakes\SimpleData;
1719
use Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer;
@@ -53,6 +55,16 @@ function resolveHelper(
5355
expect($helper->transformer)->toEqual(new DateTimeInterfaceTransformer('d-m-y'));
5456
});
5557

58+
it('can get the cast with transformer attribute', function () {
59+
$helper = resolveHelper(new class () {
60+
#[WithCastAndTransformer(FakeCastTransformer::class)]
61+
public SimpleData $property;
62+
});
63+
64+
expect($helper->transformer)->toEqual(new FakeCastTransformer());
65+
expect($helper->cast)->toEqual(new FakeCastTransformer());
66+
});
67+
5668
it('can get the mapped input name', function () {
5769
$helper = resolveHelper(new class () {
5870
#[MapInputName('other')]

0 commit comments

Comments
 (0)