moneyphp / money

PHP implementation of Fowler's Money pattern.
http://moneyphp.org
MIT License
4.63k stars 441 forks source link

Currency: ensure the code is uppercase (or lowercase, depending on the decision in this issue) #637

Closed Aerendir closed 3 years ago

Aerendir commented 3 years ago

Currently the Currency object doesn't ensure consistency on $code property.


$upperCurrency = new Currency('EUR');
$lowerCurrency = new Currency('eur');

echo $upperCurrency->getCode(); // Returns 'EUR'
echo $lowerCurrency->getCode(); // Returns 'eur'

This is not convenient as it doesn't ensure consistency and may cause some issues.

The first issue is on identity:

var_dump($lowerCurrency->getCode() === $upperCurrency->getCode()); // bool(false), while it should be true

Directly descending from the first issue, there is a database issue.

I've created a Doctrine type that uses the Currency object to create a currency database field type.

Unfortunately, as the object doesn't ensure consistency, if I pass it eur (lowercase), it cannot find entites that have the currency set as uppercase (EUR).

For sure, I could ensure consistency on myself, but simply adding a function call to the Currency object, all will be more solid:

final class Currency implements \JsonSerializable
{
    /**
     * Currency code.
     *
     * @var string
     */
    private $code;

    /**
     * @param string $code
     */
    public function __construct($code)
    {
        if (!is_string($code)) {
            throw new \InvalidArgumentException('Currency code should be string');
        }

        if ($code === '') {
            throw new \InvalidArgumentException('Currency code should not be empty string');
        }

-        $this->code = $code;
+        $this->code = strtoupper($code); // or strtolower($code), depending on the preference of the lead devs of this package
    }
...

I proposed a PR using strtoupper() but, if you prefer, also strtolower() can be used.