diff --git a/src/Assets/Asset.php b/src/Assets/Asset.php index c11106cc4f3..c8d9cf5abb7 100644 --- a/src/Assets/Asset.php +++ b/src/Assets/Asset.php @@ -113,8 +113,12 @@ public function exists() return $this->disk()->exists($path); } - public function meta() + public function meta($key = null) { + if (func_num_args() === 1) { + return $this->metaValue($key); + } + if (! config('statamic.assets.cache_meta')) { return $this->generateMeta(); } @@ -134,6 +138,21 @@ public function meta() }); } + private function metaValue($key) + { + $value = Arr::get($this->meta(), $key); + + if (! is_null($value)) { + return $value; + } + + Cache::forget($this->metaCacheKey()); + + $this->writeMeta($meta = $this->generateMeta()); + + return Arr::get($meta, $key); + } + public function generateMeta() { $meta = ['data' => $this->data->all()]; @@ -360,7 +379,7 @@ public function extension() */ public function lastModified() { - return Carbon::createFromTimestamp($this->meta()['last_modified']); + return Carbon::createFromTimestamp($this->meta('last_modified')); } /** @@ -492,7 +511,7 @@ public function move($folder, $filename = null) */ public function dimensions() { - return [$this->meta()['width'], $this->meta()['height']]; + return [$this->meta('width'), $this->meta('height')]; } /** @@ -554,7 +573,7 @@ public function ratio() */ public function size() { - return $this->meta()['size']; + return $this->meta('size'); } /** diff --git a/tests/Assets/AssetTest.php b/tests/Assets/AssetTest.php index b31f260d787..c2d247ce9e0 100644 --- a/tests/Assets/AssetTest.php +++ b/tests/Assets/AssetTest.php @@ -376,6 +376,38 @@ public function it_generates_meta_on_demand_if_it_doesnt_exist() $this->assertEquals($metaWithData, Cache::get($asset->metaCacheKey())); } + /** @test */ + public function it_generates_meta_on_demand_if_a_required_value_is_missing() + { + Storage::fake('test'); + + $file = UploadedFile::fake()->image('image.jpg', 30, 60); // creates a 723 byte image + Storage::disk('test')->putFileAs('foo', $file, 'image.jpg'); + $realFilePath = Storage::disk('test')->getAdapter()->getPathPrefix().'foo/image.jpg'; + touch($realFilePath, $timestamp = Carbon::parse('2021-02-22 09:41:42')->timestamp); + + $container = Facades\AssetContainer::make('test')->disk('test'); + $asset = (new Asset)->container($container)->path('foo/image.jpg'); + + $incompleteMeta = [ + 'data' => [], + ]; + + $completeMeta = [ + 'data' => [], + 'size' => 723, + 'last_modified' => $timestamp, + 'width' => 30, + 'height' => 60, + ]; + + Storage::disk('test')->put('foo/.meta/image.jpg.yaml', YAML::dump($incompleteMeta)); + + $asset->size(); + + $this->assertEquals($completeMeta, YAML::parse(Storage::disk('test')->get('foo/.meta/image.jpg.yaml'))); + } + /** @test */ public function it_hydrates_data_from_meta_file() {