Skip to content

[4.x] Update child URIs when parent slug changes #9454

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
May 8, 2024

Conversation

jacksleight
Copy link
Contributor

@jacksleight jacksleight commented Feb 2, 2024

Fixes #9445

This PR implements a new listener that updates the URI index for all child pages whenever the parent page is updated.

It should probably only run if the slug has actually changed, but I'm not sure if there's a way to check that in an EntrySaved listener?

I couldn't figure out the right way or place to do the test, if you can point me in the right direction I'll add that in.

@jacksleight jacksleight changed the title [4.x] Fix child URIs when parent slug changes [4.x] Update child URIs when parent slug changes Feb 2, 2024
Copy link
Member

@duncanmcclean duncanmcclean left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it might be better for this logic to live in the Entry@save method instead so it's next to the rest of the save logic?

Also, with it being a listener on the EntrySaved event, it won't trigger if someone's doing $entry->saveQuietly().

@jacksleight
Copy link
Contributor Author

Oh yeah good point. I only did it like that because I was copying the other UpdateStructuredEntryUris listener that runs for tree updates, but saveQuietly is definitely an issue.

Shall I change it?

@jasonvarga
Copy link
Member

I think its okay where it is 👌

It should probably only run if the slug has actually changed, but I'm not sure if there's a way to check that in an EntrySaved listener?

There's no way at the moment, but should be once #5502 gets implemented.

@jasonvarga
Copy link
Member

Since #5502 is pretty close to being merged, I'll mark this as a draft until we implement only doing this when the slug changes.

@jasonvarga jasonvarga marked this pull request as draft February 23, 2024 20:48
Copy link
Member

@jasonvarga jasonvarga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the isDirty PR is ready, use it to make sure that all of this only happens if the slug has changed.

@jacksleight
Copy link
Contributor Author

Cool, will do.

@jacksleight
Copy link
Contributor Author

Once the isDirty PR is ready, use it to make sure that all of this only happens if the slug has changed.

Done

@jacksleight jacksleight marked this pull request as ready for review March 27, 2024 17:46
@jasonvarga
Copy link
Member

Duncan was right. Not sure why I was okay with leaving it as an event. Anyway, I updated it for you.

Thanks both!

@jasonvarga jasonvarga merged commit f6e5757 into statamic:4.x May 8, 2024
18 checks passed
@nadinengland
Copy link
Contributor

nadinengland commented Sep 30, 2024

@jasonvarga this change is causing me an issue which results in an infinite loop.

The Stache driver appears to sidestep this (haven't looked too much into it as to why) but I'm using a custom Eloquent driver and it's triggering a infinite loop for me. Completely appreciate you can't support anyone's custom stuff, but that isn't the root cause of my issue as far as I can tell.

This is because empty() php method returns false for objects: empty(collect()) === false in the updateChildPageUris() method.

I believe this should be changed to use Laravel's blank() which checks to see if it's a Laravel Collection.

Separately, this is a bit difficult to patch in the short term as the method is private, can't be overridden. It might have been discussed at length before, so apologies if this is rehashing that, but switching this and many other method to protected helps to make the code more flexible when issues like this crop up as we can monkey patch them in the container :)

Thanks as always for all your great work.

@duncanmcclean
Copy link
Member

The Stache driver appears to sidestep this (haven't looked too much into it as to why) but I'm using a custom Eloquent driver and it's triggering an infinite loop for me. Completely appreciate you can't support anyone's custom stuff, but that isn't the root cause of my issue as far as I can tell.

Are you able to open an issue on the eloquent-driver and we can look into it further.

@nadinengland
Copy link
Contributor

nadinengland commented Sep 30, 2024

I certainly can but before I do, and just to be totally clear, the issue is in the statamic/cms repo and is unrelated to the eloquent driver that you support. I am not using the Eloquent driver supported by Statamic, but rather a custom driver as mentioned, apologies for not making that clear.

The bug I mentioned is on line 438 of statamic/cms/src/Entries/Entry.php:

        if (empty($ids = $page->flattenedPages()->pluck('id'))) {
            return;
        }

This code will never return true as empty() always returns false if given an object. blank() should be used in this use case.

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.

Updating a parent page's slug makes child pages inaccessible
4 participants