Magento product list with custom productCollection - php

For my module I need to create a custom productCollection built with various addAttributeToFilter modifiers. However, I have no idea how to get such a collection into a product list like the default magento one.
So basicly I'd like to create a pre-filtered product list, could anyone give me some advice on how to start such a thing?
EDIT: Just to clarify, I can make the collection, just not show it like the default product list.

After hours of struggling I found a solution:
I overrided Mage_Catalog_Block_Product_List and made my own _getProductCollection with:
$collection = parent::_getProductCollection();
$collection->addAttributeToFilter('attribute', array('operator' => 'value'));
/* more filters go here */
$this->_productCollection = $collection;
return $this->_productCollection;
This seemed to be the only way to get the original product list working without any errors or category problems.
With thanks to Guerra!!

use this in list.phtml:
$_productCollection->clear()
->addAttributeToFilter('attribute_set_id', array('eq' => 63))
->load();

You can try :
Mage::getModel('catalog/product')->getCollection()->addAttributeToFilter();
http://www.magentocommerce.com/wiki/1_-_installation_and_configuration/using_collections_in_magento

Related

How To Access Magento Navigation Order Property

I'm not great at Magento by any means, so I'm not looking for the perfect answer but some direction would be greatly appreciated.
In my Magento site.
Under Catalog -> Manage Categories.
You can drag and drop the categories and sub categories to reorganize them.
However this does not change the order on the frontend.
I had previously added a sorting logic to:
/app/code/core/Mage/Catalog/Block/Navigation.php
Which was added inside of the function renderCategoryMenuItemHtml
That works well to sort the categories alphabetically:
$_tmp_children = array();
foreach ($activeChildren as $child) {
if ($child->getIsActive()) {
$_tmp_children[$child->getName()] = $child;
}
}
ksort($_tmp_children,SORT_STRING);
I had assumed that just reverting to the original would have sorted by the position in the admin area, but that is not the case.
Does anyone know how the property the I could access or method I could call instead of getName() that would get the property for 'position' ?
I've tried just doing $child->position and variations of that.
Once I removed the code I mentioned (In the correct file) the problem solved itself, the Navigation sorts by position automatically.

Prestashop 1.6 product_list: get number of attached attribute combinations

I'm building my first prestashop. I have a couple of products with attribute combinations that have an impact on the price. In list views, I would like to detect if a product has more than one combination attached to it, in order to display a 'from' before the price.
I have not been able to find a way to access anything related to attributes or combinations from the product_list.tpl.
I found a function in product.php that might be suitable for what I'm trying to achieve.
public function hasAttributes()
{
if (!Combination::isFeatureActive())
return 0;
return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT COUNT(*)
FROM `'._DB_PREFIX_.'product_attribute` pa
'.Shop::addSqlAssociation('product_attribute', 'pa').'
WHERE pa.`id_product` = '.(int)$this->id
);
}
From product_list.tpl I can access other stuff inside the product class like e.g. 'features' and I was hoping to get the attributes in a similar way.
The only place I could find 'features' being declared as a variable was in the product controller, as part of this array:
$this->context->smarty->assign(array( ...
So I assumed that's the way to go, add a variable and point to the desired function inside the product class. but no matter what I enter here it just doesn't work out. What am I doing wrong? Is this the right approach at all?
Thanks in advance.
You can view the site at rhum-martinique.de
You can use the method ProductCore::getAttributeCombinaisons and check its result with the count function
Add this function to the file /config/config.inc.php
function count_product_combinations($id_product)
{
$product = new Product($id_product);
return count($product->getAttributeCombinaisons(Context::getContext()->language->id));
}
Add this code to your tpl file:
{if count_product_combinations($product.id_product) > 1}
<span class="price-prefix">{l s='From'}</span>
{/if}

Magento load product collection with all attributes

I need to iterate over some products and access custom attributes, my code is:
$collection = Mage::getModel('catalog/product')
->getCollection()
->addAttributeToSelect('*')
->addAttributeToFilter(array(array('attribute' => 'status', 'eq' => '1')))
// more filters
->load();
then I have to:
foreach ($collection as $product) {
// here I can't access custom attributes
$product = Mage::getModel('catalog/product')->load($product->getId());
// here I can access them
}
and my problem is when I have a lot of products my script spends a lot of time in foreach loop. Can I somehow speed this by loading collection with all attributes?
I suggest all your attributes should go in flat tables.
So do some attributes setting like searchable, available in front end listing.
Then do an indexing.
Now when you get product collection you will get needed attributes and then code from there.
Instead of a loop loading each product you need to load a collection of products.
If you are using flat-tables, you have to add your custom attributes to the flat index. You can add them in the config.xml of the according module.
You can than skip the productload in the foreach which is probably causing the long processing time.
What you are doing is not a good practice and should be avoided. You may try this
foreach($collection->getItems() as $item){
echo $item->getName(); //$item is product instance. you can use it
}
EDIT
In your question, you are doing a serious mistake and it should be avoided. That is what I am trying to point out through my answer.
See what you are doing here.
foreache($bigcollection as $singleone){
$product = Mage::getModel('catalog/product')->load($id);
}
Basically you are loading a product inside a big for loop. It is a big mistake. Because if you do this, Magento need to do "extra fetching works" from database. Do not use that method. Through my solution, I showed you how to avoid loading a product inside a forloop. It is much reliable method.
If you dont want to use forloop, I think you need to edit your question and put that requirement there.
If you need to avoid for loop, you need to go for flat table concepts. That is the only one way that I know. Otherwise you cannot avoid a for each loop. :)

Magento Adminhtml Grid using sales/order_item collection filtered by customer

My objective is simple. I have a module called Quotes, I have managed to get Magento to create a new quote record each time a cart is created by changing the is_active column when a quote is 'checked out'. So I have a bunch of quotes each related to a customer and i have sales/order_item rows each related to a quote.
I have a page in the backend which displays a grid of all the quotes. When a quote is clicked, the edit page has two tabs, one with a Form.php showing the details of the quote. (customer name, date etc), then I have another tab which should contain a grid of all the items in that quote. It seems so simple:
$this->addTab("items_section", array(
"label" => Mage::helper("quote")->__("Quote Items"),
"title" => Mage::helper("quote")->__("Quote Items"),
"content" => $this->getLayout()->createBlock("quote/adminhtml_quotes_edit_tab_cart")->toHtml(),
));
Then in my cart block I have this:
protected function _prepareCollection()
{
$collection = Mage::getModel('sales/order_item')->getCollection();
print_r($collection);
$this->setCollection($collection);
return parent::_prepareCollection();
}
I'm not even interested in loading the correct collection (by order_id) because there is a problem ro be solved here first: The print_r statement reveals the collection I specified but passing it to $this->setCollection($collection) gives me 'No records found' rendered in the grid. In typical Magento fashion there are no errors etc. I understand that the model is supposed to query the database as needed but that doesn't seem to be happening. I suppose it's time to read Mage::core files but you can imagine my frustration at such a simple tasking being so complicated so I would appreciate it if anyone who knows what's going on here can help me out. Thanks in advance.
I may be wrong, but you can't setCollection() on a quote with sales order items. It has to be populated with sales/quote model items.
I don't know what the scope of $this is in _prepareCollection() but i'm assuming since its on the cart block, its dealing with a quote.
Just a hint, you might instead of print_r($collection), try doing this...
echo "<pre>";
foreach ($collection as $item) {
var_dump($item->debug());
}
It supplies pretty much just the important info instead of the database structure. You can also check your item type and make sure you are using the correct model for your setCollection method. You can also throw a break; in there if you want to just get the first item etc. Debugging magento objects can be tedious, and i've found that this helps.
Our head developer managed to help me get it working. We're still not sure why but this seemed to work
protected function _prepareCollection()
{
$quoteId = $this->getRequest()->getParam('id');
$quote = Mage::getModel('sales/quote')->getCollection()->addFieldToFilter('entity_id', $quoteId);
if ($quote->getFirstItem()->getId()) {
$collection = $quote->getFirstItem()->getItemsCollection(false);
}
$this->setCollection($collection);
return parent::_prepareCollection();
}

Magento ->getSku() or getData(’sku’) returns empty string

I have Magento 1.3.2 and I have weird issue:
When I am in list.phtml, and I try to fetch the SKU by using getSku() or getData('sku') I get empty string. getName() does work. However, when I do that from other pages, it works well.
I var_dump-ed it and no SKU is shown.
What can cause this?
I'm surprised nobody has given you the easiest and most proper answer yet:
Go to your admin, Catalog >> Attributes >> Manage Attributes. Then edit the 'sku' attribute. Change the "Used in Product Listing" from 'No' to 'Yes'. You will then have access to it from the product object in list.phtml with ->getSku()
The other option is to re-load the product object in the list.phtml using the ID of the product you already have. The code reads something a little like:
$sku = Mage::getModel('catalog/product')->load($_product->getId())->getSku();
Note that $_product is what you are getting in your collection already, and note that getSku is case sensitive (as are all Magento attributes getter/setters).
#Prattski's solution is preferable as you don't really want to be messing with loading/manipulating the objects, but it sounds as though your collection is a little messed up. SKU is one of the core fields that exists in the base catalog_product_entity table, so would be unusual not to be loaded.
Probably sku is not added to the list of attributes when a collection is retrieved. I assume you are talking a bout the file /template/catalog/product/list.phtml. If so, then you need to extend the corresponding code file (/app/code/core/Mage/Catalog/Block/Product/List.php).
I think your best bet is to overload the getLoadedProductCollection() method to:
public function getLoadedProductCollection()
{
return $this->_getProductCollection()->addAttributeToSelect('sku');
}
This might not work, I have not been able to test it, as in my store the sku and all other attributes are accessible in the list.phtml template file.
Try this:
<?php
$current_product = Mage::registry('current_product');
if($current_product) {
$sku = $current_product->getSku();
// output sku
echo $sku;
}
?>
I had same problem too but tried $_product['sku']
it works for me
$_product["sku"]; enough to get the product sku.

Categories