From 06a0e949c9d9c64be208993be0f79a54cd8680cb Mon Sep 17 00:00:00 2001 From: Freek Van der Herten Date: Thu, 17 Mar 2022 16:42:26 +0100 Subject: [PATCH] Allow path generators to be customised per model (#2845) * wip * wip * Fix styling * wip * Fix styling * wip * Fix styling Co-authored-by: freekmurze --- src/MediaCollections/Filesystem.php | 4 ++-- src/MediaCollections/Models/Media.php | 11 +++++++++-- src/ResponsiveImages/ResponsiveImage.php | 2 +- .../PathGenerator/PathGeneratorFactory.php | 18 ++++++++++++++++-- .../UrlGenerator/UrlGeneratorFactory.php | 2 +- .../PathGenerator/BasePathGeneratorTest.php | 13 +++++++++++++ 6 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/MediaCollections/Filesystem.php b/src/MediaCollections/Filesystem.php index dde4fc46e..ecf0a8270 100644 --- a/src/MediaCollections/Filesystem.php +++ b/src/MediaCollections/Filesystem.php @@ -237,7 +237,7 @@ public function syncFileNames(Media $media): void public function syncMediaPath(Media $media): void { - $factory = PathGeneratorFactory::create(); + $factory = PathGeneratorFactory::create($media); $oldMedia = (clone $media)->fill($media->getOriginal()); @@ -291,7 +291,7 @@ protected function renameConversionFiles(Media $media): void public function getMediaDirectory(Media $media, ?string $type = null): string { $directory = null; - $pathGenerator = PathGeneratorFactory::create(); + $pathGenerator = PathGeneratorFactory::create($media); if (! $type) { $directory = $pathGenerator->getPath($media); diff --git a/src/MediaCollections/Models/Media.php b/src/MediaCollections/Models/Media.php index e17d1bdad..2bde7e1c2 100644 --- a/src/MediaCollections/Models/Media.php +++ b/src/MediaCollections/Models/Media.php @@ -26,6 +26,7 @@ use Spatie\MediaLibrary\Support\File; use Spatie\MediaLibrary\Support\MediaLibraryPro; use Spatie\MediaLibrary\Support\TemporaryDirectory; +use Spatie\MediaLibrary\Support\UrlGenerator\UrlGenerator; use Spatie\MediaLibrary\Support\UrlGenerator\UrlGeneratorFactory; use Spatie\MediaLibraryPro\Models\TemporaryUpload; @@ -81,18 +82,24 @@ public function getUrl(string $conversionName = ''): string public function getTemporaryUrl(DateTimeInterface $expiration, string $conversionName = '', array $options = []): string { - $urlGenerator = UrlGeneratorFactory::createForMedia($this, $conversionName); + $urlGenerator = $this->getUrlGenerator($conversionName); return $urlGenerator->getTemporaryUrl($expiration, $options); } public function getPath(string $conversionName = ''): string { - $urlGenerator = UrlGeneratorFactory::createForMedia($this, $conversionName); + $urlGenerator = $this->getUrlGenerator($conversionName); return $urlGenerator->getPath(); } + + public function getUrlGenerator(string $conversionName): UrlGenerator + { + return UrlGeneratorFactory::createForMedia($this, $conversionName); + } + public function getAvailableUrl(array $conversionNames): string { foreach ($conversionNames as $conversionName) { diff --git a/src/ResponsiveImages/ResponsiveImage.php b/src/ResponsiveImages/ResponsiveImage.php index dbaa011bb..bbbbb0ec5 100644 --- a/src/ResponsiveImages/ResponsiveImage.php +++ b/src/ResponsiveImages/ResponsiveImage.php @@ -97,7 +97,7 @@ protected function stringBetween(string $subject, string $startCharacter, string public function delete(): self { - $pathGenerator = PathGeneratorFactory::create(); + $pathGenerator = PathGeneratorFactory::create($this->media); $path = $pathGenerator->getPathForResponsiveImages($this->media); diff --git a/src/Support/PathGenerator/PathGeneratorFactory.php b/src/Support/PathGenerator/PathGeneratorFactory.php index ebde62cb7..4b57351e3 100644 --- a/src/Support/PathGenerator/PathGeneratorFactory.php +++ b/src/Support/PathGenerator/PathGeneratorFactory.php @@ -3,18 +3,32 @@ namespace Spatie\MediaLibrary\Support\PathGenerator; use Spatie\MediaLibrary\MediaCollections\Exceptions\InvalidPathGenerator; +use Spatie\MediaLibrary\MediaCollections\Models\Media; class PathGeneratorFactory { - public static function create(): PathGenerator + public static function create(Media $media): PathGenerator { - $pathGeneratorClass = config('media-library.path_generator'); + $pathGeneratorClass = self::getPathGeneratorClass($media); static::guardAgainstInvalidPathGenerator($pathGeneratorClass); return app($pathGeneratorClass); } + protected static function getPathGeneratorClass(Media $media) + { + $defaultPathGeneratorClass = config('media-library.path_generator'); + + foreach (config('media-library.custom_path_generators', []) as $modelClass => $customPathGeneratorClass) { + if (is_a($media->model_type, $modelClass, true)) { + return $customPathGeneratorClass; + } + } + + return $defaultPathGeneratorClass; + } + protected static function guardAgainstInvalidPathGenerator(string $pathGeneratorClass): void { if (! class_exists($pathGeneratorClass)) { diff --git a/src/Support/UrlGenerator/UrlGeneratorFactory.php b/src/Support/UrlGenerator/UrlGeneratorFactory.php index 03693d583..5d001e2a0 100644 --- a/src/Support/UrlGenerator/UrlGeneratorFactory.php +++ b/src/Support/UrlGenerator/UrlGeneratorFactory.php @@ -18,7 +18,7 @@ public static function createForMedia(Media $media, string $conversionName = '') /** @var \Spatie\MediaLibrary\Support\UrlGenerator\UrlGenerator $urlGenerator */ $urlGenerator = app($urlGeneratorClass); - $pathGenerator = PathGeneratorFactory::create(); + $pathGenerator = PathGeneratorFactory::create($media); $urlGenerator ->setMedia($media) diff --git a/tests/Support/PathGenerator/BasePathGeneratorTest.php b/tests/Support/PathGenerator/BasePathGeneratorTest.php index 363db00be..a8db00df1 100644 --- a/tests/Support/PathGenerator/BasePathGeneratorTest.php +++ b/tests/Support/PathGenerator/BasePathGeneratorTest.php @@ -3,6 +3,7 @@ use Spatie\MediaLibrary\Conversions\ConversionCollection; use Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator; use Spatie\MediaLibrary\Tests\Support\PathGenerator\CustomPathGenerator; +use Spatie\MediaLibrary\Tests\TestSupport\TestModels\TestModelWithConversion; beforeEach(function () { $this->config = app('config'); @@ -36,3 +37,15 @@ expect($this->urlGenerator->getPathRelativeToRoot())->toEqual($pathRelativeToRoot); }); + +it('can use a custom path generator on the model', function () { + config()->set('media-library.custom_path_generators', [ + TestModelWithConversion::class => CustomPathGenerator::class, + ]); + + $media = $this->testModelWithConversion + ->addMedia($this->getTestFilesDirectory('test.jpg')) + ->toMediaCollection(); + + expect($media->getUrl())->toEqual('/media/c4ca4238a0b923820dcc509a6f75849b/test.jpg'); +});