I'm trying to handle basic validation of my API calls in the Laravel's routes. Here is what I want to achieve:
Route::group(['prefix' => 'api/v1/properties/'], function () {
Route::get('purchased', 'PropertiesController#getPropertyByProgressStatus', function () {
//pass variable x = 1 to the controller
});
Route::get('waiting', 'PropertiesController#getPropertyByProgressStatus', function () {
//pass variable x = 2 to the controller
});
});
Long story short, depending on the segment of the URI after api/v1/properties/ I want to pass a different parameter to the controller. Is there a way to do that?
I was able to get it to work with the following route.php file:
Route::group(['prefix' => 'api/v1/properties/'], function () {
Route::get('purchased', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 1
]);
Route::get('remodeled', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 1
]);
Route::get('pending', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 3
]);
Route::get('available', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 4
]);
Route::get('unavailable', [
'uses' => 'PropertiesController#getPropertyByProgressStatus', 'progressStatusId' => 5
]);
});
and the following code in the controller:
public function getPropertyByProgressStatus(\Illuminate\Http\Request $request) {
$action = $request->route()->getAction();
print_r($action);
Pretty much the $action variable is going to let me access the extra parameter that I passed from the route.
I think that you can do it directly in the controller and receiving the value as a parameter of your route:
First you need to specify the name of the parameter in the controller.
Route::group(['prefix' => 'api/v1/properties/'], function ()
{
Route::get('{parameter}', PropertiesController#getPropertyByProgressStatus');
In this way, the getPropertyByProgressStatus method is going to receive this value, so in the controller:
class PropertiesController{
....
public function getPropertyByProgressStatus($parameter)
{
if($parameter === 'purchased')
{
//do what you need
}
elseif($parameter === 'waiting')
{
//Do another stuff
}
....
}
I hope it helps to solve your issue.
Take a view for this courses: Learn Laravel or Create a RESTful API with Laravel
Best wishes.
----------- Edited ---------------
You can redirect to the route that you want:
Route::group(['prefix' => 'api/v1/properties/'], function () {
Route::get('purchased', function () {
return redirect('/api/v1/properties/purchased/valueToSend');
});
Route::get('waiting', function () {
return redirect('/api/v1/properties/waiting/valueToSend');
});
Route::get('purchased/{valueToSend}', PropertiesController#getPropertyByProgressStatus);
});
Route::get('waiting/{valueToSend}', PropertiesController#getPropertyByProgressStatus);
});
});
The last two routes response to the redirections and send that value to the controller as a parameter, is the most near that I think to do this directly from the routes.
Related
I have 2 views file for each 2 forms in one page , i can successfully add data from first form to database and read it but when i tried in second views, it gives 419 | PAGE EXPIRED error. I use same code i used in first views to add data.
this is my routes :
Route::group([
'prefix' => 'atribut',
'as' => 'atribut.'
], function () {
Route::group(['prefix' => 'tabHome', 'as' => 'tabHome.'], function () {
Route::get('', [AtributDashboardController::class, 'showTab'])->name('showTab');
Route::post('addDataFirst', [AtributDashboardController::class, 'addDataFirst'])->name('addDataFirst');
Route::get('deleteDataFirst/{id}', [AtributDashboardController::class, 'deleteDataFirst'])->name('deleteDataFirst');
Route::post('addDataSecond', [AtributDashboardController::class, 'addDataSecond'])->name('addDataSecond');
Route::get('deleteDataSecond/{id}', [AtributDashboardController::class, 'deleteDataSecond'])->name('deleteDataSecond');
});
});
This is my method in controller to add data:
public function __construct()
{
$this->inpDataFirst = new inpDataFirst ();
$this->inpDataSecond = new inpDataSecond ();
}
public function addDataFirst()
{
$data = [
'name' => Request()->nameForm,
'address' => Request()->addressForm,
];
$this->inpDataFirst->addData($data);
return redirect('atribut/tabHome');
}
public function addDataSecond()
{
$data = [
'name' => Request()->nameForm,
'address' => Request()->addressForm,
];
$this->inpDataSecond->addData($data);
return redirect('atribut/tabHome');
}
in first view i have form action :
{{route('frontend.atribut.tabHome.addDataFirst')}}
and in second view i have form action :
{{route('frontend.atribut.tabHome.addDataSecond')}}
the form is in same page but different views file, that's why i use return redirect
419 error is shown when csrf token is mismatched add #csrf to your form
My route:
Route::group([
'prefix' => '{locale}',
'where' => ['locale' => '[a-zA-Z]{2}'],
'middleware' => 'setlocale'],
function () {
// GROUP FOR AUTHENTICATION
Route::group([
'middleware' => 'auth:sanctum', 'verified',
], function () {
// GROUP FOR ADMIN
Route::group([
'prefix' => 'admin',
'as' => 'admin.',
], function () {
Route::resource('partner', PartnerFormController::class);
});
});
});
My view that when I click, it shows the details page:
Edit
My controller:
public function show(PartnerForm $partnerForm, $id)
{
$details = DB::table('partner_forms')->where('id', $id)
->first();
return view('admin.partner-details', compact('details'));
}
I tried to call $details->name or $details->in my view details page but it didnt work. The URL is working properly by displaying http://127.0.0.1:8000/en/admin/partner/1 but when i dd() my $id in controller it returns en, which I believe is the en from the URL.
Instead of sending the ID along with the route, send all the variables and enter the information into the new page in the control without the need to connect to the database and using route model binding.
Example :
view A
Foo
route
Route::get('.../{partner}', [Controller::class, 'Bar'])->name('admin.partner.show');
controller
public function Bar(Partner_MODEL $partner){
return view('view_name', compact('partner'));
}
view B : use $partner.
Important note : in (route, controller method, compact meethod) The variable name must be similar
I need to call different controller for the same url based on a middleware. The url has to be the same, so redirecting in the middleware is not an option. The code below is sample, controllers for dozens for routes are already finished, so checking the session value there is not an option either.
Tried to create two different middleware (has/hasnt the session value), but the latter route group overwrites the previous anyway. Any clue? Maybe a different approach needed?
route.php looks like this:
Route::group(array('namespace' => 'Admin', 'prefix' => 'admin', 'middleware' => 'auth'), function () {
// set of default routes
Route::get('/', array('as' => 'admin', 'uses' => 'FirstController#index'))->middleware('admin');
Route::get('/profile', array('as' => 'profile', 'uses' => 'FirstController#profile'))->middleware('admin');
Route::group(array('middleware' => 'sessionhassomething'), function () {
// set of the same routes like above but overwritten if middleware validates
Route::get('/', array('as' => 'admin', 'uses' => 'SecondController#index'))->middleware('admin');
Route::get('/profile', array('as' => 'profile', 'uses' => 'SecondController#profile'))->middleware('admin');
});
});
SessionHasSomething middleware:
class sessionHasSomething {
public function handle($request, Closure $next)
{
if(session()->has("something_i_need_to_be_set")) {
return $next($request);
}
// return what if not set, or ...?
}
}
Thanks in advance!
If you are only checking if session()->has('something'), it is possible to use route closures to add a condition within the route which needs to be dynamic.
Below is an example:
Route::get('/', function() {
$controller = session()->has('something')) ? 'SecondController' : 'FirstController';
app('app\Http\Controllers\' . $controller)->index();
});
->index() being the method within the controller class.
We almost have the same issue and here's what I did. (I didn't use middleware).
In my blade.php, I used #if, #else and #endif
<?php
use App\Models\User;
$check = User::all()->count();
?>
#if ($check == '0')
// my html/php codes for admin
#else
// my html/php codes for users
#endif
you can also do that in your controller, use if,else.
I need all the route under same prefix manager with one middleware for guest manager_guest and another for logged in user manager_auth.
This code bellow is my route web.php file.
Is there any other way ?
My routes:
Route::prefix('manager')->group(['middleware' => 'manager_guest'], function () {
Route::get('/register', 'Manager\RegisterController#showRegister')->name('manager.register.create');
Route::post('/register', 'Manager\RegisterController#register')->name('manager.register.store');
Route::get('/login', 'Manager\LoginController#showLogin')->name('manager.login.create');
Route::post('/login', 'Manager\LoginController#login')->name('manager.login');
});
Route::prefix('manager')->group(['middleware' => 'manager_auth'], function () {
Route::post('/logout', 'Manager\LoginController#logout')->name('manager.logout');
Route::get('/profile', 'Manager\PageController#profile')->name('manager.profile');
});
Error after executing php artisan route:list
PHP Warning: Uncaught ErrorException: Array to string conversion in E:\laragon\www\laraveladmin\vendor\laravel\framework\src\Illuminate\Routing\Router.php:329
Stack trace:
#0 E:\laragon\www\laraveladmin\vendor\laravel\framework\src\Illuminate\Routing\Router.php(329): Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(8, 'Array to string...', 'E:\\laragon\\www\\...', 3
29, Array)
#1 E:\laragon\www\laraveladmin\vendor\laravel\framework\src\Illuminate\Routing\Router.php(329): require()
#2 E:\laragon\www\laraveladmin\vendor\laravel\framework\src\Illuminate\Routing\Router.php(285): Illuminate\Routing\Router->loadRoutes(Array)
#3 E:\laragon\www\laraveladmin\vendor\laravel\framework\src\Illuminate\Routing\RouteRegistrar.php(104): Illuminate\Routing\Router->group(Array, Array)
#4 E:\laragon\www\laraveladmin\routes\web.php(30): Illuminate\Routing\RouteRegistrar->group(Array, Object(Closure))
#5 E:\laragon\www\laraveladmin\vendor\laravel\framework\src\Illuminate\Routing\Router.php(329): require('E:\\laragon\\www\\...')
#6 in E:\laragon\www\laraveladmin\vendor\laravel\framework\src\Illuminate\Routing\Router.php on line 329
PHP Fatal error: Illuminate\Routing\Router::loadRoutes(): Failed opening required 'Array' (include_path='E:\Developer\Wbserver\php\PEAR') in E:\laragon\www\laraveladmin\vendor\laravel\framework\src\Illuminate
\Routing\Router.php on line 329
[Symfony\Component\Debug\Exception\FatalErrorException] Illuminate\Routing\Router::loadRoutes(): Failed opening required 'Array' (include_path='E:\Developer\Wbserver\php\PEAR')
Try this instead
Route::group(['prefix' => 'manager', 'middleware' => 'manager_guest'], function() {
});
You could "factorize" your code like this:
Route::prefix('manager')->group(function () {
Route::middleware(['manager_guest'])->group(function () {
// These will be prefixed with "manager" and assigned the "manager_guest" middleware
});
Route::middleware(['manager_auth'])->group(function () {
// These will be prefixed with "manager" and assigned the "manager_auth" middleware
});
// These will just be prefixed with "manager"
});
I noticed all your controllers live in the sub-namespace Manager. You can chain the methods and make your routes file even cleaner. For instance:
Route::prefix('manager')->namespace('Manager')->group(function () {
Route::middleware(['manager_guest'])->group(function () {
Route::get('register', 'RegisterController#showRegister')->name('mananger.register.create');
});
Route::middleware(['manager_auth'])->group(function () {
Route::get('profile', 'PageController#profile')->name('mananger.profile');
});
});
None of the other answers worked for me as I had a lot of routes to change, and didn't want to change namespaces. The key to making this work is "as". The downside of this being that it changes the path when using "route()", but your use of name on each route here would override that anyway.
Route::group(['prefix' => 'manager', 'middleware' => ['manager_guest'], 'as' => 'manager_guest'], function() {
...
}
Route::group(['prefix' => 'manager', 'middleware' => ['manager_auth'], 'as' => 'manager_auth'], function() {
...
}
I've a simple route into the file web.php:
Route::get('first/{param?}', [
'uses' => 'App\Http\Controllers\MyController#index',
'as' => 'myControllerIndex'
]);
Now, I'd like to create a second route that uses the first route but passing specific params.
I tried something like this:
Route::get('second', function () {
return file_get_contents(route('myControllerIndex', ['param' => 'book1']));
});
but it doesn't work.
Can anyone help me?
Thank you.
You could use a redirect
Route::get('second', function () {
return redirect()->route('myControllerIndex', ['param' => 'book1']);
});
Or you can access the controller directly
Route::get('second', function () {
return app('App\Http\Controllers\MyController')->index('book1');
});