Laravel/Eloquent normalize relations for JSON response? - php

(Edited to add a better example with multiple characters with the same book and author)
Using Laravel 8, but this must be a generic enough problem I just don't know the name for or can't find. I've tried "normalizing eloquent JSON response" ad nauseum and nothing seems to be this specific issue.
I have some basic relations defined in Laravel, but I want to separate them out for a JSON response.
e.g.
Character belongsTo Book
Book belongsTo Author
So (ignore any syntax issues, it's quickly typed pseudo code)
$characters = Character::with('book', 'book.author')->get();
$characters->toJson();
Output:
[
{
"id": 1,
"book_id": 1,
"name": "Some character",
"book": [{
"id": 1,
"author_id": 1,
"name": "Some book",
"author": [{
"id": 1,
"name": "Some author"
}]
}]
},
{
"id": 2,
"book_id": 1,
"name": "A second character",
"book": [{
"id": 1,
"author_id": 1,
"name": "Some book",
"author": [{
"id": 1,
"name": "Some author"
}]
}]
}
]
But what I really want is this so I can feed it into a front end (React) simple ORM, but unnested and deduplicated (since the originally nested response could have the same book entry for multiple characters for example).
{
"characters": [{
"id": 1,
"book_id": 1,
"name": "Some character"
}, {
"id": 2,
"book_id": 1,
"name": "A second character"
}],
"books": [{
"id": 1,
"author_id": 1,
"name": "Some book"
}],
"authors": [{
"id": 1,
"name": "Some author"
}],
}

Related

Pivot data from JSON object

I have a base table where i store records per team in a json object;
[
{
"Id": 1,
"date": "01-01-2022",
"Group": "A",
"Description": "test 1"
},
{
"Id": 2,
"date": "01-01-2022",
"Group": "B",
"Description": "test 2"
},
{
"Id": 3,
"date": "08-01-2022",
"Group": "B",
"Description": "test 3"
},
{
"Id": 4,
"date": "16-01-2022",
"Group": "A",
"Description": "test 4"
},
{
"Id": 5,
"date": "16-01-2022",
"Group": "C",
"Description": "test 5"
}
]
Now for reporting purpose i need to pivot the table like:
Date
A
B
C
01-01-2022
test 1
test 2
-
08-01-2022
-
test 3
-
16-01-2022
test 4
-
test 5
I really dont know how to perform such action with PHP or Javascript.. Tried with for each loops but i only got the date as a unique value.
btw; for empty rows to show "-" is fine.

Array filter JSON data with price parameter

I have this JSON data and I am using this code to match the title. It works, but now I want to go one step further and list all products which are less than some price, or more than some price, or equal to some price
$json = '[{
"id": 2042049298481,
"title": "Test Product 53",
"variants": [{
"id": 15733087797297,
"title": "Default Title",
"price": "100.00",
"sku": "no"
}]
}, {
"id": 2196682342449,
"title": "its test yar",
"variants": [{
"id": 16385289879601,
"title": "Default Title",
"price": "144.00",
"sku": "no"
}]
}, {
"id": 4175970041905,
"title": "uhjkjhkhk",
"variants": [{
"id": 30302326554673,
"title": "Default Title",
"price": "1000.00",
"sku": "10"
}]
}, {
"id": 4183828791345,
"title": "kaminsss",
"variants": [{
"id": 30346449518641,
"title": "Default Title",
"price": "111.00",
"sku": "no"
}]
}, {
"id": 4247884890161,
"title": "hellooo",
"variants": [{
"id": 30579860832305,
"title": "Default Title",
"price": "1111.00",
"sku": "no"
}]
}, {
"id": 4248143822897,
"title": "10oct latest collection",
"variants": [{
"id": 31157780938801,
"title": "50",
"price": "111.00",
"sku": "no-1"
}, {
"id": 31157802270769,
"title": "60",
"price": "101.00",
"sku": ""
}, {
"id": 31157804761137,
"title": "70",
"price": "111.00",
"sku": ""
}]
}, {
"id": 4284600746033,
"title": "18oct2019",
"variants": [{
"id": 31595410030641,
"title": "120 / black",
"price": "100.00",
"sku": "10"
}]
}, {
"id": 4285596860465,
"title": "test2222",
"variants": [{
"id": 30877916921905,
"title": "Default Title",
"price": "111.00",
"sku": "no"
}]
}]';
$array = json_decode($json,1);
$filter_name ='title';
$filter_value ='Test';
$expected88 = array_filter($array, function($el) use ($filter_value, $filter_name) {
return ($el[$filter_name] >= $filter_value);
});
echo json_encode($expected88,true);
This works flawlessly for title but we want to filter based on variant price. There may be several prices for one variant and if $filter_value is greater than, equal to, or less than, anyone can occur.
For example user may search for product whose minimum price is 50, so in that case, if any variant is matching criteria then it will list those products, or user may search that all variants' prices should be less than 50.
We tried like this
$expected = array_filter($array, function ($var) use ($filter_value) {
return ($var[$filter_name] >= $filter_value);
});
but it did not work.
We tried foreach and tested again but it always gave empty result
Here is possible solution
$filter_name ='variants';
$filter_value = 200;
$filter_field = "price";
$expected88 = array_filter($array, function($el) use ($filter_value, $filter_name, $filter_field) {
return ((int)$el[$filter_name][0][$filter_field] >= (int)$filter_value);
});

How to get a particular string from and api response?

I have been on a little project of mine now i want to find imdb_id using tmdb_id so for that I have been trying to use the API.
https://api.themoviedb.org/3/tv/67026?api_key=myapikey&append_to_response=external_ids
which brings up the results like this
{
"backdrop_path": "/hcFbIbDzsB9aSSw9VkSGFEl5sGO.jpg",
"created_by": [{
"id": 230174,
"credit_id": "577eb8e5c3a368694a0027ac",
"name": "David Guggenheim",
"gender": 2,
"profile_path": "/hqSydaadHO6EsBIn3BQEzzfxNUY.jpg"
}],
"episode_run_time": [42],
"first_air_date": "2016-09-21",
"genres": [{
"id": 18,
"name": "Drama"
}, {
"id": 10768,
"name": "War & Politics"
}],
"homepage": "https://www.netflix.com/title/80113647",
"id": 67026,
"in_production": false,
"languages": ["en"],
"last_air_date": "2019-06-07",
"last_episode_to_air": {
"air_date": "2019-06-07",
"episode_number": 10,
"id": 1809432,
"name": "#truthorconsequences",
"overview": "On election day, Kirkman turns to his therapist to assuage his conscience about the events -- and his own decisions -- of the momentous prior 36 hours.",
"production_code": "",
"season_number": 3,
"show_id": 67026,
"still_path": "/cpy3uV100RyZuvJN535JLTrj4Nz.jpg",
"vote_average": 7.0,
"vote_count": 1
},
"name": "Designated Survivor",
"next_episode_to_air": null,
"networks": [{
"name": "ABC",
"id": 2,
"logo_path": "/ndAvF4JLsliGreX87jAc9GdjmJY.png",
"origin_country": "US"
}, {
"name": "Netflix",
"id": 213,
"logo_path": "/wwemzKWzjKYJFfCeiB57q3r4Bcm.png",
"origin_country": ""
}],
"number_of_episodes": 53,
"number_of_seasons": 3,
"origin_country": ["US"],
"original_language": "en",
"original_name": "Designated Survivor",
"overview": "Tom Kirkman, a low-level cabinet member is suddenly appointed President of the United States after a catastrophic attack during the State of the Union kills everyone above him in the Presidential line of succession.",
"popularity": 30.031,
"poster_path": "/5R125JAIh1N38pzHp2dRsBpOVNY.jpg",
"production_companies": [{
"id": 28788,
"logo_path": null,
"name": "Genre Films",
"origin_country": "US"
}, {
"id": 19366,
"logo_path": "/vOH8dyQhLK01pg5fYkgiS31jlFm.png",
"name": "ABC Studios",
"origin_country": "US"
}, {
"id": 78984,
"logo_path": null,
"name": "Entertainment 360",
"origin_country": "US"
}],
"seasons": [{
"air_date": "2016-09-20",
"episode_count": 21,
"id": 78328,
"name": "Season 1",
"overview": "Tom Kirkman, a low-level cabinet member is suddenly appointed President of the United States after a catastrophic attack during the State of the Union kills everyone above him in the Presidential line of succession.",
"poster_path": "/1QHlD6z9FnXuuTDVLJnjrtLfVyq.jpg",
"season_number": 1
}, {
"air_date": "2017-09-27",
"episode_count": 22,
"id": 91130,
"name": "Season 2",
"overview": "",
"poster_path": "/z4hdj8cYyqCO9lVBOGm6YZsnMho.jpg",
"season_number": 2
}, {
"air_date": "2019-06-07",
"episode_count": 10,
"id": 122914,
"name": "Season 3",
"overview": "",
"poster_path": "/wn310FWQhjjpHbqsMRBcXr28EHc.jpg",
"season_number": 3
}],
"status": "Canceled",
"type": "Scripted",
"vote_average": 7.2,
"vote_count": 408,
"external_ids": {
"imdb_id": "tt5296406",
"freebase_mid": null,
"freebase_id": null,
"tvdb_id": 311876,
"tvrage_id": 51115,
"facebook_id": "DesignatedSurvivor",
"instagram_id": "designatedsurvivor",
"twitter_id": "DesignatedNFLX"
}
}
So now if I want to get just the IMDb_ID form the external_ids then what code should i use in PHP and store it in a variable.
Thank you very much in advance.
use the json_decode method to treat JSON like a PHP object
$data = 'your JSON object';//raw data as string in $data
$decoded = json_decode($data);//decoded data as PHP object
echo $decoded->external_ids->imdb_id; //access any property you like
hope this helps!!!

Using blog post tags with JSON

I have some JSON as below
"tags":
{
"business-school":
{
"name": "Business School",
"slug": "business-school",
"parent": 0,
"description": "",
"post_count": 13,
"id": 169072,
"taxonomy": "post_tag"
},
"canterbury":
{
"name": "Canterbury",
"slug": "canterbury",
"parent": 0,
"description": "",
"post_count": 37,
"id": 5349,
"taxonomy": "post_tag"
I have managed to display the relevant tags that were entered with the posts. On other blogs though I have seen the tags as hyperlinks and was wondering how this was implemented. what would they be linked to?. Is it something that is possible within a JSON framework with PHP bearing in mind I am not that familiar with JSON or is it something that is best left to blogging sites.
If you can keep the relationship of your data like below then you can easily implement that TAG with HYPERLINKS technique with your blog post also.
Format for TAGS Where each Tag will be associated with an ID
So your anchor link will be like -
https://blogs.canterbury.ac.uk/cafa/tag/555/ https://blogs.canterbury.ac.uk/cafa/tag/777/
"tags":
{
"business-school":
{
"name": "Business School",
"slug": "business-school",
"parent": 0,
"description": "",
"post_count": 13,
"id": 169072,
"taxonomy": "post_tag",
"tag_id": 555
},
"canterbury":
{
"name": "Canterbury",
"slug": "canterbury",
"parent": 0,
"description": "",
"post_count": 37,
"id": 5349,
"taxonomy": "post_tag",
"tag_id": 777
}
}
Format for Blog Post in respect to those TAG ID
When user click on any of those hyperlinks you'll get the TAG ID & from those TAG ID you can respective POSTS tagged with those ID. Ex- TAG ID 555 is associated with 2 POSTS.
{
"555": [{
"blog_id": 111,
"blog_excerpt": "your blog excerpt",
"date": "2017-04-15"
}, {
"blog_id": 222,
"blog_excerpt": "your blog excerpt",
"date": "2017-04-16"
}],
"777": [{
"blog_id": 333,
"blog_excerpt": "your blog excerpt",
"date": "2017-04-17"
}, {
"blog_id": 444,
"blog_excerpt": "your blog excerpt",
"date": "2017-04-18"
}]
}
Hope you'll get my Point.

Kendo UI Gantt chart not processing JSON

I've tried to switch the datasource of the Kendo UI Gantt example inside PHP. I have mapped the schema with what is being returned, but I just get a blank gantt chart with one heading - "undefined".
{
"1": {
"id": "1",
"orderId": "1",
"title": "TESTER1",
"start": "\/new Date('2016-01-01 09:00:00')\/",
"end": "\/new Date('2016-02-01 00:00:00')\/",
"project": "1",
"client": "4218",
"parent": "0",
"percentComplete": "10.11"
},
"2": {
"id": "2",
"orderId": "2",
"title": "TESTER2",
"start": "\/new Date('2016-01-03 09:00:00')\/",
"end": "\/new Date('2016-02-01 00:00:00')\/",
"project": "1",
"client": "4218",
"parent": "0",
"percentComplete": "50.00"
}
}
Above is the JSON being sent back to Kendo, but it doesn't render.
Found the solution:
I type casted the integers, set parents to null rather than zero (0) and converted dates into milliseconds in the PHP layer before putting through to Kendo. I also removed the keys which resulted in the below JSON to be created. This solved my rendering problem.
[{
"id": 1,
"orderId": 1,
"title": "TESTER1",
"start": "\/Date(1463126400000)\/",
"end": "\/Date(1463958000000)\/",
"project": 1,
"client": 4218,
"parent": null,
"percentComplete": 10
}, {
"id": 2,
"orderId": 2,
"title": "TESTER2",
"start": "\/Date(1463990400000)\/",
"end": "\/Date(1464130800000)\/",
"project": 1,
"client": 4218,
"parent": null,
"percentComplete": 50
}]

Categories