Jump to content

How to output wire message after running a hook problem


Juergen
 Share

Recommended Posts

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

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 by kongondo
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

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 :(

  • Like 2
Link to comment
Share on other sites

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

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

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

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

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

umlauts_in_message.thumb.gif.e796a5ba2fa4109b508c76ff701c8a55.gif

System Notification

umlauts_in_message2.thumb.gif.ef6a5f5488a47a51042a97ac72a4c4db.gif

So, there must be something else going on (and yes, I tried without my English Text in there as well :)).

Edited by kongondo
Link to comment
Share on other sites

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';
}

 

  • Like 1
Link to comment
Share on other sites

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.

Screenshot(4).thumb.png.d61d63b24a4dcd92ad526614c1d364b4.png

 

Link to comment
Share on other sites

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

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

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

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 :)

  • Like 2
Link to comment
Share on other sites

 

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.

  • Like 1
Link to comment
Share on other sites

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. 

 

  • Like 2
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...