I want to have one route rule for both GET and POST methods that redirect to one controller. Problem is GET doesn't require any parameters (it returns a view) but POST will have some parameters that are sent through a form.
In ASP.NET MVC5 I do it with one route rule and two controller methods with the same name but one of them (the POST method) has a [HttpPost] attribute and the parameters it needs while the GET method doesn't have any parameter or attribute.
How does one implement something like that in Laravel 5.x?
This is the possible controller:
public function convertUrl($somedataforpost)
{
if(Request::isMethod('get'))
{
// return a view
}
if(Request::isMethod('post'))
{
// do something with POST data
}
}
This is an example of how you would implement the rule:
Route::match(['get', 'post'], 'order/{invoice}/confirm', ['uses' => 'OrderController#paymentConfirmation', 'as' => 'order.payment.confirmation']);
Related
so i have my routes defined within a global route group and inside i have two others groups, on with middleware 'employee' and one with middleware 'admin' and each one have their own controllers.
The two groups have a route index with the same url " /document " but each executes a different controller.
My problem is the index route that the last defined group always overrides the previous one.
The wanted behaviour is that if employee middleware is valid, execute the empController#index action, else if the admin controller is valid, execute the adminController#index action while keeping the same url for both, and i must keep each route in a seperate group, and the two routes must have the same url.
How can i acheive that? Thanks
here are the two conflicting routes
Route::group(['as' => 'admin.', 'middleware' => ['admin']], function() { Route::get('/document', 'Admin\DocumentController#index')->name('document.index'); .... });
Route::group(['middleware' => ['employee']], function() { Route::get('/document', 'DocumentController#index')->name('document.index'); .... });
It sounds like you want to perform different actions based on whether the request is coming from an employee or an admin. My suggestion would be to have one url, one route and one controller function for this.
Within the controller function (or in middleware that attaches its findings to the request if you wanted to do that), have logic to call one method or another.
A pseudo example in PersonController.php:
if(\Auth::user()->isAdmin()) {
// return an admin view or perform an admin function
else {
// return an employee view or perform an employee function
}
Where the isAdmin() function is something you've defined in a model like User.php.
I have get some documents from Laravel Documentation.But i can't get details clearly from that. There are lot of routing methods and how to use that for my requirements? Commonly most people are using this, but what are the other routing methods?
Route::get()
Route::post()
How to pass the message or values through this Routing? Using Controller like this is a only way?
Route::get('/app', 'AppController#index');
Types of Routing in Laravel
There are some Routing methods in Laravel, There are
1. Basic GET Route
GET is the method which is used to retrieve a resource. In this example, we are simply getting the user route requirements then return the message to him.
Route::get('/home', function() { return 'This is Home'; });
2. Basic POST Route
To make a POST request, you can simply use the post(); method, that means when your are submitting a Form using action="myForm" method="POST", then you want to catch the POST response using this POST route.
Route::post('/myForm', function() {return 'Your Form has posted '; });
3. Registering A Route For Multiple Verbs
Here you can retrieve GET request and POST requests in one route. MATCH will get that request here,
Route::match(array('GET', 'POST'), '/home', function() { return 'GET & POST'; });
4. Any HTTP Verb
Registering A Route Responding To Any HTTP Verb. This will catch all the request from your URL according to the parameters.
Route::any('/home', function() { return 'Hello World'; });
Usage of Routing in Laravel
When your are Using the Route::, Here you can manage your controller functions and views as follows,
1. Simple Message Return
You can return a simple message which will display in the webpage when user request that URL.
Route::get('/home', function(){return 'You Are Requesting Home';});
2. Return a View
You can return a View which will display in the webpage when user request that URL
// show a static view for the home page (app/views/home.blade.php)
Route::get('/home', function()
{
return View::make('home');
});
3. Request a Controller Function
You can call a function from the Controller when user request that URL
// call a index function from HomeController (app/Http/Controllers)
Route::get('/home', 'HomeController#index');
4. Catch a value from URL
You can catch a value from requested URL then pass that value to a function from Controller. Example : If you call public/home/1452 then value 1452 will be cached and will pass to the controller
// call a show function from HomeController (app/Http/Controllers)
Route::get('/home/{id}', 'HomeController#show');
You can get help about routing from Laravel.
There are 4 methods ofform data sending that you must know --
Route::get for <form method="GET">
Route::post for <form method="POST">
Route::put for <form method="PUT"> -- This one is for updating your database, I recommend you to use laravelcollective/html, like this -- {!! Form::open(['method' => 'PUT']) !!}, but in your web browser you can find the method as POST only
Route::delete for <form method="DELETE"> -- This one is for deleteing a field in your database, I recommend you to use laravelcollective/html, like this -- {!! Form::open(['method' => 'DELETE']) !!}, but in your web browser you can find the method as POST only
There are many much you have to know about Laravel Routing, like CRUD, etc.
This is driving me crazy as I think I'm doing the right thing but its not working correctly.
I have a route with a middleware attached to it like below;
Route::get('post/{id}/{name}', 'BlogController#post')->name('blog-post')->middleware('blogGuard');
As you can see I've defined 2 route params
In my controller I have below;
public function post () {
return view('pages.blog.post');
}
With the middleware defined like this;
public function handle($request, Closure $next)
{
if (is_null($request->input('id')) ||
is_null($request->input('name'))) {
return redirect()->route('blog-home');
}
return $next($request);
}
Now if I click on a link like so; http://blog.example.co.uk/post/153/firstpost the middleware should not fire correct?
This is not the case. The middleware executes and I'm redirected. But if I remove the middleware then I'm able to access the page.
Any help appreciated.
If you are trying to access route parameters you probably want to explicitly get them from the route.
$request->route('id'); // pulls the $route->parameter('id');
$request->route('name'); // pulls the $route->parameter('name');
$request->id will check the request inputs before falling back to returning a route parameter.
$request->input('id') will only check the input sources for the request and not the route params.
If you use $request->id expecting to get the route param 'id', one could break your logic by passing id=anythinghere to the querystring or adding a 'id' var to a post request.
Try this
if (!$request->id ||
!$request->name)
I'm using laravel 5 and this is my problem. User fill in form X and if he isin't logged in, he gets redirected to fill in more fields form OR he gets possibility to log in. Everything works just fine, if user fill in additional fields, but if he login, laravel redirects user to form X with GET method instead of POST.
This is how my middleware redirect looks like:
return redirect()->guest('user/additional-fields');
This redirect appears on successfull log in:
return redirect()->intended();
So on redirect intended i get error
MethodNotAllowedHttpException. URL is correct which is defined as POST method. What am I missing here? Why does laravel redirects intended as GET method? How could I solve this problem? Thanks!
EDIT:
Route::post('/user/log-in-post', ['as' => 'user-log-in-post', 'uses' => 'UserController#postUserLogIn']);
This is my route, I hope this is one you need.
You can use a named route to solve this issue:
Lets make a named route like this:
For Get
Route::get('user/additional-fields',array(
'uses' => 'UserController#getAdditionalFields',
'as' => 'user.getAdditionalFields'
));
For post
Route::post('user/additional-fields',array(
'uses' => 'UserController#postAdditionalFields',
'as' => 'user.postAdditionalFields'
));
So we can now ensure Laravel uses the right route by doing this
return redirect()->guest(route('user.getAdditionalFields'));
Also note that its not possible to redirect a POST because Laravel expects form to be submitted. SO you can't do this:
return redirect()->guest(route('user.postAdditionalFields'));
except you use something like cURL or GuzzleHttp simulate a post request
You have to trick Laravel router by passing an "_method" the inputs.
The best way I found is by adding tricking and rewriting the Authenticate middleware
You have to rewrite the handle method to allow your redirection with your new input.
redirect()->guest('your/path')->with('_method', session('url.entended.method', 'GET'));
When you want to redirect to a route using another method than GET, simply do a Session::flash('url.entended.method', 'YOUR_METHOD').
Tell me if it do the trick
Very Simple Approach for Post method Route form Controller.
The idea behind this is, every Route always calls the Action method of a Controller. so that in that case you can directly call that method in place of Redirect action performed.
check a code sample of XYZController
$registration = Registration::find($req->regId);
$registration->update([ 'STEP_COMPLETED' => 5]); // Step 5 completed.
# Call Post Method Route
return $this->admissionFinish($req);
Note that $req should have all parameter that required in next
action Method.
change the below code in app\exceptions\handler.php
use Exception;
use Request;
use Illuminate\Auth\AuthenticationException;
use Response;
protected function unauthenticated($request,AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
//return redirect()->guest(route('login'));
return redirect()->guest('http://127.0.0.1:8000/api/signinnew'); // change this part to your login router
}
And in routes(i.e api.php):
Route::Any('signinnew', [UserLogonController::class, 'signinNew']);
This will work in laravel 8x
I try to set some specific filter on all controller methods with:
public function __construct() {
$this->beforeFilter(function(){
//whathever
});
}
and it's working well on normal GET methods, problem occures when there is some POST method:
Route::post('settings/menu-order/{direction}', array(
'as' => 'setting.menu-order.move',
'uses' => function($direction) {
$controller = new CMSSettingsController();
return $controller->doMoveMenu($direction);
}));
after click in a button which send POST with $direction, I'v got
Call to a member function filter() on a non-object
in vendor/laravel/framework/src/Illuminate/Routing/Controller.php
protected function registerClosureFilter(Closure $filter)
{
$this->getFilterer()->filter($name = spl_object_hash($filter), $filter);
return $name;
}
If I use already registred filter it's working, so what's going on?
I have few controllers which need specific function todo before running controller methods, so I can't make global universal filter. Is there any other good solution?
The problem could be that you are calling the controller action directly instead of letting the Router do it for you. When the router tries to apply the filters, instead of applying them on the controller, it ends up attempting to apply them on the output of the doMoveMenu action - which, of course, is not a Controller object and has no method filter.
Instead, your route should look like this:
Route::post('settings/menu-order/{direction}', array(
'as' => 'setting.menu-order.move',
'uses' => 'CMSSettingsController#doMoveMenu'));
The reason you don't need to do the method call manually is that since your Route has a parameter in it and your method accepts a parameter, the Router will automatically pass the parameter into the action method. Additionally, since you are providing a method name as the uses value, Laravel knows that it has to instantiate the Controller and run the filters.