laravel 5 , passing values from multiple controllers - php

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.

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.

It is possible to pass 2 differents types of parameters to a Laravel controller?

I already have a GET route with an URI /projects/{id} which displays Infos of a project with a given id. I also have a GET index route (/projects), which shows all my projects.
My problem is that I currently try to create different indexes (for example one which only displays the projects where I am assigned [e.g. on /projects/mines], or the projects which are pending administrator approval [e.g. on /projects/proposals], and still others displays).
So I want to know if I can have two GET routes /projects/{id}and /projects/{display_mode} which will be calling two differents methods of my ProjectController (respectively show and index).
Thanks for your help! :)
You may have one route /projects which returns all projects as default.
If there is query parameter like
/projects?displayMode=proposals
then you can apply filters.
In your controller it would look something like this
$projects = Project::query();
if ($request->query('displayMode') == 'proposals')
$projects->where('pending', true)
return $projects->get();
You can add multiple filters too in the same way
I'm not sure about specific Laravel options for the route definitions (sorry!), but if the {id} will always be an integer and {display_mode} will always have non-digits in it, you could keep just one route, but do the conditional handling in your controller. Just have the mainAction do something likeā€¦
return preg_match('/^\d+$/', $param) ? idHelperAction($param) : displayModeHelperAction($param);
Then create those two helper functions and have them return whatever you want.
$param is supposed to be whatever you get from that route parameter -- /projects/{param}.
That should call the idHelperAction for routes where $param is all digits and nothing else; otherwise, it should call the displayModeHelperAction. Either way, it sends the same $param to the helper function and returns whatever that helper function returns -- effectively splitting one route definition into two possible actions.
Of course, you might have to add some context in the code sample. If the functions are all defined in the same class, you might need to use $this->idHelperAction($param) or self::idHelperAction($param) (and the same with the other helper action), depending on whether it's static or not; or tell it where to find the functions if you put them in another class, etc., etc. -- all the normal contextual requirements.

Two Controllers and 1 View in Laravel

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

How to simulate a request from view.

I'm new in cakephp and I'm just wondering, how to test models and controllers without using views?
I have to simulate saving data using models and controllers without using froms from views. I was thinking about to make an array with the needed values, but maybe there is a better way to do that?
you can mock your model functions using code like:
$model = $this->getMockForModel('MyModel', array('save'));
$model->expects($this->once())
->method('save')
->will($this->returnValue(true));
You can output variables at any time from controllers (or models) without getting to the views. Yes, it's not how you should do things with an MVC framework, but for testing, it's pretty easy to whack this below your database call in the model/controller:
<? echo '<pre>'; print_r($my_array); exit; ?>
The other thing you can do is at the top of your action function in the controller put:
$this->layout = '';
$this->render(false);
... which will bypass the layout and skip the view rendering, so you can output whatever you like within that function without using the view.
At the beginning of your action, you may use:
$this->autoRender = false;
This will allow you to access your action directly by going to it's path (e.g. CONTROLLER/ACTION). Before passing your data array to save() or saveAll(), I recommend double-checking it with Debugger::dump(), and follow that with die(). This will make the array containing the save data print on your screen so you can verify it looks proper and follows Cake's conventions. The die() will prevent it from actually saving the data.
If everything looks correct, remove the dump() and die() and test it out again.
The first response, from Ayo Akinyemi, should also work well if you are Unit Testing your application.

How can I change Zend Framework's routing schema to not use key/value pairs?

Rather than using controller/action/key1/value1/key2/value2 as my URL, I'd like to use controller/action/value1/value2. I think I could do this by defining a custom route in my Bootstrap class, but I want my entire application to behave this way, so adding a custom route for each action is out of the question.
Is this possible? If so, how would I then access valueN? I'd like to be able to define the parameters in my action method's signature. e.x.:
// PostsController.php
public function view($postID) {
echo 'post ID: ' . $postID;
}
I'm using Zend Framework 1.9.3
Thanks!
While I don't think it's possible with the current router to allow N values (a fixed number would work) you could write a custom router that would do it for you.
I would question this approach, however, and suggest that actually listing all of your routes won't take long and will be easier in the long run. A route designed as you've suggested would mean that either your named parameters are always in the same order, i.e.
/controller/action/id/title/colour
or that they are almost anonymous
/controller/action/value1/value2/value3
With code like
$this->getRequest()->getParam('value2'); //fairly meaningless
Does it have to be N or can you say some finite value? For instance can you imagine that you'll never need more than say 5 params? If so you can set up a route:
/:controller/:action/:param0/:param1/:param2/:param3/:param4
Which will work even if you don't specify all 5 params for every action. If you ever need 6 somewhere else you can just add another /:paramN onto the route.
Another solution I've worked with before is to write a plugin which parses the REQUEST_URI and puts all the extra params in the request object in the dispatchLoopStartup() method. I like the first method better as it makes it more obvious where the params are coming from.

Categories