Skip to content

Commit

Permalink
Add better support for livewire
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenvanassche committed Nov 17, 2022
1 parent e709ee4 commit ac30b6e
Show file tree
Hide file tree
Showing 10 changed files with 173 additions and 50 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: 7
weight: 8
---

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: 9
weight: 10
---

Rule inferrers will try to infer validation rules for properties within a data object.
Expand Down
2 changes: 1 addition & 1 deletion 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: 8
weight: 9
---

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 Down
2 changes: 1 addition & 1 deletion docs/advanced-usage/internal-structures.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Internal structures
weight: 10
weight: 11
---

This package has some internal structures which are used to analyze data objects and their properties. They can be helpful when writing casts, transformers or rule inferrers.
Expand Down
48 changes: 48 additions & 0 deletions docs/advanced-usage/use-with-livewire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
title: Use with Livewire
weight: 7
---

> Livewire is a full-stack framework for Laravel that makes building dynamic interfaces simple without leaving the comfort of Laravel.
Laravel Data works excellently with [Laravel Livewire](https://laravel-livewire.com).

You can use a data object as one of the properties of your Livewire component as such:

```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');
}
}
```

A few things are required to make this work:

1) You should implement `Wireable` on all the data classes you'll be using with Livewire
2) Each of these classes should also use the `WireableData` trait provided by this package
3) That's it

We can update our previous example to make it work with Livewire as such:

```php
class SongData extends Data implements Wireable
{
use WireableData;

public function __construct(
public string $title,
public string $artist,
) {
}
}
```
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: 11
weight: 12
---

It is possible to validate the request before a data object is constructed. This can be done by adding validation attributes to the properties of a data object like this:
Expand Down
20 changes: 20 additions & 0 deletions src/Concerns/WireableData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Spatie\LaravelData\Concerns;

use Spatie\LaravelData\Resolvers\DataFromSomethingResolver;

trait WireableData
{
public function toLivewire(): array
{
return $this->toArray();
}

public static function fromLivewire($value): static
{
return app(DataFromSomethingResolver::class)
->ignoreMagicalMethods('fromLivewire')
->execute(static::class, $value);
}
}
12 changes: 11 additions & 1 deletion src/Resolvers/DataFromSomethingResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public function __construct(
protected DataConfig $dataConfig,
protected DataFromArrayResolver $dataFromArrayResolver,
protected bool $withoutMagicalCreation = false,
protected array $ignoredMagicalMethods = [],
) {
}

Expand All @@ -29,6 +30,13 @@ public function withoutMagicalCreation(bool $withoutMagicalCreation = true): sel
return $this;
}

public function ignoreMagicalMethods(string ...$methods): self
{
array_push($this->ignoredMagicalMethods, ...$methods);

return $this;
}

public function execute(string $class, mixed ...$payloads): BaseData
{
if ($data = $this->createFromCustomCreationMethod($class, $payloads)) {
Expand Down Expand Up @@ -63,7 +71,9 @@ protected function createFromCustomCreationMethod(string $class, array $payloads
$customCreationMethods = $this->dataConfig
->getDataClass($class)
->methods
->filter(fn (DataMethod $method) => $method->isCustomCreationMethod);
->filter(fn(DataMethod $method) => $method->isCustomCreationMethod
&& ! in_array($method->name, $this->ignoredMagicalMethods)
);

$methodName = null;

Expand Down
Loading

1 comment on commit ac30b6e

@francoism90
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rubenvanassche I'm really happy with Livewire support! I was now using a custom wireable trait, but this looks really good! :)

Please sign in to comment.