Magento: Proper way to iterate over a Varien Object collection - magento

If I were to create a collection that would retrieve all products belonging to category with a given ID, as below:
$storeId = Mage::app()->getStore()->getId();
$product = Mage::getModel('catalog/product');
$category = Mage::getModel('catalog/category')->load(39);
$catName = $category->getName();
$visibility = array(
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
);
$products = $product->setStoreId($storeId)
->getCollection()
->addAttributeToFilter('visibility', $visibility)
->addCategoryFilter($category)
->addAttributeToSelect(array('name'), 'inner')
->setOrder('name', 'asc')
;
$collection = $products;
How would I then iterate over the collection and access each item's data, item being a product in this case.
I would have expected something like the below to give me each items available data but doesn't seem to work:
foreach ($collection as $key => $value) {
var_dump($value->getData());
}

You're close. Try doing
foreach ($collection as $obj) {
echo $obj->getName();
}

Related

Get order items (products) by Order number

Here I show how to get items from a Order by the order number id:
$order = Mage::getModel('sales/order')->load($order_id);
$items = $order->getAllItems();
$itemcount = count($items);
$name = array();
$unitPrice = array();
$sku = array();
$ids = array();
$qty = array();
foreach ($items as $itemId => $item) {
$name[] = $item->getName();
$unitPrice[] = $item->getPrice();
$sku[] = $item->getSku();
$ids[] = $item->getProductId();
$qty[] = $item->getQtyToInvoice();
}
How can I do the same but in SQL, get all the items information (name, price, image..) by order number id.
// getSelect() method allowed for order collection only so you can print query for specific order as as below.
$order_id = 12345;
$orders = Mage::getResourceModel('sales/order_collection')
->addAttributeToSelect('*')
->addAttributeToFilter('entity_id', $order_id);
echo $orders->getSelect();
Use sql query like :
This is for select item name and data
select sales_flat_order.entity_id,sales_flat_order.increment_id,sales_flat_order_item.item_id, sales_flat_order_item.sku, sales_flat_order_item.name from sales_flat_order right join sales_flat_order_item on sales_flat_order.entity_id = sales_flat_order_item.order_id where increment_id = 100000042

How to load multiple category id in magento?

Hi i want to load multiple category id in magento, i used in this but it fetch only 1st category of subcategory not rest of category.
$category = $model->load(79,80,91);
You can use this:
$categories = array(1,2,3);
$category = Mage::getModel('catalog/category')->getCollection()->addAttributeToFilter('entity_id', array('in'=>$categories));
foreach($category as $categorys) {
//or do Somthing
}
you have to use collection instead of load
$collection = Mage::getModel('catalog/category')->getCollection()
->setStoreId(Mage::app()->getStore()->getId())
->addAttributeToSelect('name')
->addIdFilter(array(79,80,91))
->addAttributeToFilter('is_active', 1)//get only active categories if you want
->addAttributeToSort('position', 'desc'); //sort by position
and then you can use loop throw
foreach($collection as $category) {
echo $category->getName()
}
hope this will work for you.
you can use this,
$categories = array(10,13);
$_category = Mage::getModel('catalog/category');
$cats = $_category->getCollection()->addAttributeToFilter('entity_id', array('in'=>$categories));
foreach($cats as $cat) {
Zend_Debug::dump($cat);
//or
// do Somthing
}

Magento: How to limit a collection (sales/order) by a certain category?

I'm trying to limit order for admin users by category, I can find the collection of product id by category and collect sales/order but how can I use this with an event observer?
$category_id = 44;
$category = Mage::getModel("catalog/category")->load($category_id);
$products = Mage::getModel("catalog/product")->getCollection()
->addCategoryFilter($category);
Next I collect just the product ids so I can use them:
$product_ids = array();
foreach ($products as $product)
$product_ids[] = $product->getId();
$items = Mage::getModel("sales/order_item")->getCollection()
->addFieldToFilter("product_id", array("in" => $product_ids));
You can use SetPageSize and SetCurPage for that
$col = Mage::getModel('YOUR MODEL')
->getCollection()
->setPageSize(17)
->setCurPage(1);
HTH

magento product collection with specific id

i select products with
$products = Mage::getModel('catalog/product')->getCollection()->addAttributeToFilter('entity_id', array('in' => $productIds));
how can i archieve that the collection is in the same order as the ids in $productIds?
thanks
$productIds = array(1,3,2);
$products = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id', array('in' => $productIds));
$products->getSelect()->order("find_in_set(entity_id,'".implode(',',$productIds)."')");
foreach($products as $product)
{
echo $product->getEntityId();
echo $product->getSku();
}
See more #
Magento get a product collection in an arbitrary order
How to select mysql rows in the order of IN clause

Magento - Collection Filter by Array Keep Order

Is it possible to filter a Magento collection using an array of id's BUT have the collection results ordered by the order of the id's passed to the filter.
For example:
$collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToFilter('entity_id', array(
'in' => array(1, 3, 2),
));
I would like the collection to have products in order, 1,3,2 so as when looping through the collection they come out in that specific order?
The only alternative i currently have is to manually create an array of products:
$productIds = array(1,3,2);
$collection = array();
foreach($productIds as $productId) {
$collection[] = Mage::getModel('catalog/product')->load($productId);
}
This obviously works but seems like an ugly way to do this.
is there a way to do this purely via magento collections?
$productIds = array(1,3,2);
/**
* Build up a case statement to ensure the order of ids is preserved
*/
$orderString = array('CASE e.entity_id');
foreach($productIds as $i => $productId) {
$orderString[] = 'WHEN '.$productId.' THEN '.$i;
}
$orderString[] = 'END';
$orderString = implode(' ', $orderString);
/**
* Filter the collection
*/
$productCollection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id', array('in' => $productIds));
/**
* Apply the order based on the case statement
*/
$productCollection->getSelect()
->order(new Zend_Db_Expr($orderString))
Pretty old but a simple solution I found on stackoverflow is
$productIds = array(1,3,2);
$products = Mage::getModel('catalog/product')->getCollection()
->addAttributeToFilter('entity_id', array('in' => $productIds));
$products->getSelect()->order("find_in_set(entity_id,'".implode(',',$productIds)."')");
from here on stackoverflow
You can load the collection before sorting it in PHP. Eg :
$result = array();
$productIds = array(1,3,2);
$collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToFilter('entity_id', array('in' => $productIds))
->load();
foreach ($productIds as $productId) {
if ($product = $collection->getItemById($productId)) {
$result[$productId] = $product;
}
}
Else, purely with collections, you should first pass by the Zend_Db_Select object of the collection, to be able to sort on expressions (what may not be possible with eg EAV based collections and calls to addAttributeToSort or sortOrder).
Then you can either use multiple order calls as stated in Gershon's answer, or use a single order with a generated CASE WHEN THEN statement. Knowing that it could depend on the maximum number of IDs you may have to filter on.
This is a challenging question, here is a solution that should work:
$collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToFilter('entity_id', array(
'in' => array(1928, 1930, 1929),
))
->addAttributeToSort('entity_id = 1928', 'ASC')
->addAttributeToSort('entity_id = 1930', 'ASC')
->addAttributeToSort('entity_id = 1929', 'ASC')
;

Resources