Newer
Older

Yassine Doghri
committed
<?php

Yassine Doghri
committed

Yassine Doghri
committed
/**
* @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Controllers\Admin;
use App\Models\EpisodeModel;
use App\Models\PodcastModel;
use App\Models\SoundbiteModel;

Yassine Doghri
committed
use CodeIgniter\I18n\Time;

Yassine Doghri
committed
class Episode extends BaseController
{
/**
* @var \App\Entities\Podcast
*/
protected $podcast;
/**
* @var \App\Entities\Episode|null
*/
protected $episode;

Yassine Doghri
committed
/**
* @var \App\Entities\Soundbite|null
*/
protected $soundbites;

Yassine Doghri
committed
public function _remap($method, ...$params)
{
$this->podcast = (new PodcastModel())->getPodcastById($params[0]);

Yassine Doghri
committed
if (count($params) > 1) {
if (

Yassine Doghri
committed
!($this->episode = (new EpisodeModel())

Yassine Doghri
committed
->where([
'id' => $params[1],
'podcast_id' => $params[0],

Yassine Doghri
committed
])
->first())
) {
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
}
unset($params[1]);
unset($params[0]);

Yassine Doghri
committed
}
return $this->$method(...$params);

Yassine Doghri
committed
}
public function list()
{
$episodes = (new EpisodeModel())
->where('podcast_id', $this->podcast->id)
->orderBy('created_at', 'desc');

Yassine Doghri
committed
$data = [
'podcast' => $this->podcast,
'episodes' => $episodes->paginate(10),
'pager' => $episodes->pager,

Yassine Doghri
committed
];
replace_breadcrumb_params([
0 => $this->podcast->title,
]);

Yassine Doghri
committed
return view('admin/episode/list', $data);
}
public function view()
{
$data = [
'podcast' => $this->podcast,
'episode' => $this->episode,
];
replace_breadcrumb_params([
0 => $this->podcast->title,
1 => $this->episode->title,
]);
return view('admin/episode/view', $data);
}

Yassine Doghri
committed
public function create()
{
helper(['form']);
$data = [
'podcast' => $this->podcast,
];

Yassine Doghri
committed
replace_breadcrumb_params([
0 => $this->podcast->title,
]);
return view('admin/episode/create', $data);

Yassine Doghri
committed
public function attemptCreate()
{
$rules = [
'enclosure' => 'uploaded[enclosure]|ext_in[enclosure,mp3,m4a]',
'image' =>
'is_image[image]|ext_in[image,jpg,png]|min_dims[image,1400,1400]|is_image_squared[image]',
'transcript' => 'ext_in[transcript,txt,html,srt,json]',
'chapters' => 'ext_in[chapters,json]',

Yassine Doghri
committed
'publication_date' => 'valid_date[Y-m-d H:i]|permit_empty',
];
if (!$this->validate($rules)) {
return redirect()
->back()
->withInput()
->with('errors', $this->validator->getErrors());

Yassine Doghri
committed
}

Yassine Doghri
committed
$publicationDate = $this->request->getPost('publication_date');

Yassine Doghri
committed
$newEpisode = new \App\Entities\Episode([
'podcast_id' => $this->podcast->id,
'title' => $this->request->getPost('title'),
'slug' => $this->request->getPost('slug'),
'enclosure' => $this->request->getFile('enclosure'),
'description_markdown' => $this->request->getPost('description'),
'image' => $this->request->getFile('image'),
'location' => $this->request->getPost('location_name'),
'transcript' => $this->request->getFile('transcript'),
'chapters' => $this->request->getFile('chapters'),
'parental_advisory' =>
$this->request->getPost('parental_advisory') !== 'undefined'
? $this->request->getPost('parental_advisory')
: null,

Yassine Doghri
committed
'number' => $this->request->getPost('episode_number')
? $this->request->getPost('episode_number')
: null,
'season_number' => $this->request->getPost('season_number')
? $this->request->getPost('season_number')
: null,
'type' => $this->request->getPost('type'),
'is_blocked' => $this->request->getPost('block') == 'yes',
'created_by' => user(),
'updated_by' => user(),

Yassine Doghri
committed
'published_at' => $publicationDate
? Time::createFromFormat(
'Y-m-d H:i',
$publicationDate,
$this->request->getPost('client_timezone')
)->setTimezone('UTC')
: null,
]);

Yassine Doghri
committed
$episodeModel = new EpisodeModel();
if (!($newEpisodeId = $episodeModel->insert($newEpisode, true))) {
return redirect()
->back()
->withInput()

Yassine Doghri
committed
->with('errors', $episodeModel->errors());
}
// update podcast's episode_description_footer_markdown if changed
$podcastModel = new PodcastModel();
if ($this->podcast->hasChanged('episode_description_footer_markdown')) {
$this->podcast->episode_description_footer_markdown = $this->request->getPost(
'description_footer'
);
if (!$podcastModel->update($this->podcast->id, $this->podcast)) {
return redirect()
->back()
->withInput()
->with('errors', $podcastModel->errors());
}
}
return redirect()->route('episode-view', [
$this->podcast->id,
$newEpisodeId,
]);

Yassine Doghri
committed
}
public function edit()
{
helper(['form']);
$data = [
'podcast' => $this->podcast,
'episode' => $this->episode,
];

Yassine Doghri
committed
replace_breadcrumb_params([
0 => $this->podcast->title,
1 => $this->episode->title,
]);
return view('admin/episode/edit', $data);
}
public function attemptEdit()
{
$rules = [
'enclosure' =>
'uploaded[enclosure]|ext_in[enclosure,mp3,m4a]|permit_empty',
'image' =>
'is_image[image]|ext_in[image,jpg,png]|min_dims[image,1400,1400]|is_image_squared[image]',
'transcript' => 'ext_in[transcript,txt,html,srt,json]',
'chapters' => 'ext_in[chapters,json]',

Yassine Doghri
committed
'publication_date' => 'valid_date[Y-m-d H:i]|permit_empty',
];
if (!$this->validate($rules)) {
return redirect()
->back()
->withInput()
->with('errors', $this->validator->getErrors());
}

Yassine Doghri
committed
$this->episode->title = $this->request->getPost('title');
$this->episode->slug = $this->request->getPost('slug');
$this->episode->description_markdown = $this->request->getPost(
'description'
);
$this->episode->location = $this->request->getPost('location_name');
$this->episode->parental_advisory =
$this->request->getPost('parental_advisory') !== 'undefined'
? $this->request->getPost('parental_advisory')
: null;

Yassine Doghri
committed
$this->episode->number = $this->request->getPost('episode_number')
? $this->request->getPost('episode_number')
: null;
$this->episode->season_number = $this->request->getPost('season_number')
? $this->request->getPost('season_number')
: null;
$this->episode->type = $this->request->getPost('type');
$this->episode->is_blocked = $this->request->getPost('block') == 'yes';

Yassine Doghri
committed
$publicationDate = $this->request->getPost('publication_date');
$this->episode->published_at = $publicationDate
? Time::createFromFormat(
'Y-m-d H:i',
$publicationDate,
$this->request->getPost('client_timezone')
)->setTimezone('UTC')
: null;
$this->episode->updated_by = user();
$enclosure = $this->request->getFile('enclosure');
if ($enclosure->isValid()) {
$this->episode->enclosure = $enclosure;

Yassine Doghri
committed
}
$image = $this->request->getFile('image');
if ($image) {
$this->episode->image = $image;
}
$transcript = $this->request->getFile('transcript');
if ($transcript->isValid()) {
$this->episode->transcript = $transcript;
}
$chapters = $this->request->getFile('chapters');
if ($chapters->isValid()) {
$this->episode->chapters = $chapters;
}

Yassine Doghri
committed
$episodeModel = new EpisodeModel();
if (!$episodeModel->update($this->episode->id, $this->episode)) {
return redirect()
->back()
->withInput()

Yassine Doghri
committed
->with('errors', $episodeModel->errors());
}
// update podcast's episode_description_footer_markdown if changed
$this->podcast->episode_description_footer_markdown = $this->request->getPost(
'description_footer'
);
if ($this->podcast->hasChanged('episode_description_footer_markdown')) {
$podcastModel = new PodcastModel();
if (!$podcastModel->update($this->podcast->id, $this->podcast)) {
return redirect()
->back()
->withInput()
->with('errors', $podcastModel->errors());
}
}
return redirect()->route('episode-view', [
$this->podcast->id,
$this->episode->id,
]);

Yassine Doghri
committed
}
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
public function transcriptDelete()
{
unlink($this->episode->transcript);
$this->episode->transcript_uri = null;
$episodeModel = new EpisodeModel();
if (!$episodeModel->update($this->episode->id, $this->episode)) {
return redirect()
->back()
->withInput()
->with('errors', $episodeModel->errors());
}
return redirect()->back();
}
public function chaptersDelete()
{
unlink($this->episode->chapters);
$this->episode->chapters_uri = null;
$episodeModel = new EpisodeModel();
if (!$episodeModel->update($this->episode->id, $this->episode)) {
return redirect()
->back()
->withInput()
->with('errors', $episodeModel->errors());
}
return redirect()->back();
}

Yassine Doghri
committed
public function delete()
{

Yassine Doghri
committed
(new EpisodeModel())->delete($this->episode->id);

Yassine Doghri
committed
return redirect()->route('episode-list', [$this->podcast->id]);

Yassine Doghri
committed
}
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
public function soundbitesEdit()
{
helper(['form']);
$data = [
'podcast' => $this->podcast,
'episode' => $this->episode,
];
replace_breadcrumb_params([
0 => $this->podcast->title,
1 => $this->episode->title,
]);
return view('admin/episode/soundbites', $data);
}
public function soundbitesAttemptEdit()
{
$soundbites_array = $this->request->getPost('soundbites_array');
$rules = [
'soundbites_array.0.start_time' =>
'permit_empty|required_with[soundbites_array.0.duration]|decimal|greater_than_equal_to[0]',
'soundbites_array.0.duration' =>
'permit_empty|required_with[soundbites_array.0.start_time]|decimal|greater_than_equal_to[0]',
];
foreach ($soundbites_array as $soundbite_id => $soundbite) {
$rules += [
"soundbites_array.{$soundbite_id}.start_time" => 'required|decimal|greater_than_equal_to[0]',
"soundbites_array.{$soundbite_id}.duration" => 'required|decimal|greater_than_equal_to[0]',
];
}
if (!$this->validate($rules)) {
return redirect()
->back()
->withInput()
->with('errors', $this->validator->getErrors());
}
foreach ($soundbites_array as $soundbite_id => $soundbite) {
if (
!empty($soundbite['start_time']) &&
!empty($soundbite['duration'])
) {
$data = [
'podcast_id' => $this->podcast->id,
'episode_id' => $this->episode->id,
'start_time' => $soundbite['start_time'],
'duration' => $soundbite['duration'],
'label' => $soundbite['label'],
'updated_by' => user()->id,
];
if ($soundbite_id == 0) {
$data += ['created_by' => user()->id];
} else {
$data += ['id' => $soundbite_id];
}
$soundbiteModel = new SoundbiteModel();
if (!$soundbiteModel->save($data)) {
return redirect()
->back()
->withInput()
->with('errors', $soundbiteModel->errors());
}
}
}
return redirect()->route('soundbites-edit', [
$this->podcast->id,
$this->episode->id,
]);
}
public function soundbiteDelete($soundbiteId)
{
(new SoundbiteModel())->deleteSoundbite(
$this->podcast->id,
$this->episode->id,
$soundbiteId
);
return redirect()->route('soundbites-edit', [
$this->podcast->id,
$this->episode->id,
]);
}