Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incompatibilty with Winzou state machine #44

Closed
petermein opened this issue Jul 29, 2020 · 9 comments
Closed

Incompatibilty with Winzou state machine #44

petermein opened this issue Jul 29, 2020 · 9 comments
Labels

Comments

@petermein
Copy link

The interface declaration doesn't match with the implemenation in this package

Declaration of Sebdesign\SM\StateMachine\StateMachine::apply($transition, bool $soft = false, array $context = Array): bool must be compatible with SM\StateMachine\StateMachine::apply(string $transition, $soft = false): bool

@sebdesign
Copy link
Owner

sebdesign commented Jul 29, 2020

Thanks for reporting this!

Could you provide a stack trace for this error? Which PHP version are you using?

@sebdesign sebdesign added the bug label Jul 29, 2020
@robvanaarle
Copy link

robvanaarle commented Jul 30, 2020

I'm having the same issue with PHP 7.2.22 and PHP 7.3.20, it's triggering the Fatal error as specified by petermein.

The StateMachine class and interface of winzou declares the method apply as
public function apply(string $transition, $soft = false): bool

Your StateMachine class declares it as
public function apply($transition, bool $soft = false, array $context = []): bool

This is incompatible and causes the Fatal error.

Digging deeper I found out I'm on version 0.4.0 of winzou/state-machine. If I clone this repo and run composer update I get version 0.4.1, which matches with your declaration of apply(). That explains why you didn't notice. I don't know why I don't get 0.4.1. The github repo of that package does not have a release of 0.4.1. I'm not sure what is going on here.

Edit: Creating an empty project with a composer.json that only requires version 3.0.1 of your package will also provide me with version 0.4.0 of winzou/state-machine.

@sebdesign
Copy link
Owner

@robvanaarle I think I understand your issue. When I added support for Laravel 7 and Symfony 5, I had to fork winzou/state-machine to https://github.com/sebdesign/state-machine, in order to fix compatibility issues. I had tagged my changes as v0.4.0 and v0.4.1.

I did send a PR to the original repository then, and the changes were tagged just a few days ago: https://github.com/winzou/state-machine/releases/tag/0.4.0

So if you didn't add the following repository to your composer.json, composer will install winzou/state-machine:0.4.0. Which by the way should be fine, because the code is essentially the same. But I have to test it again.

+ "repositories": [
+     {
+         "type": "vcs",
+         "url": "https://github.com/sebdesign/state-machine"
+     }
+ ]

It's strange that the tests are passing in all PHP versions in Travis, and there's no such error.

@robvanaarle
Copy link

The tag you're referring to is for commit da3ef73. In that commit the apply() method was changed from
public function apply($transition, $soft = false)

to
public function apply(string $transition, $soft = false): bool

which does not match your definition of apply():
public function apply($transition, bool $soft = false, array $context = []): bool

That is the reason it's not working. I solved it temporarily by adding the following dependency:
"winzou/state-machine": "dev-master#0e2d44594ed270fdf0860681b8f4236b0078c7e6 as 0.4.x-dev"

@sebdesign
Copy link
Owner

You're right! I didn't notice that the original package added the string typehint to the $transition parameter. I thought that the $context was the issue.

I have to think for a strategy to fix this in a BC way, without breaking applications that are relying on non-string $transition arguments.

@robvanaarle
Copy link

Actually the Fatal Error is caused due to your bool typehint for $soft. If you remove that, it's working again. I've tested it in my project. Here is a simple script that can reproduce and solve it:

interface WinzouStateMachineInterface {
    public function apply(string $transition, $soft = false): bool;
}

class WinzouStateMachine implements WinzouStateMachineInterface {
    public function apply(string $transition, $soft = false): bool {
        return false;
    }
}

// This will cause the fatal
class SebdesignStateMachine extends WinzouStateMachine {
    public function apply($transition, bool $soft = false, array $context = []): bool {
        return true;
    }
}

// This works
class SebdesignStateMachine extends WinzouStateMachine {
    public function apply($transition, $soft = false, array $context = []): bool {
        return true;
    }
}

@sebdesign sebdesign reopened this Jul 31, 2020
@sebdesign
Copy link
Owner

@robvanaarle I've pushed your suggestion to master. Could please try it before I tag this as a new release?

@robvanaarle
Copy link

Yes. The code change is as expected and using master in my project let my unit tests pass again. Thanks!

@sebdesign
Copy link
Owner

I've tagged v3.0.2. Thanks for your help with this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants