2020-06-08 20:32:42 +00:00
|
|
|
|
<?php
|
2020-08-04 11:25:22 +00:00
|
|
|
|
|
2021-06-08 09:52:11 +00:00
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
2020-06-10 15:00:12 +00:00
|
|
|
|
/**
|
2022-02-19 16:06:11 +00:00
|
|
|
|
* @copyright 2020 Ad Aures
|
2020-06-10 15:00:12 +00:00
|
|
|
|
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
|
|
|
|
|
* @link https://castopod.org/
|
|
|
|
|
*/
|
2020-06-08 20:32:42 +00:00
|
|
|
|
|
|
|
|
|
namespace App\Entities;
|
|
|
|
|
|
2021-12-24 09:49:34 +00:00
|
|
|
|
use App\Entities\Clip\Soundbite;
|
2021-05-06 14:00:48 +00:00
|
|
|
|
use App\Libraries\SimpleRSSElement;
|
2021-12-20 17:12:12 +00:00
|
|
|
|
use App\Models\ClipModel;
|
2021-08-13 16:07:45 +00:00
|
|
|
|
use App\Models\EpisodeCommentModel;
|
2023-08-28 13:53:04 +00:00
|
|
|
|
use App\Models\EpisodeModel;
|
2021-05-14 17:59:35 +00:00
|
|
|
|
use App\Models\PersonModel;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
use App\Models\PodcastModel;
|
2021-08-13 11:07:29 +00:00
|
|
|
|
use App\Models\PostModel;
|
2021-05-06 14:00:48 +00:00
|
|
|
|
use CodeIgniter\Entity\Entity;
|
2021-12-21 13:42:31 +00:00
|
|
|
|
use CodeIgniter\Files\File;
|
2021-12-17 17:14:37 +00:00
|
|
|
|
use CodeIgniter\HTTP\Files\UploadedFile;
|
2020-10-22 17:41:59 +00:00
|
|
|
|
use CodeIgniter\I18n\Time;
|
2023-08-29 15:51:44 +00:00
|
|
|
|
use Exception;
|
2022-02-02 17:01:19 +00:00
|
|
|
|
use League\CommonMark\Environment\Environment;
|
|
|
|
|
use League\CommonMark\Extension\Autolink\AutolinkExtension;
|
|
|
|
|
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
|
|
|
|
use League\CommonMark\Extension\DisallowedRawHtml\DisallowedRawHtmlExtension;
|
|
|
|
|
use League\CommonMark\Extension\SmartPunct\SmartPunctExtension;
|
|
|
|
|
use League\CommonMark\MarkdownConverter;
|
2024-02-12 16:55:09 +00:00
|
|
|
|
use Modules\Analytics\OP3;
|
2023-03-16 13:00:05 +00:00
|
|
|
|
use Modules\Media\Entities\Audio;
|
|
|
|
|
use Modules\Media\Entities\Chapters;
|
|
|
|
|
use Modules\Media\Entities\Image;
|
|
|
|
|
use Modules\Media\Entities\Transcript;
|
|
|
|
|
use Modules\Media\Models\MediaModel;
|
2021-05-06 14:00:48 +00:00
|
|
|
|
use RuntimeException;
|
2023-06-13 16:05:02 +00:00
|
|
|
|
use SimpleXMLElement;
|
2020-06-08 20:32:42 +00:00
|
|
|
|
|
2021-05-12 14:00:25 +00:00
|
|
|
|
/**
|
|
|
|
|
* @property int $id
|
|
|
|
|
* @property int $podcast_id
|
|
|
|
|
* @property Podcast $podcast
|
2023-08-28 13:53:04 +00:00
|
|
|
|
* @property ?string $preview_id
|
|
|
|
|
* @property string $preview_link
|
2021-05-12 14:00:25 +00:00
|
|
|
|
* @property string $link
|
|
|
|
|
* @property string $guid
|
|
|
|
|
* @property string $slug
|
|
|
|
|
* @property string $title
|
2021-12-14 16:41:10 +00:00
|
|
|
|
* @property int $audio_id
|
2023-05-09 07:47:54 +00:00
|
|
|
|
* @property ?Audio $audio
|
2022-12-09 15:04:42 +00:00
|
|
|
|
* @property string $audio_url
|
2022-01-21 08:52:28 +00:00
|
|
|
|
* @property string $audio_web_url
|
|
|
|
|
* @property string $audio_opengraph_url
|
2021-05-14 17:59:35 +00:00
|
|
|
|
* @property string|null $description Holds text only description, striped of any markdown or html special characters
|
2021-05-12 14:00:25 +00:00
|
|
|
|
* @property string $description_markdown
|
|
|
|
|
* @property string $description_html
|
2023-04-14 11:11:53 +00:00
|
|
|
|
* @property ?int $cover_id
|
|
|
|
|
* @property ?Image $cover
|
2021-12-14 16:41:10 +00:00
|
|
|
|
* @property int|null $transcript_id
|
2021-12-17 17:14:37 +00:00
|
|
|
|
* @property Transcript|null $transcript
|
2021-12-14 16:41:10 +00:00
|
|
|
|
* @property string|null $transcript_remote_url
|
|
|
|
|
* @property int|null $chapters_id
|
2021-12-17 17:14:37 +00:00
|
|
|
|
* @property Chapters|null $chapters
|
2021-12-14 16:41:10 +00:00
|
|
|
|
* @property string|null $chapters_remote_url
|
2021-05-12 14:00:25 +00:00
|
|
|
|
* @property string|null $parental_advisory
|
|
|
|
|
* @property int $number
|
|
|
|
|
* @property int $season_number
|
|
|
|
|
* @property string $type
|
|
|
|
|
* @property bool $is_blocked
|
2021-05-17 17:11:23 +00:00
|
|
|
|
* @property Location|null $location
|
2021-05-12 14:00:25 +00:00
|
|
|
|
* @property string|null $location_name
|
|
|
|
|
* @property string|null $location_geo
|
2021-05-17 17:11:23 +00:00
|
|
|
|
* @property string|null $location_osm
|
2025-01-08 11:11:19 +00:00
|
|
|
|
* @property array<string|int,mixed>|null $custom_rss
|
2021-05-12 14:00:25 +00:00
|
|
|
|
* @property string $custom_rss_string
|
2022-03-15 16:47:35 +00:00
|
|
|
|
* @property bool $is_published_on_hubs
|
2024-12-28 15:23:02 +00:00
|
|
|
|
* @property int $downloads_count
|
2021-08-13 11:07:29 +00:00
|
|
|
|
* @property int $posts_count
|
|
|
|
|
* @property int $comments_count
|
2022-07-21 16:21:26 +00:00
|
|
|
|
* @property EpisodeComment[]|null $comments
|
2022-09-28 15:02:09 +00:00
|
|
|
|
* @property bool $is_premium
|
2021-05-12 14:00:25 +00:00
|
|
|
|
* @property int $created_by
|
|
|
|
|
* @property int $updated_by
|
2022-09-28 15:02:09 +00:00
|
|
|
|
* @property string $publication_status
|
|
|
|
|
* @property Time|null $published_at
|
|
|
|
|
* @property Time $created_at
|
|
|
|
|
* @property Time $updated_at
|
2021-05-12 14:00:25 +00:00
|
|
|
|
*
|
2022-09-28 15:02:09 +00:00
|
|
|
|
* @property Person[] $persons
|
|
|
|
|
* @property Soundbite[] $soundbites
|
|
|
|
|
* @property string $embed_url
|
2021-05-12 14:00:25 +00:00
|
|
|
|
*/
|
2020-06-08 20:32:42 +00:00
|
|
|
|
class Episode extends Entity
|
|
|
|
|
{
|
2021-05-14 17:59:35 +00:00
|
|
|
|
protected Podcast $podcast;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-05-14 17:59:35 +00:00
|
|
|
|
protected string $link;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-12-17 17:14:37 +00:00
|
|
|
|
protected ?Audio $audio = null;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2022-12-09 15:04:42 +00:00
|
|
|
|
protected string $audio_url;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-12-14 16:41:10 +00:00
|
|
|
|
protected string $audio_web_url;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-12-14 16:41:10 +00:00
|
|
|
|
protected string $audio_opengraph_url;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-10-20 14:22:58 +00:00
|
|
|
|
protected string $embed_url;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-12-17 17:14:37 +00:00
|
|
|
|
protected ?Image $cover = null;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-05-17 17:11:23 +00:00
|
|
|
|
protected ?string $description = null;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-12-17 17:14:37 +00:00
|
|
|
|
protected ?Transcript $transcript = null;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-12-17 17:14:37 +00:00
|
|
|
|
protected ?Chapters $chapters = null;
|
2020-11-24 20:18:08 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2021-05-18 17:16:36 +00:00
|
|
|
|
* @var Person[]|null
|
2020-11-24 20:18:08 +00:00
|
|
|
|
*/
|
2021-05-18 17:16:36 +00:00
|
|
|
|
protected ?array $persons = null;
|
2021-02-10 16:20:01 +00:00
|
|
|
|
|
2020-12-07 20:13:46 +00:00
|
|
|
|
/**
|
2021-12-24 09:49:34 +00:00
|
|
|
|
* @var Soundbite[]|null
|
2020-12-07 20:13:46 +00:00
|
|
|
|
*/
|
2021-12-21 16:25:03 +00:00
|
|
|
|
protected ?array $soundbites = null;
|
2020-12-07 20:13:46 +00:00
|
|
|
|
|
2021-04-02 17:20:02 +00:00
|
|
|
|
/**
|
2021-08-13 11:07:29 +00:00
|
|
|
|
* @var Post[]|null
|
2021-04-02 17:20:02 +00:00
|
|
|
|
*/
|
2021-08-13 11:07:29 +00:00
|
|
|
|
protected ?array $posts = null;
|
2021-04-02 17:20:02 +00:00
|
|
|
|
|
2021-07-12 18:40:22 +00:00
|
|
|
|
/**
|
2021-08-13 16:07:45 +00:00
|
|
|
|
* @var EpisodeComment[]|null
|
2021-07-12 18:40:22 +00:00
|
|
|
|
*/
|
|
|
|
|
protected ?array $comments = null;
|
|
|
|
|
|
2021-05-17 17:11:23 +00:00
|
|
|
|
protected ?Location $location = null;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-05-14 17:59:35 +00:00
|
|
|
|
protected string $custom_rss_string;
|
2021-05-19 16:35:13 +00:00
|
|
|
|
|
2021-05-17 17:11:23 +00:00
|
|
|
|
protected ?string $publication_status = null;
|
2020-10-22 17:41:59 +00:00
|
|
|
|
|
2021-03-19 16:12:36 +00:00
|
|
|
|
/**
|
2023-08-26 13:03:01 +00:00
|
|
|
|
* @var array<int, string>
|
|
|
|
|
* @phpstan-var list<string>
|
2021-03-19 16:12:36 +00:00
|
|
|
|
*/
|
2022-06-13 16:30:34 +00:00
|
|
|
|
protected $dates = ['published_at', 'created_at', 'updated_at'];
|
2020-08-14 18:27:57 +00:00
|
|
|
|
|
2021-05-12 14:00:25 +00:00
|
|
|
|
/**
|
|
|
|
|
* @var array<string, string>
|
|
|
|
|
*/
|
2020-06-08 20:32:42 +00:00
|
|
|
|
protected $casts = [
|
2023-06-12 14:47:38 +00:00
|
|
|
|
'id' => 'integer',
|
|
|
|
|
'podcast_id' => 'integer',
|
2023-08-28 13:53:04 +00:00
|
|
|
|
'preview_id' => '?string',
|
2023-06-12 14:47:38 +00:00
|
|
|
|
'guid' => 'string',
|
|
|
|
|
'slug' => 'string',
|
|
|
|
|
'title' => 'string',
|
|
|
|
|
'audio_id' => 'integer',
|
|
|
|
|
'description_markdown' => 'string',
|
|
|
|
|
'description_html' => 'string',
|
|
|
|
|
'cover_id' => '?integer',
|
|
|
|
|
'transcript_id' => '?integer',
|
2021-12-14 16:41:10 +00:00
|
|
|
|
'transcript_remote_url' => '?string',
|
2023-06-12 14:47:38 +00:00
|
|
|
|
'chapters_id' => '?integer',
|
|
|
|
|
'chapters_remote_url' => '?string',
|
|
|
|
|
'parental_advisory' => '?string',
|
|
|
|
|
'number' => '?integer',
|
|
|
|
|
'season_number' => '?integer',
|
|
|
|
|
'type' => 'string',
|
|
|
|
|
'is_blocked' => 'boolean',
|
|
|
|
|
'location_name' => '?string',
|
|
|
|
|
'location_geo' => '?string',
|
|
|
|
|
'location_osm' => '?string',
|
|
|
|
|
'custom_rss' => '?json-array',
|
|
|
|
|
'is_published_on_hubs' => 'boolean',
|
2024-12-28 15:23:02 +00:00
|
|
|
|
'downloads_count' => 'integer',
|
2023-06-12 14:47:38 +00:00
|
|
|
|
'posts_count' => 'integer',
|
|
|
|
|
'comments_count' => 'integer',
|
|
|
|
|
'is_premium' => 'boolean',
|
|
|
|
|
'created_by' => 'integer',
|
|
|
|
|
'updated_by' => 'integer',
|
2020-06-08 20:32:42 +00:00
|
|
|
|
];
|
2020-06-26 14:34:52 +00:00
|
|
|
|
|
2021-12-21 13:42:31 +00:00
|
|
|
|
public function setCover(UploadedFile | File $file = null): self
|
2020-06-30 18:17:41 +02:00
|
|
|
|
{
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if (! $file instanceof File || ($file instanceof UploadedFile && ! $file->isValid())) {
|
2021-05-12 14:00:25 +00:00
|
|
|
|
return $this;
|
2020-06-30 18:17:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-17 17:14:37 +00:00
|
|
|
|
if (array_key_exists('cover_id', $this->attributes) && $this->attributes['cover_id'] !== null) {
|
|
|
|
|
$this->getCover()
|
|
|
|
|
->setFile($file);
|
|
|
|
|
$this->getCover()
|
2023-06-21 16:17:11 +00:00
|
|
|
|
->updated_by = $this->attributes['updated_by'];
|
2021-12-17 17:14:37 +00:00
|
|
|
|
(new MediaModel('image'))->updateMedia($this->getCover());
|
|
|
|
|
} else {
|
|
|
|
|
$cover = new Image([
|
2023-03-16 13:00:05 +00:00
|
|
|
|
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $this->attributes['slug'] . '.' . $file->getExtension(),
|
2024-04-28 16:39:01 +00:00
|
|
|
|
'sizes' => config('Images')
|
2025-01-08 11:11:19 +00:00
|
|
|
|
->podcastCoverSizes,
|
2023-06-21 16:17:11 +00:00
|
|
|
|
'uploaded_by' => $this->attributes['updated_by'],
|
|
|
|
|
'updated_by' => $this->attributes['updated_by'],
|
2021-12-17 17:14:37 +00:00
|
|
|
|
]);
|
|
|
|
|
$cover->setFile($file);
|
|
|
|
|
|
|
|
|
|
$this->attributes['cover_id'] = (new MediaModel('image'))->saveMedia($cover);
|
|
|
|
|
}
|
2021-05-12 14:00:25 +00:00
|
|
|
|
|
2020-06-30 18:17:41 +02:00
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-01 17:12:03 +00:00
|
|
|
|
public function getCover(): Image
|
2020-06-26 14:34:52 +00:00
|
|
|
|
{
|
2021-12-20 17:12:12 +00:00
|
|
|
|
if ($this->cover instanceof Image) {
|
|
|
|
|
return $this->cover;
|
2020-06-30 18:17:41 +02:00
|
|
|
|
}
|
2021-05-12 14:00:25 +00:00
|
|
|
|
|
2021-12-20 17:12:12 +00:00
|
|
|
|
if ($this->cover_id === null) {
|
|
|
|
|
$this->cover = $this->getPodcast()
|
|
|
|
|
->getCover();
|
|
|
|
|
|
|
|
|
|
return $this->cover;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->cover = (new MediaModel('image'))->getMediaById($this->cover_id);
|
|
|
|
|
|
2021-12-14 16:41:10 +00:00
|
|
|
|
return $this->cover;
|
2020-06-30 18:17:41 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-21 13:42:31 +00:00
|
|
|
|
public function setAudio(UploadedFile | File $file = null): self
|
2021-12-17 17:14:37 +00:00
|
|
|
|
{
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if (! $file instanceof File || ($file instanceof UploadedFile && ! $file->isValid())) {
|
2021-12-17 17:14:37 +00:00
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-20 17:12:12 +00:00
|
|
|
|
if ($this->audio_id !== 0) {
|
2021-12-17 17:14:37 +00:00
|
|
|
|
$this->getAudio()
|
|
|
|
|
->setFile($file);
|
|
|
|
|
$this->getAudio()
|
2023-06-21 16:17:11 +00:00
|
|
|
|
->updated_by = $this->attributes['updated_by'];
|
2021-12-17 17:14:37 +00:00
|
|
|
|
(new MediaModel('audio'))->updateMedia($this->getAudio());
|
|
|
|
|
} else {
|
2021-12-20 17:12:12 +00:00
|
|
|
|
$audio = new Audio([
|
2023-08-02 19:05:12 +02:00
|
|
|
|
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $file->getRandomName(),
|
2021-12-21 13:42:31 +00:00
|
|
|
|
'language_code' => $this->getPodcast()
|
|
|
|
|
->language_code,
|
2023-06-21 16:17:11 +00:00
|
|
|
|
'uploaded_by' => $this->attributes['updated_by'],
|
|
|
|
|
'updated_by' => $this->attributes['updated_by'],
|
2021-12-17 17:14:37 +00:00
|
|
|
|
]);
|
2021-12-20 17:12:12 +00:00
|
|
|
|
$audio->setFile($file);
|
2021-12-17 17:14:37 +00:00
|
|
|
|
|
2021-12-20 17:12:12 +00:00
|
|
|
|
$this->attributes['audio_id'] = (new MediaModel())->saveMedia($audio);
|
2021-12-17 17:14:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-14 16:41:10 +00:00
|
|
|
|
public function getAudio(): Audio
|
2020-11-24 20:18:08 +00:00
|
|
|
|
{
|
2021-12-17 17:14:37 +00:00
|
|
|
|
if (! $this->audio instanceof Audio) {
|
2021-12-14 16:41:10 +00:00
|
|
|
|
$this->audio = (new MediaModel('audio'))->getMediaById($this->audio_id);
|
|
|
|
|
}
|
2020-06-26 14:34:52 +00:00
|
|
|
|
|
2021-12-14 16:41:10 +00:00
|
|
|
|
return $this->audio;
|
2020-11-24 20:18:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-21 13:42:31 +00:00
|
|
|
|
public function setTranscript(UploadedFile | File $file = null): self
|
2021-12-17 17:14:37 +00:00
|
|
|
|
{
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if (! $file instanceof File || ($file instanceof UploadedFile && ! $file->isValid())) {
|
2021-12-17 17:14:37 +00:00
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if ($this->getTranscript() instanceof Transcript) {
|
2021-12-17 17:14:37 +00:00
|
|
|
|
$this->getTranscript()
|
|
|
|
|
->setFile($file);
|
|
|
|
|
$this->getTranscript()
|
2023-06-21 16:17:11 +00:00
|
|
|
|
->updated_by = $this->attributes['updated_by'];
|
2021-12-17 17:14:37 +00:00
|
|
|
|
(new MediaModel('transcript'))->updateMedia($this->getTranscript());
|
|
|
|
|
} else {
|
|
|
|
|
$transcript = new Transcript([
|
2023-06-12 14:47:38 +00:00
|
|
|
|
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $this->attributes['slug'] . '-transcript.' . $file->getExtension(),
|
2021-12-21 13:42:31 +00:00
|
|
|
|
'language_code' => $this->getPodcast()
|
2025-01-08 11:11:19 +00:00
|
|
|
|
->language_code,
|
2023-06-21 16:17:11 +00:00
|
|
|
|
'uploaded_by' => $this->attributes['updated_by'],
|
|
|
|
|
'updated_by' => $this->attributes['updated_by'],
|
2021-12-17 17:14:37 +00:00
|
|
|
|
]);
|
|
|
|
|
$transcript->setFile($file);
|
|
|
|
|
|
2022-01-09 16:37:13 +00:00
|
|
|
|
$this->attributes['transcript_id'] = (new MediaModel('transcript'))->saveMedia($transcript);
|
2021-12-17 17:14:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getTranscript(): ?Transcript
|
2020-11-24 20:18:08 +00:00
|
|
|
|
{
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if ($this->transcript_id !== null && ! $this->transcript instanceof Transcript) {
|
2021-12-17 17:14:37 +00:00
|
|
|
|
$this->transcript = (new MediaModel('transcript'))->getMediaById($this->transcript_id);
|
2021-05-03 17:39:58 +00:00
|
|
|
|
}
|
2020-06-30 18:17:41 +02:00
|
|
|
|
|
2021-12-14 16:41:10 +00:00
|
|
|
|
return $this->transcript;
|
2020-06-26 14:34:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-21 13:42:31 +00:00
|
|
|
|
public function setChapters(UploadedFile | File $file = null): self
|
2021-12-17 17:14:37 +00:00
|
|
|
|
{
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if (! $file instanceof File || ($file instanceof UploadedFile && ! $file->isValid())) {
|
2021-12-17 17:14:37 +00:00
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if ($this->getChapters() instanceof Chapters) {
|
2021-12-17 17:14:37 +00:00
|
|
|
|
$this->getChapters()
|
|
|
|
|
->setFile($file);
|
|
|
|
|
$this->getChapters()
|
2023-06-21 16:17:11 +00:00
|
|
|
|
->updated_by = $this->attributes['updated_by'];
|
2021-12-17 17:14:37 +00:00
|
|
|
|
(new MediaModel('chapters'))->updateMedia($this->getChapters());
|
|
|
|
|
} else {
|
|
|
|
|
$chapters = new Chapters([
|
2023-06-12 14:47:38 +00:00
|
|
|
|
'file_key' => 'podcasts/' . $this->getPodcast()->handle . '/' . $this->attributes['slug'] . '-chapters' . '.' . $file->getExtension(),
|
2021-12-21 13:42:31 +00:00
|
|
|
|
'language_code' => $this->getPodcast()
|
2025-01-08 11:11:19 +00:00
|
|
|
|
->language_code,
|
2023-06-21 16:17:11 +00:00
|
|
|
|
'uploaded_by' => $this->attributes['updated_by'],
|
|
|
|
|
'updated_by' => $this->attributes['updated_by'],
|
2021-12-17 17:14:37 +00:00
|
|
|
|
]);
|
|
|
|
|
$chapters->setFile($file);
|
|
|
|
|
|
2022-01-09 16:37:13 +00:00
|
|
|
|
$this->attributes['chapters_id'] = (new MediaModel('chapters'))->saveMedia($chapters);
|
2021-12-17 17:14:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function getChapters(): ?Chapters
|
2020-11-24 20:18:08 +00:00
|
|
|
|
{
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if ($this->chapters_id !== null && ! $this->chapters instanceof Chapters) {
|
2021-12-20 17:12:12 +00:00
|
|
|
|
$this->chapters = (new MediaModel('chapters'))->getMediaById($this->chapters_id);
|
2021-05-03 17:39:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-14 16:41:10 +00:00
|
|
|
|
return $this->chapters;
|
2020-11-24 20:18:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-12-09 15:04:42 +00:00
|
|
|
|
public function getAudioUrl(): string
|
2020-06-26 14:34:52 +00:00
|
|
|
|
{
|
2024-02-12 16:55:09 +00:00
|
|
|
|
$audioURL = url_to(
|
|
|
|
|
'episode-audio',
|
|
|
|
|
$this->getPodcast()
|
2025-01-08 11:11:19 +00:00
|
|
|
|
->handle,
|
2024-02-12 16:55:09 +00:00
|
|
|
|
$this->slug,
|
|
|
|
|
$this->getAudio()
|
2025-01-08 11:11:19 +00:00
|
|
|
|
->file_extension
|
2024-02-12 16:55:09 +00:00
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Wrap episode url with OP3 if episode is public and OP3 is enabled on this podcast
|
|
|
|
|
if (! $this->is_premium && service('settings')->get(
|
|
|
|
|
'Analytics.enableOP3',
|
|
|
|
|
'podcast:' . $this->podcast_id
|
|
|
|
|
)) {
|
|
|
|
|
$op3 = new OP3(config('Analytics')->OP3);
|
|
|
|
|
|
|
|
|
|
return $op3->wrap($audioURL, $this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $audioURL;
|
2020-06-26 14:34:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-21 08:52:28 +00:00
|
|
|
|
public function getAudioWebUrl(): string
|
2020-10-26 16:13:43 +00:00
|
|
|
|
{
|
2022-12-09 15:04:42 +00:00
|
|
|
|
return $this->getAudioUrl() . '?_from=-+Website+-';
|
2020-10-26 16:13:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-01-21 08:52:28 +00:00
|
|
|
|
public function getAudioOpengraphUrl(): string
|
2020-11-04 17:03:20 +00:00
|
|
|
|
{
|
2022-12-09 15:04:42 +00:00
|
|
|
|
return $this->getAudioUrl() . '?_from=-+Open+Graph+-';
|
2020-11-04 17:03:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-03 17:39:58 +00:00
|
|
|
|
/**
|
2021-12-14 16:41:10 +00:00
|
|
|
|
* Gets transcript url from transcript file uri if it exists or returns the transcript_remote_url which can be null.
|
2021-05-03 17:39:58 +00:00
|
|
|
|
*/
|
2021-12-14 16:41:10 +00:00
|
|
|
|
public function getTranscriptUrl(): ?string
|
2020-11-24 20:18:08 +00:00
|
|
|
|
{
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if ($this->transcript instanceof Transcript) {
|
2021-12-17 17:14:37 +00:00
|
|
|
|
return $this->transcript->file_url;
|
2021-05-03 17:39:58 +00:00
|
|
|
|
}
|
2022-03-04 14:33:48 +00:00
|
|
|
|
|
2021-12-14 16:41:10 +00:00
|
|
|
|
return $this->transcript_remote_url;
|
2020-11-24 20:18:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-03 17:39:58 +00:00
|
|
|
|
/**
|
2021-12-14 16:41:10 +00:00
|
|
|
|
* Gets chapters file url from chapters file uri if it exists or returns the chapters_remote_url which can be null.
|
2021-05-03 17:39:58 +00:00
|
|
|
|
*/
|
2021-05-06 14:00:48 +00:00
|
|
|
|
public function getChaptersFileUrl(): ?string
|
2020-11-24 20:18:08 +00:00
|
|
|
|
{
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if ($this->chapters instanceof Chapters) {
|
2021-12-17 17:14:37 +00:00
|
|
|
|
return $this->chapters->file_url;
|
2021-05-03 17:39:58 +00:00
|
|
|
|
}
|
2021-05-06 14:00:48 +00:00
|
|
|
|
|
2021-12-14 16:41:10 +00:00
|
|
|
|
return $this->chapters_remote_url;
|
2020-11-24 20:18:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-02-10 16:20:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* Returns the episode's persons
|
|
|
|
|
*
|
2021-05-14 17:59:35 +00:00
|
|
|
|
* @return Person[]
|
2021-02-10 16:20:01 +00:00
|
|
|
|
*/
|
2021-05-12 14:00:25 +00:00
|
|
|
|
public function getPersons(): array
|
2021-02-10 16:20:01 +00:00
|
|
|
|
{
|
2021-05-18 17:16:36 +00:00
|
|
|
|
if ($this->id === null) {
|
2021-06-08 09:52:11 +00:00
|
|
|
|
throw new RuntimeException('Episode must be created before getting persons.');
|
2021-02-10 16:20:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-18 17:16:36 +00:00
|
|
|
|
if ($this->persons === null) {
|
2021-06-08 09:52:11 +00:00
|
|
|
|
$this->persons = (new PersonModel())->getEpisodePersons($this->podcast_id, $this->id);
|
2021-02-10 16:20:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-04-02 17:20:02 +00:00
|
|
|
|
return $this->persons;
|
2021-02-10 16:20:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-12-07 20:13:46 +00:00
|
|
|
|
/**
|
2021-12-14 16:41:10 +00:00
|
|
|
|
* Returns the episode’s clips
|
2020-12-07 20:13:46 +00:00
|
|
|
|
*
|
2021-12-24 09:49:34 +00:00
|
|
|
|
* @return Soundbite[]
|
2020-12-07 20:13:46 +00:00
|
|
|
|
*/
|
2021-12-21 16:25:03 +00:00
|
|
|
|
public function getSoundbites(): array
|
2020-12-07 20:13:46 +00:00
|
|
|
|
{
|
2021-05-18 17:16:36 +00:00
|
|
|
|
if ($this->id === null) {
|
2021-12-21 16:25:03 +00:00
|
|
|
|
throw new RuntimeException('Episode must be created before getting soundbites.');
|
2020-12-07 20:13:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-21 16:25:03 +00:00
|
|
|
|
if ($this->soundbites === null) {
|
|
|
|
|
$this->soundbites = (new ClipModel())->getEpisodeSoundbites($this->getPodcast()->id, $this->id);
|
2020-12-07 20:13:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-12-21 16:25:03 +00:00
|
|
|
|
return $this->soundbites;
|
2020-12-07 20:13:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-12 14:00:25 +00:00
|
|
|
|
/**
|
2021-08-13 11:07:29 +00:00
|
|
|
|
* @return Post[]
|
2021-05-12 14:00:25 +00:00
|
|
|
|
*/
|
2021-08-13 11:07:29 +00:00
|
|
|
|
public function getPosts(): array
|
2021-04-02 17:20:02 +00:00
|
|
|
|
{
|
2021-05-18 17:16:36 +00:00
|
|
|
|
if ($this->id === null) {
|
2021-08-13 11:07:29 +00:00
|
|
|
|
throw new RuntimeException('Episode must be created before getting posts.');
|
2021-04-02 17:20:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-13 11:07:29 +00:00
|
|
|
|
if ($this->posts === null) {
|
|
|
|
|
$this->posts = (new PostModel())->getEpisodePosts($this->id);
|
2021-04-02 17:20:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-13 11:07:29 +00:00
|
|
|
|
return $this->posts;
|
2021-04-02 17:20:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-07-12 18:40:22 +00:00
|
|
|
|
/**
|
2021-08-13 16:07:45 +00:00
|
|
|
|
* @return EpisodeComment[]
|
2021-07-12 18:40:22 +00:00
|
|
|
|
*/
|
|
|
|
|
public function getComments(): array
|
|
|
|
|
{
|
|
|
|
|
if ($this->id === null) {
|
|
|
|
|
throw new RuntimeException('Episode must be created before getting comments.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ($this->comments === null) {
|
2021-08-13 16:07:45 +00:00
|
|
|
|
$this->comments = (new EpisodeCommentModel())->getEpisodeComments($this->id);
|
2021-07-12 18:40:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->comments;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-12 14:00:25 +00:00
|
|
|
|
public function getLink(): string
|
2020-06-26 14:34:52 +00:00
|
|
|
|
{
|
2022-03-04 14:33:48 +00:00
|
|
|
|
return url_to('episode', esc($this->getPodcast()->handle), esc($this->attributes['slug']));
|
2020-06-26 14:34:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-10-20 14:22:58 +00:00
|
|
|
|
public function getEmbedUrl(string $theme = null): string
|
2021-02-27 21:21:26 +00:00
|
|
|
|
{
|
2022-03-04 14:33:48 +00:00
|
|
|
|
return $theme
|
2023-02-22 16:29:45 +00:00
|
|
|
|
? url_to('embed-theme', esc($this->getPodcast()->handle), esc($this->attributes['slug']), $theme)
|
2022-03-04 14:33:48 +00:00
|
|
|
|
: url_to('embed', esc($this->getPodcast()->handle), esc($this->attributes['slug']));
|
2021-02-27 21:21:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-14 17:59:35 +00:00
|
|
|
|
public function setGuid(?string $guid = null): static
|
2020-06-26 14:34:52 +00:00
|
|
|
|
{
|
2024-04-26 09:26:22 +00:00
|
|
|
|
$this->attributes['guid'] = $guid ?? $this->getLink();
|
2021-05-12 14:00:25 +00:00
|
|
|
|
|
|
|
|
|
return $this;
|
2020-06-26 14:34:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-14 17:59:35 +00:00
|
|
|
|
public function getPodcast(): ?Podcast
|
2020-06-26 14:34:52 +00:00
|
|
|
|
{
|
2021-06-08 09:52:11 +00:00
|
|
|
|
return (new PodcastModel())->getPodcastById($this->podcast_id);
|
2020-06-26 14:34:52 +00:00
|
|
|
|
}
|
2020-07-27 09:35:34 +00:00
|
|
|
|
|
2021-05-14 17:59:35 +00:00
|
|
|
|
public function setDescriptionMarkdown(string $descriptionMarkdown): static
|
2020-07-27 09:35:34 +00:00
|
|
|
|
{
|
2022-02-02 17:01:19 +00:00
|
|
|
|
$config = [
|
2023-06-12 14:47:38 +00:00
|
|
|
|
'html_input' => 'escape',
|
2020-08-04 11:25:22 +00:00
|
|
|
|
'allow_unsafe_links' => false,
|
2022-02-02 17:01:19 +00:00
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$environment = new Environment($config);
|
|
|
|
|
$environment->addExtension(new CommonMarkCoreExtension());
|
|
|
|
|
$environment->addExtension(new AutolinkExtension());
|
|
|
|
|
$environment->addExtension(new SmartPunctExtension());
|
|
|
|
|
$environment->addExtension(new DisallowedRawHtmlExtension());
|
|
|
|
|
|
|
|
|
|
$converter = new MarkdownConverter($environment);
|
2020-07-27 09:35:34 +00:00
|
|
|
|
|
2020-10-29 15:45:19 +00:00
|
|
|
|
$this->attributes['description_markdown'] = $descriptionMarkdown;
|
2022-02-02 17:01:19 +00:00
|
|
|
|
$this->attributes['description_html'] = $converter->convert($descriptionMarkdown);
|
2020-10-29 15:45:19 +00:00
|
|
|
|
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-12 14:00:25 +00:00
|
|
|
|
public function getDescriptionHtml(?string $serviceSlug = null): string
|
2020-10-29 15:45:19 +00:00
|
|
|
|
{
|
2021-05-12 14:00:25 +00:00
|
|
|
|
$descriptionHtml = '';
|
|
|
|
|
if (
|
2021-05-19 16:35:13 +00:00
|
|
|
|
$this->getPodcast()
|
|
|
|
|
->partner_id !== null &&
|
|
|
|
|
$this->getPodcast()
|
|
|
|
|
->partner_link_url !== null &&
|
|
|
|
|
$this->getPodcast()
|
|
|
|
|
->partner_image_url !== null
|
2021-05-12 14:00:25 +00:00
|
|
|
|
) {
|
2021-05-19 16:35:13 +00:00
|
|
|
|
$descriptionHtml .= "<div><a href=\"{$this->getPartnerLink(
|
|
|
|
|
$serviceSlug,
|
|
|
|
|
)}\" rel=\"sponsored noopener noreferrer\" target=\"_blank\"><img src=\"{$this->getPartnerImageUrl(
|
|
|
|
|
$serviceSlug,
|
2021-05-12 14:00:25 +00:00
|
|
|
|
)}\" alt=\"Partner image\" /></a></div>";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$descriptionHtml .= $this->attributes['description_html'];
|
|
|
|
|
|
|
|
|
|
if ($this->getPodcast()->episode_description_footer_html) {
|
2021-05-19 16:35:13 +00:00
|
|
|
|
$descriptionHtml .= "<footer>{$this->getPodcast()
|
2025-01-08 11:11:19 +00:00
|
|
|
|
->episode_description_footer_html}</footer>";
|
2021-05-12 14:00:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $descriptionHtml;
|
2020-10-29 15:45:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-12 14:00:25 +00:00
|
|
|
|
public function getDescription(): string
|
2020-10-29 15:45:19 +00:00
|
|
|
|
{
|
2021-05-12 14:00:25 +00:00
|
|
|
|
if ($this->description === null) {
|
|
|
|
|
$this->description = trim(
|
2024-02-17 13:01:39 +00:00
|
|
|
|
(string) preg_replace('~\s+~', ' ', strip_tags((string) $this->attributes['description_html'])),
|
2021-05-12 14:00:25 +00:00
|
|
|
|
);
|
2020-10-29 15:45:19 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-12 14:00:25 +00:00
|
|
|
|
return $this->description;
|
2020-07-27 09:35:34 +00:00
|
|
|
|
}
|
2020-08-14 18:27:57 +00:00
|
|
|
|
|
2021-05-12 14:00:25 +00:00
|
|
|
|
public function getPublicationStatus(): string
|
2020-10-22 17:41:59 +00:00
|
|
|
|
{
|
2021-05-17 17:11:23 +00:00
|
|
|
|
if ($this->publication_status === null) {
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if (! $this->published_at instanceof Time) {
|
2021-05-17 17:11:23 +00:00
|
|
|
|
$this->publication_status = 'not_published';
|
2022-07-05 16:39:20 +00:00
|
|
|
|
} elseif ($this->getPodcast()->publication_status !== 'published') {
|
|
|
|
|
$this->publication_status = 'with_podcast';
|
2021-05-17 17:11:23 +00:00
|
|
|
|
} elseif ($this->published_at->isBefore(Time::now())) {
|
|
|
|
|
$this->publication_status = 'published';
|
|
|
|
|
} else {
|
|
|
|
|
$this->publication_status = 'scheduled';
|
|
|
|
|
}
|
2020-12-09 17:52:30 +00:00
|
|
|
|
}
|
2020-10-22 17:41:59 +00:00
|
|
|
|
|
2021-05-17 17:11:23 +00:00
|
|
|
|
return $this->publication_status;
|
2020-10-22 17:41:59 +00:00
|
|
|
|
}
|
2020-12-23 14:11:38 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Saves the location name and fetches OpenStreetMap info
|
|
|
|
|
*/
|
2021-05-17 17:11:23 +00:00
|
|
|
|
public function setLocation(?Location $location = null): static
|
2020-12-23 14:11:38 +00:00
|
|
|
|
{
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if (! $location instanceof Location) {
|
2021-05-12 14:00:25 +00:00
|
|
|
|
$this->attributes['location_name'] = null;
|
|
|
|
|
$this->attributes['location_geo'] = null;
|
2021-05-17 17:11:23 +00:00
|
|
|
|
$this->attributes['location_osm'] = null;
|
2021-05-12 14:00:25 +00:00
|
|
|
|
|
2021-05-17 17:11:23 +00:00
|
|
|
|
return $this;
|
|
|
|
|
}
|
2021-05-12 14:00:25 +00:00
|
|
|
|
|
2020-12-23 14:11:38 +00:00
|
|
|
|
if (
|
2021-05-19 16:35:13 +00:00
|
|
|
|
! isset($this->attributes['location_name']) ||
|
2021-05-17 17:11:23 +00:00
|
|
|
|
$this->attributes['location_name'] !== $location->name
|
2020-12-23 14:11:38 +00:00
|
|
|
|
) {
|
2021-05-17 17:11:23 +00:00
|
|
|
|
$location->fetchOsmLocation();
|
2021-05-12 14:00:25 +00:00
|
|
|
|
|
2021-05-17 17:11:23 +00:00
|
|
|
|
$this->attributes['location_name'] = $location->name;
|
|
|
|
|
$this->attributes['location_geo'] = $location->geo;
|
|
|
|
|
$this->attributes['location_osm'] = $location->osm;
|
2020-12-23 14:11:38 +00:00
|
|
|
|
}
|
2021-05-12 14:00:25 +00:00
|
|
|
|
|
2020-12-23 14:11:38 +00:00
|
|
|
|
return $this;
|
|
|
|
|
}
|
2021-03-19 16:12:36 +00:00
|
|
|
|
|
2021-05-12 14:00:25 +00:00
|
|
|
|
public function getLocation(): ?Location
|
|
|
|
|
{
|
|
|
|
|
if ($this->location_name === null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 11:11:53 +00:00
|
|
|
|
if (! $this->location instanceof Location) {
|
2021-06-08 09:52:11 +00:00
|
|
|
|
$this->location = new Location($this->location_name, $this->location_geo, $this->location_osm);
|
2021-05-12 14:00:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $this->location;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-19 16:12:36 +00:00
|
|
|
|
/**
|
|
|
|
|
* Get custom rss tag as XML String
|
|
|
|
|
*/
|
2021-05-19 16:35:13 +00:00
|
|
|
|
public function getCustomRssString(): string
|
2021-03-19 16:12:36 +00:00
|
|
|
|
{
|
2021-05-12 14:00:25 +00:00
|
|
|
|
if ($this->custom_rss === null) {
|
2021-03-19 16:12:36 +00:00
|
|
|
|
return '';
|
|
|
|
|
}
|
2021-05-06 14:00:48 +00:00
|
|
|
|
|
|
|
|
|
helper('rss');
|
|
|
|
|
|
|
|
|
|
$xmlNode = (new SimpleRSSElement(
|
2023-07-29 08:04:19 +00:00
|
|
|
|
'<?xml version="1.0" encoding="utf-8"?><rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:podcast="https://podcastindex.org/namespace/1.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"/>',
|
2021-05-06 14:00:48 +00:00
|
|
|
|
))
|
|
|
|
|
->addChild('channel')
|
|
|
|
|
->addChild('item');
|
2021-05-19 16:35:13 +00:00
|
|
|
|
array_to_rss([
|
|
|
|
|
'elements' => $this->custom_rss,
|
2021-06-08 09:52:11 +00:00
|
|
|
|
], $xmlNode);
|
2021-05-12 14:00:25 +00:00
|
|
|
|
|
2022-10-17 14:17:50 +00:00
|
|
|
|
return str_replace(['<item>', '</item>'], '', (string) $xmlNode->asXML());
|
2021-03-19 16:12:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Saves custom rss tag into json
|
|
|
|
|
*/
|
2021-05-19 16:35:13 +00:00
|
|
|
|
public function setCustomRssString(?string $customRssString = null): static
|
2021-03-19 16:12:36 +00:00
|
|
|
|
{
|
2021-08-11 12:15:20 +00:00
|
|
|
|
if ($customRssString === '') {
|
|
|
|
|
$this->attributes['custom_rss'] = null;
|
2021-05-06 14:00:48 +00:00
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-19 16:12:36 +00:00
|
|
|
|
helper('rss');
|
2023-06-13 16:05:02 +00:00
|
|
|
|
|
|
|
|
|
$customXML = simplexml_load_string(
|
2023-07-29 08:04:19 +00:00
|
|
|
|
'<?xml version="1.0" encoding="utf-8"?><rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:podcast="https://podcastindex.org/namespace/1.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0"><channel><item>' .
|
2023-06-13 16:05:02 +00:00
|
|
|
|
$customRssString .
|
|
|
|
|
'</item></channel></rss>',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (! $customXML instanceof SimpleXMLElement) {
|
|
|
|
|
// TODO: Failed to parse custom xml, should return error?
|
|
|
|
|
return $this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$customRssArray = rss_to_array($customXML)['elements'][0]['elements'][0];
|
2021-05-06 14:00:48 +00:00
|
|
|
|
|
2021-03-19 16:12:36 +00:00
|
|
|
|
if (array_key_exists('elements', $customRssArray)) {
|
2021-06-08 09:52:11 +00:00
|
|
|
|
$this->attributes['custom_rss'] = json_encode($customRssArray['elements']);
|
2021-03-19 16:12:36 +00:00
|
|
|
|
} else {
|
|
|
|
|
$this->attributes['custom_rss'] = null;
|
|
|
|
|
}
|
2021-05-06 14:00:48 +00:00
|
|
|
|
|
|
|
|
|
return $this;
|
2021-03-19 16:12:36 +00:00
|
|
|
|
}
|
2021-03-30 16:21:00 +00:00
|
|
|
|
|
2021-05-19 16:35:13 +00:00
|
|
|
|
public function getPartnerLink(?string $serviceSlug = null): string
|
2021-03-30 16:21:00 +00:00
|
|
|
|
{
|
2021-05-12 14:00:25 +00:00
|
|
|
|
$partnerLink =
|
2024-02-17 13:01:39 +00:00
|
|
|
|
rtrim((string) $this->getPodcast()->partner_link_url, '/') .
|
2021-03-30 16:21:00 +00:00
|
|
|
|
'?pid=' .
|
2021-05-19 16:35:13 +00:00
|
|
|
|
$this->getPodcast()
|
|
|
|
|
->partner_id .
|
2021-03-30 16:21:00 +00:00
|
|
|
|
'&guid=' .
|
2022-10-17 14:17:50 +00:00
|
|
|
|
urlencode((string) $this->attributes['guid']);
|
2021-05-12 14:00:25 +00:00
|
|
|
|
|
|
|
|
|
if ($serviceSlug !== null) {
|
|
|
|
|
$partnerLink .= '&_from=' . $serviceSlug;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $partnerLink;
|
2021-03-30 16:21:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2021-05-19 16:35:13 +00:00
|
|
|
|
public function getPartnerImageUrl(string $serviceSlug = null): string
|
2021-03-30 16:21:00 +00:00
|
|
|
|
{
|
2024-02-17 13:01:39 +00:00
|
|
|
|
return rtrim((string) $this->getPodcast()->partner_image_url, '/') .
|
2021-05-17 17:11:23 +00:00
|
|
|
|
'?pid=' .
|
2021-05-19 16:35:13 +00:00
|
|
|
|
$this->getPodcast()
|
|
|
|
|
->partner_id .
|
2021-05-17 17:11:23 +00:00
|
|
|
|
'&guid=' .
|
2022-10-17 14:17:50 +00:00
|
|
|
|
urlencode((string) $this->attributes['guid']) .
|
2021-08-31 08:52:28 +00:00
|
|
|
|
($serviceSlug !== null ? '&_from=' . $serviceSlug : '');
|
2021-03-30 16:21:00 +00:00
|
|
|
|
}
|
2023-08-28 13:53:04 +00:00
|
|
|
|
|
|
|
|
|
public function getPreviewLink(): string
|
|
|
|
|
{
|
|
|
|
|
if ($this->preview_id === null) {
|
|
|
|
|
// generate preview id
|
|
|
|
|
if (! $previewUUID = (new EpisodeModel())->setEpisodePreviewId($this->id)) {
|
|
|
|
|
throw new Exception('Could not set episode preview id');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$this->preview_id = $previewUUID;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return url_to('episode-preview', (string) $this->preview_id);
|
|
|
|
|
}
|
2023-11-29 16:00:28 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the episode's clip count
|
|
|
|
|
*/
|
|
|
|
|
public function getClipCount(): int|string
|
|
|
|
|
{
|
|
|
|
|
if ($this->id === null) {
|
|
|
|
|
throw new RuntimeException('Episode must be created before getting number of video clips.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (new ClipModel())->getClipCount($this->podcast_id, $this->id);
|
|
|
|
|
}
|
2020-06-08 20:32:42 +00:00
|
|
|
|
}
|