Last active
February 1, 2021 09:42
-
-
Save parijke/ad4c197559c2af8d0a61a8d141173924 to your computer and use it in GitHub Desktop.
MoneyPHP in Symfony
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping | |
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> | |
<embeddable name="Money\Currency"> | |
<field name="code" type="string" length="3"> | |
<options> | |
<option name="fixed">true</option> | |
</options> | |
</field> | |
</embeddable> | |
</doctrine-mapping> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping | |
http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> | |
<embeddable name="Money\Money"> | |
<field name="amount" type="string"/> | |
<embedded name="currency" class="Money\Currency"/> | |
</embeddable> | |
</doctrine-mapping> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Twig; | |
use Money\MoneyFormatter; | |
use Twig\Extension\AbstractExtension; | |
use Twig\TwigFilter; | |
class MoneyExtension extends AbstractExtension | |
{ | |
private MoneyFormatter $intlMoneyFormatter; | |
public function __construct(MoneyFormatter $intlMoneyFormatter) | |
{ | |
$this->intlMoneyFormatter = $intlMoneyFormatter; | |
} | |
public function getFilters(): array | |
{ | |
return [ | |
new TwigFilter('money', [$this->intlMoneyFormatter, 'format']), | |
]; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Form\DataTransformer; | |
use Money\Currencies; | |
use Money\Currency; | |
use Money\Money; | |
use Money\MoneyFormatter; | |
use Money\Number; | |
use Symfony\Component\Form\DataTransformerInterface; | |
use Symfony\Component\Form\Exception\TransformationFailedException; | |
class MoneyTransformer implements DataTransformerInterface | |
{ | |
private Currency $currency; | |
private MoneyFormatter $moneyFormatter; | |
private int $subunit; | |
public function __construct(string $defaultCurrency, MoneyFormatter $moneyFormatter, Currencies $currencies) | |
{ | |
$currency = new Currency($defaultCurrency); | |
$this->subunit = $currencies->subunitFor($currency); | |
$this->currency = $currency; | |
$this->moneyFormatter = $moneyFormatter; | |
} | |
public function transform($value): ?string | |
{ | |
if (!$value instanceof Money) { | |
return null; | |
} | |
return $this->moneyFormatter->format($value); | |
} | |
public function reverseTransform($value): Money | |
{ | |
if ($value instanceof Money) { | |
return $value; | |
} | |
if (empty($value) && !is_array($value)) { | |
return new Money(0, $this->currency); | |
} | |
if (!is_numeric($value)) { | |
throw new TransformationFailedException(sprintf('Money value has to be a numeric value, "%s" given', is_object($value) ? get_class($value) : gettype($value))); | |
} | |
$number = Number::fromNumber($value)->base10(-$this->subunit); | |
return new Money($number->getIntegerPart(), $this->currency); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App\Form\Type; | |
use App\Form\DataTransformer\MoneyTransformer; | |
use Symfony\Component\Form\AbstractType; | |
use Symfony\Component\Form\Extension\Core\Type\NumberType; | |
use Symfony\Component\Form\FormBuilderInterface; | |
class MoneyValueType extends AbstractType | |
{ | |
private MoneyTransformer $moneyTransformer; | |
public function __construct(MoneyTransformer $moneyTransformer) | |
{ | |
$this->moneyTransformer = $moneyTransformer; | |
} | |
public function buildForm(FormBuilderInterface $builder, array $options) | |
{ | |
$builder->addModelTransformer($this->moneyTransformer); | |
} | |
public function getParent(): string | |
{ | |
return NumberType::class; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
services: | |
Money\Currencies: | |
class: Money\Currencies\ISOCurrencies | |
Money\MoneyFormatter: | |
class: Money\Formatter\DecimalMoneyFormatter | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment