Skip to content

Commit 64ee984

Browse files
committed
Implement casting to Decimal in DecimalObjectCast trait
1 parent fbc4137 commit 64ee984

File tree

1 file changed

+55
-12
lines changed

1 file changed

+55
-12
lines changed

Diff for: src/DecimalObjectCast.php

+55-12
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,69 @@
88
* "decimal" cast uses `number_format`, but we can utilize the `toFixed` method
99
* provided by Decimal\Decimal to prepare the value.
1010
*
11-
* This trait does not provide a cast from string to Decimal; this should be
12-
* done manually using an accessor like `getPriceAttribute`, which should return
13-
* a new Decimal\Decimal using the precision of the column in the database.
11+
* This trait extends the default behavior by allowing the precision and scale
12+
* of the decimal value to be specified via the attribute's casting definition.
13+
* For example, `decimal:2:8` would cast the attribute to a Decimal with 2 digits
14+
* of scale and 8 digits of precision.
1415
*/
1516
trait DecimalObjectCast
1617
{
1718
/**
18-
* Return a decimal as string to be written to the database.
19+
* Cast an attribute to a native PHP type.
1920
*
20-
* @see \Illuminate\Database\Eloquent\Concerns\HasAttributes::asDecimal
21+
* @see \Illuminate\Database\Eloquent\Concerns\HasAttributes::castAttribute
2122
*
22-
* @param Decimal $value
23-
* @param int $decimals
23+
* @param string $key
24+
* @param mixed $value Raw value
2425
*
25-
* @return \Decimal\Decimal
26+
* @return mixed Transformed value
2627
*/
27-
protected function asDecimal($value, $decimals)
28+
protected function castAttribute($key, $value)
2829
{
29-
assert($value instanceof Decimal);
30-
31-
return $value->toFixed($decimals, $commas = false, PHP_ROUND_HALF_UP);
30+
if ($value !== null) {
31+
$casts = $this->getCasts();
32+
if (array_key_exists($key, $casts)) {
33+
$castType = $casts[$key];
34+
if ($this->isDecimalCast($castType)) {
35+
$precision = explode(':', $castType)[2] ?? Decimal::DEFAULT_PRECISION;
36+
37+
return new Decimal($value, $precision);
38+
}
39+
}
40+
}
41+
42+
return parent::castAttribute($key, $value);
43+
}
44+
45+
/**
46+
* Set a given attribute on the model.
47+
*
48+
* @see \Illuminate\Database\Eloquent\Concerns\HasAttributes::setAttribute
49+
*
50+
* @param string $key
51+
* @param mixed $value Raw value
52+
*
53+
* @return mixed The model
54+
*/
55+
public function setAttribute($key, $value)
56+
{
57+
if ($value !== null) {
58+
$casts = $this->getCasts();
59+
if (array_key_exists($key, $casts)) {
60+
$castType = $casts[$key];
61+
if ($this->isDecimalCast($castType)) {
62+
if (!$value instanceof Decimal) {
63+
$value = $this->castAttribute($key, $value);
64+
}
65+
66+
$decimals = explode(':', $castType)[1];
67+
$this->attributes[$key] = $value->toFixed($decimals, false, PHP_ROUND_HALF_UP);
68+
69+
return $this;
70+
}
71+
}
72+
}
73+
74+
return parent::setAttribute($key, $value);
3275
}
3376
}

0 commit comments

Comments
 (0)