Juergen Posted February 6, 2018 Share Posted February 6, 2018 Hello @ all, I am running a lot of hooks which are located inside the ready.php. Now I want to output some info to the user after a hook function took place in form of a message in a backend. Just to clearify: $pages->addHookAfter('saveReady', function($event) { //here comes the logic $this->message('test'); }); I want to output fe a message that a specific action (the creation of events) took place, but nothing happens. I have done this in the past in the same way with success, but now nothing works (I use the latest dev) What is wrong with this piece of code? Thanks Link to comment Share on other sites More sharing options...
kongondo Posted February 6, 2018 Share Posted February 6, 2018 (edited) 1 hour ago, Juergen said: What is wrong with this piece of code? I've tested with ProcessWire 3.0.88 and the latest, 3.0.90 and your code works fine in both. 1 hour ago, Juergen said: I am running a lot of hooks which are located inside the ready.php. Maybe a code collision? Edited February 6, 2018 by kongondo 1 1 Link to comment Share on other sites More sharing options...
Juergen Posted February 7, 2018 Author Share Posted February 7, 2018 8 hours ago, kongondo said: Maybe a code collision? Could be the problem. Thanks for confirming the correctness of the code, so I can focus on finding the problem. Link to comment Share on other sites More sharing options...
Juergen Posted February 7, 2018 Author Share Posted February 7, 2018 Ok I found the mistake: There was a missing $child->of(false); before saving values to a child page in a foreach loop and this causes the messages to not appear. So keep an eye to always include the command for unformatted values before storing something in the DB if you save!! Otherwise tracing the problem to its source will take a lot of time 2 Link to comment Share on other sites More sharing options...
adrian Posted February 7, 2018 Share Posted February 7, 2018 Just curious - I would have thought that Tracy would report the exception most likely on the bluescreen page and if not, I think the PW logs icon would turn red because it should be logged there. Did neither of those happen? Exception: Can’t save page 1: /: Call $page->of(false); before getting/setting values that will be modified and saved. Link to comment Share on other sites More sharing options...
Juergen Posted February 8, 2018 Author Share Posted February 8, 2018 No I have got no errors, wheter in PW logs neither in Tracy. But now the problem is back and it seems there is an interference with other hooks. The problem is that the hooks works well, but the messages still dont appear and I havent find a way to check where the problem comes from. Could the problem occur if you are running the same hook type multiple times ? In my case I have a lot of "addHookAfter('saveReady'...) hooks running. Link to comment Share on other sites More sharing options...
Juergen Posted February 8, 2018 Author Share Posted February 8, 2018 Ok, I have traced down the problem once more and it seems that the creation and saving of child pages inside the hook function is responsible for this behaviour. If I comment out the creation of the child pages the messages appear: foreach($eventdatesarray as $eventdate){ if($page->template == 'event_businessvacations'){ $itemtemplate = 'single-business-vacation'; } if($page->template == 'event_dates'){ $itemtemplate = 'single-date'; } if($page->template == 'event_events'){ $itemtemplate = 'single-event'; } if($page->template == 'event_specialbusinesshours'){ $itemtemplate = 'single-special-business-hours'; } $k = new Page(); $k->of(false); $k->parent = wire('pages')->get($page->id); $k->template = $itemtemplate; // set template ......... ......... $k->save(); //especially the saving seems to make problems with messages } Does anyone have the same problem? The hook itself works and the child pages will be created, only the messages dont appear. Link to comment Share on other sites More sharing options...
Juergen Posted February 8, 2018 Author Share Posted February 8, 2018 OK, here is the final solution for this problem: Dont use German Umlauts (ä,ü,ö) inside your message texts. It prevents the message from appearing. Maybe this could be also the case with other special characters (fe ß) - but not tested. This doesnt work: $this->message("Überraschung"); but this works: $this->message("Ueberraschung"); A little mistake but really hard to find. So keep an eye to only use default letters in message texts!!!!!! Link to comment Share on other sites More sharing options...
kongondo Posted February 8, 2018 Share Posted February 8, 2018 (edited) 24 minutes ago, Juergen said: A little mistake but really hard to find. So keep an eye to only use default letters in message texts!!!!!! Hmm. I don't think so. Both of these work for me $pages->addHookAfter('saveReady', function($event) { // here comes the logic #$this->message('Überraschung');// single quotes $this->message("Überraschung");// double quotes }); I have tested in both the old messages and the new(ish) system notifications. Normal Notification System Notification So, there must be something else going on (and yes, I tried without my English Text in there as well ). Edited February 8, 2018 by kongondo Link to comment Share on other sites More sharing options...
kongondo Posted February 8, 2018 Share Posted February 8, 2018 1 hour ago, Juergen said: If I comment out the creation of the child pages the messages appear: Just a by the way, this code: if($page->template == 'event_businessvacations'){ $itemtemplate = 'single-business-vacation'; } if($page->template == 'event_dates'){ $itemtemplate = 'single-date'; } if($page->template == 'event_events'){ $itemtemplate = 'single-event'; } if($page->template == 'event_specialbusinesshours'){ $itemtemplate = 'single-special-business-hours'; } The conditions you are checking are mutually exclusive. A $page->template can only ever have one name. So, there is no need to check it four times. You can use if, elseif, etc (or case:), to have PHP break out of the condition check once a match has been found. E.g. if($page->template == 'event_businessvacations'){ $itemtemplate = 'single-business-vacation'; } elseif($page->template == 'event_dates'){ $itemtemplate = 'single-date'; } elseif($page->template == 'event_events'){ $itemtemplate = 'single-event'; } elseif($page->template == 'event_specialbusinesshours'){ $itemtemplate = 'single-special-business-hours'; } 1 Link to comment Share on other sites More sharing options...
Juergen Posted February 8, 2018 Author Share Posted February 8, 2018 Yes I have done it with switch/case outside of the foreach - this was a part from the old code. Link to comment Share on other sites More sharing options...
Juergen Posted February 8, 2018 Author Share Posted February 8, 2018 30 minutes ago, kongondo said: Both of these work for me In my case they dont work if I use special characters. I have also tested it with and without special characters and nothing will be shown if I use "ü", but if I replace the "ü" with "ue" everything works as expected. I also have replaced the hard coded message text with translateable text, so there are no German Umlauts present any more. But this is really a strange thing. The main problem is that I dont get any information from the log files or from Tracy, so it was a trial and error experiment. I removed always a little part of the code to check where the problem could be. This leads me to this cause. Link to comment Share on other sites More sharing options...
Soma Posted February 8, 2018 Share Posted February 8, 2018 In my case this works all normal. Message is shown not matter what I do. But I wonder how your complete code looks like. For example you can't just create pages in a saveReady hook without handling the endless recursion you will get. It would give a 500 server error. Also creating and deleting pages could be something as the message session flash could get cleared out on something. My experience is once you get down that rabbit hole with lots of hooks on saved or especially saveReady it can get very hard to find the issue. Chances are we can't help you without having the whole thing and sitting in front. Edit: aka we don't even know what PW version you're using. Link to comment Share on other sites More sharing options...
Juergen Posted February 8, 2018 Author Share Posted February 8, 2018 49 minutes ago, Soma said: For example you can't just create pages in a saveReady hook without handling the endless recursion you will get. I dont know what you mean with endless recursion. The pages will created from an array with dates (fe an array with 10 dates). So 10 child pages will be created. There is a hard limit of 732 pages that can be created (limited by the RRULE library I use to get the recurrences of dates). Ah you mean recursion functions - translation problem. By the way: latest DEV and PHP 7 Link to comment Share on other sites More sharing options...
Soma Posted February 8, 2018 Share Posted February 8, 2018 I mean you hook into save and you create pages that you save triggering the hook again and again and again. Link to comment Share on other sites More sharing options...
Juergen Posted February 8, 2018 Author Share Posted February 8, 2018 Oh I understand! I only check after starting the hook if it is the right template and then make some manipulations. So it would be better to check before starting the hook if it is the right template. Thats the current case: $pages->addHookAfter('saveReady', function($event) { $page = $event->arguments(0); $page->of(false); $pages = wire('pages'); $name = $page->template->name; if(in_array($page->template->name, ['event_businessvacations', 'event_dates', 'event_events', 'event_specialbusinesshours'])){ ........ } }); But this would prevent the hook to be triggered on every page: $pageid = $input->get('id'); if(in_array(wire('pages')->get($pageid)->template->name, ['event_businessvacations', 'event_dates', 'event_events', 'event_specialbusinesshours'])){ $pages->addHookAfter('saveReady', function($event) { $page = $event->arguments(0); $page->of(false); $pages = wire('pages'); $name = $page->template->name; ........ }); } Is that what you mean? Link to comment Share on other sites More sharing options...
adrian Posted February 8, 2018 Share Posted February 8, 2018 Just a quick note on the $page->template to $itemtemplate conversion. You could replace all that logic with: $itemtemplate = rtrim(str_replace(array('event_', 'special', 'business'), array('single-', 'special-', 'business-'), $page->template), 's'); It's really up to you whether this seems nicer or more complicated 2 Link to comment Share on other sites More sharing options...
Juergen Posted February 8, 2018 Author Share Posted February 8, 2018 Thanks I am always glad to read about optimizations! 1 Link to comment Share on other sites More sharing options...
adrian Posted February 8, 2018 Share Posted February 8, 2018 9 minutes ago, Juergen said: Thanks I am always glad to read about optimizations! Not sure it's actually an optimization - more of a reduction and maybe a simplification depending on how you look at things. It also might handle template names without any additional logic which can also be nice. 1 Link to comment Share on other sites More sharing options...
Soma Posted February 8, 2018 Share Posted February 8, 2018 1 hour ago, Juergen said: Oh I understand! I only check after starting the hook if it is the right template and then make some manipulations. So it would be better to check before starting the hook if it is the right template. Thats the current case: $pages->addHookAfter('saveReady', function($event) { $page = $event->arguments(0); $page->of(false); $pages = wire('pages'); $name = $page->template->name; if(in_array($page->template->name, ['event_businessvacations', 'event_dates', 'event_events', 'event_specialbusinesshours'])){ ........ } }); But this would prevent the hook to be triggered on every page: $pageid = $input->get('id'); if(in_array(wire('pages')->get($pageid)->template->name, ['event_businessvacations', 'event_dates', 'event_events', 'event_specialbusinesshours'])){ $pages->addHookAfter('saveReady', function($event) { $page = $event->arguments(0); $page->of(false); $pages = wire('pages'); $name = $page->template->name; ........ }); } Is that what you mean? Yes, you just have to make sure the hook doesn't loop into nirvana. That's one way yes, but maybe the ID isn't always there. It's not so much a problem that the hook get's called multiple times if you restrict it via the template or something else (ie a $this->skip flag you set to true) but maybe some code in there gets executed still, like your message idk. It depends a lot what you do and possibly trigger in your hook. I found myself often tracking and trying to figure out what's going wrong for hours and hours, which is not fun at all. Sometimes it's a side effect or even possibly a bug you never know. 2 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