commit 33783730a7758ccfd905400ac704f5d154f96183
parent 605c05a8e203080653bdbc256659d56fd9a3f59d
Author: Christian Grothoff <christian@grothoff.org>
Date: Thu, 2 Oct 2025 23:52:51 +0200
get server-side price list validation to work
Diffstat:
4 files changed, 21 insertions(+), 24 deletions(-)
diff --git a/src/Form/TurnstileSettingsForm.php b/src/Form/TurnstileSettingsForm.php
@@ -306,9 +306,11 @@ class TurnstileSettingsForm extends ConfigFormBase {
'field_name' => 'field_price',
'entity_type' => 'node',
'type' => 'string',
- 'cardinality' => 1,
+ 'cardinality' => 1, // FIXME: should we allow cardinality > 1 instead of ","-separation here?
'settings' => [
'max_length' => 255,
+ 'case_sensitive' => FALSE,
+ 'is_ascii' => TRUE,
],
]);
$field_storage->save();
diff --git a/src/Plugin/Validation/Constraint/TalerPriceListFormatConstraint.php b/src/Plugin/Validation/Constraint/TalerPriceListFormatConstraint.php
@@ -17,7 +17,7 @@ class TalerPriceListFormatConstraint extends Constraint {
public $invalidFormat = 'The price list "@value" is not valid. Please enter a valid price list (e.g., "EUR:1" or "USD:3,CHF:2" to support payment in multiple currencies).';
- public $invalidCurrency = 'Price uses currency "@currency" that is not supported by the Taler merchant backend. Please only use supported currencies.';
+ public $invalidCurrency = 'Price uses currency "@currency" that is not supported by the Taler merchant backend. The supported currencies are: @supported';
public $backendTrouble = 'Failed to fetch configuration data from Taler merchant backend.';
diff --git a/src/Plugin/Validation/Constraint/TalerPriceListFormatConstraintValidator.php b/src/Plugin/Validation/Constraint/TalerPriceListFormatConstraintValidator.php
@@ -17,6 +17,7 @@ class TalerPriceListFormatConstraintValidator extends ConstraintValidator {
\Drupal::logger('turnstile')->debug('Validating price list');
if (!isset($item)) {
+ \Drupal::logger('turnstile')->debug('No item, skipping validation');
return;
}
@@ -24,13 +25,15 @@ class TalerPriceListFormatConstraintValidator extends ConstraintValidator {
// Empty is OK, simply gratis.
if (empty($pricelist)) {
+ \Drupal::logger('turnstile')->debug('No pricelist, skipping validation');
return;
}
- $pattern = '/^(([A-Za-z]{1,11}:\d+(\.\d{1,8})?)(\s*,\s*[A-Za-z]{1,11}:\d+(\.\d{1,8})?)*$)?/';
+ $pattern = '/^(([A-Za-z]{1,11}:\d*(\.\d{1,8})?)(\s*,\s*[A-Za-z]{1,11}:\d*(\.\d{1,8})?)*)?$/';
if (preg_match($pattern, $pricelist) !== 1) {
+ \Drupal::logger('turnstile')->debug('Pricelist has invalid format, rejecting it');
$this->context->addViolation($constraint->invalidFormat, [
'@value' => $pricelist,
]);
@@ -96,20 +99,30 @@ class TalerPriceListFormatConstraintValidator extends ConstraintValidator {
// Parse and validate each amount in the comma-separated list.
$amounts = preg_split('/\s*,\s*/', trim($pricelist));
+ $currencies = $backend_config['currencies'];
foreach ($amounts as $amount) {
// Extract currency from each amount (format: CURRENCY:NUMBER[.FRACTION]).
+ \Drupal::logger('turnstile')->debug('Checking amount @amount', [
+ '@amount' => $amount,
+ ]);
if (preg_match('/^([A-Za-z]{1,11}):/', $amount, $matches)) {
$currency = $matches[1];
+ \Drupal::logger('turnstile')->debug('Checking currency @currency', [
+ '@currency' => $currency,
+ ]);
- if (!$this->checkCurrency($currency, $backend_config)) {
+ if (! isset($currencies[strtoupper($currency)])) {
+ \Drupal::logger('turnstile')->debug('Unsupported currency in pricelist, rejecting it');
$this->context->addViolation($constraint->invalidCurrency, [
- '@currency' => $currency
+ '@currency' => $currency,
+ '@supported' => implode(', ', array_keys($currencies)),
]);
return;
}
}
}
+ \Drupal::logger('turnstile')->debug('Pricelist is OK');
return;
} catch (\Exception $e) {
@@ -128,23 +141,4 @@ class TalerPriceListFormatConstraintValidator extends ConstraintValidator {
}
}
-
- /**
- * Check if a currency is supported by the merchant backend.
- *
- * @param string $currency
- * The currency code to check.
- * @param array $backend_config
- * The decoded JSON configuration from the payment backend.
- *
- * @return bool
- * TRUE if the currency is supported, FALSE otherwise.
- */
- protected function checkCurrency($currency, array $backend_config) {
- $currencies = $backend_config['currencies'];
- if (! isset($currencies[strtoupper($currency)]))
- return FALSE;
- return TRUE;
- }
-
}
\ No newline at end of file
diff --git a/turnstile.module b/turnstile.module
@@ -369,6 +369,7 @@ function turnstile_create_order(NodeInterface $node) {
return FALSE;
}
+ // FIXME: support v1 contract terms and use it if we have multiple currencies in $price!
$fulfillment_url = $node->toUrl('canonical', ['absolute' => TRUE])->toString();
$order_data = [
'order' => [