Jump to content

Hooks inside init.php to namespaced classes does not work


Juergen
 Share

Recommended Posts

Hello @all

I have tried to apply a hook to a class of a module of my mine which runs inside a namespace. The hook is included inside the site/init.php.

$this->wire()->addHookAfter('Label::renderAsterisk', function(HookEvent $event) {
    bd('render Asterisk');
});

This hook runs on the function renderAsterisk() which is hookable and part of the class "Label" (original File: Label.php).

This class descends from Wire so hooks should work inside this class, but I guess the main problem is that this class runs inside its own namespace called "FrontendForms".


So I tried different versions within the hook to define the class:

  • FrontendForms\Label::renderAsterisk
  • \FrontendForms\Label::renderAsterisk
  • \\FrontendForms\Label::renderAsterisk
  • FrontendForms\\Label::renderAsterisk

 None of the versions above work!

After a search on the internet, I found a discussion about this problem here. It seems that other people have also stumbled upon this problem.

My question: Has anyone already struggled with the same problem and found a solution on how to get hooks to work on classes with namespaces, or could there be another cause responsible for this behavior?

Additional info: This issue comes from my FrontendForms module and I've used hooks in the past to manipulate the output a bit (look here). The hooks have worked in the past, but it seems that they don't work anymore in PW version 3.

Thanks for your help!

Link to comment
Share on other sites

Hello @bernhard

This is interesting, but in my case the hook does not get fired. It seems that that it will be ignored.

The function is hookable by prefixing 3 underscores:

public function ___renderAsterisk(): string
    {
        return '<span class="asterisk">*</span>';
    }

The class 'Label' itself (where the function above is part of) is derived from the Wire class (take a look here on the top parent class), so hooks must be implemented and should work. Only to mention: the top parent class called 'Tag' is an abstract class - could this have an impact on the issue?

Do you have a working example in one of your numerous modules, where you use a hook inside the init.php to hook a method in one of your modules?

Link to comment
Share on other sites

/site/init.php

wire()->addHookAfter('Foo::hello', function ($event) {
  $event->return .= ' - hooked :)';
});

/site/modules/WhatEver/Test.module.php

<?php

namespace ProcessWire;

use MyNamespace\Foo;

class Test extends WireData implements Module
{

  public static function getModuleInfo()
  {
    return [
      'title' => 'Test',
      'version' => '0.0.1',
      'summary' => 'Your module description',
      'autoload' => true,
      'singular' => true,
      'icon' => 'smile-o',
      'requires' => [],
      'installs' => [],
    ];
  }

  public function init()
  {
    wire()->classLoader->addNamespace('MyNamespace', __DIR__ . '/classes');
  }

  public function ready()
  {
    $foo = new Foo();
    bd($foo->hello());
  }
}

/site/modules/WhatEver/classes/Foo.php

<?php

namespace MyNamespace;

use ProcessWire\Wire;

class Foo extends Wire
{
  public function ___hello()
  {
    return "HELLO!";
  }
}

dvTQHNQ.png

  • Like 2
Link to comment
Share on other sites

Thanks for your quick response @bernhard

I compared your example to mine and I see that you are calling the method ($foo->hello()) inside your ready() method. In this case it works on my side too, but this is not the scenario that I want.

I want to manipulate the output not inside the ready() but before page render, so the markup of the method should be changed before the page will be rendered.

 public function ___renderAsterisk(): string
    {
        return '<span class="asterisk">*</span>';
    }

This is a render function, which will be called during the render function of the form and the form will be rendered during the page will be rendered. So I want to change the output of the renderAsterisk() method inside the site/init.php and this does not work at all.

wire()->addHookAfter('Label::renderAsterisk', function ($event) {
        $event->return = ' - hooked aha :)';
    });

So this works fine if the renderAsterisk() method will be called inside the ready.php separately.

$foo = new Label();
    bd($foo->renderAsterisk());

But it does not work if the renderAsterisk() method is included inside another render function (in this case inside the render function of the form. This should be the issue of the problem.

To simplify: It works if the renderAsterisk() method will be called directly, but not if this method is included within another method and will be called there.

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