Index: trunk/extensions/DonationInterface/donationinterface.php |
— | — | @@ -87,6 +87,7 @@ |
88 | 88 | $wgAutoloadClasses['DonationData'] = $donationinterface_dir . 'gateway_common/DonationData.php'; |
89 | 89 | $wgAutoloadClasses['GatewayAdapter'] = $donationinterface_dir . 'gateway_common/gateway.adapter.php'; |
90 | 90 | $wgAutoloadClasses['GatewayForm'] = $donationinterface_dir . 'gateway_common/GatewayForm.php'; |
| 91 | +$wgAutoloadClasses['DataValidator'] = $donationinterface_dir . 'gateway_common/DataValidator.php'; |
91 | 92 | |
92 | 93 | //load all possible form classes |
93 | 94 | $wgAutoloadClasses['Gateway_Form'] = $donationinterface_dir . 'gateway_forms/Form.php'; |
Index: trunk/extensions/DonationInterface/tests/resources/forms/UniversalTest.php |
— | — | @@ -158,7 +158,7 @@ |
159 | 159 | |
160 | 160 | $return .= $this->getFormMessagesByType('general'); |
161 | 161 | |
162 | | - $return .= $this->getFormMessagesByType('invalidamount'); |
| 162 | + $return .= $this->getFormMessagesByType('amount'); |
163 | 163 | |
164 | 164 | $return .= $this->getFormMessagesByType('retryMsg'); |
165 | 165 | |
Index: trunk/extensions/DonationInterface/payflowpro_gateway/payflowpro_gateway.body.php |
— | — | @@ -39,10 +39,10 @@ |
40 | 40 | if ( $this->adapter->posted ) { |
41 | 41 | // The form was submitted and the payment method has been set |
42 | 42 | // Check form for errors |
43 | | - $form_errors = $this->validateForm( $this->errors ); |
| 43 | + $form_errors = $this->validateForm(); |
44 | 44 | // If there were errors, redisplay form, otherwise proceed to next step |
45 | 45 | if ( $form_errors ) { |
46 | | - $this->displayForm( $this->errors ); |
| 46 | + $this->displayForm(); |
47 | 47 | } else { // The submitted form data is valid, so process it |
48 | 48 | $result = $this->adapter->do_transaction( 'Card' ); |
49 | 49 | |
— | — | @@ -58,11 +58,12 @@ |
59 | 59 | } |
60 | 60 | } else { |
61 | 61 | // Display form for the first time |
62 | | - $this->displayForm( $this->errors ); |
| 62 | + $this->displayForm(); |
63 | 63 | } |
64 | 64 | } else {//token mismatch |
65 | | - $this->errors['general']['token-mismatch'] = wfMsg( 'donate_interface-token-mismatch' ); |
66 | | - $this->displayForm( $this->errors ); |
| 65 | + $error['general']['token-mismatch'] = wfMsg( 'donate_interface-token-mismatch' ); |
| 66 | + $this->adapter->addManualError( $error ); |
| 67 | + $this->displayForm(); |
67 | 68 | } |
68 | 69 | } |
69 | 70 | |
— | — | @@ -94,8 +95,9 @@ |
95 | 96 | } elseif ( ( $errorCode == '3' ) && ( $data['numAttempt'] < '5' ) ) { |
96 | 97 | $this->log( $msgPrefix . "Transaction unsuccessful (invalid info).", LOG_DEBUG ); |
97 | 98 | // pass responseMsg as an array key as required by displayForm |
98 | | - $this->errors['retryMsg'] = $responseMsg; |
99 | | - $this->displayForm( $this->errors ); |
| 99 | + $error['retryMsg'] = $responseMsg; |
| 100 | + $this->adapter->addManualError( $error ); |
| 101 | + $this->displayForm(); |
100 | 102 | // if declined or if user has already made two attempts, decline |
101 | 103 | } elseif ( ( $errorCode == '2' ) || ( $data['numAttempt'] >= '3' ) ) { |
102 | 104 | $this->log( $msgPrefix . "Transaction declined.", LOG_DEBUG ); |
— | — | @@ -108,14 +110,16 @@ |
109 | 111 | $this->fnPayflowDisplayPending( $data, $responseMsg ); |
110 | 112 | } elseif ( strpos( $errorCode, 'internal' ) === 0 ) { |
111 | 113 | $this->log( $msgPrefix . "Transaction unsuccessful (communication failure).", LOG_DEBUG ); |
112 | | - $this->errors['retryMsg'] = $responseMsg; |
113 | | - $this->displayForm( $this->errors ); |
| 114 | + $error['retryMsg'] = $responseMsg; |
| 115 | + $this->adapter->addManualError( $error ); |
| 116 | + $this->displayForm(); |
114 | 117 | } elseif ( !empty( $errorCode ) ) { |
115 | 118 | // This should not be hit. |
116 | 119 | $this->log( $msgPrefix . "Transaction unsuccessful (unknown failure).", LOG_DEBUG ); |
117 | 120 | $this->fnPayflowDisplayOtherResults( $responseMsg ); |
118 | | - $this->errors['retryMsg'] = $errorCode; |
119 | | - $this->displayForm( $this->errors ); |
| 121 | + $error['retryMsg'] = $errorCode; |
| 122 | + $this->adapter->addManualError( $error ); |
| 123 | + $this->displayForm(); |
120 | 124 | } |
121 | 125 | } |
122 | 126 | |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoColumnLetter2.php |
— | — | @@ -2,7 +2,7 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoColumnLetter2 extends Gateway_Form_OneStepTwoColumn { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
| 6 | + public function __construct( &$gateway ) { |
7 | 7 | global $wgScriptPath; |
8 | 8 | |
9 | 9 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoColumnLetter.css' ); |
12 | 12 | } |
13 | 13 | |
14 | | - parent::__construct( $gateway, $form_errors ); |
| 14 | + parent::__construct( $gateway ); |
15 | 15 | } |
16 | 16 | |
17 | 17 | public function generateFormStart() { |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoColumnLetter3.php |
— | — | @@ -2,7 +2,7 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoColumnLetter3 extends Gateway_Form_OneStepTwoColumn { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
| 6 | + public function __construct( &$gateway ) { |
7 | 7 | global $wgScriptPath; |
8 | 8 | |
9 | 9 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoColumnLetter.css' ); |
12 | 12 | } |
13 | 13 | |
14 | | - parent::__construct( $gateway, $form_errors ); |
| 14 | + parent::__construct( $gateway ); |
15 | 15 | } |
16 | 16 | |
17 | 17 | public function generateFormStart() { |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoColumnLetter4.php |
— | — | @@ -2,7 +2,7 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoColumnLetter4 extends Gateway_Form_OneStepTwoColumn { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
| 6 | + public function __construct( &$gateway ) { |
7 | 7 | global $wgScriptPath; |
8 | 8 | |
9 | 9 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoColumnLetter4.css' ); |
12 | 12 | } |
13 | 13 | |
14 | | - parent::__construct( $gateway, $form_errors ); |
| 14 | + parent::__construct( $gateway ); |
15 | 15 | } |
16 | 16 | |
17 | 17 | public function generateFormStart() { |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoColumnLetter5.php |
— | — | @@ -2,7 +2,7 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoColumnLetter5 extends Gateway_Form_OneStepTwoColumn { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
| 6 | + public function __construct( &$gateway ) { |
7 | 7 | global $wgScriptPath; |
8 | 8 | |
9 | 9 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoColumnLetter5.css' ); |
12 | 12 | } |
13 | 13 | |
14 | | - parent::__construct( $gateway, $form_errors ); |
| 14 | + parent::__construct( $gateway ); |
15 | 15 | } |
16 | 16 | |
17 | 17 | public function generateFormStart() { |
— | — | @@ -92,7 +92,7 @@ |
93 | 93 | $amount = $this->getEscapedValue( 'amountOther' ); |
94 | 94 | } |
95 | 95 | $form .= '<tr>'; |
96 | | - $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['invalidamount'] . '</span></td>'; |
| 96 | + $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['amount'] . '</span></td>'; |
97 | 97 | $form .= '</tr>'; |
98 | 98 | $form .= '<tr>'; |
99 | 99 | $form .= '<td class="label">' . Xml::label( wfMsg( 'donate_interface-donor-amount' ), 'amount' ) . '</td>'; |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoColumnLetter6.php |
— | — | @@ -2,7 +2,7 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoColumnLetter6 extends Gateway_Form_OneStepTwoColumn { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
| 6 | + public function __construct( &$gateway ) { |
7 | 7 | global $wgScriptPath; |
8 | 8 | |
9 | 9 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoColumnLetter6.css' ); |
12 | 12 | } |
13 | 13 | |
14 | | - parent::__construct( $gateway, $form_errors ); |
| 14 | + parent::__construct( $gateway ); |
15 | 15 | } |
16 | 16 | |
17 | 17 | public function generateFormStart() { |
— | — | @@ -92,7 +92,7 @@ |
93 | 93 | $amount = $this->getEscapedValue( 'amountOther' ); |
94 | 94 | } |
95 | 95 | $form .= '<tr>'; |
96 | | - $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['invalidamount'] . '</span></td>'; |
| 96 | + $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['amount'] . '</span></td>'; |
97 | 97 | $form .= '</tr>'; |
98 | 98 | $form .= '<tr>'; |
99 | 99 | $form .= '<td class="label">' . Xml::label( wfMsg( 'donate_interface-donor-amount' ), 'amount' ) . '</td>'; |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoStepTwoColumnLetter.php |
— | — | @@ -1,7 +1,7 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoStepTwoColumnLetter extends Gateway_Form_TwoStepTwoColumn { |
5 | | - public function __construct( &$gateway, &$form_errors ) { |
| 5 | + public function __construct( &$gateway ) { |
6 | 6 | global $wgScriptPath; |
7 | 7 | |
8 | 8 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoStepTwoColumnLetter.css' ); |
11 | 11 | } |
12 | 12 | |
13 | | - parent::__construct( $gateway, $form_errors ); |
| 13 | + parent::__construct( $gateway ); |
14 | 14 | } |
15 | 15 | |
16 | 16 | public function generateFormStart() { |
— | — | @@ -84,7 +84,7 @@ |
85 | 85 | |
86 | 86 | // amount |
87 | 87 | $form .= '<tr>'; |
88 | | - $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['invalidamount'] . '</span></td>'; |
| 88 | + $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['amount'] . '</span></td>'; |
89 | 89 | $form .= '</tr>'; |
90 | 90 | $form .= '<tr>'; |
91 | 91 | $form .= '<td class="label">' . Xml::label( wfMsg( 'donate_interface-donor-amount' ), 'amount' ) . '</td>'; |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoColumnLetter7.php |
— | — | @@ -2,7 +2,7 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoColumnLetter7 extends Gateway_Form_OneStepTwoColumn { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
| 6 | + public function __construct( &$gateway ) { |
7 | 7 | global $wgScriptPath; |
8 | 8 | |
9 | 9 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoColumnLetter7.css' ); |
12 | 12 | } |
13 | 13 | |
14 | | - parent::__construct( $gateway, $form_errors ); |
| 14 | + parent::__construct( $gateway ); |
15 | 15 | } |
16 | 16 | |
17 | 17 | public function loadPlaceholders() { |
— | — | @@ -213,7 +213,7 @@ |
214 | 214 | $amount = $this->getEscapedValue( 'amountOther' ); |
215 | 215 | } |
216 | 216 | $form .= '<tr>'; |
217 | | - $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['invalidamount'] . '</span></td>'; |
| 217 | + $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['amount'] . '</span></td>'; |
218 | 218 | $form .= '</tr>'; |
219 | 219 | $form .= '<tr>'; |
220 | 220 | $form .= '<td class="label"><div style="padding-top:4px;">' . Xml::label( wfMsg( 'donate_interface-donor-amount' ), 'amount' ) . '</div></td>'; |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoColumnPayPal.php |
— | — | @@ -1,8 +1,8 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoColumnPayPal extends Gateway_Form_OneStepTwoColumn { |
5 | | - public function __construct( &$gateway, &$form_errors ) { |
6 | | - parent::__construct( $gateway, $form_errors ); |
| 5 | + public function __construct( &$gateway ) { |
| 6 | + parent::__construct( $gateway ); |
7 | 7 | } |
8 | 8 | |
9 | 9 | public function generateFormStart() { |
Index: trunk/extensions/DonationInterface/gateway_forms/SingleColumn.php |
— | — | @@ -2,7 +2,7 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_SingleColumn extends Gateway_Form_TwoColumnLetter { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
| 6 | + public function __construct( &$gateway ) { |
7 | 7 | global $wgScriptPath; |
8 | 8 | |
9 | 9 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/SingleColumn.css' ); |
12 | 12 | } |
13 | 13 | |
14 | | - parent::__construct( $gateway, $form_errors ); |
| 14 | + parent::__construct( $gateway ); |
15 | 15 | } |
16 | 16 | |
17 | 17 | public function generateFormEnd() { |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoStepTwoColumnLetterCA.php |
— | — | @@ -1,7 +1,7 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoStepTwoColumnLetterCA extends Gateway_Form_TwoStepTwoColumn { |
5 | | - public function __construct( &$gateway, &$form_errors ) { |
| 5 | + public function __construct( &$gateway ) { |
6 | 6 | global $wgScriptPath; |
7 | 7 | |
8 | 8 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoStepTwoColumnLetter.css' ); |
11 | 11 | } |
12 | 12 | |
13 | | - parent::__construct( $gateway, $form_errors ); |
| 13 | + parent::__construct( $gateway ); |
14 | 14 | } |
15 | 15 | |
16 | 16 | public function generateFormStart() { |
— | — | @@ -84,7 +84,7 @@ |
85 | 85 | |
86 | 86 | // amount |
87 | 87 | $form .= '<tr>'; |
88 | | - $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['invalidamount'] . '</span></td>'; |
| 88 | + $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['amount'] . '</span></td>'; |
89 | 89 | $form .= '</tr>'; |
90 | 90 | $form .= '<tr>'; |
91 | 91 | $form .= '<td class="label">' . Xml::label( wfMsg( 'donate_interface-donor-amount' ), 'amount' ) . '</td>'; |
Index: trunk/extensions/DonationInterface/gateway_forms/Form.php |
— | — | @@ -62,12 +62,16 @@ |
63 | 63 | */ |
64 | 64 | abstract function getForm(); |
65 | 65 | |
66 | | - public function __construct( &$gateway, &$error ) { |
| 66 | + public function __construct( &$gateway ) { |
67 | 67 | global $wgOut, $wgRequest; |
68 | 68 | |
69 | 69 | $this->gateway = & $gateway; |
70 | 70 | $this->test = $this->gateway->getGlobal( "Test" ); |
71 | | - $this->form_errors = & $error; |
| 71 | + $gateway_errors = $this->gateway->getAllErrors(); |
| 72 | + if ( !is_array( $gateway_errors ) ){ |
| 73 | + $gateway_errors = array(); |
| 74 | + } |
| 75 | + $this->form_errors = array_merge( DataValidator::getEmptyErrorArray(), $gateway_errors ); |
72 | 76 | $this->paypal = $wgRequest->getBool( 'paypal', false ); |
73 | 77 | |
74 | 78 | /** |
— | — | @@ -599,7 +603,7 @@ |
600 | 604 | $amount = $this->getEscapedValue( 'amountOther' ); |
601 | 605 | } |
602 | 606 | $form = '<tr>'; |
603 | | - $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['invalidamount'] . '</span></td>'; |
| 607 | + $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['amount'] . '</span></td>'; |
604 | 608 | $form .= '</tr>'; |
605 | 609 | $form .= '<tr>'; |
606 | 610 | $form .= '<td class="label">' . Xml::label( wfMsg( 'donate_interface-donor-amount' ), 'amount' ) . '</td>'; |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoColumnLetter.php |
— | — | @@ -2,7 +2,7 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoColumnLetter extends Gateway_Form_OneStepTwoColumn { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
| 6 | + public function __construct( &$gateway ) { |
7 | 7 | global $wgScriptPath; |
8 | 8 | |
9 | 9 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoColumnLetter.css' ); |
12 | 12 | } |
13 | 13 | |
14 | | - parent::__construct( $gateway, $form_errors ); |
| 14 | + parent::__construct( $gateway ); |
15 | 15 | } |
16 | 16 | |
17 | 17 | public function generateFormStart() { |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoStepTwoColumnPremium.php |
— | — | @@ -1,7 +1,7 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoStepTwoColumnPremium extends Gateway_Form_TwoStepTwoColumn { |
5 | | - public function __construct( &$gateway, &$form_errors ) { |
| 5 | + public function __construct( &$gateway ) { |
6 | 6 | global $wgScriptPath; |
7 | 7 | |
8 | 8 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoStepTwoColumnPremium.css' ); |
11 | 11 | } |
12 | 12 | |
13 | | - parent::__construct( $gateway, $form_errors ); |
| 13 | + parent::__construct( $gateway ); |
14 | 14 | } |
15 | 15 | |
16 | 16 | public function generateFormStart() { |
— | — | @@ -96,7 +96,7 @@ |
97 | 97 | |
98 | 98 | // amount |
99 | 99 | $form .= '<tr>'; |
100 | | - $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['invalidamount'] . '</span></td>'; |
| 100 | + $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['amount'] . '</span></td>'; |
101 | 101 | $form .= '</tr>'; |
102 | 102 | $form .= '<tr>'; |
103 | 103 | $form .= '<td class="label">' . Xml::label( wfMsg( 'donate_interface-donor-amount' ), 'amount' ) . '</td>'; |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoStepTwoColumn.php |
— | — | @@ -2,8 +2,8 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoStepTwoColumn extends Gateway_Form { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
7 | | - parent::__construct( $gateway, $form_errors ); |
| 6 | + public function __construct( &$gateway ) { |
| 7 | + parent::__construct( $gateway ); |
8 | 8 | } |
9 | 9 | |
10 | 10 | public function loadPlaceholders() { |
— | — | @@ -166,7 +166,7 @@ |
167 | 167 | |
168 | 168 | // amount |
169 | 169 | $form = '<tr>'; |
170 | | - $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['invalidamount'] . '</span></td>'; |
| 170 | + $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['amount'] . '</span></td>'; |
171 | 171 | $form .= '</tr>'; |
172 | 172 | $form .= '<tr>'; |
173 | 173 | $form .= '<td class="label">' . Xml::label( wfMsg( 'donate_interface-donor-amount' ), 'amount' ) . '</td>'; |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoStepTwoColumnLetter2.php |
— | — | @@ -1,7 +1,7 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoStepTwoColumnLetter2 extends Gateway_Form_TwoStepTwoColumnLetter { |
5 | | - public function __construct( &$gateway, &$form_errors ) { |
| 5 | + public function __construct( &$gateway ) { |
6 | 6 | global $wgScriptPath; |
7 | 7 | |
8 | 8 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -9,6 +9,6 @@ |
10 | 10 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoStepTwoColumnLetter2.css' ); |
11 | 11 | } |
12 | 12 | |
13 | | - parent::__construct( $gateway, $form_errors ); |
| 13 | + parent::__construct( $gateway ); |
14 | 14 | } |
15 | 15 | } |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoStepTwoColumnLetter3.php |
— | — | @@ -1,14 +1,14 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoStepTwoColumnLetter3 extends Gateway_Form_TwoStepTwoColumn { |
5 | | - public function __construct( &$gateway, &$form_errors ) { |
| 5 | + public function __construct( &$gateway ) { |
6 | 6 | global $wgExtensionAssetsPath; |
7 | 7 | |
8 | 8 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
9 | 9 | if ( !strlen( $this->getStylePath() ) ) { |
10 | 10 | $this->setStylePath( $wgExtensionAssetsPath . '/DonationInterface/gateway_forms/css/TwoStepTwoColumnLetter3.css' ); |
11 | 11 | } |
12 | | - parent::__construct( $gateway, $form_errors ); |
| 12 | + parent::__construct( $gateway ); |
13 | 13 | } |
14 | 14 | |
15 | 15 | public function loadPlaceholders() { |
— | — | @@ -195,7 +195,7 @@ |
196 | 196 | |
197 | 197 | // amount |
198 | 198 | $form .= '<tr>'; |
199 | | - $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['invalidamount'] . '</span></td>'; |
| 199 | + $form .= '<td colspan="2"><span class="creditcard-error-msg">' . $this->form_errors['amount'] . '</span></td>'; |
200 | 200 | $form .= '</tr>'; |
201 | 201 | $form .= '<tr>'; |
202 | 202 | $form .= '<td colspan="2">'; |
Index: trunk/extensions/DonationInterface/gateway_forms/RapidHtml.php |
— | — | @@ -90,9 +90,9 @@ |
91 | 91 | '#emailAdd', |
92 | 92 | ); |
93 | 93 | |
94 | | - public function __construct( &$gateway, &$form_errors ) { |
| 94 | + public function __construct( &$gateway ) { |
95 | 95 | global $wgRequest; |
96 | | - parent::__construct( $gateway, $form_errors ); |
| 96 | + parent::__construct( $gateway ); |
97 | 97 | |
98 | 98 | $this->loadValidateJs(); |
99 | 99 | |
Index: trunk/extensions/DonationInterface/gateway_forms/TwoStepTwoColumnPremiumUS.php |
— | — | @@ -1,7 +1,7 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | class Gateway_Form_TwoStepTwoColumnPremiumUS extends Gateway_Form_TwoStepTwoColumn { |
5 | | - public function __construct( &$gateway, &$form_errors ) { |
| 5 | + public function __construct( &$gateway ) { |
6 | 6 | global $wgScriptPath; |
7 | 7 | |
8 | 8 | // set the path to css, before the parent constructor is called, checking to make sure some child class hasn't already set this |
— | — | @@ -9,7 +9,7 @@ |
10 | 10 | $this->setStylePath( $wgScriptPath . '/extensions/DonationInterface/gateway_forms/css/TwoStepTwoColumnPremiumUS.css' ); |
11 | 11 | } |
12 | 12 | |
13 | | - parent::__construct( $gateway, $form_errors ); |
| 13 | + parent::__construct( $gateway ); |
14 | 14 | } |
15 | 15 | |
16 | 16 | public function loadPlaceholders() { |
Index: trunk/extensions/DonationInterface/gateway_forms/OneStepTwoColumn.php |
— | — | @@ -2,8 +2,8 @@ |
3 | 3 | |
4 | 4 | class Gateway_Form_OneStepTwoColumn extends Gateway_Form { |
5 | 5 | |
6 | | - public function __construct( &$gateway, &$form_errors ) { |
7 | | - parent::__construct( $gateway, $form_errors ); |
| 6 | + public function __construct( &$gateway ) { |
| 7 | + parent::__construct( $gateway ); |
8 | 8 | |
9 | 9 | // update the list of hidden fields we need to use in this form. |
10 | 10 | $this->updateHiddenFields(); |
Index: trunk/extensions/DonationInterface/globalcollect_gateway/globalcollect_gateway.body.php |
— | — | @@ -86,12 +86,11 @@ |
87 | 87 | $payment_submethod = $this->adapter->getPaymentSubmethod(); |
88 | 88 | |
89 | 89 | // Check form for errors |
90 | | - $form_errors = $this->validateForm( $this->errors, $this->adapter->getPaymentSubmethodFormValidation() ); |
| 90 | + $form_errors = $this->validateForm( $this->adapter->getPaymentSubmethodFormValidation() ); |
91 | 91 | |
92 | 92 | // If there were errors, redisplay form, otherwise proceed to next step |
93 | 93 | if ( $form_errors ) { |
94 | | - |
95 | | - $this->displayForm( $this->errors ); |
| 94 | + $this->displayForm(); |
96 | 95 | } else { // The submitted form data is valid, so process it |
97 | 96 | // allow any external validators to have their way with the data |
98 | 97 | // Execute the proper transaction code: |
— | — | @@ -194,14 +193,16 @@ |
195 | 194 | |
196 | 195 | // If the result of the previous transaction was failure, set the retry message. |
197 | 196 | if ( $data && array_key_exists( 'response', $data ) && $data['response'] == 'failure' ) { |
198 | | - $this->errors['retryMsg'] = wfMsg( 'php-response-declined' ); |
| 197 | + $error['retryMsg'] = wfMsg( 'php-response-declined' ); |
| 198 | + $this->adapter->addManualError( $error ); |
199 | 199 | } |
200 | 200 | |
201 | | - $this->displayForm( $this->errors ); |
| 201 | + $this->displayForm(); |
202 | 202 | } |
203 | 203 | } else { //token mismatch |
204 | | - $this->errors['general']['token-mismatch'] = wfMsg( 'donate_interface-token-mismatch' ); |
205 | | - $this->displayForm( $this->errors ); |
| 204 | + $error['general']['token-mismatch'] = wfMsg( 'donate_interface-token-mismatch' ); |
| 205 | + $this->adapter->addManualError( $error ); |
| 206 | + $this->displayForm(); |
206 | 207 | } |
207 | 208 | } |
208 | 209 | |
Index: trunk/extensions/DonationInterface/gateway_common/DataValidator.php |
— | — | @@ -120,7 +120,33 @@ |
121 | 121 | return $error_token; |
122 | 122 | } |
123 | 123 | |
| 124 | + /** |
| 125 | + * getEmptyErrorArray |
| 126 | + * This only exists anymore, to make badly-coded forms happy when they start |
| 127 | + * pulling keys all over the place without checking to see if they're set or |
| 128 | + * not. |
| 129 | + * @return array All the possible error tokens as keys, with blank errors. |
| 130 | + */ |
| 131 | + public static function getEmptyErrorArray() { |
| 132 | + return array( |
| 133 | + 'general' => '', |
| 134 | + 'retryMsg' => '', |
| 135 | + 'amount' => '', |
| 136 | + 'card_num' => '', |
| 137 | + 'card_type' => '', |
| 138 | + 'cvv' => '', |
| 139 | + 'fname' => '', |
| 140 | + 'lname' => '', |
| 141 | + 'city' => '', |
| 142 | + 'country' => '', |
| 143 | + 'street' => '', |
| 144 | + 'state' => '', |
| 145 | + 'zip' => '', |
| 146 | + 'emailAdd' => '', |
| 147 | + ); |
| 148 | + } |
124 | 149 | |
| 150 | + |
125 | 151 | /** |
126 | 152 | * getErrorMessage - returns the translated error message appropriate for a |
127 | 153 | * validation error on the specified field, of the specified type. |
Index: trunk/extensions/DonationInterface/gateway_common/gateway.adapter.php |
— | — | @@ -1895,7 +1895,8 @@ |
1896 | 1896 | return get_called_class(); |
1897 | 1897 | } |
1898 | 1898 | |
1899 | | - public function setValidationErrors( $errors ) { |
| 1899 | + //only the gateway should be setting validation errors. Everybody else should set manual errors. |
| 1900 | + protected function setValidationErrors( $errors ) { |
1900 | 1901 | $this->validation_errors = $errors; |
1901 | 1902 | } |
1902 | 1903 | |
— | — | @@ -1907,6 +1908,35 @@ |
1908 | 1909 | } |
1909 | 1910 | } |
1910 | 1911 | |
| 1912 | + public function addManualError( $errors, $reset = false ) { |
| 1913 | + if ( $reset ){ |
| 1914 | + $this->manual_errors = array(); |
| 1915 | + return; |
| 1916 | + } |
| 1917 | + $this->manual_errors = array_merge( $this->manual_errors, $errors ); |
| 1918 | + } |
| 1919 | + |
| 1920 | + public function getManualErrors() { |
| 1921 | + if ( !empty( $this->manual_errors ) ) { |
| 1922 | + return $this->manual_errors; |
| 1923 | + } else { |
| 1924 | + return false; |
| 1925 | + } |
| 1926 | + } |
| 1927 | + |
| 1928 | + public function getAllErrors(){ |
| 1929 | + $validation = $this->getValidationErrors(); |
| 1930 | + $manual = $this->getManualErrors(); |
| 1931 | + $return = array(); |
| 1932 | + if ( is_array( $validation ) ){ |
| 1933 | + $return = array_merge( $return, $validation ); |
| 1934 | + } |
| 1935 | + if ( is_array( $manual ) ){ |
| 1936 | + $return = array_merge( $return, $manual ); |
| 1937 | + } |
| 1938 | + return $return; |
| 1939 | + } |
| 1940 | + |
1911 | 1941 | public function incrementNumAttempt() { |
1912 | 1942 | $this->dataObj->incrementNumAttempt(); |
1913 | 1943 | $this->refreshGatewayValueFromSource( 'numAttempt' ); |
— | — | @@ -2104,5 +2134,23 @@ |
2105 | 2135 | return $this->batch; |
2106 | 2136 | } |
2107 | 2137 | } |
| 2138 | + |
| 2139 | + public function getOriginalValidationErrors( ){ |
| 2140 | + return $this->dataObj->getValidationErrors(); |
| 2141 | + } |
| 2142 | + |
| 2143 | + //TODO: Maybe validate on $unstaged_data directly? |
| 2144 | + public function revalidate( $check_not_empty = array() ){ |
| 2145 | + $validation_errors = $this->dataObj->getValidationErrors( true, $check_not_empty ); |
| 2146 | + $this->setValidationErrors( $validation_errors ); |
| 2147 | + return $this->validatedOK(); |
| 2148 | + } |
2108 | 2149 | |
| 2150 | + public function validatedOK(){ |
| 2151 | + if ( $this->getValidationErrors() === false ){ |
| 2152 | + return true; |
| 2153 | + } |
| 2154 | + return false; |
| 2155 | + } |
| 2156 | + |
2109 | 2157 | } |
\ No newline at end of file |
Index: trunk/extensions/DonationInterface/gateway_common/DonationData.php |
— | — | @@ -17,7 +17,7 @@ |
18 | 18 | |
19 | 19 | protected $normalized = array( ); |
20 | 20 | public $boss; |
21 | | - protected $validationErrors = false; |
| 21 | + protected $validationErrors = null; |
22 | 22 | |
23 | 23 | /** |
24 | 24 | * DonationData constructor |
— | — | @@ -395,8 +395,8 @@ |
396 | 396 | $this->handleContributionTrackingID(); |
397 | 397 | $this->setCurrencyCode(); |
398 | 398 | $this->setFormClass(); |
399 | | - //TODO: Uncomment the next line when we want to start actually using the input validation. |
400 | | -// $this->validateAllInput(); |
| 399 | + |
| 400 | + $this->getValidationErrors(); |
401 | 401 | } |
402 | 402 | } |
403 | 403 | |
— | — | @@ -1294,388 +1294,35 @@ |
1295 | 1295 | } |
1296 | 1296 | |
1297 | 1297 | /** |
1298 | | - * validateAllInput |
| 1298 | + * getValidationErrors |
1299 | 1299 | * This function will go through all the data we have pulled from wherever |
1300 | 1300 | * we've pulled it, and make sure it's safe and expected and everything. |
| 1301 | + * If it is not, it will return an array of errors ready for any |
| 1302 | + * DonationInterface form class derivitive to display. |
1301 | 1303 | */ |
1302 | | - protected function validateAllInput(){ |
1303 | | - $rules = $this->buildValidationRules(); |
1304 | | - foreach ( $this->normalized as $key => $val ){ |
1305 | | - if ( $this->isSomething( $key ) ){ |
1306 | | - //make sure there's a rule for it. |
1307 | | - if ( !isset( $rules[$key] ) ){ |
1308 | | - $this->log( "Validate Error: There is no rule for $key!" ); |
1309 | | - //TODO: i18n |
1310 | | - $this->validate_setError( 'general', "Validate Error: There is no rule for $key!" ); |
1311 | | - } else { |
1312 | | - $function = $rules[$key]['validate_function']; |
1313 | | - if (method_exists( $this, $function )){ |
1314 | | - $this->{$function}( $key, $rules[$key]['error_form_token'] ); |
1315 | | - } else { |
1316 | | - $this->log( "Validate Error: There is no $function function!" ); |
1317 | | - //TODO: i18n |
1318 | | - $this->validate_setError( 'general', "Validate Error: There is no $function function!" ); |
1319 | | - } |
1320 | | - } |
1321 | | - |
1322 | | - } |
| 1304 | + public function getValidationErrors( $recalculate = false, $check_not_empty = array() ){ |
| 1305 | + if ( is_null( $this->validationErrors ) || $recalculate ) { |
| 1306 | + $this->validationErrors = DataValidator::validate( $this->normalized, $check_not_empty ); |
1323 | 1307 | } |
| 1308 | + return $this->validationErrors; |
1324 | 1309 | } |
1325 | 1310 | |
1326 | 1311 | /** |
1327 | | - * Builds the validation rule set for all the keys we're pulling. |
1328 | | - * TODO: Do some mapping here with i18n messages, too. We can't take this |
1329 | | - * into prod just throwing the generic at everything. |
1330 | | - * TODO: In general with this whole thing, the alphanumeric strategy should |
1331 | | - * be... revised. Clearly we can't have a list of 'good' characters. |
1332 | | - * Instead, we need to clean stuff that is clearly dangerous. |
1333 | | - * Also, maybe we just auto-assign the alphanumeric clean function to |
1334 | | - * anything that doesn't have other assignments, instead of dying nastily |
1335 | | - * when we have one with no assignment. That's probably more pleasant. |
1336 | | - * @return array An array of keys, the ways we want to validate them, and |
1337 | | - * what messages to set if they don't pass. |
1338 | | - * $array[$key] = array( |
1339 | | - * 'validate_function' => $function_name, |
1340 | | - * 'error_form_token' => $error_token, |
1341 | | - * |
1342 | | - * ) |
1343 | | - */ |
1344 | | - protected function buildValidationRules(){ |
1345 | | - $rules = array(); |
1346 | | - |
1347 | | - //you should group these jerks by type or something. |
1348 | | - |
1349 | | - //initial build based on general functions to run for validation. |
1350 | | - $numeric = array( |
1351 | | - 'amountGiven', |
1352 | | - 'amountOther', |
1353 | | - 'card_num', |
1354 | | - 'cvv', |
1355 | | - 'contribution_tracking_id', |
1356 | | - 'account_number', |
1357 | | - 'expiration', |
1358 | | - 'order_id', |
1359 | | - 'i_order_id', |
1360 | | - 'numAttempt' |
1361 | | - ); |
1362 | | - |
1363 | | - foreach ($numeric as $key){ |
1364 | | - $rules[$key]['validate_function'] = 'validate_numeric'; |
1365 | | - } |
1366 | | - |
1367 | | - $alphanumeric = array( |
1368 | | - 'fname', |
1369 | | - 'mname', |
1370 | | - 'lname', |
1371 | | - 'street', |
1372 | | - 'city', |
1373 | | - 'state', |
1374 | | - 'zip', |
1375 | | - 'country', |
1376 | | - 'fname2', |
1377 | | - 'lname2', |
1378 | | - 'street2', |
1379 | | - 'city2', |
1380 | | - 'state2', |
1381 | | - 'zip2', |
1382 | | - 'country2', |
1383 | | - 'size', |
1384 | | - 'premium_language', |
1385 | | - 'card_type', |
1386 | | - 'currency', |
1387 | | - 'currency_code', |
1388 | | - 'payment_method', |
1389 | | - 'payment_submethod', |
1390 | | - 'form_name', |
1391 | | - 'ffname', |
1392 | | - |
1393 | | - //for lack of a better idea what to do with these things, I'm just gonna leave these here. |
1394 | | - //If any of them need to be numeric or boolean or dealt with specially, do that. |
1395 | | - 'issuer_id', |
1396 | | - 'referrer', |
1397 | | - 'utm_source', |
1398 | | - 'utm_source_id', |
1399 | | - 'utm_medium', |
1400 | | - 'utm_campaign', |
1401 | | - 'language', |
1402 | | - 'uselang', |
1403 | | - 'comment', |
1404 | | - 'token', |
1405 | | - 'data_hash', |
1406 | | - 'action', |
1407 | | - 'gateway', |
1408 | | - 'owa_session', |
1409 | | - 'owa_ref', |
1410 | | - 'descriptor', |
1411 | | - 'account_name', |
1412 | | - 'authorization_id', |
1413 | | - 'bank_check_digit', |
1414 | | - 'bank_name', |
1415 | | - 'bank_code', |
1416 | | - 'branch_code', |
1417 | | - 'country_code_bank', |
1418 | | - 'date_collect', |
1419 | | - 'direct_debit_text', |
1420 | | - 'iban', |
1421 | | - 'transaction_type', |
1422 | | - ); |
1423 | | - |
1424 | | - foreach ($alphanumeric as $key){ |
1425 | | - $rules[$key]['validate_function'] = 'validate_alphanumeric_with_cleaning'; |
1426 | | - } |
1427 | | - |
1428 | | - $boolean = array( |
1429 | | - 'comment-option', |
1430 | | - 'email-opt', |
1431 | | - '_cache_', |
1432 | | - 'anonymous', |
1433 | | - 'optout', |
1434 | | - 'recurring', |
1435 | | - 'posted', |
1436 | | - ); |
1437 | | - |
1438 | | - foreach ($boolean as $key){ |
1439 | | - $rules[$key]['validate_function'] = 'validate_boolean'; |
1440 | | - } |
1441 | | - |
1442 | | - $rules['email']['validate_function'] = 'validate_email'; |
1443 | | - $rules['amount']['validate_amount'] = 'validate_amount'; |
1444 | | - |
1445 | | - |
1446 | | - //now, set the error token to use... |
1447 | | - |
1448 | | - foreach ( $rules as $key => $value ){ |
1449 | | - $error_token = 'general'; |
1450 | | - switch ( $key ) { |
1451 | | - case 'amountGiven' : |
1452 | | - case 'amountOther' : |
1453 | | - $error_token = 'amount'; |
1454 | | - break; |
1455 | | - case 'email' : |
1456 | | - $error_token = 'emailAdd'; |
1457 | | - break; |
1458 | | - case 'amount' : |
1459 | | - case 'card_num': |
1460 | | - case 'card_type': |
1461 | | - case 'cvv': |
1462 | | - case 'fname': |
1463 | | - case 'lname': |
1464 | | - case 'city': |
1465 | | - case 'country': |
1466 | | - case 'street': |
1467 | | - case 'state': |
1468 | | - case 'zip': |
1469 | | - $error_token = $key; |
1470 | | - break; |
1471 | | - } |
1472 | | - $rules[$key]['error_form_token'] = $error_token; |
1473 | | - } |
1474 | | - |
1475 | | - return $rules; |
1476 | | - } |
1477 | | - |
1478 | | - /** |
1479 | | - * Sets an error found during validation. |
1480 | | - * @param string $error_token The error token to set for this error. |
1481 | | - * (See RapidHTML::$error_tokens for possibilities) |
1482 | | - * @param string $msg The translated message to display at that error token. |
1483 | | - */ |
1484 | | - protected function validate_setError( $error_token, $msg ){ |
1485 | | - if ( !$this->validationErrors ){ |
1486 | | - $this->validationErrors = array(); |
1487 | | - } |
1488 | | - $this->validationErrors[$error_token] = $msg; |
1489 | | - |
1490 | | - } |
1491 | | - |
1492 | | - /** |
1493 | 1312 | * validatedOK |
1494 | 1313 | * Checks to see if the data validated ok (no errors). |
1495 | 1314 | * @return boolean True if no errors, false if errors exist. |
1496 | 1315 | */ |
1497 | 1316 | public function validatedOK() { |
1498 | | - if ( is_array( $this->validationErrors ) ){ |
1499 | | - return false; |
| 1317 | + if ( is_null( $this->validationErrors ) ){ |
| 1318 | + $this->getValidationErrors(); |
1500 | 1319 | } |
1501 | | - return true; |
1502 | | - } |
1503 | | - |
1504 | | - /** |
1505 | | - * getValidationErrors |
1506 | | - * Returns the errors set on data validation. |
1507 | | - * @return mixed Array if errors are set, else false. |
1508 | | - */ |
1509 | | - public function getValidationErrors() { |
1510 | | - return $this->validationErrors; |
1511 | | - } |
1512 | | - |
1513 | | - /** |
1514 | | - * validate_email |
1515 | | - * validateAllInput helper function |
1516 | | - * To validate any input value using this function, add a line to |
1517 | | - * $this->buildValidationRules() specifying the function name as the field |
1518 | | - * name's 'validate_function'. |
1519 | | - * @param string $key The name of the field to validate. |
1520 | | - * @param string $error_token As in RapidHTML, the pre-defined area of the |
1521 | | - * form in which to display the error. |
1522 | | - */ |
1523 | | - protected function validate_email( $key, $error_token ){ |
1524 | | - // is email address valid? |
1525 | | - $isEmail = User::isValidEmailAddr( $this->getVal($key) ); |
1526 | | - |
1527 | | - // create error message (supercedes empty field message) |
1528 | | - if ( !$isEmail ) { |
1529 | | - $this->log( __FUNCTION__ . " $key is not an email address.", LOG_DEBUG ); |
1530 | | - $this->validate_setError( $error_token, wfMsg( 'donate_interface-error-msg-email' ) ); |
1531 | | - } |
1532 | | - } |
1533 | | - |
1534 | | - /** |
1535 | | - * validate_amount |
1536 | | - * validateAllInput helper function |
1537 | | - * To validate any input value using this function, add a line to |
1538 | | - * $this->buildValidationRules() specifying the function name as the field |
1539 | | - * name's 'validate_function'. |
1540 | | - * @param string $key The name of the field to validate. |
1541 | | - * @param string $error_token As in RapidHTML, the pre-defined area of the |
1542 | | - * form in which to display the error. |
1543 | | - */ |
1544 | | - protected function validate_amount( $key, $error_token ){ |
1545 | | - if ( !$this->isSomething( $key ) ) { |
1546 | | - $this->log( __FUNCTION__ . " $key is not something.", LOG_DEBUG ); |
1547 | | - $this->validate_setError( $error_token, wfMsg( 'donate_interface-error-msg-invalid-amount' ) ); |
1548 | | - return; |
1549 | | - } |
1550 | 1320 | |
1551 | | - if ( !$this->isSomething( 'currency_code' ) ) { |
1552 | | - $this->log( __FUNCTION__ . " currency_code is not something.", LOG_DEBUG ); |
1553 | | - $this->validate_setError( $error_token, wfMsg( 'donate_interface-error-msg-general' ) ); |
1554 | | - return; |
| 1321 | + if ( count( $this->validationErrors ) === 0 ){ |
| 1322 | + return true; |
1555 | 1323 | } |
1556 | | - $currency_code = $this->getVal( 'currency_code' ); |
1557 | | - |
1558 | | - $val = $this->getVal( $key ); |
1559 | | - if ( !is_numeric( $val ) ) { |
1560 | | - $this->log( __FUNCTION__ . " $key is not valid numeric format. $val", LOG_DEBUG ); |
1561 | | - $this->validate_setError( $error_token, wfMsg( 'donate_interface-error-msg-invalid-amount' ) ); |
1562 | | - } |
1563 | | - |
1564 | | - // check amount |
1565 | | - $priceFloor = $this->adapter->getGlobal( 'PriceFloor' ); |
1566 | | - $priceCeiling = $this->adapter->getGlobal( 'PriceCeiling' ); |
1567 | | - if ( !preg_match( '/^\d+(\.(\d+)?)?$/', $val ) || |
1568 | | - ( ( float ) $this->convert_to_usd( $currency_code, $val ) < ( float ) $priceFloor || |
1569 | | - ( float ) $this->convert_to_usd( $currency_code, $val ) > ( float ) $priceCeiling ) ) { |
1570 | | - $this->validate_setError( $error_token, wfMsg( 'donate_interface-error-msg-invalid-amount' ) ); |
1571 | | - } |
| 1324 | + return false; |
1572 | 1325 | } |
1573 | 1326 | |
1574 | | - /** |
1575 | | - * validate_boolean |
1576 | | - * validateAllInput helper function |
1577 | | - * To validate any input value using this function, add a line to |
1578 | | - * $this->buildValidationRules() specifying the function name as the field |
1579 | | - * name's 'validate_function'. |
1580 | | - * @param string $key The name of the field to validate. |
1581 | | - * @param string $error_token As in RapidHTML, the pre-defined area of the |
1582 | | - * form in which to display the error. |
1583 | | - */ |
1584 | | - protected function validate_boolean( $key, $error_token ){ |
1585 | | - $val = $this->getVal($key); |
1586 | | - switch ($val) { |
1587 | | - case 0: |
1588 | | - case '0': |
1589 | | - case false: |
1590 | | - case 'false': |
1591 | | - $this->setVal( $key, 0 ); |
1592 | | - break; |
1593 | | - case 1: |
1594 | | - case '1': |
1595 | | - case true: |
1596 | | - case 'true': |
1597 | | - $this->setVal( $key, 1 ); |
1598 | | - break; |
1599 | | - default: |
1600 | | - $this->log( __FUNCTION__ . " $key is not boolean." ); |
1601 | | - $this->validate_setError( $error_token, wfMsg( 'donate_interface-error-msg-general' ), LOG_DEBUG ); |
1602 | | - break; |
1603 | | - } |
1604 | | - |
1605 | | - } |
1606 | | - |
1607 | | - /** |
1608 | | - * validate_alphanumeric_with_cleaning |
1609 | | - * validateAllInput helper function |
1610 | | - * To validate and clean any input value using this function, add a line to |
1611 | | - * $this->buildValidationRules() specifying the function name as the field |
1612 | | - * name's 'validate_function'. |
1613 | | - * TODO: Something even remotely useful here. Like the cleaning promised in |
1614 | | - * the function name. |
1615 | | - * @param string $key The name of the field to validate. |
1616 | | - * @param string $error_token As in RapidHTML, the pre-defined area of the |
1617 | | - * form in which to display the error. |
1618 | | - */ |
1619 | | - protected function validate_alphanumeric_with_cleaning( $key, $error_token ){ |
1620 | | - $val = $this->getVal($key); |
1621 | | - |
1622 | | - //instead of validating here, we should probably be proactively removing badness. |
1623 | | - if ( preg_match( '/%/', $val ) ) { //this is dumb and bad. Fixit. |
1624 | | - $this->log( __FUNCTION__ . " $key is not valid alphanumeric. $val", LOG_DEBUG ); |
1625 | | - //oooh. This blows. |
1626 | | - $this->validate_setError( $error_token, wfMsg( 'donate_interface-error-msg-general' ) ); |
1627 | | - } |
1628 | | - } |
1629 | | - |
1630 | | - /** |
1631 | | - * validate_numeric |
1632 | | - * validateAllInput helper function |
1633 | | - * To validate any input value using this function, add a line to |
1634 | | - * $this->buildValidationRules() specifying the function name as the field |
1635 | | - * name's 'validate_function'. |
1636 | | - * @param string $key The name of the field to validate. |
1637 | | - * @param string $error_token As in RapidHTML, the pre-defined area of the |
1638 | | - * form in which to display the error. |
1639 | | - */ |
1640 | | - protected function validate_numeric( $key, $error_token ){ |
1641 | | - $val = $this->getVal($key); |
1642 | | - |
1643 | | - //instead of validating here, we should probably be doing something else entirely. |
1644 | | - if ( !is_numeric( $val ) ) { |
1645 | | - $this->log( __FUNCTION__ . " $key is not valid numeric format. $val", LOG_DEBUG ); |
1646 | | - //oooh. This blows. |
1647 | | - $this->validate_setError( $error_token, wfMsg( 'donate_interface-error-msg-general' ) ); |
1648 | | - } |
1649 | | - } |
1650 | | - |
1651 | | - /** |
1652 | | - * Convert an amount for a particular currency to an amount in USD |
1653 | | - * |
1654 | | - * This is grosley rudimentary and likely wildly inaccurate. |
1655 | | - * This mimicks the hard-coded values used by the WMF to convert currencies |
1656 | | - * for validatoin on the front-end on the first step landing pages of their |
1657 | | - * donation process - the idea being that we can get a close approximation |
1658 | | - * of converted currencies to ensure that contributors are not going above |
1659 | | - * or below the price ceiling/floor, even if they are using a non-US currency. |
1660 | | - * |
1661 | | - * In reality, this probably ought to use some sort of webservice to get real-time |
1662 | | - * conversion rates. |
1663 | | - * |
1664 | | - * @param string $currency_code |
1665 | | - * @param float $amount |
1666 | | - * @return float |
1667 | | - */ |
1668 | | - static function convert_to_usd( $currency_code, $amount ) { |
1669 | | - require_once( dirname( __FILE__ ) . '/currencyRates.inc' ); |
1670 | | - $rates = getCurrencyRates(); |
1671 | | - $code = strtoupper( $currency_code ); |
1672 | | - if ( array_key_exists( $code, $rates ) ) { |
1673 | | - $usd_amount = $amount / $rates[$code]; |
1674 | | - } else { |
1675 | | - $usd_amount = $amount; |
1676 | | - } |
1677 | | - return $usd_amount; |
1678 | | - } |
1679 | | - |
1680 | 1327 | } |
1681 | 1328 | |
1682 | 1329 | ?> |
Index: trunk/extensions/DonationInterface/gateway_common/GatewayForm.php |
— | — | @@ -48,265 +48,85 @@ |
49 | 49 | public function __construct() { |
50 | 50 | $me = get_called_class(); |
51 | 51 | parent::__construct( $me ); |
52 | | - $this->errors = $this->getPossibleErrors(); |
53 | 52 | } |
54 | 53 | |
55 | 54 | /** |
56 | | - * Checks posted form data for errors and returns array of messages |
57 | | - * |
58 | | - * @param array $data Reference to the data of the form |
59 | | - * @param array $error Reference to the error messages of the form |
| 55 | + * Checks current dataset for validation errors |
| 56 | + * TODO: As with every other bit of gateway-related logic that should |
| 57 | + * definitely be available to every entry point, and functionally has very |
| 58 | + * little to do with being contained within what in an ideal world would be |
| 59 | + * a piece of mostly UI, this function needs to be moved inside the gateway |
| 60 | + * adapter class. |
60 | 61 | * @param array $options |
61 | | - * OPTIONAL - You may require certain field groups to be validated |
62 | | - * - address - Validates: street, city, state, zip |
63 | | - * - amount - Validates: amount |
64 | | - * - creditCard - Validates: card_num, cvv, expiration and sets the card |
65 | | - * - email - Validates: email |
66 | | - * - name - Validates: fname, lname |
| 62 | + * OPTIONAL - In addition to all non-optional validation which verifies |
| 63 | + * that all populated fields contain an appropriate data type, you may |
| 64 | + * require certain field groups to be non-empty. |
| 65 | + * - address - Validation requires non-empty: street, city, state, zip |
| 66 | + * - amount - Validation requires non-empty: amount |
| 67 | + * - creditCard - Validation requires non-empty: card_num, cvv, expiration and card_type |
| 68 | + * - email - Validation requires non-empty: email |
| 69 | + * - name - Validation requires non-empty: fname, lname |
67 | 70 | * |
68 | | - * @return 0|1 Returns 0 on success and 1 on failure |
| 71 | + * @return boolean Returns true on an error-free validation, otherwise false. |
69 | 72 | */ |
70 | | - public function validateForm( &$error, $options = array() ) { |
| 73 | + public function validateForm( $options = array() ) { |
71 | 74 | |
72 | | - $data = $this->adapter->getData_Unstaged_Escaped(); |
| 75 | + $check_not_empty = array(); |
73 | 76 | |
74 | | - extract( $options ); |
75 | | - |
76 | | - // Set which items will be validated |
77 | | - $address = isset( $address ) ? ( boolean ) $address : true; |
78 | | - $amount = isset( $amount ) ? ( boolean ) $amount : true; |
79 | | - $creditCard = isset( $creditCard ) ? ( boolean ) $creditCard : false; |
80 | | - $email = isset( $email ) ? ( boolean ) $email : true; |
81 | | - $name = isset( $name ) ? ( boolean ) $name : true; |
82 | | - |
83 | | - // These are set in the order they will most likely appear on the form. |
84 | | - |
85 | | - if ( $name ) { |
86 | | - $this->validateName( $data, $error ); |
| 77 | + foreach ( $options as $option ){ |
| 78 | + $add_checks = array(); |
| 79 | + switch( $option ){ |
| 80 | + case 'address' : |
| 81 | + $add_checks = array( |
| 82 | + 'street', |
| 83 | + 'city', |
| 84 | + 'state', |
| 85 | + 'country', |
| 86 | + 'zip', //this should really be added or removed, depending on the country and/or gateway requirements. |
| 87 | + //however, that's not happening in this class in the code I'm replacing, so... |
| 88 | + //TODO: Something clever in the DataValidator with data groups like these. |
| 89 | + ); |
| 90 | + break; |
| 91 | + case 'amount' : |
| 92 | + $add_checks[] = 'amount'; |
| 93 | + break; |
| 94 | + case 'creditCard' : |
| 95 | + $add_checks = array( |
| 96 | + 'card_num', |
| 97 | + 'cvv', |
| 98 | + 'expiration', |
| 99 | + 'card_type' |
| 100 | + ); |
| 101 | + break; |
| 102 | + case 'email' : |
| 103 | + $add_checks[] = 'email'; |
| 104 | + break; |
| 105 | + case 'name' : |
| 106 | + $add_checks = array( |
| 107 | + 'fname', |
| 108 | + 'lname' |
| 109 | + ); |
| 110 | + break; |
| 111 | + } |
| 112 | + $check_not_empty = array_merge( $check_not_empty, $add_checks ); |
87 | 113 | } |
88 | | - |
89 | | - if ( $address ) { |
90 | | - $this->validateAddress( $data, $error ); |
91 | | - } |
92 | | - |
93 | | - if ( $amount ) { |
94 | | - $this->validateAmount( $data, $error ); |
95 | | - } |
96 | | - |
97 | | - if ( $email ) { |
98 | | - $this->validateEmail( $data, $error ); |
99 | | - } |
100 | | - |
101 | | - if ( $creditCard ) { |
102 | | - $this->validateCreditCard( $data, $error ); |
103 | | - } |
104 | | - |
105 | | - /* |
106 | | - * $error_result would return 0 on success, 1 on failure. |
107 | | - * |
108 | | - * This is done for backward compatibility. |
109 | | - */ |
110 | | - return $this->getValidateFormResult() ? 0 : 1; |
111 | | - } |
112 | | - |
113 | | - /** |
114 | | - * Validates the address |
115 | | - * |
116 | | - * Required: |
117 | | - * - street |
118 | | - * - city |
119 | | - * - state |
120 | | - * - zip |
121 | | - * - country |
122 | | - * |
123 | | - * @param array $data Reference to the data of the form |
124 | | - * @param array $error Reference to the error messages of the form |
125 | | - * |
126 | | - * @see GatewayForm::validateForm() |
127 | | - */ |
128 | | - public function validateAddress( &$data, &$error ) { |
129 | | - |
130 | | - if ( empty( $data['street'] ) ) { |
131 | | - |
132 | | - $error['street'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-street' ) ); |
133 | | - |
134 | | - $this->setValidateFormResult( false ); |
135 | | - } |
136 | | - |
137 | | - if ( empty( $data['city'] ) ) { |
138 | | - |
139 | | - $error['city'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-city' ) ); |
140 | | - |
141 | | - $this->setValidateFormResult( false ); |
142 | | - } |
143 | | - |
144 | | - if ( empty( $data['state'] ) || $data['state'] == 'YY' ) { |
145 | | - |
146 | | - $error['state'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-state-province' ) ); |
147 | | - |
148 | | - $this->setValidateFormResult( false ); |
149 | | - } |
150 | | - |
151 | | - if ( empty( $data['country'] ) || !array_key_exists( $data['country'], $this->getCountries() )) { |
152 | | - |
153 | | - $error['country'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-country' ) ); |
154 | | - |
155 | | - $this->setValidateFormResult( false ); |
156 | | - } |
157 | | - |
158 | | - $ignoreCountries = array(); |
159 | 114 | |
160 | | - if ( empty( $data['zip'] ) && !in_array( $data['country'], $ignoreCountries ) ) { |
| 115 | + $validate_errors = $this->adapter->revalidate( $check_not_empty ); |
161 | 116 | |
162 | | - $error['zip'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-zip' ) ); |
163 | | - |
164 | | - $this->setValidateFormResult( false ); |
165 | | - } |
| 117 | + return $validate_errors; |
166 | 118 | } |
167 | 119 | |
168 | 120 | /** |
169 | | - * Validates the amount contributed |
170 | | - * |
171 | | - * @param array $data Reference to the data of the form |
172 | | - * @param array $error Reference to the error messages of the form |
173 | | - * |
174 | | - * @see GatewayForm::validateForm() |
175 | | - */ |
176 | | - public function validateAmount( &$data, &$error ) { |
177 | | - |
178 | | - if ( empty( $data['amount'] ) ) { |
179 | | - |
180 | | - $error['amount'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-amount' ) ); |
181 | | - |
182 | | - $this->setValidateFormResult( false ); |
183 | | - } |
184 | | - |
185 | | - // check amount |
186 | | - $priceFloor = $this->adapter->getGlobal( 'PriceFloor' ); |
187 | | - $priceCeiling = $this->adapter->getGlobal( 'PriceCeiling' ); |
188 | | - if ( !preg_match( '/^\d+(\.(\d+)?)?$/', $data['amount'] ) || |
189 | | - ( ( float ) $this->convert_to_usd( $data['currency_code'], $data['amount'] ) < ( float ) $priceFloor || |
190 | | - ( float ) $this->convert_to_usd( $data['currency_code'], $data['amount'] ) > ( float ) $priceCeiling ) ) { |
191 | | - |
192 | | - $error['invalidamount'] = wfMsg( 'donate_interface-error-msg-invalid-amount' ); |
193 | | - |
194 | | - $this->setValidateFormResult( false ); |
195 | | - } |
196 | | - } |
197 | | - |
198 | | - /** |
199 | | - * Validates a credit card |
200 | | - * |
201 | | - * @param array $data Reference to the data of the form |
202 | | - * @param array $error Reference to the error messages of the form |
203 | | - * |
204 | | - * @see GatewayForm::validateForm() |
205 | | - */ |
206 | | - public function validateCreditCard( &$data, &$error ) { |
207 | | - |
208 | | - if ( empty( $data['card_num'] ) ) { |
209 | | - |
210 | | - $error['card_num'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-card_num' ) ); |
211 | | - |
212 | | - $this->setValidateFormResult( false ); |
213 | | - } |
214 | | - |
215 | | - if ( empty( $data['cvv'] ) ) { |
216 | | - |
217 | | - $error['cvv'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-cvv' ) ); |
218 | | - |
219 | | - $this->setValidateFormResult( false ); |
220 | | - } |
221 | | - |
222 | | - if ( empty( $data['expiration'] ) ) { |
223 | | - |
224 | | - $error['expiration'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-expiration' ) ); |
225 | | - |
226 | | - $this->setValidateFormResult( false ); |
227 | | - } |
228 | | - |
229 | | - // validate that credit card number entered is correct and set the card type |
230 | | - if ( preg_match( '/^3[47][0-9]{13}$/', $data['card_num'] ) ) { // american express |
231 | | - $data['card'] = 'american'; |
232 | | - } elseif ( preg_match( '/^5[1-5][0-9]{14}$/', $data['card_num'] ) ) { // mastercard |
233 | | - $data['card'] = 'mastercard'; |
234 | | - } elseif ( preg_match( '/^4[0-9]{12}(?:[0-9]{3})?$/', $data['card_num'] ) ) {// visa |
235 | | - $data['card'] = 'visa'; |
236 | | - } elseif ( preg_match( '/^6(?:011|5[0-9]{2})[0-9]{12}$/', $data['card_num'] ) ) { // discover |
237 | | - $data['card'] = 'discover'; |
238 | | - } else { // an invalid credit card number was entered |
239 | | - $error['card_num'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-card-num' ) ); |
240 | | - |
241 | | - $this->setValidateFormResult( false ); |
242 | | - } |
243 | | - } |
244 | | - |
245 | | - /** |
246 | | - * Validates an email address. |
247 | | - * |
248 | | - * @param array $data Reference to the data of the form |
249 | | - * @param array $error Reference to the error messages of the form |
250 | | - * |
251 | | - * @see GatewayForm::validateForm() |
252 | | - */ |
253 | | - public function validateEmail( &$data, &$error ) { |
254 | | - |
255 | | - if ( empty( $data['email'] ) ) { |
256 | | - |
257 | | - $error['email'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-email-empty' ) ); |
258 | | - |
259 | | - $this->setValidateFormResult( false ); |
260 | | - } |
261 | | - |
262 | | - // is email address valid? |
263 | | - $isEmail = User::isValidEmailAddr( $data['email'] ); |
264 | | - |
265 | | - // create error message (supercedes empty field message) |
266 | | - if ( !$isEmail ) { |
267 | | - $error['email'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-email' ) ); |
268 | | - |
269 | | - $this->setValidateFormResult( false ); |
270 | | - } |
271 | | - } |
272 | | - |
273 | | - /** |
274 | | - * Validates the name |
275 | | - * |
276 | | - * @param array $data Reference to the data of the form |
277 | | - * @param array $error Reference to the error messages of the form |
278 | | - * |
279 | | - * @see GatewayForm::validateForm() |
280 | | - */ |
281 | | - public function validateName( &$data, &$error ) { |
282 | | - |
283 | | - if ( empty( $data['fname'] ) ) { |
284 | | - |
285 | | - $error['fname'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-fname' ) ); |
286 | | - |
287 | | - $this->setValidateFormResult( false ); |
288 | | - } |
289 | | - |
290 | | - if ( empty( $data['lname'] ) ) { |
291 | | - |
292 | | - $error['lname'] = wfMsg( 'donate_interface-error-msg', wfMsg( 'donate_interface-error-msg-lname' ) ); |
293 | | - |
294 | | - $this->setValidateFormResult( false ); |
295 | | - } |
296 | | - } |
297 | | - |
298 | | - /** |
299 | 121 | * Build and display form to user |
300 | 122 | * |
301 | | - * @param $error Array: array of error messages returned by validate_form function |
302 | | - * |
303 | 123 | * The message at the top of the form can be edited in the payflow_gateway.i18n.php file |
304 | 124 | */ |
305 | | - public function displayForm( &$error ) { |
| 125 | + public function displayForm() { |
306 | 126 | global $wgOut; |
307 | 127 | |
308 | 128 | $form_class = $this->getFormClass(); |
309 | 129 | if ( $form_class && class_exists( $form_class ) ){ |
310 | | - $form_obj = new $form_class( $this->adapter, $error ); |
| 130 | + $form_obj = new $form_class( $this->adapter ); |
311 | 131 | $form = $form_obj->getForm(); |
312 | 132 | $wgOut->addHTML( $form ); |
313 | 133 | } else { |
— | — | @@ -385,25 +205,6 @@ |
386 | 206 | } |
387 | 207 | } |
388 | 208 | |
389 | | - public function getPossibleErrors() { |
390 | | - return array( |
391 | | - 'general' => '', |
392 | | - 'retryMsg' => '', |
393 | | - 'invalidamount' => '', |
394 | | - 'card_num' => '', |
395 | | - 'card_type' => '', |
396 | | - 'cvv' => '', |
397 | | - 'fname' => '', |
398 | | - 'lname' => '', |
399 | | - 'city' => '', |
400 | | - 'country' => '', |
401 | | - 'street' => '', |
402 | | - 'state' => '', |
403 | | - 'zip' => '', |
404 | | - 'emailAdd' => '', |
405 | | - ); |
406 | | - } |
407 | | - |
408 | 209 | /** |
409 | 210 | * Convert an amount for a particular currency to an amount in USD |
410 | 211 | * |
— | — | @@ -451,7 +252,8 @@ |
452 | 253 | // if we don't have a URL enabled throw a graceful error to the user |
453 | 254 | if ( !strlen( $this->adapter->getGlobal( 'PaypalURL' ) ) ) { |
454 | 255 | $gateway_identifier = $this->adapter->getIdentifier(); |
455 | | - $this->errors['general']['nopaypal'] = wfMsg( $gateway_identifier . '_gateway-error-msg-nopaypal' ); |
| 256 | + $error['general']['nopaypal'] = wfMsg( $gateway_identifier . '_gateway-error-msg-nopaypal' ); |
| 257 | + $this->adapter->addManualError( $error ); |
456 | 258 | return; |
457 | 259 | } |
458 | 260 | // submit the data to the paypal redirect URL |
— | — | @@ -534,21 +336,19 @@ |
535 | 337 | // Display debugging results |
536 | 338 | $this->displayResultsForDebug(); |
537 | 339 | |
538 | | - $this->errors['general'] = ( !isset( $this->errors['general'] ) || empty( $this->errors['general'] ) ) ? array() : (array) $this->errors['general']; |
539 | | - |
540 | | - $this->errors['retryMsg'] = ( !isset( $this->errors['retryMsg'] ) || empty( $this->errors['retryMsg'] ) ) ? array() : (array) $this->errors['retryMsg']; |
541 | | - |
542 | 340 | foreach ( $this->adapter->getTransactionErrors() as $code => $message ) { |
543 | 341 | |
| 342 | + $error = array(); |
544 | 343 | if ( strpos( $code, 'internal' ) === 0 ) { |
545 | | - $this->errors['retryMsg'][ $code ] = $message; |
| 344 | + $error['retryMsg'][ $code ] = $message; |
546 | 345 | } |
547 | 346 | else { |
548 | | - $this->errors['general'][ $code ] = $message; |
| 347 | + $error['general'][ $code ] = $message; |
549 | 348 | } |
| 349 | + $this->adapter->addManualError( $error ); |
550 | 350 | } |
551 | 351 | |
552 | | - return $this->displayForm( $this->errors ); |
| 352 | + return $this->displayForm(); |
553 | 353 | } |
554 | 354 | |
555 | 355 | } |