Jump to content

Solved: Add hook to ProcessWire::init


Recommended Posts

Hello,

I'm working on a module wich will do some performance monitoring. I would like to be able to record time during the main hooks of Processwire.

But unfortunately, the Processwire::init hook never execute, either with addHookBefore or addHookAfter.

Here is a minimal test case, output is in a TracyDebugger bar dump.

<?php namespace ProcessWire;

/**
 * Minimal test case to hook to Proceswire::init
 * Output is a TracyDebugger bardump
 *
 */
class HookInit extends WireData implements Module {

    /**
	 * Array to store all server-timing marks
	 *
	 * @var array
	 */
	public $marksArray;

    public static function getModuleInfo(): array {
 		return [
            'title'         => __('Hook Init'),
            'singular'      => true,
            'autoload'      => true,
            'requires' => [
				'ProcessWire>=3.0.165',
				'PHP>=7.1.0',
			],
 		];
 	}

    public function __construct() {
		$this->marksArray = array();
    }

	public function init() {
        // DOESN'T WORKS
		$this->addHookBefore("ProcessWire::init", $this, 'addMark');

        // DOESN'T WORKS
		$this->addHookAfter("ProcessWire::init", $this, 'addMark');

		// WORKS
		$this->addHookBefore("ProcessWire::ready", $this, 'addMark');

        // WORKS
        $this->addHookAfter("Page::render", $this, 'addMark', array("priority" => 199));

        // Display in TracyDebugger bar dump
        $this->addHookAfter("Page::render", $this, 'displayMarks', array("priority" => 200));
    }

    /**
	 * Add a server-timing mark to the array
	 *
	 * @param  HookEvent $event
	 */
	public function addMark($event) {
        $this->marksArray[$event->id] = microtime(true);
    }

    /**
	 * Output $this->marksArray via TracyDebugger
	 *
	 * @param  HookEvent $event
	 */
	public function displayMarks($event) {
        bd($this->marksArray);
    }
}
?>

I am definitely doing something wrong (still learning...). Any help will be greatly appreciated!

Thanks!

Edited by Clément Lambelet
Solved
Link to comment
Share on other sites

  • 2 weeks later...

Hi! Sorry to bump this, but I'm still trying to wrap my head around this.

I re-read $wire->init() reference. It states "Hookable init for anyone that wants to hook immediately before any autoload modules initialized or after all modules initialized".

I would expect that $this->addHookAfter("ProcessWire::init", $this, 'addMark'); to works, as the module is autoloaded. Why is this hook not working ?

Would there be a workaround? I'm looking to hook as soon as possible during Processwire execution.

Link to comment
Share on other sites

Hi @Clément Lambelet I haven't tried to hook to ProcessWire::init within module's init method, but probably it's too late to declare hook for init method as modules initialization method is triggered within this method, have you tried to add your hooks in initBefore.php or boot.php? ( You can create these additional status files within 'site' directory and set them in your config file).

https://github.com/processwire/processwire/blob/master/wire/config.php#L1559

  • Like 1
Link to comment
Share on other sites

You might be interested in the new “preload module“ feature: https://github.com/processwire/processwire/commit/c4d301a40530cfa3b00ce559a14757684625a5ce

But you still won’t get around what Zeka said, I guess. Can’t you just take the time in your module’s init()/__construct()? That should be the earliest opportunity for a module to do anything anyway.

  • Like 1
Link to comment
Share on other sites

Thanks a lot for your replies!

@Zeka I was hoping it was not too late to hook during module's init method, alas... And I can't really add the hooks to initBefore.php or boot.php as the idea is to release the module publicly (and that it works without the end user having to add a hook himself).

@Jan Romero Super interesting this new preload feature! I'm just wondering if it's not a bit of a loss to create a module that requires the Dev branch. I've currently developed it to work on the Master branch.

Anyway, this functionality is not super fundamental to the module. I will for the moment, as you recommend, get the time during the init of the module. 

Thanks again!

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...