diff --git a/app/Views/Components/Forms/Checkbox.php b/app/Views/Components/Forms/Checkbox.php index b93160cae9aa9e5dfdf086c7d3822347f0580a27..02f3af06a6019ca7a603106f73ad1f2b750c214d 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 bb5b6a4391cb89b9499944bdf6dc13cd1f101011..626803b7190170b571697e032eb312b692846e23 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 026a62552852d4037afe084ef1acd70c0e7de044..078fad1cd278739282bb44e9cdb85d98bcad21c4 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 a0fa5e44e707699d601d6f7d285d176e8e6b1034..a8df8411e5ce07ba7be79b7fcbcf2061ba845b40 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 181e446cc9bdaeff7001b3508a33f8200aa935bc..1761148314024a84239eca8ba7a63320034c2e29 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 08d8d888ac87bf879415fe1537662a59ca4b96ac..35598deccac8aa438b8f165a7f210bc3c2c57067 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 1061e34352d453598f7d3895892a22ecd65bc551..bafa62319b8e6bfb1f0d7578f050630cbf2c98d8 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 0000000000000000000000000000000000000000..35a327eb0eceb91df92011c89bb2513b7356ef76 --- /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 8f8f4ce9ddd3bdf742cc1a4c64f7180facb332c4..a6d420822e17712a330d53b8f3cd79acd8b5de22 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>