Issue defining callbacks in state-machine.php
Closed this issue · 3 comments
I have a laravel 9 project, with php 8.1
laravel-state-machine version 3.3.0
These don't work
'callbacks' => [
'after' => [
'after_registrar' => [
'on' => 'enviar_documentacion',
'do' => [\App\Actions\AfterTramiteTransition::class, 'run'],
'args' => ['event', 'object'],
],
],
],
'callbacks' => [
'after' => [
'after_enviar_documentacion' => [
'on' => 'enviar_documentacion',
'do' => '\App\Actions\AfterTramiteTransition@run',
'args' => ['event', 'object'],
],
],
],
The error I get is :
TypeError
SM\Callback\Callback::filterCallable(): Return value must be of type callable, string returned
at vendor/winzou/state-machine/src/SM/Callback/Callback.php:142
or Return value must be of type callable, array returned
if I used the first one.
Digging a bit into the winzou library I found SM\Callback\CallbackInterface
That's an invokable class.
If I do this it works
'callbacks' => [
'after' => [
'after_enviar_documentacion' => [
'on' => 'enviar_documentacion',
'do' => new \App\Actions\AfterTramiteTransition(),
'args' => ['event', 'object'],
],
],
],
But the problem is with Laravel with that approach. php artisan config:cahe
will fail because it can't serialize the config files.
Since that class is an invokable I tried 'do' => \App\Actions\AfterTramiteTransition::class,
but no luck, same error
I don't know what I'm doing wrong or what changed but I have another project in Laravel 8, with laravel-state-machine 3.2.1 and I have no issues using 'do' => [\App\MyClass:class, 'method']
to define callbacks.
Hello,
That's quite strange. Can you tell me the version of the "winzou/state-machine" that is installed?
composer show | grep winzou/state-machine
I figured out what's happening.
The run
method on the App\Actions\AfterTramiteTransition
class is not a static method, so PHP cannot call it statically.
This package tries to resolve the instance of the App\Actions\AfterTramiteTransition
from the container, in order to call it normally. Since the class is not registered in the Laravel container, that doesn't work.
You need to register App\Actions\AfterTramiteTransition
in your AppServiceProvider
(or any other service provider) like this:
public function register()
{
$this->bind(\App\Actions\AfterTramiteTransition::class);
}
or like this:
public array $bindings = [
\App\Actions\AfterTramiteTransition => \App\Actions\AfterTramiteTransition::class,
];
or like this:
public array $bindings = [
\App\Actions\AfterTramiteTransition => null,
];
Thanks you !
That was the issue. Either defining the the method as static or manually registering the class in Laravel's container.