Skip to content

Commit

Permalink
Fix differences between contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenvanassche committed Jan 23, 2024
1 parent 2761d73 commit fcc0d8f
Show file tree
Hide file tree
Showing 26 changed files with 298 additions and 109 deletions.
2 changes: 1 addition & 1 deletion docs/advanced-usage/creating-a-cast.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Creating a cast
weight: 8
weight: 6
---

Casts take simple values and cast them into complex types. For example, `16-05-1994T00:00:00+00` could be cast into a `Carbon` object with the same date.
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced-usage/creating-a-rule-inferrer.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Creating a rule inferrer
weight: 10
weight: 8
---

Rule inferrers will try to infer validation rules for properties within a data object.
Expand Down
16 changes: 12 additions & 4 deletions docs/advanced-usage/creating-a-transformer.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Creating a transformer
weight: 9
weight: 7
---

Transformers take complex values and transform them into simple types. For example, a `Carbon` object could be transformed to `16-05-1994T00:00:00+00`.
Expand All @@ -10,10 +10,18 @@ A transformer implements the following interface:
```php
interface Transformer
{
public function transform(DataProperty $property, mixed $value): mixed;
public function transform(DataProperty $property, mixed $value, TransformationContext $context): mixed;
}
```

The value that should be transformed is given, and a `DataProperty` object which represents the property for which the value is transformed. You can read more about the internal structures of the package [here](/docs/laravel-data/v4/advanced-usage/internal-structures).
The following parameters are provided:

In the end, the transformer should return a transformed value. Please note that the given value of a transformer can never be `null`.
- **property**: a `DataProperty` object which represents the property for which the value is transformed. You can read more about the internal structures of the package [here](/docs/laravel-data/v4/advanced-usage/internal-structures)
- **value**: the value that should be transformed, this will never be `null`
- **context**: a `TransformationContext` object which contains the current transformation context with the following properties:
- **transformValues** indicates if values should be transformed or not
- **mapPropertyNames** indicates if property names should be mapped or not
- **wrapExecutionType** the execution type that should be used for wrapping values
- **transformers** a collection of transformers that can be used to transform values

In the end, the transformer should return a transformed value.
4 changes: 4 additions & 0 deletions docs/advanced-usage/normalizers.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ By default, there are five normalizers for each data object:
- **ArrayNormalizer** will cast arrays
- **JsonNormalizer** will cast json strings

A sixth normalizer can be optionally enabled:

- **FormRequestNormalizer** will normalize a form request by calling the `validated` method

Normalizers can be globally configured in `config/data.php`, and can be configured on a specific data object by overriding the `normalizers` method.

```php
Expand Down
13 changes: 11 additions & 2 deletions docs/advanced-usage/pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ By default, the pipeline exists of the following pipes:

- **AuthorizedDataPipe** checks if the user is authorized to perform the request
- **MapPropertiesDataPipe** maps the names of properties
- **FillRouteParameterPropertiesDataPipe** fills property values from route parameters
- **ValidatePropertiesDataPipe** validates the properties
- **DefaultValuesDataPipe** adds default values for properties when they are not set
- **CastPropertiesDataPipe** casts the values of properties
Expand All @@ -35,19 +36,20 @@ class SongData extends Data
->into(static::class)
->through(AuthorizedDataPipe::class)
->through(MapPropertiesDataPipe::class)
->through(FillRouteParameterPropertiesDataPipe::class)
->through(ValidatePropertiesDataPipe::class)
->through(DefaultValuesDataPipe::class)
->through(CastPropertiesDataPipe::class);
}
}
```

Each pipe implements the `DataPipe` interface and should return a `Collection` of properties:
Each pipe implements the `DataPipe` interface and should return an `array` of properties:

```php
interface DataPipe
{
public function handle(mixed $payload, DataClass $class, Collection $properties): Collection;
public function handle(mixed $payload, DataClass $class, array $properties, CreationContext $creationContext): array;
}
```

Expand All @@ -57,6 +59,13 @@ The `handle` method has several arguments:
- **class** the `DataClass` object for the data
object [more info](/docs/laravel-data/v4/advanced-usage/internal-structures)
- **properties** the key-value properties which will be used to construct the data object
- **creationContext** the context in which the data object is being created you'll find the following info here:
- **dataClass** the data class which is being created
- **validationStrategy** the validation strategy which is being used
- **mapPropertyNames** whether property names should be mapped
- **withoutMagicalCreation** whether to use the magical creation methods or not
- **ignoredMagicalMethods** the magical methods which are ignored
- **casts** a collection of global casts

When using a magic creation methods, the pipeline is not being used (since you manually overwrite how a data object is
constructed). Only when you pass in a request object a minimal version of the pipeline is used to authorize and validate
Expand Down
16 changes: 0 additions & 16 deletions docs/advanced-usage/typescript.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,3 @@ class DataObject extends Data
}
}
```

You can also make all the properties of a data object optional in TypeScript like this:

```php
class DataObject extends Data
{
#[TypeScriptOptional]
public function __construct(
public int $id,
public string $someString,
public Optional|string $optional,
)
{
}
}
```
2 changes: 1 addition & 1 deletion docs/advanced-usage/use-with-inertia.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Use with Inertia
weight: 6
weight: 9
---

> Inertia.js lets you quickly build modern single-page React, Vue, and Svelte apps using classic server-side routing and controllers.
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced-usage/use-with-livewire.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Use with Livewire
weight: 7
weight: 10
---

> Livewire is a full-stack framework for Laravel that makes building dynamic interfaces simple without leaving the comfort of Laravel.
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced-usage/validation-attributes.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Validation attributes
weight: 16
weight: 14
---

These are all the validation attributes currently available in laravel-data.
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced-usage/working-with-dates.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ within the `data.php` config file:

Now when casting a date, a valid format will be searched. When none can be found, an exception is thrown.

When a transformers hasn't explicitly stated it's format, the first format within the array is used.
When a transformers hasn't explicitly stated its format, the first format within the array is used.

## Casting dates in a different time zone

Expand Down
6 changes: 3 additions & 3 deletions docs/as-a-resource/transformers.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ It is possible to disable the transformation of values, which will make the `tra
use Spatie\LaravelData\Support\Transformation\TransformationContext;

ArtistData::from($artist)->transform(
TransformationContext::create()->withoutTransformingValues()
TransformationContextFactory::create()->transformValues(false)
);
```

Expand All @@ -118,7 +118,7 @@ The [mapping of property names](/docs/laravel-data/v4/as-a-resource/mapping-prop

```php
ArtistData::from($artist)->transform(
TransformationContext::create()->mapPropertyNames(false)
TransformationContextFactory::create()->mapPropertyNames(false)
);
```

Expand All @@ -128,7 +128,7 @@ It is possible to enable [wrapping](/docs/laravel-data/v4/as-a-resource/wrapping
use Spatie\LaravelData\Support\Wrapping\WrapExecutionType;

ArtistData::from($artist)->transform(
TransformationContext::create()->wrapExecutionType(WrapExecutionType::Enabled)
TransformationContextFactory::create()->wrapExecutionType(WrapExecutionType::Enabled)
);
```

Expand Down
2 changes: 1 addition & 1 deletion src/Concerns/BaseDataCollectable.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function getDataClass(): string
public function getIterator(): ArrayIterator
{
/** @var array<TValue> $data */
$data = $this->transform(TransformationContextFactory::create()->transformValues(false));
$data = $this->transform(TransformationContextFactory::create()->withValueTransformation(false));

return new ArrayIterator($data);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Concerns/ResponsableData.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ trait ResponsableData
public function toResponse($request)
{
$contextFactory = TransformationContextFactory::create()
->wrapExecutionType(WrapExecutionType::Enabled);
->withWrapExecutionType(WrapExecutionType::Enabled);

$includePartials = DataContainer::get()->requestQueryStringPartialsResolver()->execute(
$this,
Expand Down
2 changes: 1 addition & 1 deletion src/Concerns/TransformableData.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public function transform(

public function all(): array
{
return $this->transform(TransformationContextFactory::create()->transformValues(false));
return $this->transform(TransformationContextFactory::create()->withValueTransformation(false));
}

public function toArray(): array
Expand Down
10 changes: 1 addition & 9 deletions src/DataPipes/DataPipe.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,9 @@
interface DataPipe
{
/**
* @param mixed $payload
* @param DataClass $class
* @param array<array-key, mixed> $properties
* @param CreationContext $creationContext
*
* @return array<array-key, mixed>
*/
public function handle(
mixed $payload,
DataClass $class,
array $properties,
CreationContext $creationContext
): array;
public function handle(mixed $payload, DataClass $class, array $properties, CreationContext $creationContext): array;
}
1 change: 0 additions & 1 deletion src/Support/Creation/CreationContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Spatie\LaravelData\CursorPaginatedDataCollection;
use Spatie\LaravelData\DataCollection;
use Spatie\LaravelData\PaginatedDataCollection;
use Spatie\LaravelData\Support\Casting\GlobalCastsCollection;
use Spatie\LaravelData\Support\DataContainer;

/**
Expand Down
36 changes: 18 additions & 18 deletions src/Support/Creation/CreationContextFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use Spatie\LaravelData\CursorPaginatedDataCollection;
use Spatie\LaravelData\DataCollection;
use Spatie\LaravelData\PaginatedDataCollection;
use Spatie\LaravelData\Support\Casting\GlobalCastsCollection;
use Spatie\LaravelData\Support\DataContainer;

/**
Expand All @@ -32,7 +31,7 @@ public function __construct(
public string $dataClass,
public ValidationStrategy $validationStrategy,
public bool $mapPropertyNames,
public bool $withoutMagicalCreation,
public bool $disableMagicalCreation,
public ?array $ignoredMagicalMethods,
public ?GlobalCastsCollection $casts,
) {
Expand All @@ -48,25 +47,12 @@ public static function createFromConfig(
dataClass: $dataClass,
validationStrategy: ValidationStrategy::from($config['validation_strategy']),
mapPropertyNames: true,
withoutMagicalCreation: false,
disableMagicalCreation: false,
ignoredMagicalMethods: null,
casts: null,
);
}

public static function createFromContext(
CreationContext $context
) {
return new self(
dataClass: $context->dataClass,
validationStrategy: $context->validationStrategy,
mapPropertyNames: $context->mapPropertyNames,
withoutMagicalCreation: $context->withoutMagicalCreation,
ignoredMagicalMethods: $context->ignoredMagicalMethods,
casts: $context->casts,
);
}

public function validationStrategy(ValidationStrategy $validationStrategy): self
{
$this->validationStrategy = $validationStrategy;
Expand Down Expand Up @@ -95,6 +81,13 @@ public function alwaysValidate(): self
return $this;
}

public function withPropertyNameMapping(bool $withPropertyNameMapping = true): self
{
$this->mapPropertyNames = $withPropertyNameMapping;

return $this;
}

public function withoutPropertyNameMapping(bool $withoutPropertyNameMapping = true): self
{
$this->mapPropertyNames = ! $withoutPropertyNameMapping;
Expand All @@ -104,7 +97,14 @@ public function withoutPropertyNameMapping(bool $withoutPropertyNameMapping = tr

public function withoutMagicalCreation(bool $withoutMagicalCreation = true): self
{
$this->withoutMagicalCreation = $withoutMagicalCreation;
$this->disableMagicalCreation = $withoutMagicalCreation;

return $this;
}

public function withMagicalCreation(bool $withMagicalCreation = true): self
{
$this->disableMagicalCreation = ! $withMagicalCreation;

return $this;
}
Expand Down Expand Up @@ -157,7 +157,7 @@ public function get(): CreationContext
dataClass: $this->dataClass,
validationStrategy: $this->validationStrategy,
mapPropertyNames: $this->mapPropertyNames,
withoutMagicalCreation: $this->withoutMagicalCreation,
withoutMagicalCreation: $this->disableMagicalCreation,
ignoredMagicalMethods: $this->ignoredMagicalMethods,
casts: $this->casts,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Spatie\LaravelData\Support\Casting;
namespace Spatie\LaravelData\Support\Creation;

use ArrayIterator;
use IteratorAggregate;
Expand Down
2 changes: 1 addition & 1 deletion src/Support/DataConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use ReflectionClass;
use Spatie\LaravelData\Contracts\BaseData;
use Spatie\LaravelData\RuleInferrers\RuleInferrer;
use Spatie\LaravelData\Support\Casting\GlobalCastsCollection;
use Spatie\LaravelData\Support\Creation\GlobalCastsCollection;
use Spatie\LaravelData\Support\Transformation\GlobalTransformersCollection;

class DataConfig
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function add(string $transformable, Transformer $transformer): self
public function findTransformerForValue(mixed $value): ?Transformer
{
if (gettype($value) !== 'object') {
return null;
return $this->transformers[get_debug_type($value)] ?? null;
}

foreach ($this->transformers as $transformable => $transformer) {
Expand Down
Loading

0 comments on commit fcc0d8f

Please sign in to comment.