How can I access controller methods via url in Laravel? - php

I'n new to Laravel and I'm not quite sure of all the routing stuff yet, so I want to do things the way I'm comfortable with for the time, which is accessing a controller method via url. So I have a controller called User, in that a function called getLogin(). I want to access this via 'mydomain.com/user/login'. It doesn't currently work, so how do I do this?

While I agree with Phil Sturgeon's article that for a typical app, it's wise to make routes as obvious as possible, there are some cases where a url segment to controller method scheme might be convenient. I sometimes use Laravel for prototyping/testing some code and need a predictable url-to-method to spin off examples. You can grab the segment using Request::segment() and camelcase it using Laravel's Str::camel(). For example, with a route like:
Route::get('/lara-learn/{method}',
array(
'as' => 'lara-learn_' . Request::segment(2),
'uses' => 'LaraLearnController#' . Str::camel( Request::segment(2) )
)
);
You can visit /lara-learn/lara-config and land on the laraConfig() method:
class LaraLearnController extends BaseController {
public function laraConfig(){
return "hey from laraConfig";
}
}
If we want, we can also choose the controller dynamically from the url, say using the first segment. So we can generalize our route even more:
Route::get('/{controller}/{method}',
array(
'as' => Request::segment(1) . '_' . Request::segment(2),
'uses' => studly_case( Request::segment(1) ) . 'Controller#' . Str::camel( Request::segment(2) )
)
);
Visiting /lara-learn/lara-config should land us on the laraConfig method example above.

Laravel does not automatically map routes in controller/method fashion.
You have not posted what is in your routes.php file, but one of the simplest approaches is to do this:
Route::get('users/login', array('as' => 'login', 'uses' => 'User#getLogin'));
There are multiple approaches, though. You might consider reading the docs about routing

Route::resource('/recipes', 'recipesController#index');
you have to make route like this and u have to access it in url as
localhost/projectname/public/recipes

Related

Laravel Subdirectory Views

what I'm trying to do is set it up so that the user can go to "/project/index" ("/" being the route ofc) but I'm not quite sure how to do it in laravel?
What I currently have:
Routing:
Route::get('project.index', array('as' => 'project/index', 'uses' => 'ProjectController#indexPage'));
Also in routing:
View::addLocation('project'); //Project View
View::addNamespace('project', 'project');
In my Project Controller:
public function indexPage()
{
return View::make('index', array('pageTitle' => 'Project Index'));
}
Any ideas? Thanks in advance.
PS: It's Laravel 4
You have your routing a little wrong. Try out the following
Route::get('project/index', ['as' => 'project.index', 'uses' => 'ProjectController#index']);
So the first parameter into the Route::get() function should be the URL the user is visiting for example http://example.com/project/index. The as key in the array provided is the name you're giving to the route.
By giving the route a name you can use this throughout your application, rather than using the url the user is visiting. For example you might want to generate a link to your route
Link
This will generate a link to http://example.com/project/index. This makes it convenient in the future should you wish to change your URLs without changing lots of links throughout your view files.
Route::get('foobar/index', ['as' => 'project.index', 'uses' => 'ProjectController#index']);
The URL generated through route('project/index') would now be http://example.com/foobar/index
Checkout the routing documentation for further information http://laravel.com/docs/4.2/routing

Methods of using filters in Laravel - what is the difference

I try to learn Laravel, and I'd like to verify the user is logged in before calling a controller to do stuff.
There seems to be at least 3 different ways to accomplish this, and I'd like to know what is the difference between these.
Route::get('/main', 'StuffController#doStuff')->before('auth');
Route::get('/main', array('before' => 'auth', 'uses' => 'StuffController#doStuff'));
Or in the controllers constructor:
public function __construct() {
$this->beforeFilter('auth');
}
There are no differences. Laravel is the Framework that allow you to accomplish many tasks in many ways.
I prefer to add filters in routes grouping them, for example:
// logged users paths
Route::group(
['before' => 'auth'],
function () {
Route::get('/dashboard', [
'as' => 'dashboard',
'uses' => 'DashboardController#mainPage'
]);
}
);
// paths only for admin
Route::group(
['before' => 'admin'],
function () {
Route::get('/admin',
['as' => 'admin_dashboard',
'uses' => 'AdminDashBoardController#mainPage'
]);
Route::get('/categories/{page?}',
['as' => 'categories',
'uses' => 'CategoryController#displayList'
])->where('page', '[1-9]+[0-9]*');
}
);
There is one benefit of such use - its' much easier to look if all routes have correct filters.
Assume you want to display some content only for logged users and you need to use auth filter. You have many controllers to display content for logged users.
If you use beforeFilter directly in those controllers or in parent controllers constructor the following things can happen:
you may forget to put beforeFilter in all your controller constructors
you may forget in your controller constructor to run parent constructor (where you have beforeFilter)
you may extend not the class you wanted (for example you extend BaseController and you have beforeFilter defined in AuthController and in one or some classes you extend BaseController)
Those situations can cause that you display content for unlogged users because you need to remember about auth filter it in each controller and if you want to make sure you did everything right, you need to look at code of all your controllers.
Using route grouping (as I showed above) you can easily look at one file (of course assuming you use one file for routing) and you will see which routes use auth filter and which don't.
Of course I assume many people will have their own opinion on that thing but that's me personal preference to use filters in routes.
Your two ways have no difference, just different syntax style.
I prefer to put the auth filter in a BaseController, then extends all controllers I want to be authed from BaseController. Just write once, used everywhere. Btw, you can also put your csrf filter here.
class BaseController extends Controller {
public function __construct() {
$this->beforeFilter('auth');
$this->beforeFilter('csrf', array('on' => 'post'));
}
}

Laravel Route::resource naming

I have the following in my routes.php
Route::resource('g', 'GameController');
I link to these generated routes via HTML::linkRoute('g.index', 'Title', $slug) which produces a link to http://domain/g/demo-slug
What I am looking to do is verify if it is possible to have the prefix be declared in one place so I'm not hunting for links if a URL structure were to change.
For example, I would want to change http://domain/g/demo-slug to http://domain/video-games/demo-slug
I was hoping to use the similar functionality with the standard routes, but that does not seem to be available to resource routes.
Route::get('/', array('as' => 'home', 'uses' => 'HomeController#getUpdated'));
Route::group() takes a 'prefix'. If you put the Route::resource() inside, that should work.
Tangent, I find this reads better:
Route::get('/', array('uses' => 'HomeController#getUpdated', 'as' => 'home'));
As far as I know it's true you can't have named routes for a resource controllers (sitation needed) but you can contain them in a common space using Route::group() with a prefix. You can even supply a namespace, meaning you can swap out an entire api with another quickly.
Route::group(array(
'prefix' => 'video-games',
'before' => 'auth|otherFilters',
'namespace' => '' // Namespace of all classes used in closure
), function() {
Route::resource('g', 'GameController');
});
Update
It looks like resource controllers are given names internally, which would make sense as they are referred to internally by names not urls. (php artisan routes and you'll see the names given to resource routes).
This would explain why you can't name or as it turns out is actually the case, rename resource routes.
I guess you're probably not looking for this but Route:group is your best bet to keep collections of resources together with a common shared prefix, however your urls will need to remain hard coded.
You can give custom names to resource routes using the following syntax
Resource::route('g', 'GameController', ['names' => [
'index' => 'games.index',
'create' => 'games.create',
...
]])
This means you can use {!! route('games.index') !!} in your views even if you decided to change the URL pattern to something else.
Documented here under Named resource routes

Laravel using named routes

Regarding the use of named routes, these 2 lines allow me to access the same page so which is correct?
// Named route
Route::get('test/apples', array('as'=>'apples', 'uses'=>'TestController#getApples'));
// Much simpler
Route::get('apples', 'TestController#getApples');
Is there any reason I should be using named routes if the latter is shorter and less prone to errors?
Named routes are better, Why ?
It's always better to use a named route because insstsead of using the url you may use the name to refer the route, for example:
return Redirect::to('an/url');
Now above code will work but if you would use this:
return Redirect::route('routename');
Then it'll generate the url on the fly so, if you even change the url your code won't be broken. For example, check your route:
Route::get('apples', 'TestController#getApples');
Route::get('apples', array('as' => 'apples.show', 'uses' => 'TestController#getApples'));
Both routes are same but one without name so to use the route without name you have to depend on the url, for example:
return Redirect::to('apples');
But same thing you may do using the route name if your route contains a name, for example:
return Redirect::route('apples.show');
In this case, you may change the url from apples to somethingelse but still your Redirect will work without changing the code.
The only advantage is it is easier to link to, and you can change the URL without going through and changing all of its references. For example, with named routes you can do stuff like this:
URL::route('apples');
Redirect::route('apples');
Form::open(array('route' => 'apples'));
Then, if you update your route, all of your URLs will be updated:
// from
Route::get('test/apples', array('as'=>'apples', 'uses'=>'TestController#getApples'));
// to
Route::get('new/apples', array('as'=>'apples', 'uses'=>'TestController#getApples'));
Another benefit is logically creating a URL with a lot parameters. This allows you to be a lot more dynamic with your URL generation, so something like:
Route::get('search/{category}/{query}', array(
'as' => 'search',
'uses' => 'SearchController#find',
));
$parameters = array(
'category' => 'articles',
'query' => 'apples',
);
echo URL::route('search', $parameters);
// http://domain.com/search/articles/apples
The only reason to name the route is if you need to reference it later. IE: from your page in a view or something, check whether you are in that route.

Required order for specifying restful routes in Laravel 4?

I'm trying to understand routing in Laravel 4. I read a good post here on StackOverflow and a link to beware the route to evil, a post about manually specifying routes. I like the idea of specifying my routes manually and having the routes.php act as documentation. But it seems like I need to be cautious about the order of my Routes if I'm going to specify my own instead of using Route::resource() If I have the new or create route before the show then I won't be routed to the show because of the variable in URI? The order in which the routes are defined is important right?
// This will not work if I try and browse to dogs/new
Route::get('dogs', array('as' => 'dogs', 'uses' => 'DogsController#index'));
Route::get('dogs/{dogs}', array('as' => 'dog', 'uses' => 'DogsController#show'));
Route::get('dogs/new', array('as' => 'new_dog', 'uses' => 'DogsController#create'));
It seems I need to make sure that the dogs/new comes before the dogs/{dogs} for new to return correctly. I'm not clear on what {dogs} does or that's different from (:any) or {any} I've seen a few different uses in examples and pseudo code. I see that /new is the same as {...} when the route is before the more specific is the {} like a wildcard in Laravel 4? Is the (:...) the old way?
As an aside I've noticed a different naming convention from some of the examples I've seen when I run php artisan routes with a resource route like Route::resource('photos', 'PhotosController'); The method and named route for post to index to a create a new resource is named photos.store and #store. The method and named route for a link to a form to create a new resource is photos.create and #create. Is that Laravel 4 thing or conventions in other frameworks?
Route::get('dogs/{dogs}', array('as' => 'dog', 'uses' => 'DogsController#show'));
The above url expecting a parameter after dogs segment.
for example: http://laravel.com/dogs/xyz, http://laravel.com/dogs/new
after dogs url segment, Laravel will accept anything. So, your another routing will never executed for the route parameter.
Route::get('dogs/new', array('as' => 'new_dog', 'uses' => 'DogsController#create'));
More about route parameters:
http://laravel.com/docs/routing#route-parameters
Resource Controllers
Laravel and Ruby on rails support resource full routing. I think, Tailor borrow the resource full routing idea from Ruby on rails.
The following routes will generate if you use resource controller:
index
create
store
update
show
edit
destroy
http://guides.rubyonrails.org/routing.html
http://laravel.com/docs/controllers#resource-controllers

Categories