Jump to content
celfred

Basic hook question...

Recommended Posts

Hello,

I am getting nuts trying to understand hooks and I hope someone in the community will be able to help. This is deiving me crazy ! I have tested tens of possibilities to eventually reduce my code to this :

  bd('outside');
  $wire->addHookAfter('Page::render', function($event) {
    bd('inside');
  });

And if someone could tell me why my bd('inside'); never triggers... I would be infinitely grateful !

EDIT : Forgot to say : this piece of code is in my _init.php included in my template (but I've also tried in my site/ready.php for no better results...)

Share this post


Link to post
Share on other sites

No problem here with your code.

image.png.ef7fc0520d6d86ed908d4cff38df38a0.png

I'm actually not sure what to suggest at the moment.

Do other hooks behave any better? 

  • Like 1

Share this post


Link to post
Share on other sites

Well... I have this in the preceding lines which seems to work ok :

	  $wire->addHook('LazyCron::everyDay', null, 'checkActivity'); // Check all players activity
  $wire->addHook('LazyCron::everyDay', null, 'randomSpecial'); // Set random special monsters
  $wire->addHook('LazyCron::everyDay', null, 'emptyTmp'); // Empty /tmp subtree every night
  $wire->addHook('LazyCron::everyDay', null, 'cleanTest'); // Init test-team players
	

Is there a basic hook other that Page::render which I could test with ? (I must admit I'm getting lost in all those hooks, hence my post in the 'Get started' forum 🙂 )

For info, I'm with PW 3.0.62.

Thanks for the help !

Share this post


Link to post
Share on other sites

You could try Page::path or maybe one of the other page hooks. Don't forget Tracy's Captain Hook panel for easily finding hooks for a particular PW variable / object / class.

image.thumb.png.a1d53f75964ccd810c4b44a112e9c42b.png

Share this post


Link to post
Share on other sites

Ah... This TracyDebugger is indeed extraordinary 🙂

There might be a clue here : my Page hooks are in lesser number than yours (no 'if', no 'links').

If I use Page::path, my 'inside' gets triggered, but as soon as I use Page::render, nothing happens 😞 And why is Page::render not listed our tables (only renderField or renderValue) ?

 

Capture du 2019-03-13 16-49-00.png

Share this post


Link to post
Share on other sites

Those numbers are line numbers in the Page.php file. It suggests you are running an older version of PW.

Page::render is a unique hook in that it actually comes from the PageRender.module file.

image.thumb.png.852b518097fb86c98c65bd08eeacbc89.png

Perhaps you could try hooking into PageRender::renderPage and see if that works.

Share this post


Link to post
Share on other sites

Ok. I have the same as you then in PageRender.module, but... hooking into PageRender::renderPage keeps me 'outside' 😞 

Share this post


Link to post
Share on other sites
10 minutes ago, celfred said:

Ok. I have the same as you then in PageRender.module, but... hooking into PageRender::renderPage keeps me 'outside' 😞 

What page are you viewing to test this? I don't think it should matter, but just curious.

Other than that, I wonder if you can try updating to the latest PW version, just in case.

Share this post


Link to post
Share on other sites

I'm viewing my homepage on localhost (the page can be seen there), but actually I went on many other pages to test, checked cache and so on... but no change...

2 minutes ago, adrian said:

Other than that, I wonder if you can try updating to the latest PW version, just in case.

I was just thinking about this. But I'm afraid I won't be able to do that right now. I always get scared of such a major update in case I break things 🙂  I prefer having more time ahead of me to do such an action. I'm not trusting my dev abilities !

So I stay tuned for ideas and I'll keep you updated when I update. But thanks a lot for your help @adrian.

Share this post


Link to post
Share on other sites

Just a thought: could there be a before hook on Page::render (perhaps from a 3rd party module) that replaces the original function and prevents after hooks from running? You can see all active hooks with trace with that little snippet:

$allHooks = $hooks->getHooks($page, 'render');
bd($allHooks);

Make sure to visit a page on the frontend, otherwise ProcessPageRender won't be invoked and Page::render won't even exist (at least that's the case here when testing on 3.0.96.

  • Like 1

Share this post


Link to post
Share on other sites

Ouah... I'm again discovering things here 🙂

@BitPoet   I've tested your code and here's what I get (Now what it means is a little over my head...) :

Capture du 2019-03-13 18-24-38.png

Capture du 2019-03-13 18-25-08.png

Share this post


Link to post
Share on other sites

The hooks in that list look good to me. A bit of a shot in the dark, but you might try and disable frontend editing in case it is enabled and see if that changes anything.

Share this post


Link to post
Share on other sites

Thanks again, but nothing changes...

So you know :

  • I disabled FrontEndEdit module
  • I cleaned all my files in the assets/cache/folder
  • I updated on my local site to PW 3.0.123

And my Page::render hook is still ignored. I tried Page::loaded and this one works well (I get my 'inside' message).

This is driving me crazy 😞 

Share this post


Link to post
Share on other sites

I think you need to try disabling all autoload modules - Tracy's Module Disabler panel make this easy.

If that still doesn't work, then try a fresh PW install just to rule out anything else.

Share this post


Link to post
Share on other sites

Indeed Tracy allows to easily disable modules. I did check them all and... no change...

Regarding a fresh install, that sounds like a huge task to me : reinstall a new database, reinstall the different modules I use, re-import data... and how will I put that back to my remote site if it solves the issue ? I'm speechless 🙂 

I've just started looking at the 'Export Profile' and trying to follow the instructions on a new local installation. But it fails. I get many errors creating the database (pa.pages does not exist, pa.modules does not exist...) and it freezes. I guess my files are too large... And I'm wondering if that's the proper way to do things I have a feeling doing an export on a new install will export the problem as well, no ? I tend to think I'll have to do all steps I've mentionned in my preceding paragraph one by one (can you confirm this is what I should do ?) but then that would take me a very long time... So I would tell you in a few days (or even weeks ?)

I can't understand how I got into this situation 😞 Anyway, thanks a lot for your help and as I said, once you'd confirm I have to re-install things 1 by 1, I will get to it at my possible pace 😉 

Share this post


Link to post
Share on other sites

Sorry, I wasn't suggesting setting everything up again - just a clean PW install with no modules, pages, templates etc just to see if it works. I imagine it will, but thought it might be a good sanity check in case there is some weird server setting somehow interfering - although I can't imagine what and you mentioned that you tried on your local dev as well and it still doesn't work.

 

  • Like 1

Share this post


Link to post
Share on other sites
7 hours ago, celfred said:

EDIT : Forgot to say : this piece of code is in my _init.php included in my template (but I've also tried in my site/ready.php for no better results...)

The hook code definitely needs to be in /site/ready.php or /site/init.php. It won't work in your template-prepended _init.php file - the page is already rendering by the time that code executes.

  • Like 3

Share this post


Link to post
Share on other sites

@Robin S : OK ! I'll test during the day. Actually, I think I did test in site/ready.php but I was wondering if bd() would work there and I imagined then that I had no simple way to see if everything worked (see my dev level !). Since I already had a couple of working hooks in templates/_init.php, I used it again here...

So most of my last tests (disabling all modules for example) need to be re-tested in site/ready.php. I'll do this during the day and tell you how this is going.

@adrian Oh ok; Then, I'll do that also from a blank-site profile.

Thanks a lot !

Share this post


Link to post
Share on other sites

I'd also place a bd('render was called') directly in the core's render function to see if it gets executed. Or a die('render') there, whatever you want. Just to make sure the method is actually called (similar to what BitPoet said).

Share this post


Link to post
Share on other sites
4 hours ago, celfred said:

I think I did test in site/ready.php but I was wondering if bd() would work there

bd() will work in site/init.php and site/ready.php - your OP code works for me in both of those files. You mentioned you had tested there already, so I didn't think about it, but I think @Robin S might be correct about what the problem is.

Share this post


Link to post
Share on other sites

Back here with... quite an amount of shame...

I'm sorry I have taken time from you all. Here's the thing : my site/ready.php which I thought did not have access to bd() because I couldn't even see a simple bd('ok'); was not at the right place. A bell just rang in my head a few minutes ago after making a fresh re-install of a blank profile ! I came back to my original local site and thought : "No way, Fred ! site/ready.php NOT your-website-root/ready.php !!!!" I moved ready.php and.... tada ! (Of course...). What a nerd...

So again, SORRY for having taken some of your time, but thanks for your helpful answers. I still have learned quite a lot from our exchange and that is the most important thing.

I'm glad I posted in 'Getting started' ;)

  • Like 3

Share this post


Link to post
Share on other sites

Glad it all worked out - we've all done similar things 🙂

  • Like 2
  • Thanks 1

Share this post


Link to post
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

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By gebeer
      Hello all,
      wasn't sure where to put this, so it goes in General section.
      Ryan shows a hook that we can use to mirror files on demand from live server to development environment to be up to date with the files on the server without having to download complete site/assets/files folder.
      I just implemented this but had problems getting files to load from a site in development that is secured with user/password via htaccess.
      First I tried to use WireHttp setHeader method for basic authentication like this
      function mirrorFilesfromLiveServer(HookEvent $event) { $config = $event->wire('config'); $file = $event->return; if ($event->method == 'url') { // convert url to disk path $file = $config->paths->root . substr($file, strlen($config->urls->root)); } if (!file_exists($file)) { // download file from source if it doesn't exist here $src = 'http://mydomain.com/site/assets/files/'; $url = str_replace($config->paths->files, $src, $file); $http = new WireHttp(); // basic authentication $u = 'myuser'; $pw = 'mypassword'; $http->setHeader('Authorization: Basic', base64_encode("$u:$pw")); $http->download($url, $file); } } But, unfortunately this didn't work.
      So now I am using curl to do the download. My hook function now looks like this
      function mirrorFilesfromLiveServer(HookEvent $event) { $config = $event->wire('config'); $file = $event->return; if ($event->method == 'url') { // convert url to disk path $file = $config->paths->root . substr($file, strlen($config->urls->root)); } if (!file_exists($file)) { // download file from source if it doesn't exist here $src = 'http://mydomain.com/site/assets/files/'; $fp = fopen($file, 'w+'); // init file pointer $url = str_replace($config->paths->files, $src, $file); $u = 'myuser'; $pw = 'mypassword'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_TIMEOUT, 50); // crazy high timeout just in case there are very large files curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_USERPWD, "$u:$pw"); // authentication curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // authentication curl_setopt($ch, CURLOPT_FILE, $fp); // give curl the file pointer so that it can write to it curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $data = curl_exec($ch); curl_close($ch); } } Now I can load files and images from the htaccess protected development server 🙂
      If anyone knows how to get this to work with WireHttp, please let me know. Thank you.
    • By Guy Incognito
      I've created a simple sports league fixture generator in a template called 'League'. Teams are added as page references then a fixture list is created as a ProFields table by hooking page save to add new rows to the table.
      The bit I need help with is that I'm trying to check a fixture doesn't already exist before adding it to the table (e.g. if a new team is added to the league). I'm trying to do this with a PW selector to filter the fixtures table and check whether Team A vs Team B already exists in the table. Then on the next line checking no fixture was found by using count().
      However as soon as I add the selector the script no longer adds any rows to the table. If I take it out, it all works fine (albeit with duplicate fixtures each time the page is saved). I've also tested the selector in a page template and it filters as expected. It's late here (UK)... I'm probably doing something stupid! Any ideas?
      <?php //Hook page save to generate league fixture lists $wire->addHookAfter("Pages::saved(template=league)", function ($event) { //Get which page has been saved $page = $event->arguments(0); $noFixturesAdded = 0; //For each team in league cycle through and add home fixtures foreach ($page->teams_in_league as $teamA) { foreach ($page->teams_in_league as $teamB) { //Check if fixture already exists $existingFixtures = $page->fixtures("team_a=$teamA,team_b=$teamB"); //Check team A is not the same as team B as you can't play yourself //Then add row to fixture table if ($teamB != $teamA && $existingFixtures->count() < 1 ) { $fixture = $page->fixtures->makeBlankItem(); $fixture->team_a = $teamA->id; $fixture->team_b = $teamB->id; $page->fixtures->add($fixture); $noFixturesAdded ++; } } } //Save updates to table $page->save('fixtures'); $message = "League saved. $noFixturesAdded new fixtures were added"; $this->message($message); });  
    • By Noel Boss
      👋 PW Pros…
      I have some hooks that I need to bind at the init phase (or even __construct) and I was wondering, and I couldn't find a good and simple way to determine if I'm in the admin. Would be nice if there is a reliable short option to do so, but I can't seem to find one… Is there a coherent way to tell this no matter where I am?
      Right now, I use the following method inside one of my modules:
      public function isAdmin($page = null) { if ( strpos($this->input->url, $this->urls->admin) !== false || $this->process instanceof ProcessPageList || $this->process instanceof ProcessPageEdit || ($page instanceof Page && $page->rootParent->id == $this->config->adminRootPageID) ) { return true; } return false; } @ryan wouldn't it be nice to have something like wire()->isAdmin(); like wire()->user->isLoggedin(); to tell if we are in admin – very early on (probably even in __construct() phase of modules?
    • By Macaco
      It's a bilingual site. There are two pages: "Artists" and "Events" each with a "Page Reference" field connecting each other.
      - Artists has a field where one can choose events available.
      - Events has a field where you can either choose artists available or create new ones.
      The problems: 
      - When I create an "Artist" page and select events from the list, it doesn't update the collection of participating artists on the "Event" page.
      - When I create an artist from the "Event" page. The field 'artist page > settings > language' is not "Active" for the second language.  When the artist page is created manually,"Active" is on by default.
      I know this all have to do with hooks, but I'm don't fully understand the logics.
    • By VeiJari
      Hello forum! 
      I started to write my first hook for Processwire but I'm pretty confused how you should write these. My idea is to hook after publishing in init.php (called before templates)  for a certain template. 
       
      Here's the code: 

      Trying to reset the checkbox (ajasta) and then saving it so it shows unchecked in the admin page when publishing "article" page. 
      But the code isn't doing anything. Not even dumping anything
      What seems to be the problem? And have you made a similar hook for this usage or am I doing it totally wrong? 😄
      Thanks for the support in advance!
×
×
  • Create New...