mrzard/open-exchange-rates-bundle
A Symfony bundle that integrates the Open Exchange Rates API, giving your app currency conversion and live exchange rate lookups through a simple, configurable service.
Architecture fit. This is a Symfony 2 bundle, not a Laravel package, despite being classified in the PHP/Laravel track. Bundles are Symfony's extension primitive (a Bundle class, a DI Extension, YAML/XML service definitions, kernel registration). Laravel has no concept of bundles — integration would require either standing up a Symfony kernel inside a Laravel app or bypassing the bundle layer entirely and consuming only its HTTP client. Neither is a sound architecture. The package's actual functionality appears to be a thin wrapper over the OpenExchangeRates REST API, which is a solved problem in a Laravel context via the framework's Http facade.
Integration feasibility. Low. The blocking issue is Composer resolution, not code. A 2017 Symfony 2 bundle will constrain symfony/* to the 2.x/3.x line, while Laravel 9+ requires Symfony 6.x/7.x components. Installing both in one vendor/ tree is effectively impossible without --ignore-platform-reqs hacks that trade a dependency error for a runtime fatal. Even in isolation, the package targets PHP 5.6–7.0 era idioms (no scalar type hints, no return types, no PSR-18 client).
Technical risk. High and asymmetric. The 0.195 score and single-digit stars are consistent with what the metadata shows: last release December 2017, zero dependents, one maintainer. That means no security patching, no PHP 8 compatibility, no CVE response, and no downstream users validating the code path in production. The only genuinely durable asset here is the mapping between the OpenExchangeRates endpoints and a domain model — the wrapper code itself has negative value.
Key questions.
GET /latest.json, /historical/{date}.json, and /currencies.json? If the answer is "a typed response object," it is reimplementable in an afternoon.Recommendation: treat as a reference implementation to read, not a dependency to install.
Stack fit. Poor as a library; acceptable as a spec. The correct Laravel-shaped equivalent is a small ExchangeRateService using Illuminate\Support\Facades\Http, a Cache::remember layer keyed on (base, date), and a typed DTO. This is roughly 40–80 lines and eliminates the entire Symfony coupling problem.
Migration path. If the goal is to adopt the capability rather than the package:
app_id, base, symbols), and the response envelope (note OXR's rates map and the timestamp/disclaimer/license fields).ExchangeRateProvider interface with one concrete OpenExchangeRatesProvider, so a second provider (ECB, Fixer, exchangerate.host) can be swapped without touching callers.If a team is somehow already running this bundle on Symfony 2: it is on an EOL framework and the migration is off Symfony 2, not off this bundle. Do not let the bundle's rewrite become a dependency of that larger migration.
Compatibility. Assume hard conflict on symfony/* and likely on php (>=5.6 style constraints). Confirm with composer why-not in a scratch project. There is no PSR-18/PSR-17 compliance, so it cannot slot into a modern HTTP abstraction.
Sequencing. Spike (0.5 day) → build native provider + cache (1–2 days) → contract tests (0.5 day) → swap behind interface. Total under a week. Attempting to force the bundle in will cost more than that in dependency debugging alone, with a worse end state.
Maintenance. The package is effectively abandoned. Any adopted code becomes a permanent fork you own: PHP 8 upgrades, Guzzle major-version bumps, and OXR API changes all land on your team. The fork's ongoing cost exceeds the original build cost within the first upgrade cycle — a strong argument for reimplementation from day one.
Support. No maintainer response expectation, no issue triage, no security disclosure channel, 9 stars means no community backstop. For a component sitting in the pricing or checkout path, that is a compliance and incident-response gap, not just an inconvenience.
Scaling. The binding constraint is the OXR quota, not CPU. Rate limits are enforced per app_id per month, and rates change hourly — so a cache TTL of one hour with a warm-up job is the practical design. The bundle, as written, offers no evidence of caching, retry, or backoff, which means the first traffic spike converts directly into HTTP 429s. Historical lookups should be persisted once and never re-fetched.
Failure modes. Enumerate these explicitly because the package does not handle them:
timestamp and rejecting rates older than a defined threshold.rates map; code that assumes key presence will throw. Needs an explicit "unsupported pair" path.Ramp-up. Reading and understanding the code is trivial (likely a few hundred lines). That is precisely the argument against adoption: the knowledge-transfer cost is near zero because the capability is cheap to rebuild, while the ownership cost of the fork is permanent.
How can I help you explore Laravel packages today?