Skip to content

Commit 9bd6307

Browse files
committed
fixe block data
1 parent 720da9c commit 9bd6307

File tree

8 files changed

+88
-23
lines changed

8 files changed

+88
-23
lines changed

src/Abstracts/BlockData.php

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,26 @@
22

33
namespace Yuges\Contentable\Abstracts;
44

5-
use Spatie\LaravelData\Data;
6-
use Illuminate\Validation\Rule;
75
use Yuges\Contentable\Config\Config;
86
use Yuges\Contentable\Enums\BlockType;
97
use Yuges\Contentable\Factories\BlockDataFactory;
10-
use Spatie\LaravelData\Attributes\PropertyForMorph;
8+
use Yuges\Contentable\Exceptions\InvalidBlockType;
119
use Yuges\Contentable\Interfaces\BlockDataInterface;
12-
use Spatie\LaravelData\Contracts\PropertyMorphableData;
13-
use Spatie\LaravelData\Attributes\MergeValidationRules;
1410
use Yuges\Contentable\Interfaces\BlockType as BlockTypeInterface;
1511

16-
#[MergeValidationRules]
17-
abstract class BlockData extends Data implements BlockDataInterface, PropertyMorphableData
12+
abstract class BlockData implements BlockDataInterface
1813
{
19-
protected const DURATION = 0.0;
14+
protected const float DURATION = 0.0;
15+
protected const ?BlockTypeInterface TYPE = null;
2016

21-
#[PropertyForMorph]
2217
public string $type;
2318

24-
public static function morph(array $properties): ?string
25-
{
26-
$type = Config::getBlockTypeClass(BlockType::class)::tryFrom($properties['type']);
19+
public function __construct() {
20+
if (! static::TYPE) {
21+
throw InvalidBlockType::notDefined(static::class);
22+
}
2723

28-
return $type ? BlockDataFactory::getClass($type) : null;
24+
$this->type = static::TYPE->value;
2925
}
3026

3127
public function getType(): BlockTypeInterface
@@ -62,13 +58,6 @@ public static function fromJsonData(BlockTypeInterface $type, string $data): ?Bl
6258
return self::fromArrayData($type, $data);
6359
}
6460

65-
public static function rules(): array
66-
{
67-
return [
68-
'type' => [Rule::enum(Config::getBlockTypeClass(BlockType::class))],
69-
];
70-
}
71-
7261
public function duration(): float
7362
{
7463
return static::DURATION;

src/Data/Blocks/ParagraphData.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44

55
use Yuges\Contentable\Config\Config;
66
use Yuges\Contentable\Enums\BlockType;
7+
use Yuges\Contentable\Interfaces\BlockType as BlockTypeInterface;
78

89
class ParagraphData extends \Yuges\Contentable\Abstracts\BlockData
910
{
10-
public string $type = BlockType::Paragraph->value;
11+
protected const BlockTypeInterface TYPE = BlockType::Paragraph;
1112

1213
public function __construct(
1314
public ?string $text = '',
1415
) {
16+
parent::__construct();
1517
}
1618

1719
public function getData(): array
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Yuges\Contentable\Exceptions;
4+
5+
use Exception;
6+
use TypeError;
7+
use Yuges\Contentable\Interfaces\BlockType;
8+
9+
class InvalidBlockType extends Exception
10+
{
11+
public static function notDefined(string $class): TypeError
12+
{
13+
return new TypeError("Block type is not defined in the `{$class}` class");
14+
}
15+
16+
public static function doesNotImplementBlockType(string $class): TypeError
17+
{
18+
$BlockType = BlockType::class;
19+
20+
return new TypeError("Block type enum `{$class}` must implement `{$BlockType}`");
21+
}
22+
}

src/Factories/BlockDataFactory.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Yuges\Contentable\Factories;
44

5+
use BackedEnum;
6+
use ReflectionClass;
57
use Yuges\Contentable\Config\Config;
68
use Yuges\Contentable\Interfaces\BlockType;
79
use Yuges\Contentable\Exceptions\InvalidBlockData;
@@ -19,7 +21,23 @@ public static function create(BlockType $type, array $data): ?BlockDataInterface
1921

2022
static::validateBlockData($class);
2123

22-
return $class::from($data);
24+
$parameters = new ReflectionClass($class)->getConstructor()->getParameters();
25+
26+
foreach ($data as $key => $value) {
27+
$parameter = array_find($parameters, fn ($parameter) => $parameter->getName() === $key);
28+
29+
if (! $parameter) {
30+
unset($data[$key]);
31+
}
32+
33+
$type = $parameter->getType();
34+
35+
if (is_subclass_of($type->getName(), BackedEnum::class)) {
36+
$data[$key] = $type->getName()::from($value);
37+
}
38+
}
39+
40+
return new $class(...$data);
2341
}
2442

2543
/** @return ?class-string<BlockDataInterface> */

src/Interfaces/BlockDataInterface.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ public function getData(): array;
1313

1414
public function toArrayData(): array;
1515

16+
public static function fromArrayData(BlockType $type, array $data): ?BlockDataInterface;
17+
1618
public function toJsonData(): string;
1719

18-
public static function from(mixed ...$payloads): static;
20+
public static function fromJsonData(BlockType $type, string $data): ?BlockDataInterface;
1921

2022
public function duration(): float;
2123
}

tests/Integration/ContentTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,14 @@
1212
use Yuges\Contentable\Data\Blocks\ListData;
1313
use Yuges\Contentable\Data\Blocks\HeaderData;
1414
use Yuges\Contentable\Tests\Stubs\Models\Post;
15+
use Yuges\Contentable\Tests\Stubs\Blocks\ParagraphData;
1516

1617
class ContentTest extends TestCase
1718
{
1819
public function testContentPost()
1920
{
21+
new ParagraphData('test');
22+
2023
$post = Post::query()->create([
2124
'title' => 'New post',
2225
]);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Yuges\Contentable\Tests\Stubs\Blocks;
4+
5+
use Yuges\Contentable\Tests\Stubs\Enums\BlockType;
6+
7+
class ParagraphData extends \Yuges\Contentable\Data\Blocks\ParagraphData
8+
{
9+
protected const BlockType TYPE = BlockType::Delimiter;
10+
11+
public function __construct(
12+
public ?string $text = '',
13+
) {
14+
parent::__construct($text);
15+
}
16+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace Yuges\Contentable\Tests\Stubs\Enums;
4+
5+
enum BlockType: string implements \Yuges\Contentable\Interfaces\BlockType
6+
{
7+
case List = 'list';
8+
case Quote = 'quote';
9+
case Header = 'header';
10+
case Paragraph = 'paragraph';
11+
case Delimiter = 'delimiter';
12+
case Test = 'Test';
13+
}

0 commit comments

Comments
 (0)