Awight has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/341727 )

Change subject: [WIP] Deprecate "manual" errors
......................................................................

[WIP] Deprecate "manual" errors

The original intent may have been a firewall between the validation errors
which can only be set by the adapter, and errors which can be set by other
classes.

I'm simplifying down to a single list of errors.  If any errors are present,
you will not advance to the next step in your donation.

Change-Id: I279052521a20e28d0935ce100c31087a2519e365
---
M amazon_gateway/amazon.api.php
M gateway_common/DonationData.php
M gateway_common/GatewayPage.php
M gateway_common/donation.api.php
M gateway_common/gateway.adapter.php
M gateway_forms/Mustache.php
M globalcollect_gateway/orphan.adapter.php
M tests/phpunit/Adapter/AstroPay/AstroPayTest.php
M tests/phpunit/GatewayPageTest.php
M tests/phpunit/GatewayValidationTest.php
M tests/phpunit/includes/test_gateway/TestingGenericAdapter.php
11 files changed, 82 insertions(+), 97 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface 
refs/changes/27/341727/1

diff --git a/amazon_gateway/amazon.api.php b/amazon_gateway/amazon.api.php
index 07ad771..c82a956 100644
--- a/amazon_gateway/amazon.api.php
+++ b/amazon_gateway/amazon.api.php
@@ -25,11 +25,11 @@
 
                $adapter = new AmazonAdapter( $adapterParams );
 
-               if ( $adapter->getAllErrors() ) {
+               if ( $adapter->getErrors() ) {
                        $output->addValue(
                                null,
                                'errors',
-                               $adapter->getAllErrors()
+                               $adapter->getErrors()
                        );
                } else if ( $token && $adapter->checkTokens() ) {
                        if ( $recurring ) {
diff --git a/gateway_common/DonationData.php b/gateway_common/DonationData.php
index 07c6d43..4983ab1 100644
--- a/gateway_common/DonationData.php
+++ b/gateway_common/DonationData.php
@@ -1088,7 +1088,7 @@
                                $this->getVal( 'language' ),
                                array( $this->gateway->getGlobal( 
'FallbackCurrency' ) )
                        );
-                       $this->gateway->addManualError( $error );
+                       $this->gateway->mergeError( $error );
                }
        }
 }
diff --git a/gateway_common/GatewayPage.php b/gateway_common/GatewayPage.php
index 8d32960..f4ce1c7 100644
--- a/gateway_common/GatewayPage.php
+++ b/gateway_common/GatewayPage.php
@@ -163,14 +163,13 @@
         * a piece of mostly UI, this function needs to be moved inside the 
gateway 
         * adapter class.
         *
-        * @return boolean Returns false on an error-free validation, otherwise 
true.
-        * FIXME: that return value seems backwards to me.
+        * @return boolean Returns true on an error-free validation, otherwise 
false.
         */
        public function validateForm() {
 
-               $validated_ok = $this->adapter->revalidate();
+               $validated_ok = $this->adapter->validate();
 
-               return !$validated_ok;
+               return $validated_ok;
        }
 
        /**
@@ -348,14 +347,16 @@
                        if ( $this->isProcessImmediate() ) {
                                // Check form for errors
                                // FIXME: Should this be rolled into 
adapter.doPayment?
-                               $form_errors = $this->validateForm() || 
$this->adapter->getManualErrors();
+                               $validated_ok = $this->validateForm();
 
-                               // If there were errors, redisplay form, 
otherwise proceed to next step
-                               if ( $form_errors ) {
-                                       $this->displayForm();
-                               } else {
-                                       // Attempt to process the payment, and 
render the response.
+                               // Proceed to the next step, unless there were 
errors.
+                               if ( $validated_ok ) {
+                                       // Attempt to process the payment, then 
render the response.
                                        $this->processPayment();
+                               } else {
+                                       // Redisplay form to give the donor 
notification and a
+                                       // chance correct their errors.
+                                       $this->displayForm();
                                }
                        } else {
                                $this->adapter->session_addDonorData();
@@ -363,7 +364,7 @@
                        }
                } else { //token mismatch
                        $error['general']['token-mismatch'] = $this->msg( 
'donate_interface-token-mismatch' );
-                       $this->adapter->addManualError( $error );
+                       $this->adapter->mergeError( $error );
                        $this->displayForm();
                }
        }
@@ -510,7 +511,7 @@
                                else {
                                        $error['general'][ $code ] = $message;
                                }
-                               $this->adapter->addManualError( $error );
+                               $this->adapter->mergeError( $error );
                        }
                        $this->displayForm();
                } else {
diff --git a/gateway_common/donation.api.php b/gateway_common/donation.api.php
index d560699..ab9bc1f 100644
--- a/gateway_common/donation.api.php
+++ b/gateway_common/donation.api.php
@@ -27,9 +27,10 @@
                        return; // already failed with a dieUsage call
                }
 
-               $gatewayObj->revalidate();
-               if ( $gatewayObj->getAllErrors() ) {
-                       $outputResult['errors'] = $gatewayObj->getAllErrors();
+               $validated_ok = $gatewayObj->validate();
+               if ( !$validated_ok ) {
+                       $outputResult['errors'] = $gatewayObj->getErrors();
+                       // FIXME: What is this junk?  Smaller API, like 
getResult()->addErrors
                        $this->getResult()->setIndexedTagName( 
$outputResult['errors'], 'error' );
                        $this->getResult()->addValue( null, 'result', 
$outputResult );
                        return;
diff --git a/gateway_common/gateway.adapter.php 
b/gateway_common/gateway.adapter.php
index fe1cc9a..b6f87ca 100644
--- a/gateway_common/gateway.adapter.php
+++ b/gateway_common/gateway.adapter.php
@@ -53,7 +53,7 @@
        protected $dataConstraints = array();
 
        /**
-        * $error_map maps gateway errors to client errors
+        * $error_map Reference map from gateway error to client error.
         *
         * The key of each error should map to a i18n message key or a callable
         * By convention, the following three keys have these meanings:
@@ -248,9 +248,10 @@
                $this->session_resetOnSwitch(); // Need to do this before 
creating DonationData
 
                // FIXME: this should not have side effects like setting 
order_id_meta['final']
+               // TODO: On second thought, neither set data nor validate here.
                $this->dataObj = new DonationData( $this, 
$options['external_data'] );
 
-               $this->setValidationErrors( 
$this->getOriginalValidationErrors() );
+               $this->errors = $this->dataObj->getValidationErrors();
 
                $this->unstaged_data = $this->dataObj->getDataEscaped();
                $this->staged_data = $this->unstaged_data;
@@ -276,7 +277,7 @@
                        $error = array( 'general' => array( 'internal-0001' =>
                                $this->getErrorMapByCodeAndTranslate( 
'internal-0001' )
                        ) );
-                       $this->addManualError( $error );
+                       $this->mergeError( $error );
                }
        }
 
@@ -910,11 +911,12 @@
                        $return = new PaymentTransactionResponse();
                        $return->setCommunicationStatus( false );
                        $return->setMessage( 'Failed data validation' );
-                       foreach ( $this->getAllErrors() as $code => $error ) {
+                       foreach ( $this->errors as $code => $error ) {
+                               // TODO: Error should already be in a native 
format.
                                $return->addError( $code, array( 'message' => 
$error, 'logLevel' => LogLevel::INFO, 'debugInfo' => '' ) );
                        }
                        // TODO: should we set $this->transaction_response ?
-                       $this->logger->info( "Failed Validation. Aborting 
$transaction " . print_r( $this->getValidationErrors(), true ) );
+                       $this->logger->info( "Failed Validation. Aborting 
$transaction " . print_r( $this->errors, true ) );
                        return $return;
                }
 
@@ -1481,6 +1483,8 @@
        /**
         * Parse the response to get the errors in a format we can log and 
otherwise deal with.
         * @return array a key/value array of codes (if they exist) and 
messages.
+        * TODO: Move to a parsing class, where these are part of an interface
+        * rather than empty although non-abstract.
         */
        protected function parseResponseErrors( $response ) {
                return array();
@@ -2148,46 +2152,24 @@
                return get_called_class();
        }
 
-       //only the gateway should be setting validation errors. Everybody else 
should set manual errors.
-       protected function setValidationErrors( $errors ) {
-               $this->validation_errors = $errors;
+       /**
+        * Return list of all errors that prevent this transaction from 
continuing.
+        */
+       public function getErrors() {
+               return $this->errors;
        }
 
-       public function getValidationErrors() {
-               if ( !empty( $this->validation_errors ) ) {
-                       return $this->validation_errors;
-               } else {
-                       return false;
-               }
-       }
-
-       public function addManualError( $errors, $reset = false ) {
-               if ( $reset ){
-                       $this->manual_errors = array();
-                       return;
-               }
-               $this->manual_errors = array_merge( $this->manual_errors, 
$errors );
-       }
-
-       public function getManualErrors() {
-               if ( !empty( $this->manual_errors ) ) {
-                       return $this->manual_errors;
-               } else {
-                       return false;
-               }
-       }
-
-       public function getAllErrors(){
-               $validation = $this->getValidationErrors();
-               $manual = $this->getManualErrors();
-               $return = array();
-               if ( is_array( $validation ) ){
-                       $return = array_merge( $return, $validation );
-               }
-               if ( is_array( $manual ) ){
-                       $return = array_merge( $return, $manual );
-               }
-               return $return;
+       /**
+        * Add errors those already stored.
+        *
+        * @param array $errors Map from field or field group key to error 
string.
+        * Merged by key rather than as a list, hence the awkward plural.
+        *
+        * TODO: Encapsulate errors as objects.  Provide both merge list and 
append item to list methods?
+        * FIXME: Nasty that array_merge overwrites rather than appending.  Fix 
while encapsulating the list.
+        */
+       public function mergeError( $errors ) {
+               $this->errors = array_merge( $this->errors, $errors );
        }
 
        /**
@@ -2373,10 +2355,6 @@
                return $this->batch;
        }
 
-       public function getOriginalValidationErrors() {
-               return $this->dataObj->getValidationErrors();
-       }
-
        /**
         * Build list of required fields
         * TODO: Determine if this ever needs to be overridden per gateway, or 
if
@@ -2465,19 +2443,23 @@
         *
         * TODO: Maybe validate on $unstaged_data directly?
         */
-       public function revalidate() {
+       public function validate() {
                $check_not_empty = $this->getRequiredFields();
+               // This is where the gateway adds its own validations.
+               // TODO: Something with transformers?
 
-               $validation_errors = $this->dataObj->getValidationErrors( true, 
$check_not_empty );
-               $this->setValidationErrors( $validation_errors );
+               // FIXME: We're relying on side effects.  Call an obvious 
action like dataObj->validate() instead.
+               $this->dataObj->getValidationErrors( true, $check_not_empty );
+
                return $this->validatedOK();
        }
 
+       /**
+        * @return boolean True if submitted data is valid and sufficient to 
proceed to the next step.
+        * TODO: Were we also trying to indicate whether the validation step 
has succeeded here, by distinguishing array() != false?
+        */
        public function validatedOK(){
-               if ( $this->getValidationErrors() === false ){
-                       return true;
-               }
-               return false;
+               return !$this->errors;
        }
 
        /**
diff --git a/gateway_forms/Mustache.php b/gateway_forms/Mustache.php
index 7101c55..6629553 100644
--- a/gateway_forms/Mustache.php
+++ b/gateway_forms/Mustache.php
@@ -250,7 +250,7 @@
         * @return array
         */
        protected function getErrors() {
-               $errors = $this->gateway->getAllErrors();
+               $errors = $this->gateway->getErrors();
                $return = array( 'errors' => array(
                        'general' => array(),
                        'field' => array(),
diff --git a/globalcollect_gateway/orphan.adapter.php 
b/globalcollect_gateway/orphan.adapter.php
index eb85ba8..c1edf13 100644
--- a/globalcollect_gateway/orphan.adapter.php
+++ b/globalcollect_gateway/orphan.adapter.php
@@ -81,7 +81,7 @@
                //have to do this again here.
                $this->reAddHardData();
 
-               $this->revalidate();
+               $this->validate();
        }
 
        public function addRequestData( $dataArray ) {
diff --git a/tests/phpunit/Adapter/AstroPay/AstroPayTest.php 
b/tests/phpunit/Adapter/AstroPay/AstroPayTest.php
index 7af0d9c..90a7dbc 100644
--- a/tests/phpunit/Adapter/AstroPay/AstroPayTest.php
+++ b/tests/phpunit/Adapter/AstroPay/AstroPayTest.php
@@ -521,7 +521,7 @@
                $init['currency_code'] = 'CLP';
                $gateway = $this->getFreshGatewayObject( $init );
 
-               $errors = $gateway->getValidationErrors();
+               $errors = $gateway->getErrors();
 
                $this->assertNotEmpty( $errors );
                $this->assertTrue(
diff --git a/tests/phpunit/GatewayPageTest.php 
b/tests/phpunit/GatewayPageTest.php
index 27edc9c..48df283 100644
--- a/tests/phpunit/GatewayPageTest.php
+++ b/tests/phpunit/GatewayPageTest.php
@@ -81,9 +81,9 @@
 
                $this->assertTrue( $this->adapter->validatedOK() );
 
-               $manualErrors = $this->adapter->getManualErrors();
+               $errors = $this->adapter->getErrors();
                $msg = $this->page->msg( 
'donate_interface-fallback-currency-notice', 'USD' )->text();
-               $this->assertEquals( $msg, $manualErrors['general'] );
+               $this->assertEquals( $msg, $errors['general'] );
                $this->assertEquals( 100, 
$this->adapter->getData_Unstaged_Escaped( 'amount' ) );
                $this->assertEquals( 'USD', 
$this->adapter->getData_Unstaged_Escaped( 'currency_code' ) );
        }
@@ -97,9 +97,9 @@
 
                $this->page->validateForm();
 
-               $manualErrors = $this->adapter->getManualErrors();
+               $errors = $this->adapter->getErrors();
                $msg = $this->page->msg( 
'donate_interface-fallback-currency-notice', 'OMR' )->text();
-               $this->assertEquals( $msg, $manualErrors['general'] );
+               $this->assertEquals( $msg, $errors['general'] );
                $this->assertEquals( 38, 
$this->adapter->getData_Unstaged_Escaped( 'amount' ) );
                $this->assertEquals( 'OMR', 
$this->adapter->getData_Unstaged_Escaped( 'currency_code' ) );
        }
@@ -112,8 +112,8 @@
 
                $this->assertTrue( $this->adapter->validatedOK() );
 
-               $manualErrors = $this->adapter->getManualErrors();
-               $this->assertEquals( null, $manualErrors['general'] );
+               $errors = $this->adapter->getErrors();
+               $this->assertEquals( null, $errors['general'] );
                $this->assertEquals( 100, 
$this->adapter->getData_Unstaged_Escaped( 'amount' ) );
                $this->assertEquals( 'USD', 
$this->adapter->getData_Unstaged_Escaped( 'currency_code' ) );
        }
@@ -124,9 +124,9 @@
 
                $this->page->validateForm();
 
-               $manualErrors = $this->adapter->getManualErrors();
+               $errors = $this->adapter->getErrors();
                $msg = $this->page->msg( 
'donate_interface-fallback-currency-notice', 'USD' )->text();
-               $this->assertEquals( $msg, $manualErrors['general'] );
+               $this->assertEquals( $msg, $errors['general'] );
                $this->assertEquals( 100, 
$this->adapter->getData_Unstaged_Escaped( 'amount' ) );
                $this->assertEquals( 'USD', 
$this->adapter->getData_Unstaged_Escaped( 'currency_code' ) );
        }
@@ -137,8 +137,8 @@
 
                $this->page->validateForm();
 
-               $manualErrors = $this->adapter->getManualErrors();
-               $this->assertEquals( null, $manualErrors['general'] );
+               $errors = $this->adapter->getErrors();
+               $this->assertEquals( null, $errors['general'] );
                $this->assertEquals( 200, 
$this->adapter->getData_Unstaged_Escaped( 'amount' ) );
                $this->assertEquals( 'BBD', 
$this->adapter->getData_Unstaged_Escaped( 'currency_code' ) );
        }
diff --git a/tests/phpunit/GatewayValidationTest.php 
b/tests/phpunit/GatewayValidationTest.php
index 77d9444..e009026 100644
--- a/tests/phpunit/GatewayValidationTest.php
+++ b/tests/phpunit/GatewayValidationTest.php
@@ -75,7 +75,7 @@
 
                $this->assertFalse( $this->adapter->validatedOK() );
 
-               $errors = $this->adapter->getValidationErrors();
+               $errors = $this->adapter->getErrors();
                $this->assertArrayHasKey( 'amount', $errors );
        }
 
@@ -90,7 +90,7 @@
 
                $this->assertFalse( $this->adapter->validatedOK() );
 
-               $errors = $this->adapter->getValidationErrors();
+               $errors = $this->adapter->getErrors();
                $this->assertArrayHasKey( 'amount', $errors );
        }
 
@@ -105,7 +105,7 @@
 
                $this->assertFalse( $this->adapter->validatedOK() );
 
-               $errors = $this->adapter->getValidationErrors();
+               $errors = $this->adapter->getErrors();
                $this->assertArrayHasKey( 'currency_code', $errors );
        }
 
@@ -126,7 +126,7 @@
 
                $this->assertFalse( $this->adapter->validatedOK() );
 
-               $errors = $this->adapter->getValidationErrors();
+               $errors = $this->adapter->getErrors();
                $this->assertArrayHasKey( 'country', $errors );
        }
 
@@ -141,7 +141,7 @@
 
                $this->assertFalse( $this->adapter->validatedOK() );
 
-               $errors = $this->adapter->getValidationErrors();
+               $errors = $this->adapter->getErrors();
                $this->assertArrayHasKey( 'email', $errors );
        }
 
@@ -156,7 +156,7 @@
 
                $this->assertFalse( $this->adapter->validatedOK() );
 
-               $errors = $this->adapter->getValidationErrors();
+               $errors = $this->adapter->getErrors();
                $this->assertArrayHasKey( 'fname', $errors );
        }
 
@@ -169,7 +169,7 @@
 
                $this->assertFalse( $this->adapter->validatedOK() );
 
-               $errors = $this->adapter->getValidationErrors();
+               $errors = $this->adapter->getErrors();
                $this->assertArrayHasKey( 'currency_code', $errors );
        }
 
@@ -191,7 +191,7 @@
 
                $this->assertFalse( $this->adapter->validatedOK() );
 
-               $errors = $this->adapter->getValidationErrors();
+               $errors = $this->adapter->getErrors();
                $this->assertArrayHasKey( 'general', $errors );
        }
 }
diff --git a/tests/phpunit/includes/test_gateway/TestingGenericAdapter.php 
b/tests/phpunit/includes/test_gateway/TestingGenericAdapter.php
index e010e82..c00a5b5 100644
--- a/tests/phpunit/includes/test_gateway/TestingGenericAdapter.php
+++ b/tests/phpunit/includes/test_gateway/TestingGenericAdapter.php
@@ -22,7 +22,8 @@
 class TestingGenericAdapter extends GatewayAdapter {
 
        /**
-        * A list of fake errors that is returned each time revalidate() is 
called.
+        * A list of fake errors that is returned each time validate() is 
called.
+        * FIXME: s/re/validate
         */
        public $errorsForRevalidate = array();
 
@@ -37,16 +38,16 @@
                return 'xml';
        }
 
-       public function revalidate($check_not_empty = array()) {
+       public function validate($check_not_empty = array()) {
                if ( !empty( $this->errorsForRevalidate ) ) {
                        $fakeErrors = 
$this->errorsForRevalidate[$this->revalidateCount];
                        if ( $fakeErrors !== null ) {
                                $this->revalidateCount++;
-                               $this->setValidationErrors( $fakeErrors );
+                               $this->mergeError( $fakeErrors );
                                return empty( $fakeErrors );
                        }
                }
-               return parent::revalidate($check_not_empty);
+               return parent::validate($check_not_empty);
        }
 
        public function normalizeOrderID( $override = null, $dataObj = null ) {

-- 
To view, visit https://gerrit.wikimedia.org/r/341727
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I279052521a20e28d0935ce100c31087a2519e365
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/DonationInterface
Gerrit-Branch: master
Gerrit-Owner: Awight <awi...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to