 Hi, everyone. Thanks for joining me on this session. Today I will talk to you about Drupal 8 from perspective of symphony developers. Before I start, I will introduce myself. So my name is Antonio Peric-Major. I come from Split, Croatia. I'm the CEO of Locustic, co-founder of symphony Croatia user group and organizer and co-founder of Shift Conference. If you want to contact me, these are my contacts, my Twitter account. So please be free to tweet or send email if you have any questions. Few words about my company. We are agency specialized in designing and developing mobile and web solutions for our clients. We also do training and consulting. And at the moment, we have 20 employees. These are a few pictures from our office. And one of the things that we are very proud of is that almost 25% of our team are the women, which are also amazing developers. And before I start, I have a few questions. So first question is, how many Drupal experts is here? Anyone? Just please raise your hands. Do you have experience with symphony also? Oh, cool. And how many symphony developers? And with experience in Drupal? OK, so basically the title of this talk can be also the Drupal 1014 symphony developers. I will cover the basics, how to install symphony, how to prepare your developing environment, how things work under the hood. And I will show you how to create simple modules based on symphony components. Before we start, small disclaimer, as I already told, I'm the symphony developer. I'm not expert in Drupal. Little bit about history. So in 2012, Fabian Potessier wrote a blog post about Drupal is going to use symphony for building the new version. But they didn't use entire full stack of the symphony. They used only the components. But the principles how they build Drupal under the hood, you will see that is very, very similar to the way how we are building symphony applications. What this means? This means that Drupal developers should learn more. Like, they need to switch to the object oriented programming. They need to learn a new framework. And for symphony developers, that means that we have very powerful CMS, which we know how it works and we can use it. Also, that was a really good thing for community. Because after Composer, that we are not splitting so much inside the PHP communities. As before, we were like islands, like, I don't know, WordPress, Drupal, PHP, symphony, Lara, or whatever community. Now, we are sharing components. So we are forced to build better code to share it with other developers. A few words about Drupal and symphony. So Drupal is for content strategist to build the content, to build the website. And the very best thing about Drupal is that he's very powerful out of the box, even include the APIs. You can build custom types and everything else. And symphony is a framework built for professional developers that allow us to build complex web application in easier way. In Drupal 8, we have three types of knowledge. First type is about Drupal, which is same in Drupal 6, Drupal 7, Drupal 8. It's about no types about how Drupal manages the content inside his database. Second type of the knowledge is symphony knowledge. And third type is something new, like plugins, blocks, and things that comes in Drupal 8. We will, of course, focus on symphony knowledge at this talk. So let's see how it is built. On left side, we have symphony full stack with CMF components, because the Drupal 8 used CMF routing because it allows dynamic routing. And Drupal 8 is built on top of the symphony components here with a trig, with Drupal components, and then everything on the top is Drupal Core. Then we have modules and, of course, distributions at the end result. The symphony components that Drupal is using are listed here. And the most important is, I will say, this part here, dependency injection, even dispatcher, HTTP foundation, and HTTP kernel. So from the list of the components, you may be already have the idea that everything is about dependency injection. It's about dependency injection container. So if you do any work with Drupal 8 and if you are not using the hooks, you will get in contact with dependency injection container, everything. Like from the HTTP kernel request response, controller, even dispatching, listener, subscribers, whatever everything is inside dependency injection container. OK. Let's set up our development environment. If you just want to test Drupal like you don't want to see the code, you want to install it quick without setting up your environment, there is nice website. It's called Simply Test Me. You can pick the Drupal version and just launch Sandbox and you will get installation, I think, for one hour or 30 minutes. And you can play with the content to see what you can build out of the box with a Drupal. Of course, you can install any distribution, any module on this website. There is also Acquia desktop. So it is prepared environment for Drupal development. It works mostly out of the box. So if you want to use that, it's also easy to set up. But of course, if you have any of your Symphony to your Symphony 3 development environment, you can use that. I personally use Vagrant with PHP 7 at the moment. But you can use PHP Build-In Server or Docker or whatever you prefer in your daily work. Some tools that we will use during development with a Drupal. First one is a Drush. Drush is Drupal console. Let's call it in that way. But you will see we have actually Drupal console. And we can manage a website with Drush, like update the core and modules, clear cache, update DB, create some content to restore Drupal, things like that. It's quite easy to install. Again, we will use Composer. We can install globally or we can install for every single project. But the easiest way is to install that globally and then just use it from the console, of course. You can check your status by Drush status. And then you will see, is it installed or not? And if you just hit the Drush, you will get the list of all things that Drush can do for you. Of course, there is too much things to be on one page. But if you grab it, for example, user, you will get some information on what you can do with the user. Here, you can see that we can change password, recover password, create user, or things like that. This is not Drupal 8 thing. It exists in Drupal for a while. But the new thing is a Drupal console. It's built on top of Symphonic console. So usually, when I do development in a Symphonic, I do a lot of things from console. Of course, like creating bundles or something like that, updating database migrations or things like that. Drupal console is similar to that, but it's for Drupal. So you will see from the list of features that you can do with Drupal console, it's similar with it as a Drush. But there are some things that you can do with Drupal console, but you cannot do with Drush and Vise versa. For example, you can install and uninstall models with Drush. But with Drupal console, you can create a skeleton for building a new model. You will see that later. Drupal console, it's also easy to install. Again, with the composer, then we need to install Drupal console launcher. And after that, we can run it with a Drupal. Drupal list will give us a list of all features, all commands that we can use with a Drupal console. And of course, again, there is too many options that we can use. But if we grab something like model, you will see that we can debug model. We can generate new model. We can generate new content types or whatever. And one more tool that I personally recommended. It's not advertised because they are sponsorship district, but PHPStorm, it's a very powerful tool. There is symphony plug-in. There is Drupal support. So it makes your life much easier when you are developing this kind of application with Drupal. OK, how to install Drupal? There are three options to install Drupal. You can use Drush, Drush, DL, Drupal. It will download the latest stable version of Drupal. You can install it. We can use Composer or we can just download the zip file and extract it and we can start using. As this is talk for the symphony developers, I will use Composer. There are two packages that we can use. It's a Drupal slash Drupal. It's a Drupal Composer slash Drupal project. The second one is let's call it community version, which already have some configuration prepared for you. So you don't need to, for example, you will see how to add settings for downloading Drupal models with Composer later. Here is the difference. And this Drupal, this one, it's more the structure of the folder is maybe a little more like in symphony way. This is the difference. So this community version comes with Drush, Drupal, console, some scaffold files, repositories, config, and other path configurations. But we will start with Drupal slash Drupal. So it's quite easy to start your project. Just Composer create project Drupal Drupal. You will get Drupal repository clone. All dependencies installed. And your Composer JSON file will look with something like this. But you won't have this thing and this thing here. We need to add this manually. And this thing allows us to download Drupal modules with Composer later. So we are defining repositories for Drupal, custom things, or some core modules, installer path where to install that. So you see that the contributed models are installed in modules slash contrips slash name of the model. And the packages are not from package guests, it's packagesDrupal.org. So if you want to install some model, you will run Composer requireDrupal slash model name, for example, slash token. And you will get the model installed in your Drupal project. OK, after you installed via Composer, you will run your application in browser. And with few buttons next, next, next, and few configuration, you will get your Drupal site run. So basically, that's it. When you install it, you will get just blank website with welcome to PHP UK, it's title of the project. We can add some dummy content. It's quite easy. We will use Drupal console. So we have some orders for create comments, create nodes, create user vocabularies, or just users. We run the command. We get three in this situation, 25 nodes created for content on our website. But as a symphony developer, what is missing on this screen? Something is missing. When you're working with symphony applications, there is always something there, it's web profiler. It's not included in Drupal core. And it's part of a model core devil. And it's quite easy to install. You will do just composer required Drupal devil. Here is the description of the module. You see that he has some other features also, like generating content, devil node access, and web profiler. And after you install that model, you need to enable it. First, you need to enable devil. Then you need to enable web profiler. Or you can do that also with the Drush, for example. So the command drush pm enable devil will enable your plugin. You just need to download it before. After we enable it, the screen is cut. But the web profiler will be here. You see that this is from part of it. Like I can see that for this page is view page controller, function handle, and root name is view frontend page page one. And this is good entry point for start learning Drupal, because you will see how it acts, like which action is handled by which controller, which routes are handling your request, and things like that. It's very good to start seeing how it works, what is happening. You can see all the events that are hit, how the routes are defined, when he loads the dynamic route, when static. So it's quite good to inspect what's happening in a Drupal. Of course, you have some other informations there. I'm sorry. The screen is cut, but also you can configure what you want to see inside your web profiler. So for example, the events are turned off by default. I always prefer to turn them on, because a lot of things happening in Drupal are based on the events. Actually, hooks from Drupal 7 and previous versions are starting to be replaced entirely with events subscribers. OK, how this works under the hood, let's see some code. So this is our folder structure, and this is our lib slash Drupal slash core. This is the core of your Drupal 8 project. So if you do everything proper, if you are not fixing some bugs in a core, you shouldn't put anything in this folder. The second folder is modules. You see that I installed the devil module, so I have one contribute inside this contribute folder. But actually, I'm putting all my custom modules that I'm building, and with the models you are customizing your Drupal inside this folder. So most of my work, if it's not teaming, will go to this folder. Second one is profiles. For the profiles, we can have different steps that run after deployment and installation. In sites, we are defining the configuration for our sites. Drupal can handle multiple websites, so one installation can handle multiple websites. And of course, there is teams folder where we are building our layout, our teams. You know what's vendor folder. And this is interesting. Like if you are using, again, PHP Store, you can have editor config plugin because the symphony and the Drupal doesn't have the same coding standard. For example, the obvious difference is that the Drupal is using two spaces and the symphony is using four spaces. And Drupal is also PSR for... It's following the PSR for standards. If you want to see what's happening when you got some error, you need to uncomment these three lines and enable settings local. And then you can add... You have example here. Example... Sorry, I move it already here to settings.local.php. So you can get all the errors printed on your screen. Okay, let's move to the request response. Same as in your symphony application where we have front-end controller, we have front-end controller here. It looks almost the same as symphony one. So it's based on kernel, Drupal kernel, which is based on symphony one. And the request in basic looks like symphony one. Like we have request, that request should have response at the end. And actually, it is always response but of different types. And we have events during entire process. So after our request is handled by kernel, the root defines the action. Some events are hit. We can of course interrupt that with event. Did some small example later to show you. And the only thing that is more complex in Drupal than in symphonies, you cannot read here but it's this part here. So this is basically exactly the same as a symphony but this is the part where Drupal has a lot of events to handle how you should view your content. The basic pipeline goes like this. Like after control returns render array, the view will be triggered by the HTTP kernel because the controller results not a response but a render array. If you return the response, the pipeline is done because it's a requirement that we must return the response. After that, the main contents to view subscriber is subscribed to the view event. And next main content to view subscriber checks negation request format is supported. Of course, on the root level, on control level, event level, wherever we can manipulate with everything of this. If negation request format is not supported for all 60s return, otherwise, we are going to the main context renderer interface and we are rendering response. We have four main content renderers. It's HTML, it's Ajax, it's dialogue and the model. And it basically looks something like this. This is HTML renderer. That's the one you will use most probably. And he has this big method which renders response and you will see that at the end, he's returning object which inheriting originally symphony response. Routing, as I already told you, like Drupal is using CMF routing. So in your standard symphony application, you cannot use, in easy way, you cannot use, out of the box actually, you cannot use the dynamic routes. But in Drupal, you have, of course. And this is the way how we define the routes. So it's the same as a symphony, but we have some additional parameters like permissions, like entity access. And basically that's, I think two that you will use most. And some default arguments. Permissions, for example, access content, permission usually any user can see your content, but you can limit that, for example, that only registered user can see the content. So if user is not registered, then login in your system, he cannot see this page. Controllers, controllers are just classes that have some public functions that return response. Basically, same as in a symphony, of course, things are not so easy, but this is proper controller. Like it's a class, it has public method, and it returns response. Of course, the controllers extend in usual situation. Controllers extends control base, and we get some helper methods. Like most of the helper methods are getting the services from dependency injection container. Like, for example, current user, we will get from the container, get current user. Language manager, we will get from container language manager. So if you are preferring to work with service oriented architecture in symphony application, you will see that this is almost the same way how we are working in symphony world. The one more interesting thing which allows much easier dependency injection to controllers is that this controller, controller base implements container injection interface, which means that he needs to implement static function create. The static function create gets container, and then it's quite easy to do dependency injection without any additional configuration in your YAML file, for example. So we need to have this public static function create method, and then we need to return the static with services we want to inject. We got them from the dependency injection container, and then in our construct we are just accepting that that's two arguments. So these two arguments we got here, we are rejecting them, and this is actually factory method nothing. There is no any magic. Regarding services in Drupal, there is plenty number of services, probably every module that you install gives you additional services, but this is the core. Services definition, you'll see only few specifications here. These actually are some parameters now, download are some services, but here is just debug from Drupal container debug with grep user. These are some services that you can use regarding the services. So for example, user authentication, user share, temp store, user permissions, user data, current user, which gives you authentication. Yeah. In this injection container in Drupal? In Drupal, the Drupal is using the dependency injection container from Symfony, and almost everything is built on top of that. That's the reason why you as a Symfony developer can use that quite easily. Events listener, I think this is like maybe the biggest improvement in Drupal 8. Events are replacing the hooks. Hooks, I'm not very familiar with Drupal 7, but from the research hooks were like global functions that you can use anywhere to hook to anything. Now it's done with events and subscribers, which is much better regarding performance, regarding clean code, regarding testing. I don't think hooks were impossible to test, and now every event can be tested. And regarding registering event subscriber is quite easy, so it's again identical as in Symfony way. Like define service in your model, tag it with event subscriber, define class for your subscriber that implements again Symfony event dispatcher event subscriber interface in your class get subscriber events, and this is, I will show you an example later how it looks like. Building custom module, it's very simple module. I will show you how to build HelloPHPUK model, then I will show you how to eject your service inside it, how to do the listener, and I will show you that actually there is no any kind of magic behind it because there is only convention and rules which are parsed with Drupal Core. So for building the Drupal model, the first thing you need to build is folder, of course. It's a module machine name, and then we need to add this, again, model machine name.info.yaml file. Previously in Drupal 7, this was .modules file, and this is all information that we need to add. Like this is the name of our module, this is the type and description, of course, the version of Drupal we want to use, and package is the place where we want to put this module in our administration. With these five things defined in your YAML file, your module is already visible to your Drupal application, so you can go to the back end and you can install your model. Of course, he doesn't do anything at the moment, but it exists, it can be installed. This is a little longer version, what we can define, we can define dependencies that are the modulus or some other things, features or something like that from Drupal that our model depends on, and test dependencies are the thing that if we start to implementing something and maybe in the future it will depend on something, we just put the test dependency and then test robots knows how to test our module. Configuration, which configuration to read? If we want to hide our module from the back end, we can set this hidden true, and this is good if you have, for example, only tests in your module, or you are building some model for only for showing some part of code to someone, and the version that should not be, it doesn't need to be defined because it will be auto-incremented with package manager. But as I already told, these five things are the only things that we need, and we see our module in the back end. We can click checkbox, we can click install, or even quicker, we can do the drush enable module. It's a little bit quicker, and if you are doing a lot of installing, uninstalling modules, it will save some time from you don't need to go to administration, do a few clicks to the navigation, enable, disable, it's much easier from the console, of course. When you do some configuration things, and when you change something, like same as in a symphony, you need to clear the cache. The only difference between symphony and the Drupal here is not clear cache, it's cache rebuild. So actually it's rebuilding all the cache. Our first controller looks, I don't know, can you read from the last rows? Okay, this is our first very simple controller. It's actually had only one public method, it's return new response. So we are returning the symphony HTTP response, and it won't go to this additional event flow of Drupal 8, it will return response, and immediately pipeline will be done, and this is our route. You need to see that we define the route here in hello phpuk.routing.yaml file, and inside SRC controller, because we need to, it's PSR4 standard, so we need to have namings SRC controller etc. If you remember from the beginning when I showed the composer Jason Fial, the core is in a lib, it's not standard PSR4, probably because of some keeping of some legacy things, but in future I think they will move probably that too, also to the SRC folder. Our route says, slash hello phpuk slash name, for default it's controller with action content, and we need to give access to the content, and this is what I want to show you, like when we include the routes here, hello phpukrouting.yaml, there is actually no any magic behind it, it's just method in a code, get in a route builder, we have the method that actually get all the routes definition, merge them, and you have routing built for your entire Drupal application. So if you search for info.yaml, if you search for services.yaml, there is similar principle to building all of this. And this is the result, like hello phpuk, hi Antonio, I see there is a root problem, this is second one, but okay slash Antonio will show me the same thing. The next thing I want to show you is that I extend the controller base, and I now want to get the display name from the current user, the current user that is logged in inside our system, that's the method get current user. So new response, hello phpuk, this current user get the display name, will give me the same result as this, because my username when I created the Drupal site was Antonio. The next thing I want to show you is, here I use the get current user from controller base from the helper method, by next example I want to show you how easy is to inject that. So I have this public static function create method, I get the user services from container, I return the new static with user services. In my construct, I'm getting the user services, I'm setting this private user services method to user services, and I can access in the same way to this display name in my controller. The next thing I want to show you is how to build your services. Again, it's the same thing as in a symphony. We need to define hello phpuk.services.yaml, please notice that this is in level above the SRC folder. So it's in a root folder of our hello phpuk module. So I want to build services, hello phpuk module dot say hello. This is not the rule, but it's much easier if you prefix all your services, rootings and everything else with the machine name of your module because you will get the unique routes in that way, and it's much easier to debug later what's happening. The thing I want to inject inside this simple service is the other service is current user. This current user is a Drupal 8 service. It's not symphony service. Like it's not from the core of the symphony. And this is how it looks like. I'm injecting the Drupal current user, current user, and I have only one public function which returns hello this current user display name. The next thing I want to do, I want to inject that service to my controller. So again, I have create method, but this time I'm injecting my service. So the name I gave it here, hello phpuk, say hello. I'm injecting, I'm getting it here, injecting to my constructor. And then the response is just this service, say hello, say hello. The result is hello, Antonia, it's the same. Just this is done with the services. This is quite simple example, but to show you how you can create your services, how you can inject other service from the Drupal, and how you can use it in a simple way. The next thing I want to show you, how to render this inside existing Drupal template. So in a symphony, we know there is rule that controller must return response. And usually if you are using base controller from the framework, we have this render function or something like that that in behind, it works in a way that creates response, give it the template, give it the data, and give the end result to the user. In this situation with Drupal, we can return the array with this hash in a keys, and he knows how to process that. Actually, we are, that's the part where additional, the pipeline I mentioned at the beginning of the talk, that events knows how to parse this, and then from this they know how to build response and serve that response to the end user. And result of this is actually something with the template. So my content is here, I could add the title, I can hook to some event to change that, do whatever I want with that. Okay, next thing is building my subscriber to event. If you list, I can show you later, I have my Vagrant machine up here, so and we will probably have time to show you some more things. If you list all the events that are happening, as I already told you, there is all list of symphony events plus some additional Drupal events. Usually the core modules, and if they are properly built in thinking of future, modules should also have some events that you can hook and change the things. So overriding some more elections should be, again in a symphony way, like hook to the event, change the date, or hook to event, change the response, or hook to event, don't do nothing, or just block the website, as I will show you now. Like, I will build a simple event here, which will show the message to the user that site is under maintenance. I want to hook on a kernel event, and the first one that's kernel request. So what I'm doing, I'm defining again the service, which is actually event subscriber here, we tag it with that, and it's class maintenance listener. That class looks like this. Like on kernel request, sorry, first we need to implement event subscriber interface, it requires to have this public static function, get subscriber events. We define events on which we want to subscribe, and which methods, which action will be hit when that event happens. In this situation on kernel request defined here, we want to run the method on kernel request. We get the event, we set the response, and we stop propagation. So on this event, we want to return response to the user and that's all, he doesn't go further in a pipeline. This is like Qt, if you have big website and you need to do maintenance in a very quick way, you just hook this to this event and show that message to users. So on first kernel request event, the response is served to that user. The next thing I want to show you is how to add URL to the backend to allow users to do easier configuration of your model. So again, all these things were done with the hooks before. Like you had the hook, then in the hook, you have some way of specification where to hook what. Now we have configuration files or we have event listeners to change the hooks. Of course, hooks still exist in a symphony eight, but slowly I think they are switching everything to events listeners and with idea probably to remove that in version nine. So we define HelloPHPUK links.menu.yaml and we define title of our URL, description, which is the parent URL of it, which is the route when we click where we want to go and what is the weight, like what is the importance of our URL. And when you add that, you got it here. Like HelloPHPUK model settings, when user click, he will go to the settings. Recap, I show you some basic things how Drupal work. It's one hour or 45 minutes of talk. It's quite short time to do all the things. So there is quite powerful API for Drupal. Like you can talk about Drupal, request a response for an hour. You can do about Drupal a routing API for an hour. There is quite a lot of advanced things built inside it. So one hour it's quite hard to give you better knowledge of it. The idea of this talk was to give you introduction, how it works. So if you have never worked with a Drupal, to start working because always the hardest thing is to start. When you start digging, when you start building first things, then things go by itself. But how powerful is it? For example, if you are building your custom module, you have everything that you need for build, for example, caching for the key value caching, for authentication, for getting all information from the user, for manipulating with the data. All that are inside the services. Of course, as you work more with a Drupal, you will get more knowledge what you can build with a Drupal API, send with your Drupal services built inside. Dependency ejection is the backbone of all Drupal. So same as a symphony application, everything is there. And you can get it quite easy. I show you the best way, how you can get it. You, of course, can get it with the static method that's built also in Drupal Core class. But the best way is to inject that to container and then get it once when you need it at the beginning of your controller. Building simple Drupal models is quite easy. It's quite easy to start, of course. If you are building some complex things, then you will need to invest more time, of course. I have more time. We can do a QA session. Or I can show you some, maybe some things from the Drupal console, more what you can do, like building content types and building the module without even writing the code, because you can generate all the skeleton from the console. So if you have questions, please raise your hand. Yeah. Sorry, I didn't understand the question. I think the best definition of the Drupal is that his CMF is more content management framework than just CMS solution. For example, basic difference between WordPress and Drupal is that in Drupal, you have everything ready for building any type of content. In other CMS, you probably need to install some plugins to do things that you can build in Drupal from the core. Also, Drupal is mobile-ready, so you can get the API quite easy from the core. There is multi-language website. There is multi-website. So it's quite powerful at the moment. And I think the idea of switching to the symphony framework was great because people who are building Drupal, their job is to build an amazing system for managing the content. And some other people shouldn't maintain the framework. There is no sense to build two things when there is really powerful framework outside. No, it's not built on any distribution of symphony. It's built on top of symphony components. But for routing, they are using CMF routing. And the list of the components I show you at the beginning, there is quite a number of slides. But you see the difference here? This is on the left, it's symphony full stack with CMF components. You know that standard edition of symphony does not include CMF components. And then here is distribution of Drupal. So the core is built on top of symphony components. Of course, there is still some part of legacy there. But it's built on top of the symphony, not standard edition of symphony. Like, for example, EZ is built on top of full stack symphony. Drupal, not yet. Maybe in future, I don't know. But at the moment, it is not built on. Actually, no. It's stored as a node. Like, they are on the same table on the same level. But then you have vocabularies, which build the entire structure of the website. But they are not using PHP CR. You have entity API for that. OK, thank you.