### Install spatie/laravel-typescript-transformer Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/typescript Install the package via composer. ```bash composer require spatie/laravel-typescript-transformer ``` -------------------------------- ### Initial Controller Example Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/collections A basic controller method returning a collection of `SongData` objects using the `collect` method. ```php class SongController { public function index() { return SongData::collect(Song::all()); } } ``` -------------------------------- ### Example JSON Output with Query String Include Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/lazy-properties Demonstrates the JSON output when a property is included via the `?include=` query string. ```json { "name" : "Ruben Van Assche", "favorite_song" : { "name" : "Never Gonna Give You Up", "artist" : "Rick Astley" } } ``` -------------------------------- ### Install Laravel Data via Composer Source: https://spatie.be/docs/laravel-data/v4/installation-setup Use this command to add the Laravel Data package to your project. ```bash composer require spatie/laravel-data ``` -------------------------------- ### Example JSON Output without Query String Include Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/lazy-properties Shows the default JSON output when no specific properties are requested via query string. ```json { "name" : "Ruben Van Assche" } ``` -------------------------------- ### Implementing a Custom Normalizer Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/normalizers Provides an example of creating a custom normalizer by implementing the `Normalizer` interface. The `normalize` method should return an array or null if it cannot handle the payload. ```php class ArrayableNormalizer implements Normalizer { public function normalize(mixed $value): ?array { if (! $value instanceof Arrayable) { return null; } return $value->toArray(); } } ``` -------------------------------- ### Render Livewire Component with Data Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/use-with-livewire Render a Livewire component and pass data using Laravel Data. This example shows how to initialize the component with existing data. ```php ``` -------------------------------- ### Output of `with` method Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/appending-properties The `with` method returns an array of properties that will be appended to the data object's transformation. This example shows the structure of the appended `endpoints`. ```php [ 'id' => 1, 'name' => 'Never gonna give you up', 'artist' => 'Rick Astley', 'endpoints' => [ 'show' => 'https://spatie.be/songs/1', 'edit' => 'https://spatie.be/songs/1', 'delete' => 'https://spatie.be/songs/1', ], ] ``` -------------------------------- ### Container Reference with Dependency Parameters Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes Pass parameters to the dependency when resolving it from the container for use in validation attributes. This example passes a 'repository' parameter to `SongSettings`. ```php class SongData extends Data { public function __construct( public string $title, #[Max(new ContainerReference(SongSettings::class, 'max_song_title_length', parameters: ['repository' => 'redis']))] public string $artist, ) { } } ``` -------------------------------- ### Define Data Structure Source: https://spatie.be/docs/laravel-data/v4/validation/manual-rules Example of a data structure that will be validated. ```php 'Best songs ever made', 'songs' => [ ['title' => 'Never Gonna Give You Up'], ['title' => 'Heroes', 'artist' => 'David Bowie'], ], ]; ``` -------------------------------- ### PHP Data Object with Lazy and Optional Properties Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/typescript Example of a PHP Data object demonstrating lazy and optional properties. ```php class DataObject extends Data { public function __construct( public Lazy|string $lazy, public Optional|string $optional, ) { } } ``` -------------------------------- ### Basic Data Class with Validation Rules Source: https://spatie.be/docs/laravel-data/v4/validation/skipping-validation This example shows a basic Data class with a constructor and static rules method, defining validation for request inputs. ```php class SongData extends Data { public function __construct( public string $name, ) { } public static function fromRequest(Request $request): static{ return new self("{$request->input('first_name')} {$request->input('last_name')}") } public static function rules(): array { return [ 'first_name' => ['required', 'string'], 'last_name' => ['required', 'string'], ]; } } ``` -------------------------------- ### Define Validation Rules Source: https://spatie.be/docs/laravel-data/v4/validation/manual-rules Example of defining manual validation rules for the data structure. ```php ['string', 'required'], 'songs' => ['present', 'array'], 'songs.*.title' => ['string', 'required'], 'songs.*.artist' => ['string', 'nullable'], 'songs.*' => [NestedRules(...)], ]; ``` -------------------------------- ### Livewire Component Using Data with Synths Enabled Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/use-with-livewire Example of a Livewire component that uses a Laravel Data object as a property, leveraging Livewire Synths for seamless integration without explicit `Wireable` implementation. ```php class SongUpdateComponent extends Component { public SongData $data; public function mount(public int $id): void { $this->data = SongData::from(Song::findOrFail($id)); } public function save(): void { Artist::findOrFail($this->id)->update($this->data->toArray()); } public function render(): string { return ``` -------------------------------- ### Combined Cast and Transformer Implementation Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/creating-a-transformer Example of a class implementing both Cast and Transformer interfaces to apply the same logic for both casting and transformation. ```php class ToUpperCastAndTransformer implements Cast, Transformer { public function cast(DataProperty $property, mixed $value, array $properties, CreationContext $context): string { return strtoupper($value); } public function transform(DataProperty $property, mixed $value, TransformationContext $context): string { return strtoupper($value); } } ``` -------------------------------- ### Inferring Validation Rules from Data Class Source: https://spatie.be/docs/laravel-data/v4/validation/auto-rule-inferring Example of a data class and the validation rules automatically inferred by the package based on property types and nullability. ```php class ArtistData extends Data{ public function __construct( public string $name, public int $age, public ?string $genre, ) { } } ``` ```php [ 'name' => ['required', 'string'], 'age' => ['required', 'integer'], 'genre' => ['nullable', 'string'], ] ``` -------------------------------- ### Custom Cast Implementation Example Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/eloquent-casting Illustrates a custom cast implementation for a specific data type, such as a custom object or array structure, ensuring proper serialization and deserialization. ```php namespace App\Data\Casts; use Spatie\LaravelData\Casts\Cast; use Spatie\LaravelData\Support\DataContainer; use Carbon\Carbon; class CarbonToTimestampCast implements Cast { public function cast(DataContainer $container, string $property, mixed $value, array $context = []): mixed { if ($value instanceof Carbon) { return $value->getTimestamp(); } return Carbon::createFromTimestamp($value)->getTimestamp(); } } ``` -------------------------------- ### Configure Global Transformers Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/transformers Define global transformers in the `data.php` configuration file to handle specific types or interfaces by default. This example shows how to configure transformers for `DateTimeInterface` and `Arrayable`. ```php use Illuminate\Contracts\Support\Arrayable; use Spatie\LaravelData\Transformers\ArrayableTransformer; use Spatie\LaravelData\Transformers\DateTimeInterfaceTransformer; /* * Global transformers will take complex types and transform them into simple * types. */ 'transformers' => [ DateTimeInterface::class => DateTimeInterfaceTransformer::class, Arrayable::class => ArrayableTransformer::class, ], ``` -------------------------------- ### Configure Global Casts in data.php Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/casts Define global casts in the `config/data.php` file to apply them across multiple data objects. This example shows how to cast `DateTimeInterface` implementations. ```php 'casts' => [ DateTimeInterface::class => Spatie\LaravelData\Casts\DateTimeInterfaceCast::class, ], ``` -------------------------------- ### Enabling Livewire Synths in Configuration Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/use-with-livewire Illustrates how to enable the experimental Livewire Synths feature by modifying the `data.php` configuration file. This allows using data objects with Livewire without implementing `Wireable`. ```php 'livewire' => [ 'enable_synths' => false, ] ``` -------------------------------- ### Generated TypeScript Type Example Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/typescript This is the TypeScript type generated from the example PHP Data object. ```typescript { nullable: number | null; int: number; bool: boolean; string: string; float: number; array: Array; lazy? : string; optional? : string; simpleData: SimpleData; dataCollection: Array; } ``` -------------------------------- ### Define Data Object with Property Mappers Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/available-property-mappers Use the `#[MapName]` attribute with various mapper classes to define how property names should be mapped. This example shows mapping to camelCase, snake_case, kebab-case, studly_case, lowerCase, and upperCase, as well as a custom provided name. ```php use Spatie\LaravelData\Mappers\CamelCaseMapper; use Spatie\LaravelData\Mappers\SnakeCaseMapper; use Spatie\LaravelData\Mappers\KebabCaseMapper; use Spatie\LaravelData\Mappers\ProvidedNameMapper; use Spatie\LaravelData\Mappers\StudlyCaseMapper; use Spatie\LaravelData\Mappers\LowerCaseMapper; use Spatie\LaravelData\Mappers\UpperCaseMapper; class ContractData extends Data { public function __construct( #[MapName(CamelCaseMapper::class)] public string $name, #[MapName(SnakeCaseMapper::class)] public string $recordCompany, #[MapName(KebabCaseMapper::class)] public string $vatNumber, #[MapName(new ProvidedNameMapper('country field'))] public string $country, #[MapName(StudlyCaseMapper::class)] public string $cityName, #[MapName(LowerCaseMapper::class)] public string $addressLine1, #[MapName(UpperCaseMapper::class)] public string $addressLine2, ) { } } ``` -------------------------------- ### PHP Data Object Example Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/typescript This is an example of a PHP Data object that can be transformed into a TypeScript type. ```php class DataObject extends Data { public function __construct( public null|int $nullable, public int $int, public bool $bool, public string $string, public float $float, /** @var string[] */ public array $array, public Lazy|string $lazy, public Optional|string $optional, public SimpleData $simpleData, /** @var \Spatie\LaravelData\Tests\Fakes\SimpleData[] */ public DataCollection $dataCollection, ) { } } ``` -------------------------------- ### TypeScript Definition Example Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/typescript Example of a TypeScript interface generated from a Laravel Data class. This interface mirrors the structure and types of the corresponding PHP Data class. ```typescript export interface UserData { id: number; name: string; email: string; created_at: string | null; updated_at: string | null; } ``` -------------------------------- ### Configure Reflection Discovery Base Path and Namespace Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/performance When using reflection discovery with a non-standard directory structure or namespace, configure the `base_path` and `root_namespace` options. ```php 'structure_caching' => [ 'reflection_discovery' => [ 'enabled' => true, 'base_path' => base_path(), 'root_namespace' => null, ], ], ``` -------------------------------- ### Injecting Values with `create()` and named arguments Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/injecting-property-values Shows how to use `create()` with named arguments for injecting values. This improves readability and maintainability, especially with many constructor parameters. ```php namespace App\Data; use Spatie\LaravelData\Data; class UserData extends Data { public function __construct( public string $name, public string $email, public string $password ) {} } $user = UserData::create( name: 'John Doe', email: 'john@example.com', password: 'secret' ); ``` -------------------------------- ### Pass Parameters to Local Casts Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/casts Parameters can be passed to casts using the `#[WithCast]` attribute, for example, specifying the enum type. ```php #[WithCast(EnumCast::class, type: Format::class)] public Format $format ``` -------------------------------- ### Using Normalizers with Eloquent Models Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/normalizers Demonstrates how to create a data object from an Eloquent model using the `from` method, which leverages normalizers internally. ```php SongData::from(Song::findOrFail($id)); ``` -------------------------------- ### Include Multiple Properties via Query String Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/lazy-properties Illustrates how to include multiple properties by separating them with commas in the query string. ```http https://spatie.be/my-account?include=favorite_song,favorite_movie ``` -------------------------------- ### DoesntStartWith Validation Attribute Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/validation-attributes Validates that a string attribute does not start with a specified prefix. Can check against a single prefix or an array of prefixes. ```PHP #[DoesntStartWith('a')] public string $closure; ``` ```PHP #[DoesntStartWith(['a', 'b'])] public string $closure; ``` ```PHP #[DoesntStartWith('a', 'b')] public string $closure; ``` -------------------------------- ### Instantiate Abstract Data Subclasses Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/abstract-data Create individual instances of the concrete subclasses by providing the necessary properties. ```php Singer::from(['name' => 'Rick Astley', 'voice' => 'tenor']); Musician::from(['name' => 'Rick Astley', 'instrument' => 'guitar']); ``` -------------------------------- ### Get Transformed Data Object Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/transformers The `transform()` method, when called without arguments, behaves like `toArray()`, applying all configured transformations. ```php ArtistData::from($artist)->transform(); ``` -------------------------------- ### Injecting Values with `create()` and mixed arguments Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/injecting-property-values Illustrates using `create()` with a mix of array data and named arguments for injecting values. This provides flexibility when combining different data sources. ```php namespace App\Data; use Spatie\LaravelData\Data; class UserData extends Data { public function __construct( public string $name, public string $email, public string $password ) {} } $user = UserData::create( ['name' => 'John Doe'], email: 'john@example.com', password: 'secret' ); ``` -------------------------------- ### Get First Item from Collection Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/collections Retrieve the first item from a collection using the `first` method. This method is implemented from Laravel collections. ```php SongData::collect(Song::all(), DataCollection::class)->first(); // SongData object ``` -------------------------------- ### Including All Post Properties Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Demonstrates how to include all properties of the posts collection in the JSON output using the wildcard character. ```php $postData->include('posts.*')->toJson(); ``` -------------------------------- ### Get Data Object from FormRequest in Controller Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/get-data-from-a-class-quickly In a controller, after injecting a FormRequest with the `WithData` trait, you can call `getData()` to obtain the data object. ```php class SongController { public function __invoke(SongRequest $request): SongData { $data = $request->getData(); $song = Song::create($data->toArray()); return $data; } } ``` -------------------------------- ### Create Data Object using `SongData::from()` Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/request-to-data-object Use the `from` method to create a data object from a request instance. This method also handles validation. ```php class UpdateSongController { public function __invoke( Song $model, SongRequest $request ){ $model->update(SongData::from($request)->all()); return redirect()->back(); } } ``` -------------------------------- ### Validation Error for Missing Nested Image Data Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Example validation error response when the nested image data is missing required fields. ```json { "message": "The image must be an array. (and 2 more errors)", "errors": { "image": [ "The image must be an array." ], "image.filename": [ "The image.filename field is required." ], "image.size": [ "The image.size field is required." ] } } ``` -------------------------------- ### Implementing Base Data Class with Traits and Interfaces Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/traits-and-interfaces This code demonstrates the structure of the base `Data` class, showing how it implements multiple interfaces and uses various traits to achieve its functionality. This pattern can be extended to create custom data classes. ```php use Illuminate\Contracts\Support\Responsable; use Spatie\LaravelData\Concerns\AppendableData; use Spatie\LaravelData\Concerns\BaseData; use Spatie\LaravelData\Concerns\ContextableData; use Spatie\LaravelData\Concerns\EmptyData; use Spatie\LaravelData\Concerns\IncludeableData; use Spatie\LaravelData\Concerns\ResponsableData; use Spatie\LaravelData\Concerns\TransformableData; use Spatie\LaravelData\Concerns\ValidateableData; use Spatie\LaravelData\Concerns\WrappableData; use Spatie\LaravelData\Contracts\AppendableData as AppendableDataContract; use Spatie\LaravelData\Contracts\BaseData as BaseDataContract; use Spatie\LaravelData\Contracts\EmptyData as EmptyDataContract; use Spatie\LaravelData\Contracts\IncludeableData as IncludeableDataContract; use Spatie\LaravelData\Contracts\ResponsableData as ResponsableDataContract; use Spatie\LaravelData\Contracts\TransformableData as TransformableDataContract; use Spatie\LaravelData\Contracts\ValidateableData as ValidateableDataContract; use Spatie\LaravelData\Contracts\WrappableData as WrappableDataContract; abstract class Data implements Responsable, AppendableDataContract, BaseDataContract, TransformableDataContract, IncludeableDataContract, ResponsableDataContract, ValidateableDataContract, WrappableDataContract, EmptyDataContract { use ResponsableData; use IncludeableData; use AppendableData; use ValidateableData; use WrappableData; use TransformableData; use BaseData; use EmptyData; use ContextableData; } ``` -------------------------------- ### Get Data Object from Model Instance Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/get-data-from-a-class-quickly Once the `WithData` trait is applied to a Model, you can call `getData()` on an instance to retrieve its corresponding data object. ```php Song::firstOrFail($id)->getData(); // A SongData object ``` -------------------------------- ### Handle Null DataCollection with Default Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/eloquent-casting When the 'songs' attribute is null, this setup ensures a DataCollection is returned, allowing count() to be called without errors. ```php $artist = Artist::create([ 'songs' => null ]); $artist->songs; // DataCollection $artist->songs->count();// 0 ``` -------------------------------- ### Combine Input and Output Name Mapping Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/mapping-property-names Use `#[MapName]` to combine input and output property name mapping strategies. ```php #[MapName(SnakeCaseMapper::class)] class ContractData extends Data { public function __construct( public string $name, public string $recordCompany, ) { } } ``` -------------------------------- ### Injecting Values with `create()` Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/injecting-property-values Demonstrates using the `create()` static method for injecting values. This method is often used when you need to pass additional arguments to the constructor that are not part of the initial data array. ```php namespace App\Data; use Spatie\LaravelData\Data; class UserData extends Data { public function __construct( public string $name, public string $email, public string $password ) {} } $user = UserData::create( ['name' => 'John Doe', 'email' => 'john@example.com'], 'secret' ); ``` -------------------------------- ### Container Reference with Specific Dependency Property Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes Reference a specific property of a dependency resolved from the container. This example uses the `max_song_title_length` property from the `SongSettings` class. ```php class SongData extends Data { public function __construct( public string $title, #[Max(new ContainerReference(SongSettings::class, 'max_song_title_length'))] public string $artist, ) { } } ``` -------------------------------- ### Prepare Data for Pipeline Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/pipeline Use the prepareForPipeline method to modify properties after normalization but before they enter the data pipeline. ```php class SongMetadata { public function __construct( public string $releaseYear, public string $producer, ) {} } class SongData extends Data { public function __construct( public string $title, public SongMetadata $metadata, ) {} public static function prepareForPipeline(array $properties): array { $properties['metadata'] = Arr::only($properties, ['release_year', 'producer']); return $properties; } } ``` -------------------------------- ### Instantiate Data Object with Mapped Names Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/mapping-property-names Create a data object instance using its constructor. When the data object is transformed, the configured name mapping (e.g., snake_case for output) will be applied automatically. ```php $contract = new ContractData( name: 'Rick Astley', recordCompany: 'RCA Records', ); ``` -------------------------------- ### Add Global Transformer Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/transformers Add a global transformer to apply a specific transformation to all properties of a given type. This example adds `StringToUpperTransformer` for all 'string' properties. ```php ArtistData::from($artist)->transform( TransformationContextFactory::create()->withGlobalTransformer( 'string', StringToUpperTransformer::class ) ); ``` -------------------------------- ### Extend Pipeline with firstThrough Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/pipeline Extend the existing pipeline by adding a new pipe at the beginning using the firstThrough method. ```php class SongData extends Data { public static function pipeline(): DataPipeline { return parent::pipeline()->firstThrough(GuessCasingForKeyDataPipe::class); } } ``` -------------------------------- ### StartsWith Validation Attribute Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/validation-attributes Validate that a string attribute starts with a specific prefix. Accepts a single string, an array of strings, or multiple string arguments. ```PHP #[StartsWith('a')] public string $closure; ``` ```PHP #[StartsWith(['a', 'b'])] public string $closure; ``` ```PHP #[StartsWith('a', 'b')] public string $closure; ``` -------------------------------- ### Get Data Object with Value Transformation Disabled Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/transformers Use `TransformationContextFactory::create()->withoutValueTransformation()` with the `transform()` method to disable value transformations, similar to the `all()` method. ```php use Spatie\LaravelData\Support\Transformation\TransformationContext; ArtistData::from($artist)->transform( TransformationContextFactory::create()->withoutValueTransformation() ); ``` -------------------------------- ### Configure Directories for Structure Discovery Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/performance Specify the directories to be searched for data objects by the structure discoverer. By default, it scans `app/data` recursively. Modify this to include other directories. ```php 'structure_caching' => [ 'directories' => [ app_path('Data'), ], ], ``` -------------------------------- ### Authenticated User Reference with Specific Guard Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes Specify a different authentication guard than the default when using `AuthenticatedUserReference`. This example uses the 'api' guard for email uniqueness. ```php class UserData extends Data { public function __construct( public string $name, #[Unique('users', 'email', ignore: new AuthenticatedUserReference(guard: 'api'))] public string $email, ) { } } ``` -------------------------------- ### Define Includes in includeProperties Method Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/lazy-properties Defines 'songs' to be included by default for all transformations of AlbumData. This is a permanent configuration. ```php class AlbumData extends Data { /** * @param Lazy|Collection $songs */ public function __construct( public string $title, public Lazy|Collection $songs, ) { } public function includeProperties(): array { return [ 'songs' ]; } } ``` -------------------------------- ### Iterating Over a DataCollection Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/collections Shows how to iterate over a collection of data objects using a `foreach` loop, accessing properties of each item. ```php foreach ($songs as $song){ echo $song->title; } ``` -------------------------------- ### Validate and create Data object with defaults Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/defaults Use `validateAndCreate()` to create a Data object, applying validation rules. If no values are provided, defaults will be used. ```php SongData::validateAndCreate(); ``` -------------------------------- ### Configure `make:data` command defaults Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/commands Customize the default namespace and suffix for generated data objects by modifying the `data.php` configuration file. These settings can be overridden by command-line options. ```php 'commands' => [ /* * Provides default configuration for the `make:data` command. These settings can be overridden with options * passed directly to the `make:data` command for generating single Data classes, or if not set they will * automatically fall back to these defaults. See `php artisan make:data --help` for more information */ 'make' => [ /* * The default namespace for generated Data classes. This exists under the application's root namespace, * so the default 'Data` will end up as '\App\Data', and generated Data classes will be placed in the * app/Data/ folder. Data classes can live anywhere, but this is where `make:data` will put them. */ 'namespace' => 'Data', /* * This suffix will be appended to all data classes generated by make:data, so that they are less likely * to conflict with other related classes, controllers or models with a similar name without resorting * to adding an alias for the Data object. Set to a blank string (not null) to disable. */ 'suffix' => 'Data', ], ] ``` -------------------------------- ### Unique Validation with Authenticated User Reference Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes Utilize `AuthenticatedUserReference` in validation attributes to reference the currently logged-in user. This example ensures a user's email is unique. ```php use Spatie\LaravelData\Support\Validation\References\AuthenticatedUserReference; class UserData extends Data { public function __construct( public string $name, #[Unique('users', 'email', ignore: new AuthenticatedUserReference())] public string $email, ) { } } ``` -------------------------------- ### Publish Laravel Data Configuration Source: https://spatie.be/docs/laravel-data/v4/installation-setup Run this Artisan command to publish the package's configuration file to your application. ```bash php artisan vendor:publish --provider="Spatie\LaravelData\LaravelDataServiceProvider" --tag="data-config" ``` -------------------------------- ### Creating and Transforming Author Data Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Demonstrates creating an Author model, associating posts, and transforming it into an AuthorData object. Initially, only the name is included in the JSON. ```php $author = Author::create([ 'name' => 'Ruben Van Assche' ]); $author->posts()->create([ [ 'title' => 'Hello laravel-data', 'content' => 'This is an introduction post for the new package', 'status' => 'draft', 'published_at' => null, ] ]); AuthorData::from($author); ``` ```json { "name" : "Ruben Van Assche" } ``` -------------------------------- ### Inferred Validation Rules Example Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes This shows the merged validation rules for the `SongData` object, including automatically inferred `required` and `string` rules alongside the custom attributes. ```php [ 'uuid' => ['required', 'string', 'uuid'], 'ip' => ['required', 'string', 'max:15', 'ip', 'starts_with:192.'], ] ``` -------------------------------- ### Create Data Object from Plain PHP Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Instantiate a data object like a regular PHP object, passing constructor arguments directly. This is useful for creating data objects programmatically. ```php $post = new PostData( 'Hello laravel-data', 'This is an introduction post for the new package', PostStatus::published, CarbonImmutable::now() ); ``` -------------------------------- ### Create a DataCollection Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/collections Use DataCollection::class to create a collection of Data objects from a Laravel Eloquent collection. Ensure SongData::collect is used. ```php use Spatie\LaravelData\DataCollection; SongData::collect(Song::all(), DataCollection::class); ``` -------------------------------- ### Get Generated Validation Rules Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Retrieve the validation rules automatically generated by a data object based on its property types. This is useful for debugging or custom validation scenarios. ```php class DataController { public function __invoke(Request $request) { dd(PostData::getValidationRules($request->toArray())); } } ``` -------------------------------- ### Enable Data Wrapping Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/transformers Enable data wrapping for the transformed output by calling `withWrapping()` on the `TransformationContextFactory`. This will wrap the output in a 'data' key. ```php use Spatie\LaravelData\Support\Wrapping\WrapExecutionType; ArtistData::from($artist)->transform( TransformationContextFactory::create()->withWrapping() ); ``` -------------------------------- ### Injecting Values with a Constructor Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/injecting-property-values Shows how to use a constructor to inject values into a Data object. This method is standard for defining required properties. ```php namespace App\Data; use Spatie\LaravelData\Data; class UserData extends Data { public function __construct( public string $name, public string $email, public string $password ) {} } $user = UserData::from(['name' => 'John Doe', 'email' => 'john@example.com', 'password' => 'secret']); ``` -------------------------------- ### Get Data Object Without Transformation Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/transformers Call the `all()` method on a data object to retrieve its properties without applying any transformations. This is useful for preserving original data types. ```php ArtistData::from($artist)->all(); ``` -------------------------------- ### Instantiate Data Object Directly Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/creating-a-data-object.md Instantiate a data object using its constructor, similar to any other PHP class. ```php new SongData('Never gonna give you up', 'Rick Astley'); ``` -------------------------------- ### Get Raw Array from Data Object Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/from-data-to-array Retrieve the raw array representation of a data object without recursively transforming its properties. This is useful when you need the immediate values. ```php SongData::from(Song::first())->all(); ``` -------------------------------- ### Create an Inertia-ready Data Resource Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/use-with-inertia Define a Data Resource that can be directly passed to Inertia. This resource will handle the transformation of your Eloquent models or other data into a format suitable for your frontend. ```php use Spatie\LaravelData\Data;\n\nclass UserData extends Data\n{\n public function __construct(\n public int $id,\n public string $name,\n public string $email,\n ) {} } ``` -------------------------------- ### Define Lazy Property with Model Casting Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/lazy-properties Example of defining a lazy property that casts a related model's data. This demonstrates the repetitive code structure that AutoLazy aims to simplify. ```php class UserData extends Data { public function __construct( public string $title, public Lazy|SongData $favorite_song, ) { } public static function fromModel(User $user): self { return new self( $user->title, Lazy::create(fn() => SongData::from($user->favorite_song)) ); } } ``` -------------------------------- ### Include Multiple Properties via Grouped Query String Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/lazy-properties Shows an alternative method for including multiple properties using grouped query parameters. ```http https://spatie.be/my-account?include[]=favorite_song&include[]=favorite_movie ``` -------------------------------- ### Create Data object with default values Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/defaults Instantiate a Data object using `from()` without providing values for properties with defaults. The default values will be used. ```php SongData::from(); ``` -------------------------------- ### Validation Attribute Referencing Authenticated User Property Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes Reference a specific property of the authenticated user within a validation attribute. This example uses a custom property `max_song_title_length` from the authenticated user. ```php class SongData extends Data { #[Max(new AuthenticatedUserReference('max_song_title_length'))] public string $title, ) { } } ``` -------------------------------- ### Basic DataCollection Operations Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/collections Demonstrates common operations on a DataCollection, such as counting items, modifying an item by index, adding a new item, and removing an item. ```php // Counting the amount of items in the collection count($collection); ``` ```php // Changing an item in the collection $collection[0]->title = 'Giving Up on Love'; ``` ```php // Adding an item to the collection $collection[] = SongData::from(['title' => 'Never Knew Love', 'artist' => 'Rick Astley']); ``` ```php // Removing an item from the collection unset($collection[0]); ``` -------------------------------- ### Automatic Rule Generation in Laravel Data Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Laravel Data automatically generates validation rules based on property types. For example, 'required' for non-nullable properties and 'string' for string types. ```php array:4 [ "title" => array:2 [ 0 => "required" 1 => "string" ] "content" => array:2 [ 0 => "required" 1 => "string" ] "status" => array:2 [ 0 => "required" 1 => Illuminate\Validation\Rules\Enum { #type: "App\Enums\PostStatus" } ] "published_at" => array:2 [ 0 => "nullable" 1 => "date" ] ] ``` -------------------------------- ### Configure Cache Store and Prefix Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/performance Customize the cache store and prefix for structure caching in the `data.php` configuration file. This allows you to use specific cache drivers and namespaces. ```php 'structure_caching' => [ 'cache' => [ 'store' => 'redis', 'prefix' => 'laravel-data', ], ], ``` -------------------------------- ### Define a Native Enum Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Use native PHP enums to represent distinct states or types within your data objects. This example defines `PostStatus` with draft, published, and archived states. ```php enum PostStatus: string { case draft = 'draft'; case published = 'published'; case archived = 'archived'; } ``` -------------------------------- ### Create SongData Collection from Array Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/collections Use the `collect` method to create a collection of `SongData` objects from a simple array of attributes. The package automatically handles the conversion. ```php SongData::collect([ ['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley'], ['title' => 'Giving Up on Love', 'artist' => 'Rick Astley'], ]); // returns an array of SongData objects ``` -------------------------------- ### Define a Data Object Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Extend the base `Data` class and define public properties for your data structure. This example defines a `PostData` object with title, content, status, and publication date. ```php use Spatie\LaravelData\Data; class PostData extends Data { public function __construct( public string $title, public string $content, public PostStatus $status, public ?CarbonImmutable $published_at ) { } } ``` -------------------------------- ### Get a Wrapped Array with Explicit Wrapping Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/wrapping Use `wrap()` to explicitly define a key for wrapping a data object or collection. The `transform` method with `WrapExecutionType::Enabled` ensures the wrapping is applied. ```php SongData::from(Song::first())->wrap('data')->transform(wrapExecutionType: WrapExecutionType::Enabled); ``` -------------------------------- ### Generate TypeScript Definitions Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/typescript Run this command to generate the TypeScript file from your data objects. ```bash php artisan typescript:transform ``` -------------------------------- ### Unique Validation with Route Parameter and Model Property Reference Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes When referencing a route parameter that is a model, you can specify which property of that model to use for ignoring the unique constraint. This example uses the `uuid` property. ```php class SongData extends Data { public function __construct( public string $title, #[Unique('songs', ignore: new RouteParameterReference('song', 'uuid'))] public string $uuid, ) { } } ``` -------------------------------- ### Create Magic Creation Method for String Input Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Define a static fromString method to create PostData objects from a pipe-delimited string. This method handles parsing and instantiation. ```php use Spatie\LaravelData\Data; use Spatie\LaravelData\Attributes\WithCast; use Carbon\CarbonImmutable; class PostData extends Data { public function __construct( public string $title, public string $content, public PostStatus $status, #[WithCast(ImageCast::class)] public ?Image $image, #[Date] public ?CarbonImmutable $published_at ) { } public static function fromString(string $post): PostData { $fields = explode('|', $post); return new self( $fields[0], $fields[2], PostStatus::from($fields[1]), null, null ); } } ``` -------------------------------- ### Infer Validation Rules from Data Object Source: https://spatie.be/docs/laravel-data/v4/validation/introduction The package automatically infers validation rules based on property types. For example, `string` becomes `required`, `string` and `?string` becomes `nullable`, `string`. ```php class ArtistData extends Data{ public function __construct( public string $name, public int $age, public ?string $genre, ) { } } // Inferred rules: // [ // 'name' => ['required', 'string'], // 'age' => ['required', 'integer'], // 'genre' => ['nullable', 'string'], // ] ``` -------------------------------- ### Referencing Root Fields in Validation Attributes Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes To reference fields starting from the root data object, use `FieldReference` with `fromRoot: true`. This allows conditional validation based on top-level data properties. ```php class SongData extends Data { public function __construct( public string $title, #[RequiredIf(new FieldReference('album_name', fromRoot: true), 'Whenever You Need Somebody')] public string $artist, ) { } } ``` -------------------------------- ### Define default values using constructor Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/defaults Use the constructor to set default values for properties like strings, integers, and booleans. This approach works for simple types. ```php class SongData extends Data { public function __construct( public string $title = 'Never Gonna Give You Up', public string $artist = 'Rick Astley', ) { } } ``` -------------------------------- ### Custom Collection Creation Method Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/collections Define a custom static method starting with `collect` (e.g., `collectArray`) in your data class to handle complex collection creation logic, such as populating constructor properties. ```php class SongCollection extends Collection { public function __construct( $items = [], public array $artists = [], ) { parent::__construct($items); } } ``` ```php class SongData extends Data { public string $title; public string $artist; public static function collectArray(array $items): SongCollection { return new SongCollection( parent::collect($items), array_unique(array_map(fn(SongData $song) => $song->artist, $items)) ); } } ``` ```php SongData::collectArray([ ['title' => 'Never Gonna Give You Up', 'artist' => 'Rick Astley'], ['title' => 'Living on a prayer', 'artist' => 'Bon Jovi'], ]); // returns an SongCollection of SongData objects ``` -------------------------------- ### Including Multiple Post Properties Source: https://spatie.be/docs/laravel-data/v4/getting-started/quickstart Shows how to include multiple specific properties ('title' and 'status') for each post in the JSON output. ```php $postData->include('posts.{title,status}')->toJson(); ``` -------------------------------- ### Using WithCastAndTransformer Attribute Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/creating-a-transformer Demonstrates how to apply a custom cast and transformer to a data property using the `WithCastAndTransformer` attribute. ```php class SongData extends Data { public function __construct( public string $title, #[WithCastAndTransformer(SomeCastAndTransformer::class)] public string $artist, ) { } } ``` -------------------------------- ### Use Abstract Type in Parent Data Class Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/abstract-data Define a parent data class that uses the abstract data class as a property type. This setup requires a mechanism to resolve the correct subclass. ```php class Contract extends Data { public string $label; public Person $artist; } ``` -------------------------------- ### Configure Default Name Mapping Strategy Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/mapping-property-names Set a default name mapping strategy for all data objects in the `data.php` configuration file. ```php 'name_mapping_strategy' => [ 'input' => SnakeCaseMapper::class, 'output' => null, ], ``` -------------------------------- ### Define Nested Data Object Structure Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/from-data-to-array Define a data object that includes another data object as a property. Ensure the nested data object is correctly instantiated, for example, using `SongData::from()`. ```php class UserData extends Data { public function __construct( public string $title, public string $email, public SongData $favorite_song, ) { } public static function fromModel(User $user): self { return new self( $user->title, $user->email, SongData::from($user->favorite_song) ); } } ``` -------------------------------- ### Validation Attribute Referencing Container Dependency Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes Use `ContainerReference` to inject and reference values from Laravel's service container into validation attributes. This example references a configuration value for maximum song title length. ```php use Spatie\LaravelData\Support\Validation\References\ContainerReference; class SongData extends Data { public function __construct( public string $title, #[Max(new ContainerReference('max_song_title_length'))] public string $artist, ) { } } ``` -------------------------------- ### Set Global Wrap Key in Configuration Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/wrapping Configure a global default wrap key for all data objects in the `config/data.php` file. Set this to `null` to disable wrapping globally. ```php 'wrap' => 'data', ``` -------------------------------- ### Create Data Object from Model with Nested Data Objects - PHP Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/model-to-data-object Handle nested relationships by providing a mapping for nested Data Objects. This example shows how to map a 'posts' relationship to a collection of 'PostData' objects. ```php use App\Models\User; use App\Data\UserData; use App\Data\PostData; $user = User::find(1); $userData = UserData::from($user, ['posts' => PostData::class]); ``` -------------------------------- ### Implementing WireableData for Livewire Integration Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/use-with-livewire Shows how to make a Laravel Data class compatible with Livewire by implementing the `Wireable` interface and using the `WireableData` trait. ```php class SongData extends Data implements Wireable { use WireableData; public function __construct( public string $title, public string $artist, ) { } } ``` -------------------------------- ### Handle Multiple Date Formats in Configuration Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/working-with-dates Configure an array of date formats in `data.php` to handle different incoming date string formats. The casting process will attempt to match any of these formats. ```php 'date_format' => [DATE_ATOM, 'Y-m-d'], ``` -------------------------------- ### Generated Validation Rules for Nested Data Source: https://spatie.be/docs/laravel-data/v4/validation/using-validation-attributes When using nested data objects, the generated validation rules reflect the hierarchical structure, allowing validation of properties within nested objects. For example, `song.artist` is validated based on `song.title`. ```php [ 'album_name' => ['required', 'string'], 'songs' => ['required', 'array'], 'song.title' => ['required', 'string'], 'song.artist' => ['string', 'required_if:song.title,"Never Gonna Give You Up"'], ] ``` -------------------------------- ### Instantiate Parent Data Class with Subclass Data Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/abstract-data Provide data for the parent data class, including data that can be used to construct one of the abstract class's subclasses. ```php Contract::from(['label' => 'PIAS', 'artist' => ['name' => 'Rick Astley', 'voice' => 'tenor']]); Contract::from(['label' => 'PIAS', 'artist' => ['name' => 'Rick Astley', 'instrument' => 'guitar']]); ``` -------------------------------- ### Cache Data Structures Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/performance Run this command to analyze and cache the structures of all data objects in your application. Execute it after creating or modifying data objects and before deploying to production. ```bash php artisan data:cache-structures ``` -------------------------------- ### Livewire Component with Data Property Source: https://spatie.be/docs/laravel-data/v4/advanced-usage/use-with-livewire Demonstrates how to use a Laravel Data object as a public property in a Livewire component and hydrate it from a database model. ```php class Song extends Component { public SongData $song; public function mount(int $id) { $this->song = SongData::from(Song::findOrFail($id)); } public function render() { return view('livewire.song'); } } ``` -------------------------------- ### Configure Throw on Max Transformation Depth (Global) Source: https://spatie.be/docs/laravel-data/v4/as-a-resource/transformers Configure whether to throw a `MaxTransformationDepthReached` exception or return an empty array when the maximum transformation depth is reached. ```php 'throw_when_max_transformation_depth_reached' => true, ``` -------------------------------- ### Handle Optional Data Object Creation Source: https://spatie.be/docs/laravel-data/v4/as-a-data-transfer-object/creating-a-data-object.md Use the `optional` method to safely create a data object, returning `null` if the input is `null`. This prevents errors when dealing with potentially null values. ```php SongData::optional(null); ```