From b1303c525517498b0edfb9885ff36e08c72628b5 Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Thu, 29 Sep 2022 10:51:12 +0000
Subject: [PATCH] fix(premium-podcasts): return different cached page when
 podcast is unlocked

- clear podcast cache when setting subscription link
- update and add missing translation keys
---
 app/Controllers/EpisodeController.php         | 35 +++++++++++++------
 app/Controllers/PodcastController.php         |  3 ++
 modules/Admin/Language/en/Breadcrumb.php      |  1 +
 modules/Admin/Language/en/Episode.php         |  2 +-
 modules/PremiumPodcasts/Config/Routes.php     | 10 +++---
 .../Controllers/LockController.php            | 34 +++++-------------
 .../Controllers/SubscriptionController.php    | 16 +++++----
 .../Language/en/Subscription.php              |  8 ++---
 .../email/{removed.php => deleted.php}        |  2 +-
 themes/cp_admin/subscription/list.php         |  2 +-
 themes/cp_app/podcast/unlock.php              |  2 +-
 11 files changed, 60 insertions(+), 55 deletions(-)
 rename themes/cp_admin/subscription/email/{removed.php => deleted.php} (87%)

diff --git a/app/Controllers/EpisodeController.php b/app/Controllers/EpisodeController.php
index ebfedc22d5..5465474e12 100644
--- a/app/Controllers/EpisodeController.php
+++ b/app/Controllers/EpisodeController.php
@@ -70,11 +70,18 @@ class EpisodeController extends BaseController
             $this->registerPodcastWebpageHit($this->episode->podcast_id);
         }
 
-        $locale = service('request')
-            ->getLocale();
-        $cacheName =
-            "page_podcast#{$this->podcast->id}_episode#{$this->episode->id}_{$locale}" .
-            (can_user_interact() ? '_authenticated' : '');
+        $cacheName = implode(
+            '_',
+            array_filter([
+                'page',
+                "podcast#{$this->podcast->id}",
+                "episode#{$this->episode->id}",
+                service('request')
+                    ->getLocale(),
+                is_unlocked($this->podcast->handle) ? 'unlocked' : null,
+                can_user_interact() ? 'authenticated' : null,
+            ]),
+        );
 
         if (! ($cachedView = cache($cacheName))) {
             $data = [
@@ -112,11 +119,19 @@ class EpisodeController extends BaseController
             $this->registerPodcastWebpageHit($this->episode->podcast_id);
         }
 
-        $locale = service('request')
-            ->getLocale();
-        $cacheName =
-            "page_podcast#{$this->podcast->id}_episode#{$this->episode->id}_activity_{$locale}" .
-            (can_user_interact() ? '_authenticated' : '');
+        $cacheName = implode(
+            '_',
+            array_filter([
+                'page',
+                "podcast#{$this->podcast->id}",
+                "episode#{$this->episode->id}",
+                'activity',
+                service('request')
+                    ->getLocale(),
+                is_unlocked($this->podcast->handle) ? 'unlocked' : null,
+                can_user_interact() ? 'authenticated' : null,
+            ]),
+        );
 
         if (! ($cachedView = cache($cacheName))) {
             $data = [
diff --git a/app/Controllers/PodcastController.php b/app/Controllers/PodcastController.php
index 1242e91040..4e2450f49e 100644
--- a/app/Controllers/PodcastController.php
+++ b/app/Controllers/PodcastController.php
@@ -74,6 +74,7 @@ class PodcastController extends BaseController
                 'activity',
                 service('request')
                     ->getLocale(),
+                is_unlocked($this->podcast->handle) ? 'unlocked' : null,
                 can_user_interact() ? 'authenticated' : null,
             ]),
         );
@@ -122,6 +123,7 @@ class PodcastController extends BaseController
                 'about',
                 service('request')
                     ->getLocale(),
+                is_unlocked($this->podcast->handle) ? 'unlocked' : null,
                 can_user_interact() ? 'authenticated' : null,
             ]),
         );
@@ -188,6 +190,7 @@ class PodcastController extends BaseController
                 $seasonQuery ? 'season' . $seasonQuery : null,
                 service('request')
                     ->getLocale(),
+                is_unlocked($this->podcast->handle) ? 'unlocked' : null,
                 can_user_interact() ? 'authenticated' : null,
             ]),
         );
diff --git a/modules/Admin/Language/en/Breadcrumb.php b/modules/Admin/Language/en/Breadcrumb.php
index 4b4cd3a0bf..46863af3bb 100644
--- a/modules/Admin/Language/en/Breadcrumb.php
+++ b/modules/Admin/Language/en/Breadcrumb.php
@@ -47,4 +47,5 @@ return [
     'video-clips' => 'video clips',
     'embed' => 'embeddable player',
     'notifications' => 'notifications',
+    'suspend' => 'suspend',
 ];
diff --git a/modules/Admin/Language/en/Episode.php b/modules/Admin/Language/en/Episode.php
index f800ee95eb..92631ddf1c 100644
--- a/modules/Admin/Language/en/Episode.php
+++ b/modules/Admin/Language/en/Episode.php
@@ -110,7 +110,7 @@ return [
             'bonus_hint' => 'Extra content for the show (for example, behind the scenes info or interviews with the cast) or cross-promotional content for another show',
         ],
         'premium_title' => 'Premium',
-        'premium' => 'Episode must only be accessible to premium subscribers',
+        'premium' => 'Episode must be accessible to premium subscribers only',
         'parental_advisory' => [
             'label' => 'Parental advisory',
             'hint' => 'Does the episode contain explicit content?',
diff --git a/modules/PremiumPodcasts/Config/Routes.php b/modules/PremiumPodcasts/Config/Routes.php
index f657acf46f..2859b596f3 100644
--- a/modules/PremiumPodcasts/Config/Routes.php
+++ b/modules/PremiumPodcasts/Config/Routes.php
@@ -99,17 +99,17 @@ $routes->group(
                     ],
                 );
                 $routes->get(
-                    'remove',
-                    'SubscriptionController::remove/$1/$2',
+                    'delete',
+                    'SubscriptionController::delete/$1/$2',
                     [
-                        'as' => 'subscription-remove',
+                        'as' => 'subscription-delete',
                         'filter' =>
                             'permission:podcast-manage_subscriptions',
                     ],
                 );
                 $routes->post(
-                    'remove',
-                    'SubscriptionController::attemptRemove/$1/$2',
+                    'delete',
+                    'SubscriptionController::attemptDelete/$1/$2',
                     [
                         'filter' =>
                             'permission:podcast-manage_subscriptions',
diff --git a/modules/PremiumPodcasts/Controllers/LockController.php b/modules/PremiumPodcasts/Controllers/LockController.php
index 8d57947eca..2a50727344 100644
--- a/modules/PremiumPodcasts/Controllers/LockController.php
+++ b/modules/PremiumPodcasts/Controllers/LockController.php
@@ -45,33 +45,15 @@ class LockController extends BaseController
 
     public function index(): string
     {
-        $locale = service('request')
-            ->getLocale();
-        $cacheName =
-            "page_podcast#{$this->podcast->id}_{$locale}_unlock" .
-            (can_user_interact() ? '_authenticated' : '');
-
-        if (! ($cachedView = cache($cacheName))) {
-            $data = [
-                // TODO: metatags for locked premium podcasts
-                'metatags' => '',
-                'podcast' => $this->podcast,
-            ];
-
-            helper('form');
-
-            if (can_user_interact()) {
-                return view('podcast/unlock', $data);
-            }
-
-            // The page cache is set to a decade so it is deleted manually upon podcast update
-            return view('podcast/unlock', $data, [
-                'cache' => DECADE,
-                'cache_name' => $cacheName,
-            ]);
-        }
+        $data = [
+            // TODO: metatags for locked premium podcasts
+            'metatags' => '',
+            'podcast' => $this->podcast,
+        ];
+
+        helper('form');
 
-        return $cachedView;
+        return view('podcast/unlock', $data);
     }
 
     public function attemptUnlock(): RedirectResponse
diff --git a/modules/PremiumPodcasts/Controllers/SubscriptionController.php b/modules/PremiumPodcasts/Controllers/SubscriptionController.php
index d5147f231d..055de5b833 100644
--- a/modules/PremiumPodcasts/Controllers/SubscriptionController.php
+++ b/modules/PremiumPodcasts/Controllers/SubscriptionController.php
@@ -88,6 +88,10 @@ class SubscriptionController extends BaseController
         service('settings')
             ->set('Subscription.link', $subscriptionLink, 'podcast:' . $this->podcast->id);
 
+        // clear cached podcast pages to render Call To Action
+        cache()
+            ->deleteMatching("page_podcast#{$this->podcast->id}*");
+
         return redirect()->route('subscription-list', [$this->podcast->id])->with(
             'message',
             lang('Subscription.messages.linkSaveSuccess')
@@ -396,7 +400,7 @@ class SubscriptionController extends BaseController
         );
     }
 
-    public function remove(): string
+    public function delete(): string
     {
         helper('form');
 
@@ -412,7 +416,7 @@ class SubscriptionController extends BaseController
         return view('subscription/delete', $data);
     }
 
-    public function attemptRemove(): RedirectResponse
+    public function attemptDelete(): RedirectResponse
     {
         $db = db_connect();
         $db->transStart();
@@ -423,15 +427,15 @@ class SubscriptionController extends BaseController
         $email = service('email');
 
         if (! $email->setTo($this->subscription->email)
-            ->setSubject(lang('Subscription.emails.removed_subject', [], $this->podcast->language_code))
-            ->setMessage(view('subscription/email/removed', [
+            ->setSubject(lang('Subscription.emails.deleted_subject', [], $this->podcast->language_code))
+            ->setMessage(view('subscription/email/deleted', [
                 'subscription' => $this->subscription,
             ]))->setMailType('html')
             ->send()) {
             $db->transRollback();
             return redirect()->route('subscription-list', [$this->podcast->id])->with(
                 'errors',
-                [lang('Subscription.messages.removeError'), $email->printDebugger([])]
+                [lang('Subscription.messages.deleteError'), $email->printDebugger([])]
             );
         }
 
@@ -439,7 +443,7 @@ class SubscriptionController extends BaseController
 
         return redirect()->route('subscription-list', [$this->podcast->id])->with(
             'messages',
-            lang('Subscription.messages.removeSuccess', [
+            lang('Subscription.messages.deleteSuccess', [
                 'subscriber' => $this->subscription->email,
             ])
         );
diff --git a/modules/PremiumPodcasts/Language/en/Subscription.php b/modules/PremiumPodcasts/Language/en/Subscription.php
index 7371c8ab0c..f8af256f70 100644
--- a/modules/PremiumPodcasts/Language/en/Subscription.php
+++ b/modules/PremiumPodcasts/Language/en/Subscription.php
@@ -60,8 +60,8 @@ return [
         'editError' => 'Subscription could not be edited.',
         'regenerateTokenSuccess' => 'Token regenerated! An email was sent to {subscriber} with the new token.',
         'regenerateTokenError' => 'Token could not be regenerated.',
-        'removeSuccess' => 'Subscription was canceled! An email was sent to {subscriber} to tell him.',
-        'removeError' => 'Subscription could not be canceled.',
+        'deleteSuccess' => 'Subscription was removed! An email was sent to {subscriber}.',
+        'deleteError' => 'Subscription could not be removed.',
         'suspendSuccess' => 'Subscription was suspended! An email was sent to {subscriber}.',
         'suspendError' => 'Subscription could not be suspended.',
         'resumeSuccess' => 'Subscription was resumed! An email was sent to {subscriber}.',
@@ -93,8 +93,8 @@ return [
         'suspended_reason' => 'That is for the following reason: {0}',
         'resumed_subject' => 'Your subscription has been resumed!',
         'resumed' => 'Your subscription for {podcastTitle} has been resumed! You may access the podcast\'s premium episodes again.',
-        'removed_subject' => 'Your subscription has been removed!',
-        'removed' => 'Your subscription for {podcastTitle} has been removed! You no longer have access to the podcast\'s premium episodes.',
+        'deleted_subject' => 'Your subscription has been removed!',
+        'deleted' => 'Your subscription for {podcastTitle} has been removed! You no longer have access to the podcast\'s premium episodes.',
         'footer' => '{castopod} hosted on {host}',
     ],
 ];
diff --git a/themes/cp_admin/subscription/email/removed.php b/themes/cp_admin/subscription/email/deleted.php
similarity index 87%
rename from themes/cp_admin/subscription/email/removed.php
rename to themes/cp_admin/subscription/email/deleted.php
index 909067dce6..093b615693 100644
--- a/themes/cp_admin/subscription/email/removed.php
+++ b/themes/cp_admin/subscription/email/deleted.php
@@ -1,6 +1,6 @@
 <?= lang('Subscription.emails.greeting', [], $subscription->podcast->language_code) ?><br/><br/>
 
-<?= lang('Subscription.emails.removed', [
+<?= lang('Subscription.emails.deleted', [
     'podcastTitle' => '<strong>' . $subscription->podcast->title . '</strong>',
 ], $subscription->podcast->language_code, false) ?>
 
diff --git a/themes/cp_admin/subscription/list.php b/themes/cp_admin/subscription/list.php
index 3d09685eed..c63833a69a 100644
--- a/themes/cp_admin/subscription/list.php
+++ b/themes/cp_admin/subscription/list.php
@@ -94,7 +94,7 @@
                             [
                                 'type' => 'link',
                                 'title' => lang('Subscription.delete'),
-                                'uri' => route_to('subscription-remove', $podcast->id, $subscription->id),
+                                'uri' => route_to('subscription-delete', $podcast->id, $subscription->id),
                                 'class' => 'font-semibold text-red-600',
                             ],
                         ];
diff --git a/themes/cp_app/podcast/unlock.php b/themes/cp_app/podcast/unlock.php
index 1e89af1513..78ec988cbc 100644
--- a/themes/cp_app/podcast/unlock.php
+++ b/themes/cp_app/podcast/unlock.php
@@ -75,7 +75,7 @@
     <header class="relative flex flex-col-reverse justify-between w-full col-start-2 bg-top bg-no-repeat bg-cover sm:flex-row sm:items-end bg-header aspect-[3/1]" style="background-image: url('<?= $podcast->banner->medium_url ?>');">
         <div class="absolute bottom-0 left-0 w-full h-full backdrop-gradient mix-blend-multiply"></div>
         <div class="flex items-center pl-4 -mb-6 md:pl-8 md:-mb-8 gap-x-4">
-            <img src="<?= $podcast->cover->thumbnail_url ?>" alt="<?= esc($podcast->title) ?>" class="h-24 rounded-full sm:h-28 md:h-36 ring-3 ring-background-elevated aspect-square" loading="lazy" />
+            <img src="<?= $podcast->cover->thumbnail_url ?>" alt="<?= esc($podcast->title) ?>" class="z-[45] h-24 rounded-full sm:h-28 md:h-36 ring-3 ring-background-elevated aspect-square" loading="lazy" />
             <div class="relative flex flex-col text-white -top-3 sm:top-0 md:top-2">
                 <h1 class="text-lg font-bold leading-none line-clamp-2 md:leading-none md:text-2xl font-display"><?= esc($podcast->title) ?><span class="ml-1 font-sans text-base font-normal">@<?= esc($podcast->handle) ?></span></h1>
                 <div class="">
-- 
GitLab