From 8c0d2ea8385af14e21b96d0cb10b94b942a84913 Mon Sep 17 00:00:00 2001 From: Ali ABOUSSEBABA Date: Mon, 17 Jun 2024 12:59:56 +0100 Subject: [PATCH] Make media lazy loading configurable (#3627) * Make media lazy loading configurable * Fix config variable name --- .gitignore | 1 + config/media-library.php | 6 +++ docs/installation-setup.md | 8 +++- src/InteractsWithMedia.php | 6 ++- tests/Feature/Performance/PerformanceTest.php | 38 +++++++++++++++++++ 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 936b88e15..c5a6b38aa 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ phpunit.xml .php-cs-fixer.cache phpstan.neon tests/Support/temp/ +.idea/ diff --git a/config/media-library.php b/config/media-library.php index b6c913200..7f6abbdb7 100644 --- a/config/media-library.php +++ b/config/media-library.php @@ -266,4 +266,10 @@ * If you set this to `/my-subdir`, all your media will be stored in a `/my-subdir` directory. */ 'prefix' => env('MEDIA_PREFIX', ''), + + /* + * When forcing lazy loading, media will be loaded even if you don't eager load media and you have + * disabled lazy loading globally in the service provider. + */ + 'force_lazy_loading' => env('FORCE_MEDIA_LIBRARY_LAZY_LOADING', true), ]; diff --git a/docs/installation-setup.md b/docs/installation-setup.md index 05217ba91..8b151aba3 100644 --- a/docs/installation-setup.md +++ b/docs/installation-setup.md @@ -266,7 +266,13 @@ return [ * You can specify a prefix for that is used for storing all media. * If you set this to `/my-subdir`, all your media will be stored in a `/my-subdir` directory. */ - 'prefix' => env('MEDIA_PREFIX', ''), + 'prefix' => env('MEDIA_PREFIX', ''), + + /* + * When forcing lazy loading, media will be loaded even if you don't eager load media and you have + * disabled lazy loading globally in the service provider. + */ + 'force_lazy_loading' => env('FORCE_MEDIA_LIBRARY_LAZY_LOADING', true), ]; ``` diff --git a/src/InteractsWithMedia.php b/src/InteractsWithMedia.php index de9307d01..d77f88a2b 100644 --- a/src/InteractsWithMedia.php +++ b/src/InteractsWithMedia.php @@ -530,8 +530,12 @@ protected function mediaIsPreloaded(): bool public function loadMedia(string $collectionName): Collection { + if (config('media-library.force_lazy_loading') && $this->exists) { + $this->loadMissing('media'); + } + $collection = $this->exists - ? $this->loadMissing('media')->media + ? $this->media : collect($this->unAttachedMediaLibraryItems)->pluck('media'); $collection = new MediaCollections\Models\Collections\MediaCollection($collection); diff --git a/tests/Feature/Performance/PerformanceTest.php b/tests/Feature/Performance/PerformanceTest.php index 13df0cade..b6ea49de5 100644 --- a/tests/Feature/Performance/PerformanceTest.php +++ b/tests/Feature/Performance/PerformanceTest.php @@ -1,5 +1,9 @@ testModelWithConversion->create(['name' => "test{$index}"]); @@ -17,3 +21,37 @@ expect(DB::getQueryLog())->toHaveCount(2); }); + +it('can lazy load media by default even prevent lazy loading globally enabled', function () { + foreach (range(1, 10) as $index) { + $testModel = $this->testModelWithConversion->create(['name' => "test{$index}"]); + $testModel->addMedia($this->getTestJpg())->preservingOriginal()->toMediaCollection('images'); + } + + Model::preventLazyLoading(); + + DB::connection()->enableQueryLog(); + + $testModels = $this->testModelWithConversion->get(); + + foreach ($testModels as $testModel) { + $testModel->getFirstMediaUrl('images', 'thumb'); + } + + expect(DB::getQueryLog())->toHaveCount(12); +}); + +it('throws an exception when lazy loading is disabled on both the config and globally', function () { + foreach (range(1, 10) as $index) { + $testModel = $this->testModelWithConversion->create(['name' => "test{$index}"]); + $testModel->addMedia($this->getTestJpg())->preservingOriginal()->toMediaCollection('images'); + } + + Model::preventLazyLoading(); + + Config::set('media-library.force_lazy_loading', false); + + $testModels = $this->testModelWithConversion->get(); + + expect(fn() => $testModels->first()->getFirstMediaUrl('images', 'thumb'))->toThrow(LazyLoadingViolationException::class); +});