Skip to content

Commit 72a5ed8

Browse files
authored
Store model reference on assets (#452)
* We don't need this blink as its handled in Asset::fromModel now * Store model reference on asset * Remove unnecessary test
1 parent 61fd51b commit 72a5ed8

File tree

4 files changed

+213
-101
lines changed

4 files changed

+213
-101
lines changed

src/Assets/Asset.php

Lines changed: 44 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,15 @@
55
use Illuminate\Database\Eloquent\Model;
66
use Illuminate\Support\Facades\Cache;
77
use Statamic\Assets\Asset as FileAsset;
8-
use Statamic\Assets\AssetUploader as Uploader;
98
use Statamic\Contracts\Assets\Asset as AssetContract;
109
use Statamic\Data\HasDirtyState;
11-
use Statamic\Facades\Blink;
12-
use Statamic\Facades\Path;
1310
use Statamic\Support\Arr;
1411
use Statamic\Support\Str;
1512

1613
class Asset extends FileAsset
1714
{
15+
protected $model;
16+
1817
use HasDirtyState {
1918
syncOriginal as traitSyncOriginal;
2019
}
@@ -36,10 +35,8 @@ public static function fromModel(Model $model)
3635
->container($model->container)
3736
->path(Str::replace('//', '/', $model->folder.'/'.$model->basename))
3837
->hydrateMeta($model->meta)
39-
->syncOriginal();
40-
41-
Blink::put('eloquent-asset-'.$asset->id(), $asset);
42-
Blink::put($asset->metaCacheKey(), $model->meta);
38+
->syncOriginal()
39+
->model($model);
4340

4441
return $asset;
4542
}
@@ -65,29 +62,17 @@ public function meta($key = null)
6562
return $meta;
6663
}
6764

68-
// this handles asset::make() without save()
69-
// e.g. when checking a file exists already when uploading
70-
if (! $this->disk()->exists($this->path())) {
71-
return ['data' => []];
65+
if ($meta = $this->model()?->meta) {
66+
return $meta;
7267
}
7368

74-
return Blink::once($this->metaCacheKey(), function () {
75-
if ($model = app('statamic.eloquent.assets.model')::where([
76-
'container' => $this->containerHandle(),
77-
'folder' => $this->folder(),
78-
'basename' => $this->basename(),
79-
])->first()) {
80-
return $model->meta;
81-
}
69+
$meta = $this->generateMeta();
8270

83-
$meta = $this->generateMeta();
84-
85-
if (! $meta['data']) {
86-
$meta['data'] = [];
87-
}
71+
if (! $meta['data']) {
72+
$meta['data'] = [];
73+
}
8874

89-
return $meta;
90-
});
75+
return $meta;
9176
}
9277

9378
public function exists()
@@ -97,18 +82,7 @@ public function exists()
9782

9883
public function metaExists()
9984
{
100-
if (Blink::has($this->metaCacheKey())) {
101-
return true;
102-
}
103-
104-
return Blink::once('eloquent-asset-meta-exists-'.$this->id(), function () {
105-
return app('statamic.eloquent.assets.model')::query()
106-
->where([
107-
'container' => $this->containerHandle(),
108-
'folder' => $this->folder(),
109-
'basename' => $this->basename(),
110-
])->exists();
111-
});
85+
return $this->model() ? true : false;
11286
}
11387

11488
private function metaValue($key)
@@ -142,12 +116,15 @@ public function hydrateMeta($meta)
142116

143117
public function writeMeta($meta)
144118
{
145-
$meta['data'] = Arr::removeNullValues($meta['data']);
119+
$meta['data'] = Arr::removeNullValues($meta['data'] ?? []);
120+
121+
if (! $model = self::makeModelFromContract($this, $meta)) {
122+
return;
123+
}
146124

147-
self::makeModelFromContract($this, $meta)?->save();
125+
$model->save();
148126

149-
Blink::put($this->metaCacheKey(), $meta);
150-
Blink::put('eloquent-asset-meta-exists-'.$this->id(), true);
127+
$this->model($model);
151128
}
152129

153130
public static function makeModelFromContract(AssetContract $source, $meta = [])
@@ -156,18 +133,26 @@ public static function makeModelFromContract(AssetContract $source, $meta = [])
156133
$meta = $source->meta();
157134
}
158135

159-
// Make shure that a extension could be found, as the extension field is required.
136+
// Make sure that a extension could be found, as the extension field is required.
160137
if (! $extension = $source->extension()) {
161138
return null;
162139
}
163140

164-
$original = $source->getOriginal();
141+
$model = false;
142+
143+
if (method_exists($source, 'model')) {
144+
$model = $source->model();
145+
}
146+
147+
if (! $model) {
148+
$model = app('statamic.eloquent.assets.model')::make([
149+
'container' => $source->containerHandle(),
150+
'folder' => $source->folder(),
151+
'basename' => $source->basename(),
152+
]);
153+
}
165154

166-
$model = app('statamic.eloquent.assets.model')::firstOrNew([
167-
'container' => $source->containerHandle(),
168-
'folder' => Arr::get($original, 'folder', $source->folder()),
169-
'basename' => Arr::get($original, 'basename', $source->basename()),
170-
])->fill([
155+
$model->fill([
171156
'meta' => $meta,
172157
'filename' => $source->filename(),
173158
'extension' => $extension,
@@ -185,50 +170,22 @@ public static function makeModelFromContract(AssetContract $source, $meta = [])
185170
return $model;
186171
}
187172

188-
public function metaPath()
189-
{
190-
return $this->path();
191-
}
192-
193-
/**
194-
* Move the asset to a different location.
195-
*
196-
* @param string $folder The folder relative to the container.
197-
* @param string|null $filename The new filename, if renaming.
198-
* @return $this
199-
*/
200-
public function move($folder, $filename = null)
173+
public function model($model = null)
201174
{
202-
$filename = Uploader::getSafeFilename($filename ?: $this->filename());
203-
$oldPath = $this->path();
204-
$oldMetaPath = $this->metaPath();
205-
$oldFolder = $this->folder();
206-
$oldBasename = $this->basename();
207-
$newPath = Str::removeLeft(Path::tidy($folder.'/'.$filename.'.'.pathinfo($oldPath, PATHINFO_EXTENSION)), '/');
208-
209-
$this->hydrate();
210-
$this->disk()->rename($oldPath, $newPath);
211-
$this->path($newPath);
212-
$this->save();
213-
214-
if ($oldMetaPath != $this->metaPath()) {
215-
$oldMetaModel = app('statamic.eloquent.assets.model')::where([
216-
'container' => $this->containerHandle(),
217-
'folder' => $oldFolder,
218-
'basename' => $oldBasename,
219-
])->first();
220-
221-
if ($oldMetaModel) {
222-
$meta = $oldMetaModel->meta;
223-
$oldMetaModel->delete();
224-
225-
$this->writeMeta($meta);
226-
}
175+
if (func_num_args() === 0) {
176+
return $this->model;
227177
}
228178

179+
$this->model = $model;
180+
229181
return $this;
230182
}
231183

184+
public function metaPath()
185+
{
186+
return $this->path();
187+
}
188+
232189
public function getCurrentDirtyStateAttributes(): array
233190
{
234191
return array_merge([
@@ -243,8 +200,6 @@ protected function clearCaches()
243200
{
244201
$this->meta = null;
245202

246-
Blink::forget("eloquent-asset-{$this->id()}");
247-
Blink::forget($this->metaCacheKey());
248203
Cache::forget($this->metaCacheKey());
249204
}
250205
}

src/Assets/AssetRepository.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ public function findByUrl(string $url)
6464

6565
public function delete($asset)
6666
{
67+
if ($id = $asset->id()) {
68+
Blink::forget("eloquent-asset-{$id}");
69+
}
70+
6771
$this->query()
6872
->where([
6973
'container' => $asset->container(),
@@ -76,6 +80,9 @@ public function delete($asset)
7680
public function save($asset)
7781
{
7882
$asset->writeMeta($asset->generateMeta());
83+
84+
$id = $asset->id();
85+
Blink::put("eloquent-asset-{$id}", $asset);
7986
}
8087

8188
public static function bindings(): array

tests/Assets/AssetContainerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Database\Events\QueryExecuted;
66
use Illuminate\Foundation\Testing\RefreshDatabase;
7+
use Illuminate\Support\Facades\Cache;
78
use Illuminate\Support\Facades\Storage;
89
use PHPUnit\Framework\Attributes\Test;
910
use Statamic\Facades;
@@ -56,4 +57,18 @@ public function calling_folders_uses_eloquent_asset_container_contents()
5657

5758
$this->assertTrue($queryExecuted);
5859
}
60+
61+
#[Test]
62+
public function creating_a_folder_adds_it_to_the_folder_cache()
63+
{
64+
$this->assertCount(1, $this->container->folders());
65+
$this->assertCount(1, Cache::get('asset-folder-contents-'.$this->container->handle()));
66+
67+
$this->container->assetFolder('foo')->save();
68+
69+
$this->assertCount(2, $this->container->folders());
70+
$this->assertCount(2, Cache::get('asset-folder-contents-'.$this->container->handle()));
71+
$this->assertSame(['/', 'foo'], $this->container->folders()->all());
72+
73+
}
5974
}

0 commit comments

Comments
 (0)