diff --git a/app/Config/Images.php b/app/Config/Images.php index cb8c4e59fc6e6e5fdc10fdc363f6f1065267351b..e48805adf64d6bde68ff3d7bcc54f9d7c1acf8b0 100644 --- a/app/Config/Images.php +++ b/app/Config/Images.php @@ -126,6 +126,10 @@ class Images extends BaseConfig ], ]; + public string $avatarDefaultPath = 'castopod-avatar-default.jpg'; + + public string $avatarDefaultMimeType = 'image/jpg'; + public string $podcastBannerDefaultPath = 'castopod-banner-default.jpg'; public string $podcastBannerDefaultMimeType = 'image/jpeg'; diff --git a/app/Database/Migrations/2020-05-29-120000_add_media.php b/app/Database/Migrations/2020-05-29-120000_add_media.php index 6f80aad11463276eb67441428f6e4909e58e367e..f807837014d1dbc2c1cfc023cb24f270829b974f 100644 --- a/app/Database/Migrations/2020-05-29-120000_add_media.php +++ b/app/Database/Migrations/2020-05-29-120000_add_media.php @@ -37,7 +37,7 @@ class AddMedia extends Migration ], 'file_metadata' => [ 'type' => 'JSON', - 'nullable' => true, + 'null' => true, ], 'type' => [ 'type' => 'ENUM', @@ -46,6 +46,7 @@ class AddMedia extends Migration ], 'description' => [ 'type' => 'TEXT', + 'null' => true, ], 'language_code' => [ 'type' => 'VARCHAR', 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 436c741b5fd872bf4f7791aa487f0b7df5140380..65913aee8e5479b212c3812bfeef32a4640f46de 100644 --- a/app/Database/Migrations/2020-05-30-101500_add_podcasts.php +++ b/app/Database/Migrations/2020-05-30-101500_add_podcasts.php @@ -54,7 +54,6 @@ class AddPodcasts extends Migration 'type' => 'INT', 'unsigned' => true, 'null' => true, - 'default' => null, ], 'language_code' => [ 'type' => 'VARCHAR', @@ -69,7 +68,6 @@ class AddPodcasts extends Migration 'type' => 'ENUM', 'constraint' => ['clean', 'explicit'], 'null' => true, - 'default' => null, ], 'owner_name' => [ 'type' => 'VARCHAR', 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 9e0efaa25078539b49e870f16f09f500500b41dc..bbbad3f8dade4fc861aea76ebc8d28a0591d31d5 100644 --- a/app/Database/Migrations/2020-06-05-170000_add_episodes.php +++ b/app/Database/Migrations/2020-06-05-170000_add_episodes.php @@ -79,7 +79,6 @@ class AddEpisodes extends Migration 'type' => 'ENUM', 'constraint' => ['clean', 'explicit'], 'null' => true, - 'default' => null, ], 'number' => [ 'type' => 'INT', diff --git a/app/Database/Migrations/2020-06-05-190000_add_platforms.php b/app/Database/Migrations/2020-06-05-190000_add_platforms.php index 24dec9434ab8b39a7d6a2da2fbbe77fa06e03ded..7cc3231e360c312dc4ade70cfbfc918318a3a3a6 100644 --- a/app/Database/Migrations/2020-06-05-190000_add_platforms.php +++ b/app/Database/Migrations/2020-06-05-190000_add_platforms.php @@ -39,7 +39,6 @@ class AddPlatforms extends Migration 'type' => 'VARCHAR', 'constraint' => 512, 'null' => true, - 'default' => null, ], ]); $this->forge->addField('`created_at` timestamp NOT NULL DEFAULT NOW()'); diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php index dbdb47ccde4b6115d0e80380d7ed1c26b4b34fa8..feeede4d35d3051c015960b4c03a7413276192df 100644 --- a/app/Entities/Episode.php +++ b/app/Entities/Episode.php @@ -15,14 +15,13 @@ use App\Entities\Media\Chapters; use App\Entities\Media\Image; use App\Entities\Media\Transcript; use App\Libraries\SimpleRSSElement; -use App\Models\ClipsModel; +use App\Models\ClipModel; use App\Models\EpisodeCommentModel; use App\Models\MediaModel; use App\Models\PersonModel; use App\Models\PodcastModel; use App\Models\PostModel; use CodeIgniter\Entity\Entity; -use CodeIgniter\Files\File; use CodeIgniter\HTTP\Files\UploadedFile; use CodeIgniter\I18n\Time; use League\CommonMark\CommonMarkConverter; @@ -181,7 +180,7 @@ class Episode extends Entity } else { $cover = new Image([ 'file_name' => $this->attributes['slug'], - 'file_directory' => 'podcasts/' . $this->attributes['handle'], + 'file_directory' => 'podcasts/' . $this->getPodcast()->handle, 'sizes' => config('Images') ->podcastCoverSizes, 'uploaded_by' => user_id(), @@ -197,10 +196,19 @@ class Episode extends Entity public function getCover(): Image { - if (! $this->cover instanceof Image) { - $this->cover = (new MediaModel('image'))->getMediaById($this->cover_id); + if ($this->cover instanceof Image) { + return $this->cover; } + if ($this->cover_id === null) { + $this->cover = $this->getPodcast() + ->getCover(); + + return $this->cover; + } + + $this->cover = (new MediaModel('image'))->getMediaById($this->cover_id); + return $this->cover; } @@ -210,22 +218,22 @@ class Episode extends Entity return $this; } - if ($this->audio_id !== null) { + if ($this->audio_id !== 0) { $this->getAudio() ->setFile($file); $this->getAudio() ->updated_by = (int) user_id(); (new MediaModel('audio'))->updateMedia($this->getAudio()); } else { - $transcript = new Audio([ + $audio = new Audio([ 'file_name' => $this->attributes['slug'], - 'file_directory' => 'podcasts/' . $this->attributes['handle'], + 'file_directory' => 'podcasts/' . $this->getPodcast()->handle, 'uploaded_by' => user_id(), 'updated_by' => user_id(), ]); - $transcript->setFile($file); + $audio->setFile($file); - $this->attributes['transcript_id'] = (new MediaModel())->saveMedia($transcript); + $this->attributes['audio_id'] = (new MediaModel())->saveMedia($audio); } return $this; @@ -255,7 +263,7 @@ class Episode extends Entity } else { $transcript = new Transcript([ 'file_name' => $this->attributes['slug'] . '-transcript', - 'file_directory' => 'podcasts/' . $this->attributes['handle'], + 'file_directory' => 'podcasts/' . $this->getPodcast()->handle, 'uploaded_by' => user_id(), 'updated_by' => user_id(), ]); @@ -291,7 +299,7 @@ class Episode extends Entity } else { $chapters = new Chapters([ 'file_name' => $this->attributes['slug'] . '-chapters', - 'file_directory' => 'podcasts/' . $this->attributes['handle'], + 'file_directory' => 'podcasts/' . $this->getPodcast()->handle, 'uploaded_by' => user_id(), 'updated_by' => user_id(), ]); @@ -306,7 +314,7 @@ class Episode extends Entity public function getChapters(): ?Chapters { if ($this->chapters_id !== null && $this->chapters === null) { - $this->chapters = (new MediaModel('document'))->getMediaById($this->chapters_id); + $this->chapters = (new MediaModel('chapters'))->getMediaById($this->chapters_id); } return $this->chapters; @@ -324,7 +332,7 @@ class Episode extends Entity helper('analytics'); // remove 'podcasts/' from audio file path - $strippedAudioFilePath = substr($this->audio->file_path, 9); + $strippedAudioFilePath = substr($this->getAudio()->file_path, 9); return generate_episode_analytics_url( $this->podcast_id, @@ -400,7 +408,7 @@ class Episode extends Entity } if ($this->clips === null) { - $this->clips = (new ClipsModel())->getEpisodeClips($this->getPodcast() ->id, $this->id); + $this->clips = (new ClipModel())->getEpisodeClips($this->getPodcast() ->id, $this->id); } return $this->clips; diff --git a/app/Entities/Media/Audio.php b/app/Entities/Media/Audio.php index 288f95506ee66df297bbd333cab5c6b6ed645920..de71409fb841519f622360ad1d22feafe4ddc952 100644 --- a/app/Entities/Media/Audio.php +++ b/app/Entities/Media/Audio.php @@ -39,12 +39,13 @@ class Audio extends BaseMedia parent::setFile($file); $getID3 = new GetID3(); - $audioMetadata = $getID3->analyze((string) $file); + $audioMetadata = $getID3->analyze(media_path($this->file_path)); - $this->attributes['file_mimetype'] = $audioMetadata['mimetype']; + $this->attributes['file_mimetype'] = $audioMetadata['mime_type']; $this->attributes['file_size'] = $audioMetadata['filesize']; - $this->attributes['description'] = $audioMetadata['comments']['comment']; - $this->attributes['file_metadata'] = $audioMetadata; + // @phpstan-ignore-next-line + $this->attributes['description'] = @$audioMetadata['id3v2']['comments']['comment']; + $this->attributes['file_metadata'] = json_encode($audioMetadata); return $this; } diff --git a/app/Entities/Media/BaseMedia.php b/app/Entities/Media/BaseMedia.php index 36b672b99788b5e402b406507b8ce99ff4f7c913..f71781f80c88a6d5218a104f2f86be689b55ac5a 100644 --- a/app/Entities/Media/BaseMedia.php +++ b/app/Entities/Media/BaseMedia.php @@ -20,11 +20,12 @@ use CodeIgniter\Files\File; * @property string $file_directory * @property string $file_extension * @property string $file_name + * @property string $file_name_with_extension * @property int $file_size * @property string $file_mimetype - * @property array $file_metadata + * @property array|null $file_metadata * @property 'image'|'audio'|'video'|'document' $type - * @property string $description + * @property string|null $description * @property string|null $language_code * @property int $uploaded_by * @property int $updated_by @@ -33,8 +34,6 @@ class BaseMedia extends Entity { protected File $file; - protected string $type = 'document'; - /** * @var string[] */ @@ -49,9 +48,9 @@ class BaseMedia extends Entity 'file_path' => 'string', 'file_size' => 'int', 'file_mimetype' => 'string', - 'file_metadata' => 'json-array', + 'file_metadata' => '?json-array', 'type' => 'string', - 'description' => 'string', + 'description' => '?string', 'language_code' => '?string', 'uploaded_by' => 'integer', 'updated_by' => 'integer', @@ -81,6 +80,7 @@ class BaseMedia extends Entity $this->attributes['file_name'] = $filename; $this->attributes['file_directory'] = $dirname; $this->attributes['file_extension'] = $extension; + $this->attributes['file_name_with_extension'] = "{$filename}.{$extension}"; } } @@ -101,4 +101,10 @@ class BaseMedia extends Entity return $this; } + + public function deleteFile(): void + { + helper('media'); + unlink(media_path($this->file_path)); + } } diff --git a/app/Entities/Media/Image.php b/app/Entities/Media/Image.php index fff51e00a6f730da9b5a3d5f3729084187c5c91f..7d48b0f4d05e4472de4eacde9daa088f3885805c 100644 --- a/app/Entities/Media/Image.php +++ b/app/Entities/Media/Image.php @@ -70,9 +70,7 @@ class Image extends BaseMedia public function deleteFile(): void { - helper('media'); - - unlink(media_path($this->file_path)); + parent::deleteFile(); $this->deleteSizes(); } diff --git a/app/Entities/Person.php b/app/Entities/Person.php index c8b8478913f6037ae81e35f7ba5e9e22f123e3c3..d13e614e304e703093171a89573da5c5bcbe896f 100644 --- a/app/Entities/Person.php +++ b/app/Entities/Person.php @@ -14,6 +14,7 @@ use App\Entities\Media\Image; use App\Models\MediaModel; use App\Models\PersonModel; use CodeIgniter\Entity\Entity; +use CodeIgniter\Files\File; use CodeIgniter\HTTP\Files\UploadedFile; use RuntimeException; @@ -55,20 +56,20 @@ class Person extends Entity /** * Saves the person avatar in `public/media/persons/` */ - public function setAvatar(?UploadedFile $file = null): static + public function setAvatar(UploadedFile | File $file = null): static { - if ($file === null || ! $file->isValid()) { + if ($file === null || ($file instanceof UploadedFile && ! $file->isValid())) { return $this; } - if (array_key_exists('cover_id', $this->attributes) && $this->attributes['cover_id'] !== null) { + if (array_key_exists('avatar_id', $this->attributes) && $this->attributes['avatar_id'] !== null) { $this->getAvatar() ->setFile($file); $this->getAvatar() ->updated_by = (int) user_id(); (new MediaModel('image'))->updateMedia($this->getAvatar()); } else { - $cover = new Image([ + $avatar = new Image([ 'file_name' => $this->attributes['unique_name'], 'file_directory' => 'persons', 'sizes' => config('Images') @@ -76,9 +77,9 @@ class Person extends Entity 'uploaded_by' => user_id(), 'updated_by' => user_id(), ]); - $cover->setFile($file); + $avatar->setFile($file); - $this->attributes['cover_id'] = (new MediaModel('image'))->saveMedia($cover); + $this->attributes['avatar_id'] = (new MediaModel('image'))->saveMedia($avatar); } return $this; @@ -89,10 +90,15 @@ class Person extends Entity if ($this->attributes['avatar_id'] === null) { helper('media'); return new Image([ - 'file_path' => media_path('castopod-avatar-default.jpg'), - 'file_mimetype' => 'image/jpeg', - 'sizes' => config('Images') - ->personAvatarSizes, + 'file_path' => config('Images') + ->avatarDefaultPath, + 'file_mimetype' => config('Images') + ->avatarDefaultMimeType, + 'file_size' => 0, + 'file_metadata' => [ + 'sizes' => config('Images') + ->personAvatarSizes, + ], ]); } diff --git a/app/Entities/Podcast.php b/app/Entities/Podcast.php index d2e5a04bb7996848be9f97d7e1236ce7f38735c2..67534ddb57bd9c66ba3f207ff0521cdf3d7c85d6 100644 --- a/app/Entities/Podcast.php +++ b/app/Entities/Podcast.php @@ -19,6 +19,7 @@ use App\Models\PersonModel; use App\Models\PlatformModel; use App\Models\UserModel; use CodeIgniter\Entity\Entity; +use CodeIgniter\Files\File; use CodeIgniter\HTTP\Files\UploadedFile; use CodeIgniter\I18n\Time; use League\CommonMark\CommonMarkConverter; @@ -194,9 +195,9 @@ class Podcast extends Entity return $this->actor; } - public function setCover(?UploadedFile $file = null): self + public function setCover(UploadedFile | File $file = null): self { - if ($file === null || ! $file->isValid()) { + if ($file === null || ($file instanceof UploadedFile && ! $file->isValid())) { return $this; } @@ -232,9 +233,9 @@ class Podcast extends Entity return $this->cover; } - public function setBanner(?UploadedFile $file): self + public function setBanner(UploadedFile | File $file = null): self { - if ($file === null || ! $file->isValid()) { + if ($file === null || ($file instanceof UploadedFile && ! $file->isValid())) { return $this; } diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php index 15ad1c088f72c9f898afc9674f8f5a97616d86d7..a608e03ba5fc6d5d050f574aa55d6694e9e2771f 100644 --- a/app/Helpers/components_helper.php +++ b/app/Helpers/components_helper.php @@ -144,7 +144,7 @@ if (! function_exists('publication_button')) { case 'scheduled': $label = lang('Episode.publish_edit'); $route = route_to('episode-publish_edit', $podcastId, $episodeId); - $variant = 'accent'; + $variant = 'warning'; $iconLeft = 'upload-cloud'; break; case 'published': diff --git a/app/Helpers/rss_helper.php b/app/Helpers/rss_helper.php index 93e40cf2dc41f61bf769746bc6efbbd9672892a6..076296b505e0b8c6b3c83bf8fe7bd36998fdcc88 100644 --- a/app/Helpers/rss_helper.php +++ b/app/Helpers/rss_helper.php @@ -267,7 +267,7 @@ if (! function_exists('get_rss_feed')) { $transcriptElement->addAttribute('language', $podcast->language_code); } - if ($episode->chapters->file_url !== '') { + if ($episode->getChapters() !== null) { $chaptersElement = $item->addChild('chapters', null, $podcastNamespace); $chaptersElement->addAttribute('url', $episode->chapters->file_url); $chaptersElement->addAttribute('type', 'application/json+chapters'); diff --git a/app/Models/ClipModel.php b/app/Models/ClipModel.php index 6a7b2d8cc5f9588f4560e1f2c97b63325bc5ac80..3a1b8b25264746a7395ef75ffdecc891fbf40142 100644 --- a/app/Models/ClipModel.php +++ b/app/Models/ClipModel.php @@ -16,7 +16,7 @@ use App\Entities\Clip; use CodeIgniter\Database\BaseResult; use CodeIgniter\Model; -class ClipsModel extends Model +class ClipModel extends Model { /** * @var string diff --git a/app/Models/MediaModel.php b/app/Models/MediaModel.php index ceea6a957fee43bc3e8a3905d712f6727138dbdf..f0fd5b8389b1a2b340da971430b2630742877acc 100644 --- a/app/Models/MediaModel.php +++ b/app/Models/MediaModel.php @@ -128,8 +128,10 @@ class MediaModel extends Model return $this->update($media->id, $media); } - public function deleteMedia(int $mediaId): bool + public function deleteMedia(object $media): bool { - return $this->delete($mediaId, true); + $media->deleteFile(); + + return $this->delete($media->id, true); } } diff --git a/modules/Admin/Controllers/EpisodeController.php b/modules/Admin/Controllers/EpisodeController.php index 637f84da1032ff020c71e2bbbe54d49c124bd6a8..7cdb144a8f2d5fb46a134bd7357db0f7d1eea4eb 100644 --- a/modules/Admin/Controllers/EpisodeController.php +++ b/modules/Admin/Controllers/EpisodeController.php @@ -15,9 +15,10 @@ use App\Entities\EpisodeComment; use App\Entities\Location; use App\Entities\Podcast; use App\Entities\Post; -use App\Models\ClipsModel; +use App\Models\ClipModel; use App\Models\EpisodeCommentModel; use App\Models\EpisodeModel; +use App\Models\MediaModel; use App\Models\PodcastModel; use App\Models\PostModel; use CodeIgniter\Exceptions\PageNotFoundException; @@ -125,6 +126,9 @@ class EpisodeController extends BaseController ->with('errors', $this->validator->getErrors()); } + $db = db_connect(); + $db->transStart(); + $newEpisode = new Episode([ 'podcast_id' => $this->podcast->id, 'title' => $this->request->getPost('title'), @@ -143,10 +147,10 @@ class EpisodeController extends BaseController ? $this->request->getPost('parental_advisory') : null, 'number' => $this->request->getPost('episode_number') - ? $this->request->getPost('episode_number') + ? (int) $this->request->getPost('episode_number') : null, 'season_number' => $this->request->getPost('season_number') - ? $this->request->getPost('season_number') + ? (int) $this->request->getPost('season_number') : null, 'type' => $this->request->getPost('type'), 'is_blocked' => $this->request->getPost('block') === 'yes', @@ -156,9 +160,6 @@ class EpisodeController extends BaseController 'published_at' => null, ]); - $db = db_connect(); - $db->transStart(); - $transcriptChoice = $this->request->getPost('transcript-choice'); if ($transcriptChoice === 'upload-file') { $newEpisode->setTranscript($this->request->getFile('transcript_file')); @@ -178,8 +179,8 @@ class EpisodeController extends BaseController } $episodeModel = new EpisodeModel(); - if (! ($newEpisodeId = $episodeModel->insert($newEpisode, true))) { + $db->transRollback(); return redirect() ->back() ->withInput() @@ -195,6 +196,7 @@ class EpisodeController extends BaseController $podcastModel = new PodcastModel(); if (! $podcastModel->update($this->podcast->id, $this->podcast)) { + $db->transRollback(); return redirect() ->back() ->withInput() @@ -202,6 +204,8 @@ class EpisodeController extends BaseController } } + $db->transComplete(); + return redirect()->route('episode-view', [$this->podcast->id, $newEpisodeId]); } @@ -268,36 +272,34 @@ class EpisodeController extends BaseController if ($transcriptChoice === 'upload-file') { $transcriptFile = $this->request->getFile('transcript_file'); if ($transcriptFile !== null && $transcriptFile->isValid()) { - $this->episode->transcript_file = $transcriptFile; + $this->episode->setTranscript($transcriptFile); $this->episode->transcript_remote_url = null; } } elseif ($transcriptChoice === 'remote-url') { if ( - ($transcriptFileRemoteUrl = $this->request->getPost('transcript_remote_url')) && - (($transcriptFile = $this->episode->transcript_file) !== null) + ($transcriptRemoteUrl = $this->request->getPost('transcript_remote_url')) && + (($transcriptFile = $this->episode->transcript_id) !== null) ) { - unlink((string) $transcriptFile); - $this->episode->transcript->file_path = null; + (new MediaModel())->deleteMedia($this->episode->transcript); } - $this->episode->transcript_remote_url = $transcriptFileRemoteUrl === '' ? null : $transcriptFileRemoteUrl; + $this->episode->transcript_remote_url = $transcriptRemoteUrl === '' ? null : $transcriptRemoteUrl; } $chaptersChoice = $this->request->getPost('chapters-choice'); if ($chaptersChoice === 'upload-file') { $chaptersFile = $this->request->getFile('chapters_file'); if ($chaptersFile !== null && $chaptersFile->isValid()) { - $this->episode->chapters = $chaptersFile; + $this->episode->setChapters($chaptersFile); $this->episode->chapters_remote_url = null; } } elseif ($chaptersChoice === 'remote-url') { if ( - ($chaptersFileRemoteUrl = $this->request->getPost('chapters_remote_url')) && - (($chaptersFile = $this->episode->chapters_file) !== null) + ($chaptersRemoteUrl = $this->request->getPost('chapters_remote_url')) && + (($chaptersFile = $this->episode->chapters) !== null) ) { - unlink((string) $chaptersFile); - $this->episode->chapters->file_path = null; + (new MediaModel())->deleteMedia($this->episode->chapters); } - $this->episode->chapters_remote_url = $chaptersFileRemoteUrl === '' ? null : $chaptersFileRemoteUrl; + $this->episode->chapters_remote_url = $chaptersRemoteUrl === '' ? null : $chaptersRemoteUrl; } $db = db_connect(); @@ -338,16 +340,12 @@ class EpisodeController extends BaseController public function transcriptDelete(): RedirectResponse { - unlink((string) $this->episode->transcript_file); - $this->episode->transcript->file_path = null; - - $episodeModel = new EpisodeModel(); - - if (! $episodeModel->update($this->episode->id, $this->episode)) { + $mediaModel = new MediaModel(); + if (! $mediaModel->deleteMedia($this->episode->transcript)) { return redirect() ->back() ->withInput() - ->with('errors', $episodeModel->errors()); + ->with('errors', $mediaModel->errors()); } return redirect()->back(); @@ -355,16 +353,12 @@ class EpisodeController extends BaseController public function chaptersDelete(): RedirectResponse { - unlink((string) $this->episode->chapters_file); - $this->episode->chapters->file_path = null; - - $episodeModel = new EpisodeModel(); - - if (! $episodeModel->update($this->episode->id, $this->episode)) { + $mediaModel = new MediaModel(); + if (! $mediaModel->deleteMedia($this->episode->chapters)) { return redirect() ->back() ->withInput() - ->with('errors', $episodeModel->errors()); + ->with('errors', $mediaModel->errors()); } return redirect()->back(); @@ -797,7 +791,7 @@ class EpisodeController extends BaseController public function soundbiteDelete(string $clipId): RedirectResponse { - (new ClipsModel())->deleteClip($this->podcast->id, $this->episode->id, (int) $clipId); + (new ClipModel())->deleteClip($this->podcast->id, $this->episode->id, (int) $clipId); return redirect()->route('clips-edit', [$this->podcast->id, $this->episode->id]); } diff --git a/modules/Admin/Controllers/PersonController.php b/modules/Admin/Controllers/PersonController.php index a2020c022857827468c35efd0b11cad45ec1c2df..da410de48d645930cbdd12920edf411fddbe1a79 100644 --- a/modules/Admin/Controllers/PersonController.php +++ b/modules/Admin/Controllers/PersonController.php @@ -76,24 +76,29 @@ class PersonController extends BaseController ->with('errors', $this->validator->getErrors()); } + $db = db_connect(); + $db->transStart(); + $person = new Person([ - 'avatar' => $this->request->getFile('avatar'), 'full_name' => $this->request->getPost('full_name'), 'unique_name' => $this->request->getPost('unique_name'), 'information_url' => $this->request->getPost('information_url'), + 'avatar' => $this->request->getFile('avatar'), 'created_by' => user_id(), 'updated_by' => user_id(), ]); $personModel = new PersonModel(); - if (! $personModel->insert($person)) { + $db->transRollback(); return redirect() ->back() ->withInput() ->with('errors', $personModel->errors()); } + $db->transComplete(); + return redirect()->route('person-list'); } @@ -128,11 +133,7 @@ class PersonController extends BaseController $this->person->full_name = $this->request->getPost('full_name'); $this->person->unique_name = $this->request->getPost('unique_name'); $this->person->information_url = $this->request->getPost('information_url'); - - $avatarFile = $this->request->getFile('avatar'); - if ($avatarFile !== null && $avatarFile->isValid()) { - $this->person->avatar = new Image($avatarFile); - } + $this->person->setAvatar($this->request->getFile('avatar')); $this->person->updated_by = user_id(); diff --git a/modules/Admin/Controllers/PodcastController.php b/modules/Admin/Controllers/PodcastController.php index 09cf6693ab41bde26225701bc43ce372626fa44f..22e9a68ea978d241f5b939aba1f7d7b2fe6463e8 100644 --- a/modules/Admin/Controllers/PodcastController.php +++ b/modules/Admin/Controllers/PodcastController.php @@ -192,6 +192,9 @@ class PodcastController extends BaseController $partnerImageUrl = null; } + $db = db_connect(); + $db->transStart(); + $newPodcast = new Podcast([ 'title' => $this->request->getPost('title'), 'handle' => $this->request->getPost('handle'), @@ -226,9 +229,6 @@ class PodcastController extends BaseController 'updated_by' => user_id(), ]); - $db = db_connect(); - $db->transStart(); - $podcastModel = new PodcastModel(); if (! ($newPodcastId = $podcastModel->insert($newPodcast, true))) { $db->transRollback(); @@ -363,10 +363,8 @@ class PodcastController extends BaseController return redirect()->back(); } - $this->podcast->banner->deleteFile(); - $mediaModel = new MediaModel(); - if (! $mediaModel->deleteMedia((int) $this->podcast->banner_id)) { + if (! $mediaModel->deleteMedia($this->podcast->banner)) { return redirect() ->back() ->withInput() diff --git a/modules/Admin/Controllers/PodcastImportController.php b/modules/Admin/Controllers/PodcastImportController.php index a990cc0a1d77c2fd8f80b1b6f7e6aeeedc2a33ba..9af473052f2b2cfa4fa0afa2362a2e368421735d 100644 --- a/modules/Admin/Controllers/PodcastImportController.php +++ b/modules/Admin/Controllers/PodcastImportController.php @@ -131,6 +131,10 @@ class PodcastImportController extends BaseController if (property_exists($nsPodcast, 'guid') && $nsPodcast->guid !== null) { $guid = (string) $nsPodcast->guid; } + + $db = db_connect(); + $db->transStart(); + $podcast = new Podcast([ 'guid' => $guid, 'handle' => $this->request->getPost('handle'), @@ -139,7 +143,7 @@ class PodcastImportController extends BaseController 'title' => (string) $feed->channel[0]->title, 'description_markdown' => $converter->convert($channelDescriptionHtml), 'description_html' => $channelDescriptionHtml, - 'cover' => new Image($coverFile), + 'cover' => $coverFile, 'banner' => null, 'language_code' => $this->request->getPost('language'), 'category_id' => $this->request->getPost('category'), @@ -185,10 +189,6 @@ class PodcastImportController extends BaseController } $podcastModel = new PodcastModel(); - $db = db_connect(); - - $db->transStart(); - if (! ($newPodcastId = $podcastModel->insert($podcast, true))) { $db->transRollback(); return redirect() @@ -249,7 +249,7 @@ class PodcastImportController extends BaseController 'full_name' => $fullName, 'unique_name' => slugify($fullName), 'information_url' => $podcastPerson->attributes()['href'], - 'avatar' => new Image(download_file((string) $podcastPerson->attributes()['img'])), + 'avatar' => download_file((string) $podcastPerson->attributes()['img']), 'created_by' => user_id(), 'updated_by' => user_id(), ]); @@ -326,7 +326,7 @@ class PodcastImportController extends BaseController property_exists($nsItunes, 'image') && $nsItunes->image !== null && $nsItunes->image->attributes()['href'] !== null ) { - $episodeCover = new Image(download_file((string) $nsItunes->image->attributes()['href'])); + $episodeCover = download_file((string) $nsItunes->image->attributes()['href']); } else { $episodeCover = null; } @@ -402,7 +402,7 @@ class PodcastImportController extends BaseController 'full_name' => $fullName, 'unique_name' => slugify($fullName), 'information_url' => $episodePerson->attributes()['href'], - 'avatar' => new Image(download_file((string) $episodePerson->attributes()['img'])), + 'avatar' => download_file((string) $episodePerson->attributes()['img']), 'created_by' => user_id(), 'updated_by' => user_id(), ]); diff --git a/modules/Fediverse/Database/Migrations/2018-01-01-100000_add_activities.php b/modules/Fediverse/Database/Migrations/2018-01-01-100000_add_activities.php index c50c46a741b3c635e034a25ad36652361dc3c3be..417e809d355b908d0a9714d7a82044f8dc395445 100644 --- a/modules/Fediverse/Database/Migrations/2018-01-01-100000_add_activities.php +++ b/modules/Fediverse/Database/Migrations/2018-01-01-100000_add_activities.php @@ -48,12 +48,10 @@ class AddActivities extends Migration 'type' => 'ENUM', 'constraint' => ['queued', 'delivered'], 'null' => true, - 'default' => null, ], 'scheduled_at' => [ 'type' => 'DATETIME', 'null' => true, - 'default' => null, ], 'created_at' => [ 'type' => 'DATETIME', diff --git a/themes/cp_admin/episode/edit.php b/themes/cp_admin/episode/edit.php index 035b8d6352b539916ad3fb80be063ad112a8f5c5..6e62156348ad678834e3778028393679577a4bb0 100644 --- a/themes/cp_admin/episode/edit.php +++ b/themes/cp_admin/episode/edit.php @@ -161,12 +161,12 @@ <div class="py-2 tab-panels"> <section id="transcript-file-upload" class="flex items-center tab-panel"> - <?php if ($episode->transcript_file) : ?> + <?php if ($episode->transcript) : ?> <div class="flex mb-1 gap-x-2"> <?= anchor( $episode->transcript->file_url, icon('file', 'mr-2 text-skin-muted') . - $episode->transcript_file, + $episode->transcript->file_name_with_extension, [ 'class' => 'inline-flex items-center text-xs', 'target' => '_blank', @@ -218,33 +218,33 @@ <div class="py-2 tab-panels"> <section id="chapters-file-upload" class="flex items-center tab-panel"> - <?php if ($episode->chapters_file) : ?> + <?php if ($episode->chapters) : ?> <div class="flex mb-1 gap-x-2"> <?= anchor( $episode->chapters->file_url, - icon('file', 'mr-2') . $episode->chapters_file, + icon('file', 'mr-2') . $episode->chapters->file_name_with_extension, [ 'class' => 'inline-flex items-center text-xs', 'target' => '_blank', 'rel' => 'noreferrer noopener', ], ) . - anchor( - route_to( - 'chapters-delete', - $podcast->id, - $episode->id, + anchor( + route_to( + 'chapters-delete', + $podcast->id, + $episode->id, + ), + icon('delete-bin', 'mx-auto'), + [ + 'class' => + 'text-sm p-1 bg-red-100 rounded-full text-red-700 hover:text-red-900 focus:ring-accent', + 'data-tooltip' => 'bottom', + 'title' => lang( + 'Episode.form.chapters_file_delete', ), - icon('delete-bin', 'mx-auto'), - [ - 'class' => - 'text-sm p-1 bg-red-100 rounded-full text-red-700 hover:text-red-900 focus:ring-accent', - 'data-tooltip' => 'bottom', - 'title' => lang( - 'Episode.form.chapters_file_delete', - ), - ], - ) ?> + ], + ) ?> </div> <?php endif; ?> <Forms.Label class="sr-only" for="chapters_file" isOptional="true"><?= lang('Episode.form.chapters_file') ?></Forms.Label> diff --git a/themes/cp_admin/person/create.php b/themes/cp_admin/person/create.php index a7e2ec01931f56a793a46446623a40dfc1feeed0..09f15dc6f6956905c366ef2cd45691cdc64ef460 100644 --- a/themes/cp_admin/person/create.php +++ b/themes/cp_admin/person/create.php @@ -32,7 +32,8 @@ name="unique_name" label="<?= lang('Person.form.unique_name') ?>" hint="<?= lang('Person.form.unique_name_hint') ?>" - required="true" /> + required="true" + data-slugify="slug" /> <Forms.Field name="information_url" label="<?= lang('Person.form.information_url') ?>"