Laravel combine form submit and API request - php

I have a Laravel API that goes thru middleware and works just fine when called externally.
public function apiMethod(Request $request)
{
$requestData = $request->all();
dd($requestData);
}
In addition, I have a form that is processed by a method in a separate controller. In this method, I do a request to the API:
public function formHandler(Request $request)
{
$request = \Request::create('/path/to/the/api/', 'POST', ['A' => 1]);
$response = \Route::dispatch($request)->getContent();
}
In this case, $requestData contains the form parameters instead of the array that I pass with my API request (['A' => 1]).
So I wonder what's the right approach to solve that issue in Laravel?

Related

Laravel FormRequest does not read Form Data type request

I am new to working with Laravel FormRequest and I facing and issue with it when I the request is Form Data, It does not read the request but When I send the request like Request Payload it works fine dont Know what is the issue.
public function updateRecord($recordUnit)
{
if($this->file('logo'))
{
$urlImage = $this->uploadFileEdit($this->file('logo'), $recordUnit->logo, $this->name);
}
$recordUnit->update([
'col1' => $this->name,
]);
$recordUnit->users()->syncWithoutDetaching($this->input('user_id', []));
}

How to remove an existing item from a route request parameters? - Laravel 5.5

I want to remove an existing item from a request parameters that passes in a controller.
Here's my controller:
public function getIndex(Request $request)
{
// I need to remove a parameter from the $request here.
}
Actually, I want to dispatch a request in a controller but when I make a new instance of Request like this,
$new_request = new Request();
and add some fields to the $new_request like this:
$request->request->add([
'id' => '2',
'name' => 'test'
]);
Nothing is added! and the dispatch method can not yield a correct response with empty request!
But when I use an existing route request, every thing is ok, except extra items and I should get rid of them!
Do you need this?
public function getIndex(Request $request)
{
$request->request->remove('yourParamName');
}

Send data from Woocommerce to Laravel via webhook

I'm using Woocommerce webhooks to listen out for every time an order is created/updated/deleted.
I've setup the webhook in Woocommerce as follows
In my Laravel routes file I have set up the route as follows:
use Illuminate\Http\Request;
// API routes...
Route::post('api/v1/orders/create', function (Request $request) {
Log::debug($request->all());
return $request->all();
});
However, when I view the logs as well as the return data in POSTMAN, all I get is an empty array.
Any HTTP method other than 'GET' throws a MethodNotAllowedException
I'm not sure of any other way in Laravel to consume data other than with Request $request.
According to my understanding of routing in Laravel, the input that you pass in to the function is meant to actually be variables for your route.
So if you had a route in your API:
api/v1/orders/{id}/create then in the route function you'd pass in id as the method argument. So this would be correct:
Route::post('api/v1/orders/{id}/create', function ($id) {
Log::debug($id);
return $id;
});
It's looking for request in your route definition.
Rather create a controller. Then in your routes.php use this:
Route::post('api/v1/orders/create', 'OrdersController#create')
That tells your routing to redirect all HTTP POST calls to api/v1/orders/create to the OrdersController.php and the create() method within that controller.
In your controller, you'll be able to use the $request variable as an input argument and it should work.
So in OrdersController.php:
class OrdersController extends Controller {
public function create(Request $request) {
Log::debug($request->all());
return $request->all();
}
}
Good Luck!
This worked for me. My route in api.php is as follow.
Route::post('/woocommerce/webhook/', 'Api\WoocommerceController#test');
And my controller action is as follow.
public function test()
{
$payload = #file_get_contents('php://input');
$payload = json_decode( $payload, true);
\Log::info(json_encode( $payload));
return response()->json([ 'data' => $payload, 'status' => \Symfony\Component\HttpFoundation\Response::HTTP_OK]);
}

Slim 3 middleware validation

I'm trying to implement json-schema validator from justinrainbow as middleware in Slim 3.
I can't figure out how to get the clients input from GET/POST requests in middleware.
tried like this:
$mw = function ($request, $response, $next) {
$data = $request->getParsedBody();
print_r($data); // prints nothing
$id = $request->getAttribute('loan_id');
print_r($id); // prints nothing
// here I need to validate the user input from GET/POST requests with json-schema library and send the result to controller
$response = $next($request, $response);
return $response;
};
$app->get('/loan/{loan_id}', function (Request $request, Response $response) use ($app, $model) {
$loanId = $request->getAttribute('loan_id'); // here it works
$data = $model->getLoan($loanId);
$newResponse = $response->withJson($data, 201);
return $newResponse;
})->add($mw);
There are 2 possible ways of how I need it. what i'm doing wrong ?
validate it in middleware and send some array/json response to the controller, which i will then get as I understood with $data = $request->getParsedBody();
validate it in middleware but final check will be in controller like this:
$app->get('/loan/{loan_id}', function (Request $request, Response $response) use ($app, $model) {
if($validator->isValid()){
//
}
$loanId = $request->getAttribute('loan_id'); // here it works
$data = $model->getLoan($loanId);
$newResponse = $response->withJson($data, 201);
return $newResponse;
})->add($mw);
Best option for me it do something like here
but I don't understand what should i return in container, and how to pass get/post input to container
Your code in the first point seems alright, you only try to access route parameter from within middleware. At that point the route is not yet resolved and therefore parameters are not parsed from the URL.
This is a known use case and is described in Slim's documentation. Add the following setting to your app configuration to get your code working:
$app = new App([
'settings' => [
// Only set this if you need access to route within middleware
'determineRouteBeforeAppMiddleware' => true
]
]);
In order to understand how middleware works and how to manipulate response object, I suggest you read the User Guide - it's not that long and explains it really well.

Using a CustomRequest for Form Validation in Laravel 5.1 fails?

I've created a custom Request called CustomerRequest that I want to use to validate the form fields when a new customer is created. I cannot get it to work, it appears to be continuing into the store() method even when it should fail.
I have three required fields: givenname, surname, email
Here is my CustomerRequest:
public function rules()
{
return [
'givenname' => 'required|max:3',
'surname' => 'required',
'email' => 'required|unique:customers,email',
];
}
Here is my CustomerController:
use pams\Http\Requests\CustomerRequest;
-----------------------------------------
public function store(CustomerRequest $request, Customer $customer)
{
$request['created_by'] = Auth::user()->id;
$request['modified_by'] = Auth::user()->id;
$customer->create($request->all());
return redirect('customers');
}
When I submit the form using a givenname of "Vince" it should fail because it is greater than 3 characters long, but instead I get this error:
FatalErrorException in CustomerController.php line 52: Cannot use object of type pams\Http\Requests\CustomerRequest as array
Line 52 in the controller is $request['created_by'] = Auth::user()->id;
From what I understand, if the CustomerRequest fails then the user should be redirected back to the customers.create page and not run the code contained in the store() method.
I found the problem.
CustomerRequest had:
use Request;
instead of:
use pams\Http\Requests\Request;
Now the validation passes and fails as expected.
From docs, in Form Request Validation:
All you need to do is type-hint the request on your controller method.
The incoming form request is validated before the controller method is
called, meaning you do not need to clutter your controller with any
validation logic
Solution would be if you use it like so:
CustomerController.php
use Illuminate\Http\Request;
// ...
public function store(CustomerRequest $customerRequest, Customer $customer,Request $request)
{
$request['created_by'] = Auth::user()->id;
$request['modified_by'] = Auth::user()->id;
$customer->create($request->all());
return redirect('customers');
}
So what you want to know is that FormRequest -- which you are extending in your custom request validator CustomerRequest.php -- is a bit different than request that resides in Illuminate\Http namespace.
actually, you may find out why if you run (with your old code) dd($request['created_by'] = Auth::user()->id);. you should get the word forbidden or maybe! an exception telling that it'is not instantiable. (in my case I got forbidden because I've tested it on 5.2 right now).
$request is object, use it like following
use pams\Http\Requests\CustomerRequest;
-----------------------------------------
public function store(CustomerRequest $request, Customer $customer)
{
$inputs = $request->all();
$inputs['created_by'] = Auth::user()->id;
$inputs['modified_by'] = Auth::user()->id;
$customer->create($inputs);
return redirect('customers');
}

Categories