Lines
100.00%
8 / 8
Functions and Methods
100.00%
4 / 4
Classes and Traits
100.00%
1 / 1
| Name | Lines | Functions and Methods | CRAP | Classes and Traits | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Morphs | 100.00% | 8 / 8 | 100.00% | 4 / 4 | 5 | 100.00% | 1 / 1 | |||
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| typeColumn | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| keyColumn | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | |||||
| assertKeyTypeCapable | 100.00% | 5 / 5 | 100.00% | 1 / 1 | 2 | |||||
| 1 | <?php | |
| 2 | ||
| 3 | declare(strict_types=1); | |
| 4 | ||
| 5 | namespace BlueprintAU\Radiant\Attributes; | |
| 6 | ||
| 7 | use BlueprintAU\Radiant\Database\Schema\Enums\ColumnType; | |
| 8 | ||
| 9 | /** | |
| 10 | * Declares a polymorphic (morph) column pair on the model's table. | |
| 11 | * | |
| 12 | * Emits two synthetic columns — `{name}_type` (the related model's | |
| 13 | * class-string) and `{name}_id` (its primary-key value) — read and | |
| 14 | * written through {@see \BlueprintAU\Radiant\Model::attribute()} / | |
| 15 | * {@see \BlueprintAU\Radiant\Model::setAttribute()}. The key column's | |
| 16 | * type defaults to bigint; declare `keyType:` when the morph targets use | |
| 17 | * a different primary-key type. The alias convention is the related | |
| 18 | * model's full class-string; renaming a class changes the stored alias — | |
| 19 | * a data-migration concern documented in docs/relations.md. | |
| 20 | */ | |
| 21 | #[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)] | |
| 22 | final class Morphs | |
| 23 | { | |
| 24 | /** | |
| 25 | * Create a morph-pair declaration. | |
| 26 | * | |
| 27 | * @param string $name | |
| 28 | * @param bool $nullable | |
| 29 | * @param ColumnType $keyType The `{name}_id` column's type; every morph target's primary key must match it. | |
| 30 | */ | |
| 31 | public function __construct( | |
| 32 | public string $name, | |
| 33 | public bool $nullable = false, | |
| 34 | public ColumnType $keyType = ColumnType::BigInt, | |
| 35 | ) { | |
| 36 | } | |
| 37 | ||
| 38 | /** | |
| 39 | * The type-discriminator column name this declaration emits. | |
| 40 | * | |
| 41 | * @return string | |
| 42 | */ | |
| 43 | public function typeColumn(): string | |
| 44 | { | |
| 45 | return $this->name . '_type'; | |
| 46 | } | |
| 47 | ||
| 48 | /** | |
| 49 | * The key column name this declaration emits. | |
| 50 | * | |
| 51 | * @return string | |
| 52 | */ | |
| 53 | public function keyColumn(): string | |
| 54 | { | |
| 55 | return $this->name . '_id'; | |
| 56 | } | |
| 57 | ||
| 58 | /** | |
| 59 | * Assert the declared key type can hold a primary-key value. | |
| 60 | * | |
| 61 | * @return void | |
| 62 | * @throws \InvalidArgumentException | |
| 63 | */ | |
| 64 | public function assertKeyTypeCapable(): void | |
| 65 | { | |
| 66 | if (!$this->keyType->primaryKeyCapable()) { | |
| 67 | throw new \InvalidArgumentException( | |
| 68 | "#[Morphs(name: '{$this->name}')] declares keyType [{$this->keyType->value}], " | |
| 69 | . 'which cannot hold a primary-key value; use an integer, string, char, or uuid type.' | |
| 70 | ); | |
| 71 | } | |
| 72 | } | |
| 73 | } |