turnstile

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

commit b3fd8c035ee438092bb5517aa8f58c1872e2cdce
parent 5ca33b5e6eb1654e8a49e4b038d3451b656746f6
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  2 Nov 2025 19:47:32 +0100

also apply i18n to summary, remove choice caching, does not work well with subscription expiration

Diffstat:
Msrc/Entity/TurnstilePriceCategory.php | 52++++++++++++++--------------------------------------
Msrc/Form/PriceCategoryForm.php | 8+-------
Msrc/TalerMerchantApiService.php | 23++++++++++++++++-------
3 files changed, 31 insertions(+), 52 deletions(-)

diff --git a/src/Entity/TurnstilePriceCategory.php b/src/Entity/TurnstilePriceCategory.php @@ -81,15 +81,6 @@ class TurnstilePriceCategory extends ConfigEntityBase { protected $prices = []; /** - * The expirations array. Says when which subscription type is set to expire. - * - * Structure: ['subscription_id' => $TIMESTAMP ] - * - * @var array - */ - protected $expirations = []; - - /** * Gets the description. * * @return string @@ -137,25 +128,26 @@ class TurnstilePriceCategory extends ConfigEntityBase { * Return the different payment choices in a way suitable * for GNU Taler v1 contracts. * + * @param array $expirations + * Times when each possible subscription type expires. * @return array * Structure suitable for the choices array in the v1 contract */ - public function getPaymentChoices(): array { - $cid = 'taler_turnstile:payment_choices:' . $this->id(); - if ($cache = \Drupal::cache()->get($cid)) { - return $cache->data; - } - + public function getPaymentChoices(array $subscriptions): array { $max_cache = time() + 3600; $choices = []; foreach ($this->getPrices() as $tokenFamilySlug => $currencyMap) { - $expi = $this->expirations[$tokenFamilySlug] ?? 0; - if ($expi < time()) - continue; // already expired - $max_cache = min ($max_cache, - $expi); - + if ("%none%" !== $tokenFamilySlug) { + $subscription = $subscriptions[$tokenFamilySlug]; + $expi = $subscription['valid_before_s'] ?? 0; + if ($expi < time()) { + \Drupal::logger('taler_turnstile')->info('Subscription category @slug expired at @expire, skipping it.', ['@slug' => $tokenFamilySlug, '@expire' => $expi]); + continue; // already expired + } + $max_cache = min ($max_cache, + $expi); + } foreach ($currencyMap as $currencyCode => $price) { $inputs = []; if ("%none%" !== $tokenFamilySlug) @@ -224,19 +216,6 @@ class TurnstilePriceCategory extends ConfigEntityBase { } // for each possible currency } // for each type of subscription - - // This should return ['config:taler_turnstile_price_category.' . $this->id()]; - $tags = $this->getCacheTags(); - // Invalidate cache if getSubscriptionPrice() changes - $tags[] = 'config:taler_turnstile.settings'; - // Invalidate cache also when translations change - $tags[] = 'locale'; - \Drupal::cache()->set( - $cid, - $choices, - $max_cache, - $tags - ); return $choices; } @@ -245,14 +224,11 @@ class TurnstilePriceCategory extends ConfigEntityBase { * * @param array $prices * The prices array. - * @param array $expirations - * Times when each possible subscription type expires. * * @return $this */ - public function setPrices(array $prices, array $expirations) { + public function setPrices(array $prices) { $this->prices = $prices; - $this->expirations = $expirations; return $this; } diff --git a/src/Form/PriceCategoryForm.php b/src/Form/PriceCategoryForm.php @@ -159,12 +159,10 @@ class PriceCategoryForm extends EntityForm { */ public function save(array $form, FormStateInterface $form_state) { $price_category = $this->entity; - $subscriptions = $this->apiService->getSubscriptions(); // Filter out empty prices. $prices = $form_state->getValue('prices'); $filtered_prices = []; - $sub_expirations = []; foreach ($prices as $subscription_id => $currencies) { $sub_active = FALSE; foreach ($currencies as $currency_code => $price) { @@ -173,13 +171,9 @@ class PriceCategoryForm extends EntityForm { $sub_active = TRUE; } } - if ($sub_active) { - $sub_expirations[$subscription_id] - = $subscriptions[$subscription_id]['valid_before_s']; - } } - $price_category->setPrices($filtered_prices, $sub_expirations); + $price_category->setPrices($filtered_pricess); $status = $price_category->save(); if ($status === SAVED_NEW) { diff --git a/src/TalerMerchantApiService.php b/src/TalerMerchantApiService.php @@ -245,10 +245,10 @@ class TalerMerchantApiService { $tokenFamilies = $jbody['token_families']; $now = time (); // in seconds since Epoch - $valid_before = ($family['valid_before']['t_s'] === 'never') - ? PHP_INT_MAX - : $family['valid_before']['t_s']; foreach ($tokenFamilies as $family) { + $valid_before = ($family['valid_before']['t_s'] === 'never') + ? PHP_INT_MAX + : $family['valid_before']['t_s']; if ( ($family['kind'] === 'subscription') && ($family['valid_after']['t_s'] < $now) && ($valid_before >= $now) ) { @@ -260,9 +260,16 @@ class TalerMerchantApiService { 'description' => $family['description'], 'description_i18n' => ($family['description_i18n'] ?? NULL), ]; + $found = TRUE; } - }; - \Drupal::cache()->set($cid, $result, time() + self::CACHE_BACKEND_DATA_SECONDS); + else + { + $this->logger->info('Token family @slug is not valid right now, skipping it.', ['@slug' => $family['slug']]); + } + }; // end foreach token family + \Drupal::cache()->set($cid, + $result, + time() + self::CACHE_BACKEND_DATA_SECONDS); return $result; } catch (RequestException $e) { @@ -548,8 +555,8 @@ class TalerMerchantApiService { $this->logger->debug('No price category, cannot setup new order'); return FALSE; } - - $choices = $price_category->getPaymentChoices(); + $subscriptions = $this->getSubscriptions(); + $choices = $price_category->getPaymentChoices($subscriptions); if (empty($choices)) { $this->logger->debug('Price list is empty, cannot setup new order'); return FALSE; @@ -570,6 +577,8 @@ class TalerMerchantApiService { 'version' => 1, 'choices' => $choices, 'summary' => 'Access to: ' . $node->getTitle(), + 'summary_i18n' => $this->buildTranslationMap ('Access to: @title', + ['@title' => $node->getTitle()]), 'fulfillment_url' => $fulfillment_url, 'pay_deadline' => [ 't_s' => $order_expiration,