Lars282 Posted August 24, 2012 Share Posted August 24, 2012 Hey. I have got a question on how to get a module to do the following: Registered users can use a form to add pages to my website, but they are added as unpublished until a moderator can review them and then publish them through the admin. What I want to add now is that the user who originally added the page receives a notification email once the page has been published. How can I hook in after 'publishing' the page? Thanks, Lars Link to comment Share on other sites More sharing options...
ryan Posted August 24, 2012 Share Posted August 24, 2012 I don't have a simple solution to this one, but will do more thinking about how I could have ProcessWire provide a hook like Pages::statusChanged or something like that. But until we have something like that, here are a couple ways you could do it: Option 1 Add a hook to Pages::saveReady and have your hook function do something like this: Pages::saveReady hook $page = $event->arguments[0]; if($page->id && $page->isChanged('status') && !$page->is(Page::statusUnpublished)) { $result = $this->db->query("SELECT status FROM pages WHERE id={$page->id}"); list($status) = $result->fetch_row(); if($status & Page::statusUnpublished) { // page is about to be published // send your email } } Option 2 The other option would be to change your workflow such that user submitted pages went into a different parent than the live ones. For instance, user-submissions might go into parent /pending/ and published submissions would live in /live/. Then you could have your hook monitor for when a page is moving from /pending/ to /live/. If you wanted to, you could also have it take care of the publishing automatically: Pages::saveReady hook $page = $event->arguments[0]; if(!$page->parentPrevious) return; // if page is not being moved then stop now if($page->parent->name == 'live' && $page->parentPrevious->name == 'pending') { $page->removeStatus(Page::statusUnpublished); // send your email } 5 Link to comment Share on other sites More sharing options...
Lars282 Posted August 24, 2012 Author Share Posted August 24, 2012 I think I prefer option 1 but am not sure whether I understand what the if statements are checking for. if($page->id && $page->isChanged('status') && !$page->is(Page::statusUnpublished)) Why is the $page->id needed? $page->isChanged('status') simply checks if the status has changed? !$page->is(Page::statusUnpublished) checks for whether the page is published now, after saving? Having checked this, it is known that the page is published now and had a different status. So now we need to check that the previous status was Unpublished? So why is the query to the DB needed and why isn't if(Page::statusUnpublished) enough? Also, how do I hook to Pages::saveReady? And where am I hooking to? Before the new values have been written into the DB but after the $page holds the new values? Sorry for so many question, this is the first time I am actually trying to use hooks myself. Link to comment Share on other sites More sharing options...
Soma Posted August 24, 2012 Share Posted August 24, 2012 (edited) I think I prefer option 1 but am not sure whether I understand what the if statements are checking for. if($page->id && $page->isChanged('status') && !$page->is(Page::statusUnpublished)) Why is the $page->id needed? $page->isChanged('status') simply checks if the status has changed? !$page->is(Page::statusUnpublished) checks for whether the page is published now, after saving? Yes, this is for the page current in memory I think. It's not yet saved to db hence the saveReady(). Checking for ID makes sure it's a page that has an id. Having checked this, it is known that the page is published now and had a different status. So now we need to check that the previous status was Unpublished? So why is the query to the DB needed and why isn't if(Page::statusUnpublished) enough? See previous. I think you need to query DB to really check if the page was unpublished before as the current in memory Page is already status "published". Also, how do I hook to Pages::saveReady? And where am I hooking to? Before the new values have been written into the DB but after the $page holds the new values? I think this goes into init() and would be public function init() { $this->addHookAfter('Page::saveReady', $this, 'sendMailOnPublish'); } The last param is the function name in your module that will get called. public function sendMailOnPublish(HookEvent $event) { // Ryans ... code } Maybe also wanna read http://wiki.processw...essWire_Modules Edited August 24, 2012 by Soma hard work making post with code and edit them.. Link to comment Share on other sites More sharing options...
slkwrm Posted August 24, 2012 Share Posted August 24, 2012 Checking for ID makes sure it's a page that has an id. I think that if($page->id) checks here that the page isn't a new/just created one. 1 Link to comment Share on other sites More sharing options...
ryan Posted August 25, 2012 Share Posted August 25, 2012 @Lars282 Soma and Slkwrm have it right. Keep in mind that saveReady is called after it's been confirmed the save() will definitely occur, and right before the save actually occurs. So this is the ideal hook for you to use in your case. I think you need to query DB to really check if the page was unpublished before as the current in memory Page is already status "published". This is correct. We don't yet have a property $page->statusPrevious property like we do for parent or template. So there's no way for you to know what the previous status was short of loading another copy of the page, or just querying the database like in the example. But now you've got me thinking I may need to add a statusPrevious property in a future version. For your hook attachment code, I would suggest this: public function ready() { $this->pages->addHook('saveReady', $this, 'sendMailOnPublish'); } …basically the same as what Soma suggested, except that I would add it to $this->pages directly since there is only ever 1 instance of $pages, making it slightly more efficient to do this way. Your actual hook function will be in the same class as your ready() function, and would resemble the one Soma posted. I think that if($page->id) checks here that the page isn't a new/just created one. This is correct. If there was no $page->id, it would be a new/unsaved page, and you wouldn't want to go querying the DB for it as we know it wouldn't be there. So that's what the $page->id check is for. 3 Link to comment Share on other sites More sharing options...
tires Posted October 13, 2021 Share Posted October 13, 2021 Hello! I tried to make my own module using the code above. But unfortunately no mail is been sent. If i delete the if statement that starts with "if($page->template ..." it works. But then a mail is sent after every page modification. Here is my module code. Do you see any error? <?php class MailNotificator extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'MailNotificator', 'version' => 1, 'summary' => 'Hook the saving of pages to add own processes.', 'singular' => true, // Limit the module to a single instance 'autoload' => true, // Load the module with every call to ProcessWire ); } public function ready() { $this->pages->addHook('saveReady', $this, 'afterSaveReady'); } public function afterSaveReady(HookEvent $event) { $page = $event->arguments[0]; if($page->template =="mytemplate" && $page->id && $page->isChanged('status') && !$page->is(Page::statusUnpublished)) { $result = $this->db->query("SELECT status FROM pages WHERE id={$page->id}"); list($status) = $result->fetch_row(); if($status & Page::statusUnpublished) { $to = "your@email.com"; $from = "my@email.com"; $subject = "New page: ".$page->title; $body = $page->text; $bodyhtml = "<html><body><p>".$page->text."</p></body></html>"; $numSent = $this->mail->subject($subject) ->to($to) ->from($from) ->body($body) ->bodyHTML($bodyhtml) ->send(); } } } } Thanks and good night! Link to comment Share on other sites More sharing options...
bernhard Posted October 14, 2021 Share Posted October 14, 2021 maybe you are just missing a second & ? & --> && if($status & Page::statusUnpublished) { 1 Link to comment Share on other sites More sharing options...
tires Posted October 14, 2021 Share Posted October 14, 2021 Thank you for the answer! I still tried the doubble ampersand. Without success. Any other suggestion? BTW. Is this line correct? $numSent = $this->mail->subject($subject) Link to comment Share on other sites More sharing options...
3fingers Posted October 14, 2021 Share Posted October 14, 2021 Try to change the trigger from "saveReady to "save"? // Before public function ready() { $this->pages->addHook('saveReady', $this, 'afterSaveReady'); } // After public function ready() { $this->pages->addHookAfter('save', $this, 'afterSaveReady'); } 1 Link to comment Share on other sites More sharing options...
tires Posted October 14, 2021 Share Posted October 14, 2021 Thanks for your answer! I tried it without success. It seems that this line is responisble for the error. If i delete the if statemant the mail is sent (twice and after every change of the page). if($page->template =="mytemplate" && $page->id && $page->isChanged('status') && !$page->is(Page::statusUnpublished)) { Link to comment Share on other sites More sharing options...
bernhard Posted October 14, 2021 Share Posted October 14, 2021 We have a hook for that by now: https://processwire.com/api/ref/pages/published/ <?php $wire->addHookAfter("Pages::published(template=yourpagetemplate)", function(HookEvent $event) { $page = $event->arguments(0); $mail = new WireMail(); $mail->subject("Page {$page->title} has been published..."); ... $mail->send(); }); Not sure if that is really what you want though... Maybe you want to send an email when the page is created? Then Pages::added is for you: https://processwire.com/api/ref/pages/added/ 5 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now