turnstile

Drupal paywall plugin
Log | Files | Refs | README | LICENSE

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:
Msrc/Form/TurnstileSettingsForm.php | 4+++-
Msrc/Plugin/Validation/Constraint/TalerPriceListFormatConstraint.php | 2+-
Msrc/Plugin/Validation/Constraint/TalerPriceListFormatConstraintValidator.php | 38++++++++++++++++----------------------
Mturnstile.module | 1+
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' => [