Change Laravel's default (root) controller - php

In Laravel the default controller is the Home_Controller. However I have a controller called frontend. I want to use this instead of the home controller.
When I register a route like this:
Route::controller(Controller::detect());
then a request to /offer will be handled from within the home controller like home#offer. I want to use frontend#offer and access it from the site's root - not like /frontend/offer.
What should I do?
Thanks in advance.

Home_Controller is one of the hard-coded convention which exist in Laravel 3, however there are still ways to define routing to point the Frontend_Controller methods, my preference would be.
Route::any('/(index|offer|something)', function ($action)
{
return Controller::call("frontend#{$action}");
});
Limitation with this is that you need to define all supported "actions" method in Frontend_Controller.

My guess is that the only reason you think the Home_Controller is some sort of default is because you are using Controller::detect(); I really haven't seen anything in the documentation to make me think that the Home_Controller is anything special at all. In fact, it doesn't even look like it is routed to in the example documentation. Given that, my first suggestion would be to get rid of Controller::detect() and see if that fixes your problem.
Barring that, have you tried registering frontend as route named home? It appears that all URL::home() does is search for the 'Home' route, and then redirect to it. When using controller routing this can be done with something to the effect of.
Route::get('/',
array(
'as' => 'home',
'uses' => 'frontend#index'
)
);
Or is that not your desired effect? Do you want all routes which aren't otherwise found to be redirected to your frontend controller?
If you are concerned about your urls looking pretty, you can probably use some rewrite rules in your .htaccess file to make the whole process of routing to /frontend/index transparent you your users.

Add this to your routes.php :
Route::get('/', array('as' => 'any.route.name', 'uses' => 'frontend#offer'));
If you have any other / route, just remove it.

Related

Laravel 5 redirect to path with parameters (not route name)

I've been reading everywhere but couldn't find a way to redirect and include parameters in the redirection.
This method is for flash messages only so I can't use this.
return redirect('user/login')->with('message', 'Login Failed');
This method is only for routes with aliases my routes.php doesn't currently use an alias.
return redirect()->route('profile', [1]);
Question 1
Is there a way to use the path without defining the route aliases?
return redirect('schools/edit', compact($id));
When I use this approach I get this error
InvalidArgumentException with message 'The HTTP status code "0" is not valid.'
I have this under my routes:
Route::get('schools/edit/{id}', 'SchoolController#edit');
Edit
Based on the documentation the 2nd parameter is used for http status code which is why I'm getting the error above. I thought it worked like the URL facade wherein URL::to('schools/edit', [$school->id]) works fine.
Question 2
What is the best way to approach this (without using route aliases)? Should I redirect to Controller action instead? Personally I don't like this approach seems too long for me.
I also don't like using aliases because I've already used paths in my entire application and I'm concerned it might affect the existing paths if I add an alias? No?
redirect("schools/edit/$id");
or (if you prefer)
redirect("schools/edit/{$id}");
Just build the path needed.
'Naming' routes isn't going to change any URI's. It will allow you to internally reference a route via its name as opposed to having to use paths everywhere.
Did you watch the class Illuminate\Routing\Redirector?
You can use:
public function route($route, $parameters = [], $status = 302, $headers = [])
It depends on the route you created. If you create in your app\Http\Routes.php like this:
get('schools/edit/{id}', 'SchoolController#edit');
then you can create the route by:
redirect()->action('SchoolController#edit', compact('id'));
If you want to use the route() method you need to name your route:
get('schools/edit/{id}', ['as' => 'schools.edit', 'uses' => 'SchoolController#edit']);
// based on CRUD it would be:
get('schools/{id}/edit', ['as' => 'schools.edit', 'uses' => 'SchoolController#edit']);
This is pretty basic.
PS. If your schools controller is a resource (CRUD) based you can create a resource() and it will create the basic routes:
Route::resource('schools', 'SchoolController');
// or
$router->resource('schools', 'SchoolController');
PS. Don't forget to watch in artisan the routes you created

Laravel - why not relative URL's?

I have been learning Laravel recently and I have seemingly missed a key point: why should relative links be avoided?
For example, I have been suggested to use URL::to() which outputs the full path of the page passed as a parameter - but why do this when you could just insert a relative link anyway? E.g., putting URL::to('my/page') into a <href> will just insert http://www.mywebsite.com/my/page into the <href>; but on my website href='my/page' works exactly the same. On my website I have based all relative URL's from the index.php file found in the public directory.
Clearly, I'm missing a key point as to why full paths are used.
I've found that using route() on named routes to be a much better practice. If at one point you decide, for example, that your admin panel shouldn't point to example.com/admin, but example.com/dashboard, you will have to sift through your entire code to find all references to Url::to("/admin"). With named routes, you just have to change the reference in routes.php
Example:
Route::get('/dashboard', ['as' => 'admin', 'uses' => 'AdminController#index']);
Now every time you need to provide a link to your admin page, just do this:
Admin
Much better approach, in my opinion.
This is even available in your backend, say in AdminController.php
// do stuff
return redirect()->route('admin');
http://laravel.com/docs/5.1/routing#named-routes
Neither absolute nor relative links should be used - it's advisable to use named routes like so:
Route::get('my/page', ['as' => 'myPage', function () {
// return something
}]);
or
Route::get('my/page', 'FooController#showPage')->name('myPage');
Then, generate links to pages using URL::route() method (aliased as route() in L5), which is available in Blade as well as in your backend code.
That way, you can change the path to your routes at any time without having to worry about breaking links anywhere in your application.

cakephp 3 prefix routing

I'm trying to set up a routing prefix in cakephp 3 so any URLs starting with /json/ get the prefix key set and I can change the layout accordingly in the app controller. Other than that, they should use the usual controller and action. I have added the following to routes.php
$routes->prefix('json', function($routes) {
$routes->connect(
'/:controller/:action/*',
[],
['routeClass' => 'InflectedRoute']
);
});
I want to direct all requests with json as first url segment to controller specified in second url segment. e.g. /json/users/add_account_type/ goes to users controller. However when accessing this URL I get the message:
Error: Create the class UsersController below in file:
src/Controller/Json/UsersController.php
whereas I want it to be using
src/Controller/UsersController.php
I think this should be possible but I can't quite see what I'm doing wrong when consulting the book. Have partly based my code on: CakePHP3.x controller name in url when using prefix routing
Thanks a lot in advance
That's simply how prefix routing now works in 3.x, as explained in the docs, prefixes are being mapped to subnamespaces, and thus to separate controllers in subfolders.
http://book.cakephp.org/3.0/en/development/routing.html#prefix-routing
If you'd wanted to change that behavior (I don't really see why), one way would be to implement a custom ControllerFactory dispatcher filter.
http://book.cakephp.org/3.0/en/development/dispatch-filters.html
On a side note, the RequestHandler component supports layout/template switching out of the box, so maybe you should give that a try.
http://book.cakephp.org/3.0/en/controllers/components/request-handling.html
http://book.cakephp.org/3.0/en/views/json-and-xml-views.html
Prefix routing is a way of namespacing parts of your routes to a dedicated controller. It seem that what you want is a scope and not a prefix, for what you describe:
Router::scope('/json', function($routes) {
$routes->fallbacks('InfledtedRoute')
});

Prevent access to /index (default Controller action)

My routes.php looks like this:
Route::controller('/', 'HomeController');
The default root action is getIndex(). Typing the address [DOMAIN NAME]/index though, returns the start page as well. How do I prevent this? I want the start page to only be accessible when going to the root URI of my project (/).
You are using RESTful Resource Controllers, replace it with,
Route::get('/', 'HomeController#getIndex');
OTHER OPTIONS
/ refers to index method in the controller by default, you could make index refer to another method which creates the view you want like.
Route::get('index', 'SomeController#someMethod');
in your route.php file
If you want the page to show a 404 you can use in your SomeController#someMethod
public function someMethod()
{
App::abort(404)
}
Or without the use of a method
Route::get('index', function() {
App::abort(404)
})
Like pointed out in the comments, you need to blacklist the /index route. But only that one! You don't need to blacklist every route you don't want your users to see, because Laravel will handle that for every route that is not defined. But index is a special case, because you have to name the default route some name, don't you?
So long talk, short meaning: Rest assured, you will only have to blacklist each index route, if it is that important to you.
I solved it like this:
Route::get('/', 'HomeController#index');
Route::controller('/', 'HomeController');
There's a reason I want a controller that takes care of all my routes :)

Laravel - Change base URL globally?

Let assume, the base URL of my application is - http://www.example.com (I have not set anything in any config file to specify this). There are a lot of hard coded urls in the application.
eg. Contact
Now, if I go though the application using an URL like - http://www.example.com/country, is it possible to assign a global base URL, where when I click on contact it will take me to - http://www.example.com/country/contact.
There are a lot of such hard-coded URL, changing it individually will take a lot of time (like appending it with a global variable). Is there any simpler way to do this or is there any config specific for this in laravel? I am fairly new to laravel. Any help would be appreciated.
You can use the somewhat cumbersome solution of applying a filter, as suggested by #worldask, but I think it would be better to set a named route and change all occurrences using a regular expression (any decent editor allows for that). That way, for the lifetime of your application you only need to change the routes in routes.php, and it will be reflected everywhere.
e.g
Route::get('country/contact', ['as' => 'contact',
'uses' => 'SomeController#someFn'];
Contact
Of course, the same principle applies to adding a prefixed group of routes, so you can wrap the entire routes file with a group prefixed by 'country'.
you can try Route Prefixing
Route::group(array('prefix' => 'country'), function(){
Route::get('Contact', 'HomeController#index');
Route::get('another', 'HomeController#index');
});
edit
try route filter
Route::filter('filtername', function($route, $request, $value)
{
if ($route == 'country') {
return Redirect::to(url);
}
});

Categories