elcodi/currency-bundle
Currency Bundle is a Symfony package from the Elcodi e-commerce suite for managing currencies in your application. It provides currency entities, services, and framework integration under the MIT license as part of the read-only Elcodi project.
elcodi/elcodi monorepo, last tagged in Feb 2016. Pull it with composer require elcodi/currency-bundle and expect to fight the symfony/* and php constraints in its composer.json — it targets Symfony 2.x-era stacks. If you need a patch, fork elcodi/elcodi, not this repo (PRs here are ignored by design).AppKernel: new Elcodi\Bundle\CurrencyBundle\ElcodiCurrencyBundle(). Confirm it boots before you write any code — most failures at this stage are Doctrine mapping or container-compile issues, not currency logic.src/Elcodi/Component/Currency/:
Entity/Currency — at minimum iso, symbol, name (plus id)Factory/CurrencyFactoryDirector/CurrencyDirector — creates/normalizes new instancesRepository/CurrencyRepository — includes ISO lookupsServices/CurrencyManager — the entry point you should useCurrencyAwareInterface / CurrencyAwareTrait — how other Elcodi entities (prices, orders) attach a currencyelcodi.currency_manager, elcodi.currency_director); verify with bin/console debug:container currency --show-private since the docs for this version are sparse.$manager = $this->get('elcodi.currency_manager');
// create
$eur = $manager->create();
$eur->setIso('EUR')->setSymbol('€')->setName('Euro');
$manager->save($eur);
// look up
$currency = $manager->getRepository()->findOneByIso('EUR');
{{ price.amount|number_format(2, '.', ',') }} {{ price.currency.symbol }}
Resolve through the manager, never through Doctrine directly. The bundle sits on top of Elcodi's ObjectManager/repository-provider indirection. Injecting elcodi.currency_manager (or the repository provider for the currency namespace) keeps you compatible with Elcodi's overrides and test doubles. Reach for EntityManager::getRepository() only in throwaway scripts.
Seed via data fixtures, not controllers. Elcodi bundles conventionally ship DataFixtures/ORM/*Data classes that load a starter set of ISO codes. Load them in dev once, then treat the table as reference data. Avoid ad-hoc $manager->create() calls in request handlers — concurrent first-requests will race and create duplicate ISOs unless you add your own unique constraint (see Gotchas).
Override the entity class through config, not by subclassing in place. Set elcodi_currency.entity.currency to your own class in config.yml. The bundle's Doctrine mapping and factory are wired to the configured class parameter, so overriding only the PHP class leaves the manager pointing at the original entity. Apply the same pattern to the factory/director if you add fields.
Make your own entities CurrencyAware. Implement CurrencyAwareInterface and use CurrencyAwareTrait on orders, products, price rows. This is the idiom the rest of Elcodi (money-bundle, cart, order bundles) expects, so you get consistency when you add those later.
Snapshot the ISO on the order, relate the currency elsewhere. Store currency_iso as a string on anything financially historical, and a relation only on live/editable objects. Currency rows get edited (symbols, names) and occasionally deleted; an order that resolves its currency through a join will silently restate history when that happens.
Multi-currency pricing: rows, not render-time conversion. If you support more than one currency, keep a price per (product, currency) and use the converter/exchange-rate services from the Currency component only for display estimates. Never let the accounting amount depend on a live rate lookup.
Wrap the default currency once. Rather than calling the manager per request, resolve the default at container build or cache it in your own provider service and inject that. It removes a query from every page and gives you one place to change when the shop switches base currency.
Formatting is yours. Build a small Twig extension around PHP's NumberFormatter (intl) and pass the Currency object in. That's an afternoon of work and buys you locale-aware output the bundle never provided.
Currency entity and factory from the monorepo and skip the bundle; the domain model is ~3 fields and a few lookups. Use the real bundle only if you're already deep in Elcodi.elcodi/elcodi; the split repos are mirrors and stale by design.setIso('EURO') will happily persist. Add a length/format assertion on the entity override and a unique index on iso in your own migration, or you will eventually have three "USD" rows.#[AsAlias] attributes and no typed service config. You'll write services.yml aliases and inject by ID. Don't try to autowire CurrencyRepository — inject the manager or repository provider instead.symbol is ambiguous. $ is USD, CAD, AUD, and more. If you ever display more than one currency, show the ISO alongside the symbol.findOneByIso. Run them once, then manage currencies through your own admin.doctrine:mapping:info (is Currency actually mapped?), debug:container currency (what's the real manager ID?), then a doctrine:schema:validate run. Nine times out of ten the "currency not found" bug is a mapping or class-parameter problem, not a logic problem.elcodi.currency_manager survives a composer update; a patch inside vendor/ does not. If you must patch, commit the fork URL in composer.json now, because there will be no upstream fix later.How can I help you explore Laravel packages today?