Laravel routing, redirect with parameters - laravel

I'm aware there are similar questions, but the answers provided there do not work for me.
I had the following URL in my Laravel application:
http://example.com/anatomy/18917/why-cant-i-bend-my-back
Now the "anatomy" section has been renamed to "physio" and the new URL for the same content is this:
http://example.com/physio/18917/why-cant-i-bend-my-back
It's a GET route with the format physio/{id}/{slug}
Now, I would like to provide backwards compatibility (for any users that may have bookmarked an article in the old URL format).
So I am trying to redirect, for example, anatomy/18917/why-cant-i-bend-my-back to physio/18917/why-cant-i-bend-my-back. I have tried the following but it's not working:
$router->get('anatomy/{id}/{slug}', function() {
return redirect()->to('physio', ['id' => $id, 'slug' => $slug]);
});
And the error I get is undefined variable: id. If I do the following it redirects correctly to the homepage, but I would rather redirect to the actual article with the given parameters.
$router->get('anatomy/{id}/{slug}', function() {
return redirect()->to('/');
});

change
$router->get('anatomy/{id}/{slug}', function() {
return redirect()->to('physio', ['id' => $id, 'slug' => $slug]);
});
to
$router->get('anatomy/{id}/{slug}', function($id,$slug) {
return redirect()->to('physio', ['id' => $id, 'slug' => $slug]);
});
You nedd to pass $id and $slug in function
source

inside the controller
function($id,$slug) {
return redirect()->to('physio', ['id' => $id, 'slug' => $slug]);
};

Related

simulate route in laravel

I have this route defined
Route::get('test/something/{id?}', 'MyController#mymethod')->name('test.something');
So if go to domain_1.com/test/something/123 I get some page with data.
Now, I want to to show the exact same thing if the site if accessed form another domain with subdomain. I've defined this:
Route::group(['domain' => 'subdomain.domain_2.com'], function() {
Route::get('/', 'MyController#mymethod', ['id' => 123]);
});
but I got to subdomain.domain_2.com, I get Too few arguments error. How can I pass the id parameter to the method in the route?
You could use redirect like:
Route::get('test/something/{id?}', 'MyController#mymethod')->name('test.something');
Route::group(['domain' => 'subdomain.domain_2.com'], function() {
Route::get('/', function(){
return redirect('/test/something/123');
});
});
If you don't want to use redirect, you could check the current url from the method in the controller like:
public function mymethod($id=null){
$currentUrl = request()->url();
if (strpos($currentUrl, 'subdomain') !== false) {
$id = 123;
}
// your function
}
I've found this piece of code that gets the job done, but I'm not sure is the correct way to achieve what I want
Route::group(['domain' => 'subdomain.domain_2.com'], function()
{
Route::get('/', [ 'as' => 'some_alias', function()
{
return app()->make(App\Http\Controllers\MyController::class)->callAction('mymethod', $parameters = [ 'id' => 123 ]);
}]);
});

Laravel | How to append parameter to URL when using Redirect::route and Redirect::back()?

My view provides links like http://finance.dev/home/customer/6#tab_1_3 so that user a can directly navigate to a tab in the page using the link.
In my routes I have :
Route::get('/home/customer/{id}',[
'as' => 'home.customer',
'uses' => 'CustomerController#show'
]);
Route::get('/home/customer/{id}/{navigate}/{tab}',[
'as' => 'home.customer.navigate',
'uses' => 'CustomerController#navigate'
]);
I am passing the required variables to route using:
window.location.href = '/home/customer/'+id+'/'+navigate+'/'+tab;
And my controller logic is :
public function navigate($id, $navigate, $tab)
{
$user = customer::find($id);
if($navigate == 'previous')
{
// get previous user id
$go = customer::where('id', '<', $user->id)->max('id');
}
elseif ($navigate == 'next') {
// get next user id
$go = customer::where('id', '>', $user->id)->min('id');
}
else{
return \Redirect::back();
}
return \Redirect::route('home.customer', array('id' => $go));
}
The above code successfully returns a URL like http://finance.dev/home/customer/6
Now I am trying to figure out how to define \Redirect::route and \Redirect::back() to return a URL like http://finance.dev/home/customer/6#tab_1_3
How can I go about this?
$url = URL::route('home.customer', ['id' => $go])."#tab_1_6";
return \Redirect::to($url);
Reference Link

Laravel login redirect doesn't work

I have made the login/tregistration form. Registration works well but login redirect doesn't work. I have the following function in my controller:
public function doLogin() {
$credentials = [
'email' => Input::get('email'),
'password' => Input::get('password')
];
if (Auth::attempt($credentials)) {
return Redirect::to('/');
} else {
dd('error');
}
}
and the routes.php
Route::resource('car', 'CarController');
Route::get('users', 'UserController#index');
Route::post('users/register', array('uses' => 'UserController#store'));
Route::post('users/signin', array('uses' => 'UserController#doLogin'));
Route::get('users/logout', array('uses' => 'UserController#doLogout'));
Route::get('/', 'CarController#index');
CarController
public function index() {
$cars = DB::select('select * from cars');
$result = DB::select('select c.*, i.sgs, i.tpl, i.kasko, i.inter_permis from cars as c left join insur_docs as i on i.car_id = c.id');
$date = Carbon::now();
$limit_date = Carbon::now()->addMonths(1);
return View::make('pages.index', array(
'cars' => $cars,
'result' => $result,
'date' => $date,
'limit_date' => $limit_date,
));
}
The problem is that it doesn't redirects to index page just refresh the page. If not correct credentials it shows "error" else if correct credentials it just refresh page and doesn't redirects. I f I replace redirect with success message it shows it. I have the same code localy and login with redirect is ok, but in google app engine (my project online) doesn't redirect.
The example you have used wouldn't actually redirect the user for two reasons.
The use of Redirect::route() excepts the parameter passed to be the name of a route, eg one defined like so
Route::get('/', ['as' => 'home', 'uses' => 'YourController#yourMethod']);
To redirect here you would use Redirect::route('home').
You aren't actually returning the redirect. Any response for a route, whether it be within a controller method or a closure, must be returned using the return keyword.
So to correct your code, it'd be like this:
public function doLogin() {
$credentials = [
'email' => Input::get('email'),
'password' => Input::get('password')
];
if (Auth::attempt($credentials)) {
return Redirect::to('/');
} else {
dd('error');
}
}
I moved the credentials to an array as it looks tidier and it makes it easier to read when displaying on this site, so you don't have to do that, but it may make things easier for you.

Laravel 4 : Route returning wrong information

I am setting up an API with Laravel so that I can connect with an AngularJS front-end.
I have 2 routes that go to the same controller method -> BallController#getSpecs
My routes are set up as follows:
Route::group(['prefix' => '/api/v1', 'before' => 'auth.basic'], function() {
Route::group(['prefix' => '/ball'], function() {
Route::get('/', 'BallController#getIndex');
Route::get('{id}', 'BallController#getIndex');
Route::get('specs', 'BallController#getSpecs');
Route::get('{id}/specs', 'BallController#getSpecs');
});
});
Now I am having trouble with Route::get('specs', 'BallController#getSpecs'); route.
The getSpecs method is defined as follows:
public function getSpecs($id = null)
{
if(empty($id))
{
Ball::all()->each(function($ball) {
$json = [$ball->id => [
'name' => $ball->name,
'core' => $ball->core->toArray(),
'coverstock' => $ball->coverstock->toArray(),
'finish' => $ball->finish->toArray(),
'manufacturer' => $ball->manufacturer->toArray()
]];
});
return Response::json($json);
}
else
{
$ball = Ball::find($id);
if(empty($ball))
{
return Response::json('You\'ve got no ballss', 404);
}
else
{
return Response::json([$ball->id => [
'name' => $ball->name,
'core' => $ball->core->toArray(),
'coverstock' => $ball->coverstock->toArray(),
'finish' => $ball->finish->toArray(),
'manufacturer' => $ball->manufacturer->toArray()
]]);
}
}
}
When I call /api/v1/ball/1/specs specifying an id I get the correct information back, however when I call /api/v1/ball/specs my function returns my error message 'You've got no balls'
ID should be null in this cast putting me into the first part of my if statement but for some reason I am getting into my else and getting my error because obviously no ID was provided and the ball won't exist.
Any help/insight will be appreciated.
Edit: I think it may be sending it to the wrong method. I think that /api/v1/ball/specs is being sent to BallController#getIndex instead of BallController#getSpecs.
The problem is in this part of the routing:
Route::get('{id}', 'BallController#getIndex');
Route::get('specs', 'BallController#getSpecs');
When it sees "/api/v1/ball/specs", it will actually call getIndex() with the "id" parameter set to "specs", because that's the first matching route. One way to fix it would be to define the "specs" route first before you define the "{id}" route. But a better solution would be to limit the accepted values of the "{id}" parmeter like this...
Route::get('{id}', 'BallController#getIndex')->where('id', '[0-9]+');
One other suggestion, there shouldn't be a leading "/" in your prefix values (apparently the code may be working anyway, but they aren't really supposed to be there. So the complete updated route might look like this...
Route::group(['prefix' => 'api/v1', 'before' => 'auth.basic'], function() {
Route::group(['prefix' => 'ball'], function() {
Route::get('/', 'BallController#getIndex');
Route::get('specs', 'BallController#getSpecs');
Route::get('{id}', 'BallController#getIndex')->where('id', '[0-9]+');
Route::get('{id}/specs', 'BallController#getSpecs')->where('id', '[0-9]+');
});
});

Laravel 4 password reminder: redirection issue

I'm using the Laravel 4 password reminder functionality, as described here: http://four.laravel.com/docs/security#password-reminders-and-reset. In order to generate the token, send the email and create de DB record in the password_reminder table, I use the standard code in my routes file :
Route::post('password/remind', function() {
$credentials = array('email' => Input::get('email'));
return Password::remind($credentials);
});
This code is suppose to send me back to my input form in case of any error (unknown email address for instance). Instead of that, I get a MethodNotAllowedHttpException. The reason is Laravel don't try to send me back to my form URL (which is /password/forgot): he tries to redirect me to /password/remind, in GET, and this route does not exist (of course) in my routes.php file.
I checked the code of the Illuminate\Auth\Reminders\PasswordBroker class, which is responsible of this redirection, and found out this method :
protected function makeErrorRedirect($reason = '')
{
if ($reason != '') $reason = 'reminders.'.$reason;
return $this->redirect->refresh()->with('error', true)->with('reason', $reason);
}
I replaced $this->redirect->refresh() by $this->redirect->back(), and everything is now working as excepted. But as I couldn't find any comment on this bug anywhere, I assume I'm doing something wrong… But I can't find what !
Here is my routes.php file:
Route::get('password/forgot', array('as' => 'forgot', 'uses' => 'SessionsController#forgot'));
Route::post('password/remind', function() {
$credentials = array('email' => Input::get('email'));
return Password::remind($credentials);
});
Route::get('password/reset/{token}', function($token) {
return View::make('sessions.reset')->with('token', $token);
});
Route::post('password/reset/{token}', array('as' => 'reset', 'uses' => 'SessionsController#reset'));
my SessionsController relevant code:
class SessionsController extends BaseController {
[...]
public function forgot() {
return View::make('sessions.forgot');
}
public function reset() {
$credentials = array(
'email' => Input::get('email'),
'password' => Input::get('password'),
'password_confirmation' => Input::get('password_confirmation')
);
Input::flash();
return Password::reset($credentials, function($user, $password) {
$user->password = Hash::make($password);
$user->save();
return Redirect::to('home');
});
}
}
and finally my view code:
{{ Form::open(array('url' => 'password/remind', 'class' => 'form', 'role' => 'form', 'method'=>'post')) }}
<div class="form-group">
{{ Form::label('email', 'E-mail') }}
{{ Form::text('email', '', array('autocomplete'=>'off', 'class' => 'form-control')) }}
</div>
{{ Form::submit("Envoyer", array("class"=>"btn btn-primary")) }}
{{ Form::close() }}
If it is possible, I highly recommend you to upgrade to Laravel 4.1, because it comes with a more flexible (also easier to understand and to work with) solution for password remind/reset.
Check out this example with Laravel 4.1:
https://github.com/laracasts/Laravel-4.1-Password-Resets/blob/master/app/controllers/RemindersController.php

Resources