sebdesign/laravel-state-machine

add properties to states

himan72 opened this issue ยท 22 comments

Hi
if we can add a properties array to states so we can add extra data ( displa_name, css_classe ...)

How would you use this extra data? Could you give me some example?

Hi something like this

//...
'graph' => [
        //...
        'states' => [
            [
            	'new', 
            	'options' => [
            		'initial' => true,
            		'display_name' => 'New', 
            		'css_class' => ['primary']
            	]
            ],
            [
            	'draft', 
            	'options' => [
            		'initial' => false,
            		'display_name' => 'Draft', 
            		'css_class' => ['info']
            	]
            ],
            
        ],
        'transitions' => [
            'accept_for_review' => [
                'from' => ['new'],
                'to' => 'accepted',
                'options' =>[
                    'css' => [
                        'class' => 'primary',
                        'color' => '#e1e1e1'
                    ],
                    'display_name' => 'accept_for_review',
                ],
            ],
        ]
        //...
    ]

What should the state machine do with these options?
Can you give me an example of how these options are used in the application?

those options will be used on the frontend to display the states of an article

<span class="badge {{ $article->state_options['css_class']}}">{{ $article->state_options['display_name']}}</span>

I did something similar in a project where I needed some options/metadata. I will come up with a solution and let you know as soon as possible!

excellent thanks a lot for your support

Hi @himan72 ,

I have implement a feature to set and get metadata for state machine graphs, states and transitions.
You can find the code on the metadata branch. To install it on your project you must require the dev-metadata version in your composer.json. I haven't released it yet because I want to get some feedback from you.

Here is the documentation on how to use it:
https://github.com/sebdesign/laravel-state-machine/tree/metadata#metadata

In your case the config would be like this: (note that you need to specify the state name in a 'name' key)

'graph' => [
        //...
        'states' => [
            [
            	'name' => 'new', 
            	'metadata' => [
            		'initial' => true,
            		'display_name' => 'New', 
            		'css_class' => 'primary',
            	]
            ],
            [
            	'name' => 'draft', 
            	'metadata' => [
            		'initial' => false,
            		'display_name' => 'Draft', 
            		'css_class' => 'info',
            	]
            ],
            
        ],
        'transitions' => [
            'accept_for_review' => [
                'from' => ['new'],
                'to' => 'accepted',
                'metadata' =>[
                    'css' => [
                        'class' => 'primary',
                        'color' => '#e1e1e1'
                    ],
                    'display_name' => 'accept_for_review',
                ],
            ],
        ]
        //...
    ]

And you would use it like this (you can get the metadata from the state machine of the $article, not from the $article itself, but you can create a helper method in your model if you want):

<span class="badge {{ $articleStateMachine->metadata('state', 'css_class') }}">
    {{ $articleStateMachine->metadata('state', 'display_name') }}
</span>

<button class="btn btn-{{ $articleStateMachine->metadata()->transition('accept_for_review', 'css.class') }}" style="color: {{ $articleStateMachine->metadata()->transition('accept_for_review', 'css.color') }};">
    {{ $articleStateMachine->metadata()->transition('accept_for_review', 'display_name') }}
</button>

Let me know your thoughts!

Hi @sebdesign ,
Awesome this the enhancement that i was looking for. It gives more flexibility to the state machine.
I will test it this WE and get back to you?
Thanks a lot for your support.

Hi @sebdesign .
What to do if there is multiple transition steps(multiple transition steps) to reach from one state to another .

Hi. @hemantachhami19 made a point: a state machine should only care/manage states and transitions between. All metadata and properties associated to a given state, I think it should be handled outside the SM.

At first, i thought this was a nice addition... but if there are multiple transition steps, you will end scratching your head trying to figure out wich transition set wich property.

I'm not following the problem here. I asked @hemantachhami19 for more information in #17, but there is no answer yet. What are multiple transition steps? As far as I know, a transition can have multiple from states but only one to state.

Regarding this PR, a state can have its own metadata, while a transition can have it's own metadata.

Could you give me an example of the problem you're trying to solve? @damarev

Thanks!

Not really trying to solve a problem, just thought that data and/or properties related to a particular state, should be managed (getted or setted) outside the SM, via singleton class, config file, translation file... seems like more flexible and "neat".

Just thoughts... really not against that the metadata branch should be merged. Thank you for your work!

@damarev that was my initial thought, but since we already have a config file, it seems to be the right place to implement this.

But if someone has different needs, they can develop their own MetadataStoreInterface implementation and use it with dependency injection. The metadata store is not really coupled to the configuration, so you can use your own singleton/service/translation file, etc.

The inspiration for this feature came from Symfony Workflow (also see symfony/symfony#26092).

@sebdesign Do you have any plans to add this feature in the master branch? I couldn't install your dev-metadata branch in Laravel v5.8 projects.

Thank you for your awesome work.

Hi @ddevdreamer ,

Today I will update the metadata branch to support Laravel 5.8.
Thanks for reporting this!

@sebdesign I've created a pull request #19 if it would save you some time. Thank you.

@ddevdreamer I have added support for Laravel 5.8 on the metadata branch. Thanks for your PR though.

Let me know how it goes. Cheers!

@sebdesign It is working perfect. Thank you so much.

Great! If everyone is happy about this, I can release it in v1.4.0.

@sebdesign Any plans on this? Just checking. Thank you.

Great! If everyone is happy about this, I can release it in v1.4.0.

@divan-mt I will release it today!

Hi everybody,

v1.4.0 has been release, with support for metadata. For those who were using the metadata branch in their composer.json, please update your dependencies to ^1.4.

Let me know if there anything else!