mirror of
https://code.castopod.org/adaures/castopod
synced 2025-04-19 13:01:19 +00:00
parent
9548337a7c
commit
dbb4030da4
@ -183,10 +183,6 @@ class AddPodcasts extends Migration
|
||||
'updated_at' => [
|
||||
'type' => 'DATETIME',
|
||||
],
|
||||
'deleted_at' => [
|
||||
'type' => 'DATETIME',
|
||||
'null' => true,
|
||||
],
|
||||
]);
|
||||
|
||||
$this->forge->addPrimaryKey('id');
|
||||
|
@ -127,12 +127,6 @@ class AuthSeeder extends Seeder
|
||||
],
|
||||
[
|
||||
'name' => 'delete',
|
||||
'description' =>
|
||||
'Delete a podcast without removing it from database',
|
||||
'has_permission' => ['superadmin'],
|
||||
],
|
||||
[
|
||||
'name' => 'delete_permanently',
|
||||
'description' => 'Delete any podcast from the database',
|
||||
'has_permission' => ['superadmin'],
|
||||
],
|
||||
|
@ -81,7 +81,6 @@ use RuntimeException;
|
||||
* @property int $updated_by
|
||||
* @property Time $created_at;
|
||||
* @property Time $updated_at;
|
||||
* @property Time|null $deleted_at;
|
||||
*
|
||||
* @property Episode[] $episodes
|
||||
* @property Person[] $persons
|
||||
|
@ -73,11 +73,6 @@ class PodcastModel extends Model
|
||||
*/
|
||||
protected $returnType = Podcast::class;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $useSoftDeletes = true;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
|
@ -127,6 +127,9 @@ $routes->group(
|
||||
'as' => 'podcast-delete',
|
||||
'filter' => 'permission:podcasts-delete',
|
||||
]);
|
||||
$routes->post('delete', 'PodcastController::attemptDelete/$1', [
|
||||
'filter' => 'permission:podcasts-delete',
|
||||
]);
|
||||
|
||||
$routes->group('persons', function ($routes): void {
|
||||
$routes->get('/', 'PodcastPersonController/$1', [
|
||||
|
@ -739,8 +739,6 @@ class EpisodeController extends BaseController
|
||||
->with('error', lang('Episode.messages.deletePublishedEpisodeError'));
|
||||
}
|
||||
|
||||
$audio = $this->episode->audio;
|
||||
|
||||
$db = db_connect();
|
||||
|
||||
$db->transStart();
|
||||
@ -755,7 +753,7 @@ class EpisodeController extends BaseController
|
||||
->with('errors', $episodeModel->errors());
|
||||
}
|
||||
|
||||
$episodeMediaList = [$this->episode->transcript, $this->episode->chapters, $audio];
|
||||
$episodeMediaList = [$this->episode->transcript, $this->episode->chapters, $this->episode->audio];
|
||||
|
||||
//only delete episode cover if different from podcast's
|
||||
if ($this->episode->cover_id !== null) {
|
||||
@ -775,6 +773,8 @@ class EpisodeController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
$db->transComplete();
|
||||
|
||||
$warnings = [];
|
||||
|
||||
//remove episode media files from disk
|
||||
@ -787,8 +787,6 @@ class EpisodeController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
$db->transComplete();
|
||||
|
||||
if ($warnings !== []) {
|
||||
return redirect()
|
||||
->route('episode-list', [$this->podcast->id])
|
||||
|
@ -21,6 +21,15 @@ use App\Models\PodcastModel;
|
||||
use CodeIgniter\Exceptions\PageNotFoundException;
|
||||
use CodeIgniter\HTTP\RedirectResponse;
|
||||
use Config\Services;
|
||||
use Modules\Analytics\Models\AnalyticsPodcastByCountryModel;
|
||||
use Modules\Analytics\Models\AnalyticsPodcastByEpisodeModel;
|
||||
use Modules\Analytics\Models\AnalyticsPodcastByHourModel;
|
||||
use Modules\Analytics\Models\AnalyticsPodcastByPlayerModel;
|
||||
use Modules\Analytics\Models\AnalyticsPodcastByRegionModel;
|
||||
use Modules\Analytics\Models\AnalyticsPodcastModel;
|
||||
use Modules\Analytics\Models\AnalyticsWebsiteByBrowserModel;
|
||||
use Modules\Analytics\Models\AnalyticsWebsiteByEntryPageModel;
|
||||
use Modules\Analytics\Models\AnalyticsWebsiteByRefererModel;
|
||||
|
||||
class PodcastController extends BaseController
|
||||
{
|
||||
@ -420,10 +429,166 @@ class PodcastController extends BaseController
|
||||
]);
|
||||
}
|
||||
|
||||
public function delete(): RedirectResponse
|
||||
public function delete(): string
|
||||
{
|
||||
(new PodcastModel())->delete($this->podcast->id);
|
||||
helper(['form']);
|
||||
|
||||
return redirect()->route('podcast-list');
|
||||
$data = [
|
||||
'podcast' => $this->podcast,
|
||||
];
|
||||
|
||||
replace_breadcrumb_params([
|
||||
0 => $this->podcast->title,
|
||||
]);
|
||||
return view('podcast/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();
|
||||
|
||||
//delete podcast episodes
|
||||
$podcastEpisodes = (new EpisodeModel())->where('podcast_id', $this->podcast->id)
|
||||
->findAll();
|
||||
|
||||
foreach ($podcastEpisodes as $podcastEpisode) {
|
||||
$episodeModel = new EpisodeModel();
|
||||
|
||||
if (! $episodeModel->delete($podcastEpisode->id)) {
|
||||
$db->transRollback();
|
||||
return redirect()
|
||||
->back()
|
||||
->withInput()
|
||||
->with('errors', $episodeModel->errors());
|
||||
}
|
||||
|
||||
$episodeMediaList = [$podcastEpisode->transcript, $podcastEpisode->chapters, $podcastEpisode->audio];
|
||||
|
||||
//only delete episode cover if different from podcast's
|
||||
if ($podcastEpisode->cover_id !== null) {
|
||||
$episodeMediaList[] = $podcastEpisode->cover;
|
||||
}
|
||||
|
||||
foreach ($episodeMediaList as $episodeMedia) {
|
||||
if ($episodeMedia !== null && ! $episodeMedia->delete()) {
|
||||
$db->transRollback();
|
||||
return redirect()
|
||||
->back()
|
||||
->withInput()
|
||||
->with('error', lang('Podcast.messages.deleteEpisodeMediaError', [
|
||||
'episode_slug' => $podcastEpisode->slug,
|
||||
'type' => $episodeMedia->type,
|
||||
]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//delete podcast
|
||||
$podcastModel = new PodcastModel();
|
||||
|
||||
if (! $podcastModel->delete($this->podcast->id)) {
|
||||
$db->transRollback();
|
||||
return redirect()
|
||||
->back()
|
||||
->withInput()
|
||||
->with('errors', $podcastModel->errors());
|
||||
}
|
||||
|
||||
//delete podcast media
|
||||
$podcastMediaList = [
|
||||
[
|
||||
'type' => 'cover',
|
||||
'file' => $this->podcast->cover,
|
||||
],
|
||||
[
|
||||
'type' => 'banner',
|
||||
'file' => $this->podcast->banner,
|
||||
],
|
||||
];
|
||||
|
||||
foreach ($podcastMediaList as $podcastMedia) {
|
||||
if ($podcastMedia['file'] !== null && ! $podcastMedia['file']->delete()) {
|
||||
$db->transRollback();
|
||||
return redirect()
|
||||
->back()
|
||||
->withInput()
|
||||
->with('error', lang('Podcast.messages.deletePodcastMediaError', [
|
||||
'type' => $podcastMedia['type'],
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
//delete podcast actor
|
||||
$actorModel = new ActorModel();
|
||||
|
||||
if (! $actorModel->delete($this->podcast->actor_id)) {
|
||||
$db->transRollback();
|
||||
return redirect()
|
||||
->back()
|
||||
->withInput()
|
||||
->with('errors', $actorModel->errors());
|
||||
}
|
||||
|
||||
//delete podcast analytics
|
||||
$analyticsModels = [
|
||||
new AnalyticsPodcastModel(),
|
||||
new AnalyticsPodcastByCountryModel(),
|
||||
new AnalyticsPodcastByEpisodeModel(),
|
||||
new AnalyticsPodcastByHourModel(),
|
||||
new AnalyticsPodcastByPlayerModel(),
|
||||
new AnalyticsPodcastByRegionModel(),
|
||||
new AnalyticsWebsiteByBrowserModel(),
|
||||
new AnalyticsWebsiteByEntryPageModel(),
|
||||
new AnalyticsWebsiteByRefererModel(),
|
||||
];
|
||||
foreach ($analyticsModels as $analyticsModel) {
|
||||
if (! $analyticsModel->where([
|
||||
'podcast_id' => $this->podcast->id,
|
||||
])->delete()) {
|
||||
$db->transRollback();
|
||||
return redirect()
|
||||
->back()
|
||||
->withInput()
|
||||
->with('errors', $analyticsModel->errors());
|
||||
}
|
||||
}
|
||||
|
||||
$db->transComplete();
|
||||
|
||||
//delete podcast media files and folder
|
||||
$folder = 'podcasts/' . $this->podcast->handle;
|
||||
|
||||
$mediaRoot = config('App')
|
||||
->mediaRoot . '/' . $folder;
|
||||
|
||||
helper('filesystem');
|
||||
|
||||
if (! delete_files($mediaRoot) || ! rmdir($mediaRoot)) {
|
||||
return redirect()->route('podcast-list')
|
||||
->with('message', lang('Podcast.messages.deleteSuccess', [
|
||||
'podcast_handle' => $this->podcast->handle,
|
||||
]))
|
||||
->with('warning', lang('Podcast.messages.deletePodcastMediaFolderError', [
|
||||
'folder_path' => $folder,
|
||||
]));
|
||||
}
|
||||
|
||||
return redirect()->route('podcast-list')
|
||||
->with('message', lang('Podcast.messages.deleteSuccess', [
|
||||
'podcast_handle' => $this->podcast->handle,
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ return [
|
||||
image {cover}
|
||||
audio {audio}
|
||||
other {media}
|
||||
} file {file_path}. You must manually remove it from your disk.',
|
||||
} file {file_path}. You may manually remove it from your disk.',
|
||||
'sameSlugError' => 'An episode with the chosen slug already exists.',
|
||||
],
|
||||
'form' => [
|
||||
|
@ -26,6 +26,20 @@ return [
|
||||
'createSuccess' => 'Podcast has been successfully created!',
|
||||
'editSuccess' => 'Podcast has been successfully updated!',
|
||||
'importSuccess' => 'Podcast has been successfully imported!',
|
||||
'deleteSuccess' => 'Podcast @{podcast_handle} successfully deleted!',
|
||||
'deletePodcastMediaError' => 'Failed to delete podcast {type, select,
|
||||
cover {cover}
|
||||
banner {banner}
|
||||
other {media}
|
||||
}.',
|
||||
'deleteEpisodeMediaError' => 'Failed to delete podcast episode {episode_slug} {type, select,
|
||||
transcript {transcript}
|
||||
chapters {chapters}
|
||||
image {cover}
|
||||
audio {audio}
|
||||
other {media}
|
||||
}.',
|
||||
'deletePodcastMediaFolderError' => 'Failed to delete podcast media folder {folder_path}. You may manually remove it from your disk.',
|
||||
],
|
||||
'form' => [
|
||||
'identity_section_title' => 'Podcast identity',
|
||||
@ -219,6 +233,12 @@ return [
|
||||
'film_reviews' => 'Film Reviews',
|
||||
'tv_reviews' => 'TV Reviews',
|
||||
],
|
||||
'delete_form' => [
|
||||
'disclaimer' =>
|
||||
"Deleting the podcast will delete all episodes, media files, posts and analytics associated with it. This action is irreversible, you will not be able to retrieve them afterwards.",
|
||||
'understand' => 'I understand, I want the podcast to be permanently deleted',
|
||||
'submit' => 'Delete',
|
||||
],
|
||||
'by' => 'By {publisher}',
|
||||
'season' => 'Season {seasonNumber}',
|
||||
'list_of_episodes_year' => '{year} episodes ({episodeCount})',
|
||||
|
@ -115,12 +115,6 @@ class AuthSeeder extends Seeder
|
||||
],
|
||||
[
|
||||
'name' => 'delete',
|
||||
'description' =>
|
||||
'Delete a podcast without removing it from database',
|
||||
'has_permission' => ['superadmin'],
|
||||
],
|
||||
[
|
||||
'name' => 'delete_permanently',
|
||||
'description' => 'Delete any podcast from the database',
|
||||
'has_permission' => ['superadmin'],
|
||||
],
|
||||
|
@ -18,6 +18,10 @@ if (session()->has('message')): ?>
|
||||
</Alert>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (session()->has('warning')): ?>
|
||||
<Alert variant="warning" class="mb-4"><?= esc(session('warning')) ?></Alert>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (session()->has('warnings')): ?>
|
||||
<Alert variant="warning" class="mb-4">
|
||||
<ul>
|
||||
|
27
themes/cp_admin/podcast/delete.php
Normal file
27
themes/cp_admin/podcast/delete.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?= $this->extend('_layout') ?>
|
||||
|
||||
<?= $this->section('title') ?>
|
||||
<?= lang('Podcast.delete') ?>
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('pageTitle') ?>
|
||||
<?= lang('Podcast.delete') ?>
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?= $this->section('content') ?>
|
||||
|
||||
<form action="<?= route_to('podcast-delete', $podcast->id) ?>" method="POST" class="flex flex-col w-full max-w-xl mx-auto">
|
||||
<?= csrf_field() ?>
|
||||
|
||||
<Alert variant="danger" glyph="alert" class="font-semibold"><?= lang('Podcast.delete_form.disclaimer') ?></Alert>
|
||||
|
||||
<Forms.Checkbox class="mt-2" name="understand" required="true" isChecked="false"><?= lang('Podcast.delete_form.understand') ?></Forms.Checkbox>
|
||||
|
||||
<div class="self-end mt-4">
|
||||
<Button uri="<?= route_to('podcast-view', $podcast->id) ?>"><?= lang('Common.cancel') ?></Button>
|
||||
<Button type="submit" variant="danger"><?= lang('Podcast.delete_form.submit') ?></Button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<?= $this->endSection() ?>
|
@ -244,9 +244,10 @@
|
||||
</Forms.Toggler>
|
||||
</Forms.Section>
|
||||
|
||||
<Button variant="primary" type="submit" class="self-end"><?= lang('Podcast.form.submit_edit') ?></Button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
<Button class="mt-8" variant="danger" uri="<?= route_to('podcast-delete', $podcast->id) ?>" iconLeft="delete-bin"><?= lang('Podcast.delete') ?></Button>
|
||||
|
||||
<?= $this->endSection() ?>
|
||||
|
Loading…
x
Reference in New Issue
Block a user