Kohana: A Lightweight PHP Framework

[Seminar] [Kohana: A Lightweight PHP Framework] [Brandon Liu] [Harvard University] [This is CS50.] [CS50.TV] Hi everyone. My name is Brandon I’m a junior here at the college doing computer science, and today we’re going to talk about Kohana, which is a PHP web development framework Today is going to be a live coding seminar, so I’m basically going to spend 5-10 minutes explaining what Kohana is, and then I’m literally going to build a super simple blog for you right here literally from scratch We’re going to download the code from the Kohana website, and we’re going to start building a blog, and hopefully it’ll be very instructive, because you’ll see perhaps maybe I’ll make some mistakes, and you’ll see me recover from them, or you’ll see my thought process as I build through this blog, and meanwhile, you’ll also get familiar with the framework itself Hopefully it’ll be a very instructive exercise First, what exactly is a framework? If you’ve been taking CS50 so far, you haven’t really worked with any frameworks yet, and the thing is this You’ve probably done 1 web development pset already, and let’s say you continue to build websites and keep building websites You’ll start to notice a few things The first thing you’ll notice is that you’re probably doing the same things over and over again all the time, things like cleaning user input data, things like organizing your files in a certain way The other thing you’ll also probably notice is that your code may start to become very, very messy, and you may leave it messy and just have a very hard time maintaining it, or you may start to structure your code and making it modular in certain ways to make it more maintainable This is where web frameworks basically came in These people who had built a lot of websites, they said, “We don’t need to redo this every single time we build a website.” “Why don’t we just make a package that does all these things for you every single time you want to build a website?” And so that when you make a new website, you just focus on what exactly this particular website is about You don’t need to repeat all the various configuration and separation of codes and rewriting code that you often have to do when you’re making websites The idea is that a framework allows you to write a higher-level code without having to worry about lower-level details A lower-level detail might be something like dealing with cleaning user input data That’s something that you shouldn’t really need to worry about You should focus on what your web allocation is actually about It eliminates a lot of boilerplate code It is an architecture for your project The most popular one would be Model-View-Controller, which I’m going to talk about in a second And a lot of times these frameworks embody a set of procedures, rules, and best practices for you to use so that when you adopt the web framework you have to write your code in a certain way, and it’s generally an agreed upon set of principles by the community that is generally accepted to be a good way of writing code It makes your code more maintainable, more usable, so on and so forth And finally, the thing I want to emphasize about frameworks versus libraries is this idea about inversion of control, and the thing is this The difference between a library and a framework is that with a library you are still writing the main program, and you’re sort of invoking the library and calling upon the library to do something for you The difference between a library and a framework is that the framework starts out with the control, and it invokes your code, so you can think of it as–this is why it’s called a framework– the framework provides this frame and structure for your code, and you fill in the holes, and this will become more apparent in a second when you see me start to write code within the context of the framework You’ll see that I’m filling in the gaps, and the framework is kind of controlling all the moving pieces, and I have to put the pieces in the right places Today we’re going to talk about Kohana, which is one of many PHP frameworks There are web frameworks, and there are ones in virtually every single language, and I’m picking Kohana because Kohana is arguably and generally recognized as the easiest PHP framework to pick up It’s the most lightweight There are other ones out there that come with many, many more features, but they tend to be more difficult to pick up And finally, Kohana uses the MVC architecture It’s lightweight enough that we can literally build a project right here right in front of your eyes, and you can pretty much follow along pretty easily What is the MVC architecture? It stands for Model-View-Controller, and maybe if you think about the code you’ve been writing so far for some of your web development psets you may be able to see some of this, but usually when you start writing a more complex web application, the division between these 3 segments becomes more and more evident I laid out the MVC here sort of as a stack, and often you’ll hear people talk about stacks in web development, and this is to illustrate the idea that each layer, each component really tries to only communicate between 2 other components Someone accesses your website as a client or a browser They interact with your program through the view code The view code interacts with the controller The controller interacts with the model, and the model interacts with the SQL database And there is no hopping in between if you write your code properly What do these things do?

The model essentially is the piece of code that deals with your data Anything that deals with your database, with the objects that you store, or retrieving those objects in the database, that’s all handled by the model Maybe you have objects in your database We’re going to create a model having to do with posts, so a post may have some attributes to it You may have functions around storing those posts or retrieving posts or filtering the posts and so on and so forth, and that’s all the code that’s handled by the model The controller is sort of the application logic, and a lot of different things can go in the application logic If you’re talking to a different API, that may be where you’re dealing with the application logic If you’re trying to have to bring in data from multiple different models and have to combine them in some way, that often may be handled by the controller For example, on Facebook, if you friend someone, then perhaps that act of establishing that relationship may be done by the controller And finally, the view is the code that’s generating what you actually see A lot of times I think in the CS50 psets they don’t really encourage you guys to separate these 3 things You’ll probably have this big, long file where at the top you make some SQL query and maybe do some processing on the data you retrieved from the database, and then you have all your HTML at the bottom And you may find that as you create more and more pages that you’re going to have some code repetition, and also, the thing is your file gets really big and long and becomes unwieldy to manage The reason why MVC is so well regarded is for a number of reasons The first thing is something called separation of concerns which is the idea that when you have– ideally 1 piece of code should do 1 thing and do it really well, and you shouldn’t combine pieces of code that do disparate things For example, view code and model code, they don’t really have to be related They don’t have to be in the same files, so when you can, separate them out so it’s easy to maintain The other thing is code reuse You may find yourself writing the same SQL query or doing similar queries that could be abstracted into 1 function, and that’s the idea behind models and controllers, having it in a separate function that you can reuse in different places in your project And finally, that’s tied to DRYing your code, or not repeating yourself, don’t repeat yourself This is very comprehensible in development Whenever you can, you don’t want to repeat yourself, because if you repeat yourself, it’s much more costly to maintain If you want to change 1 thing, you have to change it everywhere, and that leads to bugs, and it’s horrible All right Any questions so far about Kohana at all? Great Now we’re going to dive into the live coding session, and hopefully everything goes well I am going to basically build this website on one of my remote servers, and that way you guys can also see the website and access the website, and also the environment is better configured than my remote machine, because it’s running Linux instead of OS X We’re literally going to start KohanaFramework.org I’m going to download the code from the website I’m going to copy the link address, go to my server, download it, and I’m going to extract it [Student] What’s the largest you can make the text? [Brandon Liu] Is that better? [Student] Is that doable?>>[Brandon Liu] Yeah, that’s fine I downloaded a ZIP file and unzipped that into a directory called Kohana, and we’re going to rename that CS50-Kohana, and let’s go in Awesome Here you see a bunch of different files Most of you can ignore–we’re not going to go through every single file that’s in here because of our time constraints, but generally when you install Kohana, the first thing you do is you go to the directory, and you’ll basically do some environment tests and whatnot to make sure your environment is properly set to run Kohana and make sure that everything is all right You can see most things passed, but generally you always run into this 1 problem where it complains that some directory is not writable, and that’s because of some permissions I don’t know how much you guys have learned about file permissions in CS50, but if you do web development, you’re going to run into this issue a lot I’m going to make it writable and I think I also have to–there we go

Okay, so now you can see everything passed, and now it will tell you to rename the install.php file I’m going to move the install.php file to installed.php, and now if I refresh, it gives me some error, and this is where the debugging comes in This is where you can see what’s actually going to happen The thing is, by default, Kohana assumes that your project is at the root directory of your domain, so it’s expecting you to be at demo.brandonkliu.com We have to tell it that it’s actually in a subfolder It’s in a subfolder called CS50 Kohana The thing is, it’s misinterpreting CS50-Kohana as something else, which I’ll explain to you in a second But I should tell you that’s something that’s to be expected What we’re going to do is we’re going to go into this folder called bootstrap.php, which is the configuration folder where a lot of different things are set up I open that up Then maybe one of the first things I’ll do is change the time zone And then let’s see Aha! Right here There are a bunch of different configuration sayings in here, but the one I’m looking for is this thing called base URL, and by default I get it set to Kohana, but I’m going to change that to CS50-Kohana, and I think that should fix it Yes, great By default, to see that it’s working, it says, “Hello World.” Where did that come from? How did we get to Hello World? Where exactly is the code that actually wrote that? To understand that, I’ll introduce this concept called routing Pretty much all web frameworks have the concept called routing, which is the piece of the software that will map a certain URL to a certain piece of code within your framework For example, if you have some URL and you go to some URL like foo.com/blog/all then what the framework is going to do–or at least what Kohana is going to do– is it’s going to find a class called controller blog, and it’s going to run the function named action all I know I’m talking about class and functions, and I know you guys haven’t covered classes and functions in CS50 yet, but for now, you can think of classes as just a group of functions, a way of grouping functions together That’s really all you need to know Now if we look at our folder structure, inside the application folder there is another folder called classes, and the other folders are called Controller and Model If you look inside the Controller folder, we see that there is a file called Welcome, and you can see here is a class called Controller Welcome, and there is a function called Action Index, and what it does is it sets the body of your response to Hello World That’s where the code is being written The other question is, well, I didn’t go to blah, blah, blah, /welcome/index How did I end up here? Well, that’s simply because here at the bottom of our bootstrap file where we set our routes you can see that they set some defaults for you The default controller is Welcome. The default action is Index That’s why when we put nothing in there it automatically went to the Welcome controller and the index Action Everything make sense so far? Now, you can do more than just go to Controller and a specific action You can also pass in parameters to the controller Just as an example, I’m going to add another action to this controller to show you Let’s call this action Echo, because it’s going to tell you whatever you give it, and so I’m basically going to grab a parameter that’s going to be sent through me to the routing program, and as you can see here, this line right here, you can see that this basically means you have controller, and you have a /, and you have action, and you have another /, and that’s going to be parameters, and because we have this name ID within angle brackets, that means that we’re naming this parameter ID Later in my controller code if I want to grab a hold of that parameter, I can use the code I wrote, find the parameter named ID That’s what I did here, and I’m going to return and say, “You said” that

And so now if I go to our website, I go to cs50-kohana/welcome/echo/Helloooo– oh, that’s right There is 1 step I left out This is part of the live coding idea Here’s 1 thing. Let’s see So normally by default with a lot of these web applications you have to include this index.php thing in your URL, because the idea is index.php is sort of the entry point of your application, but of course, that’s sort of annoying to have You don’t want to have index.php appear in your URL, and pretty much every web framework out of the box has this index.php problem, and so you have to take some measures to be able to remove that And so in this case, what we’re going to do is we’re going to use a file called .htaccess, and this is something that’s specific to the Apache web server, and it can do things like rewrite URLs and redirect URLs and so on and so forth, and Kohana is nice enough to provide a template .htaccess file that we can use As you can see, there is a file there called example.htaccess, and we’re going to copy that to .htaccess I’m going to open this and edit it, and basically it does a bunch of different things The key line you may want to look at is right here The idea is that this sets up a rule that says, “Okay, whatever you type in, prepend index.php to that.” You can see that The .* stands for anything, match anything, and then the second part is index.php/$0, and $0 refers to whatever was matched previously Does that make sense? But the really key thing I want to change is change this rewrite base, which is the URL base It sort of assumes where you’re working from I’m going to add CS50 Kohana to that, and that way now if I remove the index.php, it should work, and I’m going to add some numbers to show you that it indeed did work Sounds good Any questions so far? [Student] How did it know to make the 123? Is that an argument? Exactly. You can think of it just like an argument But the weird thing, though, is that the way Kohana does it is they don’t do it exactly like an argument You have to grab it like this You have to grab the request object and ask for the parameter that’s named ID, and that name ID comes from that bootstrap file that I showed earlier, and the name ID was in those angle brackets, and that’s how you grab those parameters Awesome Any other questions? Like I said, controllers, they handle application logic, so that’s 1 instance where you can see that’s– it’s very basic, but it’s still application logic, the idea of grabbing the parameter and creating a new string that says, “You said blah,” and then spitting that back to you And generally what you do is you create different controllers You create separate controllers for different parts of your website Today we’re going to make a very simple website, and it’s going to be a very basic blog We’re going to make a new controller just for the posts in a blog But then if I were to also add comments to the blog post, then I would probably want to make a new controller for those comments If I wanted to add users, I would probably add a new controller for those users, and in general, the idea is that whenever you have a new model, a new data object that you’re dealing with, you have a single controller for that data object Today we’re only going to work with 1 data object, and that’s going to be posts, and also you can think of data objects as corresponding to tables Generally each table corresponds to 1 type of data object, so the post table will have 1 post model, which will have 1 post controller corresponding to that, and the same for comments, the same for users, and so on and so forth And that’s a general rule of thumb There are going to be special cases where you may differ from that, but 90% of the time that’s what you’re going to be doing, and I’ll show you that’s what we’re going to be doing today 1 more concept before we dive back into the code, this idea of object relational mapping You guys have already done a web development pset, and you’ve seen that you make an SQL query, and whatever it returns to you are rows You get these rows, and you index them by some name, the name of the column and the table, and that’s how you work with it, and it can be a bit cumbersome But furthermore, if you have relationships within your database,

like for example if I have comments and posts, then maybe I want to grab the parent post of a comment If I use just rows in SQL, then all I can get is the ID of the parent post and not the actual post itself But when we’re coding, what we actually want is to actually grab the parent post itself sometimes What object relational mapping does is it takes the results of the database query and puts it into objects for you, which are much nicer to work with than plain arrays and rows For example, now when I have a comment perhaps, and I want to grab its parent post, and I do maybe comment arrow post, then it will actually give me the post object corresponding to the actual parent post, not just some ID, which I would otherwise have to use and make another SQL query to grab the post, which is cumbersome and unnecessary And furthermore, by mapping all these data rows into objects, you can also attach more functions to objects, so for example, I talked about how classes are essentially groupings of functions You can think of it like that For example, maybe I have this post object, and maybe I’d like to have some sort of function attached to it that basically tells me was it recently posted? Was it posted within the last week, true or false? And that’s a function I can attach onto that object, and it’s really convenient to have it in the same place, and there are a host of different functions you can create for these objects, and it’s really nice to be able to attach it to a class, to an object, whereas if you just had rows coming from your database, then you can’t really attach any functionality to that It’s literally just data Any questions about that at all? ORMs are very common web development, and there are a lot of different types of ORMs, and Kohana has its own ORM It’s very basic, but you’ll get a taste of what it looks like Let’s create a model for our blog posts, and the first thing we obviously need to do is to create an actual table within our database to actually store our data for those posts The first thing I’m going to do is go to phpMyAdmin Have you guys used phpMyAdmin before? Okay, awesome, so you guys already know what that is, and I’m going to create a new table called Kohana Posts, and it’s going to be really simple I’ll have to log back in All we’re going to do today is have an author and a body, just keep it simple I’m going to create that table, and now we just have a table representing our posts with 2 fields for our author and our body The other thing I am going to do now is configure my web application so it knows how to connect to the database, and this, again, is something that you’ll have to do with all web applications You have to tell it the user name and the password and the name of the database and so on and so forth to figure out how to actually connect to your database In Kohana, we have something called a database module, and in the configuration folder we have this folder called Database, and as you can see, there are a bunch of settings you have to set here to tell it what’s the user name and the password for the database so I can actually connect to it And since I don’t want you guys to actually know the user name and password of my database, I have a file where I already set it all up, and I’m going to copy and paste it over Awesome Okay. I think that’s all the configuration I need to do, but let’s see We’ll keep working in it, and if something crashes, then we’ll fix it Now what I’m going to do is I’m going to create a new controller Or actually, sorry First I have to create a new model I’ll create a new model called Post.php,

and what we’re going to do is we’re going to call it class Model_Post Get some syntax highlighting on, and so when I say, “extends ORM,” that’s basically some more object-oriented programming, which unfortunately you guys haven’t learned in CS50 yet, but it’s pretty easy to pick up It gives me all this extra functionality that comes in this ORM package, and so I get a bunch of extra functions and whatnot for free, which you’ll see a bit of in a second Right now actually all I need to do is create this class I don’t even need to make any function or anything, but I’ve created a class that represents the table, and because I’ve extended this ORM class, I get a bunch of things for free, so for now you don’t have to set anything more up And now what I’m going to do is I’m going to create a new controller, which I’m going to name blog.php, and I’m going to copy over the Welcome controller so I don’t have to retype some stuff, and now I have to rename this Now what I’m going to do to test to make sure everything is working out, I’m going to grab the first post from my database and print the body of the post on the screen To do that what I’m going to do first is I’m going to save the posts to a variable so what we’re going to do is– in Kohana what you do is to grab the post object it’s kind of cumbersome, but you have to do this thing called ORM:: factory, and then you pass in the name of the model you want, and it returns the ORM object that represents that model And then, like I said, when we extend the ORM object, we get all these methods for free, so for example, we get this new function called “find all,” which automatically returns every single post in the database, which is pretty convenient And now in the body I’m going to return the first post and return its body And of course, I need to create a post, so let’s insert a new post I’ll say, “Brandon, my very first post.” Awesome And now we’re going to go to blogs and if all works well–oh, this is some other dumb file permission thing again Hold on 1 second. It’s kind of absurd There we go. Okay I fixed that permission problem It was trying to create some files and some log, and the permissions, again, weren’t properly set, so I made it so those files were writable and executable so it could actually log to things Now it’s giving me another exception saying, “class ORM not found,” and that’s because I forgot another step That’s too bad In the bootstrap folder file, there are these modules here, which you can choose to enable or disable These are a bunch of different features that you can choose to use within Kohana, which is sort of nice For example, they have an authentication module which you can use for authenticating users They have a caching module if you want to implement some sort of caching back end to make the application work faster and whatnot We need to enable the database and the ORM module, because like I said, we’re using the database, obviously, and we also need to enable the ORM module, because we’d like to have the extra functionality, which is nice to have All I have to do is uncomment those 2 lines, and now if I refresh, it gave me another error It says, “Class Model_Post not found.” Now this is a good problem to have Let’s see Make it public No. Hold on Oh, dear

I do not know why it’s not able to find that That’s really strange I have this class right here I guess I might have to–oh I am so dumb. I forgot to add a PHP tag That’s why Now I have to undo that 1 change I just did Okay. There we go That was really silly. I didn’t have an opening PHP tag But as you can see, now it’s working properly, right? We have 1 post We grabbed the first post, and now we printed out its body Great. Fantastic Any questions so far? Nope? Any questions? Okay, so we just created the post model, very basic, and we’re going to add some functions later on We can add validations and filtering Validations are one of the things that frameworks solve for you really, really well, and I don’t think you guys had to do this for your CS50 pset, but if you do web development for your final project, you’re likely going to want to do some sort of validation, like not having blank user names, maybe having a password with at least some length, things like that And it’s really cumbersome to implement these things by ourselves, and pretty much every single web framework does it for you and allows you to do it in a very clean way And the model is where you generally express those validation rules, because it’s validating whether a model is valid or not But for now, we’re going to put that until later, and for now we’re going to work on another part, and we’re going to try and make a new view that lists all the posts The steps involved in making a new action for listing all the posts is to grab a list of all the posts and then render the list of all the posts through a view Right here, fortunately enough, we already grabbed all the posts using this first line, the find all function, and now what we’re going to do is so far I’ve been directly setting the body of the response by passing the string, but now I want to use a view, and the difference between a view and just doing this is with a view I can have a nice, big HTML template, and what I can do is pass it certain variables and then have the view automatically populate its template using those variables What I’ll do is I’ll create a new view, and I’ll name the view something like “blog/index,” and I’m going to basically bind this–oh, what am I writing? My brain is somewhere else I’m going to bind the posts variable to the view, so that way the view has access to this post variable And so now I need to create this view, so here we have this folder called “Views,” and first, I’m going to create a new folder under that called “Blog.” This is nice. That way we can have a nice hierarchy for our views And then I’m going to create another file in there called “index.php.” Awesome Actually, let’s have them both here Making a view file is probably the simplest part of all this, and these are probably things you’re already familiar with We’re going to do something really simple, start saying, “My list of blog posts.” Then we can go through, and we can iterate through the posts array, grab every single post and say something like– maybe add a line and then print out the author and the body That make sense so far? And let’s see if it works Nothing happened I wonder why Oh, I missed 1 step. Very silly of me I created a view, but I didn’t set the view as the response,

so you have to do 1 more thing You have to do “this response body” and set it to be the view There we go We have our heading, and then we have a post, and just for kicks, let’s insert another post so we can see a list And insert these 2 posts, and now if I refresh the page, we see all these posts here Does that make sense so far? Yeah, a question? Oh, okay As you can see, we’ve been able to separate all these codes out into different sections, and then you can see it’s most clear with the view code This file here that represents the view, it only cares about representing data, displaying data It gets passed some sort of data, and all it does is just show it to you In all other parts of your code, you won’t have to worry about any of that, and similarly, your view code doesn’t have to worry anything about how to access the database and so on and so forth, which is really good and makes your code a lot more maintainable Like I said, views, they’re dynamic in that it’s 1 file, but it would generate different views based on the variables you actually pass in, and furthermore, there are a lot of different helper functions that you can use to help you write your code faster, which I’ll show you in just a second Yeah [Student] So $0 is a controller, right? That second thing The question is is $0 a controller? $0 is a variable I created right here I created a view first. I assigned it to some variable Then I passed it into this function, set it as the body of the response Does that make sense? [Student] So is view :: factory, is view like a class or a library [inaudible] factory function? The question is about the view :: factory function, and basically this is some more object-oriented programming essentially View is the view class, and it has a method called “Factory,” and that’s a way to grab the object that’s named “blog/index.” And that’s some more object-oriented programming stuff that I’m not going to go into here too much Now obviously, we want to create new posts, but we don’t want to have to do it through a database, so we’re going to create a new action for creating a new post, and there is a lot of stuff we have to do The first thing we’re going to do–let’s tackle these things one by one The first thing we’ll do is we’ve got to create a form for inserting a new post, but I’m also going to add a new action first, so adding a new action is just as easy as adding a new function with your controller, and for now I’m going to do something very basic, just grab this view and post it, just display it for you And then now I’m going to create a new view file, and I’m going to start writing some stuff What’s nice about Kohana is that they provide a lot of different helper functions for you to write view code more easily, and 1 of those helper functions or helper modules is around writing forms For writing forms, I don’t really have to directly write any HTML myself You guys have written HTML forms You know how it can be really, really painful and cumbersome to write forms It’s not fun, so fortunately, we can basically write a form using Kohana’s form helper functions to do it for us We’re going to basically have fields for every single thing we have, so one for authors and one for the bodies We’re going to have a label, and we’re going to have an input And then finally, we’re going to have a submission And as you can see, this is much cleaner to write than all that messy HTML, which is kind of nice Granted, there are other web frameworks that have it even cleaner than that,

but at least this is better than writing the HTML yourself Awesome, so this is what you see That’s kind of messy, so I’m going to add a line break there to make that look a little nicer Well, of course, it still looks really, really bad, but we’re just focused on the functionality for now and not on the aesthetics No time to do everything And as you can see, now we have a super basic form, which is kind of nice This code I would say is cleaner than trying to write an HTML form yourself, so that’s nice What’s next? Now we need to do things with the action Normally when you write HTML forms, you have to tell it where it’s going to submit the form to By default in most web frameworks, it submits to the exact same URL, so the thing is, if you send a get request to /blog/new, it should display you the form, but if you send a post request to /blog/new with the data, it should actually try to save that post and do something with it What we’re going to do is basically all we have to do to check whether it’s a post request or a get request is to check what are the post variables you can set And if the post variable is set, then we’re going to try and create a new post Again, we just do this, and that creates a new post, and we’re literally going to set its fields like this, and then we’re going to save it And then I’m going to redirect to the index page so they can see our list of posts again Let’s try that I’ll say, “Brandon,” and then submit the post, and if all goes well, as you can see, it redirected me to the index page, and if I scroll to the bottom, we have a newly inserted post Yay! Yeah, question [Student] What if you had entered the exact same thing you entered before? Does it check to make sure you haven’t duplicated the same submission? Be default, no, because by default– sorry, the question is if you enter in the exact same data in the form and submit that, will it allow you to insert a duplicate object, a duplicate entry, essentially? Right now, yes, it will allow you to do that, because in databases it’s perfectly valid to have completely duplicate rows, but if that is a concern, then you can add validations, for example, to make sure that if this is exactly the same as something that already exists, then say that it’s an invalid object, and then you can even specify your error message and say, “Invalid because this already exists” or something like that But in this case, I could just create something duplicate Now let’s try and add some validations The problem with this right now is that I could literally submit a completely blank post I can click this button right now, and there we go You can’t really see it, but this extra line here indicates that I literally have a new post It just has a blank author and a blank body, and we don’t want to allow people to do that This is where validation comes in I can go to my model object, and now I can add a new function that specifies what validation rules I should add to this model to make sure that it is valid or to specify what does it mean to be a valid post? And I want to say it’s only a valid post if both the author and body are not blank, and this is how you do it in Kohana You create a new function called “Rules,” and then you basically return an associative array that defines the validation rules for this object We’re going to return the array, and then what we’re going to do is say “author,” it goes to an array, which goes to another array called “not empty.” And then I’m going to say “body.” Okay, and the syntax for this and structure for this may look a little cumbersome and a little complicated If you read the documentation, it’s pretty straightforward to figure out, But essentially this is what you need to do to specify

some validation rules, and there are a lot of different rules that Kohana will give you for free, like you can add rules to say it must be at least this length Maybe it has to be numeric. Maybe it has to be alpha numeric Maybe it has to be at most this length, so on and so forth There are a lot of different rules that Kohana provides for you, and you can go on their website, look at the documentation, and you can see all the different things that you can do But this is all I have to do, and now let’s see what happens if I submit a blank post What’s going to happen? Oh, no, I get an error I get a validation exception Well, it’s good It told me that my model is invalid, but I don’t want to display an exception to my users when they try to submit something invalid, right? I want to give them some sort of friendlier error message when something goes wrong What we’re going to do is we’re going to wrap everything in a try catch loop Actually, I think this is also something you have not learned yet in CS50, because C, the programming language C, doesn’t have exceptions, but almost every single other language has exceptions, so really, really briefly, an exception is something that a piece of code can throw an exception when something goes wrong, but then maybe some other piece of code higher up can catch that exception and do something with it For example, in this case, the piece of code that’s trying to save a model, it validates the model, and if it says, “Okay, this model is invalid,” it’s going to throw an exception, and this is kind of equivalent to in C you might return a -1 or something like that And then for me, this function, my code at a higher level, I can try and catch that exception and basically say, “Okay, if I catch the exception, what am I going to do?” Or I could choose not to catch that exception and let someone higher up catch the exception, or if nobody catches it, then the whole program crashes and says, “Something went wrong, and I couldn’t handle it.” But what we do is you wrap a piece of code in a try block, and then you also add something called a catch block, which is the sort of code that will try and catch exceptions that may occur And so if I catch this particular exception or invalidation exception, then what I’m going to do is I’m going to set the errors–I think that’s how I do it– and I’m going to set the errors to some object And then what I’m going to do is if it hits this exception, it’s not going to redirect, and if it doesn’t redirect, it’s going to come out of the if blog and hit this blog/new, which is want I want to do If there is an error, then I want to go back to the form and display those errors Now what I want to do is I want to pass in those errors to the view Okay, I think I have the view right here, and basically I want to display those errors if they exist Before I write the HTML for that, I’m going to really quickly show you what the structure of this errors variable looks like, and this is a good practice in general A lot of times you get something back from some method, some function in the web framework, and you don’t know what the variable looks like, so you don’t know how to work with it I’m going to use a print r method to basically print it out And as you can see, it tells me it’s an associate array, and you have a key, author, points to this string, author must not be empty, and another key, body, points to another string, body must not be empty I’m like, okay, cool Then I can iterate through the array and print out every single message It’s basically like an associative array with a bunch of messages What I’m going to do is “if errors,” and I’m going to create an unordered list, and I’m going to iterate through all the errors And this, and now I’m going to try submitting this again, and let’s see what we get Now we get this nice list of errors, and this is still pretty ugly, but this obviously can be formatted to look nice, but the basic idea is just in a few lines of code, we were able to validate our model, make sure that certain fields weren’t empty, and if something went wrong, then return some sort of error message I could then present back to the user

You can also customize your validation so that you can actually have an error message that is more specific to your application or something like that All that is generally customizable Unfortunately, we’re running out of time, so I’m going to have to cut off the live coding session here There are a bunch of other features that I want to demonstrate for you in this example For example, you can add templates to your site, so maybe there is some sort of HTML code that you want to apply to every single page in your site, and instead of pasting that in every single view file you have, which obviously would be a bad practice, you can basically define these templates, and then in your controller say, “Okay, I’m using this template.” “Have all my views use this template.” And the one last thing I want to demonstrate to you as well that we don’t have time for is cross-site scripting, and basically I think you guys have probably seen in CS50– I think David Malan probably talked about how you can usually inject JavaScript code into–have you talked about this? Maybe? Maybe not? But a lot of times you can inject malicious JavaScript code into someone’s database, and if they don’t escape that properly, then when they present that data back to the user, then it may run some sort of random JavaScript code you don’t want to happen, and I was going to demonstrate how you’d do that within Kohana It’s actually really, really easy I could do it right now in 2 seconds literally All you have to do is basically wrap these things in this thing called HTML entities And that will automatically escape all the characters properly and make sure you don’t get this problem [Student] You spelled the first test incorrectly [Brandon Liu] Oh, oops Okay, that’s all I had to share with you for today These slides are going to be posted, but these are generally the only resources you should really need to get started with Kohana You can go to the website. They have a user guide, and they also have an API explorer We can explore all the different functions and helper functions they have for you They generally have enough information on the website that you can use to get started and get going with Kohana There aren’t that many tutorials, I think, for Kohana, outside of what they have on the website here, so this is probably your best bet But if you want to go with the web framework and you don’t want to have to pick up a new language, and you want something that is relatively lightweight and has an easy learning curve, I would definitely suggest Kohana That’s probably the best offering for that The funny thing, though, is if we were using Ruby on Rails, we could have replicated what we just did and probably more in under 3 minutes No joke, but learning Ruby on Rails takes a lot longer than it would take to learn Kohana It’s basically your choice on what you want to choose to learn, but if you want to get up and running quickly, Kohana is definitely a very good choice Any last questions before we end? Yes [Student] How would we integrate that in a CSS framework like you were using when you were instructing? The question is how would we integrate that with a CSS framework? What we would probably do is we would probably include a new folder where we would dump all our CSS files, and then we’d also add a new template In the template we’d include those CSS files to make sure they’re referenced on every single page, and then when you actually are writing HTML, you just add appropriate classes and whatnot, and for example, when you’re using something like the form helper function, you can add more parameters afterwards to specify what classes you want to be attached to various things so they could style it properly, and that’s basically how you would go Any other questions? Awesome Thank you for your time, and thank you for coming I wasn’t going to add very much else, but 1 really quick thing is we don’t have a link to the form Really dumb Let’s add a–actually in the view, blog, index, let’s really quickly add a link that goes to the new page, the page where we can insert a new post We’re going to do this What’s nice is there is this whole group of HTML helper functions which do different things for you, so you already saw the entities function here, but they also have a function called “anchor,” which you can type in blog/new and say, “Post a new blog.” And it would create that link for you, and this seems really trivial to do, but this is nice, because suppose that you are moving your website from 1 domain to another And if you just wrote out the URLs yourself,

then you would have to change all the URLs Or maybe you moved it from 1 subfolder to another subfolder You would have to change all those URLs yourself, and that’s no fun You can use this anchor right here, and you can change the domain or the subfolder prefix in the configuration file once, and then it will apply that everywhere, and this is, again, a great example of do not repeat yourself, DRYing your code out Wherever you’re repeating yourself, try and extract in some sort of configuration file or to a different function and have it handle that for you And the very last thing that I wanted to show you was suppose we’re back at this post, and I had composed some really long essay, but I forgot to include my author Now when I click “Submit Post,” I just lost everything No! Really sad So how do you deal with that? This is what we do What we do is here for these input and text area functions, if we include a second parameter, then the value of that second parameter is going to be what the field is going to be initially populated with What we could do is in our blog controller, we could bind another variable Call it “values” maybe And pass in the post array, literally That means that if the validation failed, pass to me the post array that I submitted from the last request, and that way I can use the values from my last submission to repopulate the fields Now I can do something like values author and values body, and that way now if I do some random stuff and click “Submit Post,” then it stays there But we’re going to run into another problem That works, but if I go to the page the very first time, it’s going to crash, and that’s because the very first time we go to the page, this post variable has not been defined yet It’s null. It doesn’t exist And what we want to say is if this key exists, then return the value of this array, but if the key doesn’t exist, then return a blank string That’s the functionality we want here We want to check if the key exists before trying to access the array, and fortunately enough, Kohana also gives us a helper function for that They have this whole suite of functions under the name ARR, short for array, and they have 1 function called “get,” and you can pass in the array, and you can pass in the name of the key Then basically what it will do is it will try to get that key, but if that key doesn’t exist in the array, then it will return blank, or we can also specify a default, I believe, which is nice Now if we do the same thing again, then you see now it works the first time around, and again, if we type in some random stuff and try and submit, then it stays there And I guess I can also show you how to add a template really quickly What we can do first is we can add a new view called “template.php” within the Views folder, and what I’m going to do is I’m going to print out something called “content,” which is going to be my main content And maybe at the very bottom I’m going to add, say, copyright [inaudible student question] [Brandon Liu] Maybe this is a super basic template I want to use I want to have a folder with my copyright on every single page, and now what I’m going to do within my controller is now instead of saying, “extends Controller” I’m going to say, “extends Controller_Template,” and now instead of saying, “response body is equal to this view,” I’m going to say, “this template content is –” and I think–do I put an equal sign? I forget. Yeah, I thought so And now I set that content variable to equal the view I can do the same here And now if I refresh, you can see now this copyright is added there, and just make some random post,

and then, again, you should see that the copyright is at the very bottom of the page Great. That’s all I wanted to show you guys [Applause] Any questions? [CS50.TV]