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
68 changes: 68 additions & 0 deletions src/Assets/AssetReferenceUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@

use Statamic\Data\DataReferenceUpdater;
use Statamic\Facades\AssetContainer;
use Statamic\Fieldtypes\Sets;
use Statamic\Support\Arr;
use Statamic\Support\Str;
use Statamic\Tags\Set;

class AssetReferenceUpdater extends DataReferenceUpdater
{
Expand Down Expand Up @@ -333,4 +336,69 @@ private function updateStatamicUrlsInLinkNodes($field, $dottedPrefix)

$this->updated = true;
}

/**
* Update fields in blueprints and fieldsets.
*
* @return void
*/
protected function updateBlueprintFields()
{
if (
! Sets::previewImageConfig()
|| ! Str::startsWith($this->originalValue, Sets::previewImageConfig()['folder'].'/')
) {
return;
}

$contents = $this->item->contents();

$fieldPaths = $this->findFieldsInBlueprintContents($contents, fieldtypes: ['bard', 'replicator']);

foreach ($fieldPaths as $fieldPath) {
$fieldContents = Arr::get($contents, $fieldPath);

if (! isset($fieldContents['sets'])) {
continue;
}

$fieldContents['sets'] = collect($fieldContents['sets'])
->map(function ($setGroup) {
if (! isset($setGroup['sets'])) {
return $setGroup;
}

$setGroup['sets'] = collect($setGroup['sets'])
->map(function ($set) {
if (isset($set['image'])) {
$fullPath = Sets::previewImageConfig()['folder'].'/'.$set['image'];

if ($fullPath !== $this->originalValue) {
return $set;
}

if (Str::startsWith($this->newValue, Sets::previewImageConfig()['folder'].'/')) {
$set['image'] = Str::after($this->newValue, Sets::previewImageConfig()['folder'].'/');
} else {
unset($set['image']);
}

$this->updated = true;
}

return $set;
})
->all();

return $setGroup;
})
->all();

Arr::set($contents, $fieldPath, $fieldContents);
}

if ($this->updated) {
$this->item->setContents($contents);
}
}
}
41 changes: 40 additions & 1 deletion src/Data/DataReferenceUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Statamic\Data;

use Statamic\Fields\Blueprint;
use Statamic\Fields\Fields;
use Statamic\Fields\Fieldset;
use Statamic\Git\Subscriber as GitSubscriber;
use Statamic\Support\Arr;

Expand Down Expand Up @@ -60,7 +62,11 @@ public function updateReferences($originalValue, $newValue)
$this->originalValue = $originalValue;
$this->newValue = $newValue;

$this->recursivelyUpdateFields($this->getTopLevelFields());
if ($this->item instanceof Blueprint || $this->item instanceof Fieldset) {
$this->updateBlueprintFields();
} else {
$this->recursivelyUpdateFields($this->getTopLevelFields());
}

if ($this->updated) {
$this->saveItem();
Expand Down Expand Up @@ -317,6 +323,39 @@ protected function updateArrayValue($field, $dottedPrefix)
$this->updated = true;
}

/**
* Update fields in blueprints and fieldsets.
*
* @return void
*/
abstract protected function updateBlueprintFields();

/**
* Finds fields of a given type in the contents of a blueprint.
* Returns dot-notation paths to the fields.
*
* @param array $array
* @param array $fieldtypes
* @param string|null $dottedPrefix
* @param array $fieldPaths
* @return array
*/
protected function findFieldsInBlueprintContents($array, $fieldtypes, $dottedPrefix = '', &$fieldPaths = [])
{
foreach ($array as $key => $value) {
if (is_array($value)) {
$fieldPath = $dottedPrefix ? "$dottedPrefix.$key" : $key;
$this->findFieldsInBlueprintContents($value, $fieldtypes, $fieldPath, $fieldPaths);
}

if (is_string($value) && $key === 'type' && in_array($value, $fieldtypes)) {
$fieldPaths[] = $dottedPrefix;
}
}

return $fieldPaths;
}

/**
* Save item without triggering individual git commits, as these should be batched into one larger commit.
*/
Expand Down
15 changes: 14 additions & 1 deletion src/Fields/BlueprintRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Exception;
use Illuminate\Support\Collection;
use Statamic\Exceptions\BlueprintNotFoundException;
use Statamic\Facades;
use Statamic\Facades\Blink;
use Statamic\Facades\File;
use Statamic\Facades\Path;
Expand All @@ -23,6 +24,18 @@ class BlueprintRepository
protected $fallbacks = [];
protected $additionalNamespaces = [];

public function all()
{
$namespaces = [
...Facades\Collection::all()->map(fn ($collection) => "collections/{$collection->handle()}")->all(),
...Facades\Taxonomy::all()->map(fn ($taxonomy) => "taxonomies/{$taxonomy->handle()}")->all(),
'navigation', 'assets', 'globals', 'forms',
...$this->getAdditionalNamespaces()->keys()->all(),
];

return collect($namespaces)->flatMap(fn ($namespace) => $this->in($namespace)->values());
}

public function setDirectories(string|array $directories)
{
if (is_string($directories)) {
Expand Down Expand Up @@ -334,7 +347,7 @@ protected function makeBlueprintFromFile($path, $namespace = null)
->setInitialPath($path)
->setNamespace($namespace ?? null)
->setContents($contents);
});
})->setParent(null);
}

protected function getNamespaceAndHandle($blueprint)
Expand Down
4 changes: 4 additions & 0 deletions src/Fields/FieldsetRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ public function save(Fieldset $fieldset)
"{$directory}/{$handle}.yaml",
YAML::dump($fieldset->contents())
);

$this->fieldsets[$fieldset->handle()] = $fieldset;
}

public function delete(Fieldset $fieldset)
Expand All @@ -181,6 +183,8 @@ public function delete(Fieldset $fieldset)
}

File::delete($fieldset->path());

unset($this->fieldsets[$fieldset->handle()]);
}

public function reset(Fieldset $fieldset)
Expand Down
22 changes: 22 additions & 0 deletions src/Listeners/UpdateAssetReferences.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
use Statamic\Events\AssetReplaced;
use Statamic\Events\AssetSaved;
use Statamic\Events\Subscriber;
use Statamic\Facades\Blueprint;
use Statamic\Facades\Fieldset;

class UpdateAssetReferences extends Subscriber implements ShouldQueue
{
Expand Down Expand Up @@ -99,6 +101,26 @@ protected function replaceReferences($asset, $originalPath, $newPath)
}
});

Blueprint::all()
->each(function ($blueprint) use ($originalPath, $newPath, &$hasUpdatedItems) {
$updated = AssetReferenceUpdater::item($blueprint)
->updateReferences($originalPath, $newPath);

if ($updated) {
$hasUpdatedItems = true;
}
});

Fieldset::all()
->each(function ($fieldset) use ($originalPath, $newPath, &$hasUpdatedItems) {
$updated = AssetReferenceUpdater::item($fieldset)
->updateReferences($originalPath, $newPath);

if ($updated) {
$hasUpdatedItems = true;
}
});

if ($hasUpdatedItems) {
AssetReferencesUpdated::dispatch($asset);
}
Expand Down
10 changes: 10 additions & 0 deletions src/Taxonomies/TermReferenceUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,14 @@ protected function newValue()
{
return $this->scope.$this->newValue;
}

/**
* Update fields in blueprints and fieldsets.
*
* @return void
*/
protected function updateBlueprintFields()
{
//
}
}
1 change: 1 addition & 0 deletions tests/Assets/AssetFolderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,7 @@ private function containerWithDisk()
Storage::fake('local');

$container = Facades\AssetContainer::make('test')->disk('local');
Facades\AssetContainer::shouldReceive('find')->with('assets')->andReturn(null);
Facades\AssetContainer::shouldReceive('findByHandle')->with('test')->andReturn($container);
Facades\AssetContainer::shouldReceive('save')->with($container);

Expand Down
3 changes: 3 additions & 0 deletions tests/Assets/AssetTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,7 @@ public function it_can_be_moved_to_another_folder_with_a_new_filename()
$disk->put('old/asset.txt', 'The asset contents');
$container = Facades\AssetContainer::make('test')->disk('local');
Facades\AssetContainer::shouldReceive('save')->with($container);
Facades\AssetContainer::shouldReceive('find')->with('assets')->andReturnNull();
Facades\AssetContainer::shouldReceive('findByHandle')->with('test')->andReturn($container);
$asset = $container->makeAsset('old/asset.txt')->data(['foo' => 'bar']);
$asset->save();
Expand Down Expand Up @@ -1202,6 +1203,7 @@ public function it_lowercases_when_moving_to_another_folder_with_a_new_filename(
$disk->put('old/asset.txt', 'The asset contents');
$container = Facades\AssetContainer::make('test')->disk('local');
Facades\AssetContainer::shouldReceive('save')->with($container);
Facades\AssetContainer::shouldReceive('find')->with('assets')->andReturnNull();
Facades\AssetContainer::shouldReceive('findByHandle')->with('test')->andReturn($container);
$asset = $container->makeAsset('old/asset.txt');
$asset->save();
Expand All @@ -1225,6 +1227,7 @@ public function it_doesnt_lowercase_moved_files_when_configured()
$disk->put('old/asset.txt', 'The asset contents');
$container = Facades\AssetContainer::make('test')->disk('local');
Facades\AssetContainer::shouldReceive('save')->with($container);
Facades\AssetContainer::shouldReceive('find')->with('assets')->andReturnNull();
Facades\AssetContainer::shouldReceive('findByHandle')->with('test')->andReturn($container);
$asset = $container->makeAsset('old/asset.txt');
$asset->save();
Expand Down
39 changes: 39 additions & 0 deletions tests/Fields/BlueprintRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
use Statamic\Fields\Blueprint;
use Statamic\Fields\BlueprintRepository;
use Statamic\Support\FileCollection;
use Tests\PreventSavingStacheItemsToDisk;
use Tests\TestCase;

class BlueprintRepositoryTest extends TestCase
{
use PreventSavingStacheItemsToDisk;

private $repo;

public function setUp(): void
Expand All @@ -26,6 +29,42 @@ public function setUp(): void
Facades\Blueprint::swap($this->repo);
}

#[Test]
public function it_gets_all_blueprints()
{
$this->repo->setDirectories($this->fakeStacheDirectory.'/dev-null/blueprints');

$collection = tap(Facades\Collection::make('test'))->save();
$collection->entryBlueprint()->save();

$taxonomy = tap(Facades\Taxonomy::make('test'))->save();
$taxonomy->termBlueprint()->save();

$nav = tap(Facades\Nav::make('test'))->save();
$nav->blueprint()->save();

$assetContainer = tap(Facades\AssetContainer::make('test'))->save();
$assetContainer->blueprint()->save();

Facades\GlobalSet::make('test')->save();
$this->repo->make('test')->setNamespace('globals')->save();

$form = tap(Facades\Form::make('test'))->save();
$form->blueprint()->save();

$all = $this->repo->all();

$this->assertEveryItemIsInstanceOf(Blueprint::class, $all);
$this->assertEquals([
'collections.test.test',
'taxonomies.test.test',
'navigation.test',
'assets.test',
'globals.test',
'forms.test',
], $all->map->fullyQualifiedHandle()->all());
}

#[Test]
public function it_gets_a_blueprint()
{
Expand Down
1 change: 1 addition & 0 deletions tests/Git/GitEventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,7 @@ public function it_batches_asset_references_changes_into_one_commit()
],
]);

BlueprintRepository::shouldReceive('all')->andReturn(collect([$blueprint]));
BlueprintRepository::shouldReceive('in')->with('collections/pages')->andReturn(collect([$blueprint]));

foreach (range(1, 3) as $i) {
Expand Down
Loading