I'm trying to make a collection from some arrays of data:
$myCollection = collect(
['product_id' => 1, 'price' => 200, 'discount' => '50'],
['product_id' => 2, 'price' => 400, 'discount' => '50']
);
When I loop out I would like to do:
foreach ($myCollection as $product) {
echo $product->price;
echo $product->discount;
}
But the underlying elements appear to still be in an arrays format, how can I achieve the above output?
If you want the inner arrays to be a collection, then you can do so as follows:
$myCollection = collect([
['product_id' => 1, 'price' => 200, 'discount' => '50'],
['product_id' => 2, 'price' => 400, 'discount' => '50']
])->map(function($row) {
return collect($row);
});
If you want the inner arrays to be objects, then you can do as follows:
$myCollection = collect([
['product_id' => 1, 'price' => 200, 'discount' => '50'],
['product_id' => 2, 'price' => 400, 'discount' => '50']
])->map(function($row) {
return (object) $row;
});
You can also iterate over each of the results...
$myCollection = collect([
['product_id' => 1, 'price' => 200, 'discount' => '50'],
['product_id' => 2, 'price' => 400, 'discount' => '50']
])->map(function($row) {
return (object) $row;
})->each(function($row) {
echo sprintf('ProductId: %d, Price: %d, Discount: %s'.PHP_EOL, $row->product_id, $row->price, $row->discount);
});
Output:
ProductId: 1, Price: 200, Discount: 50
ProductId: 2, Price: 400, Discount: 50
Simple as you are getting a collection of an associative arrays because you are collecting arrays elements, so the collection helper doesn't want to modify it in case you need it as array.
Knowing this, if you want to collect objects you should pass an element of object type.
You can cast object data type into the array, like this:
$myCollection = collect( (object) array(
(object) ['product_id' => 1, 'price' => 200, 'discount' => '50'],
(object) ['product_id' => 2, 'price' => 400, 'discount' => '50'])
);
Then you have a collection of objects !
Function collect() takes array of elements. You can fix your code also by enclosing all the elements into [] and then converting Collection elements to objects instead of leaving them to be arrays
$myCollection = collect([
(object)(['product_id' => 1, 'price' => 200, 'discount' => '50']),
(object)(['product_id' => 2, 'price' => 400, 'discount' => '50'])
]
);
foreach ($myCollection as $product) {
echo $product->price;
echo $product->discount;
}
There's a syntax error in your collection definition:
$myCollection = collect([
['product_id' => 1, 'price' => 200, 'discount' => '50'],
['product_id' => 2, 'price' => 400, 'discount' => '50']
]);
Also, since you're using a Collection, you no longer need to use a foreach loop:
$myCollection->each(function ($item) {
echo $item['price'];
})
Related
I have the following collection
$collection = collect([
['id' => 1, 'name' => 'Design'],
['id' => 2, 'name' => 'Art'],
['id' => 3, 'name' => 'Comms'],
['id' => 2, 'name' => 'Art'],
['id' => 3, 'name' => 'Comms'],
['id' => 3, 'name' => 'Comms'],
]);
I want only unique items in the collection and the collection should be sorted by number of duplicates. So an item which has most number of duplicates must appear on top as follows
$collection = collect([
['id' => 3, 'name' => 'Comms'],
['id' => 2, 'name' => 'Art'],
['id' => 1, 'name' => 'Design'],
]);
I can remove duplicates using unique method but cannot find a want to sort them.
You can do it with mapWithKeys()
https://laravel.com/docs/8.x/collections#method-mapwithkeys
$collection = $collection->groupBy('id')->mapWithKeys(function (Collection $row) {
return [$row->count() => $row->first()];
})->sortKeysDesc();
I'm trying to use Laravel collections for a simple case. I'm building a collection of furniture items and I would like to amend the item lines with additional information afterwards :
$collection = collect([
['name' => 'Desk', 'color' => 'Black'],
['name' => 'Chair', 'color' => 'Black'],
['name' => 'Bookcase', 'color' => 'Red'],
]);
I would like to add a 'stock_value' field for some items, based on the item key 'name' (for instance). In the end, I would like the collection to become something like :
['name' => 'Desk', 'color' => 'Black', 'stock_value' => 4],
['name' => 'Chair', 'color' => 'Black'],
['name' => 'Bookcase', 'color' => 'Red', 'stock_value' => 9]
I don't know how to achieve that. Any help would be greatly appreciated.
$stockValue = 9;
return $collection->transform(function ($array) use ($stockValue) {
if ($array['name'] === 'Desk') {
$array['stock_value'] = $stockValue;
}
return $array;
});
You may use transform to modify your collection.
i was finding method for fetching item in collection by specific key and value, and i have found one which is where(),
But i also want to delete that item after fetching it from original collection, but i couldn't find any method which can do both.
i have seen pull() method but it fetches by key and removes that column from collection but i want to remove particular item only.
I have looked in collection doc, but couldn't find any native method so i am using 2 method to achieve that need, the code is as below:
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]);
$filtered_items = $collection->where('price', 100);
$filtered_collection = $collection->whereNotIn('price', [100]);
i am thinking that above 2 method will be little overhead if i can accomplish it in one method, so i am looking for other solutions guys, thanks beforehand your answers.
You need this one https://laravel.com/docs/5.5/collections#method-partition
$collection = collect([
['product' => 'Desk', 'price' => 200],
['product' => 'Chair', 'price' => 100],
['product' => 'Bookcase', 'price' => 150],
['product' => 'Door', 'price' => 100],
]);
$filtered_items = $collection->where('price', 100);
list($neededCollection, $filteredCollection) = $collection->partition(function ($i) {
return $i['price'] == 100;
});
dd($neededCollection, $filteredCollection);
result like this
This is my query:
$productItems = ProductItemResource::collection(ProductItem::where('pd_id', $id)->get());
The output of query is this:
$output = [[
'id' => 1,
'serial' => "XXXXXXAA1",
'pd_item_info' =>[
'id' => 1,
'quantity' => 5,
'product_info' => [
'id' => 1,
'product_name' => 'Keyboard'
],
]
],[
'id' => 2,
'serial' => "XXXXXXAA2",
'pd_item_info' =>[
'id' => 2,
'quantity' => 10,
'product_info' => [
'id' => 2,
'product_name' => 'Monitor'
],
]
]];
This is my condition:
foreach ($output as $productItem) {
return $productItem->pd_item_info->product_info['product_name'];
// IT HAS AN ERROR WHERE I CAN'T ACCESS THE OBJECT OF OBJECT
}
Why I'm getting error accessing object of object when I use resource?
that the result is an array is not an object.
foreach($output as productItem) {
return $productItem['pd_item_info']['product_info']['product_name'];
}
Why you create a new collection?
$productItems = ProductItemResource::collection(ProductItem::where('pd_id', $id)->get());
Result of query already is collection
ProductItem::where('pd_id', $id)->get()
I need to Create Coupons in Magento on Action of account Create.
I have created observer which is executing properly on account Create but i am Struggling with Coupons create. I have fixed coupon names on of fixed amount on applicable on cart subtotal.
I found many ans but none of them has anything about expiry of coupon
No replies yet :(
Though I found the solution.
$customer = $observer->getCustomer()->getData();
$email = $customer['email'];
$email100 = $email.'-100-1';
$datei=date('d/m/Y');
$datee = date('d/m/Y', strtotime('1 day'));
$firstname=$customer['firstname'];
$couponcode1=$email.'100-1';
$data = array(
'product_ids' => null,
'name' => sprintf('coupon-100-1', Mage::getSingleton('customer/session')->getCustomerId()),
'description' => null,
'is_active' => 1,
'website_ids' => array(1),
'customer_group_ids' => array(1),
'coupon_type' => 2,
'coupon_code' => $email100,
'uses_per_coupon' => 1,
'uses_per_customer' => 1,
'from_date' => $datei,
'to_date' => $datee,
'sort_order' => null,
'is_rss' => 1,
'test' => 'test',
'rule' => array(
'conditions' => array(
'1' =>array(
'type' => 'salesrule/rule_condition_combine',
'aggregator' => 'all',
'value' => 1,
),
'1--1' => array(
'type' => 'salesrule/rule_condition_combine',
'aggregator' => 'all',
'value' => 1,
),
'1--1--1' =>array(
'type' => 'salesrule/rule_condition_address',
'attribute' => 'base_subtotal',
'operator' => '>=',
'value' => '400'
),
'1--1--2' =>array(
'type' => 'salesrule/rule_condition_combine',
'aggregator' => 'all',
'value' => 0
),
'1--1--2--1' =>array(
'type' => 'salesrule/rule_condition_product_found',
'value' => 1,
'aggregator' => 'all'
),
'1--1--2--1--1' => array(
'type' => 'salesrule/rule_condition_product',
'attribute' => 'special_price',
'operator' => '>=',
'value' => 0
)
),
'actions' => array(
'1' =>array(
'type' => 'salesrule/rule_condition_combine',
'aggregator' => 'all',
'value' => 1,
'new_child' => null
),
)
),
'simple_action' => 'cart_fixed',
'discount_amount' => 100,
'discount_qty' => 0,
'discount_step' => null,
'apply_to_shipping' => 0,
'simple_free_shipping' => 0,
'stop_rules_processing' => 0,
'store_labels' => array()
);
$model = Mage::getModel('salesrule/rule');
$validateResult = $model->validateData(new Varien_Object($data));
if ($validateResult !== true) {
foreach($validateResult as $errorMessage) {
// print_r($errorMessage);
$session->addError($errorMessage);
}
}
if (isset($data['rule']['conditions'])) {
$data['conditions'] = $data['rule']['conditions'];
}
if (isset($data['rule']['actions'])) {
$data['actions'] = $data['rule']['actions'];
}
unset($data['rule']);
//print_r($data);
$model->loadPost($data);
$model->save();
Here the name of coupon code is email id followed by -100-1.
$datei and $datee are the initial date and the expiry date. I have customized the coupon code so that it is not being used if the cart contains special price item.
Fixed amount discount is applied on the complete cart subtotal.
In Case of query do respond.