diff --git a/src/Reactant/Models/Reactant.php b/src/Reactant/Models/Reactant.php index 6948a795..a033d4aa 100644 --- a/src/Reactant/Models/Reactant.php +++ b/src/Reactant/Models/Reactant.php @@ -43,12 +43,7 @@ final class Reactant extends Model implements protected $table = 'love_reactants'; - /** - * @var string[] - */ - protected $fillable = [ - 'type', - ]; + protected static $unguarded = true; /** * @var string[] diff --git a/src/Reactant/ReactionCounter/Models/ReactionCounter.php b/src/Reactant/ReactionCounter/Models/ReactionCounter.php index 5b570bfc..ba739d70 100644 --- a/src/Reactant/ReactionCounter/Models/ReactionCounter.php +++ b/src/Reactant/ReactionCounter/Models/ReactionCounter.php @@ -19,6 +19,7 @@ use Cog\Laravel\Love\Reactant\Models\Reactant; use Cog\Laravel\Love\ReactionType\Models\ReactionType; use Cog\Laravel\Love\Support\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -33,30 +34,31 @@ final class ReactionCounter extends Model implements protected $table = 'love_reactant_reaction_counters'; + protected static $unguarded = true; + /** - * @var array + * @var array */ protected $attributes = [ 'count' => self::COUNT_DEFAULT, 'weight' => self::WEIGHT_DEFAULT, ]; - /** - * @var string[] - */ - protected $fillable = [ - 'reaction_type_id', - 'count', - 'weight', - ]; + public function count(): Attribute + { + return new Attribute( + get: fn (int | null $value) => $value ?? self::COUNT_DEFAULT, + set: fn (int | null $value) => $value ?? self::COUNT_DEFAULT, + ); + } - /** - * @var string[] - */ - protected $casts = [ - 'count' => 'integer', - 'weight' => 'float', - ]; + public function weight(): Attribute + { + return new Attribute( + get: fn (float | null $value) => $value ?? self::WEIGHT_DEFAULT, + set: fn (float | null $value) => $value ?? self::WEIGHT_DEFAULT, + ); + } public function reactant(): BelongsTo { @@ -123,16 +125,4 @@ public function decrementWeight( ): void { $this->decrement('weight', $amount); } - - public function setCountAttribute( - int | null $count, - ): void { - $this->attributes['count'] = $count ?? self::COUNT_DEFAULT; - } - - public function setWeightAttribute( - float | null $weight, - ): void { - $this->attributes['weight'] = $weight ?? self::WEIGHT_DEFAULT; - } } diff --git a/src/Reactant/ReactionTotal/Models/ReactionTotal.php b/src/Reactant/ReactionTotal/Models/ReactionTotal.php index 30d82109..70c01380 100644 --- a/src/Reactant/ReactionTotal/Models/ReactionTotal.php +++ b/src/Reactant/ReactionTotal/Models/ReactionTotal.php @@ -17,6 +17,7 @@ use Cog\Contracts\Love\Reactant\ReactionTotal\Models\ReactionTotal as ReactionTotalInterface; use Cog\Laravel\Love\Reactant\Models\Reactant; use Cog\Laravel\Love\Support\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -31,29 +32,31 @@ final class ReactionTotal extends Model implements protected $table = 'love_reactant_reaction_totals'; + protected static $unguarded = true; + /** - * @var array + * @var array */ protected $attributes = [ 'count' => self::COUNT_DEFAULT, 'weight' => self::WEIGHT_DEFAULT, ]; - /** - * @var string[] - */ - protected $fillable = [ - 'count', - 'weight', - ]; + public function count(): Attribute + { + return new Attribute( + get: fn (int | null $value) => $value ?? self::COUNT_DEFAULT, + set: fn (int | null $value) => $value ?? self::COUNT_DEFAULT, + ); + } - /** - * @var string[] - */ - protected $casts = [ - 'count' => 'integer', - 'weight' => 'float', - ]; + public function weight(): Attribute + { + return new Attribute( + get: fn (float | null $value) => $value ?? self::WEIGHT_DEFAULT, + set: fn (float | null $value) => $value ?? self::WEIGHT_DEFAULT, + ); + } public function reactant(): BelongsTo { @@ -98,16 +101,4 @@ public function decrementWeight( ): void { $this->decrement('weight', $amount); } - - public function setCountAttribute( - int | null $count, - ): void { - $this->attributes['count'] = $count ?? self::COUNT_DEFAULT; - } - - public function setWeightAttribute( - float | null $weight, - ): void { - $this->attributes['weight'] = $weight ?? self::WEIGHT_DEFAULT; - } } diff --git a/src/Reactant/ReactionTotal/Observers/ReactionTotalObserver.php b/src/Reactant/ReactionTotal/Observers/ReactionTotalObserver.php new file mode 100644 index 00000000..e35ceb76 --- /dev/null +++ b/src/Reactant/ReactionTotal/Observers/ReactionTotalObserver.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace Cog\Laravel\Love\Reactant\ReactionTotal\Observers; + +use Cog\Laravel\Love\Reactant\ReactionTotal\Models\ReactionTotal; + +final class ReactionTotalObserver +{ + public function creating( + ReactionTotal $total, + ): void { + if ($total->getAttributeValue('count') === null) { + $total->setAttribute('count', ReactionTotal::COUNT_DEFAULT); + } + + if ($total->getAttributeValue('weight') === null) { + $total->setAttribute('weight', ReactionTotal::WEIGHT_DEFAULT); + } + } +} diff --git a/src/Reacter/Models/Reacter.php b/src/Reacter/Models/Reacter.php index f7e79de5..d5c59f23 100644 --- a/src/Reacter/Models/Reacter.php +++ b/src/Reacter/Models/Reacter.php @@ -35,12 +35,7 @@ final class Reacter extends Model implements protected $table = 'love_reacters'; - /** - * @var string[] - */ - protected $fillable = [ - 'type', - ]; + protected static $unguarded = true; /** * @var string[] diff --git a/src/Reaction/Models/Reaction.php b/src/Reaction/Models/Reaction.php index 091a6c23..c2751356 100644 --- a/src/Reaction/Models/Reaction.php +++ b/src/Reaction/Models/Reaction.php @@ -23,6 +23,7 @@ use Cog\Laravel\Love\Reacter\Models\Reacter; use Cog\Laravel\Love\ReactionType\Models\ReactionType; use Cog\Laravel\Love\Support\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -37,29 +38,40 @@ final class Reaction extends Model implements protected $table = 'love_reactions'; + protected static $unguarded = true; + /** - * @var float[] + * @var array */ protected $attributes = [ 'rate' => self::RATE_DEFAULT, ]; - /** - * @var string[] - */ - protected $fillable = [ - 'reactant_id', - 'reaction_type_id', - 'rate', - ]; + public function id(): Attribute + { + return new Attribute( + get: fn (string | null $value) => $value, + set: fn (string | null $value) => $value, + ); + } - /** - * @var string[] - */ - protected $casts = [ - 'id' => 'string', - 'rate' => 'float', - ]; + public function rate(): Attribute + { + return new Attribute( + get: fn (float | null $value) => $value ?? self::RATE_DEFAULT, + set: function (float | null $value) { + if ($value !== null && ($value < self::RATE_MIN || $value > self::RATE_MAX)) { + throw RateOutOfRange::withValueBetween( + $value, + self::RATE_MIN, + self::RATE_MAX, + ); + } + + return $value ?? self::RATE_DEFAULT; + }, + ); + } public function reactant(): BelongsTo { @@ -106,16 +118,6 @@ public function getWeight(): float return $this->getType()->getMass() * $this->getRate(); } - public function setRateAttribute( - float | null $rate, - ): void { - if ($rate !== null && ($rate < self::RATE_MIN || $rate > self::RATE_MAX)) { - throw RateOutOfRange::withValueBetween($rate, self::RATE_MIN, self::RATE_MAX); - } - - $this->attributes['rate'] = $rate ?? self::RATE_DEFAULT; - } - public function isOfType( ReactionTypeInterface $reactionType, ): bool { diff --git a/src/ReactionType/Models/ReactionType.php b/src/ReactionType/Models/ReactionType.php index a860d9fe..f107d113 100644 --- a/src/ReactionType/Models/ReactionType.php +++ b/src/ReactionType/Models/ReactionType.php @@ -29,6 +29,8 @@ final class ReactionType extends Model implements protected $table = 'love_reaction_types'; + protected static $unguarded = true; + /** * @var int[] */ @@ -36,14 +38,6 @@ final class ReactionType extends Model implements 'mass' => self::MASS_DEFAULT, ]; - /** - * @var string[] - */ - protected $fillable = [ - 'name', - 'mass', - ]; - /** * @var string[] */ diff --git a/tests/Unit/Reaction/Models/ReactionTest.php b/tests/Unit/Reaction/Models/ReactionTest.php index 89e9fc49..6a4c7ba6 100644 --- a/tests/Unit/Reaction/Models/ReactionTest.php +++ b/tests/Unit/Reaction/Models/ReactionTest.php @@ -82,7 +82,7 @@ public function it_throws_rate_out_of_range_on_fill_rate_with_overflow_value(): /** @test */ public function it_casts_id_to_string(): void { - $reaction = Reaction::factory()->make([ + $reaction = new Reaction([ 'id' => 4, ]);