Reputation: 13
In a Laravel 4.2 project I'm using the Money (https://github.com/mathiasverraes/money) library by Mathias Verraes. I've included it in the "require" section of the composer.json file like so:
"require": {
"laravel/framework": "4.2",
"mathiasverraes/money": "1.2.1",
All is working fine, now I want to override 1 function (named "stringToUnits") in the Money class. What I have done:
1) I've created a file app/lib/Projectname/Extensions/Money.php to hold that function.
<?php namespace Projectname\Extensions;
use Money\Money as OriginalMoney;
class Money extends OriginalMoney {
public static function stringToUnits($string)
{
...my version...
}
}
2) I'm trying to use the new version of stringToUnits in a service like this:
<?php namespace Projectname\Services\Payment;
use Projectname\Extensions\Money as Money;
class EloquentPaymentService implements PaymentServiceInterface {
private function compareAmountsInAccountsPayable($accountsPayable, array $payment_data) {
$amount_to_pay = Money::EUR(Money::stringToUnits($accountsPayable->amount_due_in_document_currency));
$amount_paid = Money::EUR(Money::stringToUnits($payment_data['amount_due_in_document_currency']));
$difference = $amount_paid->subtract($amount_to_pay);
if( $difference->isNegative() ) {
return $this->clearAccountsPayableWithNegativeDifference($accountsPayable, $payment_data, $difference);
}
}
private function clearAccountsPayableWithNegativeDifference($accountsPayable, array $payment_data, Money $difference) {
...
}
}
Now the function is doing its thing correctly, but Laravel gives me an error I didn't expect:
Argument 3 passed to Projectname\Services\Payment\EloquentPaymentService::clearAccountsPayableWithNegativeDifference() must be an instance of Projectname\Extensions\Money, instance of Money\Money given
So I'm puzzled: Why is the Money object I created an instance of the original \Money\Money and not from my extended class \Projectname\Extensions\Money?
I thought I was telling that to Laravel by stating "use Projectname\Extensions\Money as Money;"?
Upvotes: 1
Views: 144
Reputation: 11961
Here's the problem:
$amount_paid = Money::EUR(Money::stringToUnits($payment_data['amount_due_in_document_currency']));
From what it looks like, the original parent class methods are returning new instances of itself as a result. Your extending class doesn't have a EUR
method, so it bubbles up to the parent and the parent class returns a Money\Money
instance.
$difference = $amount_paid->subtract($amount_to_pay);
$difference
is no longer acting upon your extending class by that point. It's acting upon the original Money\Money
instance returned by the EUR
call. You can confirm this by dumping the results of your $amount_paid
variable, or using your IDE's built-in debugger and looking at the contents at that particular breakpoint.
The error can be removed by eliminating the typehint on your third argument. If you would prefer to keep it, then you will need to override the parent's callStatic
method with something like this:
namespace Projectname\Extensions;
use Money\Money as OriginalMoney;
use Money\Currency;
class Money extends OriginalMoney {
public static function stringToUnits($string)
{
...my version...
}
public static function __callStatic($method, $arguments)
{
return new Money($arguments[0], new Currency($method));
}
}
The code is untested, so I can't guarantee it will work right out of the gate. But that should at least point you in the right direction.
Upvotes: 2