turnstile

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

commit 5ca33b5e6eb1654e8a49e4b038d3451b656746f6
parent 22c290608c6b033bd9caaf530eccb7a9bdb40507
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  2 Nov 2025 17:33:51 +0100

add logic to track when subscriptions expire and purge caches when that happens

Diffstat:
Msrc/Entity/TurnstilePriceCategory.php | 24++++++++++++++++++++++--
Msrc/Form/PriceCategoryForm.php | 10+++++++++-
Msrc/TalerMerchantApiService.php | 7+++++--
3 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/src/Entity/TurnstilePriceCategory.php b/src/Entity/TurnstilePriceCategory.php @@ -81,6 +81,15 @@ 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,8 +146,16 @@ class TurnstilePriceCategory extends ConfigEntityBase { return $cache->data; } + $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); + foreach ($currencyMap as $currencyCode => $price) { $inputs = []; if ("%none%" !== $tokenFamilySlug) @@ -217,7 +234,7 @@ class TurnstilePriceCategory extends ConfigEntityBase { \Drupal::cache()->set( $cid, $choices, - \Drupal\Core\Cache\Cache::PERMANENT, + $max_cache, $tags ); return $choices; @@ -228,11 +245,14 @@ 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) { + public function setPrices(array $prices, array $expirations) { $this->prices = $prices; + $this->expirations = $expirations; return $this; } diff --git a/src/Form/PriceCategoryForm.php b/src/Form/PriceCategoryForm.php @@ -159,19 +159,27 @@ 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) { if ($price !== '') { $filtered_prices[$subscription_id][$currency_code] = $price; + $sub_active = TRUE; } } + if ($sub_active) { + $sub_expirations[$subscription_id] + = $subscriptions[$subscription_id]['valid_before_s']; + } } - $price_category->setPrices($filtered_prices); + $price_category->setPrices($filtered_prices, $sub_expirations); $status = $price_category->save(); if ($status === SAVED_NEW) { diff --git a/src/TalerMerchantApiService.php b/src/TalerMerchantApiService.php @@ -245,15 +245,18 @@ 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) { if ( ($family['kind'] === 'subscription') && ($family['valid_after']['t_s'] < $now) && - ( ($family['valid_before']['t_s'] >= $now) || - ($family['valid_before']['t_s'] === 'never') ) ) { + ($valid_before >= $now) ) { $slug = $family['slug']; $result[$slug] = [ 'name' => $family['name'], 'label' => $slug, + 'valid_before_s' => $valid_before, 'description' => $family['description'], 'description_i18n' => ($family['description_i18n'] ?? NULL), ];