I have a JSON field in my MySQL table column which has an JSON array with part of images URLs.
"images": [
{
"images": {
"original": "/storage/uploads/1.png",
"300": "/storage/uploads/300.1.png",
"600": "/storage/uploads/600.1.png",
"900": "/storage/uploads/900.1.png"
},
"thumb": "/storage/uploads/300.1.png"
},
{
"images": {
"original": "/storage/uploads/2.png",
"300": "/storage/uploads/300.2.png",
"600": "/storage/uploads/600.2.png",
"900": "/storage/uploads/900.2.png"
},
"thumb": "/storage/uploads/300.2.png"
},
{},
]
I want to get the array with appending a Base URL for each of the values of the array.
"images": [
{
"images": {
"original": "http://localhost:8000/storage/uploads/1.png",
"300": "http://localhost:8000/storage/uploads/300.1.png",
"600": "http://localhost:8000/storage/uploads/600.1.png",
"900": "http://localhost:8000/storage/uploads/900.1.png"
},
"thumb": "http://localhost:8000/storage/uploads/300.1.png"
},
{
"images": {
"original": "http://localhost:8000/storage/uploads/2.png",
"300": "http://localhost:8000/storage/uploads/300.2.png",
"600": "http://localhost:8000/storage/uploads/600.2.png",
"900": "http://localhost:8000/storage/uploads/900.2.png"
},
"thumb": "http://localhost:8000/storage/uploads/300.2.png"
},
{},
]
I have tried with Collections function like below code. But was not succeeded.
'images' => collect($item->images)->map(function ($image) {
return url($image);
})->all(),
For collections you would need to create a collection of the second images keyed array as well. collect() does not create a recursive collection.
So if you had the following array:
$item = [
"images" => [
[
"images" => [
"original" => "/storage/uploads/1.png",
"300" => "/storage/uploads/300.1.png",
"600" => "/storage/uploads/600.1.png",
"900" => "/storage/uploads/900.1.png"
],
"thumb" => "/storage/uploads/300.1.png",
], [
"images" => [
"original" => "/storage/uploads/2.png",
"300" => "/storage/uploads/300.2.png",
"600" => "/storage/uploads/600.2.png",
"900" => "/storage/uploads/900.2.png",
],
"thumb" => "/storage/uploads/300.2.png",
]
]
];
and you really wanted to use collection, then the following would work:
$item = collect($item['images'])->map(function ($item) {
$images = collect($item['images'])->map(function ($item) {
return url($item);
});
return [
"images" => $images->toArray(),
"thumb" => url($item['thumb']),
];
});
You can use nested foreach to solve this
$json = json_decode($item->images, true); // I'm using true to convert the json to array
$images = [];
foreach ($json as $index => $array) {
foreach ($array as $key => $value) {
if (is_array($value)) {
foreach ($value as $path_key => $path) {
$images[$index][$key][$path_key] = url($value[$path_key]);
}
} else {
$images[$index][$key] = url($value);
}
}
}
If you dd($images); you will get
array:2 [▼
0 => array:2 [▼
"images" => array:4 [▼
"original" => "http://localhost:8000/storage/uploads/1.png"
300 => "http://localhost:8000/storage/uploads/300.1.png"
600 => "http://localhost:8000/storage/uploads/600.1.png"
900 => "http://localhost:8000/storage/uploads/900.1.png"
]
"thumb" => "http://localhost:8000/storage/uploads/300.1.png"
]
1 => array:2 [▼
"images" => array:4 [▼
"original" => "http://localhost:8000/storage/uploads/2.png"
300 => "http://localhost:8000/storage/uploads/300.2.png"
600 => "http://localhost:8000/storage/uploads/600.2.png"
900 => "http://localhost:8000/storage/uploads/900.2.png"
]
"thumb" => "http://localhost:8000/storage/uploads/300.2.png"
]
]
Related
I have a nested collection that I want to transform, pulling some keys "up a level" and discarding some other keys.
Every item in the collection has an allergens property.
"allergens": [
{
"id": 2001,
"info": "Allergy advice",
"status": "does_contain",
"product_id": 71576,
"allergen_id": 1,
"allergen": {
"id": 1,
"name": "Celery"
}
},
{
"id": 2002,
"info": "Allergy advice",
"status": "may_contain",
"product_id": 71576,
"allergen_id": 11,
"allergen": {
"id": 11,
"name": "Peanuts"
}
}
],
I need to make each items allergens property, look like
"allergens": [
{
"id": 1,
"name": "Celery"
"status": "does_contain",
},
{
"id": 11,
"name": "Peanuts"
"status": "does_contain",
},
],
I've tried the following:
$collection = $collection->transform(function ($item, $key) {
$item->allergens = $item->allergens->map(function ($allergen) {
return [
'id' => $allergen->allergen->id,
'name' => $allergen->allergen->name,
'status' => $allergen->status,
];
});
return $item;
});
But it doesn't overwrite the allergens property
Since you're posting your collection as JSON, I reverse engineered what your actual collection would look like. Turns out, your transform() works fine as far as I can tell. Maybe that helps you to find differences between my and your collection which might lead you to your problem/solution:
$collection = collect([
(object)[
"allergens" => collect([
(object)[
"id" => 2001,
"info" => "Allergy advice",
"status" => "does_contain",
"product_id" => 71576,
"allergen_id" => 1,
"allergen" => (object)[
"id" => 1,
"name" => "Celery"
]
],
(object)[
"id" => 2002,
"info" => "Allergy advice",
"status" => "may_contain",
"product_id" => 71576,
"allergen_id" => 11,
"allergen" => (object)[
"id" => 11,
"name" => "Peanuts"
]
]
]),
]
]);
$collection = $collection->transform(function ($item, $key) {
$item->allergens = $item->allergens->map(function ($allergen) {
return [
'id' => $allergen->allergen->id,
'name' => $allergen->allergen->name,
'status' => $allergen->status,
];
});
return $item;
});
dd($collection);
Result:
Illuminate\Support\Collection {#1779 ▼
#items: array:1 [▼
0 => {#1791 ▼
+"allergens": Illuminate\Support\Collection {#1775 ▼
#items: array:2 [▼
0 => array:3 [▼
"id" => 1
"name" => "Celery"
"status" => "does_contain"
]
1 => array:3 [▼
"id" => 11
"name" => "Peanuts"
"status" => "may_contain"
]
]
}
}
]
}
I am trying to change an indexed array of arrays into a new array structure. My data is as follows:
$arr = array(
array( "year" => 1921, "name" => "bob" ),
array( "year" => 1944, "name" => "steve" ),
array( "year" => 1944, "name" => "doug" ),
array( "year" => 1921, "name" => "jim" ),
);
I would like to recreate a new array thats groups them into the same year. The best I can come up with is designating the year as the key so any row that has that year gets added to that key, but it's not the output that I'm looking for. What I need is how it's listed below.
"data": [
{
"year":"1921",
"names": [
{ "name":"bob" }, { "name":"jim"}
]
},
{
"year":1944",
"names": [
{ "name":"steve" }, { "name":"doug "}
]
}
You don't need to pre-extract the unique years nor use conditions within nested loops. Just push the data into the result set using temporary first-level keys, then remove the temporary keys when finished looping.
This ensures unique years, but allows names to be duplicated.
Code: (Demo)
$arr = [
["year" => 1921, "name" => "bob"],
["year" => 1944, "name" => "steve"],
["year" => 1944, "name" => "doug"],
["year" => 1921, "name" => "jim"],
];
foreach ($arr as $item) {
$result[$item['year']]['year'] = $item['year'];
$result[$item['year']]['names'][] = ['name' => $item['name']];
}
echo json_encode(
['data' => array_values($result)],
JSON_PRETTY_PRINT // for better visualization
);
Output:
{
"data": [
{
"year": 1921,
"names": [
{
"name": "bob"
},
{
"name": "jim"
}
]
},
{
"year": 1944,
"names": [
{
"name": "steve"
},
{
"name": "doug"
}
]
}
]
}
I am trying to create a POST to a REST API to create a new object. I cannot figure out how to properly format my JSON.
Here's the response from the GET of an existing object:
{
"name": "product 2 mem"
"type": "simple"
"categories": array:1 [▼
0 => {
"id": 75
}
]
"meta_data": array:1 [▼
"id": 3665
"key": "_yith_wcbm_product_meta"
"value": {
"id_badge": "2955"
}
}
]
}
Here is the POST I'm trying to create:
$data = [
'name' => 'product name',
'type' => 'simple',
'categories' => [
[
'id' => 75
],
'meta_data' => [
'_yith_wcbm_product_meta' => [
'id_badge' => '2955'
]
]
];
You got typo in you json data.
$response = '{
"id": 3665,
"key": "_yith_wcbm_product_meta",
"value": {
"id_badge": "2955"
}
}';
$array = json_decode($response,true);
$return = ['meta_data'=>['key'=>$array['key'],'value'=>$array['value']]];
echo json_encode($return);
I figured out how to format it:
'meta_data' => [
[
'key' => '_yith_wcbm_product_meta',
'value' => ['id_badge' => '2955']
]
I tried to use ORM to find list of provinces and their cities.
the result is same as this list:
"provinces": [
{
"name": "Prov.1",
"Cities": {
"name": "City.1"
}
},
{
"name": "Prov.1",
"Cities": {
"name": "City.2"
}
},
]
what is expected:
"provinces": [
{
"name": "Prov.1",
"Cities": [
{
"name": "City.1"
},
{
"name": "City.2"
}
]
},
]
used ORM:
Provinces::find('all', [
'with' => ['Cities']
]);
Something like
$array = [];
foreach($provinces as $province){
$key = $province['name'];
if(!isset($array[$key])){
$array[$key] = [
'name' => $province['name'],
'Cities' => [
[ 'name' => $province['Cities']['name']];
]
];
}else{
$array[$key]['Cities'][] = ['name' => $province['Cities']['name']];
}
}
//strip keys
$array = array_values($array);
Because you don't have an actual PHP array posted I'm just guessing at what it should be.
I need to get an JSON structure as following:
{
"emails": [
{
"sender": "shihas#abc.com",
"unread_count": 2,
"items": [
{
"id": "89",
"email": "shihas#abc.com",
"read": "0",
},
{
"id": "32",
"email": "shihas#abc.com",
"read": "0",
}
]
},
{
"sender": "marias123#gmail.com",
"unread_count": 0,
"items": [
{
"id": "2",
"email": "marias123#gmail.com",
"read": "1",
}
]
},
{
"sender": "gutar4320#hotmail.com",
"unread_count": 1,
"items": [
{
"id": "1",
"email": "gutar4320#hotmail.com",
"read": "0",
}
]
}
]
}
Array($hire_email):
In the below array I need to group all the details based on the email. And also count the no. of unread messages(i.e read = 0).
Array
(
[0] => Array
(
[id] => 89
[email] => shihas#abc.com
[read] => 0
)
[1] => Array
(
[id] => 32
[email] => shihas#abc.com
[read] => 0
)
[2] => Array
(
[id] => 2
[email] => marias123#gmail.com
[read] => 1
)
[3] => Array
(
[id] => 1
[email] => gutar4320#hotmail.com
[read] => 0
)
)
The following is the code snippet used for maintaining the JSON structure.
foreach($hire_email as $val) {
if($val['read']==0){ $count++; }else{ $count = 0;}
$hire_group_email[$val['email']]['sender'] = $val['email'];
$hire_group_email[$val['email']]['unread_count'] = $count;
$hire_group_email[$val['email']]['items'][] = $val;
}
$output["emails"][] = $hire_group_email;
echo json_encode($output);
This should do the trick.
$hire_email =array(
array(
"id" => "89",
"email" => "shihas#abc.com",
"read" => "0"
),
array
(
"id" => "32",
"email" => "shihas#abc.com",
"read" => "0"
),
array
(
"id" => "2",
"email" => "marias123#gmail.com",
"read" => "1"
),
array
(
"id" => "1",
"email" => "gutar4320#hotmail.com",
"read" => "0"
)
);
$tmp = array();
foreach($hire_email as $arg)
{
$tmp[$arg['email']][] = $arg;
}
$output = array();
foreach($tmp as $type => $labels)
{
$count = 0;
foreach ($labels as $value) {
if($value['read']==0){ $count++; }else{ $count = 0;}
}
$output[] = array(
'sender' => $type,
'unread_count' => $count,
'items' => $labels
);
}
echo json_encode($output);
Try doing it like this, using: array_sum and array_column, the rest is just picking out the first items values.
$array = json_decode($json, true)['emails'];
$result = [];
foreach($array as $val) {
$result[] = [
'id' => $val['items'][0]['id'],
'email' => $val['items'][0]['email'],
'read' => array_sum(array_column($val['items'], 'read'))
];
}
$output["emails"] = $result;
echo json_encode($output, JSON_PRETTY_PRINT);
Result:
{
"emails": [
{
"id": "89",
"email": "shihas#abc.com",
"read": 0
},
{
"id": "2",
"email": "marias123#gmail.com",
"read": 1
},
{
"id": "1",
"email": "gutar4320#hotmail.com",
"read": 0
}
]
}
https://3v4l.org/hi7qm
And if you want it as shown ;p (my mistake, misread it):
Loop over each item, then loop over the items and use that to build the output.
$array = json_decode($json, true)['emails'];
$result = [];
foreach($array as $val) {
foreach ($val['items'] as $item) {
$result[] = [
'id' => $item['id'],
'email' => $item['email'],
'read' => array_sum(array_column($val['items'], 'read'))
];
}
}
$output["emails"] = $result;
echo json_encode($output, JSON_PRETTY_PRINT);
Result:
{
"emails": [
{
"id": "89",
"email": "shihas#abc.com",
"read": 0
},
{
"id": "32",
"email": "shihas#abc.com",
"read": 0
},
{
"id": "2",
"email": "marias123#gmail.com",
"read": 1
},
{
"id": "1",
"email": "gutar4320#hotmail.com",
"read": 0
}
]
}
https://3v4l.org/eU95A