wordpress-turnstile

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

commit bcd22155c6cbc4aae1611a1e3351e1a4a22e57a8
parent c0fe535acacf59524b005537cad28121472198e8
Author: Christian Grothoff <christian@grothoff.org>
Date:   Sun,  2 Nov 2025 19:47:51 +0100

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

Diffstat:
Mincludes/class-price-category.php | 34+++++++++-------------------------
Mincludes/class-taler-merchant-api.php | 48++++++++++++++++++++++++++++++++++--------------
2 files changed, 43 insertions(+), 39 deletions(-)

diff --git a/includes/class-price-category.php b/includes/class-price-category.php @@ -33,9 +33,6 @@ class Taler_Price_Category { $categories = self::get_all(); $categories[$id] = $data; update_option('taler_turnstile_price_categories', $categories); - - // Clear cache - wp_cache_delete('taler_payment_choices_' . $id, 'taler_turnstile'); } /** @@ -46,7 +43,6 @@ class Taler_Price_Category { if (isset($categories[$id])) { unset($categories[$id]); update_option('taler_turnstile_price_categories', $categories); - wp_cache_delete('taler_payment_choices_' . $id, 'taler_turnstile'); return true; } return false; @@ -73,14 +69,7 @@ class Taler_Price_Category { /** * Get payment choices for GNU Taler v1 contracts */ - public static function get_payment_choices($id) { - $cache_key = 'taler_payment_choices_' . $id; - $cached = wp_cache_get($cache_key, 'taler_turnstile'); - - if ($cached !== false) { - return $cached; - } - + public static function get_payment_choices($id, $subscriptions) { $category = self::get($id); if (!$category || !isset($category['prices'])) { return array(); @@ -89,14 +78,15 @@ class Taler_Price_Category { $max_cache = time() + 3600; $choices = array(); $prices = $category['prices']; - $expirations = $category['expirations']; - foreach ($category['prices'] as $token_family_slug => $currency_map) { - $expi = $expirations[$token_family_slug]; - if ($expi < time()) - continue; // already expired - $max_cache = min ($max_cache, - $expi); + if ($token_family_slug !== '%none%') { + $subscription = $subscriptions[$tokenFamilySlug]; + $expi = $subscription['valid_before_s'] ?? 0; + if ($expi < time()) + continue; // already expired + $max_cache = min ($max_cache, + $expi); + } foreach ($currency_map as $currency_code => $price) { $inputs = array(); @@ -158,12 +148,6 @@ class Taler_Price_Category { } } } - - wp_cache_set($cache_key, - $choices, - 'taler_turnstile', - $max_cache - time()); - return $choices; } diff --git a/includes/class-taler-merchant-api.php b/includes/class-taler-merchant-api.php @@ -204,10 +204,10 @@ class Taler_Merchant_API { $token_families = $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 ($token_families as $family) { + $valid_before = ($family['valid_before']['t_s'] === 'never') + ? PHP_INT_MAX + : $family['valid_before']['t_s']; if ( ($family['kind'] === 'subscription') && ($valid_before >= $now) && ($family['valid_after']['t_s'] < $now) ) { @@ -451,28 +451,25 @@ class Taler_Merchant_API { public static function create_order($post_id) { $backend_url = get_option('taler_turnstile_payment_backend_url'); $access_token = get_option('taler_turnstile_access_token'); - if (empty($backend_url) || empty($access_token)) { error_log('No backend, cannot setup new order'); return false; } $price_category_id = get_post_meta($post_id, '_taler_price_category', true); - if (empty($price_category_id)) { error_log('No price category selected'); return false; } $price_category = Taler_Price_Category::get($price_category_id); - if (!$price_category) { error_log('No price category, cannot setup new order'); return false; } - $choices = Taler_Price_Category::get_payment_choices($price_category_id); - + $subscriptions = Taler_Merchant_API::get_subscriptions(); + $choices = Taler_Price_Category::get_payment_choices($price_category_id, $subscriptions); if (empty($choices)) { error_log('Price list is empty, cannot setup new order'); return false; @@ -488,6 +485,8 @@ class Taler_Merchant_API { 'version' => 1, 'choices' => $choices, 'summary' => 'Access to: ' . get_the_title($post_id), + 'summary_i18n' => self::build_translation_map (__('Access to: @title', 'taler-turnstile'), + ['@title' => get_the_title($post_id)]), 'fulfillment_url' => $fulfillment_url, 'pay_deadline' => array( 't_s' => $order_expiration @@ -567,9 +566,10 @@ class Taler_Merchant_API { * translation engines. Reports on issues particularly welcome. * * @param string $string The translatable string + * @param array $args placeholder replacements for the translatable string * @return array Map of language codes to translated strings */ - private static function build_translation_map($string) { + private static function build_translation_map($string, $args = []) { $translations = array(); // Detect and use WPML (WordPress Multilingual Plugin) @@ -585,6 +585,7 @@ class Taler_Merchant_API { // Get translation $translated = apply_filters('wpml_translate_single_string', $string, 'taler-turnstile', 'subscription_description', $lang_code); + $translated = self::apply_placeholder_replacements($translated, $args); $translations[$lang_code] = $translated; } @@ -602,6 +603,7 @@ class Taler_Merchant_API { // Get translation $translated = pll_translate_string($string, $lang_code); + $translated = self::apply_placeholder_replacements($translated, $args); $translations[$lang_code] = $translated; } @@ -629,7 +631,7 @@ class Taler_Merchant_API { 'language' => $lang_code ) ); - + $translated = self::apply_placeholder_replacements($translated, $args); $translations[$lang_code] = !empty($translated) ? $translated : $string; } @@ -650,18 +652,34 @@ class Taler_Merchant_API { } else { $translated = $string; } - + $translated = self::apply_placeholder_replacements($translated, $args); $translations[$lang_code] = $translated; } - return $translations; } // Fallback: No multilingual plugin detected - // Return English only - return array('en' => $string); + // Return English only with placeholder replacements + $translated = self::apply_placeholder_replacements($string, $args); + return array('en' => $translated); } + /** + * Apply placeholder replacements to a translated string + * + * @param string $string The string containing placeholders (e.g., "Kaufe @title") + * @param array $args Placeholder replacements (e.g., ['@title' => '1984']) + * @return string String with placeholders replaced + */ + private static function apply_placeholder_replacements($string, $args) { + if (empty($args)) { + return $string; + } + foreach ($args as $placeholder => $value) { + $string = str_replace($placeholder, $value, $string); + } + return $string; + } /** * Generate a hashed session identifier for payment tracking @@ -684,4 +702,6 @@ class Taler_Merchant_API { // Encode as URL-safe base64 return rtrim(strtr(base64_encode($hash), '+/', '-_'), '='); } + + } \ No newline at end of file