Skip to content
Open
45 changes: 45 additions & 0 deletions src/Assets/AssetReferenceUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -333,4 +333,49 @@ private function updateStatamicUrlsInLinkNodes($field, $dottedPrefix)

$this->updated = true;
}

/**
* Update fields in blueprints and fieldsets.
*
* @return void
*/
protected function updateBlueprintFields()
{
$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']) && $set['image'] === $this->originalValue) {
$set['image'] = $this->newValue;
$this->updated = true;
}

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

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

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

$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
13 changes: 13 additions & 0 deletions 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
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()
{
//
}
}
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