From f75bd76458eeb01a2d37912695e33f77d03b7a69 Mon Sep 17 00:00:00 2001 From: Yassine Doghri <yassine@doghri.fr> Date: Fri, 1 Oct 2021 10:59:44 +0000 Subject: [PATCH] fix: unpublish episode before deleting it + add validation step before deletion fixes #112, closes #55 --- app/Views/Components/Forms/Checkbox.php | 2 +- modules/Admin/Config/Routes.php | 8 +++ .../Admin/Controllers/EpisodeController.php | 58 ++++++++++++++++++- modules/Admin/Language/en/Breadcrumb.php | 1 + modules/Admin/Language/en/Episode.php | 8 ++- modules/Admin/Language/fr/Breadcrumb.php | 1 + modules/Admin/Language/fr/Episode.php | 12 ++++ themes/cp_admin/episode/delete.php | 27 +++++++++ themes/cp_admin/episode/unpublish.php | 2 +- 9 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 themes/cp_admin/episode/delete.php diff --git a/app/Views/Components/Forms/Checkbox.php b/app/Views/Components/Forms/Checkbox.php index b93160cae9..02f3af06a6 100644 --- a/app/Views/Components/Forms/Checkbox.php +++ b/app/Views/Components/Forms/Checkbox.php @@ -30,7 +30,7 @@ class Checkbox extends FormComponent $hint = $this->hint === null ? '' : hint_tooltip($this->hint, 'ml-1'); return <<<HTML - <label class="leading-8"> + <label class="leading-8 {$this->class}"> {$checkboxInput} <span class="ml-2">{$this->slot}{$hint}</label> </label> diff --git a/modules/Admin/Config/Routes.php b/modules/Admin/Config/Routes.php index bb5b6a4391..626803b719 100644 --- a/modules/Admin/Config/Routes.php +++ b/modules/Admin/Config/Routes.php @@ -272,6 +272,14 @@ $routes->group( 'permission:podcast_episodes-delete', ], ); + $routes->post( + 'delete', + 'EpisodeController::attemptDelete/$1/$2', + [ + 'filter' => + 'permission:podcast_episodes-delete', + ], + ); $routes->get( 'transcript-delete', 'EpisodeController::transcriptDelete/$1/$2', diff --git a/modules/Admin/Controllers/EpisodeController.php b/modules/Admin/Controllers/EpisodeController.php index 026a625528..078fad1cd2 100644 --- a/modules/Admin/Controllers/EpisodeController.php +++ b/modules/Admin/Controllers/EpisodeController.php @@ -684,9 +684,63 @@ class EpisodeController extends BaseController return redirect()->route('episode-view', [$this->podcast->id, $this->episode->id]); } - public function delete(): RedirectResponse + public function delete(): string { - (new EpisodeModel())->delete($this->episode->id); + helper(['form']); + + $data = [ + 'podcast' => $this->podcast, + 'episode' => $this->episode, + ]; + + replace_breadcrumb_params([ + 0 => $this->podcast->title, + 1 => $this->episode->title, + ]); + return view('episode/delete', $data); + } + + public function attemptDelete(): RedirectResponse + { + $rules = [ + 'understand' => 'required', + ]; + + if (! $this->validate($rules)) { + return redirect() + ->back() + ->withInput() + ->with('errors', $this->validator->getErrors()); + } + + $db = db_connect(); + + $db->transStart(); + + $allPostsLinkedToEpisode = (new PostModel()) + ->where([ + 'episode_id' => $this->episode->id, + ]) + ->findAll(); + foreach ($allPostsLinkedToEpisode as $post) { + (new PostModel())->removePost($post); + } + + // set episode published_at to null to unpublish before deletion + $this->episode->published_at = null; + + $episodeModel = new EpisodeModel(); + if (! $episodeModel->update($this->episode->id, $this->episode)) { + $db->transRollback(); + return redirect() + ->back() + ->withInput() + ->with('errors', $episodeModel->errors()); + } + + $episodeModel->delete($this->episode->id); + + $db->transComplete(); return redirect()->route('episode-list', [$this->podcast->id]); } diff --git a/modules/Admin/Language/en/Breadcrumb.php b/modules/Admin/Language/en/Breadcrumb.php index a0fa5e44e7..a8df8411e5 100644 --- a/modules/Admin/Language/en/Breadcrumb.php +++ b/modules/Admin/Language/en/Breadcrumb.php @@ -23,6 +23,7 @@ return [ 'publish' => 'publish', 'publish-edit' => 'edit publication', 'unpublish' => 'unpublish', + 'delete' => 'delete', 'fediverse' => 'fediverse', 'block-lists' => 'block lists', 'users' => 'users', diff --git a/modules/Admin/Language/en/Episode.php b/modules/Admin/Language/en/Episode.php index 181e446cc9..1761148314 100644 --- a/modules/Admin/Language/en/Episode.php +++ b/modules/Admin/Language/en/Episode.php @@ -137,10 +137,16 @@ return [ ], 'unpublish_form' => [ 'disclaimer' => - "Unpublishing the episode will delete all the notes associated with the episode and remove it from the podcast's RSS feed.", + "Unpublishing the episode will delete all the posts associated with it and remove it from the podcast's RSS feed.", 'understand' => 'I understand, I want to unpublish the episode', 'submit' => 'Unpublish', ], + 'delete_form' => [ + 'disclaimer' => + "Deleting the episode will delete all the posts associated with it and remove it from the podcast's RSS feed.", + 'understand' => 'I understand, I want to delete the episode', + 'submit' => 'Delete', + ], 'soundbites' => 'Soundbites', 'soundbites_form' => [ 'title' => 'Edit soundbites', diff --git a/modules/Admin/Language/fr/Breadcrumb.php b/modules/Admin/Language/fr/Breadcrumb.php index 08d8d888ac..35598decca 100644 --- a/modules/Admin/Language/fr/Breadcrumb.php +++ b/modules/Admin/Language/fr/Breadcrumb.php @@ -23,6 +23,7 @@ return [ 'publish' => 'publier', 'publish-edit' => 'modifier la publication', 'unpublish' => 'dépublier', + 'delete' => 'supprimer', 'fediverse' => 'fédiverse', 'block-lists' => 'listes de blocage', 'users' => 'utilisateurs', diff --git a/modules/Admin/Language/fr/Episode.php b/modules/Admin/Language/fr/Episode.php index 1061e34352..bafa62319b 100644 --- a/modules/Admin/Language/fr/Episode.php +++ b/modules/Admin/Language/fr/Episode.php @@ -141,6 +141,18 @@ return [ 'message_warning_hint' => 'Ajouter un message augmente l’engagement social, menant à une meilleure visibilité pour votre épisode.', 'message_warning_submit' => 'Publish quand même', ], + 'unpublish_form' => [ + 'disclaimer' => + 'Dépublier l’épisode supprimera toutes les publications qui lui sont associées et le retirera du flux RSS du podcast.', + 'understand' => 'Je comprends, je veux dépublier l’épisode', + 'submit' => 'Dépublier', + ], + 'delete_form' => [ + 'disclaimer' => + 'Supprimer l’épisode supprimera toutes les publications qui lui sont associées et le retirera du flux RSS du podcast.', + 'understand' => 'Je comprends, Je veux supprimer l’épisode', + 'submit' => 'Supprimer', + ], 'soundbites' => 'Extraits sonores', 'soundbites_form' => [ 'title' => 'Modifier les extraits sonores', diff --git a/themes/cp_admin/episode/delete.php b/themes/cp_admin/episode/delete.php new file mode 100644 index 0000000000..35a327eb0e --- /dev/null +++ b/themes/cp_admin/episode/delete.php @@ -0,0 +1,27 @@ +<?= $this->extend('_layout') ?> + +<?= $this->section('title') ?> +<?= lang('Episode.delete') ?> +<?= $this->endSection() ?> + +<?= $this->section('pageTitle') ?> +<?= lang('Episode.delete') ?> +<?= $this->endSection() ?> + +<?= $this->section('content') ?> + +<form action="<?= route_to('episode-delete', $podcast->id, $episode->id) ?>" method="POST" class="flex flex-col max-w-xl mx-auto"> +<?= csrf_field() ?> + +<Alert variant="danger" glyph="alert" class="font-semibold"><?= lang('Episode.delete_form.disclaimer') ?></Alert> + +<Forms.Checkbox class="mt-2" name="understand" required="true" isChecked="false"><?= lang('Episode.delete_form.understand') ?></Forms.Checkbox> + +<div class="self-end mt-4"> + <Button uri="<?= route_to('episode-view', $podcast->id, $episode->id) ?>"><?= lang('Common.cancel') ?></Button> + <Button type="submit" variant="danger"><?= lang('Episode.delete_form.submit') ?></Button> +</div> + +</form> + +<?= $this->endSection() ?> diff --git a/themes/cp_admin/episode/unpublish.php b/themes/cp_admin/episode/unpublish.php index 8f8f4ce9dd..a6d420822e 100644 --- a/themes/cp_admin/episode/unpublish.php +++ b/themes/cp_admin/episode/unpublish.php @@ -15,7 +15,7 @@ <Alert variant="danger" glyph="alert" class="font-semibold"><?= lang('Episode.unpublish_form.disclaimer') ?></Alert> -<Forms.Checkbox name="understand" required="true" isChecked="false"><?= lang('Episode.unpublish_form.understand') ?></Forms.Checkbox> +<Forms.Checkbox class="mt-2" name="understand" required="true" isChecked="false"><?= lang('Episode.unpublish_form.understand') ?></Forms.Checkbox> <div class="self-end mt-4"> <Button uri="<?= route_to('episode-view', $podcast->id, $episode->id) ?>"><?= lang('Common.cancel') ?></Button> -- GitLab