Allow to use string object name for hooks
Allow to use string class name as object when using hooks
use Foo\Bar\Controller;
// This is not working
$wire->addHook('/hello', Controller::class, 'indexHello');
// This one is working
$wire->addHook('/hello', new Controller, 'indexHello');
<?php
namespace Foo\Bar;
class Controller
{
public function indexHello(HookEvent $event)
{
header('Content-Type: application/json');
json_encode(['message' => 'String class name not working :(']);
exit;
}
}
@trk An instance of a class can have methods called, but a class name on its own can't, so isn't going to be useful here, unless maybe referring to a static method. ProcessWire knows nothing about your custom class or how it needs to be constructed, initialized, dependencies, etc. So what I'd suggest instead is this:
$wire->addHook('/hello', function($e) {
(new Controller())->indexHello();
});
Or encapsulate it all in your class. Extend Wire and attach your hooks within the class:
class Controller extends Wire {
public function __construct() {
$this->addHook('/hello', $this, 'indexHello');
}
public function indexHello($e) { ... }
}
new Controller();
Lastly, do you even need a class at all?
$wire->addHook('/hello', function($e) {
header('Content-Type: application/json');
return json_encode(['message' => 'hello world']);
});
@ryancramerdesign
Above example usage is only for example to show you the simplest usage
$wire->addHook('/user/register', User::class, 'register');
$wire->addHook('/user/login', User::class, 'login');
$wire->addHook('/user/logout', User::class, 'logout');
$wire->addHook('/user/reset-password', User::class, 'resetPassWord');
$wire->addHook('/product/{id}/similar', ProductPage::class, 'similar');
$wire->addHook('/product/{id}/slider', ProductPage::class, 'slider');
Checking $toObject variable at
https://github.com/processwire/processwire/blob/3cc76cc886a49313b4bfb9a1a904bd88d11b7cb7/wire/core/WireHooks.php#L1091 line can help
if (is_string($toObject) && class_exists($toObject)) {
$toObject = new $toObject;
}
The main purpose of this usage is don't call class until the hook triggered.
if you don't want to extend this object usage, I will use your first suggestion
$wire->addHook('/hello', function($e) {
(new Controller())->indexHello();
});
@trk are you ok with Ryan's answer? If yes, can we close this?
@matjazpotocnik I think we can use Class names as string for hooks, waiting for @ryancramerdesign answer