Trigger JSON response via Trait in Controller Larael - laravel

I'm using Laravel 8 to build an API, I have a route which for the purposes of the question is... /api/fact which GETs a random fact. I have a FactsController.php file and two traits, one for constructing a JSON response, the other for getting a fact. For some reason when calling the trait's function from within my controller (which made the request) I'm not getting any returned JSON back in Postman...
Traits/GetFact.php
<?php
namespace App\Traits;
use App\Traits\ApiResponse;
trait GetFact {
use ApiResponse;
/**
* Get random fact
*
* get random fact
*/
public function getRandomFact () {
$this->getFact();
$this->apiResponse([
'msg' => "Fact..."
], 200, true);
}
}
Traits/ApiResponse.php
<?php
namespace App\Traits;
trait ApiResponse {
/**
* API Response
*
* Return a JSON response for our API with params
*/
public function apiResponse ($data, $code, $success = false) {
return response()->json(array_merge(['success' => $success], $data), $code);
}
}
Controllers/FactController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Traits\GetFact;
class FactsController extends Controller
{
use GetFact;
/**
* Fact
*
* #param Request $request
*/
public function fact()
{
$this->getRandomFact()
}
}
When I make my request to /api/fact I should be getting the returned JSON listed where I'm calling $this->apiResponse() with the msg, but I'm not? It's like the return doesn't seem to return JSON because it's scoped to the trait and not the controller and that there isn't a return in there? How can I achieve the listed.

You are not "returning" anything from your Controller method. You have to return something for their to be a response with content. Also, fact and getRandomFact do not return anything so calling those isn't doing anything for you. You are also calling a getFact method and not assigning the return to anything (if it even returns anything).

Related

How to show custom messages in laravel 5.8?

I am using laravel 5.8 version, i have one api which is responsible for registering ,i create one Request file which contains rules() and messages() function to display error messages but it's not throwing any error messages if any validation fails ,why this is happening can somebody explain ?
UserController.php
<?php
namespace App\Http\Controllers;
use App\Http\Requests\userRequest;
use App\UserSection;
class UserController extends Controller
{
public function userRegister(userRequest $request){
//logic of my code
return response()->json($success);
}
}
userRequest.php
<?php
namespace App\Http\Requests;
use App\Rules\CustomRule;
use Illuminate\Foundation\Http\FormRequest;
class userRequest extends FormRequest
{
public function messages()
{
return [
'first_name.required' => 'A title is required',
];
}
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'first_name' => 'string|required|max:25',
'phone_number' => 'required|integer'
];
}
}
The error i am facing when i hit the route without first_name key it's showing 404 not found error
you might have missed headers part for taking the form-data
Accept = application/json
As laravel docs
If validation fails, a redirect response will be generated to send the
user back to their previous location. The errors will also be flashed
to the session so they are available for display. If the request was
an AJAX request, a HTTP response with a 422 status code will be
returned to the user including a JSON representation of the validation
errors.
So you need to specify the response type you expect, if you use postman for testing your api end point you have to add in request header Accept:application/json
<?php
namespace App\Http\Controllers;
use App\Http\Requests\userRequest;
use App\UserSection;
class UserController extends Controller
{
public function userRegister(userRequest $request){
//logic of my code
return response()->json($success);
}
}

How to access model instance in a Request class in Laravel 8?

In my Laravel project I want to authorize user via a Request like this:
<?php
namespace Domain\Contents\Http\Requests\Blog;
use Domain\Contents\Models\Blog\Post;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;
class ReadPostRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
if (request('id') === null) {
abort(403);
}
$post = Post::whereId(request('id'))->first();
return Gate::allows('view-post', $this->user(), $post);
}
// ...
}
But I think here this part of my code is little bit messy:
if (request('id') === null) {
abort(403);
}
$post = Post::whereId(request('id'))->first();
Is there any simpler solution for accessing current Post model in the Request class?
The documentation for FormRequests suggests that the authorize() method supports type hinting.
If you are using route model binding you could therefore just type hint the post:
public function authorize(Post $post)
{
return Gate::allows('view-post', $this->user(), $post);
}
Alternative solution is that you can directly access your Models that are used with Model Binding.
return Gate::allows('view-post', $this->user(), $this->post);
For ease of use you can typehint it in the comments.
/**
* #property \App\Models\Post $post
*/

Laravel 5.1 Cashier Webhook, handleCustomerSubscriptionDeleted

I'm on Laravel 5.1, stripe api 2015-10-16
I'm trying to handle: customer.subscription.deleted so I'm overriding handleCustomerSubscriptionDeleted
but the method is never called.. (even if I return a 200 response without other lines of code the stripe log a 500 error response)
I'm routing as described in docs:
Route::post('/stripe/webhook', 'WebhookController#handleWebhook');
a custom controller:
namespace App\Http\Controllers;
use App\Abbonamento;
use Symfony\Component\HttpFoundation\Response;
use Laravel\Cashier\WebhookController as BaseController;
class WebhookController extends BaseController
{
/**
* Handle a stripe webhook.
*
* #param array $payload
* #return Response
*/
public function handleInvoicePaymentSucceeded($payload)
{
$subscription = $payload['data']['object']['subscription'];
$abbo = Abbonamento::bySubscription($subscription)->first();
if ($abbo)
{
$abbo->makeStripePayment($payload);
}
}
public function handleCustomerSubscriptionDeleted($payload)
{
$subscription = $payload['data']['object']['id'];
$abbo = Abbonamento::bySubscription($subscription)->first();
if ($abbo and $abbo->subscribed())
{
$abbo->subscription()->cancel();
}
return new Response('Webhook Handled', 200);
}
}
Someone can tel me why "handleInvoicePaymentSucceeded" works but "handleCustomerSubscriptionDeleted" was never called?
The question is not about my custom entity "Abbonamento", is just about why I see always error 500 as return response in the test env on stripe for customer.subscription.deleted, and an ok response on
invoice.payment_succeeded
the problem was the method declaration,
looking at the laravel.log I swiched it to:
public function handleCustomerSubscriptionDeleted(array $payload)
so the missed part was "array"

How to pass Request object from route in Laravel?

Following is my routes where I am calling my Controller directly in route.
How can I pass Request $request to my getBlog Function.. Or is there any way to directly get $request object in my getblog function of controller ???
$artObj = App::make('App\Http\Controllers\Front\ArticleController');
return $artObj->getBlog($id);
Code in Routes:
Route::get('/{slug}', function($slug) {
// Get Id and Type depending on url
$resultarray = App\Model\UrlAlias::getTypefromUrl($slug);
if(!empty($resultarray)) {
if($resultarray[0]['type'] == 'article') {
$id = $resultarray[0]['ref_id'] ;
$artObj = App::make('App\Http\Controllers\Front\ArticleController');
return $artObj->getBlog($id);
} else {
return Response::view("errors.404", $msg, 400);
}
} else {
return Response::view("errors.404", array(), 400);
}
});
You can do in the head of the routes.php file:
use Illuminate\Http\Request;
And then in the beginning of your route:
Route::get('/{slug}', function($slug, Request $request) {
And the $request will be available to you. But that is extremely bad practice. What you should do - is move the whole logic into the controller like that:
Route::group(['namespace' => 'Front'], function(){
Route::get('/{slug}', 'ArticleController#methodName');
});
and then you can use the Request class in your controller class and the controller method:
<?php
namespace App\Http\Controllers\Front
use Illuminate\Http\Request;
class ArticleController
{ ...
public function methodName(Request $request){
...function implementation...
}
...
}
The Request is a global variable, you can access it anywhere with either php code or even some helper Laravel functions.
Just use request() and it's the same as passing the request as an object inside a variable through a function. (It's equivalent to the Request $request variable received).
It improved readability also. Just remember you can't change request objects directly, you'd better use request()->merge(['key' => 'newValue']);

Manipulating Laravel html response just before sending it to browser

What is the proper way to manipulate final output before sending it to browser? (laravel 5.*)
I have created facade
namespace App\Facades;
use Illuminate\Support\Facades\Response as ResponseFacade;
use Illuminate\Http\Response as ResponseHttp;
class Response extends ResponseFacade
{
public static function viewMod($view, $data = [], $status = 200, array $headers = [])
{
$output = \Response::view($view, $data, $status, $headers);
return some_manipulating_function($output);
}
}
and in the controller action i use
return viewMod("my_view_file", array $view_data);
but i receive corrupted output (http response headers are added to/ prepended to html)
most probably \Response related __toString method behaves strangely
any ideas? (thanks!)
You can use AfterMiddleware like below example from docs,
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);
// Perform action
return $response;
}
}

Resources