Jump to content

Hide page instead of trash or delete


Pete
 Share

Recommended Posts

I've got a requirement to prevent a page being trashed or deleted and instead hidden and show a message.

Essentially what I want to do is, for given templates, prevent anyone from being able to delete the pages.

A reasonably common example of this would be in e-commerce where you would never want to allow a product to be deleted if it has ever been ordered, otherwise the order details page would break (there is an argument there for storing a JSON array of ordered products in case the name ever changes, but we won't go into that just yet :)).

What I want to do is something like this:

public function ready() {
    $this->pages->addHookBefore('trash', $this, 'preservePages');
    $this->pages->addHookBefore('delete', $this, 'preservePages');
}
 
public function preservePages(HookEvent $event) {
        
    $page = $event->arguments[0];
    if ($this->page->template = 'template-name') {
        $page->addStatus(Page::statusHidden);
        $this->message('Page has been hidden instead of deleted - need to work on the wording');
       
        // Then some way of stopping the trash or delete methods runnning, but can't think of what would work here
        return false;
    }
}

Any ideas?

Oh, and I don't want to do it with access control for some reason I can't remember right now. That would be easy as I could just prevent users being able to delete the page :)

Link to comment
Share on other sites

Hmmm... it seems I can instead do this instead of returning false in my code above:

$this->session->redirect('../');

This way it shows the message, prevents the action and returns the user to the page tree.

Only problem then is if they move it via drag and drop in the tree and it breaks the JS a bit, but at least it prevents the action.

I guess my new question is: "is there a better way?" :)

Link to comment
Share on other sites

Ah, but I can't change the page's status :( Doing this before the redirect doesn't save:

$page->addStatus('Page::statusHidden');
$page->save();

Code is now as follows:

public function ready() {
    $this->pages->addHookBefore('trash', $this, 'preservePages');
    $this->pages->addHookBefore('delete', $this, 'preservePages');
}
 
public function preservePages(HookEvent $event) {
        
    $page = $event->arguments[0];
    if ($this->page->template = 'template-name') {
        $page->addStatus('Page::statusHidden');
        $page->save();;
        $this->message('Page has been hidden instead of deleted - need to work on the wording');
        $this->message("The page was hidden instead of deleted. Pages using the '" . $page->template . "' template can be linked to other pages, so deleting is prohibited");
        $this->session->redirect('../');
    }
}
Link to comment
Share on other sites

how about

public function preservePages(HookEvent $event) {
    $event->replace = true;
    ...

Thanks for the beer.

Really strange that you can't just remove permission to delete pages, for what reason? Feels weird when deleting page and it just gets hidden. :D

  • Like 1
Link to comment
Share on other sites

Thanks Soma, my function is now a lot shorter. I just can't get it to save the page status as hidden now though - any ideas?

Basically there is a chance of someone other than me having superuser privileges and I don't want them to tweak some settings and accidentally delete a page. Just trying to make it super-foolproof.

Link to comment
Share on other sites

Thanks again Soma, I feel like an idiot right now having the status as a string (not done it anywhere else in my modules so was just being blind :D).

All working now - for those interested, this is the final code:

public function init() {
    $this->pages->addHookBefore('trash', $this, 'preservePages');
    $this->pages->addHookBefore('delete', $this, 'preservePages');
}

public function preservePages(HookEvent $event) {
    $page = $event->arguments[0];
    if ($page->template == 'template-name') {
        $page->addStatus(Page::statusHidden);
        $page->save();
        $event->replace = true;
        $this->message("The page was hidden instead of deleted. Pages using the '" . $page->template . "' template can be linked to other pages, so deleting is prohibited");
    }
}

As you can see, much simpler after Soma's expert help.

@Soma: I can't mark both your replies as the Solved post, so will have to mark this one with the full code if that's okay?

  • Like 4
Link to comment
Share on other sites

Heh, I once tried for ages to use "status<Page::statusHidden" in a selector string...

BTW where is the if ($this->page->template = 'template-name') { gone?

Fixed - just realised it as you were posting! :)

Link to comment
Share on other sites

And for those that don't know, you can do this in ProcessWire if you want to match against multiple templates, like this:

if ($page->matches('template=template1|template2|template3|template4')) { ...

instead of this:

if ($page->template == 'template1' || $page->template == 'template2' || $page->template == 'template3' || $page->template == 'template4') { ...

Just thought that was worth sharing as I was typing it the long-hand PHP way just now and stopped myself before I wrote a lot of extra characters for no real reason!

A shorter PHP alternative than above would be this:

if (in_array($page->template, array('template1', 'template2', 'template3', 'template4')) { ...

but I much prefer the ProcessWire version.

$page->matches is a lovely thing that can be used to test the current page against any selector you can think of that makes sense in your situation.

  • Like 4
Link to comment
Share on other sites

good one I also wrote about in some thread...

and for those being even more lazy can also use the even shorter $page->is(selector) :D

if($page->is('template=template1|template2|template3|template4')){

edit: or if just for one template instead

if($page->template == "basic-page"){

use

if($page->is("basic-page")){
  • Like 5
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...