I am trying to sort out items in cart by categroy_id:
$cartItems = Mage::getModel("checkout/cart")->getItems()
->addFieldToSelect('name')
->addFieldToSelect('category_id')
->addAttributeToSort('category_id', 'ASC');
echo $cartItems->getSelect(); //debug info
foreach($cartItems as $item) {
echo $this->getItemHtml($item);
}
Magento complaints that method addAttributeToSort does not exists, had a look and of course it isn't defined.
What is the proper way of doing this query?
Otherwise,
you can try the following code:
$collection = Mage::getModel('checkout/cart')->getItems()
->addFieldToSelect('name')
->addFieldToSelect('category_id')
->addOrder('category_id', 'asc');
addAttributeToSort() does work on certain collections, but not the checkout/cart Model.
I hope this helps!
When you run Mage::getModel("checkout/cart")->getItems() you get a collection of quote items, not products. So there is no category_id on the table sales_flat_quote_item that you can access.
If you want access to the product you have to loop your collection of quote items and run ->getProduct() on each item. Then you could call functions on the product, like ->getCategoryIds() to get a list of category ids that has the product assigned to it.
Related
I am trying to display all products on my website in every category by descending SKU #'s. Can't seem to figure out how to do this, any ideas?
The following snippet will give you the collection you want, you may need to add pagination yourself if necessary.
$collection = Mage::getModel("catalog/product")->getCollection();
$collection->setOrder('sku', 'DESC');
You'll also need to join on any extra attributes with joinAttribute(), since the catalog_product database storage follows the EAV pattern.
I think this should help. Go to Admin->Catalog->Attributes->Manage Attributes find SKU and enable SKU first. Then you have to go app/code/core/Mage/Catalog/Block/Product/List/Toolbar.php. Find at line 119 and change
protected $_direction = 'asc';
Change to
protected $_direction = 'desc';
I want to sort a product collection that is already loaded by
$_productCollection = $this->getLoadedProductCollection();
The default sort in admin Magento is Style attribute
I want to sort first by Style, then by color and then by name.
I've try
$_productCollection->setOrder(array('style', 'color','name'), asc);
and also
$_productCollection->addAttributeToSort('color', Varien_Data_Collection::SORT_ORDER_ASC);
$_productCollection->addAttributeToSort('name', Varien_Data_Collection::SORT_ORDER_ASC);
but is not working.
The default sort is working good. Can someone please help?
You can do it this way:
$_productCollection = $this->getLoadedProductCollection();
$_productCollection->clear();
$_productCollection->addAttributeToSort('color', Varien_Data_Collection::SORT_ORDER_ASC);
foreach ($_productCollection as $product) {
// ...
}
This way the collection is forced to be reloaded and then your custom sorting is applied.
You can also take clone of the loaded collection and then modify the query as you want.
// clone of the current collection.Better way of modifying the colection
$_productCollection = clone $this->getLoadedProductCollection();
// unset the cuurent coolection and append your custom filter.
$_productCollection->clear()
->addAttributeToFilter('color', Varien_Data_Collection::SORT_ORDER_ASC)
->load();
Nothing here or elsewhere worked for me. No matter what I tried it would just not sort on /Magento_Catalog/templates/product/list.phtml using 'getLoadedProductCollection()'. Also had a weird issue where products would disappear after clearing cache, until a reindex was done. No idea what was going on there, something was not right.
So I got it to work in the hacky way below (Yes I know it's not 'best practice' to use object manager but it was the only thing that worked!!)
$_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$categoryId = 2;
$category = $_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
$productCollection = $_objectManager->create('Magento\Catalog\Model\ResourceModel\Product\CollectionFactory');
$_productCollection = $productCollection->create()
->addAttributeToSelect('*')
->setOrder('position', 'ASC')
->addCategoryFilter($category)->load();
If you have products in a collection that need more advanced sorting/oordering you can move the products to an assoc array which is much easier to sort/order as you like. Once the order is as you like you can add them back by first clearing your collection with $collection-removeAllItems() and then iterate your array as $product and move each product back to the collection with $collection->addItem($product);
I used this when I wanted a sticky that was not touched by different ordering/sorting.
You can use setOrder on collection to sort any collection data like below :
$_productCollection->setOrder('id','DESC');
Where id can be replace with your column name, & second parameter can be DESC & ASC as per your requirement.
Have it working in v2.3.7 using the following
$_productCollection = $block->getLoadedProductCollection();
$_productCollection->getSelect()->reset(Zend_Db_Select::ORDER);
$_productCollection->setOrder('price', 'ASC');
I am working on assignment where I need to have unassign the category previous products & need to dynamically assign the bestseller products(top 20)..I am using following code for that:-
$_productCollection = Mage::getModel("catalog/product")->getCollection()
->addAttributeToSelect(array('name', 'price', 'small_image'))
->addAttributeToSort("entity_id","DESC")
->setVisibility(Mage::getSingleton('catalog/product_visibility')->getVisibleInSiteIds())
->setPageSize($productCount);
// Delete Existing Mapped product from Category
$delQuery = 'Delete from catalog_category_product where category_id ='.$catId;
$writeConnection->query($delQuery);
foreach($_productCollection as $product){
$categoryIds = $product->getCategoryIds();
if (!in_array($catId, $categoryIds)) {
$write->query("replace into
`catalog_category_product` (category_id,product_id,position)
VALUES (?,?,0)",array($catId,$product->getEntityId()));
}
}
$process = Mage::getModel('index/indexer')->getProcessByCode('catalog_category_product');
$process->reindexAll();
$category->save();
Code is working fine but once the dynamic products are assigned to that specific category backend sorting (Default Product List Sort By) for that category products stopped working..I doubt it may be because position is 0 for each replaced product in my query but not yet sure.
If anybody have any suggestions it would be really helpful.
The position you have entered in the table is 0 for all products. Magento will then by default sort the products by the order they have been inserted into the category table rather than position.
You need to modify the position accordingly for every product to be able to display them as per default sorting(which is done using position attribute).
I am trying to get the associated products from a grouped product.I can do that, but not for the products that they are disabled. I tried a solution which mention to set : Use Flat Catalog Product to "NO" but i still can't. Any other ideas? I tried load a collection and use filters like IS_ENABLED OR DISABLED and by loading Models like
$product = Mage::getModel('catalog/product')->load($id);
$associatedProducts = $product->getTypeInstance(true)->getAssociatedProducts($product);
Any other ideas?
So lets look at the getAssociatedProducts() method of Mage_Catalog_Model_Product_Type_Grouped class. Here's the interesting part of it:
if (!Mage::app()->getStore()->isAdmin()) {
$this->setSaleableStatus($product);
}
$collection = $this->getAssociatedProductCollection($product)
->addAttributeToSelect('*')
->addFilterByRequiredOptions()
->setPositionOrder()
->addStoreFilter($this->getStoreFilter($product))
->addAttributeToFilter('status', array('in' => $this->getStatusFilters($product)));
As you can see Magento adds status to collection filter. Method getStatusFilters() returns product statuses to apply on filter. If you would look at the body of this method you would see that it returns basically $product->getData($this->_keyStatusFitlers).
This method needs to return 2 values (2 statuses). But it doesn't. Responsible for that is if statement before the collection set up:
if (!Mage::app()->getStore()->isAdmin()) {
$this->setSaleableStatus($product);
}
This parts will set only ENABLED status on the product status filters.
If you want to get disabled products from grouped product you have rewrite Mage_Catalog_Model_Product_Type_Grouped class and remove the if statement and/or set proper filters.
Let me know if you don't know how to rewrite a Magento class, then I will extend this answer.
I am trying to get the entire magento product collection, without any filters or restrictions, but I fail to get all products.
I've tried various methods already, but they all give me a very limited selection of products. Let's say the store contains 5000 products, but it only shows 500. When I check the catalog -> products is does show me the entire list.
Mage::getModel('catalog/product')->getCollection();
Mage::getResourceModel('catalog/product_collection')->addAttributeToSelect('*');
Mage::getModel("catalog/product")->getResourceCollection()->load();
All of them return the same amount (500), while I expect it to give me 5000 products. I would prefer not to use Zend or PHP and just stick to the Magento way to get them.
Does anyone know how to really get ALL products or can point me in the right direction why this isn't working?
The select-string that is returned is:
SELECT 1 AS `status`, `e`.`entity_id`, `e`.`type_id`, `e`.`attribute_set_id` FROM `catalog_product_flat_4` AS `e`
//to overwrite limit but you need first to increase your memory limit
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('*') // select all attributes
->setPageSize(5000) // limit number of results returned
->setCurPage(1); // set the offset (useful for pagination)
// we iterate through the list of products to get attribute values
foreach ($collection as $product) {
echo $product->getName(); //get name
echo (float) $product->getPrice(); //get price as cast to float
echo $product->getDescription(); //get description
echo $product->getShortDescription(); //get short description
echo $product->getTypeId(); //get product type
echo $product->getStatus(); //get product status
// getCategoryIds(); returns an array of category IDs associated with the product
foreach ($product->getCategoryIds() as $category_id) {
$category = Mage::getModel('catalog/category')->load($category_id);
echo $category->getName();
echo $category->getParentCategory()->getName(); // get parent of category
}
//gets the image url of the product
echo Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA).
'catalog/product'.$product->getImage();
echo $product->getSpecialPrice();
echo $product->getProductUrl(); //gets the product url
echo '<br />';
}
And something like this:
$products = Mage::getModel('catalog/product')->getCollection();
foreach($products as $prod) {
$product = Mage::getModel('catalog/product')->load($prod->getId());
}
With this method I get more than 500 but all my product...
Several possibilities here:
1. Some inner limitation, like 500 at all.
2. Some paging limitation. Products per page(in db abstract)
3. Some lazyload limitation.
Perhaps, there is some over problem, but I think this is some inner limit.
Turn off your flat_catalog_product in admin > system > configuration > catalog > catalog. After this you will get a full product collection. Even though this is a workaround, it helped me to achieve what I needed to achieve.
You might be using Flat Catalog Product Structure . This create separate table for each store view.
Use Code below to print sql query . you will see the collection is coming from flat table like
catalog_product_flat_38
echo Mage::getModel('catalog/product')->getCollection()->getSelect();
try using
Mage::app()->setCurrentStore('0');
// same as
Mage::app()->setCurrentStore(Mage_Core_Model_App::ADMIN_STORE_ID);
this hepled me