okay good morning welcome to Opie the
Pokemon journey this is a beginner's
level session kind of talking about the
concepts of object-oriented programming
I hope you'll enjoy it my name is fatima
my drupal.org username and twitter
handle it sugar overflow
I work for a digital echidna we're a
digital services agency in London Canada
I'm also on the leadership team for
Drupal diversity and inclusion which is
a working group in the community to kind
of improve the conversations around
making it a more inclusive and welcoming
space today I'm going to be talking
about Opie object-oriented programming
it's a way of organizing our code that
makes it a little bit more modular
reusable and flexible what this means is
instead of writing code for multiple
things we can kind of containerize our
code and write one code base and then
extend it and use it in many different
ways
and that sort of helps does not have to
write the same thing over and over again
um the way we're gonna do this session
is kind of we're gonna have a story
we're gonna go on a Pokemon journey and
throughout that journey we're going to
map some journey concepts and story
ideas into concepts that then translate
to Opie I've also added a bit where we
kind of look at an example in Drupal
core so that you have something to go
back to when you think about these
concepts so when we start on Pokemon
journey the first thing we do is we
visit Professor Oak at the gym and we
choose our starter Pokemon and for this
class we're going to use Pikachu and so
we started our journey with Pikachu so
we want to learn a little bit about what
Pikachu is and we know that he could use
a type electric pokemon and it also has
an attack called Thunderbolt and so kind
of what we have here is a model for what
a Pokemon would be
it has a name a type and an attack and
when we think about how we can model
this in code hope it provides us
something called classes um I think if
classes like blueprints they're they're
kind of fundamental sort of building
blocks for what you're trying to make
classes have two main parts to them one
is a property which you can think of as
a data point and our Pikachu example a
data point would be the name of the
Pokemon or the type of the Pokemon
another part of classes is methods you
can also think of them as functions and
these are specific to the class for
example Pokemon has the ability to
attack and in Pikachu's case that attack
isn't thunderbolt so that would be the
method for the Pikachu class gonna take
them so now we're gonna go ahead and
look at the code for our Pokemon class
and in this you'll see that when you're
creating a class in PHP you have
something called a class keyword and
then you have the name of the class the
first few things underneath class
pokemons are what we were calling the
properties or the data points of this
class so if we're Pokemon we have a
public variable called name and the
public variable called type and we also
have a method which is the public
function attack and for now it just does
something and returns an attack and
public in this case is what we call
visibility in PHP and that kind of
allows other classes to use or access
those methods so there's also protected
and private um so this is what like a
very bare-bones class would look like
and now that we have a class and we have
the ability to have a name and a type we
have to think about but how do I create
a Pokemon and in O P we call that
creating an object of this class or
instantiating the class and to that PHP
gives us is magic
call the constructor which is written
like underscore underscore construct and
a constructor basically allows us to
create the object that we're building in
that class so in this case it would
allow us to create a Pokemon you can
pass parameters to a constructor so
those are things that you will need to
give to the object when you're creating
it so in this case whenever we create
something of class Pokemon we're always
going to need to pass it a name and a
type and on there inside the constructor
we have some syntax for that this
variable which basically refers to the
class that you're in so here we're
passing in a name and a type and we're
giving the class that name in type you
don't have to take notes there'll be a
link to the slides again I feel bad when
people are typing because I'm talking
too fast and and then now that we have a
constructor we can go ahead and create a
Pokemon object and you would do that
like this and so if we're creating a
variable Pikachu we'll use the new
keyword to create an instantiation of
the class Pokemon is the name of the
class the name we're giving is Pikachu
the type we're giving is electric and
since there is an attack function in
this class this is how we can call
Pikachu's attack function this is very
pseudocode
um and then we can look at an example of
a class in Drupal core the one that I
picked was the translatable markup class
which exempts from a double markup we'll
talk a little bit more about extensors
and you can see in this they have a
constructor and the property called
translation and basically they set that
property when this class is created
[Music]
cool go back to our story so we're going
on our Pokemon journey and Pikachu and I
come across a wild Pokemon in the grass
and we capture this Pokemon and it turns
out it's an oddish and now we have to
analyze our Pokemon to kind of
understand what's the difference between
a Pikachu and an oddish
and how can we model that difference in
our code so what we have here is an
electric-type pokémon with an attack of
thunderbolt and a grass type Pokemon
with an attack called poison fire and so
now we're looking at this and we're like
hey we can't just use one generic
Pokemon class anymore because now I have
different types of Pokemon so how can we
model that in code and for that opie
provides us something fancy called
inheritance and I would send about
inheritance I was sharing because
there's a parent class which in our case
is the Pokemon class and then there are
child classes which can inherit from the
parent class and take all the
functionality but also override the
things that they want to change
my notes it says you can also think of
the Titans as a tree and the parent
class is kind of the stump of the tree
and the branches are the child class do
you have a base functionality and then
you have things that can kind of grow
from there cool now let's look at our
parent Pokemon class which is this I
kind of took out some of the properties
and so we're gonna focus on the attack
function that we have in our parent
class we can also call this a base class
and then we're gonna use the extends
keyword to create an electric pokemon
class so that extends keyword tells us
that this electric pokemon class is
inheriting or is inheriting from the
parent Pokemon class and then within
that in the public function attack we've
overridden what was just an attack with
the electric attack
we can go one step forward and make a
Pikachu class that now it stems from the
electric pokemon class which extends
from the parent Pokemon class and in
this one we can get even more specific
in the attack function and return the
Thunderbolt attack which is very
specific to the Pikachu class so
basically when you have the parent class
and child classes you can choose to
override whatever you need to override
and and that can see the flexibility to
sort of have different types of classes
but they all share one kind of base
functionality then we can look at an
example of inheritance and Drupal and
this is actually something I've used on
a project a few weeks ago so there's a
widget interface and that has a form
element function and then there's an
abstract class both abstract basically
it's kind of like a class that has empty
functions that you don't have to
implement you can't create an
instantiation or an object of an
abstract class but you can extend from
it and use the functionality to create
other classes so in this case the last
part the range widget extends the widget
base which implements the widget
interface which has that form element
function so you can kind of see how it
kind of trickles down to the class that
you're you're using for the inheritance
and then in the range widget it's not
something interesting that it doesn't
have in the original interface which is
the from and to part of the form because
it's doing a range so it's for me it was
a good example of how it's overriding
something that exists in a parent class
that is it
cool we're gonna go on with our journey
and of course and every pokemon world
you have to do gym battles and this
turns out to be our first gym ball and
we don't really do so well because we're
just like pikachu go and we don't really
strategize or think about how we're
gonna win this battle and that makes us
realize maybe we need to think a little
bit more about the sort of strengths and
weaknesses of our pokemon and that's
something that we're gonna have to model
in our class now and so if we compare
our pokemon we have pikachu sorry excuse
me
so Pikachu which has a strength against
water type Pokemon and then weakness
against ground-type pokémon and honest
which has a strength against water but
we can't against fire so we can sort of
use these strengths and weaknesses to
choose which Pokemon we sent into battle
and in order to model that into our
class we're going to use another magic
method that PHP provides and that's the
get and set methods or we can also refer
to them as the getters and setters of a
class so for example in our peanut
Pokemon class we can write the cat
weakness function which returns the
weakness of the Pokemon and the set
strength function sorry the first one is
an example together and the second one
is an example of a setter and when the
sender can actually set the strength for
the potion
and you'll see these in many different
ways like a parameter set parameter it's
a very common way to access or to add
thanks to a class when other things in
the class are protected or private and
so this is our parent class if we go
down into our sort of electric pokemon
class that's inheriting from our parent
parent class we can actually give it
parameters that have certain properties
so the strength for an electric pokemon
is grass so when you do get graph to get
strength when you call get strike on
your electric pokemon it'll return the
actual strength type that that pokemon
has
and of course when you create the
constructor you can pass in a strength
and a weakness so that's how you want to
create their Pokemon and then if we look
at getters and setters in julik or one
of the ones that I tend to use a lot it
comes from the route match class which
implements the route match interface and
it has this function plug gap parameters
and what brown patch lets you do is get
the parameters that are in the URL which
can be really useful if you're doing
some contextual filtering so this will
this will kind of if you do like if you
call this service and you do get
parameters I'll give you everything
that's there so this I think wasn't kind
of simple to understand example of a
getter in the triple class cool now that
we can have getters and setters in our
class we're gonna go back to our pokemon
object and see how we can use them take
a break okay so in fact we're gonna see
how we can use them in our pokemon
object and so in this case we'll create
a new pokemon of Pikachu give it a name
and a type and that probably
right okay so we can create a new
Pokemon Pikachu with the name and the
type and then we can call this strength
get strength Michael to get the strength
type of that Pokemon but we can also
create an electric pokémon called
Pikachu and get the strike and so here
we hit this dilemma where we're like
should we really be able to create
generic Pokemon types because now that
we have electric pokemon or water
pokemon extending from the Pokemon base
class do we really want a generic base
class to be instantiated because that
wouldn't make as much sense anymore so
OPM PHP allowed us to create a base
class but make it so that it can't have
objects of that class and that's
something fancy called interfaces so I
think of interfaces like contracts all
the methods are public but they don't
have any functionality inside them
basically any class that implements an
interface has to put the functionality
into those methods this works really
well for us for the Pokemon interface
because we'll have all the functions
that we need in a Pokemon class like
electric pokemon but you don't have to
use this as a generic pokemon so this is
an example of our Pokemon interface I
put some getters and setters in there
and also our attack function generally
interfaces are cool because you can put
all of these function calls in them and
then when you extend when you and when
you implement them you can put in all
the body and that gives you a lot of
flexibility and so let's look at
implementing this Pokemon interface with
our electric pokemon we start out by
using the implements keyword so two
class electric pokemon implements the
Pokemon interface or class Pikachu
extends electric pokemon and since it's
extending a class that's implementing an
interface its inheriting all of the
methods that were in that interface and
and then we can look at what that class
would look like so these are the
functions that are now coming from the
interface and we've basically given them
some functionality as kazuto could so
for the get strength method that's in
the interface where we're training water
and for the get weakness we return graph
um this isn't entirely correct because
the interface as you saw did have a lot
of functions and so in order for this
class to be valid we'd have to implement
all of them but this is just two
examples
[Music]
and then a good example but I think in
Drupal core for interfaces is the forum
interface and the forum interface has
this function called get form ID and so
the abstract class form base is just
basically kind of like the base for when
you create custom forms implements that
form interface at one example of a form
that they says foreign bases the user
login form and in that class you'll see
the gap form ID function actually being
implemented and returning the ID of the
user login form so this is a good
example of how the interface defines a
function that the class implements and
then the class that extends from that
class has to put something in the
function body
cool factory story so we've been
traveling quite a lot we've won a lot of
battles made a lot of friends and one of
our friends on our journeys actually
gave us a Waterstone which allowed one
of our pokémon to evolve and so that's
new to us now we have to build some kind
of evolution functionality into our
classes and in order to do that we're
going to use something that PHP provides
called traits and and I think of traits
as code snippets it's a way they're
being used code and kind of like code
copypasta but you don't have to inherit
from it you can't create an instance of
the trait so there isn't like a trait
object that you can create it's kind of
similar to a class but it's a little bit
more lightweight and for our case we're
going to create a pokemon evolution
trait which all looks something like
this for creating traits we use the
trait keyword and then the name of the
trait and in this particular trait we
have the evolves two functions that will
tell you which Pokemon is in the next
stage of evolution um in order to use
this trait in our poly world class which
extends our water pokemon class you use
a used keyword and the name of the trait
which I got wrong and that down here you
should say pokemon evolution trait so it
matches the name of the class on the
trait sorry the name of the tree and in
that trait in this class we have an
evolve function and we've been that
evolve function we're actually using the
function that were inheriting from the
poky evolution trait
okay
[Music]
I thought that was cool
she takes our great way of like if you
love a small piece of functionality that
you want to include in your class a good
example of traits in Drupal core is this
during translation trait which is
probably used before it's that team
function and in the accent class plug-in
be the action just used strength
translation tree so whatever you create
custom plugins you're extending your
extending plugin base and so you get
that string translation trait with all
of your plugins because it's in the
action
you let your first gift bottle see that
your first dad this is a bicycle
actually kind of looks like a do full
drop so we didn't have to do anything
cool so so now that you've won your
first badge now we're thinking about oh
there there needs to be a bad system
there has to be a system of how do I
earn badges what are badges what is this
new thing that we need to now implement
in our classes and the way I think about
the badge system is that it's a
functionality that can change because
different badges will have different
types of requirements I've had I've
earned them and and so something that
Opie provides us is called plugins and I
need two plugins as functional Lego
blocks so they're like pieces of
functionality that you can plug into
your classes and use there are many
different types of plugins I discovered
this while making my slides on the road
and generally there's a there's a type
of plugin that we use commonly like four
blocks and views and that's called the
annotated plugins and that's what most
of us are familiar with
there's also yamo plugins which are
menus routes or services and there are
other types of plugins like hook plugins
which are things that moved over from d7
and discovery and static plugins as well
but for now we're just gonna focus on
annotated plugins and plugins alright
our kind of things that have different
behavior but they have a common
interface and what that means is that
they all kind of are structured the same
way but they can do many different
things so you can have like five plugins
and they kind of have the same structure
but they all have different
functionality and let's look at what a
Pokemon plugin for bad system would look
like and in order to do this we're gonna
make some assumptions when you're making
a custom plug-in you have to do a couple
of things you have to create the
annotation definition you have to create
a plug-in manager so we're gonna assume
that we've done all of the above and
we're up to the step where we're
creating the plug-in base for our custom
plugin
going to call it the pokey bags plugging
base and what this does it implements a
pokey plugin interface let's say we've
also created that and what this house is
a abstract function called
is the badger um and so when we create
that custom plugin called Drupal badge
we extend the plugin base that we
created that comes with all the other
things like interface the puppet manager
and we basically implements that badge
earned functions
generally it's not that complimented
because I feel like the logics are
wanting to create a custom plugin you
might never need to maybe in very rare
cases because there are so many plug-in
types that have so many boilerplate code
there's so much boilerplate plug-in
types in core that you won't ever have
to create your own plug-in base you'll
just extend one of them and implement
the functionality that you need but in
the case of Pokemon I couldn't really
find a plug-in base that I could extend
so I had to do the assumptions of
creating one and creating the Manatee to
go with it and if we look at a plug-in
in Drupal
again this is an annotated plug-in it's
block based and block based basically
gives us all the functions are not all
the folks live but some functionality we
can use to create custom blocks in block
face there's a build function which
returns the build array of the block and
so when you create a custom block you
override that function if you want to
add things to your custom block that the
parent doesn't have like maybe you want
to add a custom array of things that you
want to display on your block and so you
would do that in your build solution
cool so now that you've been winning
badges and you're doing battle now you
want to be the very best so that means
you got to go compete in tournaments but
before you join a tournament you need to
submit your trainer profile and in order
to submit your trainer profile you need
to have all the stats of your pokémon's
wins and losses and let's just say that
all those wins and losses have been been
have been stored in a database and now
we want to retrieve them and in order to
retrieve them in our classes we're gonna
use something special that Opie provides
called services services are like
swappable operations I think of them as
the functionality is the same but the
code implementation it can be different
so you can have two or three services
that do the same thing for you like
retrieving data or sending an email but
they can all do it in different ways
services are driven it globally
available so you can use them in your
classes and there's usually an interface
that comes with it so it'll be a service
that's implementing an interface that
has the base functionality for that
service if we look at creating our
pokemon service we'll call it class
pokey data service because we're gonna
get our data for our pokemons
implementing a pokey data interface and
it has a function called get yearly
spats which takes the Pokemon as a
parameter and a gear yeah
and a year and then it returns like an
array of data for that particular
Pokemon and we're gonna make the
assumption that that pokey data
interface exists for this service now we
have a service that gets us our really
girly sacks so how do we use it and to
do that we call our Pokemon service
first we create our Pokemon and then we
load our service and here we're calling
the it's we're calling in a puppy data
helper and the sort of syntax for
loading a service globally anywhere in
Drupal is you do the slash Drupal with
the two colors and then the Machine name
of the service and so that's pokemon dot
total data service and and to actually
use it we can do the pokey data helper
with the arrow and call the method
that's in the service and passes the
parameters that it needs to return the
data for that particular Pokemon make
sense
I realize when we were going into the
more sort of like plugins and services
dependency injections out like Pokemon
may not be an easy way to explain things
anymore because when you get so deep
into the opiates kind of like you have
all these assumptions that you have to
make in order to understand the one
concept so that was a bit of a shock ooh
yeah so it starts to get exponentially
complicated it's not actually that
complicated and so we'll look at
services and geological core provides a
lot of services and you can check them
out in the core services ya know file
one of the services that I like to use
or have to use a lot is the current user
service which comes from the account
proxy class and basically that allows
you to load through the current users
and to do that you're like a module or a
class globally you would use the line at
the bottom where you're loading the user
class and then using the load function
and then calling the current user global
service to load the user
that's kind of like a double so so this
part is loading the service and this
part is calling the lowing method from
this user o'clock I'd like a click
and services in Drupal are swappable
this is a little hard to show in the
Pokemon example but one example of the
service that you can swap out would be
the email validator service which is
used in the contact form edit form and
to check if the recipient is valid so
the this particular Gmail volunteer
service comes from the googly eyes class
but essentially you could use any other
email validator service and put it in
place of the call for the contact edit
form so same functionality different
code
and then when possible you should inject
your services with dependency injection
and that's just kind of preferred to do
that you would pass that service as an
argument to the constructor or you would
use a Saturn method and we'll look at
what that looks like in our Pokemon
service so if you'll see that we have a
protected pokey data service variable in
our electric pokemon class and in our
constructor we have a polka data
interface pokey data service variable
and we're basically setting it to the
property that we have and you'll see
that we have a used statement to kind of
load that pokey data service into our
class and when you do dependency
injection in a class you need two things
you need one the constructor to load
that item and to initialize it and to
create function to create the container
to load the service into so here you
would do the name of the service in the
return statement and here you would load
it into a variable in your class so that
later on in your functionality you can
use this variable to call the functions
that are in that service
people nodding simply to make sense
you know yeah so so so I'm inside my
electric and I want to use functionality
that's only available in my pokey data
service so the first thing I would do is
I would put the use statement for that
service to load it into the case that
create a parameter to use that service
inside my class so I'll call that okay
day of service then I'll create my
constructor and in my constructor I'm
gonna pass the puppy data service
because every time I create an electric
pokemon I want to make sure that that
service is there as well so that I can
load it and use it and then I'll create
the create function to create a
container for the service to load the
service into the cuvette
whenever I think of it and when when
we're doing work I think oh I have a
service that I want to use and I'm
inside a custom block do do I have a
constructor that's my first question and
if I don't then I make a constructor I
pass in the service and then I look at
the bottom and I do I guess if I didn't
have a constructor I probably won't have
a create function so then I have to
implement the container interface right
if you create function and put the
service needs as a container and so
maybe this will help
help help it make more sense I have a
custom form I'm extending swarm base I
should also be implementing the
container interface don't as I miss that
I have an account variable and
constructor into which I'm passing the
account interface to use the account
object and to set it to the variable
inside my class then I have my create
function in which I'm calling the
current user service to put it into the
container so that I can use it when I'm
when I'm looking for like trying to call
methods from the cannon from the
container
can easily because all of your services
are in service and so will all not with
that create method agreed method is
receiving the container and then you're
in your function body of your create
you're grabbing whatever services
probably container
okay I'm gonna repeat that so that's not
good thank forgetting the container in
the parameters and then over here we're
getting the service from that service
container so that we can pass it into
our constructor and use it in our class
and so the container there's a lot of
there's a lot out there in terms of LP
and as you do more work in the backend
you'll discover new and interesting
things and this was meant to kind of be
a foundation for the basic so that you
have some kind of examples to refer to
that are not so technical so you can
kind of map out the concepts a little
easier that's also how I first learned
programming and I hope that helps thank
you you can reach me at chigger overflow
and deal or Twitter and the sli's are
actively
[Applause]
question actually haven't played any of
them so so when I first learned Opie it
was for C++ and my professor used this
example of warriors and Nobles and we
have to create this medieval environment
where we had warrior class from noble
class and then they did battle and so
when I first wanted to give this
presentation I talked to a friend and I
was like hey what do you think of this
like analogy and he was like and I was
like Oh have to find something simpler
so I did a lot of research and like
people use animals and then they do like
cat dog have different you know
properties or they do vehicles and
they'll do train and car house like what
can I use that's both exciting a lot of
people would know about it
and would be interesting I don't like
somehow so I've been actually playing
the games I do play pokemon go like that
counts okay that's my favorite game
the questions
now he's smiling
um the API jobs are really good and they
have like chunks of pages for that API
dr. Poddar grifoll and he has a lot of
foreign documentation for ope plug-in
services they have a really great
example about custom plugins called the
ice cream factory
there we go whole page where they talk
but I just in fact vielen create plugins
for flavors and things of that is an
interesting read
in any question
well thanks for coming