Skip to content

[6.x] Fix the Stache watcher not removing entries whose files were deleted - #15797

Open
DanielDarrenJones wants to merge 5 commits into
statamic:6.xfrom
DanielDarrenJones:fix/6x-watcher-deleted-files
Open

DanielDarrenJones wants to merge 5 commits into
statamic:6.xfrom
DanielDarrenJones:fix/6x-watcher-deleted-files

Conversation

@DanielDarrenJones

Copy link
Copy Markdown
Contributor

Fixes #12824.

When the Stache watcher is on and an entry's file is deleted from disk, the entry is never removed: Entry::find() still returns it, it still appears in queries and the Control Panel, and only php please stache:clear gets rid of it. Since #11863, handleFileChanges() builds its list of deleted files as keys, but the loop that flushes them still treats each value as a path (getKeyFromPath($path)), finds nothing and removes nothing.

The same method also kept the paths it memoized before applying any changes, so for the rest of that request a renamed file still pointed at its old path, and a newly added file couldn't be found by getItem().

What this changes

  • Deleted paths are kept together with the key each one had.
  • Deletions are decided after the modified files are read, since reading them is what reveals their keys. A key that comes back under a new path was renamed or moved (what [5.x] Updated the Stache Store to not remove stache items that exist #11863 was protecting), so only its old path is released. Every other key is flushed as before: item, path, index entries, handleDeletedItem().
  • The memoized paths are dropped once the path index has been updated, so added and renamed files are found straight away.

Tests

Each of these fails on 6.x and passes with this change:

Test On 6.x
BasicStoreTest::the_watcher_removes_an_item_whose_file_was_deleted the deleted item is still returned
BasicStoreTest::the_watcher_keeps_an_item_whose_file_was_renamed the item still points at the old file
BasicStoreTest::the_watcher_handles_a_deleted_and_an_added_file_in_the_same_request the deleted item is still returned
Stores\EntriesStoreTest::the_watcher_removes_an_entry_whose_file_was_deleted the deleted entry is still found (an end-to-end version of the report)

The tests are in their own commit, so you can see them fail before the fix:

git checkout e057ecfcb
vendor/bin/pest --filter watcher tests/Stache/BasicStoreTest.php tests/Stache/Stores/EntriesStoreTest.php

The full suite passes with the change.

These fail on 6.x: a file deleted on disk is never removed from the Stache,
and a renamed file keeps pointing at its old path for the rest of the request.
Since statamic#11863 the watcher's list of deleted files holds keys, but the loop that
flushes them still looked each one up as a path, so nothing was removed.

Deleted paths are now kept with their keys, and the decision is made after the
modified files are read: a key that comes back under a new path was renamed,
so only its old path is released; any other key is flushed. The memoized
paths are also dropped once the path index is updated, so added and renamed
files are found for the rest of the request.

Fixes statamic#12824
A term file holds the term and its localizations, so several keys share one path.
Flipping paths() kept only one key per path, leaving the other localizations cached.

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 not working

1 participant