Giter Site home page Giter Site logo

statemachinebundle's People

Contributors

apoorva-shah avatar bpolaszek avatar cawolf avatar coldic3 avatar cordoval avatar firstred avatar kswzr avatar lchrusciel avatar loic425 avatar mtdavidson avatar nicolassing avatar pamil avatar papsou avatar pmartelletti avatar rdohms avatar ruudy-es avatar wadjeroudi avatar winzou avatar zales0123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

statemachinebundle's Issues

Symfony 4 support (3.4.9 deprecation warning)

Version 0.3.1 claims to be Symfony4 compatible, but when running this version as a part of Symfony 3.4.9, I still get the following deprecation warning:

Auto-registration of the command "winzou\Bundle\StateMachineBundle\Command\winzouStateMachineDebugCommand" is deprecated since Symfony 3.4 and won't be supported in 4.0. Use PSR-4 based service discovery instead.

$this not in object context

So was working with Sylius about a year ago really enjoyed your State Machine Bundle's implementation within in. I'm trying to incorporate it into my own project but am running into errors. I'm working with Symfony 4 and have an autowired service that's throwing a '$this not in object context' when I try to use it with the transition callback. But when I use the same service in a controller or command or something, it works fine. Thoughts? Is there a config setting somewhere I need to set?

Twig extension helper functions. Is it needed?

Hi,

I've found myself in need to test if transitions is possible inside template, which is easily can be solved with twig extension like this.

 <?php
 
 namespace Acme\AppBundle\Twig;
 
 use SM\Factory\FactoryInterface;
 
 class StateMachineExtension extends \Twig_Extension
 {
     /**
      * @var FactoryInterface
      */
     protected $factory;
 
     /**
      * @param FactoryInterface $factory
      */
     public function __construct(FactoryInterface $factory) {
         $this->factory = $factory;
     }
 
     public function getFunctions()
     {
         return [
             new \Twig_SimpleFunction('acme_statemachine_can', [$this, 'can']),
         ];
     }
 
     /**
      * @param object $subject
      * @param string $graph
      * @param string $transition
      *
      * @return bool
      */
     public function can($subject, $graph, $transition)
     {
         $stateMachine = $this->factory->get($subject, $graph);
 
         return $stateMachine->can($transition);
     }
 
     public function getName()
     {
         return 'acme_statemachine_extension';
     }
 }
 ~                                                                
{% if acme_statemachine_can(payment, 'sylius_payment', 'complete') %}
    {{ buttons.put(path('sylius_backend_payment_update_state', {'id': payment.id, 'transition': 'complete'}), 'Complete') }}
{% endif %}

Is this feature falls into bundles scope? If so, let me know and I would be glad to provide PR.

Bug during overrides in configuration

Hello,

I was trying the new sylius 1.0.0@alpha and tried to disable a state and transitions but it seems that the way that configuration is parsed does not respect overrides and merge all together...

I created test and made a PR, tell me if it seems ok for you and i can create the code to respect this spec

#31

Feature Request - Debug Command / List Callbacks

I'd like to see a command line command that works a lot like the debug:event-dispatcher command, where you supply a graph, a transition, and optionally before/after and it lists all of the callbacks, in order, just like the event dispatcher lists the event listeners. Does anyone else have any thoughts about this? IMO this is useful if your state-machines are configured in more that one config file and you want to see everything in one place. Thoughts? Suggestions?

Factory Question

I've always wondered why we need to instantiate a different state machine for each instantiated domain object, can't we just instantiate one state machine per class, per graph? So instead of doing $sm = $factory->get($object, 'graph-name') for each domain object, you'd just do it once per CLASS and be able to pass instances of that class into the state machine asking it to transition the given object through a transition.

Here's the example of what I'm talking about:

$foos = [new Foo(), new Foo(), new Foo()];
$fooDefaultSM = $factory->get(current($foos), 'default') // First argument can also be a class name maybe?
foreach ($foos as $foo) {
    if ($fooDefaultSM->can($foo, 'some-transition'))
        $fooDefaultSM->apply($foo, 'some-transition);
    }
}

Under the current implementation, you need to instantiate one SM per iteration of the loop (3 of them). Under the proposed interface, you'd only need one SM total.

Thoughts? Am I missing something?

sharing a transition graph

Hi, maybe this is a stupid question. I was wondering if there is any easy way to share a graph.
Say I have 2 entities that follow the same state graph, which is pretty common in cms systems (draft, proposal, confirmed, published, etc).
I'd like to create a common flow that I could attach in configuration to each entity.

Is that possible?
Thx

Execute a callback on multiple transitions

Hello,

I just would like to know if it's possible to execute the same callback on multiple transitions like :

        callbacks:
            after:
                create_invoice:
                    on:   ['confirm', 'cashing_and_collection_of_goods']
                    do:   [ "@app.infrastructure.state_handler.order.invoice", create ]
                    args: [ 'object' ]

usage example in Sylius is not very clear

i have tried to use this with https://github.com/Sylius/Sylius/pull/1426/files in view and others i found, however is not very clear

I am getting

) Vendor\UseCases\WorkflowTest::it_goes_through_the_whole_workflow
SM\SMException: Cannot create a state machine because the configuration
for object Vendor\Domain\ACase with graph vendor_transition does not exist.

I think it may be because i copied the state machine from sylius into my project and the configuration gets assigned in a weird way. Do you have any hint? maybe a doc cookbook would come handy to use this more. The specs don't tell us how to do it at the symfony level.

Symfony 4 Support

Does the latest version of this bundle 0.3.1 fully support Symfony 4?

I still got some autowiring issues:

Cannot autowire service "***\ProfileController": argument "$statemachine" of method "__construct()" references class "SM\Factory\Factory" but no such service exists. It cannot be auto-registered because it is from a different root namespace.

Maybe I have to include some configuration files?

ContainerAwareCallback warning.

Not sure what triggered it.. but I have seen it a few times.

Warning: strpos() expects parameter 1 to be string, object given in /Users/kayue/Sites/store/vendor/winzou/state-machine-bundle/Callback/ContainerAwareCallback.php on line 40

Call Stack:
    0.0002     228976   1. {main}() /Users/kayue/Sites/store/app/console:0
    0.0227    2780728   2. Symfony\Component\Console\Application->run() /Users/kayue/Sites/store/app/console:28
    0.0252    2977504   3. Symfony\Bundle\FrameworkBundle\Console\Application->doRun() /Users/kayue/Sites/store/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:121
    0.2312   18938440   4. Symfony\Component\Console\Application->doRun() /Users/kayue/Sites/store/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php:96
    0.2338   18939856   5. Symfony\Component\Console\Application->doRunCommand() /Users/kayue/Sites/store/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:191
    0.2348   19019096   6. Symfony\Component\Console\Command\Command->run() /Users/kayue/Sites/store/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php:898
    0.2351   19023440   7. Doctrine\Bundle\FixturesBundle\Command\LoadDataFixturesDoctrineCommand->execute() /Users/kayue/Sites/store/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php:244
    1.7017   26742648   8. Doctrine\Common\DataFixtures\Executor\ORMExecutor->execute() /Users/kayue/Sites/store/vendor/doctrine/doctrine-fixtures-bundle/Doctrine/Bundle/FixturesBundle/Command/LoadDataFixturesDoctrineCommand.php:106
    1.7017   26744080   9. Doctrine\ORM\EntityManager->transactional() /Users/kayue/Sites/store/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Executor/ORMExecutor.php:85
    1.7065   26938696  10. call_user_func() /Users/kayue/Sites/store/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:243
    1.7065   26938784  11. Doctrine\Common\DataFixtures\Executor\ORMExecutor->Doctrine\Common\DataFixtures\Executor\{closure}() /Users/kayue/Sites/store/vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:243
    7.9412   62978464  12. Doctrine\Common\DataFixtures\Executor\AbstractExecutor->load() /Users/kayue/Sites/store/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Executor/ORMExecutor.php:83
    7.9417   62979544  13. Hypebeast\Bundle\CoreBundle\DataFixtures\ORM\LoadOrdersData->load() /Users/kayue/Sites/store/vendor/doctrine/data-fixtures/lib/Doctrine/Common/DataFixtures/Executor/AbstractExecutor.php:121
   25.0190  113213056  14. Hypebeast\Bundle\CoreBundle\DataFixtures\ORM\LoadOrdersData->setState() /Users/kayue/Sites/store/src/Hypebeast/Bundle/CoreBundle/DataFixtures/ORM/LoadOrdersData.php:75
   25.3522  113775472  15. SM\StateMachine\StateMachine->apply() /Users/kayue/Sites/store/src/Hypebeast/Bundle/CoreBundle/DataFixtures/ORM/LoadOrdersData.php:96
   25.3525  113777256  16. SM\StateMachine\StateMachine->callCallbacks() /Users/kayue/Sites/store/vendor/winzou/state-machine/src/SM/StateMachine/StateMachine.php:123
   25.3526  113782952  17. SM\Callback\Callback->__invoke() /Users/kayue/Sites/store/vendor/winzou/state-machine/src/SM/StateMachine/StateMachine.php:204
   25.3527  113783000  18. winzou\Bundle\StateMachineBundle\Callback\ContainerAwareCallback->call() /Users/kayue/Sites/store/vendor/winzou/state-machine/src/SM/Callback/Callback.php:77
   25.3528  113783536  19. SM\Callback\Callback->call() /Users/kayue/Sites/store/vendor/winzou/state-machine-bundle/Callback/ContainerAwareCallback.php:46
   25.3534  113812688  20. call_user_func_array() /Users/kayue/Sites/store/vendor/winzou/state-machine/src/SM/Callback/Callback.php:68
   25.3535  113813368  21. SM\Callback\CascadeTransitionCallback->apply() /Users/kayue/Sites/store/vendor/winzou/state-machine/src/SM/Callback/Callback.php:68
   25.3535  113814120  22. SM\StateMachine\StateMachine->apply() /Users/kayue/Sites/store/vendor/winzou/state-machine/src/SM/Callback/CascadeTransitionCallback.php:61
   25.3538  113814488  23. SM\StateMachine\StateMachine->callCallbacks() /Users/kayue/Sites/store/vendor/winzou/state-machine/src/SM/StateMachine/StateMachine.php:123
   25.3538  113814488  24. SM\Callback\Callback->__invoke() /Users/kayue/Sites/store/vendor/winzou/state-machine/src/SM/StateMachine/StateMachine.php:204
   25.3539  113814536  25. winzou\Bundle\StateMachineBundle\Callback\ContainerAwareCallback->call() /Users/kayue/Sites/store/vendor/winzou/state-machine/src/SM/Callback/Callback.php:77
   25.3539  113814632  26. strpos() /Users/kayue/Sites/store/vendor/winzou/state-machine-bundle/Callback/ContainerAwareCallback.php:40

The object is a SM\Callback\CascadeTransitionCallback.

I will try to reproduce it in Sylius's master when I have time.

Read the graph definition from DB

I @winzou , Just googling, I found this bundle. I'm surpised by your great job.

I was wondering if there is way to read the graph definition from my DB. I want to be able to create the states, transitions and callbacks from my front web app.

Doy you think there is a workaround ?

I appreciate your help.

Deprecation warning in Symfony 4.3

In Symfony 4.3, the following deprecation warning is thrown:

The "Symfony\Component\Config\Definition\Builder\TreeBuilder::root()" method called for the "winzou_state_machine" configuration is deprecated since Symfony 4.3, pass the root name to the constructor instead.

A fix for a similar issue can be seen here: FriendsOfSymfony/FOSMessageBundle@e0a0587

It's possibe to add several `do` in a callback?

Hi there. Not an issue. Hope you don't mind i post the question here. I'm working with sylius and sylius used this bundle. In a sylius yml file you can see something like

winzou_state_machine:
    sylius_order_checkout:
        class: "%sylius.model.order.class%"
        property_path: checkoutState
        graph: sylius_order_checkout
        state_machine_class: "%sylius.state_machine.class%"
        ...
        callbacks:
            after:               
                sylius_hold_inventory:
                    on: ["complete"]
                    do: ["@sylius.inventory.order_inventory_operator", "hold"]
                    args: ["object"]

My question is if i could add my own do to that after sylius hold inventory from my own bundle. I need that sylius still do its job, but i need to do some things... is this possible?

Disabling callbacks based on Expression language

Hello,

Right now we can disable a callback via enabled: false.
Wouldn't be awesome if we could put Expressions using the ExpressionEngine instead of a boolean ?

Use case: feature flags
This way we could enable/disable callbacks with business logic instead of adding the logic itself inside the callback code wenever possible.

callbacks:
    my_callback:
        ...
        enabled: "object.getSettings().hasFeature('email_enabled')"

Symfony 5 support

One of the last pull requests apparently made the bundle compatible with Symfony 5.

Would it be possible to officially check if the bundle is compatible, and if so tag a version with an amended composer.json to allow Symfony 5?

Thanks!

Add php8.1 enum support

Hi there,

It would be nice if the bundle could be compatible with the new php enum:

https://www.php.net/manual/fr/language.enumerations.basics.php

Here's some sample with the current doc:

<?php

namespace App\Enum;

enum ArticleStates: string
{
      case NewArticle = 'new';
      case PendingReview = 'pending_review';
      //...
}
<?php

namespace App\Entity;

use  App\Enum\ArticleStates;

class Article
{
     /** @var ArticleStates */
     private $state;
     //...

   public function getState() : ArticleStates
   {
         return $this->state;
   }

  public function setState(ArticleStates $state) : self
  {
     $this->state = $state;
      return $this;
  } 
  //...
}

Declaration of ContainerAwareCallbackFactory::get must be compatible with CallbackFactory::get(): CallbackInterface

Hi

I have next bundle version at my composer.lock:

{
            "name": "winzou/state-machine-bundle",
            "version": "v0.3.1",
...
            "require": {
...
                "winzou/state-machine": "~0.3"
            },
}

After doing composer update

  - Updating winzou/state-machine (0.3.3 => 0.4.0): Downloading (100%)         

I see

In ContainerAwareCallbackFactory.php line 35:
                                                                               
  Compile Error: Declaration of winzou\Bundle\StateMachineBundle\Callback\Con  
  tainerAwareCallbackFactory::get(array $specs) must be compatible with SM\Ca  
  llback\CallbackFactory::get(array $specs): SM\Callback\CallbackInterface 

I guess winzou/state-machine-bundle:v0.3.2 and winzou/state-machine-bundle:v0.4.3 should contain something like this (0.4.0+ excluded):

            "require": {
...
                "winzou/state-machine": "^0.3"
            },

rather than ~0.3

Define controller as service

I have method "UpdateStateToPaymentProgress" inside controller

public function UpdateStateToPaymentProgress(Cart $cart, $state)
    {
        $dm = $this->getDocumentManager();
        $cart->setState($state);
        $dm->persist($cart);
        $dm->flush();
    }

This is my config file

(...)
transitions:
            create:
                from: [new]
                to: created
            payment:
                from: [created]
                to:   progressPayment
(...)
callbacks:
            # will be called after applying a transition            
            after:
                progress_pay_cart:
                    on:   'payment'
                    do:   [@application.cart.checkout, 'UpdateStateToPaymentProgress']
                    args: ['object', '"progressPayment"']

i define controller as service in service.yml

services:
    application.cart.checkout:
        class:     Application\CartBundle\Controller\CheckoutController 

the problem is when i call method $cartSM->apply('payment') , the entity dont change state, and the bundle dnt call method of controller.

I have followed instructions (require + AppKernel bundle activation) but it does not work....

FileLoaderLoadException: Cannot import resource "/var/www/app/src/App/MainBundle/DependencyInjection/../Resources/config/maquina-estado-ticket.yml" from "/var/www/app/src/App/MainBundle/DependencyInjection/../Resources/config/services.yml". (There is no extension able to load the configuration for "winzou_state_machine" (in /var/www/app/src/App/MainBundle/DependencyInjection/../Resources/config/maquina-estado-ticket.yml). Looked for namespace "winzou_state_machine", found none)

thx in advance

support request - help.what does @sm.callback.cascade_transition do?

I use sylius.

winzou_state_machine:
    sylius_order_checkout:
        class: "%sylius.model.order.class%"
        property_path: checkoutState
        graph: sylius_order_checkout
        state_machine_class: "%sylius.state_machine.class%"
        states:
            cart: ~
            addressed: ~
            shipping_selected: ~
            payment_selected: ~
            completed: ~
        transitions:
            address:
                from: [cart]
                to: addressed
            readdress:
                from: [payment_selected, shipping_selected, addressed]
                to: cart
            select_shipping:
                from: [addressed]
                to: shipping_selected
            reselect_shipping:
                from: [payment_selected, shipping_selected]
                to: addressed
            select_payment:
                from: [shipping_selected]
                to: payment_selected
            reselect_payment:
                from: [payment_selected]
                to: shipping_selected
            complete:
                from: [payment_selected]
                to: completed
        callbacks:
            after:
                sylius_process_cart:
                    on: ["address", "select_shipping"]
                    do: ["@sylius.order_processing.order_processor", "process"]
                    args: ["object"]
                sylius_recalculate_cart:
                    on: ["address", "readdress", "select_shipping", "reselect_shipping", "select_payment", "reselect_payment"]
                    do: ["@sylius.order_processing.order_recalculator", "recalculate"]
                    args: ["object"]
                sylius_create_order:
                    on: ["complete"]
                    do: ["@sm.callback.cascade_transition", "apply"]
                    args: ["object", "event", "'create'", "'sylius_order'"]
                sylius_create_payment:
                    on: ["complete"]
                    do: ["@sm.callback.cascade_transition", "apply"]
                    args: ["object.getPayments()", "event", "'create'", "'sylius_payment'"]
                sylius_request_shipping:
                    on: ["complete"]
                    do: ["@sm.callback.cascade_transition", "apply"]
                    args: ["object", "event", "'request_shipping'", "'sylius_order_shipping'"]

what is this @sm.callback.cascade_transition? i can't figure it out and its only one place in code

Integer constants states

Is it possible to use integer constants as states?

For example:

<?php

namespace My\Bundle\Entity;

class Article
{
    const STATE_NEW = 1;
    const STATE_PENDING_REVIEW = 2;
    const STATE_AWAITING_CHANGES = 3;
    // ...
}
winzou_state_machine:
    my_bundle_article:
        class: My\Bundle\Entity\Article
        property_path: state           
        graph: simple                  
        states:
            - My\Bundle\Entity\Article::STATE_NEW # ?
            - My\Bundle\Entity\Article::STATE_PENDING_REVIEW # ?
            - My\Bundle\Entity\Article::STATE_AWAITING_CHANGES # ?
            # ...

Tests

Will be you interested on add tests to the bundle? Phpunit works for you?

Thanks.

trigger a service on initial state (aka entitie creation)

Hello,

I'd like to trigger a service on the initial state (aka entity creation),

I know that I can do it without the state machine, with an event listener, but I feel like the whole point of the state machine is to not use classical event listener, so it seems odd to me to have to use them on this first stage.

How should I do in this use case ? use an event, or use this (awesome) tool in a way that I didn't imagined?

Thanks by advance,
Bruno (a huge fan of winzou and his awesome symfony MOOC on openclassroom)

Get next state

Hello, I don't know if this is possible, but would to know if is possible get the next state before apply the transition.

Extra arguments when using callbacks

hi,
i have a question on how to pass extra arguments when using callbacks, like i have the follow configuration:

callbacks:
    after:
         sylius_process_cart:
                    on: ["select_shipping", "address", "select_payment", "skip_shipping", "skip_payment"]
                    do: ["@sylius.order_processing.order_processor", "process"]
                    args: ["object"]

then, in the args field i want to add another args(is an object), pls tell me how can i finish this operation? thx.

Visual graph generation

Hello,

one thing i am always missing is something like a visual presentations of the states like this state diagram

Example

As i have some complex machines with 10+ states and therefore lots of transitions, this would help me to better understand and explain the machine to another person. Is there something which you evaluated? It could for example be used for automated document generation.

Here some sources as reference:

Here is an example based on your graph

digraph finite_state_machine {
    rankdir=LR;
    size="8,5"

    node [shape = doublecircle]; new;
    node [shape = point ]; qi

    node [shape = circle];
    qi -> new;
    new  -> pending_review [ label = "create" ];
    pending_rewiew  -> awaiting_changes  [ label = "ask for changes" ];
    pending_review -> accepted [ label = "approve" ];
    awaiting_changes -> pending_review [ label = "submit review" ];
    rejected -> accepted [ label = "approve" ];
    accepted -> published [label = "publish"]
    accepted -> awaiting_changes  [ label = "ask for changes" ];
}

dot -Tpng gv-file.gv -o myFiniteStateMachine.png


myfinitestatemachine

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.