switch route in web.php laravel - php

I've 2 routes in my web.php
1) Route::get('/{url}', 'MenuController#menu');
which provide url :
/menu
2) Route::get('/{name}', 'HomeSlideviewController#index')->name('promotiondetail');
which provide url :
/menu (different page but same name in route 1)
/food
I want to use 2 route if route = same name I want to use route 1 if route 1 dont have url It will use route 2 . In web.php is their anyway to do something like
if(Route::get('/{url}', 'MenuController#menu')) is null use
`Route::get('/{name}', 'HomeSlideviewController#index')->name('promotiondetail');`
now in my web.php I do this
Route::get('/{url}', 'MenuController#menu');
Route::get('/{name}', 'HomeSlideviewController#index')->name('promotiondetail');
when I go /food It will go page not found.
UPDATE
In my controller I try this
try {
// if find url
}
} catch (\Exception $e) {
//if not find url
return redirect()->route('promotiondetail', $url);
}
and It return Error redirected you too many times
UPDATE 3
$url = food

Your problem is that when you use
Route::get('/{url}', 'MenuController#menu');
Route::get('/{name}', 'HomeSlideviewController#index')->name('promotiondetail');
you are having the same request because {url} or {name} are optional parameters and what happens is that it will always match the first case. The best solution for you can be using this part of code:
Route::get('/menu', 'MenuController#menu');
Route::get('/{name}', 'HomeSlideviewController#index')->name('promotiondetail');
You should always have the one with only optional parameters last, because otherwise it will always be executed first because it will be matching. And what you should remember is that using /{name} it will match anything, it is like a variable and can contain a number also it can be a string, for instance a url might be domain/{anything}. If you use /name it will match only if you are having domain/name as request.
You might want to read Laravel routing for more information about routing.

The problem you have is that both routes are essentially the same, /{something}.
You have a couple of solutions.
Firstly, sort out your routes, make them slightly different so they don't match each other and correct the order.
For example;
Route::get('/promo/{name}', 'HomeSlideviewController#index')->name('promotiondetail');
Route::get('/{url}', 'MenuController#menu')->name('menu');
Another solution that may work for you is to place the promotiondetail route first, and do a check in that for the same name, if not then redirect to the other controller. So in your index function of HomeSlideviewController, try something like;
public function index($name) {
if ($name !== 'whatever you want it not to be') {
return redirect()->route('menu);
}
// continue
}

Related

Limit parameters in codeigniter URI

I'm facing an issue with codeigniter URI routing.
I have a route like this:
website.local/terms/SOMEINFORMATIONID/SOMECURRENCY
Where SOMEINFORMATIONID & SOMECURRENCY are the URI parameters.
The problem is, when I call website.local/terms/SOMEINFORMATIONID/SOMECURRENCY/SDFSDFSDFSD
So this means, that i'm introducing a third parameter, the URI still works, but what I want is, when the route is "executed" with more than 2 parameters, get a 404 error.
I was trying to find something in codeigniter documentation, but I couldn't find anything, anyway I don't know for what I should look for (codeigniter uri parameters limited, etc...).
As additional information, my route looks like this in routes.php:
$route['terms/(:any)/(:any)'] = 'xxx/terms/$1/$2';
in controller:
//check segment
$sdf= $this->uri->segment(4);
if ( ! empty($sdf)) $this->my404();
and function
public function my404 () {
$this->output->set_status_header('404');
$data['error'] = 'Not Found...'
$this->smarty->view( 'error.tpl', $data);
}
if you are using ci3, you can add one more route at last like
$ route ['(. +)'] = 'error_page'; // all the urlĀ“s that you don't have before will display the error you want

Laravel 5.2 Redirecting With WildCard ID not working

I got an error with redirecting I dont know why, i read the documentation of laravel 5.2 about redirecting and still not working pls help me thanks, here is my route in the routes.php
Route::get('/orders/view/{id}', 'OrderController#view');
here is my code in the controller for the redirecting
return redirect()->route('/orders/view/', ['id' => 5]);
and still it gives me this error
InvalidArgumentException in UrlGenerator.php line 314: Route
[/orders/view/] not defined.
The Problem
You're trying to redirect to a route by it's name, but you're passing an URL to the method.
return redirect() # Initialize a redirect...
->route(...); # to a route by it's name
The solutions
There are multiple ways to solve this. You can either redirect by path (that's
how you're trying to do at the moment), or by using route names.
Method 1: Redirect by path
You can redirect by path in two ways:
- concat the path by hand
- use the URL facade.
Concat the path by hand
$url = '/orders/view/' . $order->id;
return redirect($url);
Use the URL facade
# Remember to remove the trailing slash.
# Appending a trailing slash would lead to example.com/orders/view//1
$url = URL::to('/orders/view', [$order->id]);
return redirect($url);
You're done!
Method 2: Redirect by route name
To use route names, you need to prepare your routes and give them a name.
I recommend this way, because sometimes it's more clear but it also makes
maintaining your application easier when you need to change some paths, because
the names will be still the same. Read more about it here:
https://laravel.com/docs/5.2/routing#named-routes
This also allows you to use the easy-to-use and useful route() helper method.
Prepare your routes file
To assign your routes a name, you need to pass them to your router in your app/Http/routes.php.
# Example 1
Route::get('/orders/view/{id}', [
'as' => 'orders.view', 'uses' => 'OrderController#view'
]);
# Example 2
Route::get('/orders/view/{id}', 'OrderController#view')->name('orders.view');
For myself, I recommend to use the second syntax. It makes your code more
readable.
Redirect by route name
Now it's time to redirect! If you're using the method of route naming, you don't
even have to change much in your code.
return redirect()->route('orders.view', ['id' => $order->id]);
A note from my side
Have a look on route-model-binding in the documentation:
https://laravel.com/docs/5.2/routing#route-model-binding
This allows you to pass a model instance directly to the route() method and
it helps you fetching models by passing the proper model to your controller method
like this:
# Generate route URL
route('orders.view', $order);
# Controller
public function view(Order $order) {
return $order;
}
And in your app/Http/routes.php you would have {order} instead of {id}:
Route::get('/orders/view/{order}', 'OrderController#view');
You can use
return redirect()->action('OrderController#view', ['id' => 5]);
or
// $id = 5
return redirect()->to('/orders/view/'.$id);

Dynamic url issue in Laravel

Hi I have project structured in 2 parts: frontend urls and backend urls. The backend urls are like base-url/admin/pagename the frontend urls are like base-url/pagename.
I want to create some dynamic pages. The url name are came from the database.
this is my route from the web.php file:
Route::any('{slug}', 'PageController#show');
This is my controller
public function show($slug = null)
{
if('admin' != $slug){
$page = Pages::where('route', $slug)->where('active', 1);
$page = $page->firstOrFail();
return view($page->template)->with('page', $page);
}
}
Somehow I want to avoid to take into consideration every url starting with baseurl/admin/. I am wondering if I can do it from the web.php. If yes , how ?
Define all your static routes first for precedence issues. Then define your any route at the end, with some regular expressions
Route::any('{slug}', 'PageController#show')->where('slug', '^[a-zA-Z0-9-]*$');
This is telling the url to only allow alphanumeric and dashes -. So any url with a forward slash wont work.
/my-first-page-1 --> should work
/my/first/page/2 --> shouldn't work
this way you know baseurl/admin/ will never work. You can search online for more regular expressions.
try this:
Route::any('/base-url/admin/{slug}', 'SomeController#someMethod');
Route::any('{slug}', 'PageController#show');
laravel routes are matched from top to bottom and it will stop when it finds the first match, so routes defined first take precedence over those defined later, in this case, the first route will match any request for url starting with /base-url/admin/ and the second route will match everything else.
you just need to replace 'SomeController#someMethod' with the controller in charge of that functionality

How can I check whether the route "URL" exists?

In Laravel 5.2, is there a particular way (handler) to check whether a route is existing or not? Let's say, for a basic URL like:
http://www.example.com/laravel
I then want to handle the non-existing URLs (like: /laravel) from my Main Page Router, which is:
Route::get('/{page}', funtion(){
//check if $page is a valid route URL? Or 404?
});
How do I purposely check whether this route is a valid one or not?
I use the following as my last route:
Route::any('{catchall}', function($page) {
abort(404);
} )->where('catchall', '(.*)');
If you are not aware yet, abort(404) will return the view 404.blade.php from resources/views/errors.
Simply put your Route::get('/{page}','MainController#getPage'); last. That way if it finds another route before it will use it but if it doesn't then it will get caught by this. For example:
Route::get('/welcome','WelcomeController#getWelcome');
Route::get('/test','TestController#getTest');
Route::get('/{page}','MainController#getPage');
If you were to hit /welcome or /test it should route them to the correct controller. If you where to hit /hello it should go to the MainController and hit function getPage($page) with $page being the page you hit.
If it hits MainController#getPage you know it was basically a 404.
If you need to know before you hit the route for some reason you could create something like this:
Route::get('/checkurl/{page}',function($page) {
$exists = Route::has('/' . $page);
return (new Response(json_encode(['exists'=>$exists]),200);
});
Adding last route with any catch doesn't works anymore with laravel 5.5.1+

RESTful trailing slash routes in laravel

I have the following routes in my Laravel 3 RESTful api project
Route::delete('/(:any)', 'resources#destroy');
Route::delete('users/(:any)', 'users#destroy');
The problem I am having is when a user sends a delete request to /users/
What I want to happen is that the users#destroy route is called with parameter null. In my controller I have an exception for a user trying to delete a null resource.
What seems to be happening is that the resource#destroy route is called with parameter users. This obviously has the undesired affect of deleting the users resource.
I know I could modify my .htaccess but technically /users/ does belong to the users controller not the resources controller. I want to maintain that relationship.
I was wondering if there is a simple way to solve this from within Laravel?
EDIT: have the above working with the answer below. Now I have an error in my get routes
Route::get('users/(:any?)', 'users#show');
Route::get('users', 'users#index');
/users and /users/ both call users#index which I don't want.
I need GET /users to go to users#index and GET /users/ to go to users#show with null parameter
I worked around the trailing slash by adding a filter to my routes
Route::group(array('before' => 'trailingslash'), function()
{
//routes in here
});
Route::filter('trailingslash', function() {
$current = URI::full();
if(substr($current, -1) == '/'){
return return Response::error('404');
}
});
one point you need to consider.
Routes are defined without a front-slash. The only exception to this is the default route which is represented with only a front-slash.
so Route::delete('/(:any)', 'resources#destroy') will cause undesired result.
Moreover, your order is wrong.
(:any) will match user too and will send the request to resources controller.
so what you need to do is,
change the order (make it reverse).
change the route of resources considering according to the rules. like resources/delete etc.....
What I want to happen is that the users#destroy route is called with parameter null. In my controller I have an exception for a user trying to delete a null resource.
to do this, (after making the changes above....)
change the route of user/(:any) to user/(:any?) which will make the 2nd segment optional.
After that, straight forward.
$foo = URI::segment(2, null);
//Rest will follow.
EDIT
Now, the following code,
Route::get('users/(:any?)', 'users#show');
Route::get('users', 'users#index');
does not make any sense.
if i type user, what the router is suppose to take?
user#show with no optional segment or user#index?
Routes are design so that it removes the ambiguity. You are going in the opposite direction with making it all ambiguity.
just make a simple route.
like show
user/show
delete
user/delete
edit
user/edit
etc....
The type of routing you are applying is confusing for both users and developers as it carries ambiguity.

Categories