Skip to content

Commit 6622cb3

Browse files
authored
docs: rewrite README and Resources/doc/index.md, add top-level LICENSE (#63)
1 parent 072ef8a commit 6622cb3

4 files changed

Lines changed: 547 additions & 161 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2014 - 2026 Florian Voutzinos
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 196 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,210 @@
1-
# <img src="https://s3.amazonaws.com/swap.assets/swap_logo.png" height="30px" width="30px"/> Symfony Swap
1+
# Symfony Swap
22

33
[![Tests](https://github.com/florianv/symfony-swap/actions/workflows/tests.yml/badge.svg)](https://github.com/florianv/symfony-swap/actions/workflows/tests.yml)
44
[![Psalm](https://github.com/florianv/symfony-swap/actions/workflows/psalm.yml/badge.svg)](https://github.com/florianv/symfony-swap/actions/workflows/psalm.yml)
55
[![Total Downloads](https://img.shields.io/packagist/dt/florianv/swap-bundle.svg?style=flat-square)](https://packagist.org/packages/florianv/swap-bundle)
66
[![Version](http://img.shields.io/packagist/v/florianv/swap-bundle.svg?style=flat-square)](https://packagist.org/packages/florianv/swap-bundle)
77

8-
Swap allows you to retrieve currency exchange rates from various services such as **[Fixer](https://fixer.io/)**, **[Currency Data](https://currencylayer.com)**
9-
or **[Exchange Rates Data](https://exchangeratesapi.io)** and optionally cache the results.
8+
> _Drop-in Symfony bundle for currency conversion. Multi-provider exchange rates with fallback, caching, and Symfony Cache integration. Maintained since 2014._
109
11-
## QuickStart
10+
**Install the bundle, drop a `florianv_swap.yaml` in `config/packages/`, and the `florianv_swap.swap` service is ready to inject. No service container plumbing, no boilerplate.**
11+
12+
Symfony Swap is a drop-in package for **Symfony currency conversion**. Install it, configure providers in `config/packages/florianv_swap.yaml`, and pull **Symfony exchange rates** from multiple providers in one call. The bundle integrates with Symfony Cache out of the box and supports Symfony 6.4 / 7 / 8. Used in real-world Symfony applications since 2014.
13+
14+
## 💡 What is Symfony Swap?
15+
16+
- Symfony Swap is the Symfony integration of [Swap](https://github.com/florianv/swap), the PHP currency conversion library.
17+
- It registers a `florianv_swap.swap` service in the container (`Swap\Swap` class).
18+
- Configuration lives in `config/packages/florianv_swap.yaml`.
19+
- Caching uses Symfony Cache (`array`, `apcu`, `filesystem`, or any PSR-16 service ID).
20+
- Providers are tried in priority order (higher priority first).
21+
22+
## 🎯 When should you use Symfony Swap?
23+
24+
- Use Symfony Swap when you need exchange rates inside a Symfony application: localized prices, invoice totals, multi-currency reporting, historical FX data.
25+
- You do not need to install [Swap](https://github.com/florianv/swap) separately. It is pulled in as a dependency, and Symfony Swap exposes it through Symfony's container and cache.
26+
27+
## 🧠 Why Symfony Swap and not raw Swap?
28+
29+
Using [Swap](https://github.com/florianv/swap) directly inside a Symfony app means three pieces of plumbing on every project: registering the builder and the Swap service yourself, wiring Symfony Cache to the PSR-16 contract, and configuring providers in PHP rather than in the container. Doable, but boilerplate every project pays for.
30+
31+
Symfony Swap does this for you:
32+
33+
- **Drop-in.** Add the bundle to `config/bundles.php` and you are set.
34+
- **Symfony Cache integration.** Choose `array`, `apcu`, `filesystem`, or any PSR-16 service ID under `cache.type`.
35+
- **Container service.** `florianv_swap.swap` is ready to inject from any controller, service, or command.
36+
- **Configurable.** `config/packages/florianv_swap.yaml` exposes providers, options, and the cache.
37+
- **Priority-ordered providers.** Each provider has a `priority`; the bundle sorts them (higher priority tried first).
38+
39+
If you are not on Symfony, use [Swap](https://github.com/florianv/swap) directly.
40+
41+
## 📦 Installation
42+
43+
Symfony Swap requires PHP 8.2 or newer and Symfony 6.4, 7, or 8.
1244

1345
```bash
14-
$ composer require florianv/swap-bundle php-http/message php-http/guzzle6-adapter ^1.0
46+
composer require florianv/swap-bundle symfony/http-client nyholm/psr7
1547
```
1648

17-
## Documentation
18-
19-
The complete documentation can be found [here](https://github.com/florianv/symfony-swap/blob/master/Resources/doc/index.md).
20-
21-
## Services
22-
23-
Here is the list of the currently implemented services:
24-
25-
| Service | Base Currency | Quote Currency | Historical |
26-
|---------------------------------------------------------------------------|----------------------|----------------|----------------|
27-
| [Fixer](https://fixer.io/) | EUR (free, no SSL), * (paid) | * | Yes |
28-
| [Currency Data](https://currencylayer.com) | USD (free), * (paid) | * | Yes |
29-
| [Exchange Rates Data](https://exchangeratesapi.io) | USD (free), * (paid) | * | Yes |
30-
| [Abstract](https://www.abstractapi.com) | * | * | Yes |
31-
| [coinlayer](https://coinlayer.com) | * Crypto (Limited standard currencies) | * Crypto (Limited standard currencies) | Yes |
32-
| [Fixer](https://fixer.io) | EUR (free, no SSL), * (paid) | * | Yes |
33-
| [currencylayer](https://currencylayer.com) | USD (free), * (paid) | * | Yes |
34-
| [exchangeratesapi](https://exchangeratesapi.io) | USD (free), * (paid) | * | Yes |
35-
| [European Central Bank](https://www.ecb.europa.eu/home/html/index.en.html) | EUR | * | Yes |
36-
| [National Bank of Georgia](https://nbg.gov.ge) | * | GEL | Yes |
37-
| [National Bank of the Republic of Belarus](https://www.nbrb.by) | * | BYN (from 01-07-2016),<br>BYR (01-01-2000 - 30-06-2016),<br>BYB (25-05-1992 - 31-12-1999) | Yes |
38-
| [National Bank of Romania](http://www.bnr.ro) | RON, AED, AUD, BGN, BRL, CAD, CHF, CNY, CZK, DKK, EGP, EUR, GBP, HRK, HUF, INR, JPY, KRW, MDL, MXN, NOK, NZD, PLN, RSD, RUB, SEK, TRY, UAH, USD, XAU, XDR, ZAR | RON, AED, AUD, BGN, BRL, CAD, CHF, CNY, CZK, DKK, EGP, EUR, GBP, HRK, HUF, INR, JPY, KRW, MDL, MXN, NOK, NZD, PLN, RSD, RUB, SEK, TRY, UAH, USD, XAU, XDR, ZAR | Yes |
39-
| [National Bank of Ukranie](https://bank.gov.ua) | * | UAH | Yes |
40-
| [Central Bank of the Republic of Turkey](http://www.tcmb.gov.tr) | * | TRY | Yes |
41-
| [Central Bank of the Republic of Uzbekistan](https://cbu.uz) | * | UZS | Yes |
42-
| [Central Bank of the Czech Republic](https://www.cnb.cz) | * | CZK | Yes |
43-
| [Central Bank of Russia](https://cbr.ru) | * | RUB | Yes |
44-
| [Bulgarian National Bank](http://bnb.bg) | * | BGN | Yes |
45-
| [WebserviceX](http://www.webservicex.net) | * | * | No |
46-
| [1Forge](https://1forge.com) | * (free but limited or paid) | * (free but limited or paid) | No |
47-
| [Cryptonator](https://www.cryptonator.com) | * Crypto (Limited standard currencies) | * Crypto (Limited standard currencies) | No |
48-
| [CurrencyDataFeed](https://currencydatafeed.com) | * (free but limited or paid) | * (free but limited or paid) | No |
49-
| [Open Exchange Rates](https://openexchangerates.org) | USD (free), * (paid) | * | Yes |
50-
| [Xignite](https://www.xignite.com) | * | * | Yes |
51-
| [Currency Converter API](https://www.currencyconverterapi.com) | * | * | Yes (free but limited or paid) |
52-
| [xChangeApi.com](https://xchangeapi.com) | * | * | Yes |
53-
| [fastFOREX.io](https://www.fastforex.io) | USD (free), * (paid) | * | No |
54-
| [exchangerate.host](https://www.exchangerate.host) | * | * | Yes |
55-
| Array | * | * | Yes |
56-
57-
## Credits
49+
Register the bundle in `config/bundles.php` (Symfony Flex skips this step if a recipe applies):
5850

59-
- [Florian Voutzinos](https://github.com/florianv)
60-
- [All Contributors](https://github.com/florianv/symfony-swap/contributors)
51+
```php
52+
// config/bundles.php
53+
return [
54+
// ...
55+
Florianv\SwapBundle\FlorianvSwapBundle::class => ['all' => true],
56+
];
57+
```
58+
59+
Skip to [Quickstart](#-quickstart).
60+
61+
---
6162

62-
## License
63+
_Optional: any PSR-18 HTTP client paired with a PSR-17 factory works. If your app already uses Guzzle, swap `symfony/http-client` for `php-http/guzzle7-adapter`. See the [documentation](Resources/doc/index.md) for alternatives._
64+
65+
## ⚡ Quickstart
66+
67+
Configure at least one provider in `config/packages/florianv_swap.yaml`. The European Central Bank works without an API key:
68+
69+
```yaml
70+
# config/packages/florianv_swap.yaml
71+
florianv_swap:
72+
providers:
73+
european_central_bank:
74+
priority: 0
75+
```
76+
77+
Inject the service:
78+
79+
```php
80+
use Swap\Swap;
81+
use Symfony\Component\DependencyInjection\Attribute\Autowire;
82+
83+
final class CurrencyController
84+
{
85+
public function __construct(
86+
#[Autowire(service: 'florianv_swap.swap')]
87+
private readonly Swap $swap,
88+
) {}
89+
90+
public function rate(): array
91+
{
92+
// EUR → USD exchange rate
93+
$rate = $this->swap->latest('EUR/USD');
94+
95+
return [
96+
'value' => $rate->getValue(), // e.g. 1.0823
97+
'date' => $rate->getDate()->format('Y-m-d'), // e.g. 2026-04-29
98+
'provider' => $rate->getProviderName(), // 'european_central_bank'
99+
];
100+
}
101+
}
102+
```
103+
104+
Or fetch directly from the container:
105+
106+
```php
107+
$swap = $container->get('florianv_swap.swap');
108+
$rate = $swap->latest('EUR/USD');
109+
```
110+
111+
Add commercial providers under `providers:` and they will be chained with the configured priority order:
112+
113+
```yaml
114+
# config/packages/florianv_swap.yaml
115+
florianv_swap:
116+
cache:
117+
ttl: 3600
118+
type: filesystem
119+
providers:
120+
apilayer_fixer:
121+
api_key: '%env(SWAP_FIXER_KEY)%'
122+
priority: 10 # tried first
123+
open_exchange_rates:
124+
app_id: '%env(SWAP_OER_APP_ID)%'
125+
priority: 5 # tried second
126+
european_central_bank:
127+
priority: 0 # free fallback for EUR-base pairs
128+
```
63129
64-
The MIT License (MIT). Please see [LICENSE](https://github.com/florianv/symfony-swap/blob/master/Resources/meta/LICENSE) for more information.
130+
Providers are tried in priority order (higher first). If a provider does not support the requested currency pair, it is skipped silently. If a provider throws an error, the next provider is tried. If every provider fails, a `ChainException` is thrown with all collected errors.
131+
132+
## 💾 Caching
133+
134+
Set `cache` in `config/packages/florianv_swap.yaml`:
135+
136+
```yaml
137+
# config/packages/florianv_swap.yaml
138+
florianv_swap:
139+
cache:
140+
ttl: 3600
141+
type: filesystem # array, apcu, filesystem, or a PSR-16 service ID
142+
```
143+
144+
For a custom cache, point `type` at any service implementing `Psr\SimpleCache\CacheInterface`:
145+
146+
```yaml
147+
florianv_swap:
148+
cache:
149+
ttl: 3600
150+
type: my_psr16_cache_service
151+
```
152+
153+
Per-query overrides are documented in the [full documentation](Resources/doc/index.md#-caching).
154+
155+
## 🛠 Common use cases
156+
157+
- Display localized prices in multi-currency Symfony storefronts.
158+
- Compute invoice totals across currencies in a Symfony API.
159+
- Reconcile multi-currency ledgers using historical rates.
160+
- Power internal FX dashboards with rate history.
161+
- Build currency conversion infrastructure for Symfony-based fintech and ERP applications.
162+
163+
## 🧭 Which package should I use?
164+
165+
The Swap ecosystem is a layered toolkit for currency conversion in PHP:
166+
167+
- **Swap.** The easy-to-use, high-level API for plain PHP.
168+
- **Exchanger.** Lower-level, more granular alternative; direct access to provider implementations.
169+
- **Laravel Swap.** Laravel application of Swap.
170+
- **Symfony Swap.** Symfony integration of Swap (this package).
171+
172+
All four packages are MIT-licensed and require PHP 8.2 or newer.
173+
174+
## 📚 Documentation
175+
176+
The full documentation, with the per-provider configuration reference, custom service registration, cache types, and FAQ, is in [Resources/doc/index.md](Resources/doc/index.md). The full provider list with capabilities is in the [Swap README](https://github.com/florianv/swap#-providers).
177+
178+
## 🧩 Related packages
179+
180+
The Swap ecosystem:
181+
182+
- [**Swap**](https://github.com/florianv/swap): easy-to-use PHP currency conversion library.
183+
- [**Exchanger**](https://github.com/florianv/exchanger): exchange rate provider layer.
184+
- [**Laravel Swap**](https://github.com/florianv/laravel-swap): Laravel application of Swap.
185+
- [**Symfony Swap**](https://github.com/florianv/symfony-swap): Symfony integration of Swap (this package).
186+
187+
## 🤝 Sponsorship
188+
189+
The Swap ecosystem is open to selected sponsorships from exchange rate API providers and financial infrastructure companies.
190+
191+
Sponsorship can include:
192+
193+
- Documentation visibility
194+
- Integration examples
195+
- Ecosystem-level visibility across Swap, Exchanger, Laravel Swap, and Symfony Swap
196+
197+
For inquiries, contact the maintainer via [GitHub](https://github.com/florianv).
198+
199+
## 🙌 Contributing
200+
201+
Issues and pull requests are welcome. Please see the existing [issues](https://github.com/florianv/symfony-swap/issues) before opening a new one.
202+
203+
## 📄 License
204+
205+
The MIT License (MIT). Please see [LICENSE](LICENSE) for more information.
206+
207+
## 👏 Credits
208+
209+
- [Florian Voutzinos](https://github.com/florianv)
210+
- [All contributors](https://github.com/florianv/symfony-swap/contributors)

0 commit comments

Comments
 (0)