<?php
declare(strict_types=1);
namespace App\Twig;
use App\Entity\Blo\Product;
use App\Service\Blo\CurrencyConverter;
use Symfony\Component\HttpFoundation\RequestStack;
use Twig\Extension\AbstractExtension;
use Twig\Extension\GlobalsInterface;
use Twig\TwigFilter;
use Twig\TwigFunction;
class BloCurrencyExtension extends AbstractExtension implements GlobalsInterface
{
public function __construct(
private readonly RequestStack $requestStack,
private readonly CurrencyConverter $converter,
) {
}
public function getFilters(): array
{
return [
new TwigFilter('blo_price', [$this, 'formatPrice']),
];
}
public function getFunctions(): array
{
return [
new TwigFunction('blo_currency_label', [$this, 'getCurrencyLabel']),
];
}
/**
* Convertit un montant depuis sa devise d'origine vers la devise sélectionnée
* par l'utilisateur, puis le formate avec le libellé d'affichage (ex. F CFA).
*
* Usage Twig : {{ product.price|blo_price(product.currency) }}
* {{ order.totalGrand|blo_price }} (suppose XOF par défaut)
*/
public function formatPrice(float|string|null $amount, string $fromCurrency = 'XOF'): string
{
if ($amount === null || $amount === '') {
return '';
}
$targetCurrency = $this->getCurrentCurrency();
$converted = $this->converter->convert($amount, $fromCurrency, $targetCurrency);
$decimals = $this->converter->getDecimals($targetCurrency);
return number_format($converted, $decimals, ',', ' ') . ' ' . $this->getCurrencyLabel($targetCurrency);
}
public function getCurrencyLabel(string $code): string
{
return Product::CURRENCY_DISPLAY[$code] ?? $code;
}
public function getGlobals(): array
{
return [
'blo_current_currency' => $this->getCurrentCurrency(),
'blo_currencies' => Product::CURRENCIES,
'blo_currency_display' => Product::CURRENCY_DISPLAY,
];
}
private function getCurrentCurrency(): string
{
$request = $this->requestStack->getCurrentRequest();
if ($request === null || !$request->hasSession()) {
return 'XOF';
}
$currency = $request->getSession()->get('_currency', 'XOF');
if (!is_string($currency) || !array_key_exists($currency, Product::CURRENCIES)) {
return 'XOF';
}
return $currency;
}
}