public function validate(GatewayType $adapter, $normalized, &$errors)
 {
     if (!isset($normalized['amount']) || !isset($normalized['currency_code'])) {
         // Not enough info to validate
         return;
     }
     if (isset($errors['currency_code'])) {
         // Already displaying an error
         return;
     }
     $value = $normalized['amount'];
     if (self::isZeroIsh($value)) {
         $errors['amount'] = DataValidator::getErrorMessage('amount', 'not_empty', $normalized['language']);
         return;
     }
     $currency = $normalized['currency_code'];
     $min = self::convert($adapter->getGlobal('PriceFloor'), $currency);
     $max = self::convert($adapter->getGlobal('PriceCeiling'), $currency);
     if (!is_numeric($value) || $value < 0) {
         $errors['amount'] = WmfFramework::formatMessage('donate_interface-error-msg-invalid-amount');
     } else {
         if ($value > $max) {
             // FIXME: should format the currency values in this message
             $errors['amount'] = WmfFramework::formatMessage('donate_interface-bigamount-error', $max, $currency, $adapter->getGlobal('MajorGiftsEmail'));
         } else {
             if ($value < $min) {
                 $locale = $normalized['language'] . '_' . $normalized['country'];
                 $formattedMin = self::format($min, $currency, $locale);
                 $errors['amount'] = WmfFramework::formatMessage('donate_interface-smallamount-error', $formattedMin);
             }
         }
     }
 }
 public function testWhitespaceAmount()
 {
     $this->normalized['amount'] = '    ';
     $this->validate();
     $this->assertNotEmpty($this->errors, 'No error for whitespace amount');
     $expected = DataValidator::getErrorMessage('amount', 'not_empty', 'en');
     $this->assertEquals($expected, $this->errors['amount'], 'Wrong error message for whitespace amount');
 }
 /**
  * Should set a validation error on fiscal_number
  */
 function testDoPaymentBadFiscalNumber()
 {
     $init = $this->getDonorTestData('BR');
     $this->setLanguage($init['language']);
     $init['payment_method'] = 'cc';
     $gateway = $this->getFreshGatewayObject($init);
     $gateway->setDummyGatewayResponseCode('fiscal_number');
     $result = $gateway->doPayment();
     $this->assertTrue($result->getRefresh(), 'PaymentResult should be a refresh');
     $errors = $gateway->getTransactionResponse()->getErrors();
     $expectedMessage = DataValidator::getErrorMessage('fiscal_number', 'calculated', $init['language'], $init['country']);
     $this->assertEquals($expectedMessage, $errors['internal-0000']['message']);
     $this->assertEquals('fiscal_number', $errors['internal-0000']['context']);
 }
 /**
  * Returns an array of rules used to validate data before submission.
  * Each entry's key should correspond to the id of the target field, and
  * the value should be a list of rules with keys as described in
  * @see ClientSideValidationHelper::getClientSideValidation
  */
 protected function getClientSideValidationRules()
 {
     $language = $this->getData_Unstaged_Escaped('language');
     $country = $this->getData_Unstaged_Escaped('country');
     // Start with the server required field validations.
     $requiredRules = array();
     foreach ($this->getRequiredFields() as $field) {
         $requiredRules[$field] = array(array('required' => true, 'message' => DataValidator::getErrorMessage($field, 'not_empty', $language, $country)));
     }
     $transformerRules = array();
     foreach ($this->data_transformers as $transformer) {
         if ($transformer instanceof ClientSideValidationHelper) {
             $transformer->getClientSideValidation($this->unstaged_data, $transformerRules);
         }
     }
     return array_merge_recursive($requiredRules, $transformerRules);
 }
 protected static function getErrorMessage($type, $language, $country)
 {
     return DataValidator::getErrorMessage(self::$key, $type, $language, $country);
 }
 /**
  * Sets communication status and errors for responses to NewInvoice
  * @param array $response
  */
 protected function processNewInvoiceResponse($response)
 {
     // Increment sequence number so next NewInvoice call gets a new order ID
     $this->incrementSequenceNumber();
     if (!isset($response['status'])) {
         $this->transaction_response->setCommunicationStatus(false);
         $this->logger->error('AstroPay response does not have a status code');
         throw new ResponseProcessingException('AstroPay response does not have a status code', ResponseCodes::MISSING_REQUIRED_DATA);
     }
     $this->transaction_response->setCommunicationStatus(true);
     if ($response['status'] === '0') {
         if (!isset($response['link'])) {
             $this->logger->error('AstroPay NewInvoice success has no link');
             throw new ResponseProcessingException('AstroPay NewInvoice success has no link', ResponseCodes::MISSING_REQUIRED_DATA);
         }
     } else {
         $logme = 'AstroPay response has non-zero status.  Full response: ' . print_r($response, true);
         $this->logger->warning($logme);
         $code = 'internal-0000';
         $message = $this->getErrorMapByCodeAndTranslate($code);
         $context = null;
         if (isset($response['desc'])) {
             // error codes are unreliable, so we have to examine the description
             if (preg_match('/^invoice already used/i', $response['desc'])) {
                 $this->logger->error('Order ID collision! Starting again.');
                 throw new ResponseProcessingException('Order ID collision! Starting again.', ResponseCodes::DUPLICATE_ORDER_ID, array('order_id'));
             } else {
                 if (preg_match('/^could not (register user|make the deposit)/i', $response['desc'])) {
                     // AstroPay is overwhelmed.  Tell the donor to try again soon.
                     $message = WmfFramework::formatMessage('donate_interface-try-again');
                 } else {
                     if (preg_match('/^user (unauthorized|blacklisted)/i', $response['desc'])) {
                         // They are blacklisted by AstroPay for shady doings,
                         // or listed delinquent by their government.
                         // Either way, we can't process 'em through AstroPay
                         $this->finalizeInternalStatus(FinalStatus::FAILED);
                     } else {
                         if (preg_match('/^the user limit has been exceeded/i', $response['desc'])) {
                             // They've spent too much via AstroPay today.
                             // Setting context to 'amount' will tell the form to treat
                             // this like a validation error and make amount editable.
                             $context = 'amount';
                             $message = WmfFramework::formatMessage('donate_interface-error-msg-limit');
                         } else {
                             if (preg_match('/param x_cpf$/i', $response['desc'])) {
                                 // Something wrong with the fiscal number
                                 $context = 'fiscal_number';
                                 $language = $this->dataObj->getVal_Escaped('language');
                                 $country = $this->dataObj->getVal_Escaped('country');
                                 $message = DataValidator::getErrorMessage('fiscal_number', 'calculated', $language, $country);
                             } else {
                                 if (preg_match('/invalid control/i', $response['desc'])) {
                                     // They think we screwed up the signature.  Log what we signed.
                                     $signed = AstroPaySignature::getNewInvoiceMessage($this->getData_Staged());
                                     $signature = $this->getData_Staged('control');
                                     $this->logger->error("{$logme} Signed message: '{$signed}' Signature: '{$signature}'");
                                 } else {
                                     // Some less common error.  Also log message at 'error' level
                                     $this->logger->error($logme);
                                 }
                             }
                         }
                     }
                 }
             }
         }
         $this->transaction_response->setErrors(array($code => array('message' => $message, 'debugInfo' => $logme, 'logLevel' => LogLevel::WARNING, 'context' => $context)));
     }
 }