WEBVTT

NOTE Created by CaptionSync from Automatic Sync Technologies www.automaticsync.com

00:00:00.036 --> 00:00:07.636 align:middle
So excellent, excellent.

00:00:08.736 --> 00:00:10.126 align:middle
Thank you all for being here.

00:00:10.896 --> 00:00:14.576 align:middle
Um, do you know this is a
large conference and you know,

00:00:14.576 --> 00:00:16.446 align:middle
when you're organizing a
large conference like this,

00:00:16.506 --> 00:00:18.756 align:middle
you do want to have the best speakers, right?

00:00:19.576 --> 00:00:22.166 align:middle
So, and what do you usually do
when you're having a conference?

00:00:22.166 --> 00:00:26.806 align:middle
You put the best speakers upfront, like the
keynote is obviously the most impressive one

00:00:26.806 --> 00:00:30.196 align:middle
and then you have the best speakers
and then they slowly decline.

00:00:31.776 --> 00:00:36.986 align:middle
Um, as you know, Michelle is not here,
Michelle was about to do this talk so

00:00:36.986 --> 00:00:41.926 align:middle
and her kid got sick and you can't really leave
a two year old home in Switzerland by itself.

00:00:41.956 --> 00:00:42.886 align:middle
So she had to stay home.

00:00:43.006 --> 00:00:45.956 align:middle
So the conference organizers
thought, Hey, what should we do?

00:00:46.126 --> 00:00:46.736 align:middle
Michelle is sick.

00:00:46.736 --> 00:00:48.936 align:middle
So obviously they did the best thing they could.

00:00:48.936 --> 00:00:51.066 align:middle
They call the second best speaker, right?

00:00:53.286 --> 00:00:56.456 align:middle
Unfortunately that person couldn't make it.

00:00:57.516 --> 00:01:01.846 align:middle
So they called the most knowledgeable speaker
who knows the Workflow component the best,

00:01:02.706 --> 00:01:04.476 align:middle
and that person didn't make it either.

00:01:05.346 --> 00:01:09.166 align:middle
Um, however, like five or six calls
down the line, they find my name

00:01:09.486 --> 00:01:12.666 align:middle
and here I am and I hope I can give you.

00:01:12.916 --> 00:01:13.826 align:middle
Yeah, thank you.

00:01:18.146 --> 00:01:20.356 align:middle
At least one guy or girl is very polite.

00:01:20.356 --> 00:01:26.776 align:middle
I hope I could give you like a, a
talk that could match Michelle's talk.

00:01:27.876 --> 00:01:36.576 align:middle
So with uh, with that said, my talk is titled
Knowing Your State Machines and I would

00:01:36.576 --> 00:01:40.506 align:middle
like to do this talk because I
believe web developers only care

00:01:40.506 --> 00:01:43.056 align:middle
about printing out HTML as quick as possible.

00:01:43.416 --> 00:01:47.176 align:middle
They don't care about fancy algorithms,
they don't care about design patterns.

00:01:47.506 --> 00:01:49.306 align:middle
They just want to print stuff
really, really quick.

00:01:50.326 --> 00:01:53.776 align:middle
And so I want to tell you about something that
makes your code a little bit more elegant.

00:01:54.936 --> 00:01:58.236 align:middle
So I didn't, I didn't bring any state machines.

00:01:58.886 --> 00:02:00.556 align:middle
It's nothing I can have in my pocket.

00:02:01.506 --> 00:02:06.616 align:middle
It's a state machine is just something
that hold states, like any states.

00:02:07.316 --> 00:02:11.566 align:middle
It could be the state of a pull
request or this small washer

00:02:11.566 --> 00:02:13.396 align:middle
on your - small lights on your washer.

00:02:14.056 --> 00:02:16.206 align:middle
It could be, yeah, it could be anything.

00:02:16.206 --> 00:02:19.966 align:middle
So it's basically a way of thinking,
a way to relate to problems.

00:02:21.246 --> 00:02:22.746 align:middle
And why state machines?

00:02:22.746 --> 00:02:23.166 align:middle
Blah Blah.

00:02:23.166 --> 00:02:24.156 align:middle
There's a lot of texts in this.

00:02:24.156 --> 00:02:27.916 align:middle
If you work at a company where your
manager needs convincing, this is a slide -

00:02:27.916 --> 00:02:29.556 align:middle
just to take a photo or show him later.

00:02:30.386 --> 00:02:33.576 align:middle
I'm sorry, show him or her later.

00:02:35.256 --> 00:02:36.046 align:middle
Quick about me.

00:02:36.086 --> 00:02:38.296 align:middle
I do plenty of work on Happyr.

00:02:38.296 --> 00:02:41.726 align:middle
We are a job advert platform - it matches
people with confidence, blah blah.

00:02:41.806 --> 00:02:43.426 align:middle
I do plenty of Symfony things.

00:02:43.536 --> 00:02:47.866 align:middle
I run PHP meetups in Stockholm
and I do plenty of open source.

00:02:48.636 --> 00:02:55.576 align:middle
I started my real open source career in
2015 on a SymfonyCon, just like this one.

00:02:55.846 --> 00:02:57.726 align:middle
The PSR-6 cache had just came out.

00:02:58.076 --> 00:03:00.626 align:middle
So me and my friends were like,
hey, why don't we implement this.

00:03:01.006 --> 00:03:03.146 align:middle
Why don't we make an implementation of PSR-6.

00:03:03.426 --> 00:03:04.466 align:middle
So we did.

00:03:04.756 --> 00:03:09.246 align:middle
We created the PHP-cache organization and
CacheBundle and I thought open source is great.

00:03:09.576 --> 00:03:14.476 align:middle
So I started to get involved with
HTTPPlug, which is kind of an abstraction

00:03:14.476 --> 00:03:20.136 align:middle
over HTTP clients and when you do HTTP clients,
you do API clients and then you do mail clients.

00:03:20.626 --> 00:03:23.806 align:middle
And I even wrote like, Oh, this
is how you should do API clients,

00:03:23.806 --> 00:03:25.366 align:middle
this is the boilerplate for FIG.

00:03:25.866 --> 00:03:28.906 align:middle
And currently I'm maintaining
both Guzzle and Buzz.

00:03:29.116 --> 00:03:33.076 align:middle
I've written my PSR-7, I've
written PSR standards and stuff.

00:03:33.076 --> 00:03:34.506 align:middle
I, I do plenty of things.

00:03:36.026 --> 00:03:41.236 align:middle
The most interesting library here, which
I like the most is this one, the NSA one.

00:03:42.296 --> 00:03:48.606 align:middle
With NSA, you can totally violate class
privacy: accessing private properties

00:03:48.656 --> 00:03:54.456 align:middle
or methods is super easy with NSA, I do also
contribute to a bunch of other libraries:

00:03:55.116 --> 00:03:56.286 align:middle
these are only the most fun ones.

00:03:56.936 --> 00:04:00.656 align:middle
So how should we do this about state machine?

00:04:00.656 --> 00:04:02.586 align:middle
How should we do this?

00:04:02.736 --> 00:04:08.016 align:middle
I would like to start with a lot of theory
and then l will put on some examples,

00:04:08.016 --> 00:04:09.406 align:middle
examples, and then more examples.

00:04:10.106 --> 00:04:14.126 align:middle
How does that sound?

00:04:14.566 --> 00:04:14.886 align:middle
Excellent.

00:04:14.886 --> 00:04:17.546 align:middle
Because I've got slides for this.

00:04:17.716 --> 00:04:22.996 align:middle
How I can barely see you, but how
many of you, how many of you feel

00:04:22.996 --> 00:04:24.566 align:middle
like you know, state machines by heart?

00:04:27.336 --> 00:04:27.846 align:middle
Excellent.

00:04:27.846 --> 00:04:31.466 align:middle
It's like 12 of you, which, which is excellent.

00:04:32.716 --> 00:04:35.496 align:middle
Then I guess like the rest
of you will learn plenty.

00:04:36.586 --> 00:04:38.226 align:middle
You are.. anyhow, let's get started.

00:04:38.226 --> 00:04:40.666 align:middle
Let's get: first rule of state machines.

00:04:40.736 --> 00:04:43.886 align:middle
We've got to talk about the graph theory
and the first rule of graph theory is

00:04:43.886 --> 00:04:48.966 align:middle
like these, these are not graphs.

00:04:49.106 --> 00:04:52.536 align:middle
These are charts, these are diagrams,
these are call them whatever.

00:04:52.746 --> 00:04:54.036 align:middle
They are not graphs.

00:04:54.726 --> 00:04:59.186 align:middle
A graph. It looks like this.

00:04:59.726 --> 00:05:00.966 align:middle
A graph has a node.

00:05:02.086 --> 00:05:07.326 align:middle
A more interesting graph got two nodes,
and nodes can be connected with edges

00:05:08.236 --> 00:05:12.746 align:middle
and edges can either be undirected
like this one or it can be directed.

00:05:13.356 --> 00:05:19.456 align:middle
An edge can also have a weight.

00:05:19.606 --> 00:05:21.626 align:middle
Does this seem familiar for most of you?

00:05:22.996 --> 00:05:23.506 align:middle
Excellent.

00:05:23.846 --> 00:05:24.206 align:middle
Excellent.

00:05:24.996 --> 00:05:30.406 align:middle
This is a full-fledged graph.

00:05:30.756 --> 00:05:32.836 align:middle
This is like the cool graphs can be.

00:05:33.446 --> 00:05:37.436 align:middle
And it can represent pretty much
whatever thing you like it to represent.

00:05:38.256 --> 00:05:44.086 align:middle
If you slap on some numbers on here
and maybe you can have a problem,

00:05:44.186 --> 00:05:47.946 align:middle
maybe this represents cities
and roads between them.

00:05:48.186 --> 00:05:53.556 align:middle
Maybe it represents computers in the
network, maybe, maybe they represent people

00:05:53.556 --> 00:05:54.906 align:middle
and how well they know each other.

00:05:54.906 --> 00:05:59.316 align:middle
And say we've got a graph like
this and you wonder how much....

00:05:59.316 --> 00:06:01.746 align:middle
say they are computers in the network.

00:06:02.176 --> 00:06:04.286 align:middle
How much data can you transfer from a to b?

00:06:05.236 --> 00:06:08.646 align:middle
This might be a problem you're having,

00:06:08.646 --> 00:06:13.166 align:middle
so this is called the maximum flow
problem and there is a solution to this.

00:06:13.476 --> 00:06:17.076 align:middle
And say that you want to find
the shorter distance between a

00:06:17.226 --> 00:06:21.376 align:middle
and b. You can solve this this by
Birpartite breadth-first search.

00:06:22.216 --> 00:06:24.026 align:middle
And say that you want to...

00:06:24.906 --> 00:06:31.186 align:middle
Say that you want to find out what's the
cheapest way of visiting all these cities,

00:06:31.416 --> 00:06:34.776 align:middle
or these nodes, visiting only every node once.

00:06:35.126 --> 00:06:38.176 align:middle
That's a traveling salesman problem and
there is a solution to that as well.

00:06:38.866 --> 00:06:43.236 align:middle
Or say that these are cities and you should
put out some electricity grid between them.

00:06:43.236 --> 00:06:47.416 align:middle
This is the minimum spanning tree problem
and there's a solution for that as well.

00:06:47.416 --> 00:06:52.566 align:middle
What I want to tell you is if you've got
a problem, if you can express this problem

00:06:52.566 --> 00:06:56.576 align:middle
as a graph problem, there's
already a solution to it.

00:06:56.576 --> 00:06:58.826 align:middle
So you don't, you don't really have
to solve these problems yourself,

00:06:58.826 --> 00:07:01.916 align:middle
you can just solve the problem getting
your problem to a graph problem.

00:07:02.736 --> 00:07:03.276 align:middle
Does it make sense?

00:07:04.616 --> 00:07:05.166 align:middle
Thank you.

00:07:05.526 --> 00:07:12.526 align:middle
This, what I just did, I gave you like
six months of university math of graphs.

00:07:12.896 --> 00:07:16.566 align:middle
So this is basically the big graph theory
I just gave you a quick introduction of.

00:07:17.516 --> 00:07:21.156 align:middle
A cool thing about graphs
is that you can reduce them.

00:07:22.436 --> 00:07:23.516 align:middle
Say, consider this graph.

00:07:23.946 --> 00:07:27.686 align:middle
I want to reduce them by giving them a new rule.

00:07:28.066 --> 00:07:33.926 align:middle
And say, the rule might be:
let's remove all the loops.

00:07:34.726 --> 00:07:39.356 align:middle
If I remove all the loops
in this graph, I get a tree.

00:07:40.386 --> 00:07:43.286 align:middle
And there's plenty of algorithms
you can do in trees as well.

00:07:43.736 --> 00:07:47.786 align:middle
One of the most difficult to implement
is the red then black search tree,

00:07:48.406 --> 00:07:50.946 align:middle
which basically is good way to store
things if you want to search quickly in it.

00:07:51.536 --> 00:07:53.156 align:middle
Anyhow, I want to show you this.

00:07:53.156 --> 00:07:59.006 align:middle
You have the big graph theory and inside
of it you have the theory of a tree.

00:08:00.006 --> 00:08:02.466 align:middle
And you can continue reducing
graphs with different set

00:08:02.466 --> 00:08:05.606 align:middle
of rules and you will get a workflow.

00:08:07.926 --> 00:08:15.416 align:middle
A workflow also has nodes, but sorry, but we
decided, oh also has nodes and it also has edges

00:08:15.416 --> 00:08:18.436 align:middle
and we decided that every
edge should be directed.

00:08:18.816 --> 00:08:22.186 align:middle
We also decided that we call the
nodes places and transitions.

00:08:23.446 --> 00:08:28.376 align:middle
And a rule in this workflow is them saying: a
place can never be connected to another place.

00:08:28.606 --> 00:08:32.386 align:middle
All of this has to be a transition between them.

00:08:32.386 --> 00:08:38.686 align:middle
I know I'm shooting a lot of rules at you
now, but do you kind of feel comfortable?

00:08:39.436 --> 00:08:40.056 align:middle
Excellent.

00:08:40.056 --> 00:08:44.386 align:middle
And we decided, I mean just so it's easy to
see, we draw these transitions like a square

00:08:45.346 --> 00:08:51.616 align:middle
and a good example of a workflow is this: if
I'm in place A and execute the transition t0,

00:08:51.616 --> 00:08:58.976 align:middle
I'll get to place C. If I'm in place
B and they execute the transition t1,

00:08:58.976 --> 00:09:04.346 align:middle
I get to place C and D. Make sense?

00:09:06.616 --> 00:09:14.616 align:middle
Good. If we continue to reduce this
workflow, say we want to add rules saying

00:09:15.026 --> 00:09:22.146 align:middle
that a transition could only have one input and
one output and also the names has to be unique.

00:09:23.556 --> 00:09:28.596 align:middle
Then we actually get a state machine
that looks something like this.

00:09:28.766 --> 00:09:33.116 align:middle
So workflow multiple one
input, multiple outputs.

00:09:33.556 --> 00:09:36.776 align:middle
A state machine only can have one input
and one output, something like this.

00:09:37.046 --> 00:09:43.936 align:middle
So if execute t1, if you are in
B and execute t1 you get to D.

00:09:44.116 --> 00:09:48.146 align:middle
And because I'm drawing these images by hand,
I will choose to draw with this annotation.

00:09:50.106 --> 00:09:56.906 align:middle
Fair? So right now I have been talking for eight
minutes and we discussed the big graph theory

00:09:57.416 --> 00:10:01.656 align:middle
and we discussed the tree and
we discussed what a workflow is

00:10:01.656 --> 00:10:04.306 align:middle
and that a state machine
is just a reduced workflow.

00:10:04.306 --> 00:10:08.046 align:middle
So let's start with some examples.

00:10:08.376 --> 00:10:11.866 align:middle
I mean I know this part was the boring
part, this part was the theory part.

00:10:11.866 --> 00:10:14.456 align:middle
Let's start with some examples
of recognize that we recognize.

00:10:15.046 --> 00:10:17.656 align:middle
This is a simple state machine.

00:10:18.776 --> 00:10:24.856 align:middle
We defined three states and we defined
how we can move between the states, right?

00:10:24.966 --> 00:10:28.466 align:middle
So it's easy to see that if you are
in green we can easily move to yellow

00:10:28.466 --> 00:10:29.636 align:middle
and then we can easily move to read.

00:10:30.456 --> 00:10:33.886 align:middle
However though if we are in
green, we cannot move to red.

00:10:34.436 --> 00:10:35.446 align:middle
There's no arrow to red.

00:10:35.446 --> 00:10:40.046 align:middle
It's impossible to go direct to
red, which is which is a good thing.

00:10:40.556 --> 00:10:46.496 align:middle
I've got to keep asking you simple questions
until you give me some continuous feedback.

00:10:46.816 --> 00:10:48.026 align:middle
Do you understand this?

00:10:48.786 --> 00:10:56.126 align:middle
I work at a company called Happyr and
we deal with a lot of job adverts.

00:10:56.126 --> 00:11:00.016 align:middle
Basically we put up adverts and we match people
and people in common with soft skills, etc,

00:11:00.016 --> 00:11:02.046 align:middle
etc. Anyhow, we have a lot of job adverts.

00:11:02.426 --> 00:11:08.366 align:middle
So in a business meeting we decided like this,
this is the state machine for a job advert.

00:11:08.726 --> 00:11:12.606 align:middle
So we started draft and then
we can send it to review.

00:11:13.096 --> 00:11:15.466 align:middle
While in review, we can trash it, untrash it,

00:11:15.466 --> 00:11:17.536 align:middle
and we can send it to review
again if you'd like.

00:11:17.536 --> 00:11:19.266 align:middle
And from review you can publish and archive it.

00:11:19.806 --> 00:11:25.796 align:middle
It is impossible to archive something that is
in review or that is something that's in trash.

00:11:26.216 --> 00:11:27.006 align:middle
It's impossible.

00:11:30.096 --> 00:11:30.626 align:middle
Excellent.

00:11:31.316 --> 00:11:35.026 align:middle
Since you are very confident
now, what is this a workflow of?

00:11:40.796 --> 00:11:46.386 align:middle
Someone said a pull request issue.

00:11:46.686 --> 00:11:47.746 align:middle
Uh, I will say yes.

00:11:47.886 --> 00:11:51.646 align:middle
Correct. So basically you
start coding your pull request,

00:11:52.066 --> 00:11:54.476 align:middle
you submit it to Travis, Travis runs for awhile.

00:11:54.656 --> 00:11:58.166 align:middle
You may want to decide when
you're waiting for review

00:11:58.166 --> 00:12:00.216 align:middle
and then you may want to decide to update it.

00:12:00.216 --> 00:12:01.776 align:middle
So we'll go back to Travis running.

00:12:02.246 --> 00:12:04.476 align:middle
And maybe someone says, hey,
we need some changes.

00:12:04.796 --> 00:12:08.116 align:middle
So you go back to coding, then you
update it, then send it to review

00:12:08.116 --> 00:12:13.486 align:middle
and hopefully it gets merged or else it
could be rejected and re-opened again.

00:12:14.766 --> 00:12:16.056 align:middle
Seem straightforward?

00:12:16.806 --> 00:12:17.726 align:middle
So how about this?

00:12:18.086 --> 00:12:19.626 align:middle
Oh yeah, pull request.

00:12:19.626 --> 00:12:20.246 align:middle
So how about this?

00:12:20.566 --> 00:12:24.306 align:middle
What is it the workflow of?

00:12:27.056 --> 00:12:28.826 align:middle
What is the state machine of?

00:12:34.496 --> 00:12:37.966 align:middle
People usually yell out like,
like you, sorry, like you did.

00:12:38.136 --> 00:12:38.786 align:middle
You said doors.

00:12:38.886 --> 00:12:41.126 align:middle
I'm like no, no, not doors, it's elevator doors.

00:12:41.316 --> 00:12:42.976 align:middle
But you're equally correct.

00:12:43.056 --> 00:12:43.656 align:middle
It's doors.

00:12:44.156 --> 00:12:46.806 align:middle
So basically this is the four states
that a set of doors can be in.

00:12:46.866 --> 00:12:51.446 align:middle
Either the doors can be opened and then you
press the close button and then be closing.

00:12:51.866 --> 00:12:54.996 align:middle
While the closing we can press
open button so they go to opening.

00:12:55.356 --> 00:12:59.826 align:middle
It's impossible for doors to be open and
then in one, the next instance be closed.

00:12:59.876 --> 00:13:01.536 align:middle
They have to be closing, right?

00:13:02.816 --> 00:13:07.386 align:middle
I think. I think we kind of
know, know state machines now.

00:13:08.446 --> 00:13:10.076 align:middle
Maybe business a dictates that...

00:13:10.406 --> 00:13:14.616 align:middle
Maybe business a business dictates
that you should have a form like this,

00:13:15.116 --> 00:13:16.566 align:middle
like maybe a sign up form or whatever.

00:13:16.906 --> 00:13:21.176 align:middle
So you can have a state machine to
know where the user is in the form.

00:13:21.326 --> 00:13:26.266 align:middle
So if you leave this process, you can, you can
get back to where where he or she left off.

00:13:27.036 --> 00:13:31.376 align:middle
And if your extra nice you can have back buttons
so we can travel back and forth in this process.

00:13:32.036 --> 00:13:37.506 align:middle
If you want to implement this,
there's basically two implementations.

00:13:38.716 --> 00:13:40.626 align:middle
I'm gonna can talk to them with them bot.

00:13:40.706 --> 00:13:42.086 align:middle
No, I'm not going to talk with them.

00:13:42.086 --> 00:13:44.986 align:middle
I'm gonna talk with you about the
both of them - the implementations.

00:13:45.716 --> 00:13:50.256 align:middle
The first implementation is the state pattern
and that's using the Moore state machine.

00:13:51.136 --> 00:13:54.636 align:middle
And a Moore state machine only
cares about the current state.

00:13:55.476 --> 00:14:00.546 align:middle
The next state only cares about, the next
state is defined by the current state.

00:14:01.196 --> 00:14:05.186 align:middle
The other state machine is the Mealy
state machine and the next state depends

00:14:05.186 --> 00:14:06.996 align:middle
on the current state and some input.

00:14:06.996 --> 00:14:12.466 align:middle
I just want to say this out loud now
and then I'm gonna repeat it later.

00:14:12.746 --> 00:14:15.246 align:middle
Let's start with the state pattern
and the Moore state machine.

00:14:16.686 --> 00:14:20.986 align:middle
This is basically what you
easily read on wikipedia.

00:14:20.986 --> 00:14:22.276 align:middle
You... a state.

00:14:22.276 --> 00:14:24.006 align:middle
I'll click this.

00:14:24.536 --> 00:14:28.006 align:middle
Say you want to implement, something like this.

00:14:28.006 --> 00:14:29.616 align:middle
We want to implement a...

00:14:29.686 --> 00:14:33.876 align:middle
something that reminds you to complete your
profile, say a user signs up and you want to say

00:14:33.876 --> 00:14:37.286 align:middle
like "Hey, you should add your name" and we
remind them twice about adding their name.

00:14:37.656 --> 00:14:39.496 align:middle
If in order to add your name, like we should,

00:14:39.496 --> 00:14:42.306 align:middle
hey you should update your image
or you should add your resume.

00:14:43.276 --> 00:14:50.676 align:middle
So implementing this with a state pattern means
that each of these five states have a class

00:14:51.196 --> 00:14:53.546 align:middle
and that class itself only have one f unction.

00:14:53.866 --> 00:14:54.856 align:middle
It has a Send function.

00:14:55.566 --> 00:15:02.146 align:middle
And, and that calls itself decides
what to do and where to go next.

00:15:03.596 --> 00:15:04.026 align:middle
Makes sense?

00:15:04.856 --> 00:15:10.196 align:middle
So the idea here is that we have, have, we
have a worker like a cron job saying like: Hey,

00:15:10.196 --> 00:15:13.226 align:middle
give me all the state machine from
database somehow and start yourself.

00:15:13.546 --> 00:15:18.086 align:middle
I don't really care what you're doing - you
just send the email, send the correct emails.

00:15:20.656 --> 00:15:28.146 align:middle
So in the implementing this, I'm basically
looping over all the states and if the,

00:15:28.356 --> 00:15:30.736 align:middle
if the state machine says
"I'm done", then we're done.

00:15:31.136 --> 00:15:34.586 align:middle
So any given state just looks
something like this.

00:15:34.656 --> 00:15:40.066 align:middle
I, this is, I mean, you send an email
and then I say go to next state.

00:15:41.616 --> 00:15:42.046 align:middle
Makes sense?

00:15:42.736 --> 00:15:46.236 align:middle
We should obviously do a little,
we should modify this a little bit.

00:15:46.276 --> 00:15:49.546 align:middle
We can maybe say like, if
the user doesn't have a name,

00:15:50.026 --> 00:15:53.186 align:middle
if the user do have a name,
go to add your image state.

00:15:53.876 --> 00:15:56.926 align:middle
So the state itself says where to go next.

00:15:57.226 --> 00:16:00.216 align:middle
The sates itself decides everything what to do.

00:16:00.776 --> 00:16:03.846 align:middle
And the state is a single class.

00:16:08.346 --> 00:16:11.036 align:middle
We should also be a little bit more friendly.

00:16:11.386 --> 00:16:16.286 align:middle
This would actually flood the user's
email address, so uh, email inbox.

00:16:16.346 --> 00:16:21.626 align:middle
So we should: you should be in this state for
at least seven days until we send another email.

00:16:24.726 --> 00:16:27.516 align:middle
I know this might feel weird.

00:16:28.266 --> 00:16:30.746 align:middle
I know this might feel like
that's not really PHP.

00:16:31.576 --> 00:16:34.066 align:middle
It feels more like Java or something else.

00:16:34.416 --> 00:16:36.656 align:middle
It feels weird and I will agree with you.

00:16:38.036 --> 00:16:38.946 align:middle
This feels a bit weird.

00:16:40.036 --> 00:16:43.516 align:middle
Using this and, for the simple state
machine I showed you the five states,

00:16:43.596 --> 00:16:45.366 align:middle
you have a bunch of classes like this.

00:16:45.766 --> 00:16:47.516 align:middle
And they all pretty much look the same.

00:16:47.856 --> 00:16:51.446 align:middle
Each of this state just look,
oh, they look like this.

00:16:52.956 --> 00:17:01.906 align:middle
So I... with this I would like you to get
an idea how the state pattern works and some

00:17:01.906 --> 00:17:03.336 align:middle
of you guys are nodding politely.

00:17:03.456 --> 00:17:04.076 align:middle
Excellent.

00:17:05.156 --> 00:17:06.486 align:middle
You obviously have issues with this.

00:17:06.486 --> 00:17:09.906 align:middle
I mean you have issues: how do you store
the state machines in this database?

00:17:10.246 --> 00:17:11.536 align:middle
How do you keep track of the state?

00:17:11.716 --> 00:17:13.696 align:middle
How do you store the createdAt entity...

00:17:14.186 --> 00:17:20.946 align:middle
or data. Also it feels kind of weird
that you have one class with state.

00:17:21.636 --> 00:17:24.596 align:middle
So let's, let's do something different.

00:17:25.096 --> 00:17:29.016 align:middle
Like now we know the Moore state
machine, we know the state pattern,

00:17:29.426 --> 00:17:30.926 align:middle
so let's look at something different.

00:17:30.996 --> 00:17:34.096 align:middle
Let's look at something that
feels more like PHP.

00:17:34.096 --> 00:17:40.236 align:middle
And I'm going to stress this multiple times:
the Mealy state machine, the next state depends

00:17:40.236 --> 00:17:42.866 align:middle
on the current state and some input.

00:17:44.236 --> 00:17:47.636 align:middle
So it's obviously a little bit more flexible.

00:17:48.236 --> 00:17:49.936 align:middle
Let's try.

00:17:49.936 --> 00:17:54.006 align:middle
Let's consider this state machine
again, you all know this by heart now.

00:17:54.306 --> 00:17:55.786 align:middle
If you would write an implementation of this,

00:17:55.896 --> 00:18:02.246 align:middle
if we like PHP developers would write an
implementation of this, how would we do?

00:18:02.496 --> 00:18:03.376 align:middle
Well, what's the first?

00:18:03.376 --> 00:18:04.686 align:middle
We obviously need a class, right?

00:18:04.736 --> 00:18:07.236 align:middle
We need a state machine -
traffic light state machine class.

00:18:08.036 --> 00:18:12.376 align:middle
And we kind of want to have a
function that applies new state.

00:18:13.856 --> 00:18:19.366 align:middle
And I imagine it to be good to have like
a function that "can I apply this state?"

00:18:24.936 --> 00:18:27.286 align:middle
Good. So let's.

00:18:27.876 --> 00:18:30.106 align:middle
So I create my state machine
looking something like this.

00:18:30.706 --> 00:18:37.966 align:middle
I define all my states as constants and I also
choose to have a private property called state.

00:18:38.946 --> 00:18:45.456 align:middle
And then I just, via a switch statement say: if
someone say: "Can I do transition to yellow?"

00:18:45.886 --> 00:18:50.266 align:middle
I check if I'm currently in state green
and someone says "can (I go) to yellow?"

00:18:50.566 --> 00:18:52.066 align:middle
Then sure, that's allowed.

00:18:52.816 --> 00:18:58.036 align:middle
If I'm in state red and someone says "to
green", then it's obviously no, I return false.

00:19:02.806 --> 00:19:04.846 align:middle
And I do a similar, very
similar thing for apply.

00:19:04.846 --> 00:19:14.716 align:middle
I just do something like this.

00:19:14.906 --> 00:19:16.136 align:middle
So would this state machine.

00:19:16.726 --> 00:19:20.226 align:middle
I can easily, I can easily implement my...

00:19:20.226 --> 00:19:23.926 align:middle
This, this class is easily implement
my traffic light state machine, right?

00:19:27.746 --> 00:19:31.566 align:middle
There's an issue though: this
state machine has a private state.

00:19:32.246 --> 00:19:34.676 align:middle
So I need to store the state
machine in the database somehow.

00:19:36.126 --> 00:19:38.176 align:middle
This state machine is only
for one traffic light.

00:19:38.666 --> 00:19:41.376 align:middle
If I have multiple traffic lights in my
system, I have to have multiple state machines

00:19:41.376 --> 00:19:44.526 align:middle
which each needs to be stored in the
database, because of the state property.

00:19:45.276 --> 00:19:48.186 align:middle
What if I made my state machines more stateless?

00:19:48.886 --> 00:19:54.736 align:middle
Like I removed the private state and put
that on the, on the traffic light entity?

00:19:55.226 --> 00:19:56.176 align:middle
So I did something like this.

00:19:56.656 --> 00:20:02.226 align:middle
Can this specific traffic
light do this transition?

00:20:02.226 --> 00:20:05.266 align:middle
So now I don't need to store the
state machine in the database anymore.

00:20:05.406 --> 00:20:08.646 align:middle
I can use this state machine
for all the traffic lights.

00:20:10.086 --> 00:20:13.196 align:middle
It feels quite, feels quite good, right?

00:20:13.476 --> 00:20:14.436 align:middle
Yes. It feels quite good.

00:20:15.706 --> 00:20:17.176 align:middle
I diddothe same thing with apply function.

00:20:17.316 --> 00:20:21.246 align:middle
I just say $trafficLight-&gt;getCurrentState()
and I have a $trafficLight-&gt;setState().

00:20:22.866 --> 00:20:24.626 align:middle
Very similar, very small changes.

00:20:24.996 --> 00:20:29.216 align:middle
And I feel pretty good about the state machine
at this point and whenever I'm using this,

00:20:29.456 --> 00:20:35.906 align:middle
it might be an idea of mine to have
a function that allows more traffic.

00:20:37.246 --> 00:20:42.696 align:middle
I mean if, if, if the state is currently in
the red state and I want to allow more traffic,

00:20:43.086 --> 00:20:47.086 align:middle
I just, whatever state they're currently
in, I just move it towards green.

00:20:47.346 --> 00:20:49.446 align:middle
So I might attempt to do something like this.

00:20:51.016 --> 00:20:53.746 align:middle
So I know if I call allow more traffic twice.

00:20:53.746 --> 00:21:01.706 align:middle
I will definitely be in green.

00:21:01.896 --> 00:21:03.486 align:middle
You look confused and you should.

00:21:03.966 --> 00:21:06.396 align:middle
Because this was like my
trickery, but I didn't trick you.

00:21:06.866 --> 00:21:09.646 align:middle
If I want to make this state
machine more generic, more reusable,

00:21:09.646 --> 00:21:11.356 align:middle
obviously this is a horrible idea.

00:21:12.396 --> 00:21:18.546 align:middle
Right? So if I'm going to make it more
reusable, I may want to consider instead

00:21:18.546 --> 00:21:22.086 align:middle
of having the states all over
the place, I may want to put them

00:21:22.086 --> 00:21:24.556 align:middle
in a, uh, in a property like this.

00:21:26.056 --> 00:21:32.636 align:middle
So with this weird array looking thing, it's
actually me trying to be a bit clever again.

00:21:33.066 --> 00:21:35.776 align:middle
So I can just say: can I do the transition?

00:21:36.096 --> 00:21:43.566 align:middle
I was checking if this is, if this
property is set, if this array key exists.

00:21:45.456 --> 00:21:48.146 align:middle
I do the same kind of wizardry in apply.

00:21:48.916 --> 00:21:55.266 align:middle
Do you feel confident with this?

00:21:55.476 --> 00:21:58.536 align:middle
You kind of understand it at least
that's, that's the most important thing.

00:21:59.576 --> 00:22:01.756 align:middle
However, say you want to
make this even more generic.

00:22:02.286 --> 00:22:04.396 align:middle
I mean, I shouldn't, I mean
this is only for traffic lights.

00:22:04.696 --> 00:22:05.626 align:middle
I said, traffic light here.

00:22:05.626 --> 00:22:07.046 align:middle
What if I do something different?

00:22:07.286 --> 00:22:07.676 align:middle
What if I...

00:22:09.376 --> 00:22:10.086 align:middle
Oh, sorry.

00:22:11.656 --> 00:22:13.636 align:middle
Oh, look, the states, it should be states here.

00:22:13.636 --> 00:22:19.746 align:middle
What if I inject the states
instead in a constructor like this?

00:22:20.146 --> 00:22:22.986 align:middle
Then I have those states -
I can do this for any kind

00:22:23.146 --> 00:22:24.776 align:middle
of state machine and any kind of traffic light.

00:22:24.916 --> 00:22:27.236 align:middle
And now, oh no, I have traffic lights over here.

00:22:27.426 --> 00:22:30.496 align:middle
What if I did something like this to
have the StateAwareInterface instead?

00:22:31.696 --> 00:22:35.866 align:middle
And this StateAwareInterface just have a
getCurrentState() and setState() method.

00:22:37.006 --> 00:22:39.776 align:middle
With this class of 15 lines.

00:22:40.246 --> 00:22:43.966 align:middle
This is actually a pretty good,
pretty generic state machine, right?

00:22:44.886 --> 00:22:48.796 align:middle
And it all feels (like) PHP, all in one
class and I can configure it however

00:22:48.796 --> 00:22:50.876 align:middle
like and use an object that I like.

00:22:51.526 --> 00:22:54.466 align:middle
I hope we feel like we understand this.

00:22:56.076 --> 00:22:56.816 align:middle
Does anyone have...

00:22:56.866 --> 00:22:58.786 align:middle
oh no, I can't ask you for issues.

00:22:58.786 --> 00:23:01.726 align:middle
Does everyone feel like you
understand this class?

00:23:02.776 --> 00:23:03.356 align:middle
Excellent.

00:23:03.526 --> 00:23:04.036 align:middle
Excellent.

00:23:04.926 --> 00:23:07.886 align:middle
I'll tell you a little bit of a secret.

00:23:07.886 --> 00:23:11.526 align:middle
This is actually how the
Workflow component works.

00:23:12.756 --> 00:23:14.816 align:middle
This is the workflow of the Workflow component.

00:23:15.776 --> 00:23:23.166 align:middle
And it was very true like two or three years
ago, this was exactly the Workflow component.

00:23:23.706 --> 00:23:30.696 align:middle
And nowadays there's a lot of edge cases,
but in principle it works exactly like this.

00:23:31.296 --> 00:23:34.766 align:middle
The Workflow component all have
some more functions we showed.

00:23:34.766 --> 00:23:37.636 align:middle
I showed an implementation of
"can we do the transition?"

00:23:37.636 --> 00:23:38.456 align:middle
And "apply transition".

00:23:38.526 --> 00:23:43.736 align:middle
The workflow component has two more methods
saying "like what state are we currently in?"

00:23:43.736 --> 00:23:45.656 align:middle
And what are my valid transitions?

00:23:46.276 --> 00:23:49.176 align:middle
So let's show some examples.

00:23:49.926 --> 00:23:51.586 align:middle
Same old job advert workflow again.

00:23:51.586 --> 00:23:56.046 align:middle
In the Workflow component, this
might look like something like this.

00:23:56.626 --> 00:24:02.876 align:middle
The red circle is the current state, so I can
say: give me the state machine for job adverts.

00:24:04.126 --> 00:24:09.196 align:middle
And I say give me the current marking
for this entity and give me the places.

00:24:10.516 --> 00:24:12.846 align:middle
And marking here sounds weird.

00:24:12.846 --> 00:24:18.526 align:middle
It's because it's basically the abstraction of
getting properties from the, from the Advert.

00:24:19.966 --> 00:24:22.436 align:middle
If you ignore that, it's,
this is very simple, right?

00:24:23.536 --> 00:24:26.766 align:middle
So I get an array back and I see I'm in Draft.

00:24:27.036 --> 00:24:31.496 align:middle
I can continue showing examples saying:
state machine, can I do publish?

00:24:32.426 --> 00:24:34.506 align:middle
No, I can't, but can I do "to review"?

00:24:35.326 --> 00:24:36.226 align:middle
Yes, that's true I can.

00:24:36.526 --> 00:24:37.546 align:middle
So I continue.

00:24:37.546 --> 00:24:43.406 align:middle
I go to review and when I execute this
line, it actually moves the circle away

00:24:43.406 --> 00:24:48.736 align:middle
and from here I can say go to trash,
go to draft and go to review again.

00:24:49.406 --> 00:24:58.126 align:middle
And in this state I can say which are my
enabled translations, and I get an array back

00:24:58.256 --> 00:25:03.736 align:middle
to say I can go to publish and trash.

00:25:03.886 --> 00:25:08.196 align:middle
I just, you just understand
everything in the Workflow component.

00:25:08.196 --> 00:25:12.736 align:middle
The Workflow component itself got like 15
classes and this is the most complex one.

00:25:13.326 --> 00:25:16.246 align:middle
And you understand it fully
now, which I think is quite...

00:25:17.246 --> 00:25:21.236 align:middle
not impressive that you understand it, but it's
impressive how simple Symfony components are.

00:25:22.646 --> 00:25:25.716 align:middle
Uh, this is also, since this is
Symfony, this is also available in Twig.

00:25:26.436 --> 00:25:32.416 align:middle
Imagine, imagine when you're
editing an advert on Happyr,

00:25:32.666 --> 00:25:35.126 align:middle
imagine it looks exactly like, like Wordpress.

00:25:35.126 --> 00:25:40.166 align:middle
You have this big text box in the middle
and then you have a sidebar with like trash,

00:25:40.166 --> 00:25:42.976 align:middle
publish and stuff button like this.

00:25:43.636 --> 00:25:45.416 align:middle
This is the code for the sidebar.

00:25:45.766 --> 00:25:51.016 align:middle
So I'm checking if the workflow "can" go
to review, then show the link for review.

00:25:51.806 --> 00:25:57.216 align:middle
If the, the, the, this advert can be
published, then show the link for published.

00:25:58.056 --> 00:26:04.426 align:middle
So the same sidebar will look
differently on different adverts.

00:26:04.976 --> 00:26:14.146 align:middle
And if you are, if you're smart with the naming
of your work for transitions and you're naming

00:26:14.146 --> 00:26:17.396 align:middle
of the routes, you can do something
like this to print the sidebar.

00:26:17.426 --> 00:26:23.426 align:middle
I want to show this because it's, it's
possible, but you probably shouldn't do this.

00:26:23.776 --> 00:26:27.136 align:middle
I do want to say that...

00:26:27.376 --> 00:26:31.616 align:middle
I mean, I think this is pretty cool, right?

00:26:32.546 --> 00:26:34.746 align:middle
You, sorry.

00:26:35.486 --> 00:26:44.746 align:middle
I need to reverse, blah blah,
this is a sidebar, decisions...

00:26:45.906 --> 00:26:47.656 align:middle
This is pretty cool, right?

00:26:47.656 --> 00:26:51.766 align:middle
Your sidebar really, it changes
depending on the states.

00:26:52.366 --> 00:26:58.576 align:middle
And what's cool here though is on a business
meeting, we sat down and someone asked,

00:26:58.576 --> 00:27:01.776 align:middle
how come you can't trash
something that's in draft?

00:27:02.476 --> 00:27:07.996 align:middle
It's obviously no arrow here,
but what's the reason?

00:27:09.156 --> 00:27:11.276 align:middle
And I'm like, yeah, there is no real reason.

00:27:11.426 --> 00:27:14.736 align:middle
So let's, add this arrow.

00:27:14.826 --> 00:27:18.046 align:middle
And here's, here's the kicker.

00:27:18.476 --> 00:27:22.046 align:middle
I only changed the whiteboard.

00:27:22.046 --> 00:27:26.216 align:middle
I want to change how the, how
the state machine looks like.

00:27:26.436 --> 00:27:28.256 align:middle
I did not change any of my models.

00:27:28.766 --> 00:27:30.666 align:middle
I did not change any of my controller.

00:27:31.086 --> 00:27:33.806 align:middle
I did not change any of my services,
I did not change Twig layer,

00:27:33.806 --> 00:27:36.066 align:middle
I didn't change anything but my configuration.

00:27:36.756 --> 00:27:47.116 align:middle
And still with this change, I will see the trash
in the sidebar when the advert is in draft.

00:27:47.366 --> 00:27:51.266 align:middle
And that's pretty cool.

00:27:51.266 --> 00:27:56.726 align:middle
A year ago, I did this presentation
and when I said that's pretty cool.

00:27:56.916 --> 00:27:58.476 align:middle
People like, yeah, that's cool.

00:27:58.476 --> 00:28:00.256 align:middle
Good job, and they were kind of cheering.

00:28:00.946 --> 00:28:05.706 align:middle
But you become the words, not
only to be excited with me.

00:28:06.566 --> 00:28:10.516 align:middle
So I want to change the configuration
And the configuration looked like this.

00:28:11.026 --> 00:28:14.096 align:middle
It's super simple, This is my,
this is my core of my business.

00:28:14.096 --> 00:28:15.056 align:middle
This is my business logic.

00:28:16.576 --> 00:28:22.846 align:middle
If you're really, really paying attention,
you might spot a weird thing here.

00:28:24.366 --> 00:28:27.406 align:middle
I told you that a workflow can have, no sorry,

00:28:27.406 --> 00:28:29.766 align:middle
I told you the the state machine only
can have one input and one output.

00:28:29.996 --> 00:28:32.596 align:middle
And clearly I have two inputs here.

00:28:33.766 --> 00:28:37.676 align:middle
This Symfony configuration is
smart enough to know like, oh,

00:28:37.966 --> 00:28:42.946 align:middle
I can make two transition of this.

00:28:42.946 --> 00:28:47.106 align:middle
So it, it says, it looks like only one, but
it's actually gonna to become two transitions.

00:28:48.686 --> 00:28:52.206 align:middle
And also quickly want to show
you a multistep signup form.

00:28:52.916 --> 00:28:57.726 align:middle
Business may dictate that this is
the way we sign up to our service.

00:28:57.986 --> 00:29:00.906 align:middle
So have an intro, you add
your name, you add your email,

00:29:00.906 --> 00:29:02.336 align:middle
you add your twitter, and then you're done.

00:29:03.376 --> 00:29:07.066 align:middle
And doing this workflow in the configuration
is simple, you just do it like this.

00:29:07.146 --> 00:29:11.116 align:middle
You just say that this is a
state machine, this is my places,

00:29:11.116 --> 00:29:12.526 align:middle
and this is how you move between places.

00:29:13.556 --> 00:29:17.196 align:middle
And business might say this is good and
all, but we want to have back buttons.

00:29:17.196 --> 00:29:19.436 align:middle
We want to have a workflow
like this where you go back.

00:29:19.536 --> 00:29:21.706 align:middle
And we said, sure, no worries.

00:29:22.256 --> 00:29:23.756 align:middle
We just do something like this.

00:29:24.126 --> 00:29:26.196 align:middle
However, this is not valid YAML, right?

00:29:27.256 --> 00:29:30.386 align:middle
You cannot have multiple keys on
the same level which is called back.

00:29:31.206 --> 00:29:34.836 align:middle
So what we need to do, we need to
do something like this instead.

00:29:35.256 --> 00:29:40.026 align:middle
We add arbitrary numbers or arbitrary
names and then we have the name.

00:29:40.806 --> 00:29:42.776 align:middle
So this how we get around the issue with YAML.

00:29:43.196 --> 00:29:45.816 align:middle
So with this you can actually please
the business to have back buttons.

00:29:46.156 --> 00:29:52.286 align:middle
And I know I've been talking a lot about
state machines now and I haven't really...

00:29:52.286 --> 00:29:55.016 align:middle
This is called the Workflow component.

00:29:55.166 --> 00:29:57.826 align:middle
And it says workflow like all
over the place here, right?

00:29:58.276 --> 00:30:01.286 align:middle
So what is the difference between
a state machine and workflow?

00:30:01.286 --> 00:30:04.626 align:middle
In the beginning I mentioned the
state machine is a reduced workflow,

00:30:04.626 --> 00:30:06.596 align:middle
but what is the actual, what
is the actual difference?

00:30:06.796 --> 00:30:12.016 align:middle
As an example, I want to show you
this: this an example of a workflow.

00:30:12.296 --> 00:30:13.676 align:middle
Previously we've only seen state machines.

00:30:13.816 --> 00:30:15.386 align:middle
This is the example of a workflow.

00:30:15.866 --> 00:30:20.086 align:middle
And the main difference in a workflow and
a state machine is that in a workflow,

00:30:20.286 --> 00:30:22.286 align:middle
you may be in two places at once.

00:30:23.826 --> 00:30:27.676 align:middle
It might feel weird, but it's actually valid.

00:30:27.676 --> 00:30:30.096 align:middle
A workflow more or less describes a process.

00:30:30.606 --> 00:30:34.476 align:middle
A state machine describes traffic
lights, when you actually go back

00:30:34.596 --> 00:30:36.246 align:middle
to the beginning and stuff - how you move.

00:30:36.506 --> 00:30:43.456 align:middle
So this is a workflow for a blog post: it's
first a draft, then you request reviews

00:30:43.966 --> 00:30:48.666 align:middle
and then you get in, you get in the places
for waiting for spellchecker and waiting

00:30:48.666 --> 00:30:49.846 align:middle
for the journalist at the same time.

00:30:49.846 --> 00:30:54.406 align:middle
So there's an example where a transition
that makes you to be in two places at once.

00:30:54.966 --> 00:30:56.756 align:middle
And spellchecker is probably automatic, right?

00:30:57.026 --> 00:30:59.836 align:middle
So that's pretty quick, but you
have to wait for the journalist.

00:31:00.526 --> 00:31:05.376 align:middle
And it might be tempting to try to
publish this blog post right now.

00:31:05.376 --> 00:31:11.286 align:middle
But you can't execute the publishe transition
because both its inputs are not fulfilled:

00:31:11.286 --> 00:31:13.006 align:middle
we don't have one of the inputs, right?

00:31:13.006 --> 00:31:20.346 align:middle
So we have to wait for the journalists to catch
up and then you can eventually publish it.

00:31:20.726 --> 00:31:26.036 align:middle
I will also say a workflow
rarely contains loops.

00:31:26.376 --> 00:31:29.286 align:middle
It's rare that you go back in your workflow.

00:31:29.976 --> 00:31:32.536 align:middle
However, state machines, loops are encouraged...

00:31:33.336 --> 00:31:39.006 align:middle
kind of. People used to ask me: when should
I use workflow when I use state machine?

00:31:39.426 --> 00:31:41.786 align:middle
And the answer is boring.

00:31:41.786 --> 00:31:43.276 align:middle
It's obviously: it depends.

00:31:44.476 --> 00:31:50.606 align:middle
I tend to use workflow when
there's a clear process.

00:31:51.236 --> 00:31:53.826 align:middle
I use state machine for everything else.

00:31:53.946 --> 00:31:55.546 align:middle
It's just how I like it.

00:31:56.116 --> 00:31:58.826 align:middle
The most important thing is that
you know which one you're using.

00:31:59.176 --> 00:32:00.676 align:middle
You need to know how to relate to them.

00:32:01.356 --> 00:32:05.446 align:middle
It's like, for 99 percent of the problems, it
doesn't really matter which one you're using.

00:32:06.046 --> 00:32:07.996 align:middle
But you should know which one you're using.

00:32:08.406 --> 00:32:12.076 align:middle
Does it make sense?

00:32:12.116 --> 00:32:12.556 align:middle
Excellent.

00:32:12.556 --> 00:32:12.936 align:middle
Excellent.

00:32:13.326 --> 00:32:14.466 align:middle
So back to the Workflow component.

00:32:16.006 --> 00:32:20.636 align:middle
If you have been around in the Symfony community
for awhile, you might notice Symfony have

00:32:20.636 --> 00:32:24.786 align:middle
like 30 components and the components
are very decoupled from each other,

00:32:25.076 --> 00:32:27.186 align:middle
but they play really, really
well with each other.

00:32:27.836 --> 00:32:29.556 align:middle
And the secret there is events.

00:32:30.586 --> 00:32:33.936 align:middle
Events is the thing that makes
them play well with each other.

00:32:34.476 --> 00:32:36.686 align:middle
And the workflow component is no exception.

00:32:36.996 --> 00:32:39.946 align:middle
We have events or, the Workflow
component has events for everything.

00:32:40.566 --> 00:32:45.656 align:middle
We, all the events looks like this: you
have a generic event, say workflow.leave.

00:32:45.966 --> 00:32:50.646 align:middle
Then you have an event, say workflow
- the job advert - when they leave.

00:32:51.116 --> 00:32:56.066 align:middle
And you have events for, workflow,
job_advert, leave, draft node.

00:32:57.436 --> 00:33:00.936 align:middle
And all these, you have all these
three types of events for everything.

00:33:01.986 --> 00:33:04.176 align:middle
So we have workflow leave,
when you're leaving a node.

00:33:04.176 --> 00:33:07.726 align:middle
You have transition that would actually
transition from one node to another.

00:33:08.066 --> 00:33:11.366 align:middle
And when you enter the node, when
you have been entered the node,

00:33:11.526 --> 00:33:12.826 align:middle
and when a transition is completed.

00:33:13.336 --> 00:33:15.536 align:middle
And then you have announce
saying: Hey, I'm all done.

00:33:16.096 --> 00:33:18.526 align:middle
It might feel weird that we have so many events.

00:33:18.526 --> 00:33:23.346 align:middle
I mean these add up to like 21 events for
each transition, which is a lot of events.

00:33:24.896 --> 00:33:26.576 align:middle
However, there, there's a
reason for all of them.

00:33:26.576 --> 00:33:30.616 align:middle
Like, I know I've reviewed all the pull requests
adding more events and they all makes sense

00:33:30.616 --> 00:33:32.466 align:middle
in this specific weird edge case.

00:33:33.036 --> 00:33:35.736 align:middle
You should only care about
the one you care about.

00:33:35.736 --> 00:33:36.806 align:middle
I mean, you shouldn't...

00:33:36.946 --> 00:33:38.766 align:middle
I only use like leave and enter...

00:33:38.766 --> 00:33:39.646 align:middle
and that's fine.

00:33:39.986 --> 00:33:41.586 align:middle
So there's plenty of events.

00:33:41.726 --> 00:33:43.756 align:middle
There's also this even more events.

00:33:43.756 --> 00:33:48.796 align:middle
There's one event called the Guard event and
the Guard event is something that you use for,

00:33:49.546 --> 00:33:52.986 align:middle
adding extra logic, like external dependencies.

00:33:53.716 --> 00:33:56.256 align:middle
So: can I publish this blog post?

00:33:56.656 --> 00:33:58.706 align:middle
Like say we want to, we want
to have a rule saying:

00:33:58.706 --> 00:34:03.936 align:middle
you can only publish this blog
post if it's between3 and 4 PM.

00:34:04.206 --> 00:34:07.096 align:middle
Or if the database is online or
if the manager is in the office

00:34:07.096 --> 00:34:09.526 align:middle
or if you have the role ROLE_PUBLISHER.

00:34:10.286 --> 00:34:16.536 align:middle
So a Guard, a Guard event is how you add
this extra knowledge to your state machine.

00:34:16.536 --> 00:34:20.886 align:middle
And I think you all are comfortable
with events subscribers.

00:34:21.136 --> 00:34:24.976 align:middle
I basically say at the bottom, I say:
this is the event I'm listening to -

00:34:24.976 --> 00:34:28.806 align:middle
workflow.job_advert.guard.publish -
like the "got published" transition.

00:34:29.086 --> 00:34:32.416 align:middle
Whenever that event is dispatch
called the guardPublish() function

00:34:32.676 --> 00:34:34.646 align:middle
and run this three lines in the middle.

00:34:35.226 --> 00:34:38.606 align:middle
I would, I will assume that
you are comfortable with this.

00:34:38.866 --> 00:34:44.516 align:middle
Except for the Guard event, we may, we
can register normal event listeners.

00:34:44.516 --> 00:34:48.776 align:middle
Say you want to log every time
you move from one node to another.

00:34:49.216 --> 00:34:53.156 align:middle
So I say, the workflow, when
the job advert leaves any node -

00:34:54.196 --> 00:34:56.796 align:middle
workflow.job_advert.leave -
then I just to do a logging.

00:34:57.116 --> 00:35:02.036 align:middle
I say advert with ID performed
transition from one node to another.

00:35:02.816 --> 00:35:05.266 align:middle
It might be useful to have
this kind of log message.

00:35:08.856 --> 00:35:09.986 align:middle
I'm checking - you're still with me?

00:35:10.216 --> 00:35:11.846 align:middle
It looks like most of you are with me.

00:35:12.376 --> 00:35:17.686 align:middle
I... no surprise: I love the Workflow Component.

00:35:18.156 --> 00:35:20.026 align:middle
I use the Workflow component all over the place.

00:35:20.366 --> 00:35:21.386 align:middle
If I have...

00:35:21.526 --> 00:35:26.536 align:middle
the Symfony Security components have the
concept of voters, which are basically:

00:35:26.816 --> 00:35:31.516 align:middle
if someone wants to watch, view an advert,
I got to make sure that advert is published.

00:35:31.886 --> 00:35:35.406 align:middle
And I'm using the Workflow component
to make sure I am in state published.

00:35:36.206 --> 00:35:41.496 align:middle
So here's a simple security voter and I say:
if someone tries to view then I check this:

00:35:41.586 --> 00:35:46.516 align:middle
if the state machine got the marking
for the advert and marking is published,

00:35:46.516 --> 00:35:49.356 align:middle
like if I'm in published state,
then you're allowed to view it.

00:35:50.036 --> 00:35:52.016 align:middle
You should not be allowed to
view something that's in draft.

00:35:53.306 --> 00:35:56.486 align:middle
So I used my state machine all over the place.

00:35:57.506 --> 00:36:00.786 align:middle
I also use the state machine for domain events.

00:36:01.756 --> 00:36:08.406 align:middle
I know for sure that no advert in my
application will ever be published unless the

00:36:08.576 --> 00:36:11.976 align:middle
workflow.job_advert.enter.published
event is dispatched.

00:36:12.786 --> 00:36:14.536 align:middle
I can trust that for sure.

00:36:15.006 --> 00:36:18.056 align:middle
That's why I use this event
for my domain knowledge.

00:36:18.056 --> 00:36:22.206 align:middle
Like say business say: you should email all
your users whenever an advert is published.

00:36:22.506 --> 00:36:24.506 align:middle
And this is a good, is a
good place to hook into this.

00:36:25.466 --> 00:36:28.406 align:middle
So I never dispatch any events on my
own, I just use the workflow events.

00:36:28.966 --> 00:36:33.776 align:middle
Obviously we don't email all our users when
adverts are published, I just wanted to say,

00:36:33.996 --> 00:36:36.576 align:middle
but it's, an example how you use
your domain logic with these events?

00:36:38.086 --> 00:36:46.386 align:middle
Um, whenever, whenever I'm in business meetings
and we, the business people say we need this

00:36:46.386 --> 00:36:50.006 align:middle
and we need that and we gotta
figure out a new way to do stuff.

00:36:50.096 --> 00:36:53.646 align:middle
We write the workflow on the whiteboard.

00:36:54.296 --> 00:36:57.186 align:middle
And we change our minds, we
go back and we add new states.

00:36:57.456 --> 00:37:02.496 align:middle
We, because business people, they tend to
like graphs and images, they tend to like,

00:37:03.326 --> 00:37:05.686 align:middle
big circles and squares and arrows between them.

00:37:06.006 --> 00:37:08.216 align:middle
So it's easy to work with,
work with a whiteboard.

00:37:09.556 --> 00:37:15.616 align:middle
However, when the whiteboard meeting is done, I
want to make sure, I go back to coding and I got

00:37:15.616 --> 00:37:18.656 align:middle
to make sure that I have
configured this properly.

00:37:19.206 --> 00:37:26.506 align:middle
So I add my configuration and then I run this
command, the dump command and I'd get an image.

00:37:26.506 --> 00:37:31.066 align:middle
I mean the dump command just prints out
some text and I use this program called dots

00:37:31.196 --> 00:37:35.446 align:middle
or this script called dot which converts,
takes to an image, and I can get this image.

00:37:35.956 --> 00:37:39.556 align:middle
So then I compare the whiteboard
with my image and more often

00:37:39.556 --> 00:37:41.756 align:middle
than not I made a mistake in my configuration.

00:37:42.176 --> 00:37:45.476 align:middle
So this is a good way to make
sure you configure this properly.

00:37:46.086 --> 00:37:49.926 align:middle
And so I usually dump two
or three times and then I,

00:37:50.246 --> 00:37:51.856 align:middle
then I know I got the right conflagration.

00:37:53.276 --> 00:37:57.266 align:middle
And I know I talked a lot, and
state machines they sure are great.

00:37:57.266 --> 00:38:00.276 align:middle
I gives us, I've told you so
many benefits, but how do...

00:38:00.276 --> 00:38:03.806 align:middle
I mean where...

00:38:04.096 --> 00:38:05.216 align:middle
so I want to give you some hints.

00:38:05.216 --> 00:38:11.196 align:middle
I want to give you some: if you ever have, if
you ever have code like this, this is code,

00:38:11.196 --> 00:38:16.876 align:middle
I've written, I wrote a cCRMm or whatever
it's called, basically for salespeople

00:38:16.876 --> 00:38:21.386 align:middle
and they have a quotation and
I defined the Quotation can be

00:38:21.386 --> 00:38:23.296 align:middle
in these three states, four states.

00:38:23.556 --> 00:38:26.686 align:middle
I even have a property called status.

00:38:26.686 --> 00:38:31.016 align:middle
And whatever you see code like this in your
application, you should know like, hey,

00:38:31.216 --> 00:38:35.286 align:middle
maybe I should use a state machine for this.

00:38:35.586 --> 00:38:40.306 align:middle
Also, when you're looking at your
database and you see something like this.

00:38:40.596 --> 00:38:44.716 align:middle
Like have boolean for active, a boolean
for ended, a boolean for closed.

00:38:45.236 --> 00:38:49.436 align:middle
This is also a good sign, like "hey maybe a
state machine will be better in this scenario"

00:38:50.566 --> 00:38:54.346 align:middle
And people asking me: "Oh, Tobias,
should you really have state machines

00:38:54.346 --> 00:38:56.426 align:middle
if you only have three or four states?"

00:38:57.106 --> 00:38:59.226 align:middle
And the answer is obviously it depends.

00:38:59.406 --> 00:39:01.636 align:middle
Are you sure you never ever
would add more states?

00:39:02.026 --> 00:39:04.096 align:middle
How are the rules between those states?

00:39:04.096 --> 00:39:04.836 align:middle
How do you move?

00:39:05.106 --> 00:39:09.226 align:middle
And I would say, if you want to
make sure you don't have any bugs.

00:39:09.526 --> 00:39:11.776 align:middle
Yes, a state machine might be a good idea.

00:39:12.346 --> 00:39:17.576 align:middle
Obviously if you're only have two states,
I mean it all depends and I understand,

00:39:17.716 --> 00:39:20.256 align:middle
I'm sure you're getting the gist.

00:39:20.256 --> 00:39:21.586 align:middle
So how about processes?

00:39:22.676 --> 00:39:24.766 align:middle
If you don't have a quotation, but a process.

00:39:25.196 --> 00:39:29.046 align:middle
What if you're doing e-commerce,
it's obviously a process here.

00:39:29.326 --> 00:39:34.156 align:middle
You obviously create an order somehow
and items are being added to that order

00:39:34.316 --> 00:39:38.406 align:middle
and then you need the user to fill in the
delivery address and then you need them

00:39:38.676 --> 00:39:43.876 align:middle
to add the payment method and then you need
to call or somehow notify the delivery team

00:39:43.996 --> 00:39:45.496 align:middle
to make sure that that order is delivered.

00:39:46.566 --> 00:39:50.986 align:middle
And this is also like if you
have this strict workflow,

00:39:51.206 --> 00:39:52.816 align:middle
you should think of the Workflow component.

00:39:52.816 --> 00:39:56.786 align:middle
You should think: "Hey, maybe,
maybe I should use a workflow here."

00:39:56.876 --> 00:40:00.806 align:middle
And then you start drawing on the
whiteboard: you draw the order is created,

00:40:01.146 --> 00:40:06.456 align:middle
and then somehow we add an item we have
transition add item, so the item is added.

00:40:06.986 --> 00:40:13.846 align:middle
And then you add the shipping and then you go to
the checkout and after the order is confirmed.

00:40:14.606 --> 00:40:15.646 align:middle
And you look at this.

00:40:15.646 --> 00:40:16.706 align:middle
Yeah, sure, this makes sense.

00:40:16.706 --> 00:40:17.736 align:middle
This is a clear workflow.

00:40:18.006 --> 00:40:23.626 align:middle
However, this means a user can
only can add one item, right?

00:40:23.626 --> 00:40:27.296 align:middle
So we need to add an extra arrow here.

00:40:27.656 --> 00:40:30.806 align:middle
The user can add more than one item so
it can buy more stuff from you, right?

00:40:32.276 --> 00:40:38.486 align:middle
And this, it's pretty simple: you just go
through the workflow and the item added, sure,

00:40:38.486 --> 00:40:43.016 align:middle
add another item, add more items, add
shipping, and then order confirmed.

00:40:43.196 --> 00:40:47.266 align:middle
And the cool thing here is: this will,
each of these steps will dispatch an event.

00:40:48.126 --> 00:40:52.476 align:middle
And on this event I have an event
listener because this is my domain logic.

00:40:52.846 --> 00:40:58.116 align:middle
I can trust that this event listener is
executed each time an order is confirmed.

00:40:58.436 --> 00:41:02.006 align:middle
And I just asked the delivery service
to take care of this order somehow.

00:41:02.996 --> 00:41:03.436 align:middle
Makes Sense?

00:41:04.606 --> 00:41:11.166 align:middle
So using the state machine, I also know
that no order will ever be completed

00:41:11.166 --> 00:41:13.776 align:middle
or confirmed unless I added
the shipping address.

00:41:15.036 --> 00:41:18.376 align:middle
It's literally impossible to complete an
order without adding a shipping address.

00:41:19.586 --> 00:41:25.956 align:middle
So what I basically want to say
is, it all comes down to this:

00:41:26.176 --> 00:41:30.296 align:middle
Using the Symfony Workflow component
will make your write fewer bugs.

00:41:30.956 --> 00:41:38.776 align:middle
And I hope this short presentation of
mine have given you a new way of thinking,

00:41:38.776 --> 00:41:40.576 align:middle
a new way to relate to your problems.

00:41:41.076 --> 00:41:42.726 align:middle
Thank very much.

00:41:43.036 --> 00:41:53.746 align:middle
Thank you.

00:41:54.026 --> 00:41:56.986 align:middle
I will share my slides on joind.in.

00:41:57.456 --> 00:42:00.876 align:middle
And so if you, if you're interested
in anything, you please feel free.

00:42:01.246 --> 00:42:05.136 align:middle
If you have any questions, I think we have a
few minutes and I will throw this cube at you.

00:42:05.206 --> 00:42:08.516 align:middle
Anyone want to have a cube?

00:42:12.356 --> 00:42:14.696 align:middle
There's a question over there, please help me.

00:42:16.916 --> 00:42:18.236 align:middle
Two rows back.

00:42:18.416 --> 00:42:19.856 align:middle
Three rows back.

00:42:22.106 --> 00:42:27.376 align:middle
Did you activate the cube?

00:42:29.636 --> 00:42:31.446 align:middle
It was a mistake.

00:42:31.776 --> 00:42:33.406 align:middle
Oh, okay, mistake question.

00:42:33.646 --> 00:42:45.086 align:middle
Someone else - just throw it
to someone waving over there.

00:42:45.366 --> 00:42:50.556 align:middle
Whoever has the laser pointer in their eye.

00:42:50.556 --> 00:42:54.426 align:middle
Sorry, can you hear me?

00:42:54.796 --> 00:42:55.236 align:middle
Okay, great.

00:42:55.666 --> 00:42:59.036 align:middle
So a question is really simple:
where is e-commerce here?

00:42:59.156 --> 00:42:59.726 align:middle
Where's the camera?

00:42:59.726 --> 00:43:02.676 align:middle
I don't know where the camera
is - oh there's the camera.

00:43:02.676 --> 00:43:06.676 align:middle
I'm saying this was callex using the
workflow component for E-commerce.

00:43:07.046 --> 00:43:10.126 align:middle
Ah, where is the e-commerce?

00:43:10.396 --> 00:43:15.066 align:middle
Yeah. I assume that you missed
my five minutes beginning.

00:43:15.066 --> 00:43:16.586 align:middle
Michelle sadly got sick.

00:43:16.876 --> 00:43:18.806 align:middle
So I did a stand-in talk
about Workflow component.

00:43:19.236 --> 00:43:24.286 align:middle
So yes, I missed a lot of e-commerce stuff and
we can only blame Michelle's three year old kid.

00:43:24.726 --> 00:43:34.036 align:middle
There's one more question and
then I'm gonna let you all go.

00:43:34.376 --> 00:43:38.216 align:middle
You hear me?

00:43:38.286 --> 00:43:45.456 align:middle
Yes I do. Uh, so my question is how to
properly connect workflows with the security.

00:43:45.536 --> 00:43:49.486 align:middle
So you have two ways: you can
write a guard listener, uh,

00:43:49.486 --> 00:43:53.606 align:middle
to prevent some transitions based on security.

00:43:53.706 --> 00:43:59.286 align:middle
Or you can, as you showed, you can
do a voter and there decide based

00:43:59.336 --> 00:44:01.806 align:middle
on workflow whether you can do something or not.

00:44:01.876 --> 00:44:03.266 align:middle
So what's the correct way?

00:44:03.776 --> 00:44:05.086 align:middle
It depends what you're trying to do.

00:44:05.316 --> 00:44:11.186 align:middle
I show the voters, which, I will try to
explain, I used for handling my app security.

00:44:11.186 --> 00:44:13.666 align:middle
I used the state machine
as a substitute, as a help.

00:44:14.246 --> 00:44:18.456 align:middle
If you're going to add security,
saying like you want to make sure...

00:44:18.936 --> 00:44:24.046 align:middle
if you want to make sure that you
have the correct role for doing

00:44:24.046 --> 00:44:26.216 align:middle
such as this action, use the Guard event.

00:44:26.726 --> 00:44:29.506 align:middle
Okay. So you do something like this.

00:44:29.956 --> 00:44:31.706 align:middle
So both ways are correct?

00:44:31.706 --> 00:44:34.106 align:middle
Both are correct depending on what
you're actually trying to solve.

00:44:34.106 --> 00:44:34.986 align:middle
Okay. Thank you.

00:44:35.716 --> 00:44:38.066 align:middle
I will be around for the rest of the conference

00:44:38.196 --> 00:44:40.396 align:middle
and I also told you the best
speakers in the front.

00:44:40.786 --> 00:44:44.296 align:middle
I'm doing a second talk at the very, very
end of the conference for some reason.

00:44:44.666 --> 00:44:51.106 align:middle
So if you're interested in Symfony 4
internals, please come and visit me then.

00:44:51.106 --> 00:44:57.346 align:middle
Please review, rate all the speakers on
joind.in it's very helpful for all of us.

00:44:58.706 --> 00:45:02.486 align:middle
Thank you very much.

