Two Controllers and 1 View in Laravel - php

I have one issue to solve about some calculations in Laravel 5.1, and until now the best solution that I found is to create Two different controllers, one to handle calculation for a specific item:
Route::get('company/convert/{note}','ScenarioController#NoteConvert');
And one for all items:
Route::get('company/convert','ScenarioController#AllNotesConvert');
Both will use render the same view.
My question is: Is a good practice to do this ?
In my head one good solution is to use just one route and receive 1 specific note or all of them in some variable through the request.
Something like:
$http.get('/company/convert/',data)
Where data will receive 1 or all notes that will be converted.
P.S.: I'm using AngularJS to call this routes.

If you prefer having one method in your controller you have to change your route a bit:
Route::get('company/convert/{note?}','ScenarioController#NoteConvert');
And your method would be something like
public function NoteConvert($note=null)
{
if ($note == null) {
// do all convertions
return view()
}
// single convertion
...
}
This way NoteConvert method will be the one that will handle multiple and single convertions.
Don't forget to remove
Route::get('company/convert','ScenarioController#AllNotesConvert');
It won't be necessary anymore
Edit:
https://laravel.com/docs/5.2/routing#parameters-optional-parameters

the best way for me, will be to passe an optional parameter in the url and check it on the controller.

i think your task is to produce the data of all items and specific data with filter using note argument in the view.
i reccomend you to create the route like this
Route::controller('company', 'ScenarioController');
then create a controller with two function like this
public function getIndex()
{
return view('convert');
}
here convert is name view blade .
public function postFilter($note)
{
$x= // do what you want
return view('convert', compact('x'));
}
then add a filter in the blade using a checkbox and make the form action url as
"company/filter/{note}".
this is the better practice i think.
refer implicit routing here. https://laravel.com/docs/5.1/controllers

Related

Laravel : form does not change the URL after submit, causing me to be unable to do another POST in web.php

I have a bit of a complicated issue. I could use some help.
I have a form that is being handled by the following function:
$module = request('module');
$classe = request('classe');
$horaire = request('horaire');
$date = request('date');
$students = DB::select('SELECT * FROM `etudiants` WHERE etudiants.id_classe = '.$classe);
return view('g_absence.absence',['module'=> $module, 'classe'=>$classe,'horaire'=>$horaire,'date'=>$date,'students'=>$students]);
I take the values $module, $class, $horaire, $date and $students and need to use them inside a different view: g_absence.absence. This works fine and when the view is returned I have access to said variables.
The issue is, inside the g_absence.absence view, I have another form that also needs to be handled, and because the url remains the same even tho a different view is returned, I cant make two posts for the same path.
web.php:
Route::get('/testboy', [App\Http\Controllers\g_absence::class,'index'])->name('marquer');
Route::post('/testboy',[App\Http\Controllers\g_absence::class, 'marquer']);
Route::post('/testboy',[App\Http\Controllers\g_absence::class, 'ajoutabsence']);
The first line is the one that send to the form page just a simple
return view
The second one handle the form in that view
The third one, I want it to handle the form inside the
g_absence.absence view, but they share the same path.
Excuse me if I'm being unclear, I'm a bit of a beginner in Laravel
your problem is using the same route for different methods
basically the first route gets executed every time you use the '/testboy' action that is why your second function never get's called.
you can solve this issue by changing your urls for example:
Route::post('/testboy-marquer',[App\Http\Controllers\g_absence::class, 'marquer']);
Route::post('/testboy-ajoutabsence',[App\Http\Controllers\g_absence::class, 'ajoutabsence']);
Or you can use one function that's handle both with one url by pathing additional parameter to your url depending on your function call :
Route::post('/testboy?type=marquer',[App\Http\Controllers\g_absence::class, 'ajoutabsence']);
in your function check the type :
if(request('type') == 'marquer') {
execute marquer logic here...
} else {
execute absence logic here...
}
Using method and path with two functionalities is wrong, but if you want to somehow use both routes my same method and path which I don't recommend you must let the request to pass through like a middleware in your first block of code Instead of return a view.
Recommended way is to have 2 routes with different paths or at least one route with a parameter by which you can determine what code block must be executed.

check parameters type before run route in laravel 5

I have 2 kind on route.
like this:
You know for these:
Route::get('/{category_slug}/{article_slug}', 'mController#list');
Route::get('/{category_slug}/{subcategory_slug?}', 'mController#clist');
It run only first route.
I try binding them in RouteServiceProvider boot(){
Route::bind('category_slug', function ($category_slug, $route) {dd('category_slug') }); //works
Route::bind('article_slug', function ($article_slug, $route) { dd('article_slug') }); //works for both article_slug(ok!) and subcategory_slug(wrong!)
Route::bind('subcategory_slug', function ($subcategory_slug, $route) { dd('subcategory_slug') }); //not works
}
Is there a way to check {article_slug} or {subcategory_slug} before loading route and then system choosing right route? for example if first is wrong, then skip it and try to run second route.
for example middleware can do that?
You need to use different url or different method of request in order to fulfil your demand.
Like -
Route::get('/{category_slug}/{article_slug}', 'mController#list');
Route::post('/{category_slug}/{subcategory_slug?}', 'mController#clist');
Use Route::update() if need to modify a data which is already in database or Request::delete() to delete a data in the database.
Or like the answer of tprj29 you need to use different kinds of url
In Laravel slugs are unique per table not unique throughout all tables. I would recommend using something like a keyword to determine what slug is expected. This is way more efficient and cleaner then querying to determine if the slug is of an type article or category of object.
Route::get('/{category_slug}/', 'mController#clist');
Route::get('/{category_slug}/sub/{subcategory_slug}', 'mController#clist');
Route::get('/{category_slug}/sub/{subcategory_slug}/{article_slug}', 'mController#list');
Route::get('/{category_slug}/{article_slug}', 'mController#list');

laravel 5 , passing values from multiple controllers

I am trying to send to a view some values from different controllers
Here is my code:
Route::get('/add_email','ListsController#index_add_email');
Route::get('/add_email','RepoController#repo_index_add_email');
I am trying to display on this page (add_email) values from those two functions. Of course how its now I am getting error because the second get will overwrite the first one. How do I mix those two "GET"?
Route::get('/add_email','ListsController#index_add_email');
Inside ListsController in index_add_email function add this row:
with(new RepoController())->repo_index_add_email();
btw, make sure to have a read PSR-1 && PSR-2 guides:
PSR-1: http://www.php-fig.org/psr/psr-1/
PSR-2: http://www.php-fig.org/psr/psr-2/
Laravel doesn't support to point same route ('add_email') to different controller.
if you need to do so, handle the logic inside the action you defined.
Route::get('/add_email','ListsController#index_add_email');
Route::get('/add_email','RepoController#repo_index_add_email');
You can set the route to redirect to one controller and then call the other controller from the controller called.
For e.g. in routes.php
Route::get('/add_email','ListsController#index_add_email');
and in ListsController
public function index_add_email(...)
{
// Other code
// Call RepoController function
return app('App/Http/Controllers/RepoController')->repo_index_add_email();
}
(Assuming that's the correct namespace for RepoController.php)
Although I think this is the easiest option, it does mess with code organization. You could try working with Events and Listeners, since it would make logical sense here where two different actions are performed during the same event but again, that's simply overkill.

Get parameter passed in URL in Laravel view as variable directly?

Right now, if I have a parameter in a URL in one of my Laravel projects, I have to detect the route and grab the parameter:
Route::get('mission/{name}', 'MissionsController#show');
Pass the $name parameter as an argument to my controller:
class MissionsController extends BaseController {
public function show($missionName) {
...
}
}
Then pass it along to the view that is returned in my controller method:
return View::make('missions.mission', array(
'name' => $missionName
));
Before then using the $missionName variable in my view:
<p>{{ $missionName }}</p>
This is quite a roundabout way of doing so. Is there any way I can get the parameter from the URL directly in my view? I've tried accessing the $_GET superglobal, but it is empty. Surely there must be a better way of doing this.
Thoughts?
Use this code :
{{ Route::current()->getParameter('theParameterName') }}
EDIT: Above doesn't seem to be supported anymore in recent Laravel versions. You should use #lukasgeiter answer instead:
Route::input('name');
There is a nice shortcut for Route::current()->getParameter():
Route::input('name');
For small projects or simple examples, it may seem like this is a "roundabout" way, however this is the way it should be. In order to create more reusable, quality code, you need to have this separation of concerns. An over-simplified idea follows.
It is your route's job to figure out which controller needs to be called, and to make sure it is called with the correct parameters.
It is your controller's job to read the state of the application (input), communicate with the model (if needed), send the data into the view, and return the response. There's plenty opinion on whether or not this violates the Single Responsibility Principle, but no need to go into that here.
It is the view's job to use the data passed to it to build the response. The view shouldn't care where the data came from or how it was gotten, only that it now has it and can do what it needs. Your $missionName should be able to come from a URL segment, a URL request variable, a field on a model, or any other place you can think of, but the view shouldn't know any of that.

How to access values of multiple parameters passed to Laravel controller

I am trying to figure out how to access two (or more) parameters passed to a Laravel controller. I know how to create the route, and the URL is created correctly, but then I can only access the first passed parameter in my controller.
Route:
Route::get('managers/{id}/{parameter2}', array('as'=>'dosomething', 'uses'=> 'ManagersController#dosomething'));
where the first parameter is obviously the $id for managers, and the second parameters is to be processed by the controller.
View:
Do Something
generates the URL:
http://domain/managers/1/2
where 1 is easily accessed as the $id for managers, but when I try to access the 2nd parameter "2" using $parameter2, e.g. using a simple return: "id=$id and parameter2=$parameter2" statement, I get an "unidentified variable: $parameter2" error.
What am I doing wrong?
Is there a better way to pass multiple parameters? I'm especially asking the "better way?" question because what I want to do is use the 2nd parameter to change a value in a database table, and using a 'get' method, somebody could change the parameter value in the URL and therefore cause mischief. Must I use a 'post' method? I'd love to be able to use a link, since that works much better with the design of my application.
Thanks!
I was asked to include the controller, which I'm happy to do. Initially, just for testing, as I mentioned, my controller was a simple return to display the values of the two passed parameters. But here is what I want to be able to do, including the actual name of the function ("update_group" rather than "dosomething") --
ManagersController:
public function update_group($id)
{
DB::table('groups')->where('id','=',$parameter2)->update(array('manager_id'=>$id));
return Redirect::route('managers.show', array('id'=>$id));
}
The update table works perfectly if I replace $parameter2 with an actual value, so that syntax is fine. The issue is that Laravel says that $parameter2 is an undefined variable, despite the fact that the URL contains the value of $parameter2 as you can see above.
And since it occurs to me that the answer to this may involve adding a function to the Manager model, here is the current
Manager.php
class Manager extends Eloquent {
protected $table = 'managers'; ... (mutator and error functions)
}
Just change
public function update_group($id)
to
public function update_group($id, $parameter2)
All looks ok in your route. Seeing the controller code would help, but likely, you may not have a second parameter in your controller's dosomething() method.
public function dosomething($id, $parameter2){
var_dump($id).'<br />';
var_dump($paremter2);
}
If that isn't the case, you can try dumping it from the route's callback to further diagnose.
Route::get('managers/{id}/{parameter2}', function($id, $parameter2)
{
var_dump($id).'<br />';
var_dump($paremter2);
});
Depending on your use case, you can pass them in a query string like so: but it isn't really the 'best way', unless you're doing something like building an API that won't use the same variables in the same order all the time.
/managers?id=1&paramter2=secondParameter
var_dump(Request::query('id')).'<br />';
var_dump(Request::query('paramter2'));

Categories