turnstile

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

TurnstileConfigSubscriber.php (6232B)


      1 <?php
      2 
      3 /**
      4  * @file
      5  * Location: src/EventSubscriber/TurnstileConfigSubscriber.php
      6  *
      7  * Subscriber for turnstile config changes.
      8  */
      9 
     10 namespace Drupal\taler_turnstile\EventSubscriber;
     11 
     12 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
     13 use Drupal\Core\StringTranslation\StringTranslationTrait;
     14 use Drupal\Core\StringTranslation\TranslationInterface;
     15 use Drupal\Core\Config\ConfigCrudEvent;
     16 use Drupal\Core\Config\ConfigEvents;
     17 use Drupal\Core\Entity\EntityTypeManagerInterface;
     18 use Drupal\taler_turnstile\TurnstileFieldManager;
     19 use Drupal\taler_turnstile\TalerMerchantApiService;
     20 use Drupal\Core\Messenger\MessengerInterface;
     21 
     22 class TurnstileConfigSubscriber implements EventSubscriberInterface {
     23 
     24   // This provides the $this->t() method.
     25   use StringTranslationTrait;
     26 
     27   /**
     28    * The entity type manager.
     29    *
     30    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
     31    */
     32   protected $entityTypeManager;
     33 
     34   /**
     35    * The Turnstile field manager.
     36    *
     37    * @var \Drupal\taler_turnstile\TurnstileFieldManager
     38    */
     39   protected $fieldManager;
     40 
     41 
     42   /**
     43    * The messenger service.
     44    *
     45    * @var \Drupal\Core\Messenger\MessengerInterface
     46    */
     47   protected $messenger;
     48 
     49   /**
     50    * The Turnstile API service.
     51    *
     52    * @var \Drupal\taler_turnstile\TalerMerchantApiService
     53    */
     54   protected $apiService;
     55 
     56   /**
     57    * Constructs a TurnstileSettingsForm object.
     58    *
     59    * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
     60    *   The translation interface.
     61    * @param \Drupal\Core\Messenger\MessengerInterface
     62    *   The messenger interface.
     63    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
     64    *   The entity type manager.
     65    * @param \Drupal\taler_turnstile\TurnstileFieldManager $field_manager
     66    *   The field manager.
     67    * @param \Drupal\taler_turnstile\TalerMerchantApiService $api_service
     68    *   The Turnstile API service.
     69    */
     70   public function __construct(TranslationInterface $string_translation,
     71                               MessengerInterface $messenger,
     72                               EntityTypeManagerInterface $entity_type_manager,
     73                               TurnstileFieldManager $field_manager,
     74                               TalerMerchantApiService $api_service) {
     75     $this->stringTranslation = $string_translation;
     76     $this->messenger = $messenger;
     77     $this->entityTypeManager = $entity_type_manager;
     78     $this->fieldManager = $field_manager;
     79     $this->apiService = $api_service;
     80   }
     81 
     82   /**
     83    * {@inheritdoc}
     84    */
     85   public static function getSubscribedEvents() {
     86     // Listen for the configuration save event.
     87     $events[ConfigEvents::SAVE][] = ['onConfigSave'];
     88     return $events;
     89   }
     90 
     91   /**
     92    * React to configuration changes.
     93    *
     94    * @param \Drupal\Core\Config\ConfigCrudEvent $event
     95    * The configuration event.
     96    */
     97   public function onConfigSave(ConfigCrudEvent $event) {
     98     $config = $event->getConfig();
     99     if ($config->getName() !== 'taler_turnstile.settings') {
    100       return;
    101     }
    102     if ($event->isChanged('enabled_content_types')) {
    103       $old_enabled_types = $config->getOriginal('enabled_content_types') ?? [];
    104       $new_enabled_types = $config->get('enabled_content_types');
    105 
    106       // FIXME: Consider validating new_enabled_types.
    107 
    108       // Find content types to add and remove.
    109       $types_to_add = array_diff($new_enabled_types, $old_enabled_types);
    110       $types_to_remove = array_diff($old_enabled_types, $new_enabled_types);
    111 
    112       // Add fields to newly enabled content types.
    113       if (!empty($types_to_add)) {
    114         $this->fieldManager->addFieldsToContentTypes($types_to_add);
    115       }
    116 
    117       // Remove fields from disabled content types.
    118       if (!empty($types_to_remove)) {
    119         $this->fieldManager->removeFieldsFromContentTypes($types_to_remove);
    120       }
    121       if (empty($new_enabled_types)) {
    122         $this->fieldManager->cleanupFieldStorage();
    123       }
    124       // Display summary of changes.
    125       if (!empty($types_to_add) || !empty($types_to_remove)) {
    126         $this->displayFieldChanges($types_to_add, $types_to_remove);
    127       }
    128       \Drupal::logger('taler_turnstile')->info('Turnstile content types changed from @old to @new.', [
    129         '@old' => json_encode($old_enabled_types),
    130         '@new' => json_encode($new_enabled_types),
    131       ]);
    132     }
    133     // Subscription prices feed every category's "buy subscription"
    134     // choices, so keep all merchant templates in sync when they change.
    135     if ($event->isChanged('subscription_prices')) {
    136       $this->apiService->syncAllTemplates();
    137     }
    138     // When the operator (re)configures the merchant backend or
    139     // rotates the access token, the new instance will not yet have
    140     // any of our templates — push them all so the paywall keeps
    141     // working without manual intervention.
    142     if ($event->isChanged('payment_backend_url') ||
    143         $event->isChanged('access_token')) {
    144       $this->apiService->syncAllTemplates();
    145     }
    146   }
    147 
    148   /**
    149    * Display messages about field changes.
    150    *
    151    * @param array $types_added
    152    *   Content types that had fields added.
    153    * @param array $types_removed
    154    *   Content types that had fields removed.
    155    */
    156   protected function displayFieldChanges(array $types_added, array $types_removed) {
    157     $content_types = $this->entityTypeManager->getStorage('node_type')->loadMultiple();
    158 
    159     if (!empty($types_added)) {
    160       $added_labels = [];
    161       foreach ($types_added as $type) {
    162         if (isset($content_types[$type])) {
    163           $added_labels[] = $content_types[$type]->label();
    164         }
    165       }
    166       if (!empty($added_labels)) {
    167         $this->messenger->addStatus(
    168           $this->t('Price category fields added to: @types', [
    169             '@types' => implode(', ', $added_labels),
    170           ])
    171         );
    172       }
    173     }
    174 
    175     if (!empty($types_removed)) {
    176       $removed_labels = [];
    177       foreach ($types_removed as $type) {
    178         if (isset($content_types[$type])) {
    179           $removed_labels[] = $content_types[$type]->label();
    180         }
    181       }
    182       if (!empty($removed_labels)) {
    183         $this->messenger->addStatus(
    184           $this->t('Price category fields removed from: @types', [
    185             '@types' => implode(', ', $removed_labels),
    186           ])
    187         );
    188       }
    189     }
    190   }
    191 }