Skip to content

[6.x] Fix entry URIs going stale when a tree file changes on disk - #15798

Open
DanielDarrenJones wants to merge 2 commits into
statamic:6.xfrom
DanielDarrenJones:fix/6x-watcher-tree-file-uris
Open

DanielDarrenJones wants to merge 2 commits into
statamic:6.xfrom
DanielDarrenJones:fix/6x-watcher-tree-file-uris

Conversation

@DanielDarrenJones

Copy link
Copy Markdown
Contributor

Fixes #15796.

When a collection tree file changes on disk (after a git pull, a deploy or a hand edit) and the Stache watcher picks it up, the tree is re-read but the entries in it aren't updated: a page moved in the tree keeps its old URI until php please stache:clear. Links render to the old address, and Entry::findByUri() resolves the old URL rather than the new one.

Saving a tree through the API does the follow-up work in the CollectionTreeSaved listeners (UpdateStructuredEntryUris, UpdateStructuredEntryOrderAndParent). The watcher path dispatches no event, and CollectionTreeStore had no handleModifiedItem(), so nothing ran.

What this changes

  • CollectionTreeStore::handleModifiedItem() updates the collection's entry parents, order and URIs when the watcher picks up a changed tree. It uses the same conditions as UpdateStructuredEntryUris (no URI update for single-depth structures or collections without a route). The previous tree is already gone from the cache by then, so there's no diff to narrow it to the entries that moved, and it updates the whole collection. This only runs with the watcher on.
  • A structured collection's entry store checks the trees for changes before its own indexes are used. Without that, a request that only reads entries, such as Entry::find($id)->uri(), never touches the tree store, so the change isn't noticed until something else reads a tree. Each store only checks once per request, so this can't loop.

Test

FeatureTest::the_watcher_updates_entry_uris_when_a_tree_file_changes moves pages-directors from under About → Board to the top level of the fixture tree file and checks the next request. On 6.x it fails: uri() is still /about/board/directors. With this change it is /directors, findByUri('/directors') finds it, and the old URL no longer resolves. The fixture file is restored afterwards.

The test is in its own commit, so you can see it fail before the fix:

git checkout c4c16b281
vendor/bin/pest --filter tree_file_changes tests/Stache/FeatureTest.php

The full suite passes with the change.

This fails on 6.x: moving a page in a collection tree file leaves the entry's
URI as it was until the Stache is cleared.
Saving a tree through the API updates the entries it affects in the
CollectionTreeSaved listeners. When a tree file changes on disk instead,
the watcher re-reads the tree but nothing updates the entries, so their
URIs (and order) stay stale.

CollectionTreeStore now updates the collection's entry parents, order and
URIs when the watcher picks up a changed tree, under the same conditions as
UpdateStructuredEntryUris. Structured collections' entry stores check the
trees for changes before their own indexes are used, since that's where
their URIs come from.

Fixes statamic#15796

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stache watcher: editing a collection tree file on disk moves the page but leaves its URI (and order) stale

1 participant