Jump to content

Preventing page moves


MarkE
 Share

Recommended Posts

I have been trying to add some hooks to prevent pages from being moved in certain circumstances. It seems (to me) that this is not entirely straightforward.

First off, just a simple hook before the page save does not always work. In my use case, the 'circumstances' are when the page path is in some given array. In hooking before page save, the page path is the new page path after the move, rather than before it, so I need to do something like this:

// .... In the before page:saveReady hook
// $page is the page :) The code below operates when (isset($page->parentPrevious) && $object->parentPrevious != $object->parent)
				$name = $page->parentPrevious->path . $page->name . '/';  // need the path before it was moved
				// Because this hook operates after the move, we need to reverse the move
				if(in_array($name, $blockedNames)) {  // $blockedNames are the ones where we don't want moves
					$page->parent = $page->parentPrevious;
					$page->of(false);
					$this->wire()->session->set('bypassSaveHook', true); // to prevent loops
					$page->save();
					$this->wire()->session->remove('bypassSaveHook');
				}
//... rest of hook

This prevents the page being moved, both in the page hierarchy (by dragging) or in the page editor by changing the parent in the settings tab. 

I also tried hooking before Page:moveable with something like this

		/** @var Page $page */
		$page = $event->object;
		$moveable = $event->return;
		// ... code to set $moveable to false if conditions met
		$event->return = $moveable;

Interestingly, the (not documented?) moveable method is created as a hook by PagePermissions and so is hookable. However, this appears to catch only the situation where the move is effected by dragging the page in the tree, not when the parent is changed in the settings.

If anyone knows of any smarter way of doing this stuff, I would be interested, otherwise maybe this could be moved to a tutorial?

  • Like 1
Link to comment
Share on other sites

Thanks for sharing this. Looking at the implementation of parentPrevious inside wire/core/Page.php I thnk your solution is perfectly viable and the parentPrevious property was implemented so we can use it in circumstances like these.

At which point in your logic are you using the bypassSaveHook session variable to prevent loops, is it inside a different hook to Pages::save?

And since you are inside a Pages::saveReady hook, I think you do not need to set $page->of(false) because output formatting is already turned off at that stage. Also you do not need to do $page->save() because this is happening after the hook was executed and the page is saved with the values that you assigned inside the saveReady hook. So the loop most likely is being caused by the redundant $page->save(). Try removing that line and see if you need the bypassSaveHook session variable at all.

  • Like 1
Link to comment
Share on other sites

7 hours ago, gebeer said:

At which point in your logic are you using the bypassSaveHook session variable to prevent loops, is it inside a different hook to Pages::save?

And since you are inside a Pages::saveReady hook, I think you do not need to set $page->of(false) because output formatting is already turned off at that stage. Also you do not need to do $page->save() because this is happening after the hook was executed

Thanks @gebeer. In reality it's not quite as simple as that because my code is inside a method that is called by six different hooks, rather than in a single hook. However, passing the object argument to that method by reference, rather than by value, means that I can then avoid the unnecessary saves, as you suggest. I'll post an amended version in the tutorials thread.

  • Like 1
Link to comment
Share on other sites

  • 1 year later...

An alternative approach here is to use an idea from @Robin S here to prevent access to the settings tab thus preventing changing the parent there, then the hook on Page::moveable covers the interaction in the page tree, in which case no need for the slightly complex first hook in my OP.

Link to comment
Share on other sites

On 11/28/2022 at 12:59 AM, MarkE said:

this appears to catch only the situation where the move is effected by dragging the page in the tree, not when the parent is changed in the settings

Maybe open a bug report for this, that looks like this is not intended.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...