feat: add support for podcasting 2.0 "medium" tag with podcast, music and audiobook

closes #439
This commit is contained in:
Guy Martin 2024-02-05 16:51:04 +00:00 committed by Yassine Doghri
parent bc4f93d2b7
commit 630e788f0e
8 changed files with 95 additions and 1 deletions

View File

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
/**
* Class AddPodcastsMediumField adds medium field to podcast table in database
*
* @copyright 2020 Ad Aures
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Database\Migrations;
class AddPodcastsMediumField extends BaseMigration
{
public function up(): void
{
$fields = [
'medium' => [
'type' => "ENUM('podcast','music','audiobook')",
'null' => false,
'default' => 'podcast',
'after' => 'type',
],
];
$this->forge->addColumn('podcasts', $fields);
}
public function down(): void
{
$fields = ['medium'];
$this->forge->dropColumn('podcasts', $fields);
}
}

View File

@ -64,6 +64,7 @@ use RuntimeException;
* @property string $owner_email
* @property bool $is_owner_email_removed_from_feed
* @property string $type
* @property string $medium
* @property string|null $copyright
* @property string|null $episode_description_footer_markdown
* @property string|null $episode_description_footer_html
@ -196,6 +197,7 @@ class Podcast extends Entity
'owner_email' => 'string',
'is_owner_email_removed_from_feed' => 'boolean',
'type' => 'string',
'medium' => 'string',
'copyright' => '?string',
'episode_description_footer_markdown' => '?string',
'episode_description_footer_html' => '?string',

View File

@ -74,6 +74,8 @@ if (! function_exists('get_rss_feed')) {
$channel->addChild('title', $podcast->title, null, false);
$channel->addChildWithCDATA('description', $podcast->description_html);
$channel->addChild('medium', $podcast->medium, $podcastNamespace);
$itunesImage = $channel->addChild('image', null, $itunesNamespace);
$itunesImage->addAttribute('href', $podcast->cover->feed_url);

View File

@ -51,6 +51,7 @@ class PodcastModel extends Model
'is_owner_email_removed_from_feed',
'publisher',
'type',
'medium',
'copyright',
'imported_feed_url',
'new_feed_url',

View File

@ -219,6 +219,7 @@ class PodcastController extends BaseController
'is_owner_email_removed_from_feed' => $this->request->getPost('is_owner_email_removed_from_feed') === 'yes',
'publisher' => $this->request->getPost('publisher'),
'type' => $this->request->getPost('type'),
'medium' => $this->request->getPost('medium'),
'copyright' => $this->request->getPost('copyright'),
'location' => $this->request->getPost('location_name') === '' ? null : new Location(
$this->request->getPost('location_name')
@ -314,6 +315,7 @@ class PodcastController extends BaseController
$this->podcast->owner_name = $this->request->getPost('owner_name');
$this->podcast->owner_email = $this->request->getPost('owner_email');
$this->podcast->type = $this->request->getPost('type');
$this->podcast->medium = $this->request->getPost('medium');
$this->podcast->copyright = $this->request->getPost('copyright');
$this->podcast->location = $this->request->getPost('location_name') === '' ? null : new Location(
$this->request->getPost('location_name')

View File

@ -74,7 +74,17 @@ return [
'episodic' => 'Episodic',
'episodic_hint' => 'If episodes are intended to be consumed without any specific order. Newest episodes will be presented first.',
'serial' => 'Serial',
'serial_hint' => 'If episodes are intended to be consumed in sequential order. The oldest episodes will be presented first.',
'serial_hint' => 'If episodes are intended to be consumed in sequential order. Episodes will be presented in numeric order.',
],
'medium' => [
'label' => 'Medium',
'hint' => 'Medium as represented by podcast:medium tag in RSS. Changing this may change how players present your feed.',
'podcast' => 'Podcast',
'podcast_hint' => 'Describes a feed for a podcast show.',
'music' => 'Music',
'music_hint' => 'A feed of music organized into an "album" with each item a song within the album.',
'audiobook' => 'Audiobook',
'audiobook_hint' => 'Specific types of audio with one item per feed, or where items represent chapters within the book.',
],
'description' => 'Description',
'classification_section_title' => 'Classification',

View File

@ -56,6 +56,26 @@
isChecked="false" ><?= lang('Podcast.form.type.serial') ?></Forms.RadioButton>
</div>
</fieldset>
<fieldset>
<legend><?= lang('Podcast.form.medium.label') ?></legend>
<div class="flex gap-2">
<Forms.RadioButton
value="podcast"
name="medium"
hint="<?= esc(lang('Podcast.form.medium.podcast_hint')) ?>"
isChecked="true" ><?= lang('Podcast.form.medium.podcast') ?></Forms.RadioButton>
<Forms.RadioButton
value="music"
name="medium"
hint="<?= esc(lang('Podcast.form.medium.music_hint')) ?>"
isChecked="false" ><?= lang('Podcast.form.medium.music') ?></Forms.RadioButton>
<Forms.RadioButton
value="audiobook"
name="medium"
hint="<?= esc(lang('Podcast.form.medium.audiobook_hint')) ?>"
isChecked="false" ><?= lang('Podcast.form.medium.audiobook') ?></Forms.RadioButton>
</div>
</fieldset>
</Forms.Section>
<Forms.Section

View File

@ -78,6 +78,27 @@
isChecked="<?= $podcast->type === 'serial' ? 'true' : 'false' ?>" ><?= lang('Podcast.form.type.serial') ?></Forms.RadioButton>
</div>
</fieldset>
<fieldset>
<legend><?= lang('Podcast.form.medium.label') .
hint_tooltip(lang('Podcast.form.medium.hint'), 'ml-1') ?></legend>
<div class="flex gap-2">
<Forms.RadioButton
value="podcast"
name="medium"
hint="<?= esc(lang('Podcast.form.medium.podcast_hint')) ?>"
isChecked="<?= $podcast->medium === 'podcast' ? 'true' : 'false' ?>" ><?= lang('Podcast.form.medium.podcast') ?></Forms.RadioButton>
<Forms.RadioButton
value="music"
name="medium"
hint="<?= esc(lang('Podcast.form.medium.music_hint')) ?>"
isChecked="<?= $podcast->medium === 'music' ? 'true' : 'false' ?>" ><?= lang('Podcast.form.medium.music') ?></Forms.RadioButton>
<Forms.RadioButton
value="audiobook"
name="medium"
hint="<?= esc(lang('Podcast.form.medium.audiobook_hint')) ?>"
isChecked="<?= $podcast->medium === 'audiobook' ? 'true' : 'false' ?>" ><?= lang('Podcast.form.medium.audiobook') ?></Forms.RadioButton>
</div>
</fieldset>
</Forms.Section>
<Forms.Section