Retrieving JSON content - api

i am a beginner on laravel. i have problem on creating my POST API.
i want to use data retrieved from json POST from other application. but it always return null so i did some investigating on the request.
when i return dd($request), the result is
Illuminate\Http\Request {#43 ▼
#json: Symfony\Component\HttpFoundation\ParameterBag {#35 ▶}
#convertedFiles: []
#userResolver: Closure($guard = null) {#1241 ▼
class: "Illuminate\Auth\AuthServiceProvider"
this: Illuminate\Auth\AuthServiceProvider {#22 …}
use: {▶}
file: "C:\xampp\htdocs\attendance_online\vendor\laravel\framework\src\Illuminate\Auth\AuthServiceProvider.php"
line: "105 to 107"
}
#routeResolver: Closure() {#1246 ▼
class: "Illuminate\Routing\Router"
this: Illuminate\Routing\Router {#26 …}
use: {▶}
file: "C:\xampp\htdocs\attendance_online\vendor\laravel\framework\src\Illuminate\Routing\Router.php"
line: "655 to 657"
}
+attributes: Symfony\Component\HttpFoundation\ParameterBag {#45 ▼
#parameters: []
}
+request: Symfony\Component\HttpFoundation\ParameterBag {#35 ▼
#parameters: []
}
+query: Symfony\Component\HttpFoundation\InputBag {#51 ▼
#parameters: []
}
+server: Symfony\Component\HttpFoundation\ServerBag {#47 ▼
#parameters: array:23 [▶]
}
+files: Symfony\Component\HttpFoundation\FileBag {#48 ▼
#parameters: []
}
+cookies: Symfony\Component\HttpFoundation\InputBag {#46 ▼
#parameters: []
}
+headers: Symfony\Component\HttpFoundation\HeaderBag {#49 ▼
#headers: array:6 [▼
"accept-encoding" => array:1 [▼
0 => "gzip,deflate"
]
"content-type" => array:1 [▼
0 => "application/json"
]
"content-length" => array:1 [▼
0 => "231"
]
"host" => array:1 [▼
0 => "localhost:8000"
]
"connection" => array:1 [▼
0 => "Keep-Alive"
]
"user-agent" => array:1 [▼
0 => "Apache-HttpClient/4.5.5 (Java/12.0.1)"
]
]
#cacheControl: []
}
#content: """
{\n
\t"id_employee" = "4",\n
\t"status" = "1",\n
\t"latitude" = "3.4141414",\n
\t"longitude" = "98.444444",\n
\t"timestamp" = "2020-10-11 09:58:00.0000000",\n
\t"approval" = "1",\n
\t"message" = "this is message",\n
\t"picture_reference" = "this is pic"\n
}
"""
#languages: null
#charsets: null
#encodings: null
#acceptableContentTypes: null
#pathInfo: "/api/Attendance"
#requestUri: "/api/Attendance"
#baseUrl: ""
#basePath: null
#method: "POST"
#format: null
#session: null
#locale: null
#defaultLocale: "en"
-preferredFormat: null
-isHostValid: true
-isForwardedValid: true
-isSafeContentPreferred: null
basePath: ""
format: "html"
}
}
when i return $request->getcontent() the result is
{ "id_employee" = "4", "status" = "1", "latitude" = "3.4141414", "longitude" = "98.444444", "timestamp" = "2020-10-11 09:58:00.0000000", "approval" = "1", "message" = "this is message", "picture_reference" = "this is pic" }
but when i return $request->all() is says
<Empty JSON content>
whenever i use $request->id_employee or any other data, it always return null. when i put parameter on the URL like "?id_employee=1", $request->id_employee will return 1. i do not want to put the data on the URL, so how do i get all the content on $request?
edit:
i already tried
$id_employee = $request->id_employee;
$id_employee = $request->input("id_employee")
$id_employee = $request->input("content.id_employee")
and already confirm that $request->isjson() return 1

What version of Laravel do you have? You should be able to decode the JSON content, like this:
$content = $request->getContent()
$data = json_decode($content, true)
dd(data)
Check that the JSON is valid though - the example that you posted in your original questions had = where the : should normally go! The JSON needs to be valid and if the request has the correct Content-Type header then your call to request->input("employee_id") should work. That it doesn't makes me wonder if the JSON is well-formatted so definitely check that as well.

Related

htmlspecialchars() expects parameter 1 to be string, array given in laravel 8 with stored procedure blade file error

I am fetching data from database using stored procedure but getting below error
htmlspecialchars() expects parameter 1 to be string, array
Below is the controllers
public function index()
{
$id=2;
// $single_blog['user'] = UserRole::where('id',$id)->get();
$single_blog['user'] = DB::select("CALL FetchUserRoleWithId(".$id.")");
return view('home',$single_blog);
}
In view simple use only as
{{$user}}
If i use get() method then properly print $user data in blade file.
But using stored procedure getting below error
"htmlspecialchars() expects parameter 1 to be string, array"
Using stored procedure getting below data
array:1 [▼
"user" => array:1 [▼
0 => {#1237 ▼
+"id": 2
+"name": "SO"
+"status": "1"
+"created_by": null
}
]
]
Using get() method getting below data
array:1 [▼
"user" => Illuminate\Database\Eloquent\Collection {#1257 ▼
#items: array:1 [▼
0 => App\Models\UserRole {#1258 ▼
#fillable: array:4 [▶]
#connection: "mysql"
#table: "user_roles"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: array:8 [▼
"id" => 2
"name" => "SO"
"status" => "1"
"created_by" => null
"updated_by" => null
"deleted_at" => null
"created_at" => null
"updated_at" => null
]
#original: array:8 [▶]
#changes: []
#casts: array:1 [▶]
#classCastCache: []
#attributeCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#guarded: array:1 [▶]
#forceDeleting: false
}
]
#escapeWhenCastingToString: false
}
]
Anyone have idea how to display this data in blade file.

Call to a member function stripe() on null when cancelling the subscription

I am using Laravel 8 and Laravel Cashier for my subscriptions
When I tried to cancel the subscription, it returns
Call to a member function stripe() on null
when cancelling the subscription
Even the Auth::check() returns true
Here is my cancelSubscription method
public function cancelSubscription(Request $request){
$user = $request->user();
try{
// if(Auth::check()){
$user->subscription('My-Subscription-Name')->cancel();
// }
if($request->ajax()) {
return response([
'success' => true,
'data' => "Successfully subscribed"
], 200);
}
}catch (\Throwable $ex) {
Log::critical($ex);
if($request->ajax()) {
return response([
'success' => false,
'data' => "Server Error"
], 422);
}
}
}
Here is the code in api.php for the cancel subscription method
Route::post('/cancel-sub',[SubscriptionController::class, 'cancelSubscription'])->middleware('auth:api');
I've also tried this
public function cancelSubscription(Request $request){
$user = UserSubscription::where('stripe_id', $request->subId)->first(); //returns subscription id
try{
// if(Auth::check()){
$user->subscription('My-Subscription-Name')->cancel();
// }
if($request->ajax()) {
return response([
'success' => true,
'data' => "Successfully subscribed"
], 200);
}
}catch (\Throwable $ex) {
Log::critical($ex);
if($request->ajax()) {
return response([
'success' => false,
'data' => "Server Error"
], 422);
}
}
}
I've also tried
$user = $request->user();
$subscriptions = $user->subscriptions()->active()->first();
$subscriptions->cancel();
but it still doesn't work. Any answers will be appreciated.
I also did dd(auth()->user()->subscription('My-Subscription-Name')) and it returns true and here is the result
Laravel\Cashier\Subscription {#1293
#guarded: []
#with: array:1 [
0 => "items"
]
#casts: array:1 [
"quantity" => "integer"
]
#dates: array:4 [
0 => "created_at"
1 => "ends_at"
2 => "trial_ends_at"
3 => "updated_at"
]
#billingCycleAnchor: null
#connection: "mysql"
#table: "subscriptions"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: array:12 [
"id" => 32
"user_tbl_id" => 4697
"name" => "My-Subscription-Name"
"stripe_id" => "sub_xxx"
"stripe_status" => "active"
"stripe_price" => "price_xxx"
"quantity" => 1
"trial_ends_at" => null
"ends_at" => null
"expires_at" => "2022-10-13 20:38:54"
"created_at" => "2022-09-13 20:38:54"
"updated_at" => "2022-09-13 20:38:54"
]
#original: array:12 [
"id" => 32
"user_tbl_id" => 4697
"name" => "Choi-Nomi"
"stripe_id" => "sub_xxx"
"stripe_status" => "active"
"stripe_price" => "price_xxx"
"quantity" => 1
"trial_ends_at" => null
"ends_at" => null
"expires_at" => "2022-10-13 20:38:54"
"created_at" => "2022-09-13 20:38:54"
"updated_at" => "2022-09-13 20:38:54"
]
#changes: []
#classCastCache: []
#attributeCastCache: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: array:1 [
"items" => Illuminate\Database\Eloquent\Collection {#1303
#items: array:1 [
0 => Laravel\Cashier\SubscriptionItem {#1301
#guarded: []
#casts: array:1 [
"quantity" => "integer"
]
#connection: "mysql"
#table: "subscription_items"
#primaryKey: "id"
#keyType: "int"
+incrementing: true
#with: []
#withCount: []
+preventsLazyLoading: false
#perPage: 15
+exists: true
+wasRecentlyCreated: false
#escapeWhenCastingToString: false
#attributes: array:9 [
"id" => 33
"subscription_id" => 32
"stripe_id" => "si_xxx"
"stripe_product" => "prod_xxx"
"stripe_price" => "price_xxx"
"quantity" => 1
"user_subscription_id" => null
"created_at" => "2022-09-13 20:38:54"
"updated_at" => "2022-09-13 20:38:54"
]
#original: array:9 [
"id" => 33
"subscription_id" => 32
"stripe_id" => "si_xxx"
"stripe_product" => "prod_xxx"
"stripe_price" => "price_xxx"
"quantity" => 1
"user_subscription_id" => null
"created_at" => "2022-09-13 20:38:54"
"updated_at" => "2022-09-13 20:38:54"
]
#changes: []
#classCastCache: []
#attributeCastCache: []
#dates: []
#dateFormat: null
#appends: []
#dispatchesEvents: []
#observables: []
#relations: []
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#paymentBehavior: "allow_incomplete"
#prorationBehavior: "create_prorations"
}
]
#escapeWhenCastingToString: false
}
]
#touches: []
+timestamps: true
#hidden: []
#visible: []
#fillable: []
#couponId: null
#promotionCodeId: null
#allowPromotionCodes: false
#paymentBehavior: "allow_incomplete"
#prorationBehavior: "create_prorations"
}
I did have a look at my old project and what I did was add another method on User Model, to also delete the subscription related entries on the database
public function cancelStripeSubscription( $name = 'My Subscription Name') {
$sub = $this->subscription($name);
if ( $sub ) {
DB::table('subscriptions')->where('id', $sub->id)->delete();
DB::table('subscription_items')->where('subscription_id', $sub->id)->delete();
if ( $sub->stripe_status != 'canceled' )
$sub->cancelNow();
}
}
so you can simply call auth()->user()->cancelStripeSubscription();
In you code however, you should first check if they have active subscription or subscribe to specific product by checking subscription status
something like this;
public function cancelSubscription(Request $request){
try{
if ( auth()->user()->subscribed('default') )
/*
or if ( $user->subscribedToProduct('prod_premium', 'default'))
or if ( $user->subscribedToPrice('price_basic_monthly', 'default'))
or
$sub = auth()->user()->subscription('My-Subscription-Name')
if ( $sub && $sub->stripe_status == 'canceled' )
*/
{
auth()->user()->subscription('My-Subscription-Name')->cancel();
} else {
return response([ 'error' => true, 'message' => 'You have no active subscription' ], 404);
}
.
.
}
.
.
}
Furthermore, verify if that subscripton your trying to cancel really is a subscription object and check if user is even have a subscription
public function cancelSubscription(Request $request){
return [
'request' => $request->all(),
'user' => auth()->user(),
'subscription' => auth()->user()->subscription('My-Subscription-Name'),
'subscriptions' => auth()->user()->subscriptions()
]
.
.
}

Extracting October pages indentation in JSON for a Vue.js app

For building a vue menu in October, I have a plugin that I want to extract the October pages structure in a JSON data keeping the pages and subpages indentation.
Based on this post : How to get static page dropdown in OctoberCMS with get page tree?
I used the following code :
public function boot() {
\RainLab\Pages\Classes\Page::extend(function($model) {
$model->addDynamicMethod('getPageOptions', function() {
$theme = \Cms\Classes\Theme::getEditTheme();
$pageList = new \RainLab\Pages\Classes\PageList($theme);
$treePageList = $pageList->getPageTree(true);
$pages = [];
$this->getRecursivePage($pages, $treePageList);
return $pages;
});
});
}
public function getRecursivePage(&$pages, $subpages, $level = 0) {
$level++;
foreach($subpages as $pageArr) {
$pages[$pageArr->page->url] =
str_repeat('-',$level) . ' ' . $pageArr->page->title;
if(count($pageArr->subpages) > 0) {
$this->getRecursivePage($pages, $pageArr->subpages, $level);
}
}
}
but the returned $treePageList is too rich for that purpose and the $pages flattens the indentation.
How could I manipulate the returned JSON structure to simplify it, with only page->url and page->title and keeping the pages and subpages indentation ?
Thanks for help
EDIT :
This code with the $level produces :
array:9 [▼
"/content" => "- Content"
"/content/pages" => "-- Static Pages"
"/content/content" => "-- Content"
"/content/models" => "-- Models"
"/content/urls" => "-- URLs"
"/content/urls/tesets" => "--- tesets"
"/test-sp" => "- test-sp"
"/test-sp/oks" => "-- oks"
"/test" => "- test"
]
but I'd like to have a JSON data with levels like (not raw data visualization) :
▼ 0
page {title: , url:}
subpages []
▼ 1
page {title: , url:}
subpages
▼ 0 {title: , url:}
▼ 1 {title: , url:}
▼ 2 {title: , url:}
▼ 3 {title: , url:}
▼ 4 {title: , url:}
▼ 5 {title: , url:}
▼ 6 {title: , url:}
▼ 7 {title: , url:}
▼ 8 {title: , url:}
▼ 2
page {title: , url:}
subpages
▼ 0 {title: , url:}
▼ 1 {title: , url:}
▼ 2 {title: , url:}
Use this code
public function boot() {
\RainLab\Pages\Classes\Page::extend(function($model) {
$model->addDynamicMethod('getPageOptions', function() {
$theme = \Cms\Classes\Theme::getEditTheme();
$pageList = new \RainLab\Pages\Classes\PageList($theme);
$treePageList = $pageList->getPageTree(true);
return $this->getRecursivePage($treePageList);
});
});
$pages = \RainLab\Pages\Classes\Page::getPageOptions();
header('Content-Type: application/json');
echo json_encode($pages);
exit();
}
public function getRecursivePage($pages) {
$pageDetails = [];
foreach($pages as $iPage) {
$detail = [];
$detail['page'] = ['title' => $iPage->page->title, 'url' => $iPage->page->url];
$subpages = $this->getRecursivePage($iPage->subpages);
if(count($subpages) > 0 ) {
$detail['subpages'] = $subpages;
}
$pageDetails[] = $detail;
}
return $pageDetails;
}
Output
[
{
"page": {
"title": "static-page",
"url": "/static-page"
}
},
{
"page": {
"title": "/parent",
"url": "/parent"
},
"subpages": [
{
"page": {
"title": "child",
"url": "/parent/child"
},
"subpages": [
{
"page": {
"title": "another child",
"url": "/parent/child/another-child"
}
},
{
"page": {
"title": "another next",
"url": "/parent/child/another-next"
}
}
]
}
]
}
]
If any doubt please comment.
I solved this by adding 2 functions and calling them sequentially. One for Pages an one for Static Pages.
The functions are building a complex object with the desired structure which will be use for building the menu.
Thanks

guzzle and last fm API

I'm using Laravel for about one month and i wanted to try the guzzle module, to get last fm user infos
I've tried this request in my controller :
$client = new \GuzzleHttp\Client(['base_uri' => 'http://ws.audioscrobbler.com/']);
//$client = new \GuzzleHttp\Client();
$response = $client->get('2.0/?method=user.getinfo&user=rj&api_key=xxxxxxxxxx&format=json');
dd($response);
but i've just got this kind of things
Response {#190 ▼
-reasonPhrase: "OK"
-statusCode: 200
-headers: array:11 [▼
"date" => array:1 [▶]
"server" => array:1 [▼
0 => "Apache/2.2.22 (Unix)"
]
"x-web-node" => array:1 [▼
0 => "www223"
]
"access-control-allow-origin" => array:1 [▼
0 => "*"
]
"access-control-allow-methods" => array:1 [▼
0 => "POST, GET, OPTIONS"
]
"access-control-max-age" => array:1 [▼
0 => "86400"
]
"cache-control" => array:1 [▼
0 => "max-age=60"
]
"expires" => array:1 [▶]
"content-length" => array:1 [▼
0 => "642"
]
"connection" => array:1 [▶]
"content-type" => array:1 [▶]
]
-headerLines: array:11 [▶]
-protocol: "1.0"
-stream: Stream {#181 ▼
-stream: :stream {#237 ▼
wrapper_type: "PHP"
stream_type: "TEMP"
mode: "w+b"
unread_bytes: 0
seekable: true
uri: "php://temp"
options: []
}
-size: null
-seekable: true
-readable: true
-writable: true
-uri: "php://temp"
-customMetadata: []
}
}
Could someone help me with an example or something :) ?
For body's contents:
echo $response->getBody();

Using Eloquent to retrieve data shows different array

Well I am very very new to Laravel. So I am learning the basics from Laracast actually. I have a table called songs , a model Song.php as below:
<?php namespace App;
use Illuminate\Database\Eloquent\Model as Eloquent;
class Song extends Eloquent{
}
And a Controller SongsController.php :
use App\Song;
use DB;
class SongsController extends Controller
{
function index() {
$songs = Song::get();
$songs2 = DB::table('songs')->get();dd($songs2);
//$mysong2 = Song::whereSlug('as-long-as-you-love-me')->first();
}
}
So I expect $songs and $songs2 are same and produce same result. but dd($songs) produce result something like below:
Collection {#146 ▼
#items: array:1 [▼
0 => Song {#147 ▼
#connection: null
#table: null
#primaryKey: "id"
#perPage: 15
+incrementing: true
+timestamps: true
#attributes: array:6 [▼
"id" => "1"
"title" => "As Long as you Love me"
"slug" => "as-long-as-you-love-me"
"lyrics" => null
"created_at" => "2015-06-21 00:00:00"
"updated_at" => "2015-06-21 00:00:00"
]
#original: array:6 [▶]
#relations: []
#hidden: []
#visible: []
#appends: []
#fillable: []
#guarded: array:1 [▶]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: true
}
]
}
and $songs2 produces ( which I think the actual,but not sure):
array:1 [▼
0 => {#145 ▼
+"id": "1"
+"title": "As Long as you Love me"
+"slug": "as-long-as-you-love-me"
+"lyrics": null
+"created_at": "2015-06-21 00:00:00"
+"updated_at": "2015-06-21 00:00:00"
}
]
So I want to know which one should I use ? And is there any mistake I am doing ?
there is no mistake.
for $songs you are using eloquent with function get(), which will always return an object of type
Illuminate\Database\Eloquent\Collection
but for $songs2 you are using query builder with function get(), which will always return an array of
stdClass objects.
thats why you see different results.
both are correct and you can use both, but if you have created a model for your song, then use eloquent instead of query builder.