Laravel Routing Filtering Model View Controller Web Technologies II Artūrs Lavrenovs
Laravel Routing+MVC http://laravelbook.com/laravel-architecture/
Routing Study documentation http://laravel.com/docs/4.2/routing
Routing ALL requests coming to Laravel are routed Front controller pattern is handled by index.php Routing is handled by app/routes.php We will cover only some basic things, enough for practical assignment Laravel also enables things like domain routing, route prefixing, secure routing, etc.
Routing code Place your code in app/routes.php Routing code looks like this Route::$method($path, $action); Where Route is Laravel routing PHP Class $method is HTTP request method (or any), we will use get (for requesting data) and post (for changing data) $path is request URI path, e.g., /post/edit/123 $action is action to be performed, e.g., closures that generate and return appropriate content
Routing default page When browser requests http://project.dev actually http://project.dev/ is requested So when Default page aka Index aka root is requested, request URI path is / Handling GET request for default page Route::get('/', function() { }); return 'This is default page';
Routing action Action that gets passed to the routing call Can be Anonymous function function() { return 'This is default page'; } Array with some Laravel parameters Controller class with method MVC way 'ArticleController@showIndex' Goal of the functions is to return content to display in browser Return content itself return 'This is default page'; Call View, which instead will generate content, return it return View::make('hello'); Call Controller and expect it to return some View result (we'll be doing this)
Routing path parameters Laravel provides us with nice URLs out-of-box We don't want to spoil our nice URLs like /post/edit with parameters like?id=123 What to do? Put parameters inside path, e.g., make /post/edit?id=123 into /post/edit/123 Parameters in path are put inside {}, optional parameters marked with? at the end of the name Route::get('/post/{action}/{post_id?}', function($action, $post_id = null) { }); echo 'I want to ', $action, ' '; if (!empty($post_id)) echo $post_id;
Routing path parameter constraints Usually you have some idea what kind of parameters to expect in the URL You can place constraints (RegEx) on the Route In previous example we might want action to be a word and post_id integer )->where('action', '[A-Za-z]+') ->where('post_id', '[0-9]+'); Increased security And handle everything unknown with POST requests
Filtering
Filtering Filter is a set of rules or actions that can be applied to a route Filter can be executed in relation to route's logic before (extremely useful) affect the response after (less useful) logging, cleanup Access control is most useful type of filtering Does current user have permission to access the page under certain route? Remember EDS leak? We will cover only basics of Laravel filtering
Filtering code Filters are created as Closures and placed in app/filters.php (we will do this) and look like this Route::filter($name, $closure); Where filter is Route class method $name is some string you choose as name $closure is anonymous function doing the work Filters can also be created as PHP classes For advanced projects Create app/filters, place there, update composer.json
Example filter Let's filter access by IP Route::filter('ipfilter', function() { if ($_SERVER['REMOTE_ADDR']!== '172.16.172.1') { return Response::make('Forbidden', 401); } });
Using filters In previous step we only defined the filter, to use filter we need to attach it to the route it is done by using array with parameters as routing action Route::get('/hello/world', array( 'before' => 'ipfilter', function() { $hello = 'Hello, World!'; return $hello; } ));
Default filtering By default app/filters.php contain global filters that apply to ALL requests App::before(function($request) {}); App::after(function($request, $response) {}); There are some default filters for Laravel authentication layer (we'll discuss them later) Also CSRF token filter is provided by default
Some more useful filtering You can execute multiple filters by using array 'before'=>array('filter1','filter2','filter3') You can apply before and after filters together After filters are set by 'after'=>'afterfilter1' You can make filter more universal using parameters While defining in app/filters.php Route::filter('filter1', function($route, $request, $param){}); While attaching in app/routes.php 'before' => 'filter1:someusefulparam'
Model
Model Business domain Each important thing in the application will probably need a Model class which corresponds to database table Laravel model is handled by ORM It is called Eloquent and implements ActiveRecord Each model class extends Eloquent
Model II In a simplistic scenario Model might act only as data store In a simple Blog system probable model classes are Post, Comment, User Each class property corresponds to database table field Each method corresponds to some domain logic If no domain logic then can instantiate model class anywhere and interact with it
Model III Place models in app/models and call it ModelClass.php By default provided User model skeleton Model class name corresponds to lowercase table name Important part of the Laravel, we'll discuss this other time
View
View Visual representation of a model Job is simple - take variable and output it inside HTML (or other markup) Default approach (for most frameworks) HTML with PHP snippets echoing variables We will not use this view approach because Laravel has templating engine called Blade We will use Blade and discuss it other time
Laravel View Goal of the most browser requests is to receive rendered view You have to return the result from the Controller Code to call View rendering View::make($viewname, $data); Where View is Laravel view class and make is method rendering the view $viewname is name of the view, actual view is stored as $viewname.php in app/views/ $data is associative array containing data to display which gets expanded inside view
Laravel View file HTML file containing PHP code for only printing variables received only from $data Code inside app/routes.php Route::get('/post/{action}/{post_id?}', function($action, $post_id = "default") { }); $data = array('action'=>$action,'postid'=>$post_id); return View::make('simple', $data); Code inside app/views/simple.php <!doctype html> <html lang="en"> <head><meta charset="utf-8"><title><?php echo $action;? ></title></head> <body><p><?php echo $postid;?></p></body> </html>
Controller
Controller Place where you have to put all of your application logic (we'll do this) Controller Gets and processes input Interacts with models Return some result (usually View) to the client All the action performed in routing step (inside Closures) are moved inside controllers Each routing action corresponds to public method of Controller
Controllers in Laravel Controllers are stored in app/controllers each class in separate file Naming convention word Controller is appended to PHP Class name Controller file name Example Post controller Class gets named PostController File gets named PostController.php
Controller Class Controller class inherits (extends) Laravel BaseController class class PostController extends BaseController {} Each action must be public method of the Controller class method parameters correspond to path parameters public function showaction($action) { } return $action; But how to make it work?
Routing to Controller You still need to give Controller control using routing Route::get('/post/{action}', 'PostController@showAction'); Where {action} is path parameter passed to controller method PostController is the controller class showaction is the controller method For each method you have to manually define routing entry (same as the above) Still it sounds as gruesome task and it is
RESTful Controllers Enables to give control over whole prefix path to Controller (we'll use this) Put in routes Route::controller('post', 'PostController'); Where controller is appropriate Route method (different from previous examples) post is path prefix, usually some verb which corresponds to some real life object (possibly Model) PostController is where all the requests for the path are being routed
RESTful Controllers II Public methods of RESTful Controller class correspond to request class PostController extends BaseController { public function getaction($action) { return $action; } public function getindex() { return 'index'; } } Method names correspond to requested path First part is HTTP request method (get, post) Second part (starting with capital letter) is path getaction($action) GET /post/action/$param