Laravel call a controller within a controller - php

I have 2 controllers, one is responsible for submitting a form to the DB, the other is for PayPal integration such as this one:-
http://laravelcode.com/post/how-to-integrate-paypal-payment-gateway-in-laravel-54
I want it so that when the user presses the submit button, it does its usual DB transactions but then calls the PayPal controller to process the payment.
Is it better merge the 2 controllers into one or to call the PayPal controller as part of the store method??

You can call another controller using the following method.
$controller = app()->make('App\Http\Controllers\PaypalController');
app()->call([$controller, 'process'], [$request]);
Where your controller function is defined as:
public function process(Request $request) {}
While not the greatest practice, I have used this for calling a function referenced in a console command and in a URL.

In the function which do the DB transactions, try redirecting to your paypal function:
public function myDBFunc() {
/* do transactions */
return redirect()->route('paypalRoute');
// or return redirect()->action('PaypalController#paypalFunc');
}
Do not forget to pass your variables to your route/action.

Related

How do I pass additional data to callback method in Laravel Socialite?

I am using Laravel Socialite for social authentication. It has two methods redirect() and callback. While redirection I want to pass some data to the callback method, but I am unable to get data there. I used sessions to put values but I am getting nothing in session in the callback method.
Callback method destroys all session data?
I am achieving like this,
public function redirect(Request $req)
{
session(['tenant_slug' => $req->TenantSlug]);
return Socialite::driver('google')->stateless()->redirect();
}
and in callback method,
public function callback(Request $req,$provider)
{
dd(session()->all());
$getInfo = Socialite::driver($provider)->stateless()->user();
}
I am printing all session data but I am getting an empty sessions.
How do I achieve this?
Please help me with this.

Laravel form request - $this->user() vs. auth()->user() in authorization

Can anyone explain if there is a reason why we should not be using getting the authenticated user within a from request authorize method, via the Auth::user() or auth()->user() helpers vs. the $this->user() method as suggested in docs?
https://laravel.com/docs/5.8/validation#authorizing-form-requests
In my case, I am trying to unit test a form request and auth()->user() allows me to retrieve the user whereas $this->user() does not as I am not making a full request. I am just creating the form request object for my test.
public function setUp(): void
{
parent::setUp();
$this->subject = new \App\Http\Requests\OrderStoreRequest();
}
// Acting as has no effect when manually creating the orderStoreRequest object
public function testAuthorize()
{
$this
->actingAs(\factory(User::class)->create())
->assertTrue($this->subject->authorize());
}
ActingAs() is calling the Laravel Auth system, which in the request lifecycle is put into the request (See). Since you are just calling your request without this lifecycle, you will never get anything injected into the Request.
For your code to work, you need to set the UserResolver. This can be done like so.
$this->subject->setUserResolver(function () use($user) {
return $user;
});
For ease of usage, i would highly recommend doing Laravel feature tests instead of unit testing. You are gonna fight your way through a lot of approaches, there is not meant to be called without the Laravel lifecycle. Which you will get doing call() and json() on the app.

how to call resource controller index in a view laravel 4

I am trying to list the grid view of the product variants in product edit page. I have a separate controller and view for variants.
Now I need to know How can I call the variant Controller index method in products edit page, which will return a view with pagination ,search , filter etc.
This is a hard thing to do simple because controllers are HTTP request handlers. So, unless you are making another request, you should not call a a controller method inside your view and it will be hard to do it because they weren't meant to be used this way.
A controller should receive a request, call data processors (repositories, classes), get the result data and send them to the view, get the view result and send it back to the browser. A controller knows very little and does nothing else.
A view should receive data and plot it. There is no problem in being lots and lots of data, but it should receive data (objects are good) and plot them.
If you need to plot a view with pagination pagination, search, filter etc., you don't need a controller call to do it, you can add it as a subview:
#include('products.partials.table')
And you can reuse that view partial in any views. If those tables must be shown only sometimes, you can add conditions to it:
#if ($showTable)
#include('products.partials.table')
#endif
If that partial requires data, you produce that data in your controller:
<?php
class ProductsController extends BaseController {
public function index()
{
$allProducts = $this->productRepository->all();
$filteredProducts = $this->productRepository->filter(Input::all());
$categories = $this->categoriesRepository->all();
return View::make('products.index')
->with('products', compact('allProducts', 'filteredProducts', 'categories'))
}
}
But, still, the less your controller knows about your business, the better, so you could just do:
<?php
class ProductsController extends BaseController {
public function index()
{
$products = $this->dataRepository->getProductsFiltered(Input::only('filter'));
return View::make('products.index')
->with('products', compact('products'))
}
}
And let the repository produce the necessary information you need to plot your data.

Please suggestion a better design of this controller class

Here is the code using CodeIgniter:
The problem I encounter:
The controller will have some functions call view, and it
separated, but it is still very close with the logic itself, if the
controller change to return in JSON or XML to display result, it seems
very trouble.
Seems many method, but each one is depends another.
I think it is difficult to track the code.
Please give some suggestions thank you.
*Please reminded that, it is only the controller class. the load view is actually prepare the data for the view, won't render the page. also the doXXX function call model is only use the model method, it won't have any SQL statement. The MVC is separated, but the controller also have the functions related to the view or model, make it quite messy.
class User extends CI_Controller
{
public function register()
{
//check is logged in or not
//if not logged in , show the register page
}
public function show_register_page()
{
//generate the UI needed data , and call the view to render, and will the user will post back a valid_register function
}
public function valid_register()
{
//do all the valid logic, if success,
//do the do_register
//if fail, valid_register_fail
}
public function valid_register_fail()
{
//check is logged in or not
//show the valid register fail page
}
public function show_valid_register_fail_page()
{
//generate the UI needed data , and call the view to render
}
public function do_register()
{
//insert data in the db, the Model will be called
//if something go wrong in db, show the error page
//if everything is success, show the register success
}
public function show_db_error_page()
{
//generate the UI needed data , and call the view to render
}
public function show_register_success()
{
//generate the UI needed data , and call the view to render
}
}
1. The controller will have some functions call view, and it
separated, but it is still very close with the logic itself, if the
controller change to return in JSON or XML to display result, it seems
very trouble.
Depends on how you organized your code and what you actually pass into the view (template). If that's well structured, you can have one view for HTML, one for XML and one for json, where-as json normally just encodes the view variable's (see json_encodeDocs).
2. Seems many method, but each one is depends another.
Well, just don't do it :) The names look like you wanted to "code that into". Keep it apart. Make those function actually actions that a user performs:
register - that action handles the registration process
Make a login controller out of it that handles anything you need:
login - the login action
lost_password - the lost password action
register - the registration action
activate - the registration activation action
Everything else does not belong in there. There is no need for an action to display some page - the controller itself can decide which view to pick.
Next to that you don't need to display database errors. CI takes care of that. Just put only in what's needed and keep things simple. That should help you to reduce the number of methods and the code therein as well.
3. I think it is difficult to track the code.
Sure. Too many functions with not really speaking names. Keep things simple. It's not easy, but give naming and reducing the overall logic some love.

Best practise for handling form submission in controllers

Lets say for example I am creating a an online shop. I have a controller called products and within that controller I have a function called create_product. Create_product calls a view that displays a form where users get to enter new products into the database.
When the user fills in the form to create a product, should I send the action back to the create_product controller and handle it with an IF statement? or offload to another function?
Example
<form method="post" action="www.example.dev/products/create_product/add">
//the above form would post back to the original controller
function create_product()
{
if(uri->segment(3) == "add")
{
//call a model to do all the database stuff
}
load->view->create_product_form;
}
Is this the best way to handle this or should I be passing it off to another function?
Don't cram a ton of stuff in one function using the URI segment to filter it. createProduct() can list the products available for creation (in a CRUD format, I assume), and the submission of the form should ping another controller with the POSTed data. Perhaps insertProduct(), where the data is sanitized and sent to the model for insertion to the database.
Separation of concerns! Keep the functions as separate as possible with good descriptors for the names of the functions.
I (personally) would have a function that set the form parameters and "launch" the view with that form, and another function used to validate and call the model to put the values of that form into the database. I believe that is really up to you, but the code would be cleaner if you divide the controller with several functions depending on what they actually do.
I like the way symfony deals with forms & form submission. It is in one function (action)
simplified code:
executeCreate() {
$this->form = new Form()
if($r->isMethod('POST')) {
//handle submission
bind();
save();
}

Categories