Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions config/assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@

'cache_meta' => true,

/*
|--------------------------------------------------------------------------
| Metadata as Content
|--------------------------------------------------------------------------
|
| Asset metadata will be saved as content alongside the rest of the content.
| This is useful when wanting to track metadata changes in git while using
| another storage location for assets (ie. S3).
|
*/
'meta_as_content' => false,

/*
|--------------------------------------------------------------------------
| Focal Point Editor
Expand Down
1 change: 1 addition & 0 deletions config/stache.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@

'assets' => [
'class' => Stores\AssetsStore::class,
'directory' => base_path('content/assets'),
],

'users' => [
Expand Down
54 changes: 46 additions & 8 deletions src/Assets/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
use Statamic\Facades;
use Statamic\Facades\AssetContainer as AssetContainerAPI;
use Statamic\Facades\Blink;
use Statamic\Facades\File;
use Statamic\Facades\Image;
use Statamic\Facades\Path;
use Statamic\Facades\Stache;
use Statamic\Facades\URL;
use Statamic\Facades\YAML;
use Statamic\GraphQL\ResolvesValues;
Expand Down Expand Up @@ -255,8 +257,13 @@ public function meta($key = null)
}

return $this->meta = $this->cacheStore()->rememberForever($this->metaCacheKey(), function () {
if ($contents = $this->disk()->get($path = $this->metaPath())) {
return YAML::file($path)->parse($contents);
$contents = match (config('statamic.assets.meta_as_content')) {
true => File::get($this->metaPath()),
false => $this->disk()->get($this->metaPath()),
};

if ($contents) {
return YAML::parse($contents);
}

$this->writeMeta($meta = $this->generateMeta());
Expand Down Expand Up @@ -302,13 +309,30 @@ public function generateMeta()

public function metaPath()
{
$path = dirname($this->path()).'/.meta/'.$this->basename().'.yaml';

return (string) Str::of($path)->replaceFirst('./', '')->ltrim('/');
return Str::of($this->path())
->dirname()
->finish('/') // Sometimes the dirname is just '.', so we ensure it ends with a slash
->replaceFirst('./', '')
->explode('/')
->when(
config('statamic.assets.meta_as_content'),
fn ($path) => collect([
Stache::store('assets')->directory(),
$this->container()->handle(),
])->concat($path),
fn ($path) => $path->push('.meta'),
)
->push($this->basename().'.yaml')
->filter() // Remove any empty segments
->implode('/');
}

protected function metaExists()
{
if (config('statamic.assets.meta_as_content')) {
return File::exists($this->metaPath());
}

return $this->container()->metaFiles()->contains($this->metaPath());
}

Expand All @@ -318,7 +342,12 @@ public function writeMeta($meta)

$contents = YAML::dump($meta);

$this->disk()->put($this->metaPath(), $contents);
if (config('statamic.assets.meta_as_content')) {
File::makeDirectory(dirname($this->metaPath()), 0755, true);
File::put($this->metaPath(), $contents);
} else {
$this->disk()->put($this->metaPath(), $contents);
}
}

public function metaCacheKey()
Expand Down Expand Up @@ -676,7 +705,12 @@ public function delete()
}

$this->disk()->delete($this->path());
$this->disk()->delete($this->metaPath());

if (config('statamic.assets.meta_as_content')) {
File::delete($this->metaPath());
} else {
$this->disk()->delete($this->metaPath());
}

Facades\Asset::delete($this);

Expand Down Expand Up @@ -770,7 +804,11 @@ public function move($folder, $filename = null)
$this->path($newPath);
$this->save();

$this->disk()->rename($oldMetaPath, $this->metaPath());
if (config('statamic.assets.meta_as_content')) {
File::move($oldMetaPath, $this->metaPath());
} else {
$this->disk()->rename($oldMetaPath, $this->metaPath());
}

return $this;
}
Expand Down
54 changes: 54 additions & 0 deletions tests/Assets/AssetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use Statamic\Facades;
use Statamic\Facades\Antlers;
use Statamic\Facades\File;
use Statamic\Facades\Stache;
use Statamic\Facades\YAML;
use Statamic\Fields\Blueprint;
use Statamic\Fields\Fieldtype;
Expand Down Expand Up @@ -708,6 +709,29 @@ public function it_gets_existing_meta_data()
$this->assertEquals($expected, Cache::get($asset->metaCacheKey()));
}

#[Test]
public function it_gets_existing_meta_data_as_content()
{
config()->set('statamic.assets.meta_as_content', true);
$relativePath = 'foo/test.txt';
$metaFilePath = Stache::store('assets')->directory()."/test/{$relativePath}.yaml";

Storage::fake('test');
Storage::disk('test')->put($relativePath, '');

File::makeDirectory(dirname($metaFilePath), 0755, true);
File::put($metaFilePath, YAML::dump($data = [
'data' => ['foo' => 'bar'],
'size' => 123,
]));

$container = tap(Facades\AssetContainer::make('test')->disk('test'))->save();
$asset = (new Asset)->container($container)->path($relativePath);

$this->assertEquals($metaFilePath, $asset->metaPath());
$this->assertEquals($data, $asset->meta());
}

#[Test]
public function it_properly_merges_new_unsaved_data_to_meta()
{
Expand Down Expand Up @@ -1237,6 +1261,36 @@ public function it_doesnt_lowercase_moved_files_when_configured()
], $container->assets('/', true)->map->path()->all());
}

#[Test]
public function it_can_be_moved_to_another_folder_and_renamed_when_meta_as_content()
{
config()->set('statamic.assets.meta_as_content', true);

Storage::fake('test');
$disk = Storage::disk('test');
$disk->put('old/asset.txt', 'The asset contents');

$container = tap(Facades\AssetContainer::make('test')->disk('test'))->save();
$asset = tap($container->makeAsset('old/asset.txt')->data(['foo' => 'bar']))->save();
$meta = $asset->meta();

$metaPath = Stache::store('assets')->directory().'/'.$container->handle();

$this->assertFileExists("{$metaPath}/old/asset.txt.yaml");
$this->assertEquals(YAML::dump($asset->meta()), File::get("{$metaPath}/old/asset.txt.yaml"));
$this->assertEquals(['old/asset.txt'], $container->files()->all());

$return = $asset->move('new', 'asset2');

$this->assertEquals($return, $asset);
$disk->assertMissing('old/asset.txt');
$this->assertFileDoesNotExist("{$metaPath}/old/asset.txt.yaml");
$disk->assertExists('new/asset2.txt');
$this->assertFileExists($newMetaPath = "{$metaPath}/new/asset2.txt.yaml");
$this->assertEquals(YAML::dump($meta), File::get($newMetaPath));
$this->assertEquals(['new/asset2.txt'], $container->files()->all());
}

#[Test]
public function it_renames()
{
Expand Down
1 change: 1 addition & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ protected function getEnvironmentSetUp($app)
$app['config']->set('statamic.stache.stores.globals.directory', __DIR__.'/__fixtures__/content/globals');
$app['config']->set('statamic.stache.stores.global-variables.directory', __DIR__.'/__fixtures__/content/globals');
$app['config']->set('statamic.stache.stores.asset-containers.directory', __DIR__.'/__fixtures__/content/assets');
$app['config']->set('statamic.stache.stores.assets.directory', __DIR__.'/__fixtures__/content/assets');
$app['config']->set('statamic.stache.stores.nav-trees.directory', __DIR__.'/__fixtures__/content/structures/navigation');
$app['config']->set('statamic.stache.stores.collection-trees.directory', __DIR__.'/__fixtures__/content/structures/collections');
$app['config']->set('statamic.stache.stores.form-submissions.directory', __DIR__.'/__fixtures__/content/submissions');
Expand Down
Loading