3use LightnCandy\LightnCandy;
5use SmashPig\Core\PaymentError;
6use SmashPig\Core\ValidationError;
57 if ( $replacements ) {
58 self::$messageReplacements = $replacements;
70 self::$country = $data[
'country'];
75 self::$fieldErrors = $data[
'errors'][
'field'];
77 $hookContainer = MediaWikiServices::getInstance()->getHookContainer();
79 'AlterPaymentFormData',
81 [
'abortable' =>
false ]
86 'l10n' =>
'Gateway_Form_Mustache::l10n',
87 'fieldError' =>
'Gateway_Form_Mustache::fieldError',
92 'options' => LightnCandy::FLAG_RUNTIMEPARTIAL,
98 $data = $this->gateway->getData_Unstaged_Escaped();
99 $output = $this->gatewayPage->getContext()->getOutput();
103 $data[
'template_trail'] =
"<!-- Generated from: $relativePath -->";
106 $redirect = $this->gateway->getGlobal(
'NoScriptRedirect' );
107 $data[
'no_script_redirect'] = $redirect;
110 $appealWikiTemplate = $this->gateway->getGlobal(
'AppealWikiTemplate' );
111 $appealWikiTemplate = str_replace(
'$appeal', $data[
'appeal'], $appealWikiTemplate );
112 $appealWikiTemplate = str_replace(
'$language', $data[
'language'], $appealWikiTemplate );
113 $data[
'appeal_text'] = $output->parseAsContent(
'{{' . $appealWikiTemplate .
'}}' );
114 $data[
'is_cc'] = ( $this->gateway->getPaymentMethod() ===
'cc' );
117 $tax_ded_countries = $this->gateway->getGlobal(
'TaxDedCountries' );
118 $data[
'is_tax_ded'] = in_array( $data[
'country'], $tax_ded_countries );
119 if ( $data[
'is_tax_ded'] ) {
121 $data[
'country_full'] = $countries[$data[
'country']];
127 RequestContext::getMain()->getRequest()->getBool(
'debugMonthlyConvert' ) ||
128 ( $this->gateway->showMonthlyConvert() && $this->gatewayPage->supportsMonthlyConvert )
130 $data[
'monthly_convert'] =
true;
137 $data[
'show_continue'] = $this->gatewayPage->showContinueButton();
138 $data[
'recurring'] = (bool)$data[
'recurring'];
145 if ( !isset( $data[
'opt_in'] ) || $data[
'opt_in'] ===
'' ) {
148 $hasValidValue =
false;
149 switch ( (
string)$data[
'opt_in'] ) {
151 $data[
'opted_in'] =
true;
152 $hasValidValue =
true;
155 $data[
'opted_out'] =
true;
156 $hasValidValue =
true;
164 $logger->warning(
"Invalid opt_in value {$data['opt_in']}" );
173 $dataSources = $this->gateway->getDataSources();
174 if ( $hasValidValue && $dataSources[
'opt_in'] ===
'get' ) {
176 $data[
'opt_in_visible'] =
false;
181 if ( !$this->gatewayPage->showSubmethodButtons() ) {
182 $data[
'show_submethods'] =
false;
186 $availableSubmethods = $this->gateway->getAvailableSubmethods();
187 $showPresetSubmethod = !empty( $data[
'payment_submethod'] ) &&
188 array_key_exists( $data[
'payment_submethod'], $availableSubmethods );
192 if ( $this->gateway->getDataSources()[
'payment_submethod'] !=
'get'
193 && $showPresetSubmethod ) {
194 $showPresetSubmethod =
false;
197 $showMultipleSubmethods = ( !$showPresetSubmethod && count( $availableSubmethods ) > 1 );
198 $showSingleSubmethod = count( $availableSubmethods ) == 1;
200 if ( $showMultipleSubmethods ) {
201 $data[
'show_submethods'] =
true;
203 $data[
'submethods'] = [];
204 foreach ( $availableSubmethods as $key => $submethod ) {
205 $submethod[
'key'] = $key;
206 if ( isset( $submethod[
'logo'] ) ) {
207 $submethod[
'logo'] = $this->
getImagePath( $submethod[
'logo'] );
209 $submethod[
'srcset'] = $this->
getSrcSet( $submethod );
210 $data[
'submethods'][] = $submethod;
213 $data[
'button_class'] = count( $data[
'submethods'] ) % 4 === 0
216 } elseif ( $showSingleSubmethod || $showPresetSubmethod ) {
218 $submethodName = ( $showPresetSubmethod ) ? $data[
'payment_submethod'] :
219 array_keys( $availableSubmethods )[0];
220 $submethod = $availableSubmethods[$submethodName];
221 $data[
'submethod'] = $submethodName;
223 if ( isset( $submethod[
'logo'] ) &&
224 ( $showPresetSubmethod || !empty( $submethod[
'show_single_logo'] ) ) ) {
225 $data[
'show_single_submethod'] =
true;
226 $data[
'submethod_label_key'] = $submethod[
'label_key'] ??
false;
227 $data[
'submethod_label'] = $submethod[
'label'] ??
false;
228 $data[
'submethod_logo'] = $this->
getImagePath( $submethod[
'logo'] );
229 $data[
'submethod_srcset'] = $this->
getSrcSet( $submethod );
232 if ( isset( $submethod[
'issuerids'] ) ) {
233 $data[
'show_issuers'] =
true;
234 $data[
'issuers'] = [];
235 foreach ( $submethod[
'issuerids'] as $code => $label ) {
236 $data[
'issuers'][] = [
246 if ( empty( $submethod[
'logo_hd'] ) ) {
250 foreach ( $submethod[
'logo_hd'] as $scale => $filename ) {
252 $srcSet[] =
"$path $scale";
254 return 'srcset="' . implode(
',', $srcSet ) .
'" ';
266 $outside_personal_block = [
270 $show_personal_block =
false;
271 $address_field_count = 0;
272 $fields = $this->gateway->getFormFields();
273 foreach ( $fields as $field =>
$type ) {
274 if (
$type ===
false ) {
279 if ( in_array(
$type, [
true,
'optional' ],
true ) ) {
280 $data[
"{$field}_visible"] =
true;
281 if ( in_array( $field, $address_fields ) ) {
282 $data[
"address_visible"] =
true;
283 if ( $field !==
'street_address' ) {
285 $address_field_count++;
290 if (
$type ===
true ) {
291 $data[
"{$field}_required"] =
true;
292 if ( in_array( $field, $address_fields ) ) {
293 $data[
"address_required"] =
true;
298 if ( !in_array( $field, $outside_personal_block ) ) {
299 $show_personal_block =
true;
303 $data[
'show_personal_fields'] = $show_personal_block;
307 $surnameFirstCountries = $this->gateway->getGlobal(
'SurnameFirstCountries' );
308 if ( in_array( $data[
'country'], $surnameFirstCountries ) ) {
309 $data[
'show_surname_first'] =
true;
314 if ( !empty( $data[
"address_visible"] ) ) {
321 $data[
'address_css_class'] = $classes[$address_field_count];
323 if ( !empty( $data[
"state_province_visible"] ) ) {
331 $data[
'state_province_options'] = [];
333 foreach ( $state_list as $abbr => $name ) {
334 $selected = isset( $data[
'state_province'] )
335 && $data[
'state_province'] === $abbr;
337 $data[
'state_province_options'][] = [
340 'selected' => $selected,
346 $supportedCurrencies = $this->gateway->getCurrencies();
347 if ( count( $supportedCurrencies ) === 1 ) {
348 $data[
'show_currency_selector'] =
false;
351 $data[
'currency'] = $supportedCurrencies[0];
353 $data[
'show_currency_selector'] =
true;
355 foreach ( $supportedCurrencies as $currency ) {
356 $data[
'currencies'][] = [
358 'selected' => ( $currency === $data[
'currency'] ),
365 $data[
'language'] .
'_' . $data[
'country']
367 if ( floatval( $data[
'amount'] ) === 0.0 ) {
368 $data[
'amount'] =
'';
379 $errors = $this->gateway->getErrorState()->getErrors();
380 $return = [
'errors' => [
385 foreach ( $errors as $error ) {
386 if ( $error instanceof ValidationError ) {
387 $key = $error->getField();
390 $error->getMessageKey(),
392 RequestContext::getMain()->getLanguage()->getCode(),
393 $error->getMessageParams()
395 } elseif ( $error instanceof PaymentError ) {
396 $key = $error->getErrorCode();
397 $message = $this->gateway->getErrorMapByCodeAndTranslate( $error->getErrorCode() );
399 throw new RuntimeException(
"Unknown error type: " . var_export( $error,
true ) );
404 'message' => $message,
407 if ( in_array( $key, $fieldNames ) ) {
408 $return[
'errors'][
'field'][$key] = $errorContext;
410 $return[
'errors'][
'general'][] = $errorContext;
412 $return[
"{$key}_error"] =
true;
415 if ( $key ===
'currency' || $key ===
'amount' ) {
416 $return[
'show_amount_input'] =
true;
418 if ( !empty( $return[
'errors'][
'general'] ) ) {
419 $return[
'show_error_reference'] =
true;
427 'problems' =>
'Problems',
428 'otherways' =>
'OtherWays',
434 foreach ( $map as $contextName => $globalName ) {
435 $urlsAndEmails[$contextName .
'_url'] = htmlspecialchars(
436 $this->gateway->localizeGlobal( $globalName .
'URL' )
439 $urlsAndEmails[
'problems_email'] = $this->gateway->getGlobal(
'ProblemsEmail' );
440 return $urlsAndEmails;
456 public static function l10n( $key, ...$params ) {
457 $language = RequestContext::getMain()->getLanguage()->getCode();
462 $filteredParams = MustacheHelper::filterMessageParams( $params );
480 $context[
'cssClass'] =
'errorMsg';
483 'cssClass' =>
'errorMsgHide',
491 return MustacheHelper::render(
$path, $context );
497 $resources = parent::getResources();
498 $gatewayModules = $this->gateway->getConfig(
'ui_modules' );
499 $this->
addModules(
'scripts', $resources, $gatewayModules );
500 if ( $this->gateway->getGlobal(
'LogClientErrors' ) ) {
501 $resources[] =
'ext.donationInterface.errorLog';
503 if ( $this->gateway->showMonthlyConvert() ) {
506 $mcModules = preg_grep(
'/monthlyConvert/', $resources );
507 if ( empty( $mcModules ) ) {
510 $resources[] = $this->gateway->getGlobal(
511 'MonthlyConvertDefaultModule'
519 $modules = [
'ext.donationInterface.mustache.styles' ];
520 $gatewayModules = $this->gateway->getConfig(
'ui_modules' );
526 if ( !empty( $newModules[$key] ) ) {
529 (array)$newModules[$key]
535 return $this->gateway->getGlobal(
'Template' );
539 return "{$this->scriptPath}/extensions/DonationInterface/gateway_forms/includes/{$name}";
544 if ( empty( $data[
'variant'] ) ) {
547 $variantDir = $this->gateway->getGlobal(
'VariantConfigurationDirectory' ) .
548 DIRECTORY_SEPARATOR . $data[
'variant'] . DIRECTORY_SEPARATOR;
550 foreach ( self::$partials as $partial ) {
554 file_exists( $variantDir . $filename )
556 $partials[$partial] = rtrim( file_get_contents(
557 $variantDir . $filename
560 $partials[$partial] = rtrim( file_get_contents(
561 self::$baseDir . DIRECTORY_SEPARATOR . $filename
static format( $amount, $currencyCode, $locale)
Format an amount and currency for display to users.
static getNames( $code)
Get localized country names for a particular language, using fallback languages for missing items.
static getLogger(GatewayType $adapter, $suffix='', LogPrefixProvider $prefixer=null)
getConfig( $key=null)
Get settings loaded from adapter's config directory.
static getCountrySpecificMessage( $key, $country, $language, $params=[])
Retrieves and translates a country-specific message, or the default if no country-specific version ex...
static getByCountry( $country)