{
"id": "1",
"item_quantity": "3",
"item_id": "3",
"item_color": "White",
},
{
"id": "2",
"item_quantity": "3",
"item_id": "3",
"item_color": "Black",
},
{
"id": "3",
"item_quantity": "3",
"item_id": "4",
"item_color": "White",
},
Hi guys my output in Laravel using foreach is this,
ItemId:3 ItemQuantity:3 ItemColor:White
ItemId:3 ItemQuantity:3 ItemColor:Black
ItemId:4 ItemQuantity:3 ItemColor:White
But what I need is to combine those Item with the same ID like this,
ItemID:3 ItemQuantity:3 ItemColor:White/ ItemQuantity:3 ItemColor:Black
ItemId:4 ItemQuantity:3 ItemColor:White
BTW I use Table in my View, and Foreach to display may Data.
Thank you guys.. this is Laravel 4.2
#foreach($items as $item1)
<tr>{{$item1->id}}</td>
<td>{{$item1->item_quantity}}</td>
<td>{{$item1->item_color}}</td>
#foreach($items as $item2)
#if($item1->item_id == $item2->item_id)
<td>{{$item2->item_quantity}}</td>
<td>{{$item2->item_color}}</td>
#endif
#endforeach
</tr>
#endforeach
I am not sure what is your input objet but something like this:
function group_items($items){
$groupedOutput = array();
for each($items as $item){
$key = 'id_'.$item;
if(!array_key_exists($key, $groupedOutput)){
$groupedOutput[$key] = array();
}
$groupedOutput[$key][] = $item;
}
return $groupedOutput;
}
function print_items($groupedOutput){
for each($groupedOutput as $items){
for each($items as $item){
$itemId = $item['item_id'];
$itemQuantity = $item['item_quantity'];
$itemColor = $item['item_color'];
echo "ItemID:$itemId ItemQuantity:$itemQuantity ItemColor:$itemColor/ ";
}
}
}
//To group output
$groupedOutput = group_items($items);
//To print grouped output
print_items($groupedOutput);
// OR
var_dump(json_encode($groupedOutput));
Related
I have data as below:
[
{
"id": "3",
"title": "Boruto's Photo",
"is_lottery": 1,
"price": 10
},
{
"id": "4",
"title": "Misuki's Photo",
"is_lottery": 0,
"price": 20
}
]
I want to filter which is is_lottery == false remove the price key from this collection. The output is:
[
{
"id": "3",
"title": "Boruto's Photo",
"is_lottery": 1,
"price": 10
},
{
"id": "4",
"title": "Misuki's Photo",
"is_lottery": 0,
}
]
You can do this
$json = '[
{
"id": "3",
"title": "Boruto\'s Photo",
"is_lottery": 1,
"price": 10
},
{
"id": "3",
"title": "Misuki\'s Photo",
"is_lottery": 0,
"price": 20
}
]';
$filtered = collect(json_decode($json, true))->map(function ($array) {
if (!$array['is_lottery']) {
unset($array['price']);
}
return $array;
});
For native PHP you can do
$data = json_decode($json, true);
foreach ($data as $index => $array) {
if (!$array['is_lottery']) {
unset($array['price']);
}
$data[$index] = $array;
}
$json = [
{
"id": "3",
"title": "Boruto's Photo",
"is_lottery": 1,
"price": 10
},
{
"id": "4",
"title": "Misuki's Photo",
"is_lottery": 0,
"price": 20
}
];
$filtered = collect(json_decode($json))->map(function($value, $key) {
if (!$value['is_lottery']) {
Arr::except($value, 'price');
}
return $value;
});
you can declare new variable called $newCollection as final collection. Use foreach() to iterate your collection then delete the is_lottery from collection by using unset() then push it to $newCollection, this is example how you can delete it using foreach:
$newCollection = [];
foreach ($photos as $key => $value) {
if ($value["is_lottery"] == 0) {
unset($value["price"]);
}
array_push($newCollection,$value);
}
or you can try using forget to remove it from collection (not tested) from this ref:
How to unset (remove) a collection element after fetching it?
I have some JSON data which get from an API. I need only the products name from there. How can I get this? I am already trying with foreach loop but I can't. I am using laravel framework version 6.0
[
{
"id": 2,
"name": "Bijj",
"categories": [
{
"id": 10,
"name": "Rice",
"sbu": 2,
"products" : [
{
"id": 25,
"name": "Rajkumar",
"skus": [],
"short_description": "বাংলাদেশের আবহাওয়া উপযোগী হাইব্রিড ধান",
},
{
"id": 50,
"name": "Sera",
"skus": [],
"short_description": "বাংলাদেশের আবহাওয়া উপযোগী হাইব্রিড ধান",
}
]
},
{
"id": 20,
"name": "Vhutta",
"sbu": 2,
"products" : [
{
"id": 129,
"name": "Pack-139",
"skus": [],
"short_description": "মোচায় ৮৬ % দানা ও ১৪ % শাঁস",
},
{
"id": 125,
"name": "Don-12",
"skus": [],
"short_description": "সারা বৎসর চাষ উপযোগী",
}
]
}
]
}
]
I want to get only the all products name form there.
$getSbu = Helper::CreateGuzzleHttpClient('sbu');
foreach ($getSbu as $value) {
if($value->id == 2) {
foreach ($value->categories as $category) {
$products = $category->products;
}
}
}
After decode you can simply use this helper
use Illuminate\Support\Arr;
Arr::only($array, ['categories.products.name']);
or
Arr::only($array, ['categories.*.name']);
you want get only product's name ??
and if your data array then you have to change $value['id']
$product_names = [];
foreach ($getSbu as $value) {
if($value->id == 2) {
foreach ($value->categories as $category) {
foreach ($category->products as $product) {
$product_names[] = $product->name;
}
}
}
}
dd($product_names);
foreach (json_decode($getSbu) as $value) {
Foreach works in an array so first you must decode it in order to parse it as an array.
Since you use object parsing you don't have to use parameter true in your json_decode function. If you want an array instead of an object you can use:
foreach (json_decode($getSbu,true) as $value) {
but then you access your value like array fields, for example value['id']
Your code should look like:
$getSbu = Helper::CreateGuzzleHttpClient('sbu');
foreach (json_decode($getSbu) as $value) {
if($value->id == 2) {
foreach ($value->categories as $category) {
$products = $category->products;
}
}
}
Leverage aravel collections
// this is just ur data but as json string
$var = '[{"id":2,"name":"Bijj","categories":[{"id":10,"name":"Rice","sbu":2,"products":[{"id":25,"name":"Rajkumar","skus":[],"short_description":"বাংলাদেশের আবহাওয়া উপযোগী হাইব্রিড ধান"},{"id":50,"name":"Sera","skus":[],"short_description":"বাংলাদেশের আবহাওয়া উপযোগী হাইব্রিড ধান"}]},{"id":20,"name":"Vhutta","sbu":2,"products":[{"id":129,"name":"Pack-139","skus":[],"short_description":"মোচায় ৮৬ % দানা ও ১৪ % শাঁস"},{"id":125,"name":"Don-12","skus":[],"short_description":"সারা বৎসর চাষ উপযোগী"}]}]}]';
$objCollection = collect(json_decode($var, true));
$productNames = $objCollection->pluck('categories.*.products.*.name');
dd($productNames);
Hiii
I have 2 database tables with the columns table :1 "id, invoice_id, subject, total" table:2 "id, invoice_id, item_name, price".whenever i try to update record with the help of invoice_id if record doesn't exist in item table it will not insert new item in item table.
here i attached my JSON data
{
"date": "2019-06-08",
"client_id": "1",
"currency_id": 4,
"total_amount": null,
"subject": "RD Management",
"items": [
{
"item_name": "Saving",
"price": "500"
},
{
"item_name": "Fix",
"price": "500"
},
{
item_name": "Current",
"price": "200"
}
]
}
here one problem is also
my JSON can not send item_id also
so without item id how can i update my record...???
here 3rd item is not present in my table
here is my controller
foreach ($request->items as $key => $items)
{
$item_update = [
'item_name' => $items['item_name'],
'price' => $items['price']
];
DB::table('items')
->where('invoice_id', $id)
->update($item_update);
}
I Except output like this
"items": [
{
"id": 1,
"invoice_id": "1",
"item_name": "Saving",
"price": "500",
},
{
"id": 2,
"invoice_id": "1",
"item_name": "Fix",
"price": "500",
},
{
"id": 3,
"invoice_id": "1",
"item_name": "current",
"price": "200",
},
]
but my actual output is
"items":[
{
"id":"1"
"item_name": "Fix",
"price": "500",
},
{
"id":"2"
"invoice_id": "1",
"item_name": "Fix",
"price": "500",
}
]
this output override item_name at update time.
there are any way to solve this both problem.
If you can't identify which items already exist and which ones are new, your remaining option is to identify items by item_name+invoice_id. The downside is that you cannot update item_name this way.
If you have Eloquent models properly set up, you can use updateOrCreate().
<?php
foreach ($request->items as $key => $items)
{
$itemAfterUpdate = App\Item::updateOrCreate(
[
'invoice_id' => $id,
'item_name' => $items['item_name']
],
[ 'price' => $items['price'] ]
);
}
If not, you will basically have to do what Eloquent does behind the scenes, which is check if the item already exists based on item_name and invoice_id, and then insert or update accordingly.
<?php
foreach ($request->items as $key => $items)
{
$alreadyExists = DB::table('items')
->where('invoice_id', $id)
->where('item_name', $items['item_name'])
->exists();
}
if($alreadyExists){
DB::table('items')
->where('invoice_id', $id)
->where('item_name' => $items['item_name'])
->update(['price' => $items['price']);
}
else{
DB::table('items')->insert([
'invoice_id' => $id,
'item_name' => $items['item_name'],
'price' => $items['price']
]);
}
}
I have Models Product, ProductVariant, and Department
Department:
id | name | ....
Product:
id | name | sku | department_id | ....
ProductVariant:
id | product_id | quantity | ....
And all associated with each other like:
Relationship products: Department hasMany Products
Relationship department: Product belongsTo Department
Relationship variants: Product hasMany ProductVariants
Relationship product: Product belongsTo Product
Everything works as expected between relations over Eloquent calls
Now, using Eloquent I'm trying to retrieve a collection of following columns:
product.id | product.name | product.variant_count | product.stock | department.name
By product.stock I mean: $product->variants->sum('quantity'), but I'm having hard time getting SUM inside with() method
What I've tried so far:
$products = Product::select('id', 'name', 'sku', 'department_id') //gives product.name, sku, etc
->withCount('variants') //gives product.variants_count
->with(['variants' => function($query) {
$query->select('id', 'product_id', 'quantity'); //gives variants->each.quantity
}])
->with(['department' => function($query) {
$query->select('id', 'name'); //gives department.name
}]);
This code gives something like this:
[
{
"id": "2",
"name": "Letv LU50609 Earphone - Grey",
"sku": "PT-00002",
"department_id": "2",
"variants_count": "1",
"variants": [
{
"id": "2",
"product_id": "2",
"quantity": "35"
}
],
"department": {
"id": "2",
"name": "Phones & Tabs Accessories"
}
},
{
"id": "3",
"name": "MI In-Ear Headphones Basic 3.5mm HSEJ03JY",
"sku": "PT-00003",
"department_id": "2",
"variants_count": "5",
"variants": [
{
"id": "3",
"product_id": "3",
"quantity": "9"
},
{
"id": "4",
"product_id": "3",
"quantity": "9"
},
{
"id": "5",
"product_id": "3",
"quantity": "10"
},
{
"id": "6",
"product_id": "3",
"quantity": "7"
},
{
"id": "7",
"product_id": "3",
"quantity": "7"
}
],
"department": {
"id": "2",
"name": "Phones & Tabs Accessories"
}
}
]
But what I want to achieve is:
[
{
"id": "2",
"name": "Letv LU50609 Earphone - Grey",
"sku": "PT-00002",
"variants_count": "1",
"stock": "35",
"department": "name": "Phones & Tabs Accessories"
},
{
"id": "3",
"name": "MI In-Ear Headphones Basic 3.5mm HSEJ03JY",
"sku": "PT-00003",
"variants_count": "5",
"stock": "42",
"department": "name": "Phones & Tabs Accessories"
}
]
How can I achieve this???
Option 1
You could map() the collection before return it:
$products = Product::select('id', 'name', 'sku', 'department_id')
->withCount('variants')
->with(['variants', 'department'])
->get()
->map(function ($product){
return [
'id' => $product->id,
'name' => $product->name,
'sku' => $product->sku,
'variants_count' => $product->variants_count,
'stock' => $product->variants->sum('quantity'),
'department' => $product->department->name
];
});
Option 2
Using API Resources. Let me know if you need help in this aspect.
What about using the query builder something like this:
DB::table('products as product')
->select([
'product.id',
'product.name',
DB::raw('count(pv.id) as variant_count'),
DB::raw('sum(pv.quantity) as stock'),
'department.name'
])
->join('department', 'product.department_id', '=', 'department.id')
->join('product_variants as pv', 'product.id', '=', 'pv.id')
->get();
Not sure if this will work exactly like this, but it should give you a path.
you can access your required result with this query by checking your database tables
SELECT
products.*,
SUM(variants.available) AS stock,
COUNT(variants.id) as count,
department.name as department
FROM
products
LEFT JOIN variants ON products.id = variants.product_id
LEFT JOIN department ON products.department_id= department.id
GROUP BY
products.id
What you are looking for can be achieved in many ways. The ideal solution will build the sum within the database for best performance. To achieve so, you can use a custom query together with the Laravel query builder as already explained by #nakov or you use a little exploit of the Eloquent relationship system:
$products = Product::query()
->join('departments', 'departments.id', '=', 'products.department_id)
->withCount('variants as variant_count')
->withCount(['variants as stock' => function ($query) {
$query->selectRaw('SUM(quantity)'); // this may look weird but works
})
->select([
'products.id',
'products.name',
'departments.name as department',
])
->get();
When I execute this in my Controller
$data = User::with('teams')->find(2);
return response(['data' => $data]);
I get this as result
{
"id": 2,
"country_id": 1,
"first_name": "John",
"last_name": "Doe",
"created_at": "-0001-11-30 00:00:00",
"updated_at": "2015-02-02 23:08:21",
"full_name": "John Doe",
"teams": [
{
"id": 1,
"name": "Helpdesk medewerker",
"description": ""
},
{
"id": 2,
"name": "Retentie",
"description": ""
}
]
}
Im not interested in the full teams data, but only interested in the teamNames of the user.
I've done this by adding this
$data->each(function($user) {
$user->team_names = $user->teams->lists('name');
unset($user->teams);
});
I was wondering if this is the correct way of modifying the Eloquent result.
You can use an attribute accessor for that. Add this to your model:
protected $hidden = ['teams']; // hide teams relation in JSON output
protected $appends = ['team_names']; // add custom attribute to JSON output
public function getTeamNamesAttribute(){
return $this->teams->lists('name');
}
To change hidden and appends dynamically you can use the setter methods:
$data = User::with('teams')->find(2);
$data->setHidden(['teams']);
Filter out the columns you want in your first build.
$data = User::with(['teams' => function($query){
return $query->select('name');
}])->find(2);
Will output:
{
...
"teams": [
{
"name": "Helpdesk medewerker"
},
{
"name": "Retentie"
}
]
}
You can also use the lists method.
$data = User::with(['teams' => function($query){
return $query->lists('name');
}])->find(2);
Will output:
{
...
"teams": ["Helpdesk medewerker", "Retentie"]
}