 Um, good morning everybody. Uh, thanks for coming to my talk. Uh, they put me first. So, how many of you were here this morning for the, um, pre-note? The musical? If you don't know what I'm talking about, you weren't there. If you know what I'm talking about, you're like, yeah, I was there. Um, so that got me, like, a little hyped up. That was my first pre-note at Drupalcon. Last year, I didn't realize they had pre-notes, so I showed up promptly for the keynote, only to be passed by, like, six superheroes going the other direction, and I was like, what just happened? Like, this is awesome, so I didn't miss it this year. And if you come next year, if you miss it, don't miss it. It's, um, totally ridiculous. So I come from the symphony community. Uh, we're back-end developers, so I don't know if any of us actually have any singing skills, so we don't get to do things quite like that. Um, so, today I want to talk about, um, symphony. I'm really happy to see this room is actually pretty darn full, especially considering we were all outside five minutes ago. First, I come from the symphony world, so this is my third Drupalcon, which is awesome for me, because they don't actually use Drupal. I've actually started to use it a little bit, um, but I just come from a totally different world, and this is one of my favorite conferences to come to because of the energy that everybody has, and because of the musicals. Um, I'm the lead, uh, contributor to the symphony documentation, so if and when you start reading that, you can thank me or send me a mean email, depending on, like, whatever your perspective is. We write a lot of documentation, so it just matters finding things. I'm also a writer for a campuniversity.com, which is, um, symphony and PHP tutorial screencast, and most importantly, you can help sell her out there. Um, I am the husband of the much more talented, Leanna Pelham, who's gonna wait for us now. Hey, Leanna. Woo! Yes, I like, good, like that. Good applause there. Very nice. When she's not in the room, sometimes I'll, like, have everybody, like, tweet at her and stuff like that, so now we just wave instead. All right, so, let's, uh, let's look at where we've come from, where we're going here, because my goal is, like, how many people have, have used Drupal aid a little bit? Okay, good. Good, good, good. Okay, so we can, so you guys are starting to be familiar with some of this stuff in the beginning. The whole point of this talk is that in Drupal 7, if you're a Drupal 7 developer, you are a Drupal 7 developer. If you wanted to do something different, you had, you had some other project that didn't need Drupal, maybe it was no content, you had to kind of learn a different skill set. That is no longer the case. And it goes the other way, too. I can actually look at Drupal 8 and understand what's going on. I have no right to know what's going on in Drupal 8, but because there's so much in common between the two, I can move back and forth based on whatever problem I actually need to solve. So, um, if I have anything wrong, you guys can shout at me, uh, because I'm not a Drupal developer, but apparently in Drupal 7, the way you make pages is the little hook menu stuff, so my dinosaur menu there. And I have a page callback, so favorite dinosaur, and then it returns the string triceratops. Um, because this is my favorite dinosaur, we have these little pins we just made, by the way. If you want one of those, they're up here. Um, so in symphony and stylox, it's totally different, but it's not really actually very different at all. So in symphony and stylox, we have, so let me back up, in symphony, we have something called routes and controllers, and those of you that have used Drupal 8 a little bit, may already know what these terms are. We have routes and controllers, we have ideas of requests and responses, and we have this really fundamentally important idea of a service container. And what's really cool is, in Drupal 8, we have the exact same thing. So these things right here, like the fundamental stuff that people have a hard time learning. They're wrapping their heads around this philosophy. Once you got this though, you have this for all of them. So let me look at, let's look at, uh, what, what, what, what is the fundamental stuff for a framework? Because all frameworks, whether they're in PHP or Ruby on Rails, they all basically work the exact same way. Which again, is a good thing, because it means we can actually move our, you know, uh, pick, pick whatever solution we need for whatever problem we have. So, this is stylox. How many people have, uh, seen stylox before? Okay, actually a few less hands than I expected. So stylox is a micro framework, um, built on top of the symphony components. So symphony is a framework built on top of the symphony components. Drupal 8 is a framework or CMS built on top of the symphony components. This is also that exact same thing. Except the entire application is those six lines. That is your entire application in one file. And what we have here is we're defining one page, you see, slash hello, slash curly brace name. So basically it's defining a URL, slash hello, slash anything. And when somebody goes to that URL, it's going to say hello, that person's name. And that's the entire application right there. So, let's say we are developing this. Hey, we're going to use stylox or something. So we go ahead and throw these six lines of code together. We spin up our web server. Or, we don't. How many people have used the built-in PHP web server? Okay, if it's like a third or so, it is awesome. So PHP 5.4 and above, which you are almost all probably definitely using since 5.3 is old and deprecated, has a built-in web server. You can go to any directory on your machine and just say PHP dash capital S, localhost, colon, whatever port you want to dream up, you have a web server running. It's not something you use in production. It's something you can use when you're developing locally. So you don't necessarily, like, I don't really use web servers on my local machine very often. I mean, this can't do everything, but I use this all the time. And it kind of saves the whole, like, oh, I got to figure out where my patchy config is or engine xconfig and set up a virtual host and all that. So, I have this one file, and now I've run this one command, and I have a working application. And that is all of the fundamental concepts, using all the fundamental, like, difficult concepts that are common across Sylex, Symfony, and Drupal 8. So you can see, you can't quite see up top there. But up top there, I'm just running the PHP dash capital S for localhost colon 8001. And the URL, slash hello, slash Drupal people, and it's just screaming that back to me. And yes, you can use that web server for Drupals, while I use it for Drupal 7 and Drupal 8. So these are the fundamental concepts here. Request, routing, controller, and response. And I'm going to go over those really quickly, because once you have your mind wrapped around those, which are not difficult concepts, everything just opens up. You can just use things, all kinds of tools, everywhere. So the first thing is the route. So this is going to be, like, the URL to your page or the URL pattern. So this is going to match slash hello slash star. So the curly brace thing in symphony and Drupal 8. I can't actually block the microphone when I say stuff. The curly brace thing is a wild card. So this is a page where slash hello slash anything. So this would be, like, pretty similar to hook menu, right? It doesn't give me nods. It'd be like, no, that was the wrong analogy. Okay, I'm getting more nods than nos. So it's the same exact idea. So I said earlier, it was like it's the routes and controller things are different, but they're actually just the exact same thing you guys were always doing. So you start with the route and then the route points to a controller, which is a word you'll hear a lot. Don't be confused. A controller is a function that builds your page. So that right there is just an anonymous function that builds your page. Maybe it returns JSON or full HTML. This one's pretty darn simple. And that's pretty much like the fundamental part of every framework. You have routes, which have the URL part, and they point to a controller, which is a function that you write to build the page. And that's it. That's why we only need these two parts here. It's also one little extra credit thing. Any time you have a curly brace in the URL, you can have that as an argument to your controller. And you can even do that if you have multiple curly braces. And again, this is the same in Silux, Symphony, Drupal, because they're all using the same code behind the scenes, which is wonderful. And then our job, our only job really, is just to make this page. So request. So again, I'll back up because I don't talk about this too much. Our job, even more abstractly as developers, is just to return a request into a response. Request comes into the server. Our only job is to create and return a response. If you can do that in one little line, awesome. If you need to load up a bunch of node stuff and go through the theming layer, awesome. That's just another way to get to the end goal, which is creating a response. And when you boil this down to its smallest pieces, this is done by having a route and a controller, which is just a URL pattern and a function that builds the page. And now we have it. And now, if you didn't know that before, you now understand how every framework works basically in every language. So that was Sylex, which is teeny tiny, so like what is symphony then? Well symphony is just Sylex with kind of a directory structure. So instead of just one file, when you download like a new symphony project, it kind of gives you just some directories and says, hey, maybe you can put stuff here and put this other stuff over here. We'll give you some organization, but it's still just that same routing controller kind of flow. So download the symphony framework. We have like a little installer here. So if you go to symphony.com and click download, you'll see this code here. Basically downloads like a little binary file, a little downloader file. Once you have that up top, so the previous step gives you a little binary called symphony. So you have symphony, new up there, symphony is the name of that binary. Once you download that, whenever you want to start a new project, it's just symphony, new, and then a directory name. And so this actually goes and grabs the latest version of symphony and downloads that onto your computer and puts it in that directory, runs some, you know, checks to make sure you have kind of a sane environment and all that good stuff. And it even gives you like this really friendly message down there to kind of tell you what to do next. Cool. And this is what it gives you. And one of the issues that you can run into in any framework is like the more files that they give you in the beginning, the more you're like, whoa, I don't know what's going on. So there's a couple non-important files that I'm hiding here just to make it look easier. Those files that I'm hiding aren't actually important. This is basically all that we have inside of that new symphony project. We have the app directory, which is configuration and templates. If you're writing anything that's not a PHP file, it's going to go in that app directory. Then we have the source directory. That's where your PHP files go. And by the way, in symphony, if you're creating a PHP file, it's going to be a PHP class. So this is where your PHP classes go. And that's actually it. Those are really the only two directories that you are going to touch inside of a symphony project. The other important directory is the vendor directory. That's where outside libraries live. They're downloaded for you. If you want to go kung fu and open up core code and look into it and mess around with stuff, you can go in there. But you know, you don't actually code in there. So that's just kind of sitting there for us. So it's all about app and source. And that's it. So same thing. Okay, so we downloaded the project. In Sylex, it was just write one file. Now we kind of get this little skeleton project. And then we just start the built in PHP web server, which is already easy enough members PHP dash capital s localhost colon 8000. In symphony, we give you like a little command that does it for you. But like don't get confused that behind the scenes is just running PHP dash capital s localhost colon 8000 so that you have a web server mounted right here. The only thing that's different between like Drupal and symphony is COA of that web directory. That's your document root. So it's not like the whole project is in the document root. This command here actually sets up your web directory to be your document root. So if you had a virtual host, you pointed at the web directory. So nothing else out of web is actually accessible. Cool. And that's it. So at this point, we've downloaded the project and we have started the built in web server. And now we can go to localhost colon 8000 and we have a working, well working, right? It's not it's a big error page. Maybe a working ish symphony project. And really what this is saying is hi, I'm the symphony pacman ghost. Things are looking awesome. As you can tell by this beautiful looking error page, you just don't have any pages yet. It's like this is actually a good sign at this point. Cool. So installation check. And again, what is installation? It's downloading symphony and then running the web server. Which is kind of like Drupal as well. Drupal is the extra thing when you install that it does a bunch of setup in the database. Symphony by default doesn't use anything in the database. So it's literally just files on your computer. If you are get fussy and don't like your project just rm-rf it. And it's gone. So it doesn't like touch anything else there. So it's just get the code, start a web server, you've got a working symphony installation. Alright, so let's build a page which we already know the steps is going to be route and controller. So I'm going to keep track of the files that we're modifying up there. And well, I'll have to help you because it's cutting off a little bit on top. This is so we need to first thing we need to do is create the route. The route is not a PHP file. It's configuration file and YAML. So it's going to be in the app directory. So our app directory is for everything except for PHP files. So this is an app. That's the part you can't see of their app config routing.yml. And what we define here is remember in Silux we just had like slash hello slash curly brace name. It's the same thing here in YAML. You have a thing called path that defines the path you route. And then the other job of your route is it needs to point to that function that's going to build the page. That's the underscore controller part which is not really a dot dot dot. I shortened it here. That underscore controller points to a class colon colon a method name. So your controller is always a function in Silux. It's an anonymous function. In a symphony framework it's just a function inside of a class. So class colon colon method name. Why is it app bundle slash controller? I mean that really can be whatever you want. There's some kind of rules about auto loading and things like that. But you can make your name space whatever you want. Cool. And then here's the controller part. So we created the route. Let's create that function. So inside now this is a PHP class right. So this is going inside of the SRC directory. So inside source slash app bundle slash controller we're going to put this file here. By the way one thing I did not mention earlier that I meant to is that bundles in symphony are kind of like modules in Drupal except that the current recommendation is that you sort of put everything into one bundle. You know for like Drupal people you're like no I have many bundles have many modules. It's just kind of a philosophical thing. If you are making something that's reusable that you're going to actually share across projects then you put it in its own bundle and make it decoupled and all that good stuff. But if you're building your app where it's like hey keep your life simple and put everything into one directory. So a bundle is just like a module. It's kind of like a directory and when you start symphony we kind of give you one called app bundle. So that's why you're putting yourself inside of here. So create the class, have the function. There's two really really important things I want to highlight here. One and you'll see this in Drupal 8n symphony and every other framework at this point. The only rule about this file is that the namespace has to match the directory structure. So the fact that we're in an app bundle slash controller directory means our namespaces app bundle slash controller. And then because our class name is polite controller we need to be in polite controller dot PHP. The reason it has to do with auto loading and the fact that you know basically it has to follow those standards or else the framework doesn't know where your class lives. This is the same thing with Drupal 8. So just follow those rules and you'll be in good shape. The second thing is remember I said earlier our only job as developers is to create and return a response from our application. So in symphony the way we do that is literally our controllers because our controller is a function that builds the page. So that function that we write needs to return a symphony response object which by the way is the same as Drupal 8's response object. Symphony response object which is pretty simple because what's in a response? Text and if you want to you know you can change the header or sorry a status code and then headers. So response is nothing more than like the content of your response and some headers. So in this case we're returning a new response from our controller. And how you create that response is totally up to you guys. You guys could make a really nasty curl request out to a java application here and have it do the work. And be like oh see here's a response. I took the text from that API endpoint stuck in this response. Symphony doesn't care what you do in your controller it's entirely up to you to do whatever work you need to do to return like the all important response object at the bottom. Cool. And with that we have a working page. We define the route, we define the controller function and it returns a response. And that is the symphony framework. When I do symphony trainings like I stop at this point I was like you guys now know 50% of symphony. It's the route controller thing. This route controller thing is the same in Sylex symphony Drupal 8. You see this flow. It's very very simple. Now it is simple but I'm gonna look ahead to like how what kind of debugging tools we have. Like what if something's not working like what routes do I have in my application. Maybe I inherited an application that has like 500 routes and I'm trying to figure out where things are. So when you use the symphony framework you have a number of tools. First off, you can't see up there I'll tell you what that command is. We have a okay so Drupal has Drush. We have something called app console. It's the same thing it's an executable file that's inside of your project basically. And you can execute commands on it that help you debug. So the part that's cutting up on top there is I'm calling that app console command and I'm calling a sub command called debug colon router. Now basically saying hey application show me all of the routes you have in the system. I want to see like what the pages are inside of our system here. The vast majority of these the profiler thing I'll show you that in a second that's just a debugging tool. The key thing is there's R on the bottom for slash hello slash curly brace name. So you can always get a you know a picture of like what are the routes in the system. This also exists inside of Drupal 8. It's a contrib project called Drupal console. It's just like app console and you can also list all of the routes inside of Drupal 8. Cool. When you're using symphony framework. So my favorite things you have something called the web debug toolbar. When I don't have this I kind of panic. Sometimes if I'm not in a symphony framework project I'm like I need my debug toolbar because it has really important stuff like if I hover over right there it actually tells me what route was matched on this page and what controller is being called. So he's telling me polite controller colon colon say hello action is what's being executed on this page. So like where am I what code is running this page. It's telling you right there. Also as obviously like the amount of time it took the memory. It tells you like how many database queries were made which were none on this page. But if you do make database queries it tells you all that stuff. And if you click any of these icons here you go into another page which is called the profiler which is like the web debug toolbar times a hundred. Has like way more information. So in this case I can actually see all the log entries that were made on that request. The routing tab there which show me all of the routes in my system and show me which one matched for this. Security to tell me what user I have if I sent any emails on the request. It tells me about that on the emails. And then doctrine is the engine that we use for talking to a database. If you click on doctrine you'll be able to see every single query that was made on that page. You can even do like an explain on the query to like see why it was slow and all that good stuff. But the most important one is the timeline. This actually shows you everything that happens from request to response inside the symphony framework. Because us as developers all we do is write the route and then the controller. Like everything that happened between and around that like we don't really know something else is doing that. This gives you vision into what that is. I mean it's really supposed to be there for profiling. To be like oh which part was slow. But this is actually a great way to be like what's going on behind the scenes. Also two things I'll say about this is you can actually add your own stuff to this. So there's an object in symphony where you can basically say hey I want to start timing something called API call and then you do it and then you say I'm done timing that. And then when you refresh and go into this you're going to see that line inside of this as well. So you can add whatever you want into the profile here. The second thing I want to say is this also exists in Drupal 8 which I find fascinating. It's a contrib module called there's a couple of clapping back there. Yes this is huge it's amazing. This is how I learned how Drupal 8 works because I went here and I said okay let's just start opening up the you can't see it here but those are class names and functions. It's telling you like what functions are being called. So I was like okay let me go to the timeline and just open up these classes. Like see what they're doing. See how Drupal 8 actually works behind the scenes. So it's called Drupal Profiler. So it's a contrib module I just installed it like a few weeks ago it's it's working really well. So again we've done route and controller. So in order to create a page in symphony you touch two files. And that's it. But in the symphony framework we can do even less work and we typically do not everybody does this. One of the things about symphony for better or worse is we give you options. We never like say you have to use YAML. Every time this configuration you can do an XML, a YAML, PHP or annotation. And in our docs we even have tabs for each of them. Yes I have some very very good core doc contributors that like go out of their way to like do an XML version of every single code block we have on the site. So instead of doing routing in YAML you can do it in annotations. So if you haven't heard the word annotation before I'm guessing a lot of you have. Annotation is the word for a PHP comment that is actually parsed is configuration. Some people absolutely love them. Some people absolutely hate them. I happen to be on the first side of things. People that hate them are just because like their comments and so they're like functionality shouldn't go into comments. Fair enough. If you don't like this then you stick to the YAML version. But I like this because in order to create a page I create this file in this file alone. And that's it. So like one step to create a page inside of symphony. And as an added bonus right when you're looking at this six months from now you're like oh yeah oh yeah there's the URL to this page. It's right there. I don't have to go dig somewhere else to see like what URL is feeding into this controller function. All right so that's the route and controller. That's the first half of symphony. Oh question. Yep. Oh good question. So if you create a route in YAML and this way and you can also do an XML or PHP which one wins. And the in the same it's the answer is the same in Sylex Drupal and symphony. I know I'm like a broken record. The routes match from top to bottom. So if you have two routes that are like they have the same pattern slash hello slash curly brace name then it's going to match the first one. And that's because the router actually just goes one by one to your routes and as soon as it finds the first one that matches it quits which is actually kind of good for performance. So if you have like a thousand routes or something you know it maybe only goes to like 50 of them and finds the one and then stops. Yep. Oh good good good. Yeah yeah. Okay good. Oh man. Love it love it. Okay. So the question was like yeah but let me repeat my question which is first which actually one ends up being first. So in symphony like unlike Drupal and Drupal when you have a Drupal 8 module it just iterates over all of your modules and like looks for a routing.yml file and loads that. So you like I'm sure there's some ways to control that maybe but I'm exactly sure. In symphony you have that main app config routing.yml file that I showed earlier with where we put the YAML route. That's the only file that symphony loads to load routes by default. So what I didn't show here is in order for this to work there's actually an entry inside of your routing.yml that it basically says go read annotations from this directory. And so the answer to does an annotation route win or does a YAML route win it depends if you have the YAML route first and then the import or do you have the import first for the annotation routes and then your YAML route below that. So it's all explicit inside of that YAML file. The import for reading annotations like this is actually in there by default. So I didn't show up when you actually like download the project and go into your app config routing.yml you'll see three lines there that say hey go read annotations from the controller directory. Alright so second half of symphony is all about these services and containers. Let me give you guys like 30 seconds of really really simple non-computer science theory service because you'll hear that term a lot is a useful object. Sure there's like even better definition of that like for me like this is what it means so you hear probably like hey you should turn that into a service what are they talking about? They're talking about having an object that does some work for you and I'll show you an example in a second. So services are just useful PHP objects like for example a database connection where you can like maybe call a method called query on it that's a service it does some work for you it's useful it's called a service it's just kind of a computer science sort of term. Second the other important term is container. Container is an object but I want you to think of it almost like an associative array. It's an object that holds all of your services. So obviously in a symphony application or a Drupal application we're going to have lots of useful objects you know database connection translator object. The service container is a place where we just kind of put them all into that central spot. There's more to it than that but like that's the most important part. So if you get access to the container inside symphony then you have access to all of the useful objects that are inside of it. And in symphony and Drupal those come pre-loaded with a bunch of stuff. Like for example like in symphony this is actually really important. In symphony like nothing everything that does work in symphony even like the routing controller flow is actually done by a service. So if you ask me like what symphony does the answer is sort of nothing. There's just this big bag of useful objects and those objects do the things. And if you want to do some work inside of symphony like log something which I'll show later all you need to do is say like what's the name of the service in the container that does logging or sends emails or does something else. Once you have that that you're able once you have that name then you can go out to the container and say hey I need the logger object and it'll give it back to you and it's what actually does all the work. And that's yes and there is the question is there one container? Yes there's one container it's the most fundamentally important object inside of like symphony or a troupler is one container. Yep. It's not a singleton nothing is a singleton there's no static context but if you know the singleton pattern you can kind of think of it like that because there is only one of them. Nothing stopping you from creating multiple ones though. So inside of symphony so now you guys can see it so remember I talked about that app console script that's the way to kind of like get debugging stuff from symphony. So earlier I ran debug colon router got the list of routes debug colon container gives you the list of all of these services inside of there. And right now there are actually 224 useful objects inside of a standard symphony framework install. Those for the most part don't do anything by themselves they're just sitting there waiting for you if you want to to make use of them. I mean Drupal does even more. So for example there's one service then container called the templating service and you wouldn't necessarily guess this you'd read the docs or you can even search this if I run app console container colon or debug colon container. And I put like temp in there it'll actually give me a list back. It's like here's 10 services matching that term and you can kind of like select and get more information. So there's one called templating and it's our way in symphony to render tweak templates. So now I know that like I said it's all on symphony about figuring out what service does the work that I want to accomplish. So in our controller right now we're just returning a response inside of our controller we ultimately maybe want to render a tweak template. So we find out that it's the templating service that does that. So inside of this container I said it's like full of useful objects. It's basically an associative array. So like every object has a nickname which is a string. So this one's nickname happens to be templating an all lowercase. Okay so when you want the templating object later you'll ask for it by that little nickname. So now we know that we have this routing controller flow and we have all these random useful objects that are sitting out there waiting for us to use them. So this is good. So since the only place we really code to build a page at least now is the controller what we want is to get access to the container in the controller. If we do that then we are dangerous because we can make use of whatever objects we want. So in symphony and there's of course there's always like multiple ways to do this but in symphony your controller has a protected property called container. The reason it does is because you extend a symphony based controller and symphony detects that and injects the container so if you're like more technical you know you have a more experience with that like this is not magic this is something that does this behind the scenes but basically means when you're in control you can say this arrow container and that's the service container object and it only has basically one useful method on it git because like I said it's basically an associative array of useful objects. So we're going to say this arrow container arrow git templating that returns us back to that useful object and then we can just call a method on it. How do we know a method to call on a service? You know that's you read the documentation to figure out like how does symphony's templating you can also look at this here and see oh this is an instance of this time to twig engine so if you like diving into the source code and finding what methods are on stuff you can do it that way so you don't have to like dive in a source code because we have great documentation on all this but so we get the service call render on it and then we pass it you know the polite slash say hello dot htm of that twig that's going to be the name of our templates and then we pass a variable into that twig template so the my name on the left will be like how that variable is called in twig and its value will be assigned to name so I've made those different for clarity purposes and then still we always return a response um and by the way like I'm showing you guys some of the longer ways of doing things we have shortcut methods and symphony framework to do this kind of stuff so normally you'd actually say this arrow render instead of this arrow container arrow git company render I'm showing it this way because this is really what's going on behind the scenes when you say this arrow render which is what you'll see in our documentation that's a shortcut to go get the templating service and call render on it so I'm showing us like really the low level way because I want us to understand that it's all about these services behind the scenes that do all the work but your code will actually in reality be a little bit smaller than this which is cool so we're rendering a template called polite slash say hello .html.twig and just as a reminder because I got rid of my yaml route we've only touched one file so far in our project this one right here we built our page and now we're using the templating engine so the second thing is remember that so polite slash say hello.html.twig that's the name of our template symphony looks for templates because they're not phpcode in the app directory and it looks for the app resources views directory so when we say polite slash say hello.html.twig it just looks for app that's the part you can't see up there app actually app slash resources they're both hiding app resources views and then polite slash say hello.html.twig so symphony is like a main spot where templates live you can put them other places if you want there's one main spot that the templates live and when you render something symphony just looks there and it's pretty straightforward I'm not going to talk about twig other people are talking about twig it's amazing this is me printing out a variable very fancy and also extending a base template so now we've touched two files to create a symphony project that base.html that twig is your base layout you can do whatever you want with it we actually kind of deliver a very basic one to you in a project to start but you'll customize it so we've gone one small level up which is we have the routing controller flow and now we know that there's this service container floating around and it's something that we're going to make use of from within our controller because it's this big bag of tools so what else does symphony do what other useful objects are there and like the reason I part of the reason I put this up here is because if you want the answer to this question can be nothing you could not use any of the objects in the container that's totally up to you if you have a different way of creating your page inside of your controller and symphony by all means use your other tools you don't have to use any of symphonies built in tools they're there as a tool like optional tool if it's useful to you but sometimes I see people like using symphony tools in a very like they have a really advanced crazy edge use case like maybe it's an HTML form that's like really really weird and they try to put it in symphonies form system and they get really aggravated but when you back up you're like dude you had a form with two fields just make an HTML form and then handle it in a controller like you don't have to fit everything into the symphony tool set if it doesn't work well for you in your use case so for example what does symphony do it has integration with a library called doctrine which is an ORM for talking to the database and what I want you guys to notice here is how do you use doctrine inside of symphony well it's a service called doctrine.orm.entityManager so like everything in symphony is just a service so how does symphony talk to the database it doesn't this service does though so you can use it or you can actually again if you have like a really advanced use case you can go one level lower and there's another service in symphony called database connection which is actually also part of doctrine and basically you make this is not entirely true you make just raw SQL queries to it and then you fetch results out this is like a small wrapper around the PDO object and it's in the container there for you to use forms I mentioned this earlier this is what it looks like to make a form in symphony you actually like build this nice beautiful object and you tell it I have like an email a username gender field you kind of describe it you eventually pass this into your template on the bottom I'll show you that in a second and in the middle you actually process the form it will like go grab all the post parameters for you and like do validation so it's like a lot that goes into symphony's form system it's probably the second most complicated part of symphony after security but it's one where like the more you learn about it the more you're like this is awesome and this is what it would look like inside of your template to render that so you don't have to render it by hand you just sort of say you kind of render your fields one by one and it kind of builds the HTML form for you which of course you can customize how this looks in all kinds of different ways it's called form theming in symphony so this is really really powerful or you can just do it yourself so again optional tools like symphonies like there and like these tools are wonderful I use them but especially when you like learning if like you're like dude I just don't understand the form thing yet I'm having problems cool go and do a twig template make an HTML form and then in your controller just go and get those post parameters manually so that's symphonies request object obviously there's some extra code that would go around this that's symphonies request object which is the same as Drupal's request object and if you want to get post parameters dollar sign underscore post off of it you say request arrow request arrow git query parameters or request arrow query arrow git why is it request arrow request what kind of idiot would make a property called request on a object called request now it turns out apparently if you read some things somewhere like post parameters are known as request parameters so hence why request arrow request arrow git and there's infinitely more things that you can do in symphony via tools in the core of course but also bundles so just like you guys have contrib modules we have community open source bundles the number one job of a bundle like why would I bring a bundle into my project and this is the statement's exactly true for Drupal 8 and modules the number one job that an open source bundle brings to your project the thing that it does is it adds more services to your container and that's basically it's like oh I'm gonna get this bundle which helps me talk to Amazon's SDK because when I install it I suddenly have a new service in the container called I don't know aws underscore s3 and that's an object that's useful that can help me talk to Amazon aws s3 alright so we have services in the container so next thing we need to do is actually put some of our own core well actually let me back up so we have the routing controller flow and we have services in the container so this next step has nothing to do with symphony at all but it's like fundamentally important to like the new pattern that's kind of like in your blade the pattern we use in symphony a lot and it's creating your own services so remember service is just a useful object so I'm talking about creating your own classes to organize your code because once upon a time okay so we all know like we don't wanna duplicate code et cetera et cetera we wanna reuse stuff so normally if you have like a whole bunch of code inside of give like 20 lines of code like in old school PHP we take those 20 lines of code that maybe help us generate a thumbnail or something and we put them into a flat function called generate thumbnail because now we can reuse it and it's kind of like over there by itself so in symphony and drip late we're gonna do the exact same thing but instead of a flat function it's just gonna be a function inside of a class but the exact same thing you're like oh I wanna isolate this okay function inside of a class and that class is gonna be a service class but again that's just kind of computer science-y sort of stuff so right now when we go to slash hello slash Ryan or Drupalcon or whatever it just says hello that name so we have a new requirement where we're gonna actually generate a random greeting like oh la Ryan or something like that so where should we put this we could put it in our controller totally you know you guys can imagine what the code would look like you know a little ray of random things do an array rand et cetera et cetera pick out a random greeting boom all the code in the controller no problem but you're supposed to keep your controller skinny which you know it's a way of organizing your code you're supposed to whenever you have big chunks of code that do a job take that out and put it somewhere else so that it's you can reuse it and it's a little more clear and your controllers are easier to read so what we're gonna do in symphony or jubilee is create a class so this class the name of this class the location of this class none of that is important except your name space has to match your directory structure and your class name has to match your file name dot php so there's always that requirement but otherwise you can put this name this however you want so I have a class called random greeter and I have a public function called randomly greets and the code there is super super simple so nothing special at all I'm using a private static property for the greetings but you know this is just basically what we would have done in a flat function before super straightforward just put inside of a class cool so that was nice so now how can we use this we just use it so if you put things in a flat function you just call that flat function the only added step here is you need to instantiate your object first so that's greeter equals new random greeter that's kind of the extra step and then you just call the method on that object so create the object use the object same pattern though as before as with the flat function same goal of organizing our code so again none of this has anything to do with symphony symphony doesn't care that you're doing this doesn't know you're doing this it's just us being like you know what I want to organize my code a little bit better so let's up the ante a little bit could we log which greeting was chosen maybe that's really important we're having a problem somewhere we want to log that well question number one is like well does symphony have built-in logging and it turns out it actually does and we know that if symphony logs if symphony has the ability to log out of the box there must be a service that's actually doing that and it turns out there's a service is called logger so if you want to log something in symphony you go out and get the logger service okay so now inside of our controller very simple this arrow container arrow gets logger so again so I was like go grab the service you need and then call a method on it how did I know to call info on here well either opened up the class that's the logger or I just googled symphony's logger and read the documentation on what methods the logger gives me okay so perfectly straightforward this is another way we're just like using one of those optional tools love it okay so this is where things get interesting could we log something from inside of random greeter so the copy and paste method would give us this so I'm inside of class random greeter I've just basically copied that this arrow container arrow get thing probably most of you are gonna be like that's not gonna work because there's no container property notice this class is not extending anything why is it not extending anything because it's not useful for my application to make it extend anything symphony doesn't know or care about this so we don't have to extend anything this is just our core class there's nothing magical about this at all we don't have a container property here so it's not going to work in fact the whole container property thing is totally special to controllers so don't expect to like magically get a container property anywhere except for your controllers so this would be you know you know property doesn't exist or method called on a non-object or some error like that oh my god so dependency injection how many people have heard this term by this point good good good good fanciest term for the stupidest simplest idea of all time so uh uh dependency injection is when you pass a function all of the values it needs to do is work the ridiculous example I give is you would never make a function called add and then not give it any arguments like you figure out what I'm adding you know I'm not gonna pass you the two values you go out to some global scope and figure it out yourself I mean this doesn't make any sense so we take this a step further inside of uh, Drupalade and symphony and the more realistic example is like you used to have flat functions and on the first line of that flat function you'd say like global dbh you would actually go outside of the global scope to get some database handler object or something like that that's not dependency injection your function needs the database connection so you should actually pass that in as an argument so that's all dependency injection it's all what we've been doing all along even when we use the global keyword we're probably like ooh I'm not supposed to do that um so in practice since we have our functions in classes what this means is whenever your class whenever any function in your class needs an outside object or an outside value you're gonna add an argument to your construct function and put it there and then what are you gonna do in your construct function you're just going to set it on a private property basically save it for later and that's it if you wanna get really fancy you can you know like look up like the class or interface that the the logger implements but that's optional that's cool it's cool for auto completion but you don't have to do that then now that we have this private logger property we just use that down there so instead of this arrow container arrow get logger we just say this arrow logger and call it now we are missing a step here like don't expect that to work you should be thinking you have a like who who's gonna pass that there the point is this class now because that's a required construct argument cannot be used unless whoever instantiates it passes it a logger interface object so as far as random greeter is concerned he doesn't care who's going to use him whoever uses them has to pass in the logger so inside of our controller we'll just do that we'll say greeter equals new random greeter and we know how to get the logger inside of our controller we say this arrow container arrow get logger pass the logger into the construct set it on a property and then we use it later that's the dependency injection pattern and you'll do that over and over and over again if all of a sudden our random greeter needs to render a template we're gonna add a second construct argument for the templating object set that on a second property and then use that property down within one of our functions cool? so that entire thing was all about code organization dependency injection had nothing to do with symphony the last and very very important piece of this is we're gonna actually teach symphony how to instantiate that random greeter object which is a service because it's a useful object does some work for us we're gonna teach symphony how to instantiate that for us and the way to do that is with the yaml file and you can't see it here but it says app slash config slash services dot yml we were in the app config directory earlier because there's app config routing dot yml so when you wanna teach symphony's container how to instantiate your objects you go into this file and you just describe that so instead of us instantiating our random greeter we're gonna have symphony do it for us in order for us to do that we have to say hey symphony I have a service whose nickname is gonna be my random greeter so that's the key I'm gonna use later to get it out and when you instantiate it when I ask for it and you need to instantiate it its class is that class and it has one constructor argument which is the logger service if I had multiple constructor arguments they would just be like another dash on the next line and also see the only kind of weird thing in here is that at symbol if you take off the at symbol it will literally inject the string logger it will pass the string logger which may be what you want like if you're passing configuration totally legit but if you want it to be a service like no no no it's not the string logger it's the service logger you put the at symbol and then the service container is like oh yeah yeah okay I'll go get the logger service first and then pass that in as an argument so this is enough to teach symphony how to actually instantiate that object and now we can go to our app console debug calling container my underscore random underscore greeter and our service is now in the container so whatever number I had before like 216 services in the container is now 217 services in the container cause our guy's in there how do we use that? very simple we just don't have to instantiate the object anymore that's like it's such a small thing not that instantiating the object was difficult but we've just centralized that so this arrow container arrow get my random greeter and that's it the kind of cool thing about this and actually turns out to be huge is that in our controller which is a kind of our day by day code we don't really care how many constructor arguments that service has so if later we're using this in like 50 places in our code and we decide it needs a second constructor argument we can just go to services.yml and give it a second constructor argument cause this code's just like just give me the random greeter whatever it takes just give that to me also corollary any services in the container is always only one of them so if you ask for my random greeter like 10 times in a request you just get back the same instance second thing I'll say is it's also lazy I keep describing the container as a array of useful objects it's actually an array of directions on how to create those objects if and when we ask for them so if we go a whole request response cycle and nobody ever asks for my random greeter we don't use the memory to instantiate that object that object is never actually instantiated so you can have 230 useful objects floating around without actually adding any extra overhead you're only actually instantiating them if you use them okay and let's see here okay I'm gonna go through this very quickly this part here so at this point you guys know everything you need to know like all the most fundamental things of using symphony go download it, start playing around with it you're good to go this last thing very quickly is extra credit this is a little bit harder but it's also something that you don't do every single day so symphony has events just like Drupal has hooks and Drupal 8 also has events so you think of events and hooks is basically the same idea it's a way to come hook into a process and the way it works in symphony is you have the events are less about like what you want to do like hook menu and more about timing as symphony goes through that request response router controller flow it kind of has these hook points at various times during that process so if you want to have a hook point very early on in symphony the event you want to listen to is called kernel.request and the one that's really late is called kernel.response so I keep saying that you have to return a response from your controller guys like you, that's our job return a response from the controller okay well technically and in a symphony framework most people do that most people do not go to this extra level of fanciness I just want to like see what can we do with symphony here what kind of craziness can we do so let's say that we come from the Drupal world and we love the render array so we're like you know what I gotta get I gotta get some render array up in my symphony okay so we start doing something like that maybe we even put like some hashtag stuffs on there just to make us feel at home so now I'm just returning this random array with template key and variables key and that's it if you do this you will get a terrible exception that says I'm so angry right now because you didn't return a symphony response object from your controller and I told you to do that under all circumstances well it turns out you don't have to do that there's an event after your controller is fired that if you don't return a response from your controller you can add a hook, a listener to this event and you can basically try to transform whatever that value is into a symphony response so very quickly this is actually what a listener which again is kind of like an implementation of a hook looks like in symphony or Drupal 8 the important parts down there and they get subscribed events you're basically saying I listened to an event called kernel.view it's one of symphonies core events and when that event happens I want you to call my on view function which is that function up there which is empty right now and I also since I know we're gonna want to render a template inside of this class I've already gone done the step with the dependency injection where I'm injecting the temp I have the argument for my templating object because I know in a second I'm gonna need the templating object to render a template okay so the next step is we just register this as a service so it's pretty common I was gonna be registering as a service the difference with this service though is I don't intend to use this in my controller like our random greeter we use in our controller I want symphony to use this I wanna hook this into symphony so it actually calls my function when that event happens so the way you do that and this is a little bit more advanced but you'll see this all the time in symphony and Drupal 8 is with a tag so a lot of times you're like I need to like hook into core in some way when you like Google how do I add an event subscriber or how do I add a I don't even know a custom route loader something that's really custom hooking into the system the answer is always going to be make a service and then give it a specific tag when symphony boots it looks for all services that have that kernel.event subscriber tag and it kind of like consumes them says these guys are event listeners so it's a little bit more advanced that's kind of like a way to say my service is important it's not just a normal service I need to do something in core in some special way so it's a finite number of those tags in the system so cool so now inside of our on view function it's gonna be called after our controller and basically I'm not gonna go through this specifics here but we can just get the result back that array that we return from the controller and then down there in the bottom we're like okay we had a template key we had a variables key and then just like we did in our controller earlier we'll say this arrow templating arrow render remember I passed the templating service in as an arguments my controller and put that on a templating property and then we just set the response in the bottom cool so I said that part is something you don't do every day that's like us being like can we kung fu symphony we do something we're not supposed to be able to do all right so last thing like you guys getting into this stuff was a question question yep go for it oh good yeah so the app console that we can view the services is there a way to view listeners there as well there actually is there's also something in the profiler we have like a debug colon event dispatcher or something like that and you get a list of all the listeners of the services which is really key because like listeners are magic there's no way you can't like follow execution flow and see listeners so what I'll leave you guys with is like extra things because I want you guys to like get started with this like it's not hard if you have a problem that you need to solve that doesn't involve a CMS use symphony or use Sylex the little tiny thing like people use Sylex for all kinds of stuff so one thing we have in addition to like just starting a new project we have a symphony demo so that same installer we used earlier we said symphony new and then a directory you can say symphony demo and it downloads a full kind of fully featured symphony application talks to the database does forms you can look around there it's all like really well annotated with like here's why we're doing this so it's really really good it's actually kind of a newer thing that we have so older symphony users might not even realize this exists but it's fantastic we're always adding more stuff to it this is what it looks like you have like security you can log in all kinds of good stuff we even have this fancy button where you can like click the button and see the source code that's like yeah in charge of that page second thing is especially when you get into this for the first time you don't have to do this like I don't mean to step on anybody's workflow but like PHP storm is a wonderful ID it helps you with auto-completion of the classes there's also a ridiculous symphony plug-in so just go to bit.ly slash PHP storm dash symphony it gives you auto-completion all kinds of amazingly weird ways our documentation is gigantic I think it's like a thousand pages if you print it out then also our site campus university if you want screencasts we have like screencasts all up and down about symphony and all the scripts are free too so if you want to just read the scripts and look at the code blocks you can just go there and do that right now I said also like use Sylex use Drupal Lake because they're all using the same things so I'm gonna go through this because you guys already know this so all this is like you have three tools now symphony, Sylex and Drupal and really there's even more stuff that uses the symphony components so that your world is even bigger than this and you can go to and from them without having to like relearn a whole thing because we just learned all of the concepts in like 40 minutes routes controller services that's it, it's all the same across them so you can use Sylex to learn Drupal Lake you can use Sylex to learn symphony you can use symphony to learn Drupal vice versa so choose whatever tool is actually going to help you and that's it thank you guys very very much um if you guys want to get started in symphony and you like the screencast thing I have a coupon code there on the bottom see what I did there it's Hollywood D8 see I was trying to think of something clever right? I'm gonna keep that up for like a day so go on to Camp University and that gives you like a free all access month and we don't ask for your credit card or anything like that so it's no weirdness and if you like it you guys can tell us and I think I'm probably over time so if you have any questions come down and ask them otherwise enjoy the conference