cms
cms copied to clipboard
Multisite entry fields not synced with origin without clearing the stache
Bug description
Entry fields are not synced with origin page until the stache gets cleared. After clearing the stache one times it works as it should for all further changes.
How to reproduce
-
Create a new Statamic project including a superuser. (STATAMIC_STACHE_WATCHER=false)
-
Configure multisite with eg. three different languages.
-
Create a new collection.
-
Create a entry for the new collection.
-
Create the new entry in another language by clicking on the corresponding site in the sidebar on the right and save & publish. The Field
contentis displayed as synced.
-
Return to the origin page and edit the value of the
contentfield. Save & Publish.
-
The page from the other language does not update its value.

-
run a
php please stache:clear. -
The value is updated.

Logs
No response
Environment
Environment
Application Name: Statamic
Laravel Version: 9.29.0
PHP Version: 8.1.8
Composer Version: 2.2.7
Environment: production
Debug Mode: OFF
URL: statamic_test.test
Maintenance Mode: OFF
Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: NOT CACHED
Views: CACHED
Drivers
Broadcasting: log
Cache: statamic
Database: mysql
Logs: stack / single
Mail: smtp
Queue: sync
Session: file
Statamic
Addons: 0
Antlers: regex
Version: 3.3.35 PRO
Installation
Fresh statamic/statamic site via CLI
Antlers Parser
No response
Additional details
No response
We have exactly the same issue.
I just used a workaround with a Listener on EntrySaved...
I leave the example code here, maybe it is useful for someone else.
// event data
$savedEntry = $event->entry;
$savedEntryId = $savedEntry->id();
$savedEntryCollectionHandle = $event->entry?->collection()->handle();
Cache::forget('stache::items::entries::'.$savedEntryCollectionHandle.'::'.$savedEntryId);
$translatedEntry = Entry::query()->where('origin', $savedEntryId)->first();
if($translatedEntry != null):
$translationEntryId = $translatedEntry->id();
Cache::forget('stache::items::entries::'.$savedEntryCollectionHandle.'::'.$translationEntryId);
endif;
Interesting. I think I have the same problem when uploading a file from the frontend to an Entry. Gonna try this workaround.
I spent some time tracking down the issue here: Localized entries contain a reference to the origin entry via Entry::origin(). When saving an entry with localized descendants, the origin of these descendants does not get updated. It still contains the old data before the save (in the cache).
My solution is to recursively update the origin of all localized descendants when saving an entry with a listener on EntrySaved, similar as the solution of @j3ll3yfi5h:
use Statamic\Entries\Entry;
use Statamic\Events\EntrySaved;
/**
* This is a workaround for https://github.com/statamic/cms/issues/6714
* Remove once this issue is resolved!
*/
class UpdateCachedOriginOfDescendants
{
public function handle(EntrySaved $event) {
$this->updateCacheOfLocalizedDescendants($event->entry);
}
private function updateCacheOfLocalizedDescendants(Entry $entry)
{
$collectionHandle = $entry->collectionHandle();
$entry->descendants()->each(function ($descendant) use ($collectionHandle) {
$store = app('stache')->store("entries::${collectionHandle}");
$store->forgetItem($descendant->id());
$store->getItem($descendant->id());
});
}
}
Not sure if this is the correct solution. I think Statamic should only write the ID of the origin entry in the cache and not the whole entry and its data to avoid this. The entry could be lazy loaded when actually accessing Entry::origin(). But I have not enough knowledge to the internals of the Stache/caching used here.
Will send a PR when I have figured out how to add tests for this properly. 😄
How do you use this class inside a listener?
@plompd This class is listening on the EntrySaved event. You can register it in your App\Providers\EventServiceProvider like this:
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
// add this
\Statamic\Events\EntrySaved::class => [
\App\Listeners\UpdateCachedOriginOfDescendants::class,
]
];
Hey @wanze
thanks for working on this issue. Seems like your PR is still unmerged and the issue also exists in v4?
Do you still use the Listener to fix it?
Hi @mmodler
Yes, we still use the listener to fix this issue in every project, also 4.x. As I mentioned in my pull request, I do not think that saving descendants or clearing the Stache is the right solution. Instead, Statamic should only store the origin's id in the cache, not the whole data of the origin entry.
However, I do not have enough time at the moment to work on this. I am a bit surprised that this issue is not getting more attention. Combined with the issue of wrongly cached descendants which even needs a patch, the whole multisite feature is basically unusable when the stache watcher is disabled.