Skip to content

Commit ff51600

Browse files
committed
Refactor getAmount() - pull out the float conversion.
1 parent 2059675 commit ff51600

File tree

2 files changed

+58
-25
lines changed

2 files changed

+58
-25
lines changed

src/Omnipay/Common/Message/AbstractRequest.php

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ abstract class AbstractRequest implements RequestInterface
3737
*/
3838
protected $response;
3939

40+
/**
41+
* @var bool
42+
*/
43+
protected $zeroAmountAllowed = true;
44+
45+
/**
46+
* @var bool
47+
*/
48+
protected $negativeAmountAllowed = false;
49+
4050
/**
4151
* Create a new Request
4252
*
@@ -158,6 +168,30 @@ public function setCardReference($value)
158168
return $this->setParameter('cardReference', $value);
159169
}
160170

171+
/**
172+
* Convert an amount into a float.
173+
*
174+
* @var string|int|float $value The value to convert.
175+
* @throws InvalidRequestException on any validation failure.
176+
* @return float The amount converted to a float.
177+
*/
178+
179+
public function toFloat($value)
180+
{
181+
if ( ! is_string($value) && ! is_int($value) && ! is_float($value)) {
182+
throw new InvalidRequestException('Data type is not a valid decimal number.');
183+
}
184+
185+
if (is_string($value)) {
186+
// Validate generic number, with optional sign and decimals.
187+
if ( ! preg_match('/^[-]?[0-9]+(\.[0-9]*)?$/', $value)) {
188+
throw new InvalidRequestException('String is not a valid decimal number.');
189+
}
190+
}
191+
192+
return (float)$value;
193+
}
194+
161195
/**
162196
* Validates and returns the formated amount.
163197
*
@@ -168,41 +202,31 @@ public function setCardReference($value)
168202
public function getAmount()
169203
{
170204
$amount = $this->getParameter('amount');
171-
$message = 'Please specify amount as a string or float, '
172-
. 'with decimal places (e.g. \'10.00\' to represent $10.00).';
173205

174206
if ($amount !== null) {
175207
// Don't allow integers for currencies that support decimals.
176208
// This is for legacy reasons - upgrades from v0.9
177-
if (is_int($amount) && $this->getCurrencyDecimalPlaces() > 0) {
178-
throw new InvalidRequestException($message);
179-
}
180-
181-
if (is_string($amount)) {
182-
// Negative amounts are valid numbers at this stage.
183-
if (preg_match('/[^0-9\.-]/', $amount)) {
184-
throw new InvalidRequestException('Invalid character in amount.');
185-
}
186-
187-
// Generic number, with optional sign and decimals.
188-
if (!preg_match('/^[-]?[0-9]+(\.[0-9]*)?$/', $amount)) {
189-
throw new InvalidRequestException('Amount string is not a valid decimal number.');
190-
}
191-
192-
// Don't allow integers for currencies that support decimals (legacy v0.9).
193-
if ($this->getCurrencyDecimalPlaces() > 0 && false === strpos((string) $amount, '.')) {
194-
throw new InvalidRequestException($message);
195-
}
209+
if ($this->getCurrencyDecimalPlaces() > 0) {
210+
if (is_int($amount) || (is_string($amount) && false === strpos((string) $amount, '.'))) {
211+
throw new InvalidRequestException(
212+
'Please specify amount as a string or float, '
213+
. 'with decimal places (e.g. \'10.00\' to represent $10.00).'
214+
);
215+
};
196216
}
197217

198-
// The number_format() used later requires a float.
199-
$amount = (float)$amount;
218+
$amount = $this->toFloat($amount);
200219

201220
// Check for a negative amount.
202-
if ($amount < 0) {
221+
if ( ! $this->negativeAmountAllowed && $amount < 0) {
203222
throw new InvalidRequestException('A negative amount is not allowed.');
204223
}
205224

225+
// Check for a zero amount.
226+
if ( ! $this->zeroAmountAllowed && $amount === 0.0) {
227+
throw new InvalidRequestException('A zero amount is not allowed.');
228+
}
229+
206230
// Check for rounding that may occur if too many significant decimal digits are supplied.
207231
$decimal_count = strlen(substr(strrchr((string)$amount, '.'), 1));
208232
if ($decimal_count > $this->getCurrencyDecimalPlaces()) {

tests/Omnipay/Common/Message/AbstractRequestTest.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public function testAmountZeroFloat()
9595

9696
public function testAmountZeroString()
9797
{
98-
$this->assertSame($this->request, $this->request->setAmount('0.0'));
98+
$this->assertSame($this->request, $this->request->setAmount('0.000000'));
9999
$this->assertSame('0.00', $this->request->getAmount());
100100
}
101101

@@ -169,6 +169,15 @@ public function testAmountInvalidFormatThrowsException()
169169
$this->request->getAmount();
170170
}
171171

172+
/**
173+
* @expectedException Omnipay\Common\Exception\InvalidRequestException
174+
*/
175+
public function testAmountInvalidTypeThrowsException()
176+
{
177+
$this->assertSame($this->request, $this->request->setAmount(true));
178+
$this->request->getAmount();
179+
}
180+
172181
/**
173182
* @expectedException Omnipay\Common\Exception\InvalidRequestException
174183
*/

0 commit comments

Comments
 (0)