turnstile

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

commit 605c05a8e203080653bdbc256659d56fd9a3f59d
parent 9c5d6679aeb2deed6849312fdf58c104deef9971
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu,  2 Oct 2025 23:31:01 +0200

try again to add input validation logic, fix some typos

Diffstat:
Mturnstile.module | 51++++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 46 insertions(+), 5 deletions(-)

diff --git a/turnstile.module b/turnstile.module @@ -6,10 +6,45 @@ */ use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\Display\EntityViewDisplayInterface; use Drupal\node\NodeInterface; use GuzzleHttp\Exception\RequestException; + + + +/** + * Implements hook_entity_bundle_field_info_alter(). + */ +function turnstile_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) { + if ($entity_type->id() !== 'node') { + \Drupal::logger('turnstile')->debug('Node ID "@id" is not one Turnstile cares about', [ + '@id' => $entity_type->id(), + ]); + return; + } + $config = \Drupal::config('turnstile.settings'); + $enabled_types = $config->get('enabled_content_types') ?: []; + + // Only show price field on enabled content types. + if (! in_array($bundle, $enabled_types)) { + \Drupal::logger('turnstile')->debug('Content type "@bundle" is not one Turnstile cares about', [ + '@bundle' => $bundle, + ]); + return; + } + + if (! isset($fields['field_price'])) { + \Drupal::logger('turnstile')->debug('Node lacks field_price, strange. Not adding constraint.'); + return; + } + // Use the ID as defined in the annotation of the constraint definition + $fields['field_price']->addConstraint('TalerPriceListFormat', []); +} + + + /** * Implements hook_entity_view_alter(). */ @@ -70,7 +105,8 @@ function turnstile_check_paywall_cookie($body, NodeInterface $node) { } // Check if user is a subscriber. - if (isset($_SESSION['turnstile_subscriber']) && $_SESSION['turnstile_subscriber'] === TRUE) { + if (isset($_SESSION['turnstile_subscriber']) && + $_SESSION['turnstile_subscriber'] === TRUE) { // FIXME: should set turnstile_subscriber to *expiration* time // of the subscription and check not for TRUE but for "greater // current time". @@ -113,7 +149,12 @@ function turnstile_check_paywall_cookie($body, NodeInterface $node) { $order_info = turnstile_create_or_get_order($node); if (! $order_info) { // Fallback: just return body, not good to have unhappy readers. - return $body; + $config = \Drupal::config('turnstile.settings'); + $grant_access_on_error = $config->get('grant_access_on_error') ?: true; + if ($grant_access_on_error) { + return $body; + } + return 'Error: failed to setup order with payment backend'; } return turnstile_render_preview_with_payment_button($body, $order_info); @@ -273,7 +314,7 @@ function turnstile_check_order_status($order_id) { try { $http_client = \Drupal::httpClient(); - $response = $http_client->get($backend_url . '/private/orders/' . $order_id, [ + $response = $http_client->get($backend_url . 'private/orders/' . $order_id, [ 'headers' => [ 'Authorization' => 'Bearer ' . $access_token, ], @@ -340,7 +381,7 @@ function turnstile_create_order(NodeInterface $node) { try { $http_client = \Drupal::httpClient(); - $response = $http_client->post($backend_url . '/private/orders', [ + $response = $http_client->post($backend_url . 'private/orders', [ 'json' => $order_data, 'headers' => [ 'Authorization' => 'Bearer ' . $access_token, @@ -358,7 +399,7 @@ function turnstile_create_order(NodeInterface $node) { if (isset($result['order_id'])) { return [ 'order_id' => $result['order_id'], - 'payment_url' => $backend_url . '/orders/' . $result['order_id'], + 'payment_url' => $backend_url . 'orders/' . $result['order_id'], 'paid' => FALSE, 'refunded' => FALSE, 'created' => time(), // FIXME: probably better keep when offer expires!