Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenvanassche committed Jan 15, 2024
1 parent 82f1983 commit 7cc6e0e
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 13 deletions.
2 changes: 1 addition & 1 deletion UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ The following things are required when upgrading:
- If you have implemented a custom `Transformer`, update the `transform` method signature with the new `TransformationContext` parameter
- If you have implemented a custom `Cast`
- The `$castContext` parameter is renamed to `$properties` and changed it type from `array` to `collection`
- A new `$creationContext` parameter is added of type `CreationContext`
- A new `$context` parameter is added of type `CreationContext`
- If you have implemented a custom DataPipe, update the `handle` method signature with the new `TransformationContext` parameter
- If you manually created `ValidatePropertiesDataPipe` using the `allTypes` parameter, please now use the creation context for this
- The `withoutMagicalCreationFrom` method was removed from data in favour for creation by factory
Expand Down
36 changes: 36 additions & 0 deletions src/Attributes/WithCastAndTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Spatie\LaravelData\Attributes;

use Attribute;
use Spatie\LaravelData\Casts\Cast;
use Spatie\LaravelData\Exceptions\CannotCreateCastAttribute;
use Spatie\LaravelData\Exceptions\CannotCreateTransformerAttribute;
use Spatie\LaravelData\Transformers\Transformer;

#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY)]
class WithCastAndTransformer implements GetsCast
{
public array $arguments;

public function __construct(
/** @var class-string<Transformer&Cast> $class */
public string $class,
mixed ...$arguments
) {
if (! is_a($this->class, Transformer::class, true)) {
throw CannotCreateTransformerAttribute::notATransformer();
}

if (! is_a($this->class, Cast::class, true)) {
throw CannotCreateCastAttribute::notACast();
}

$this->arguments = $arguments;
}

public function get(): Cast&Transformer
{
return new ($this->class)(...$this->arguments);
}
}
2 changes: 1 addition & 1 deletion src/Casts/Cast.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@

interface Cast
{
public function cast(DataProperty $property, mixed $value, Collection $properties, CreationContext $creationContext): mixed;
public function cast(DataProperty $property, mixed $value, Collection $properties, CreationContext $context): mixed;
}
5 changes: 0 additions & 5 deletions src/Concerns/ResponsableData.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@

trait ResponsableData
{
/**
* @param \Illuminate\Http\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
$contextFactory = TransformationContextFactory::create()
Expand Down
12 changes: 11 additions & 1 deletion src/Contracts/ResponsableData.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,18 @@

namespace Spatie\LaravelData\Contracts;

interface ResponsableData
use Illuminate\Contracts\Support\Responsable;
use Symfony\Component\HttpFoundation\Response;

interface ResponsableData extends TransformableData, Responsable
{
/**
* @param \Illuminate\Http\Request $request
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request);

public static function allowedRequestIncludes(): ?array;

public static function allowedRequestExcludes(): ?array;
Expand Down
6 changes: 4 additions & 2 deletions src/CursorPaginatedDataCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ public function __construct(
}

/**
* @param Closure(TValue, TKey): TValue $through
* @template TOtherValue
*
* @return static
* @param Closure(TValue, TKey): TOtherValue $through
*
* @return static<TKey, TOtherValue>
*/
public function through(Closure $through): static

Check failure on line 58 in src/CursorPaginatedDataCollection.php

View workflow job for this annotation

GitHub Actions / phpstan

PHPDoc tag @return with type Spatie\LaravelData\CursorPaginatedDataCollection<TKey of (int|string), TOtherValue> is incompatible with native type static(Spatie\LaravelData\CursorPaginatedDataCollection<TKey of (int|string), TValue>).

Check failure on line 58 in src/CursorPaginatedDataCollection.php

View workflow job for this annotation

GitHub Actions / phpstan

PHPDoc tag @return with type Spatie\LaravelData\CursorPaginatedDataCollection<TKey of (int|string), TOtherValue> is incompatible with native type static(Spatie\LaravelData\CursorPaginatedDataCollection<TKey of (int|string), TValue>).
{
Expand Down
6 changes: 4 additions & 2 deletions src/PaginatedDataCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ public function __construct(
}

/**
* @param Closure(TValue, TKey): TValue $through
* @template TOtherValue
*
* @return static
* @param Closure(TValue, TKey): TOtherValue $through
*
* @return static<TKey, TOtherValue>
*/
public function through(Closure $through): static

Check failure on line 57 in src/PaginatedDataCollection.php

View workflow job for this annotation

GitHub Actions / phpstan

PHPDoc tag @return with type Spatie\LaravelData\PaginatedDataCollection<TKey of (int|string), TOtherValue> is incompatible with native type static(Spatie\LaravelData\PaginatedDataCollection<TKey of (int|string), TValue>).

Check failure on line 57 in src/PaginatedDataCollection.php

View workflow job for this annotation

GitHub Actions / phpstan

PHPDoc tag @return with type Spatie\LaravelData\PaginatedDataCollection<TKey of (int|string), TOtherValue> is incompatible with native type static(Spatie\LaravelData\PaginatedDataCollection<TKey of (int|string), TValue>).
{
Expand Down
3 changes: 2 additions & 1 deletion src/Support/DataProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Spatie\LaravelData\Attributes\Computed;
use Spatie\LaravelData\Attributes\GetsCast;
use Spatie\LaravelData\Attributes\Hidden;
use Spatie\LaravelData\Attributes\WithCastAndTransformer;
use Spatie\LaravelData\Attributes\WithoutValidation;
use Spatie\LaravelData\Attributes\WithTransformer;
use Spatie\LaravelData\Casts\Cast;
Expand Down Expand Up @@ -89,7 +90,7 @@ className: $property->class,
hasDefaultValue: $property->isPromoted() ? $hasDefaultValue : $property->hasDefaultValue(),
defaultValue: $property->isPromoted() ? $defaultValue : $property->getDefaultValue(),
cast: $attributes->first(fn (object $attribute) => $attribute instanceof GetsCast)?->get(),
transformer: $attributes->first(fn (object $attribute) => $attribute instanceof WithTransformer)?->get(),
transformer: $attributes->first(fn (object $attribute) => $attribute instanceof WithTransformer || $attribute instanceof WithCastAndTransformer)?->get(),
inputMappedName: $inputMappedName,
outputMappedName: $outputMappedName,
attributes: $attributes,
Expand Down
24 changes: 24 additions & 0 deletions tests/Fakes/CastTransformers/FakeCastTransformer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Spatie\LaravelData\Tests\Fakes\CastTransformers;

use Illuminate\Support\Collection;
use Spatie\LaravelData\Casts\Cast;
use Spatie\LaravelData\Support\Creation\CreationContext;
use Spatie\LaravelData\Support\DataProperty;
use Spatie\LaravelData\Support\Transformation\TransformationContext;
use Spatie\LaravelData\Transformers\Transformer;

class FakeCastTransformer implements Cast, Transformer
{

public function cast(DataProperty $property, mixed $value, Collection $properties, CreationContext $context): mixed
{
return $value;
}

public function transform(DataProperty $property, mixed $value, TransformationContext $context): mixed
{
return $value;
}
}
12 changes: 12 additions & 0 deletions tests/Support/DataPropertyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
use Spatie\LaravelData\Attributes\MapInputName;
use Spatie\LaravelData\Attributes\MapOutputName;
use Spatie\LaravelData\Attributes\WithCast;
use Spatie\LaravelData\Attributes\WithCastAndTransformer;
use Spatie\LaravelData\Attributes\WithoutValidation;
use Spatie\LaravelData\Attributes\WithTransformer;
use Spatie\LaravelData\Casts\DateTimeInterfaceCast;
use Spatie\LaravelData\Data;
use Spatie\LaravelData\DataCollection;
use Spatie\LaravelData\Support\DataProperty;
use Spatie\LaravelData\Tests\Fakes\CastTransformers\FakeCastTransformer;
use Spatie\LaravelData\Tests\Fakes\Models\DummyModel;
use Spatie\LaravelData\Tests\Fakes\SimpleData;
use Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer;
Expand Down Expand Up @@ -53,6 +55,16 @@ function resolveHelper(
expect($helper->transformer)->toEqual(new DateTimeInterfaceTransformer('d-m-y'));
});

it('can get the cast with transformer attribute', function () {
$helper = resolveHelper(new class () {
#[WithCastAndTransformer(FakeCastTransformer::class)]
public SimpleData $property;
});

expect($helper->transformer)->toEqual(new FakeCastTransformer());
expect($helper->cast)->toEqual(new FakeCastTransformer());
});

it('can get the mapped input name', function () {
$helper = resolveHelper(new class () {
#[MapInputName('other')]
Expand Down

0 comments on commit 7cc6e0e

Please sign in to comment.