Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • adaures/castopod
  • mkljczk/castopod-host
  • spaetz/castopod-host
  • PatrykMis/castopod
  • jonas/castopod
  • ajeremias/castopod
  • misuzu/castopod
  • KrzysztofDomanczyk/castopod
  • Behel/castopod
  • nebulon/castopod
  • ewen/castopod
  • NeoluxConsulting/castopod
  • nateritter/castopod-og
  • prcutler/castopod
14 results
Show changes
Commits on Source (4)
Showing
with 823 additions and 348 deletions
...@@ -68,11 +68,11 @@ release_app: ...@@ -68,11 +68,11 @@ release_app:
# make prepare-release.sh executable # make prepare-release.sh executable
- chmod +x ./prepare-release.sh - chmod +x ./prepare-release.sh
# IMPORTANT: delete local git tags before release to prevent eventual script failure (ie. tag already exists)
- git tag | xargs git tag -d
# run semantic-release script (configured in `.releaserc.json` file) # run semantic-release script (configured in `.releaserc.json` file)
- npm run release - npm run release
# IMPORTANT: delete local git tags after release to prevent eventual script failure (ie. tag already exists)
- git tag | xargs git tag -d
only: only:
- main - main
- alpha - alpha
......
# [1.0.0-alpha.20](https://code.podlibre.org/podlibre/castopod/compare/v1.0.0-alpha.19...v1.0.0-alpha.20) (2020-11-24)
### Bug Fixes
* **import:** use <image><url> tag when no <itunes:image> is present ([20e607a](https://code.podlibre.org/podlibre/castopod/commit/20e607afb755bc75056041738fa7cbf6723d754c))
### Features
* **rss:** add podcast-namespace tags for platforms + previousUrl tag ([dbba8dc](https://code.podlibre.org/podlibre/castopod/commit/dbba8dc58133967c778514268cbfed8098ed1dbc)), closes [#73](https://code.podlibre.org/podlibre/castopod/issues/73) [#75](https://code.podlibre.org/podlibre/castopod/issues/75) [#76](https://code.podlibre.org/podlibre/castopod/issues/76) [#80](https://code.podlibre.org/podlibre/castopod/issues/80)
# [1.0.0-alpha.19](https://code.podlibre.org/podlibre/castopod/compare/v1.0.0-alpha.18...v1.0.0-alpha.19) (2020-11-13) # [1.0.0-alpha.19](https://code.podlibre.org/podlibre/castopod/compare/v1.0.0-alpha.18...v1.0.0-alpha.19) (2020-11-13)
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
// //
// NOTE: this constant is updated upon release with Continuous Integration. // NOTE: this constant is updated upon release with Continuous Integration.
// //
defined('CP_VERSION') || define('CP_VERSION', '1.0.0-alpha.19'); defined('CP_VERSION') || define('CP_VERSION', '1.0.0-alpha.20');
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// App Namespace // App Namespace
......
...@@ -32,6 +32,7 @@ $routes->setAutoRoute(false); ...@@ -32,6 +32,7 @@ $routes->setAutoRoute(false);
$routes->addPlaceholder('podcastName', '[a-zA-Z0-9\_]{1,191}'); $routes->addPlaceholder('podcastName', '[a-zA-Z0-9\_]{1,191}');
$routes->addPlaceholder('slug', '[a-zA-Z0-9\-]{1,191}'); $routes->addPlaceholder('slug', '[a-zA-Z0-9\-]{1,191}');
$routes->addPlaceholder('base64', '[A-Za-z0-9\.\_]+\-{0,2}'); $routes->addPlaceholder('base64', '[A-Za-z0-9\.\_]+\-{0,2}');
$routes->addPlaceholder('platformType', '\bpodcasting|\bsocial|\bfunding');
/** /**
* -------------------------------------------------------------------- * --------------------------------------------------------------------
...@@ -69,6 +70,8 @@ $routes->add('audio/(:base64)/(:any)', 'Analytics::hit/$1/$2', [ ...@@ -69,6 +70,8 @@ $routes->add('audio/(:base64)/(:any)', 'Analytics::hit/$1/$2', [
$routes->get('.well-known/unknown-useragents', 'UnknownUserAgents'); $routes->get('.well-known/unknown-useragents', 'UnknownUserAgents');
$routes->get('.well-known/unknown-useragents/(:num)', 'UnknownUserAgents/$1'); $routes->get('.well-known/unknown-useragents/(:num)', 'UnknownUserAgents/$1');
$routes->get('.well-known/platforms', 'Platform');
// Admin area // Admin area
$routes->group( $routes->group(
config('App')->adminGateway, config('App')->adminGateway,
...@@ -94,11 +97,11 @@ $routes->group( ...@@ -94,11 +97,11 @@ $routes->group(
$routes->post('new', 'Podcast::attemptCreate', [ $routes->post('new', 'Podcast::attemptCreate', [
'filter' => 'permission:podcasts-create', 'filter' => 'permission:podcasts-create',
]); ]);
$routes->get('import', 'Podcast::import', [ $routes->get('import', 'PodcastImport', [
'as' => 'podcast-import', 'as' => 'podcast-import',
'filter' => 'permission:podcasts-import', 'filter' => 'permission:podcasts-import',
]); ]);
$routes->post('import', 'Podcast::attemptImport', [ $routes->post('import', 'PodcastImport::attemptImport', [
'filter' => 'permission:podcasts-import', 'filter' => 'permission:podcasts-import',
]); ]);
...@@ -280,25 +283,44 @@ $routes->group( ...@@ -280,25 +283,44 @@ $routes->group(
}); });
}); });
$routes->group('settings', function ($routes) { $routes->group('platforms', function ($routes) {
$routes->get('/', 'PodcastSettings/$1', [ $routes->get(
'as' => 'podcast-settings', '/',
]); 'PodcastPlatform::platforms/$1/podcasting',
$routes->get('platforms', 'PodcastSettings::platforms/$1', [ [
'as' => 'platforms', 'as' => 'platforms-podcasting',
'filter' => 'permission:podcast-manage_platforms', 'filter' => 'permission:podcast-manage_platforms',
]); ]
);
$routes->get(
'social',
'PodcastPlatform::platforms/$1/social',
[
'as' => 'platforms-social',
'filter' => 'permission:podcast-manage_platforms',
]
);
$routes->get(
'funding',
'PodcastPlatform::platforms/$1/funding',
[
'as' => 'platforms-funding',
'filter' => 'permission:podcast-manage_platforms',
]
);
$routes->post( $routes->post(
'platforms', 'save/(:platformType)',
'PodcastSettings::attemptPlatformsUpdate/$1', 'PodcastPlatform::attemptPlatformsUpdate/$1/$2',
['filter' => 'permission:podcast-manage_platforms'] [
'as' => 'platforms-save',
'filter' => 'permission:podcast-manage_platforms',
]
); );
$routes->add( $routes->add(
'platforms/(:num)/remove-link', '(:slug)/podcast-platform-remove',
'PodcastSettings::removePlatformLink/$1/$2', 'PodcastPlatform::removePodcastPlatform/$1/$2',
[ [
'as' => 'platforms-remove', 'as' => 'podcast-platform-remove',
'filter' => 'permission:podcast-manage_platforms', 'filter' => 'permission:podcast-manage_platforms',
] ]
); );
......
...@@ -13,7 +13,6 @@ use App\Models\LanguageModel; ...@@ -13,7 +13,6 @@ use App\Models\LanguageModel;
use App\Models\PodcastModel; use App\Models\PodcastModel;
use App\Models\EpisodeModel; use App\Models\EpisodeModel;
use Config\Services; use Config\Services;
use League\HTMLToMarkdown\HtmlConverter;
class Podcast extends BaseController class Podcast extends BaseController
{ {
...@@ -202,233 +201,6 @@ class Podcast extends BaseController ...@@ -202,233 +201,6 @@ class Podcast extends BaseController
return redirect()->route('podcast-view', [$newPodcastId]); return redirect()->route('podcast-view', [$newPodcastId]);
} }
public function import()
{
helper(['form', 'misc']);
$languageOptions = (new LanguageModel())->getLanguageOptions();
$categoryOptions = (new CategoryModel())->getCategoryOptions();
$data = [
'languageOptions' => $languageOptions,
'categoryOptions' => $categoryOptions,
'browserLang' => get_browser_language(
$this->request->getServer('HTTP_ACCEPT_LANGUAGE')
),
];
return view('admin/podcast/import', $data);
}
public function attemptImport()
{
helper(['media', 'misc']);
$rules = [
'imported_feed_url' => 'required|validate_url',
'season_number' => 'is_natural_no_zero|permit_empty',
'max_episodes' => 'is_natural_no_zero|permit_empty',
];
if (!$this->validate($rules)) {
return redirect()
->back()
->withInput()
->with('errors', $this->validator->getErrors());
}
try {
$feed = simplexml_load_file(
$this->request->getPost('imported_feed_url')
);
} catch (\ErrorException $ex) {
return redirect()
->back()
->withInput()
->with('errors', [
$ex->getMessage() .
': <a href="' .
$this->request->getPost('imported_feed_url') .
'" rel="noreferrer noopener" target="_blank">' .
$this->request->getPost('imported_feed_url') .
' ⎋</a>',
]);
}
$nsItunes = $feed->channel[0]->children(
'http://www.itunes.com/dtds/podcast-1.0.dtd'
);
$nsPodcast = $feed->channel[0]->children(
'https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md'
);
if ((string) $nsPodcast->locked === 'yes') {
return redirect()
->back()
->withInput()
->with('errors', [lang('PodcastImport.lock_import')]);
}
$converter = new HtmlConverter();
$channelDescriptionHtml = $feed->channel[0]->description;
$podcast = new \App\Entities\Podcast([
'name' => $this->request->getPost('name'),
'imported_feed_url' => $this->request->getPost('imported_feed_url'),
'new_feed_url' => base_url(
route_to('podcast_feed', $this->request->getPost('name'))
),
'title' => $feed->channel[0]->title,
'description_markdown' => $converter->convert(
$channelDescriptionHtml
),
'description_html' => $channelDescriptionHtml,
'image' => download_file($nsItunes->image->attributes()),
'language_code' => $this->request->getPost('language'),
'category_id' => $this->request->getPost('category'),
'parental_advisory' => empty($nsItunes->explicit)
? null
: (in_array($nsItunes->explicit, ['yes', 'true'])
? 'explicit'
: (in_array($nsItunes->explicit, ['no', 'false'])
? 'clean'
: null)),
'owner_name' => $nsItunes->owner->name,
'owner_email' => $nsItunes->owner->email,
'publisher' => $nsItunes->author,
'type' => empty($nsItunes->type) ? 'episodic' : $nsItunes->type,
'copyright' => $feed->channel[0]->copyright,
'is_blocked' => empty($nsItunes->block)
? false
: $nsItunes->block === 'yes',
'is_completed' => empty($nsItunes->complete)
? false
: $nsItunes->complete === 'yes',
'created_by' => user(),
'updated_by' => user(),
]);
$podcastModel = new PodcastModel();
$db = \Config\Database::connect();
$db->transStart();
if (!($newPodcastId = $podcastModel->insert($podcast, true))) {
$db->transRollback();
return redirect()
->back()
->withInput()
->with('errors', $podcastModel->errors());
}
$authorize = Services::authorization();
$podcastAdminGroup = $authorize->group('podcast_admin');
$podcastModel->addPodcastContributor(
user()->id,
$newPodcastId,
$podcastAdminGroup->id
);
$numberItems = $feed->channel[0]->item->count();
$lastItem =
!empty($this->request->getPost('max_episodes')) &&
$this->request->getPost('max_episodes') < $numberItems
? $this->request->getPost('max_episodes')
: $numberItems;
$slugs = [];
// For each Episode:
for ($itemNumber = 1; $itemNumber <= $lastItem; $itemNumber++) {
$item = $feed->channel[0]->item[$numberItems - $itemNumber];
$nsItunes = $item->children(
'http://www.itunes.com/dtds/podcast-1.0.dtd'
);
$slug = slugify(
$this->request->getPost('slug_field') === 'title'
? $item->title
: basename($item->link)
);
if (in_array($slug, $slugs)) {
$slugNumber = 2;
while (in_array($slug . '-' . $slugNumber, $slugs)) {
$slugNumber++;
}
$slug = $slug . '-' . $slugNumber;
}
$slugs[] = $slug;
$itemDescriptionHtml =
$this->request->getPost('description_field') === 'summary'
? $nsItunes->summary
: ($this->request->getPost('description_field') ===
'subtitle_summary'
? $nsItunes->subtitle . '<br/>' . $nsItunes->summary
: $item->description);
$newEpisode = new \App\Entities\Episode([
'podcast_id' => $newPodcastId,
'guid' => empty($item->guid) ? null : $item->guid,
'title' => $item->title,
'slug' => $slug,
'enclosure' => download_file($item->enclosure->attributes()),
'description_markdown' => $converter->convert(
$itemDescriptionHtml
),
'description_html' => $itemDescriptionHtml,
'image' =>
!$nsItunes->image || empty($nsItunes->image->attributes())
? null
: download_file($nsItunes->image->attributes()),
'parental_advisory' => empty($nsItunes->explicit)
? null
: (in_array($nsItunes->explicit, ['yes', 'true'])
? 'explicit'
: (in_array($nsItunes->explicit, ['no', 'false'])
? 'clean'
: null)),
'number' =>
$this->request->getPost('force_renumber') === 'yes'
? $itemNumber
: (!empty($nsItunes->episode)
? $nsItunes->episode
: null),
'season_number' => empty(
$this->request->getPost('season_number')
)
? (!empty($nsItunes->season)
? $nsItunes->season
: null)
: $this->request->getPost('season_number'),
'type' => empty($nsItunes->episodeType)
? 'full'
: $nsItunes->episodeType,
'is_blocked' => empty($nsItunes->block)
? false
: $nsItunes->block === 'yes',
'created_by' => user(),
'updated_by' => user(),
'published_at' => strtotime($item->pubDate),
]);
$episodeModel = new EpisodeModel();
if (!$episodeModel->insert($newEpisode)) {
// FIXME: What shall we do?
return redirect()
->back()
->withInput()
->with('errors', $episodeModel->errors());
}
}
$db->transComplete();
return redirect()->route('podcast-view', [$newPodcastId]);
}
public function edit() public function edit()
{ {
helper('form'); helper('form');
......
<?php
/**
* @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\CategoryModel;
use App\Models\LanguageModel;
use App\Models\PodcastModel;
use App\Models\EpisodeModel;
use App\Models\PlatformModel;
use Config\Services;
use League\HTMLToMarkdown\HtmlConverter;
class PodcastImport extends BaseController
{
/**
* @var \App\Entities\Podcast|null
*/
protected $podcast;
public function _remap($method, ...$params)
{
if (count($params) > 0) {
if (
!($this->podcast = (new PodcastModel())->getPodcastById(
$params[0]
))
) {
throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
}
}
return $this->$method();
}
public function index()
{
helper(['form', 'misc']);
$languageOptions = (new LanguageModel())->getLanguageOptions();
$categoryOptions = (new CategoryModel())->getCategoryOptions();
$data = [
'languageOptions' => $languageOptions,
'categoryOptions' => $categoryOptions,
'browserLang' => get_browser_language(
$this->request->getServer('HTTP_ACCEPT_LANGUAGE')
),
];
return view('admin/podcast/import', $data);
}
public function attemptImport()
{
helper(['media', 'misc']);
$rules = [
'imported_feed_url' => 'required|validate_url',
'season_number' => 'is_natural_no_zero|permit_empty',
'max_episodes' => 'is_natural_no_zero|permit_empty',
];
if (!$this->validate($rules)) {
return redirect()
->back()
->withInput()
->with('errors', $this->validator->getErrors());
}
try {
$feed = simplexml_load_file(
$this->request->getPost('imported_feed_url')
);
} catch (\ErrorException $ex) {
return redirect()
->back()
->withInput()
->with('errors', [
$ex->getMessage() .
': <a href="' .
$this->request->getPost('imported_feed_url') .
'" rel="noreferrer noopener" target="_blank">' .
$this->request->getPost('imported_feed_url') .
' ⎋</a>',
]);
}
$nsItunes = $feed->channel[0]->children(
'http://www.itunes.com/dtds/podcast-1.0.dtd'
);
$nsPodcast = $feed->channel[0]->children(
'https://github.com/Podcastindex-org/podcast-namespace/blob/main/docs/1.0.md'
);
if ((string) $nsPodcast->locked === 'yes') {
return redirect()
->back()
->withInput()
->with('errors', [lang('PodcastImport.lock_import')]);
}
$converter = new HtmlConverter();
$channelDescriptionHtml = $feed->channel[0]->description;
try {
$podcast = new \App\Entities\Podcast([
'name' => $this->request->getPost('name'),
'imported_feed_url' => $this->request->getPost(
'imported_feed_url'
),
'new_feed_url' => base_url(
route_to('podcast_feed', $this->request->getPost('name'))
),
'title' => $feed->channel[0]->title,
'description_markdown' => $converter->convert(
$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),
'language_code' => $this->request->getPost('language'),
'category_id' => $this->request->getPost('category'),
'parental_advisory' => empty($nsItunes->explicit)
? null
: (in_array($nsItunes->explicit, ['yes', 'true'])
? 'explicit'
: (in_array($nsItunes->explicit, ['no', 'false'])
? 'clean'
: null)),
'owner_name' => $nsItunes->owner->name,
'owner_email' => $nsItunes->owner->email,
'publisher' => $nsItunes->author,
'type' => empty($nsItunes->type) ? 'episodic' : $nsItunes->type,
'copyright' => $feed->channel[0]->copyright,
'is_blocked' => empty($nsItunes->block)
? false
: $nsItunes->block === 'yes',
'is_completed' => empty($nsItunes->complete)
? false
: $nsItunes->complete === 'yes',
'created_by' => user(),
'updated_by' => user(),
]);
} catch (\ErrorException $ex) {
return redirect()
->back()
->withInput()
->with('errors', [
$ex->getMessage() .
': <a href="' .
$this->request->getPost('imported_feed_url') .
'" rel="noreferrer noopener" target="_blank">' .
$this->request->getPost('imported_feed_url') .
' ⎋</a>',
]);
}
$podcastModel = new PodcastModel();
$db = \Config\Database::connect();
$db->transStart();
if (!($newPodcastId = $podcastModel->insert($podcast, true))) {
$db->transRollback();
return redirect()
->back()
->withInput()
->with('errors', $podcastModel->errors());
}
$authorize = Services::authorization();
$podcastAdminGroup = $authorize->group('podcast_admin');
$podcastModel->addPodcastContributor(
user()->id,
$newPodcastId,
$podcastAdminGroup->id
);
$platformModel = new PlatformModel();
$podcastsPlatformsData = [];
foreach ($nsPodcast->id as $podcastingPlatform) {
$slug = $podcastingPlatform->attributes()['platform'];
$platformModel->getOrCreatePlatform($slug, 'podcasting');
array_push($podcastsPlatformsData, [
'platform_slug' => $slug,
'podcast_id' => $newPodcastId,
'link_url' => $podcastingPlatform->attributes()['url'],
'link_content' => $podcastingPlatform->attributes()['id'],
'is_visible' => false,
]);
}
foreach ($nsPodcast->social as $socialPlatform) {
$slug = $socialPlatform->attributes()['platform'];
$platformModel->getOrCreatePlatform($slug, 'social');
array_push($podcastsPlatformsData, [
'platform_slug' => $socialPlatform->attributes()['platform'],
'podcast_id' => $newPodcastId,
'link_url' => $socialPlatform->attributes()['url'],
'link_content' => $socialPlatform,
'is_visible' => false,
]);
}
foreach ($nsPodcast->funding as $fundingPlatform) {
$slug = $fundingPlatform->attributes()['platform'];
$platformModel->getOrCreatePlatform($slug, 'funding');
array_push($podcastsPlatformsData, [
'platform_slug' => $fundingPlatform->attributes()['platform'],
'podcast_id' => $newPodcastId,
'link_url' => $fundingPlatform->attributes()['url'],
'link_content' => $fundingPlatform->attributes()['id'],
'is_visible' => false,
]);
}
if (count($podcastsPlatformsData) > 1) {
$platformModel->createPodcastPlatforms(
$newPodcastId,
$podcastsPlatformsData
);
}
$numberItems = $feed->channel[0]->item->count();
$lastItem =
!empty($this->request->getPost('max_episodes')) &&
$this->request->getPost('max_episodes') < $numberItems
? $this->request->getPost('max_episodes')
: $numberItems;
$slugs = [];
// For each Episode:
for ($itemNumber = 1; $itemNumber <= $lastItem; $itemNumber++) {
$item = $feed->channel[0]->item[$numberItems - $itemNumber];
$nsItunes = $item->children(
'http://www.itunes.com/dtds/podcast-1.0.dtd'
);
$slug = slugify(
$this->request->getPost('slug_field') === 'title'
? $item->title
: basename($item->link)
);
if (in_array($slug, $slugs)) {
$slugNumber = 2;
while (in_array($slug . '-' . $slugNumber, $slugs)) {
$slugNumber++;
}
$slug = $slug . '-' . $slugNumber;
}
$slugs[] = $slug;
$itemDescriptionHtml =
$this->request->getPost('description_field') === 'summary'
? $nsItunes->summary
: ($this->request->getPost('description_field') ===
'subtitle_summary'
? $nsItunes->subtitle . '<br/>' . $nsItunes->summary
: $item->description);
$newEpisode = new \App\Entities\Episode([
'podcast_id' => $newPodcastId,
'guid' => empty($item->guid) ? null : $item->guid,
'title' => $item->title,
'slug' => $slug,
'enclosure' => download_file($item->enclosure->attributes()),
'description_markdown' => $converter->convert(
$itemDescriptionHtml
),
'description_html' => $itemDescriptionHtml,
'image' =>
!$nsItunes->image || empty($nsItunes->image->attributes())
? null
: download_file($nsItunes->image->attributes()),
'parental_advisory' => empty($nsItunes->explicit)
? null
: (in_array($nsItunes->explicit, ['yes', 'true'])
? 'explicit'
: (in_array($nsItunes->explicit, ['no', 'false'])
? 'clean'
: null)),
'number' =>
$this->request->getPost('force_renumber') === 'yes'
? $itemNumber
: (!empty($nsItunes->episode)
? $nsItunes->episode
: null),
'season_number' => empty(
$this->request->getPost('season_number')
)
? (!empty($nsItunes->season)
? $nsItunes->season
: null)
: $this->request->getPost('season_number'),
'type' => empty($nsItunes->episodeType)
? 'full'
: $nsItunes->episodeType,
'is_blocked' => empty($nsItunes->block)
? false
: $nsItunes->block === 'yes',
'created_by' => user(),
'updated_by' => user(),
'published_at' => strtotime($item->pubDate),
]);
$episodeModel = new EpisodeModel();
if (!$episodeModel->insert($newEpisode)) {
// FIXME: What shall we do?
return redirect()
->back()
->withInput()
->with('errors', $episodeModel->errors());
}
}
$db->transComplete();
return redirect()->route('podcast-view', [$newPodcastId]);
}
}
...@@ -12,7 +12,7 @@ use App\Models\PlatformModel; ...@@ -12,7 +12,7 @@ use App\Models\PlatformModel;
use App\Models\PodcastModel; use App\Models\PodcastModel;
use Config\Services; use Config\Services;
class PodcastSettings extends BaseController class PodcastPlatform extends BaseController
{ {
/** /**
* @var \App\Entities\Podcast|null * @var \App\Entities\Podcast|null
...@@ -33,46 +33,53 @@ class PodcastSettings extends BaseController ...@@ -33,46 +33,53 @@ class PodcastSettings extends BaseController
public function index() public function index()
{ {
return view('admin/podcast/settings/dashboard'); return view('admin/podcast/platforms/dashboard');
} }
public function platforms() public function platforms($platformType)
{ {
helper('form'); helper('form');
$data = [ $data = [
'podcast' => $this->podcast, 'podcast' => $this->podcast,
'platformType' => $platformType,
'platforms' => (new PlatformModel())->getPlatformsWithLinks( 'platforms' => (new PlatformModel())->getPlatformsWithLinks(
$this->podcast->id $this->podcast->id,
$platformType
), ),
]; ];
replace_breadcrumb_params([0 => $this->podcast->title]); replace_breadcrumb_params([0 => $this->podcast->title]);
return view('admin/podcast/settings/platforms', $data); return view('admin/podcast/platforms', $data);
} }
public function attemptPlatformsUpdate() public function attemptPlatformsUpdate($platformType)
{ {
$platformModel = new PlatformModel(); $platformModel = new PlatformModel();
$validation = Services::validation(); $validation = Services::validation();
$platformLinksData = []; $podcastsPlatformsData = [];
foreach ( foreach (
$this->request->getPost('platforms') $this->request->getPost('platforms')
as $platformName => $platformLink as $platformSlug => $podcastPlatform
) { ) {
$platformLinkUrl = $platformLink['url']; $podcastPlatformUrl = $podcastPlatform['url'];
if ( if (
!empty($platformLinkUrl) && !empty($podcastPlatformUrl) &&
$validation->check($platformLinkUrl, 'validate_url') $validation->check($podcastPlatformUrl, 'validate_url')
) { ) {
$platformId = $platformModel->getPlatformId($platformName); array_push($podcastsPlatformsData, [
array_push($platformLinksData, [ 'platform_slug' => $platformSlug,
'platform_id' => $platformId,
'podcast_id' => $this->podcast->id, 'podcast_id' => $this->podcast->id,
'link_url' => $platformLinkUrl, 'link_url' => $podcastPlatformUrl,
'is_visible' => array_key_exists('visible', $platformLink) 'link_content' => $podcastPlatform['content'],
? $platformLink['visible'] == 'yes' 'is_visible' => array_key_exists(
'visible',
$podcastPlatform
)
? $podcastPlatform['visible'] == 'yes'
: false, : false,
]); ]);
} }
...@@ -80,7 +87,8 @@ class PodcastSettings extends BaseController ...@@ -80,7 +87,8 @@ class PodcastSettings extends BaseController
$platformModel->savePodcastPlatforms( $platformModel->savePodcastPlatforms(
$this->podcast->id, $this->podcast->id,
$platformLinksData $platformType,
$podcastsPlatformsData
); );
return redirect() return redirect()
...@@ -88,11 +96,11 @@ class PodcastSettings extends BaseController ...@@ -88,11 +96,11 @@ class PodcastSettings extends BaseController
->with('message', lang('Platforms.messages.updateSuccess')); ->with('message', lang('Platforms.messages.updateSuccess'));
} }
public function removePlatformLink($platformId) public function removePodcastPlatform($platformSlug)
{ {
(new PlatformModel())->removePlatformLink( (new PlatformModel())->removePodcastPlatform(
$this->podcast->id, $this->podcast->id,
$platformId $platformSlug
); );
return redirect() return redirect()
......
<?php
/**
* @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/
*/
namespace App\Controllers;
use CodeIgniter\Controller;
/*
* Provide public access to all platforms so that they can be exported
*/
class Platform extends Controller
{
public function index()
{
$model = new \App\Models\PlatformModel();
return $this->response->setJSON($model->getPlatforms());
}
}
...@@ -18,15 +18,13 @@ class AddPlatforms extends Migration ...@@ -18,15 +18,13 @@ class AddPlatforms extends Migration
public function up() public function up()
{ {
$this->forge->addField([ $this->forge->addField([
'id' => [ 'slug' => [
'type' => 'INT',
'unsigned' => true,
'auto_increment' => true,
],
'name' => [
'type' => 'VARCHAR', 'type' => 'VARCHAR',
'constraint' => 32, 'constraint' => 32,
'unique' => true, ],
'type' => [
'type' => 'ENUM',
'constraint' => ['podcasting', 'social', 'funding'],
], ],
'label' => [ 'label' => [
'type' => 'VARCHAR', 'type' => 'VARCHAR',
...@@ -42,14 +40,14 @@ class AddPlatforms extends Migration ...@@ -42,14 +40,14 @@ class AddPlatforms extends Migration
'null' => true, 'null' => true,
'default' => null, 'default' => null,
], ],
'created_at' => [
'type' => 'DATETIME',
],
'updated_at' => [
'type' => 'DATETIME',
],
]); ]);
$this->forge->addKey('id', true); $this->forge->addField(
'`created_at` timestamp NOT NULL DEFAULT current_timestamp()'
);
$this->forge->addField(
'`updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()'
);
$this->forge->addKey('slug', true);
$this->forge->createTable('platforms'); $this->forge->createTable('platforms');
} }
......
<?php <?php
/** /**
* Class AddPlatformsLinks * Class AddAddPodcastsPlatforms
* Creates platform_links table in database * Creates podcasts_platforms table in database
* *
* @copyright 2020 Podlibre * @copyright 2020 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
...@@ -22,14 +22,19 @@ class AddPodcastsPlatforms extends Migration ...@@ -22,14 +22,19 @@ class AddPodcastsPlatforms extends Migration
'type' => 'INT', 'type' => 'INT',
'unsigned' => true, 'unsigned' => true,
], ],
'platform_id' => [ 'platform_slug' => [
'type' => 'INT', 'type' => 'VARCHAR',
'unsigned' => true, 'constraint' => 32,
], ],
'link_url' => [ 'link_url' => [
'type' => 'VARCHAR', 'type' => 'VARCHAR',
'constraint' => 512, 'constraint' => 512,
], ],
'link_content' => [
'type' => 'VARCHAR',
'constraint' => 128,
'null' => true,
],
'is_visible' => [ 'is_visible' => [
'type' => 'TINYINT', 'type' => 'TINYINT',
'constraint' => 1, 'constraint' => 1,
...@@ -43,14 +48,14 @@ class AddPodcastsPlatforms extends Migration ...@@ -43,14 +48,14 @@ class AddPodcastsPlatforms extends Migration
], ],
]); ]);
$this->forge->addPrimaryKey(['podcast_id', 'platform_id']); $this->forge->addPrimaryKey(['podcast_id', 'platform_slug']);
$this->forge->addForeignKey('podcast_id', 'podcasts', 'id'); $this->forge->addForeignKey('podcast_id', 'podcasts', 'id');
$this->forge->addForeignKey('platform_id', 'platforms', 'id'); $this->forge->addForeignKey('platform_slug', 'platforms', 'slug');
$this->forge->createTable('platform_links'); $this->forge->createTable('podcasts_platforms');
} }
public function down() public function down()
{ {
$this->forge->dropTable('platform_links'); $this->forge->dropTable('podcasts_platforms');
} }
} }
...@@ -19,135 +19,303 @@ class PlatformSeeder extends Seeder ...@@ -19,135 +19,303 @@ class PlatformSeeder extends Seeder
{ {
$data = [ $data = [
[ [
'name' => 'apple-podcasts', 'slug' => 'amazon',
'type' => 'podcasting',
'label' => 'Amazon Music and Audible',
'home_url' => 'https://music.amazon.com/podcasts',
'submit_url' => 'http://amazon.com/podcasters',
],
[
'slug' => 'apple',
'type' => 'podcasting',
'label' => 'Apple Podcasts', 'label' => 'Apple Podcasts',
'home_url' => 'https://www.apple.com/itunes/podcasts/', 'home_url' => 'https://www.apple.com/itunes/podcasts/',
'submit_url' => 'submit_url' =>
'https://podcastsconnect.apple.com/my-podcasts/new-feed', 'https://podcastsconnect.apple.com/my-podcasts/new-feed',
], ],
[ [
'name' => 'blubrry', 'slug' => 'blubrry',
'type' => 'podcasting',
'label' => 'Blubrry', 'label' => 'Blubrry',
'home_url' => 'https://www.blubrry.com/', 'home_url' => 'https://www.blubrry.com/',
'submit_url' => 'https://www.blubrry.com/addpodcast.php', 'submit_url' => 'https://www.blubrry.com/addpodcast.php',
], ],
[ [
'name' => 'castbox', 'slug' => 'castbox',
'type' => 'podcasting',
'label' => 'Castbox', 'label' => 'Castbox',
'home_url' => 'https://castbox.fm/', 'home_url' => 'https://castbox.fm/',
'submit_url' => 'submit_url' =>
'https://helpcenter.castbox.fm/portal/kb/articles/submit-my-podcast', 'https://helpcenter.castbox.fm/portal/kb/articles/submit-my-podcast',
], ],
[ [
'name' => 'castro', 'slug' => 'castro',
'type' => 'podcasting',
'label' => 'Castro', 'label' => 'Castro',
'home_url' => 'http://castro.fm/', 'home_url' => 'http://castro.fm/',
'submit_url' => null, 'submit_url' =>
'https://castro.fm/support/link-to-your-podcast-in-castro',
], ],
[ [
'name' => 'deezer', 'slug' => 'chartable',
'type' => 'podcasting',
'label' => 'Chartable',
'home_url' => 'https://chartable.com/',
'submit_url' => 'https://chartable.com/podcasts/submit',
],
[
'slug' => 'deezer',
'type' => 'podcasting',
'label' => 'Deezer', 'label' => 'Deezer',
'home_url' => 'https://www.deezer.com/', 'home_url' => 'https://www.deezer.com/',
'submit_url' => 'https://podcasters.deezer.com/submission', 'submit_url' => 'https://podcasters.deezer.com/submission',
], ],
[ [
'name' => 'google-podcasts', 'slug' => 'fyyd',
'type' => 'podcasting',
'label' => 'fyyd',
'home_url' => 'https://fyyd.de/',
'submit_url' => 'https://fyyd.de/add-feed',
],
[
'slug' => 'google',
'type' => 'podcasting',
'label' => 'Google Podcasts', 'label' => 'Google Podcasts',
'home_url' => 'https://podcasts.google.com/about', 'home_url' => 'https://podcasts.google.com/about',
'submit_url' => 'submit_url' =>
'https://search.google.com/search-console/about', 'https://search.google.com/search-console/about',
], ],
[ [
'name' => 'ivoox', 'slug' => 'ivoox',
'type' => 'podcasting',
'label' => 'Ivoox', 'label' => 'Ivoox',
'home_url' => 'https://www.ivoox.com/', 'home_url' => 'https://www.ivoox.com/',
'submit_url' => null, 'submit_url' => 'http://www.ivoox.com/upload-podcast_u.html',
], ],
[ [
'name' => 'listennotes', 'slug' => 'listennotes',
'type' => 'podcasting',
'label' => 'ListenNotes', 'label' => 'ListenNotes',
'home_url' => 'https://www.listennotes.com/', 'home_url' => 'https://www.listennotes.com/',
'submit_url' => 'https://www.listennotes.com/submit/', 'submit_url' => 'https://www.listennotes.com/submit/',
], ],
[ [
'name' => 'overcast', 'slug' => 'overcast',
'type' => 'podcasting',
'label' => 'Overcast', 'label' => 'Overcast',
'home_url' => 'https://overcast.fm/', 'home_url' => 'https://overcast.fm/',
'submit_url' => 'https://overcast.fm/podcasterinfo', 'submit_url' => 'https://overcast.fm/podcasterinfo',
], ],
[ [
'name' => 'playerfm', 'slug' => 'playerfm',
'type' => 'podcasting',
'label' => 'Player.Fm', 'label' => 'Player.Fm',
'home_url' => 'https://player.fm/', 'home_url' => 'https://player.fm/',
'submit_url' => 'https://player.fm/importer/feed', 'submit_url' => 'https://player.fm/importer/feed',
], ],
[ [
'name' => 'pocketcasts', 'slug' => 'pocketcasts',
'type' => 'podcasting',
'label' => 'Pocketcasts', 'label' => 'Pocketcasts',
'home_url' => 'https://www.pocketcasts.com/', 'home_url' => 'https://www.pocketcasts.com/',
'submit_url' => 'https://www.pocketcasts.com/submit/', 'submit_url' => 'https://www.pocketcasts.com/submit/',
], ],
[ [
'name' => 'podbean', 'slug' => 'podbean',
'type' => 'podcasting',
'label' => 'Podbean', 'label' => 'Podbean',
'home_url' => 'https://www.podbean.com/', 'home_url' => 'https://www.podbean.com/',
'submit_url' => 'https://www.podbean.com/site/submitPodcast', 'submit_url' => 'https://www.podbean.com/site/submitPodcast',
], ],
[ [
'name' => 'podcast-addict', 'slug' => 'podcastaddict',
'type' => 'podcasting',
'label' => 'Podcast Addict', 'label' => 'Podcast Addict',
'home_url' => 'https://podcastaddict.com/', 'home_url' => 'https://podcastaddict.com/',
'submit_url' => 'https://podcastaddict.com/submit', 'submit_url' => 'https://podcastaddict.com/submit',
], ],
[ [
'name' => 'podcast-index', 'slug' => 'podcastindex',
'type' => 'podcasting',
'label' => 'Podcast Index', 'label' => 'Podcast Index',
'home_url' => 'https://podcastindex.org/', 'home_url' => 'https://podcastindex.org/',
'submit_url' => 'https://api.podcastindex.org/signup', 'submit_url' => 'https://api.podcastindex.org/signup',
], ],
[ [
'name' => 'podchaser', 'slug' => 'podchaser',
'type' => 'podcasting',
'label' => 'Podchaser', 'label' => 'Podchaser',
'home_url' => 'https://www.podchaser.com/', 'home_url' => 'https://www.podchaser.com/',
'submit_url' => 'https://www.podchaser.com/creators/edit', 'submit_url' => 'https://www.podchaser.com/creators/edit',
], ],
[ [
'name' => 'podtail', 'slug' => 'podcloud',
'type' => 'podcasting',
'label' => 'podCloud',
'home_url' => 'https://podcloud.fr/',
'submit_url' => 'https://podcloud.fr/studio/podcasts/new',
],
[
'slug' => 'podinstall',
'type' => 'podcasting',
'label' => 'Podinstall',
'home_url' => 'https://www.podinstall.com/',
'submit_url' => 'https://www.podinstall.com/claim.html',
],
[
'slug' => 'podtail',
'type' => 'podcasting',
'label' => 'Podtail', 'label' => 'Podtail',
'home_url' => 'https://podtail.com/', 'home_url' => 'https://podtail.com/',
'submit_url' => 'https://podtail.com/about/faq/', 'submit_url' => 'https://podtail.com/about/faq/',
], ],
[ [
'name' => 'radiopublic', 'slug' => 'podverse',
'label' => 'Radiopublic', 'type' => 'podcasting',
'label' => 'Podverse',
'home_url' => 'https://podverse.fm/',
'submit_url' =>
'https://docs.google.com/forms/d/e/1FAIpQLSdewKP-YrE8zGjDPrkmoJEwCxPl_gizEkmzAlTYsiWAuAk1Ng/viewform',
],
[
'slug' => 'radiopublic',
'type' => 'podcasting',
'label' => 'RadioPublic',
'home_url' => 'https://radiopublic.com/', 'home_url' => 'https://radiopublic.com/',
'submit_url' => 'https://podcasters.radiopublic.com/signup', 'submit_url' => 'https://podcasters.radiopublic.com/signup',
], ],
[ [
'name' => 'spotify', 'slug' => 'spotify',
'type' => 'podcasting',
'label' => 'Spotify', 'label' => 'Spotify',
'home_url' => 'https://www.spotify.com/', 'home_url' => 'https://www.spotify.com/',
'submit_url' => 'https://podcasters.spotify.com/submit', 'submit_url' => 'https://podcasters.spotify.com/submit',
], ],
[ [
'name' => 'spreaker', 'slug' => 'spreaker',
'type' => 'podcasting',
'label' => 'Spreaker', 'label' => 'Spreaker',
'home_url' => 'https://www.spreaker.com/', 'home_url' => 'https://www.spreaker.com/',
'submit_url' => 'https://www.spreaker.com/cms/shows/rss-import', 'submit_url' => 'https://www.spreaker.com/cms/shows/rss-import',
], ],
[ [
'name' => 'stitcher', 'slug' => 'stitcher',
'type' => 'podcasting',
'label' => 'Stitcher', 'label' => 'Stitcher',
'home_url' => 'https://www.stitcher.com/', 'home_url' => 'https://www.stitcher.com/',
'submit_url' => 'https://www.stitcher.com/content-providers', 'submit_url' => 'https://partners.stitcher.com/join',
], ],
[ [
'name' => 'tunein', 'slug' => 'tunein',
'type' => 'podcasting',
'label' => 'TuneIn', 'label' => 'TuneIn',
'home_url' => 'https://tunein.com/', 'home_url' => 'https://tunein.com/',
'submit_url' => 'submit_url' =>
'https://help.tunein.com/contact/add-podcast-S19TR3Sdf', 'https://help.tunein.com/contact/add-podcast-S19TR3Sdf',
], ],
[
'slug' => 'paypal',
'type' => 'funding',
'label' => 'Paypal',
'home_url' => 'https://www.paypal.com/',
'submit_url' => 'https://www.paypal.com/paypalme/my/grab',
],
[
'slug' => 'liberapay',
'type' => 'funding',
'label' => 'Liberapay',
'home_url' => 'https://liberapay.com/',
'submit_url' => 'https://liberapay.com/sign-up',
],
[
'slug' => 'patreon',
'type' => 'funding',
'label' => 'Patreon',
'home_url' => 'https://www.patreon.com/',
'submit_url' => 'https://www.patreon.com/create',
],
[
'slug' => 'tipeee',
'type' => 'funding',
'label' => 'Tipeee',
'home_url' => 'https://tipeee.com/',
'submit_url' => 'https://tipeee.com/register/',
],
[
'slug' => 'discord',
'type' => 'social',
'label' => 'Discord',
'home_url' => 'https://discord.com/',
'submit_url' => 'https://discord.com/register',
],
[
'slug' => 'facebook',
'type' => 'social',
'label' => 'Facebook',
'home_url' => 'https://www.facebook.com/',
'submit_url' =>
'https://www.facebook.com/pages/creation/?ref_type=comet_home',
],
[
'slug' => 'instagram',
'type' => 'social',
'label' => 'Instagram',
'home_url' => 'https://www.instagram.com/',
'submit_url' =>
'https://www.instagram.com/accounts/emailsignup/',
],
[
'slug' => 'linkedin',
'type' => 'social',
'label' => 'LinkedIn',
'home_url' => 'https://www.linkedin.com/',
'submit_url' => 'https://www.linkedin.com/company/setup/new/',
],
[
'slug' => 'mastodon',
'type' => 'social',
'label' => 'Mastodon',
'home_url' => 'https://joinmastodon.org/',
'submit_url' => 'https://joinmastodon.org/communities',
],
[
'slug' => 'pixelfed',
'type' => 'social',
'label' => 'Pixelfed',
'home_url' => 'https://pixelfed.org/',
'submit_url' => 'https://beta.joinpixelfed.org/',
],
[
'slug' => 'slack',
'type' => 'social',
'label' => 'Slack',
'home_url' => 'https://slack.com/',
'submit_url' => 'https://slack.com/get-started#/create',
],
[
'slug' => 'twitch',
'type' => 'social',
'label' => 'Twitch',
'home_url' => 'https://www.twitch.tv/',
'submit_url' => 'https://www.twitch.tv/signup',
],
[
'slug' => 'twitter',
'type' => 'social',
'label' => 'Twitter',
'home_url' => 'https://twitter.com/',
'submit_url' => 'https://twitter.com/i/flow/signup',
],
[
'slug' => 'youtube',
'type' => 'social',
'label' => 'Youtube',
'home_url' => 'https://www.youtube.com/',
'submit_url' => 'https://creatoracademy.youtube.com/page/home',
],
]; ];
$this->db $this->db
->table('platforms') ->table('platforms')
......
...@@ -13,12 +13,13 @@ use CodeIgniter\Entity; ...@@ -13,12 +13,13 @@ use CodeIgniter\Entity;
class Platform extends Entity class Platform extends Entity
{ {
protected $casts = [ protected $casts = [
'id' => 'integer', 'slug' => 'string',
'name' => 'string', 'type' => 'string',
'label' => 'string', 'label' => 'string',
'home_url' => 'string', 'home_url' => 'string',
'submit_url' => '?string', 'submit_url' => '?string',
'link_url' => '?string', 'link_url' => '?string',
'link_content' => '?string',
'is_visible' => '?boolean', 'is_visible' => '?boolean',
]; ];
} }
...@@ -55,7 +55,17 @@ class Podcast extends Entity ...@@ -55,7 +55,17 @@ class Podcast extends Entity
/** /**
* @var \App\Entities\Platform * @var \App\Entities\Platform
*/ */
protected $platforms; protected $podcastingPlatforms;
/**
* @var \App\Entities\Platform
*/
protected $socialPlatforms;
/**
* @var \App\Entities\Platform
*/
protected $fundingPlatforms;
/** /**
* Holds text only description, striped of any markdown or html special characters * Holds text only description, striped of any markdown or html special characters
...@@ -260,25 +270,72 @@ class Podcast extends Entity ...@@ -260,25 +270,72 @@ class Podcast extends Entity
} }
/** /**
* Returns the podcast's platform links * Returns the podcast's podcasting platform links
* *
* @return \App\Entities\Platform[] * @return \App\Entities\Platform[]
*/ */
public function getPlatforms() public function getPodcastingPlatforms()
{ {
if (empty($this->id)) { if (empty($this->id)) {
throw new \RuntimeException( throw new \RuntimeException(
'Podcast must be created before getting platform links.' 'Podcast must be created before getting podcasting platform links.'
); );
} }
if (empty($this->platforms)) { if (empty($this->podcastingPlatforms)) {
$this->platforms = (new PlatformModel())->getPodcastPlatforms( $this->podcastingPlatforms = (new PlatformModel())->getPodcastPlatforms(
$this->id $this->id,
'podcasting'
);
}
return $this->podcastingPlatforms;
}
/**
* Returns the podcast's social platform links
*
* @return \App\Entities\Platform[]
*/
public function getSocialPlatforms()
{
if (empty($this->id)) {
throw new \RuntimeException(
'Podcast must be created before getting social platform links.'
);
}
if (empty($this->socialPlatforms)) {
$this->socialPlatforms = (new PlatformModel())->getPodcastPlatforms(
$this->id,
'social'
);
}
return $this->socialPlatforms;
}
/**
* Returns the podcast's funding platform links
*
* @return \App\Entities\Platform[]
*/
public function getFundingPlatforms()
{
if (empty($this->id)) {
throw new \RuntimeException(
'Podcast must be created before getting funding platform links.'
);
}
if (empty($this->fundingPlatforms)) {
$this->fundingPlatforms = (new PlatformModel())->getPodcastPlatforms(
$this->id,
'funding'
); );
} }
return $this->platforms; return $this->fundingPlatforms;
} }
public function getOtherCategories() public function getOtherCategories()
......
...@@ -71,6 +71,71 @@ function get_rss_feed($podcast, $serviceName = '') ...@@ -71,6 +71,71 @@ function get_rss_feed($podcast, $serviceName = '')
$podcast_namespace $podcast_namespace
) )
->addAttribute('owner', $podcast->owner_email); ->addAttribute('owner', $podcast->owner_email);
if (!empty($podcast->imported_feed_url)) {
$channel->addChildWithCDATA(
'previousUrl',
$podcast->imported_feed_url,
$podcast_namespace
);
}
foreach ($podcast->podcastingPlatforms as $podcastingPlatform) {
$podcastingPlatformElement = $channel->addChild(
'id',
null,
$podcast_namespace
);
$podcastingPlatformElement->addAttribute(
'platform',
$podcastingPlatform->slug
);
if (!empty($podcastingPlatform->link_content)) {
$podcastingPlatformElement->addAttribute(
'id',
$podcastingPlatform->link_content
);
}
if (!empty($podcastingPlatform->link_url)) {
$podcastingPlatformElement->addAttribute(
'url',
htmlspecialchars($podcastingPlatform->link_url)
);
}
}
foreach ($podcast->socialPlatforms as $socialPlatform) {
$socialPlatformElement = $channel->addChild(
'social',
$socialPlatform->link_content,
$podcast_namespace
);
$socialPlatformElement->addAttribute('platform', $socialPlatform->slug);
if (!empty($socialPlatform->link_url)) {
$socialPlatformElement->addAttribute(
'url',
htmlspecialchars($socialPlatform->link_url)
);
}
}
foreach ($podcast->fundingPlatforms as $fundingPlatform) {
$fundingPlatformElement = $channel->addChild(
'funding',
$fundingPlatform->link_content,
$podcast_namespace
);
$fundingPlatformElement->addAttribute(
'platform',
$fundingPlatform->slug
);
if (!empty($socialPlatform->link_url)) {
$fundingPlatformElement->addAttribute(
'url',
htmlspecialchars($fundingPlatform->link_url)
);
}
}
// set main category first, then other categories as apple // set main category first, then other categories as apple
add_category_tag($channel, $podcast->category); add_category_tag($channel, $podcast->category);
foreach ($podcast->other_categories as $other_category) { foreach ($podcast->other_categories as $other_category) {
......
...@@ -54,11 +54,11 @@ function svg($name, $class = null) ...@@ -54,11 +54,11 @@ function svg($name, $class = null)
* @param string $class to be added to the svg string * @param string $class to be added to the svg string
* @return string svg contents * @return string svg contents
*/ */
function platform_icon($name, $class = null) function platform_icon($type, $name, $class = null)
{ {
try { try {
$svg_contents = file_get_contents( $svg_contents = file_get_contents(
'assets/images/platforms/' . $name . '.svg' 'assets/images/platforms/' . $type . '/' . $name . '.svg'
); );
} catch (\Exception $e) { } catch (\Exception $e) {
$svg_contents = file_get_contents( $svg_contents = file_get_contents(
......
...@@ -20,13 +20,14 @@ return [ ...@@ -20,13 +20,14 @@ return [
'my-account' => 'my account', 'my-account' => 'my account',
'change-password' => 'change password', 'change-password' => 'change password',
'import' => 'feed import', 'import' => 'feed import',
'settings' => 'settings',
'platforms' => 'platforms', 'platforms' => 'platforms',
'analytics' => 'Analytics', 'social' => 'social networks',
'locations' => 'Locations', 'funding' => 'funding',
'webpages' => 'Web pages', 'analytics' => 'analytics',
'unique-listeners' => 'Unique listeners', 'locations' => 'locations',
'players' => 'Players', 'webpages' => 'web pages',
'listening-time' => 'Listening time', 'unique-listeners' => 'unique listeners',
'time-periods' => 'Time periods', 'players' => 'players',
'listening-time' => 'listening time',
'time-periods' => 'time periods',
]; ];
...@@ -19,4 +19,9 @@ return [ ...@@ -19,4 +19,9 @@ return [
'removeLinkError' => 'removeLinkError' =>
'The platform link could not be removed. Try again.', 'The platform link could not be removed. Try again.',
], ],
'description' => [
'podcasting' => 'The podcast ID on this platform',
'social' => 'The podcast account ID on this platform',
'funding' => 'Call to action message',
],
]; ];
...@@ -18,8 +18,10 @@ return [ ...@@ -18,8 +18,10 @@ return [
'contributors' => 'Contributors', 'contributors' => 'Contributors',
'contributor-list' => 'All contributors', 'contributor-list' => 'All contributors',
'contributor-add' => 'Add contributor', 'contributor-add' => 'Add contributor',
'settings' => 'Settings', 'platforms' => 'External platforms',
'platforms' => 'Podcast platforms', 'platforms-podcasting' => 'Podcasting',
'platforms-social' => 'Social Networks',
'platforms-funding' => 'Funding',
'podcast-analytics' => 'Audience overview', 'podcast-analytics' => 'Audience overview',
'podcast-analytics-webpages' => 'Web pages visits', 'podcast-analytics-webpages' => 'Web pages visits',
'podcast-analytics-locations' => 'Locations', 'podcast-analytics-locations' => 'Locations',
......
...@@ -20,13 +20,14 @@ return [ ...@@ -20,13 +20,14 @@ return [
'my-account' => 'mon compte', 'my-account' => 'mon compte',
'change-password' => 'changer le mot de passe', 'change-password' => 'changer le mot de passe',
'import' => 'importer un flux', 'import' => 'importer un flux',
'settings' => 'paramètres',
'platforms' => 'plateformes', 'platforms' => 'plateformes',
'analytics' => 'Mesures d’audience', 'social' => 'réseaux sociaux',
'locations' => 'Localisations', 'funding' => 'financement',
'webpages' => 'Pages web', 'analytics' => 'mesures d’audience',
'unique-listeners' => 'Auditeurs uniques', 'locations' => 'localisations',
'players' => 'Lecteurs', 'webpages' => 'pages web',
'listening-time' => 'Durée d’écoute', 'unique-listeners' => 'auditeurs uniques',
'time-periods' => 'Périodes', 'players' => 'lecteurs',
'listening-time' => 'drée d’écoute',
'time-periods' => 'périodes',
]; ];
...@@ -19,4 +19,9 @@ return [ ...@@ -19,4 +19,9 @@ return [
'removeLinkError' => 'removeLinkError' =>
'Le lien n’a pas pu être supprimé. Merci d’essayer à nouveau.', 'Le lien n’a pas pu être supprimé. Merci d’essayer à nouveau.',
], ],
'description' => [
'podcasting' => 'L’identifiant du podcast sur cette plate-forme',
'social' => 'L’identifiant du compte du podcast sur cette plate-forme',
'funding' => 'Message d’incitation à l’action',
],
]; ];