Jump to content

Delete user when page is deleted


onjegolders
 Share

Recommended Posts

Hi again fellow PWers,

A while back I created a newUser module that added a new user when a page (student) was added. This all works great. Today I'm trying to add a delete function to this same module (as we were getting leftover users when students were deleted) but it's throwing NullPage errors.

I tried changing the hookAfter to hook Before but am still getting errors.


Also strangely it's causing an issue when trying to delete these pages from the trash. I'm getting a "this page cannot be deleted" error.
 

Any pointers would be greatly appreciated :)

------------------------------------------------------------

<?php

class Createnewuser extends WireData implements Module {

    public static function getModuleInfo() {

        return array(
            'title' => 'Create a new user',
            'version' => 101,
            'summary' => 'Creates a new user and edits an existing member on saving a member page.',
            'singular' => true,
            'autoload' => true,
            );
    }

    public function init() {
        $this->pages->addHookAfter('added', $this, 'createTheUser');
        $this->pages->addHookAfter('save', $this, 'updateTheUser');
        $this->pages->addHookBefore('delete', $this, 'deleteTheUser');
    }

    public function createTheUser($event) {

        $page = $event->arguments[0];

        if($page->template == 'student'){

          $newuser = new User();
          $newuser->of(false);
          $newuser->name = $page->name;
          $newuser->pass = $page->password;
          $newuser->save();

          $this->message("New user also added $newuser->name.");
        }

    }

     public function updateTheUser($event) {

        $page = $event->arguments[0];

        if($page->template == 'student'){

          $the_user = $this->users->get("name=$page->name");
          $the_user->of(false);

          if ($page->isChanged("password")) {
            $the_user->pass = $page->password;
          }

          if ($page->isChanged("email")) {
            $the_user->email = $page->email;
          }

          $the_user->save();

          $this->message("User $the_user->name also updated.");
        }

    }

    public function deleteTheUser($event) {

        $page = $event->arguments[0];

        if($page->template == 'student'){

          $the_user = $this->users->get("name=$page->name");
          $the_user->delete();

        }

    }

}
  • Like 1
Link to comment
Share on other sites

Thanks Martijn but that didn't change things. 

Interestingly, if I comment out the delete function I'm still getting the errors.

Is it possible the hooks for page save and page add are still running on page deletion? (I can't think why?)



Ahhh! Think I have it, I was reusing the $event variable, I changed it to $event1, $event2, $event3 and it now seems to function.

Is that right?

Link to comment
Share on other sites

Is this being called by the same user? I think you can't delete yourself when logged in. Try this:

//untested
$the_user = $this->users->get("name=$page->name");
if ($the_user === $this->user) $session->logout();
$the_user->delete();
Link to comment
Share on other sites

Another update. I'm now wondering whether even the core uses delete as it's own function or whether it's encompassed in the page edit functionality?

In the core module it checks to see if an input with a name of submitted is submitted and then it processes the delete.

Strangely this is relatively straight forward in the front end.

1) Get the user whose name is the same as the page

2) Delete user.

I'm wondering if I'm approaching this wrong as I've never really created PW modules before.

Link to comment
Share on other sites

I think it doesn't matter. The question is wether the page get's deleted or trashed (in backend?).

In general, I can't stress enough on you guys here that coding is knowing how to debug and try out thing, print out vars, exit or die. I think you would easily find the problem. The more infos you have to more likely and easily you'll find the problem. No fear! 

Often with hooks it's good to exit("your var $page->name"); or use $this->message("your var $page->name"); so you can see the message and if the hook get's called and output some infos.

Most often a NullPage means a get() or find() doesn't find a page and returns a NullPage, so further operations don't work.

  • Like 3
Link to comment
Share on other sites

So going further good coding is not just assuming it will work, often it begins with always checking if you get what you need.

if($p->id) {
    // do soemthing with $p
} else {
    $this->error("Page not found");
}

Will always make a huge difference in finding errors or prevent them.

  • Like 2
Link to comment
Share on other sites

................In general, I can't stress enough on you guys here that coding is knowing how to debug and try out thing, print out vars, exit or die. I think you would easily find the problem. The more infos you have to more likely and easily you'll find the problem. No fear! 

Often with hooks it's good to exit("your var $page->name"); or use $this->message("your var $page->name"); so you can see the message and if the hook get's called and output some infos.

Most often a NullPage means a get() or find() doesn't find a page and returns a NullPage, so further operations don't work.

Sorry to digress, but I just want to thank and agree with Soma here. He mentioned this on some post I read and it has really helped me with my coding. foreach used to be my best friend but now, exit; is my best friend closely followed by var_dump and it's cousin print_r. Add these to the knowledge that PHP and PW provide very useful messages when an error occurs, so far, these are all the debugging tools I need :). So, thank you Soma!  O0  ^-^

  • Like 3
Link to comment
Share on other sites

Thanks Diogo. I remember at first getting confused by continue. In my mind it meant carry on with what you were doing :D until I read up on it in the "PW" manual (php.net) - "leave what you were doing and move on to the next iteration" sort of thing :)

Link to comment
Share on other sites

Ok as you said pages in the trash does have their name changed?

Does $page->name really match the user page name? Can you get the user if you enter the name there hardcoded?

$the_user = $this->users->get("name=hisname");

Link to comment
Share on other sites

I also tested this a bit...as reported....

this line is the one causing the nullPage error

$this->pages->addHookAfter('save', $this, 'updateTheUser');

Without that, the page deletes fine but not the user. Btw, apparently, you can't trash a user; only delete them...I don't know if this is still the case though...

Edit:

Of course, in the post above, Soma was talking about trashing the page and not the user...

Changing the code like this deletes the user but not the page and throws the error "This page may not be deleted" ...

$this->pages->addHookBefore('trash', $this, 'deleteTheUser');
Edited by kongondo
  • Like 2
Link to comment
Share on other sites

Ok as you said pages in the trash does have their name changed?

Does $page->name really match the user page name? Can you get the user if you enter the name there hardcoded?

$the_user = $this->users->get("name=hisname");

Even if I hardcode it, it doesn't seem to work unless there is an issue with my selector

I also tested this a bit...as reported....

this line is the one causing the nullPage error

$this->pages->addHookAfter('save', $this, 'updateTheUser');
Without that, the page deletes fine but not the user. Btw, apparently, you can't trash a user; only delete them...I don't know if this is still the case though...

Edit:

Of course, in the post above, Soma was talking about trashing the page and not the user...

Changing the code like this deletes the user but not the page and throws the error "This page may not be deleted[/size]" ...

$this->pages->addHookBefore('trash', $this, 'deleteTheUser');

Thank you Kongondo for testing this, I really appreciate it. I wonder what we're missing here...

Link to comment
Share on other sites

This works for me

$this->pages->addHookAfter('deleted', $this, 'deleteUser');
public function deleteUser($event){
    $page = $event->arguments(0);
    if($page->skip) return; // to prevent multiple calls when using Pages::trash(ed)
    $page->skip = true;
    if($page->template == 'student'){
        $this->message("Page name in trash $page->name");
        $name = str_replace("{$page->id}_", "", $page->name); // strip out the id_ in name
        $u = $this->users->get($name);
        if($u->id) {
            if($this->pages->delete($u, true)) { // maybe recursive in case user has children
                $this->message("deleted user $name");
            }
        } else {
            $this->error("user $name not found");
        }
    }
}

This same code also works with this code

$this->pages->addHookAfter('delete', $this, 'deleteUser');

$this->pages->addHookAfter('trashed', $this, 'deleteUser');

$this->pages->addHookAfter('trash', $this, 'deleteUser');

Just depends what you need.

  • Like 3
Link to comment
Share on other sites

Thank you very much Soma. That's brilliant and it's got it working for me.

I was still having an issue but I think it's related to the ProcessPageDelete module as when I go into Edit->Delete it works perfectly.

I have a couple of questions if you could explain?

1. Is the "save" hook appropriate for page updates as on page deletes it is also triggering the message from my update function.

2. Could you explain what $page->skip is used for? I can't find that anywhere and I have no idea how I would have ever figured that out without your input!

Thanks again :)

Link to comment
Share on other sites

Thank you very much Soma. That's brilliant and it's got it working for me.

I was still having an issue but I think it's related to the ProcessPageDelete module as when I go into Edit->Delete it works perfectly.

Thanks again :)

I'm not sure what's the issue you're talking about, nor if you want to or use admin to delete pages, as it will trash them and not delete them. So my example is just working for all hooks either trash or delete, just a question if you want the user page to be deleted if the page gets trashed or deleted.

1. Is the "save" hook appropriate for page updates as on page deletes it is also triggering the message from my update function.

Looks ok, you could also use Pages::saved or Pages::saveReady (look at core/Pages.php to read the docs what they're doing), the problem seems more that you're doing a save() in your hook so it will trigger you save hook also. SO it will create user, save user, call save hook, update user. I'm wondering why you don't get a endless recursion (?)

2. Could you explain what $page->skip is used for? I can't find that anywhere and I have no idea how I would have ever figured that out without your input!

That's is simply to prevent recursion or in case the hook get's called multiple times.

We could also avoid this differently, but it gets the job done. You could also write:

if($page->thispageisalreadyudpated) return; // do nothing
$page->thispageisalreadyupdated = true;

edit: updated code

  • Like 3
Link to comment
Share on other sites

The issue is when using the ProcessPage Delete non-core module. It adds a link to the page so you can delete without entering the page itself.

I will have a look at the update function again. I was testing with $page->isChanged() but it's still trying to update the user even if there were no changes to the page. Strange.

if($page->template == 'student' && $page->isChanged()) {

Thanks for the explanation about skip.

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

×
×
  • Create New...