Skip to content

Commit da90e09

Browse files
authored
Merge pull request #16 from square/laravel-casts
Proposal for integration with Laravel casts
2 parents 82fc626 + e9edabf commit da90e09

File tree

12 files changed

+260
-3
lines changed

12 files changed

+260
-3
lines changed

.github/workflows/php-8-0.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
uses: shivammathur/setup-php@v2
2222
with:
2323
php-version: '8.0'
24+
extensions: pdo, pdo_sqlite
2425

2526
- name: Validate composer.json and composer.lock
2627
run: composer validate --strict

.github/workflows/php-8-1.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
uses: shivammathur/setup-php@v2
2222
with:
2323
php-version: '8.1'
24+
extensions: pdo, pdo_sqlite
2425

2526
- name: Validate composer.json and composer.lock
2627
run: composer validate --strict

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
ci-php80:
2-
./vendor/bin/phpcs --standard=PSR2 src/ tests/
32
./vendor/bin/phpunit --testsuite php80
3+
./vendor/bin/phpcs --standard=PSR2 src/ tests/
44
vendor/bin/phpstan analyse src tests --level 5 -c phpstan.php80.neon
55

66
ci-php81:
7-
./vendor/bin/phpcs --standard=PSR2 src/ tests/
87
./vendor/bin/phpunit --testsuite php81
8+
./vendor/bin/phpcs --standard=PSR2 src/ tests/
99
vendor/bin/phpstan analyse src tests --level 5 -c phpstan.neon

README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,3 +481,76 @@ that this is expected behavior by adding this library's extension in your `phpst
481481
includes:
482482
- vendor/square/pjson/extension.neon
483483
```
484+
485+
## Laravel Integration
486+
487+
### via castable
488+
489+
If you wish to cast Eloquent model attributes to classes via Pjson, you might do so with the provided casting utilities:
490+
491+
```php
492+
use Illuminate\Contracts\Database\Eloquent\Castable;
493+
use Square\Pjson\Json;
494+
use Square\Pjson\JsonSerialize;
495+
use Square\Pjson\Integrations\Laravel\JsonCastable;
496+
497+
class Schedule implements Castable // implement the laravel interface
498+
{
499+
use JsonSerialize;
500+
use JsonCastable; // use the provided Pjson trait
501+
502+
#[Json]
503+
protected int $start;
504+
505+
#[Json]
506+
protected int $end;
507+
508+
public function __construct(int $start, int $end)
509+
{
510+
$this->start = $start;
511+
$this->end = $end;
512+
}
513+
}
514+
```
515+
516+
Then in your Eloquent model:
517+
518+
```php
519+
$casts = [
520+
'schedule' => Schedule::class,
521+
];
522+
```
523+
524+
### via cast arguments
525+
526+
Alternatively, you can simply use Laravel's cast arguments. In this case the `Schedule` class stays the way it used to be:
527+
528+
```php
529+
use Square\Pjson\Json;
530+
use Square\Pjson\JsonSerialize;
531+
532+
class Schedule
533+
{
534+
use JsonSerialize;
535+
536+
#[Json]
537+
protected int $start;
538+
539+
#[Json]
540+
protected int $end;
541+
542+
public function __construct(int $start, int $end)
543+
{
544+
$this->start = $start;
545+
$this->end = $end;
546+
}
547+
}
548+
```
549+
550+
And you provide the class target of the cast like:
551+
552+
```php
553+
$casts = [
554+
'schedule' => JsonCaster::class.':'.Schedule::class,
555+
];
556+
```

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"symfony/var-dumper": "^6.0",
2323
"phpunit/phpunit": "^9.5",
2424
"squizlabs/php_codesniffer": "^3.7",
25-
"phpstan/phpstan": "^1.8"
25+
"phpstan/phpstan": "^1.8",
26+
"orchestra/testbench": "^7.11"
2627
}
2728
}

phpunit.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@
1919
<directory suffix="Test.php">tests</directory>
2020
</testsuite>
2121
</testsuites>
22+
<php>
23+
<env name="DB_CONNECTION" value="testing"/>
24+
</php>
2225
</phpunit>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Square\Pjson\Integrations\Laravel;
4+
5+
trait JsonCastable
6+
{
7+
public static function castUsing(array $arguments)
8+
{
9+
return new JsonCaster(static::class);
10+
}
11+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Square\Pjson\Integrations\Laravel;
4+
5+
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
6+
7+
class JsonCaster implements CastsAttributes
8+
{
9+
public function __construct(
10+
protected string $target
11+
) {
12+
}
13+
14+
public function get($model, $key, $value, $attributes)
15+
{
16+
if ($value === null || $value === '') {
17+
return $value;
18+
}
19+
20+
return $this->target::fromJsonString($value);
21+
}
22+
23+
public function set($model, $key, $value, $attributes)
24+
{
25+
return $value?->toJson();
26+
}
27+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Square\Pjson\Tests\Definitions\Integrations\Laravel;
4+
5+
use Square\Pjson\Json;
6+
use Square\Pjson\JsonSerialize;
7+
8+
class Address
9+
{
10+
use JsonSerialize;
11+
12+
#[Json]
13+
protected string $line1;
14+
#[Json]
15+
protected string $line2;
16+
#[Json]
17+
protected string $city;
18+
#[Json]
19+
protected string $zipcode;
20+
#[Json]
21+
protected string $country;
22+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Square\Pjson\Tests\Definitions\Integrations\Laravel;
4+
5+
use Illuminate\Contracts\Database\Eloquent\Castable;
6+
use Square\Pjson\Integrations\Laravel\JsonCastable;
7+
8+
class CastableAddress extends Address implements Castable
9+
{
10+
use JsonCastable;
11+
}

0 commit comments

Comments
 (0)