From c0a22829bd87d48535a86e60c6cd7280e44683a2 Mon Sep 17 00:00:00 2001 From: Benjamin Bellamy <ben@podlibre.org> Date: Wed, 23 Dec 2020 14:11:38 +0000 Subject: [PATCH] feat(rss): add podcast:location tag --- app/Controllers/Admin/Episode.php | 2 + app/Controllers/Admin/Podcast.php | 2 + app/Controllers/Admin/PodcastImport.php | 41 +++++++++++-- .../2020-05-30-101500_add_podcasts.php | 15 +++++ .../2020-06-05-170000_add_episodes.php | 15 +++++ app/Entities/Episode.php | 31 ++++++++++ app/Entities/Podcast.php | 31 ++++++++++ app/Helpers/components_helper.php | 59 ++++++++++++++++++- app/Helpers/location_helper.php | 52 ++++++++++++++++ app/Helpers/rss_helper.php | 38 +++++++++++- app/Language/en/Episode.php | 4 ++ app/Language/en/Podcast.php | 4 ++ app/Language/fr/Episode.php | 6 +- app/Language/fr/Podcast.php | 4 ++ app/Models/EpisodeModel.php | 3 + app/Models/PodcastModel.php | 3 + app/Views/_assets/icons/map-pin.svg | 1 + app/Views/admin/episode/create.php | 19 ++++++ app/Views/admin/episode/edit.php | 19 ++++++ app/Views/admin/episode/view.php | 6 ++ app/Views/admin/podcast/create.php | 40 +++++++++++-- app/Views/admin/podcast/edit.php | 23 +++++++- app/Views/admin/podcast/view.php | 6 ++ app/Views/episode.php | 6 ++ app/Views/podcast.php | 6 ++ 25 files changed, 421 insertions(+), 15 deletions(-) create mode 100644 app/Helpers/location_helper.php create mode 100644 app/Views/_assets/icons/map-pin.svg diff --git a/app/Controllers/Admin/Episode.php b/app/Controllers/Admin/Episode.php index d85c58db18..8ad5ce6f92 100644 --- a/app/Controllers/Admin/Episode.php +++ b/app/Controllers/Admin/Episode.php @@ -126,6 +126,7 @@ class Episode extends BaseController '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' => @@ -222,6 +223,7 @@ class Episode extends BaseController $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') diff --git a/app/Controllers/Admin/Podcast.php b/app/Controllers/Admin/Podcast.php index 359bee6162..706a9e6c0e 100644 --- a/app/Controllers/Admin/Podcast.php +++ b/app/Controllers/Admin/Podcast.php @@ -161,6 +161,7 @@ class Podcast extends BaseController 'publisher' => $this->request->getPost('publisher'), 'type' => $this->request->getPost('type'), 'copyright' => $this->request->getPost('copyright'), + 'location' => $this->request->getPost('location_name'), 'payment_pointer' => $this->request->getPost('payment_pointer'), 'is_blocked' => $this->request->getPost('is_blocked') === 'yes', 'is_completed' => $this->request->getPost('complete') === 'yes', @@ -254,6 +255,7 @@ class Podcast extends BaseController $this->podcast->owner_email = $this->request->getPost('owner_email'); $this->podcast->type = $this->request->getPost('type'); $this->podcast->copyright = $this->request->getPost('copyright'); + $this->podcast->location = $this->request->getPost('location_name'); $this->podcast->payment_pointer = $this->request->getPost( 'payment_pointer' ); diff --git a/app/Controllers/Admin/PodcastImport.php b/app/Controllers/Admin/PodcastImport.php index c4c5def8a7..0ae92f15ca 100644 --- a/app/Controllers/Admin/PodcastImport.php +++ b/app/Controllers/Admin/PodcastImport.php @@ -121,11 +121,13 @@ class PodcastImport extends BaseController $channelDescriptionHtml ), 'description_html' => $channelDescriptionHtml, - 'image' => $nsItunes->image && !empty($nsItunes->image->attributes()) - ? download_file($nsItunes->image->attributes()) - : ($feed->channel[0]->image && !empty($feed->channel[0]->image->url) - ? download_file($feed->channel[0]->image->url) - : null), + 'image' => + $nsItunes->image && !empty($nsItunes->image->attributes()) + ? download_file($nsItunes->image->attributes()) + : ($feed->channel[0]->image && + !empty($feed->channel[0]->image->url) + ? download_file($feed->channel[0]->image->url) + : null), 'language_code' => $this->request->getPost('language'), 'category_id' => $this->request->getPost('category'), 'parental_advisory' => empty($nsItunes->explicit) @@ -146,6 +148,19 @@ class PodcastImport extends BaseController 'is_completed' => empty($nsItunes->complete) ? false : $nsItunes->complete === 'yes', + 'location_name' => !$nsPodcast->location + ? null + : $nsPodcast->location->attributes()['name'], + 'location_geo' => + !$nsPodcast->location || + empty($nsPodcast->location->attributes()['geo']) + ? null + : $nsPodcast->location->attributes()['geo'], + 'location_osmid' => + !$nsPodcast->location || + empty($nsPodcast->location->attributes()['osmid']) + ? null + : $nsPodcast->location->attributes()['osmid'], 'created_by' => user(), 'updated_by' => user(), ]); @@ -243,6 +258,9 @@ class PodcastImport extends BaseController $nsItunes = $item->children( 'http://www.itunes.com/dtds/podcast-1.0.dtd' ); + $nsPodcast = $item->children( + 'https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md' + ); $slug = slugify( $this->request->getPost('slug_field') === 'title' @@ -306,6 +324,19 @@ class PodcastImport extends BaseController 'is_blocked' => empty($nsItunes->block) ? false : $nsItunes->block === 'yes', + 'location_name' => !$nsPodcast->location + ? null + : $nsPodcast->location->attributes()['name'], + 'location_geo' => + !$nsPodcast->location || + empty($nsPodcast->location->attributes()['geo']) + ? null + : $nsPodcast->location->attributes()['geo'], + 'location_osmid' => + !$nsPodcast->location || + empty($nsPodcast->location->attributes()['osmid']) + ? null + : $nsPodcast->location->attributes()['osmid'], 'created_by' => user(), 'updated_by' => user(), 'published_at' => strtotime($item->pubDate), diff --git a/app/Database/Migrations/2020-05-30-101500_add_podcasts.php b/app/Database/Migrations/2020-05-30-101500_add_podcasts.php index 30ba95eda5..19a816163a 100644 --- a/app/Database/Migrations/2020-05-30-101500_add_podcasts.php +++ b/app/Database/Migrations/2020-05-30-101500_add_podcasts.php @@ -123,6 +123,21 @@ class AddPodcasts extends Migration 'comment' => 'Wallet address for Web Monetization payments', 'null' => true, ], + 'location_name' => [ + 'type' => 'VARCHAR', + 'constraint' => 128, + 'null' => true, + ], + 'location_geo' => [ + 'type' => 'VARCHAR', + 'constraint' => 32, + 'null' => true, + ], + 'location_osmid' => [ + 'type' => 'VARCHAR', + 'constraint' => 12, + 'null' => true, + ], 'created_by' => [ 'type' => 'INT', 'unsigned' => true, diff --git a/app/Database/Migrations/2020-06-05-170000_add_episodes.php b/app/Database/Migrations/2020-06-05-170000_add_episodes.php index 8147df8fb1..7d33d94226 100644 --- a/app/Database/Migrations/2020-06-05-170000_add_episodes.php +++ b/app/Database/Migrations/2020-06-05-170000_add_episodes.php @@ -109,6 +109,21 @@ class AddEpisodes extends Migration 'constraint' => 1, 'default' => 0, ], + 'location_name' => [ + 'type' => 'VARCHAR', + 'constraint' => 128, + 'null' => true, + ], + 'location_geo' => [ + 'type' => 'VARCHAR', + 'constraint' => 32, + 'null' => true, + ], + 'location_osmid' => [ + 'type' => 'VARCHAR', + 'constraint' => 12, + 'null' => true, + ], 'created_by' => [ 'type' => 'INT', 'unsigned' => true, diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php index 65c14e0f17..4249defe87 100644 --- a/app/Entities/Episode.php +++ b/app/Entities/Episode.php @@ -120,6 +120,9 @@ class Episode extends Entity 'season_number' => '?integer', 'type' => 'string', 'is_blocked' => 'boolean', + 'location_name' => '?string', + 'location_geo' => '?string', + 'location_osmid' => '?string', 'created_by' => 'integer', 'updated_by' => 'integer', ]; @@ -479,4 +482,32 @@ class Episode extends Entity return 'scheduled'; } + + /** + * Saves the location name and fetches OpenStreetMap info + * + * @param string $locationName + * + */ + public function setLocation($locationName = null) + { + helper('location'); + + if ( + $locationName && + (empty($this->attributes['location_name']) || + $this->attributes['location_name'] != $locationName) + ) { + $this->attributes['location_name'] = $locationName; + if ($location = fetch_osm_location($locationName)) { + $this->attributes['location_geo'] = $location['geo']; + $this->attributes['location_osmid'] = $location['osmid']; + } + } elseif (empty($locationName)) { + $this->attributes['location_name'] = null; + $this->attributes['location_geo'] = null; + $this->attributes['location_osmid'] = null; + } + return $this; + } } diff --git a/app/Entities/Podcast.php b/app/Entities/Podcast.php index 8b8076b5b4..8782a0a7d6 100644 --- a/app/Entities/Podcast.php +++ b/app/Entities/Podcast.php @@ -96,6 +96,9 @@ class Podcast extends Entity 'is_locked' => 'boolean', 'imported_feed_url' => '?string', 'new_feed_url' => '?string', + 'location_name' => '?string', + 'location_geo' => '?string', + 'location_osmid' => '?string', 'payment_pointer' => '?string', 'created_by' => 'integer', 'updated_by' => 'integer', @@ -367,4 +370,32 @@ class Podcast extends Entity return $this->other_categories_ids; } + + /** + * Saves the location name and fetches OpenStreetMap info + * + * @param string $locationName + * + */ + public function setLocation($locationName = null) + { + helper('location'); + + if ( + $locationName && + (empty($this->attributes['location_name']) || + $this->attributes['location_name'] != $locationName) + ) { + $this->attributes['location_name'] = $locationName; + if ($location = fetch_osm_location($locationName)) { + $this->attributes['location_geo'] = $location['geo']; + $this->attributes['location_osmid'] = $location['osmid']; + } + } elseif (empty($locationName)) { + $this->attributes['location_name'] = null; + $this->attributes['location_geo'] = null; + $this->attributes['location_osmid'] = null; + } + return $this; + } } diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php index df2c00b8f9..3d69bab2cc 100644 --- a/app/Helpers/components_helper.php +++ b/app/Helpers/components_helper.php @@ -318,7 +318,7 @@ if (!function_exists('episode_numbering')) { * @param string $class styling classes * @param string $is_abbr component will show abbreviated numbering if true * - * @return string + * @return string|null */ function episode_numbering( $episodeNumber = null, @@ -368,4 +368,61 @@ if (!function_exists('episode_numbering')) { } } +if (!function_exists('location_link')) { + /** + * Returns link to display from location info + * + * @param string $locationName + * @param string $locationGeo + * @param string $locationOsmid + * + * @return string + */ + function location_link( + $locationName, + $locationGeo, + $locationOsmid, + $class = '' + ) { + $link = null; + if (!empty($locationName)) { + $uri = ''; + if (!empty($locationOsmid)) { + $uri = + 'https://www.openstreetmap.org/' . + ['N' => 'node', 'W' => 'way', 'R' => 'relation'][ + substr($locationOsmid, 0, 1) + ] . + '/' . + substr($locationOsmid, 1); + } elseif (!empty($locationGeo)) { + $uri = + 'https://www.openstreetmap.org/#map=17/' . + str_replace(',', '/', substr($locationGeo, 4)); + } else { + $uri = + 'https://www.openstreetmap.org/search?query=' . + urlencode($locationName); + } + $link = button( + $locationName, + $uri, + [ + 'variant' => 'default', + 'size' => 'small', + 'isRoundedFull' => true, + 'iconLeft' => 'map-pin', + ], + [ + 'class' => + 'text-gray-800' . (empty($class) ? '' : " $class"), + 'target' => '_blank', + 'rel' => 'noreferrer noopener', + ] + ); + } + return $link; + } +} + // ------------------------------------------------------------------------ diff --git a/app/Helpers/location_helper.php b/app/Helpers/location_helper.php new file mode 100644 index 0000000000..4b4207c383 --- /dev/null +++ b/app/Helpers/location_helper.php @@ -0,0 +1,52 @@ +<?php + +/** + * @copyright 2020 Podlibre + * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 + * @link https://castopod.org/ + */ + +/** + * Fetches places from Nominatim OpenStreetMap + * + * @param string $locationName + * + * @return array|null + */ +function fetch_osm_location($locationName) +{ + $osmObject = null; + if (!empty($locationName)) { + try { + $client = \Config\Services::curlrequest(); + + $response = $client->request( + 'GET', + 'https://nominatim.openstreetmap.org/search.php?q=' . + urlencode($locationName) . + '&polygon_geojson=1&format=jsonv2', + [ + 'headers' => [ + 'User-Agent' => 'Castopod/' . CP_VERSION, + 'Accept' => 'application/json', + ], + ] + ); + $places = json_decode($response->getBody(), true); + $osmObject = [ + 'geo' => + empty($places[0]['lat']) || empty($places[0]['lon']) + ? null + : "geo:{$places[0]['lat']},{$places[0]['lon']}", + 'osmid' => empty($places[0]['osm_type']) + ? null + : strtoupper(substr($places[0]['osm_type'], 0, 1)) . + $places[0]['osm_id'], + ]; + } catch (\Exception $e) { + //If things go wrong the show must go on + log_message('critical', $e); + } + } + return $osmObject; +} diff --git a/app/Helpers/rss_helper.php b/app/Helpers/rss_helper.php index e1e8e8670a..bfc1798493 100644 --- a/app/Helpers/rss_helper.php +++ b/app/Helpers/rss_helper.php @@ -65,7 +65,23 @@ function get_rss_feed($podcast, $serviceSlug = '') $itunes_image = $channel->addChild('image', null, $itunes_namespace); $itunes_image->addAttribute('href', $podcast->image->original_url); $channel->addChild('language', $podcast->language_code); - + if (!empty($podcast->location_name)) { + $locationElement = $channel->addChild( + 'location', + null, + $podcast_namespace + ); + $locationElement->addAttribute( + 'name', + htmlspecialchars($podcast->location_name) + ); + if (!empty($podcast->location_geo)) { + $locationElement->addAttribute('geo', $podcast->location_geo); + } + if (!empty($podcast->location_osmid)) { + $locationElement->addAttribute('osmid', $podcast->location_osmid); + } + } if (!empty($podcast->payment_pointer)) { $valueElement = $channel->addChild('value', null, $podcast_namespace); $valueElement->addAttribute('type', 'webmonetization'); @@ -203,6 +219,26 @@ function get_rss_feed($podcast, $serviceSlug = '') 'pubDate', $episode->published_at->format(DATE_RFC1123) ); + if (!empty($episode->location_name)) { + $locationElement = $item->addChild( + 'location', + null, + $podcast_namespace + ); + $locationElement->addAttribute( + 'name', + htmlspecialchars($episode->location_name) + ); + if (!empty($episode->location_geo)) { + $locationElement->addAttribute('geo', $episode->location_geo); + } + if (!empty($episode->location_osmid)) { + $locationElement->addAttribute( + 'osmid', + $episode->location_osmid + ); + } + } $item->addChildWithCDATA('description', $episode->description_html); $item->addChild( 'duration', diff --git a/app/Language/en/Episode.php b/app/Language/en/Episode.php index e9886c15b5..00a487219f 100644 --- a/app/Language/en/Episode.php +++ b/app/Language/en/Episode.php @@ -83,6 +83,10 @@ return [ 'chapters' => 'Chapters', 'chapters_hint' => 'File should be in JSON Chapters Format.', 'chapters_delete' => 'Delete chapters', + 'location_section_title' => 'Location', + 'location_section_subtitle' => 'What place is this episode about?', + 'location_name' => 'Location name or address', + 'location_name_hint' => 'This can be a real place or fictional', 'submit_create' => 'Create episode', 'submit_edit' => 'Save episode', ], diff --git a/app/Language/en/Podcast.php b/app/Language/en/Podcast.php index 7e7c7378d2..86f7b4c9bd 100644 --- a/app/Language/en/Podcast.php +++ b/app/Language/en/Podcast.php @@ -61,6 +61,10 @@ return [ 'publisher_hint' => 'The group responsible for creating the show. Often refers to the parent company or network of a podcast. This field is sometimes labeled as ’Author’.', 'copyright' => 'Copyright', + 'location_section_title' => 'Location', + 'location_section_subtitle' => 'What place is this podcast about?', + 'location_name' => 'Location name or address', + 'location_name_hint' => 'This can be a real place or fictional', 'monetization_section_title' => 'Monetization', 'monetization_section_subtitle' => 'Earn money thanks to your audience.', diff --git a/app/Language/fr/Episode.php b/app/Language/fr/Episode.php index 03c5702092..e691f9eed7 100644 --- a/app/Language/fr/Episode.php +++ b/app/Language/fr/Episode.php @@ -83,7 +83,11 @@ return [ 'transcript_delete' => 'Supprimer la transcription', 'chapters' => 'Chapitrage', 'chapters_hint' => 'Le fichier doit être en "JSON Chapters Format".', - 'chapters_delete' => 'Supprimer le chaptrage', + 'chapters_delete' => 'Supprimer le chapitrage', + 'location_section_title' => 'Localisation', + 'location_section_subtitle' => 'De quel lieu cet épisode parle-t-il ?', + 'location_name' => 'Nom ou adresse du lieu', + 'location_name_hint' => 'Ce lieu peut être réel ou fictif', 'submit_create' => 'Créer l’épisode', 'submit_edit' => 'Enregistrer l’épisode', ], diff --git a/app/Language/fr/Podcast.php b/app/Language/fr/Podcast.php index 754d3af776..49131cbf54 100644 --- a/app/Language/fr/Podcast.php +++ b/app/Language/fr/Podcast.php @@ -62,6 +62,10 @@ return [ 'publisher_hint' => 'Le groupe responsable de la création du podcast. Fait souvent référence à la société mère ou au réseau d’un podcast. Ce champ est parfois appelé « Auteur ».', 'copyright' => 'Droit d’auteur', + 'location_section_title' => 'Localisation', + 'location_section_subtitle' => 'De quel lieu ce podcast parle-t-il ?', + 'location_name' => 'Nom ou adresse du lieu', + 'location_name_hint' => 'Ce lieu peut être réel ou fictif', 'monetization_section_title' => 'Monétisation', 'monetization_section_subtitle' => 'Gagnez de l’argent grâce à votre audience.', diff --git a/app/Models/EpisodeModel.php b/app/Models/EpisodeModel.php index c60803a215..a28d29d349 100644 --- a/app/Models/EpisodeModel.php +++ b/app/Models/EpisodeModel.php @@ -35,6 +35,9 @@ class EpisodeModel extends Model 'season_number', 'type', 'is_blocked', + 'location_name', + 'location_geo', + 'location_osmid', 'published_at', 'created_by', 'updated_by', diff --git a/app/Models/PodcastModel.php b/app/Models/PodcastModel.php index ee14d835d8..7e401fd16f 100644 --- a/app/Models/PodcastModel.php +++ b/app/Models/PodcastModel.php @@ -37,6 +37,9 @@ class PodcastModel extends Model 'is_blocked', 'is_completed', 'is_locked', + 'location_name', + 'location_geo', + 'location_osmid', 'payment_pointer', 'created_by', 'updated_by', diff --git a/app/Views/_assets/icons/map-pin.svg b/app/Views/_assets/icons/map-pin.svg new file mode 100644 index 0000000000..8e2366f3b9 --- /dev/null +++ b/app/Views/_assets/icons/map-pin.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M17.657 15.657L12 21.314l-5.657-5.657a8 8 0 1 1 11.314 0zM5 22h14v2H5v-2z"/></svg> \ No newline at end of file diff --git a/app/Views/admin/episode/create.php b/app/Views/admin/episode/create.php index 8553a0a982..35f6fc0d57 100644 --- a/app/Views/admin/episode/create.php +++ b/app/Views/admin/episode/create.php @@ -187,6 +187,25 @@ <?= form_section_close() ?> +<?= form_section( + lang('Episode.form.location_section_title'), + lang('Episode.form.location_section_subtitle') +) ?> + +<?= form_label( + lang('Episode.form.location_name'), + 'location_name', + [], + lang('Episode.form.location_name_hint'), + true +) ?> +<?= form_input([ + 'id' => 'location_name', + 'name' => 'location_name', + 'class' => 'form-input mb-4', + 'value' => old('location_name'), +]) ?> +<?= form_section_close() ?> <?= form_section( lang('Episode.form.publication_section_title'), diff --git a/app/Views/admin/episode/edit.php b/app/Views/admin/episode/edit.php index af7018023f..9783ce5b64 100644 --- a/app/Views/admin/episode/edit.php +++ b/app/Views/admin/episode/edit.php @@ -190,6 +190,25 @@ <?= form_section_close() ?> +<?= form_section( + lang('Episode.form.location_section_title'), + lang('Episode.form.location_section_subtitle') +) ?> + +<?= form_label( + lang('Episode.form.location_name'), + 'location_name', + [], + lang('Episode.form.location_name_hint'), + true +) ?> +<?= form_input([ + 'id' => 'location_name', + 'name' => 'location_name', + 'class' => 'form-input mb-4', + 'value' => old('location_name', $episode->location_name), +]) ?> +<?= form_section_close() ?> <?= form_section( lang('Episode.form.publication_section_title'), diff --git a/app/Views/admin/episode/view.php b/app/Views/admin/episode/view.php index b1c001a6fe..a66c8d710c 100644 --- a/app/Views/admin/episode/view.php +++ b/app/Views/admin/episode/view.php @@ -11,6 +11,12 @@ $episode->publication_status, 'text-sm ml-2 align-middle' ) ?> + <?= location_link( + $episode->location_name, + $episode->location_geo, + $episode->location_osmid, + 'ml-2' + ) ?> <?= $this->endSection() ?> <?= $this->section('content') ?> diff --git a/app/Views/admin/podcast/create.php b/app/Views/admin/podcast/create.php index 8ee46f8faa..0989f6398e 100644 --- a/app/Views/admin/podcast/create.php +++ b/app/Views/admin/podcast/create.php @@ -27,6 +27,7 @@ 'id' => 'image', 'name' => 'image', 'class' => 'form-input', + 'required' => 'required', 'type' => 'file', 'accept' => '.jpg,.jpeg,.png', @@ -58,21 +59,27 @@ 'required' => 'required', ]) ?> -<?= form_fieldset('', [ - 'class' => 'mb-4', -]) ?> +<?= form_fieldset('', ['class' => 'mb-4']) ?> <legend> <?= lang('Podcast.form.type.label') . hint_tooltip(lang('Podcast.form.type.hint'), 'ml-1') ?> </legend> <?= form_radio( - ['id' => 'episodic', 'name' => 'type', 'class' => 'form-radio-btn'], + [ + 'id' => 'episodic', + 'name' => 'type', + 'class' => 'form-radio-btn', + ], 'episodic', old('type') ? old('type') == 'episodic' : true ) ?> <label for="episodic"><?= lang('Podcast.form.type.episodic') ?></label> <?= form_radio( - ['id' => 'serial', 'name' => 'type', 'class' => 'form-radio-btn'], + [ + 'id' => 'serial', + 'name' => 'type', + 'class' => 'form-radio-btn', + ], 'serial', old('type') ? old('type') == 'serial' : false ) ?> @@ -241,6 +248,26 @@ <?= form_section_close() ?> +<?= form_section( + lang('Podcast.form.location_section_title'), + lang('Podcast.form.location_section_subtitle') +) ?> + +<?= form_label( + lang('Podcast.form.location_name'), + 'location_name', + [], + lang('Podcast.form.location_name_hint'), + true +) ?> +<?= form_input([ + 'id' => 'location_name', + 'name' => 'location_name', + 'class' => 'form-input mb-4', + 'value' => old('location_name'), +]) ?> +<?= form_section_close() ?> + <?= form_section( lang('Podcast.form.monetization_section_title'), lang('Podcast.form.monetization_section_subtitle') @@ -250,7 +277,8 @@ lang('Podcast.form.payment_pointer'), 'payment_pointer', [], - lang('Podcast.form.payment_pointer_hint') + lang('Podcast.form.payment_pointer_hint'), + true ) ?> <?= form_input([ 'id' => 'payment_pointer', diff --git a/app/Views/admin/podcast/edit.php b/app/Views/admin/podcast/edit.php index 2dc632901e..0150c65a9d 100644 --- a/app/Views/admin/podcast/edit.php +++ b/app/Views/admin/podcast/edit.php @@ -251,6 +251,26 @@ <?= form_section_close() ?> +<?= form_section( + lang('Podcast.form.location_section_title'), + lang('Podcast.form.location_section_subtitle') +) ?> + +<?= form_label( + lang('Podcast.form.location_name'), + 'location_name', + [], + lang('Podcast.form.location_name_hint'), + true +) ?> +<?= form_input([ + 'id' => 'location_name', + 'name' => 'location_name', + 'class' => 'form-input mb-4', + 'value' => old('location_name', $podcast->location_name), +]) ?> +<?= form_section_close() ?> + <?= form_section( lang('Podcast.form.monetization_section_title'), lang('Podcast.form.monetization_section_subtitle') @@ -260,7 +280,8 @@ lang('Podcast.form.payment_pointer'), 'payment_pointer', [], - lang('Podcast.form.payment_pointer_hint') + lang('Podcast.form.payment_pointer_hint'), + true ) ?> <?= form_input([ 'id' => 'payment_pointer', diff --git a/app/Views/admin/podcast/view.php b/app/Views/admin/podcast/view.php index bea7fbc5ad..c21870e4be 100644 --- a/app/Views/admin/podcast/view.php +++ b/app/Views/admin/podcast/view.php @@ -6,6 +6,12 @@ <?= $this->section('pageTitle') ?> <?= $podcast->title ?> +<?= location_link( + $podcast->location_name, + $podcast->location_geo, + $podcast->location_osmid, + 'ml-4' +) ?> <?= $this->endSection() ?> <?= $this->section('headerRight') ?> diff --git a/app/Views/episode.php b/app/Views/episode.php index 2fbcf29a89..6bdf4840b8 100644 --- a/app/Views/episode.php +++ b/app/Views/episode.php @@ -100,6 +100,12 @@ <?= format_duration($episode->enclosure_duration) ?> </time> </div> + <?= location_link( + $episode->location_name, + $episode->location_geo, + $episode->location_osmid, + 'self-start mt-2' + ) ?> <audio controls preload="none" class="w-full mt-auto"> <source src="<?= $episode->enclosure_web_url ?>" type="<?= $episode->enclosure_type ?>"> Your browser does not support the audio tag. diff --git a/app/Views/podcast.php b/app/Views/podcast.php index 3d013d0d42..eaafbd9fb5 100644 --- a/app/Views/podcast.php +++ b/app/Views/podcast.php @@ -49,6 +49,12 @@ lang('Common.explicit') . '</span>' : '' ?> + <?= location_link( + $podcast->location_name, + $podcast->location_geo, + $podcast->location_osmid, + 'ml-4' + ) ?> </div> <div class="flex mb-2 space-x-2"> <?= anchor( -- GitLab