Skip to content

Commit e684359

Browse files
authored
Merge pull request #88 from Luke-Shepp/feature/87-static-macros
#87 - Allow static macros
2 parents dc6dd20 + b43e60f commit e684359

File tree

5 files changed

+98
-2
lines changed

5 files changed

+98
-2
lines changed

README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,76 @@ or
101101
<x-currency currency="USD" />
102102
```
103103

104+
### Macros
105+
106+
This package implements the Laravel `Macroable` trait, allowing macros and mixins on both `Money` and `Currency`.
107+
108+
Example use case:
109+
110+
```php
111+
use Akaunting\Money\Currency;
112+
use Akaunting\Money\Money;
113+
114+
Money::macro(
115+
'absolute',
116+
fn () => $this->isPositive() ? $this : $this->multiply(-1)
117+
);
118+
119+
$money = Money::USD(1000)->multiply(-1);
120+
121+
$absolute = $money->absolute();
122+
```
123+
124+
Macros can be called statically too:
125+
126+
```php
127+
use Akaunting\Money\Currency;
128+
use Akaunting\Money\Money;
129+
130+
Money::macro('zero', fn (?string $currency = null) => new Money(0, new Currency($currency ?? 'GBP')));
131+
132+
$money = Money::zero();
133+
```
134+
135+
### Mixins
136+
137+
Along with Macros, Mixins are also supported. This allows merging another classes methods into the Money or Currency class.
138+
139+
Define the mixin class:
140+
141+
```php
142+
use Akaunting\Money\Money;
143+
144+
class CustomMoney
145+
{
146+
public function absolute(): Money
147+
{
148+
return $this->isPositive() ? $this : $this->multiply(-1);
149+
}
150+
151+
public static function zero(?string $currency = null): Money
152+
{
153+
return new Money(0, new Currency($currency ?? 'GBP'));
154+
}
155+
}
156+
```
157+
158+
Register the mixin, by passing an instance of the class:
159+
160+
```php
161+
Money::mixin(new CustomMoney);
162+
```
163+
164+
The methods from the custom class will be available:
165+
166+
```php
167+
$money = Money::USD(1000)->multiply(-1);
168+
$absolute = $money->absolute();
169+
170+
// Static methods via mixins are supported too:
171+
$money = Money::zero();
172+
```
173+
104174
## Changelog
105175

106176
Please see [Releases](../../releases) for more information on what has changed recently.

src/Currency.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,9 @@
182182
*/
183183
class Currency implements Arrayable, Castable, Jsonable, JsonSerializable, Renderable
184184
{
185-
use Macroable;
185+
use Macroable {
186+
__callStatic as protected macroableCallStatic;
187+
}
186188

187189
protected string $currency;
188190

@@ -235,6 +237,10 @@ public function __construct(string $currency)
235237

236238
public static function __callStatic(string $method, array $arguments): Currency
237239
{
240+
if (static::hasMacro($method)) {
241+
return static::macroableCallStatic($method, $arguments);
242+
}
243+
238244
return new self($method);
239245
}
240246

src/Money.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@
186186
*/
187187
class Money implements Arrayable, Castable, Jsonable, JsonSerializable, Renderable
188188
{
189-
use Macroable;
189+
use Macroable {
190+
__callStatic as protected macroableCallStatic;
191+
}
190192

191193
const ROUND_HALF_UP = PHP_ROUND_HALF_UP;
192194

@@ -283,6 +285,10 @@ protected function convertAmount(int|float $amount, bool $convert = false): int|
283285

284286
public static function __callStatic(string $method, array $arguments): Money
285287
{
288+
if (static::hasMacro($method)) {
289+
return static::macroableCallStatic($method, $arguments);
290+
}
291+
286292
$convert = isset($arguments[1]) && is_bool($arguments[1]) && $arguments[1];
287293

288294
return new self($arguments[0], new Currency($method), $convert);

tests/CurrencyTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,11 @@ public function testResetCurrencies()
8888
$this->assertEmpty(Currency::getCurrencies());
8989
Currency::setCurrencies($currencies);
9090
}
91+
92+
public function testStaticMacro()
93+
{
94+
Currency::macro('testMacro', fn () => Currency::EUR());
95+
96+
$this->assertEquals(Currency::EUR(), Currency::testMacro());
97+
}
9198
}

tests/MoneyTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,4 +411,11 @@ public function testMakingMutable()
411411
$this->assertTrue($money->isImmutable());
412412
$this->assertFalse($money->mutable()->isImmutable());
413413
}
414+
415+
public function testStaticMacro()
416+
{
417+
Money::macro('testMacro', fn () => Money::USD(1099));
418+
419+
$this->assertEquals(Money::USD(1099), Money::testMacro());
420+
}
414421
}

0 commit comments

Comments
 (0)