Allow extending Money with custom currency provider #95
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
Superseeds #94
This is an attempt to solve #30 and #61
First, we need to accept that the
MoneyandCurrencyobjects cannot be final. In reality, they take on different shapes and forms. The currentBrick\Money\Moneyimplementation is built around ISO 4217 currencies, but users are trying to adapt it for other purposes, like cryptocurrencies or historical currencies. The reason is simple: the underlying Brick\Money manipulation engine is extremely versatile and would work just as well with those alternative currency types. This is a valid and logical use case.Secondly, with the main methods for object creation being static, proper dependency injection to configure a global default behavior becomes impossible.
The quickest solution without a major refactor would be to introduce inheritance as an extension point. This allows users to provide custom currency providers tailored to their use cases. The library itself could leverage this to introduce new types of currencies, such as the historic ISO 4217 currencies discussed here: #93 (comment).
It uses inheritance as a point of extension to define the
CurrencyProviderused and adapt the code base to rely on aCurrencyinterface instead of the previousCurrency(which was actuallyIsoCurrency).The static logic for creating
Moneyremains closely tied toIsoCurrencyProviderto prevent a more extensive breaking change.This approach balances the need for those interested in distinguishing between
MoneyandIsoMoney, while allowing other users to continue usingMoneyas they have since the library's inception, without needing to address this distinction in their context.You can now do:
It has the following breaking changes:
Currencyhas been renamed toIsoCurrencyto better reflect its role in representing ISO 4217 currenciesCurrencyis now an interface, withIsoCurrencyserving as its concrete implementation.Currency#getCurrencyCode()is nowCurrency#getCode()for clarityUnknownCurrencyExceptionhas been renamed toUnknownIsoCurrencyExceptionto align with its specific use forIsoCurrencytypesISOCurrencyProviderhas been renamed toIsoCurrencyProviderto adhere to the upcoming PSR rules for capitalization of abbreviationsPreviously, allowing
string|intas currency necessitated objects to identify the corresponding IsoCurrency, creating a tight coupling with a specific IsoCurrencyProvider implementation and a mix of unwanted responsibility for the object. To move towards a more currency-agnostic architecture, it is now advised to resolve the currency beforehand.$currencyinCurrency#is()has been refined to accept onlyCurrency, removing support forstring|int$currencyinCurrencyConverter#convert()has been refined to accept onlyCurrency, removing support forstring|int$currencyinCurrencyConverter#convertToRational()has been refined to accept onlyCurrency, removing support forstring|int