Getting Popular Searches In Magento - magento

I want to display the top 10 searches on my Magento store. Magento already stores searches made on the store under Admin > Catalog > Search Terms, so it's just a matter of getting it into my view. Does anyone know which helper or function I can access to get this list?

You have a setPopularQueryFilter method in the class Mage_CatalogSearch_Model_Mysql4_Query_Collection, after that you only have to set a limit I guess :)
Without trying, it should be something like that :
$searchCollectino=Mage::getModel('catalogsearch/query')->getCollection()
->setPopularQueryFilter()
->setPageSize($limit);

If anyone needs the Magento 2 solution:
inject the class \Magento\Search\Model\Query in your constructor and then retrieve the collection like so:
$collection = $this->query->getSuggestCollection()
This will return a collection of most popular search terms sorted by the popularity.

Related

Magento - Get attribute options value and quantity

Hello and good day to all the members of this great community. I'm still new in PHP and especially in Magento.
I'm not posting, waiting for answers, and leaving without replying back. This is a learning process. I hope to get a great support from all of you.
I have a product. I did create custom option for the product, that is an attribute named "a_size". The attribute has value of S, M and L. Each of the value has quantity.
In the single product view, I would like to call all the available size. That is the size (S, M, or L) that has quantity more than 0. I just want to show the available size, not how much the size left.
Can anybody guide me? I'm using Magento 1.7.x and as far for this 2 weeks, I did try pretty many of suggested answers from the community thru the search function.
The replies will be much appreciated. Thank you.
There are a few things to try.
Firstly check that when you set up your new attribute in the Magento Admin (Catalog->Attributes->Manage Attribute) that in the Frontend Properties box you have set Visible on Product View Page on Front-end to yes.
To get size values I use this code:
$cabac_sizeAttribute = $_product->getAttributeText("a_size");
but I have other code for getting attribute values that goes like this:
$_product_helper = Mage::helper('catalog/output');
$temp = $_product_helper->productAttribute($_product, $_product->getASize(), 'a_size');
I think it is related to the type of attribute: text, dropdown, multiselect etc so try both and see how you get on. But really the function productAttribute() is just applying formatting. You can read the function in the file app/core/Mage/Catalog/Helper/Output.php
Also, I wonder, if you have set up a configurable product and you are on the product view page then you will be viewing the configurable product. That product won't have an a_size value: you are trying to access the a_size attribute of the simple products that make up the configurable product, yes? Everything I wrote above is (I think) correct but to get the attribute of the simple products that are part of a configured product you should study the code in the function getJsonConfig() of the file app/core/Mage/Catalog/Block/Product/View/Type/Configurable.php
And in particular to these lines:
//file: file app/core/Mage/Catalog/Block/Product/View/Type/Configurable.php
//class: Mage_Catalog_Block_Product_View_Type_Configurable
//function: getJsonConfig()
foreach ($this->getAllowProducts() as $product) {
$productId = $product->getId();
foreach ($this->getAllowAttributes() as $attribute) {
$productAttribute = $attribute->getProductAttribute();
$productAttributeId = $productAttribute->getId();
$attributeValue = $product->getData($productAttribute->getAttributeCode());
Being careful about variable naming: $product is local here, I suggest changing it, and about $this - but if you are in a .phtml of the product view for configurables then I think your $this is already Mage_Catalog_Block_Product_View_Type_Configurable
Welcome to Magento coding. You are doing well; it is a long but rewarding path. (hints: local.xml is your vital friend and so is Alan Storm if you haven't come across his content yet.)
[Additionally, (welcome to Magento) I think you are trying to say eg S and L are out of stock and M is in stock but actually the function getAllowProducts() will disallow a product with zero stock and exclude it from the returned object. You will need to use
$allProducts = $this->getProduct()->getTypeInstance(true)
->getUsedProducts(null, $this->getProduct());
(taken from function getAllowProducts() in file app/core/Mage/Catalog/Block/Product/View/Type/Configurable.php)
and then, if needed, check that each product is allowed to be shown eg status=ENABLED, and then check its stock level...
]
Malachy.
If you want to get the values of your drop down attribute use the following code
$_product->getASize();
and initially load the product object

Magento: how to get the price of a product with catalog rules applied

I'm developing a script (external to Magento, not a module) which aims to output a text list of all available products, their prices and some other attributes. However, catalog price rules don't seem to be applied to product prices. If I use any of the following:
$_product->getPrice()
$_product->getFinalPrice()
I get the normal price (without rules being applied).
If I use:
$_product->getSpecialPrice()
I get null unless the product actually has a special price inserted in the product itself (i.e. if special price is not related with catalog rules).
I also tried
Mage::getModel('catalogrule/rule')->calcProductPriceRule($product,$product->getPrice())
as suggested in the answer given by Fabian Blechschmidt, but interestingly it returns the normal price only if the product is affected by any catalog rule, returning null otherwise.
There was a similar question in StackOverflow and Magento Forums some time ago, but the provided answer (which is to insert the code bellow) doesn't work for me (returned prices remain the same).
Mage::app()->loadAreaPart(Mage_Core_Model_App_Area::AREA_FRONTEND,Mage_Core_Model_App_Area::PART_EVENTS);
Does anybody have an idea of how to achieve this?
I'm using Magento 1.6.2.0.
Thanks in advance.
Thanks to you, I found a new site:
http://www.catgento.com/magento-useful-functions-cheatsheet/
And they mentioned:
Mage::getModel('catalogrule/rule')->calcProductPriceRule($product,$product->getPrice())
HTH
As catalog price rules heavily depend on time, store and visiting customer, you need to set those parameters when you want to retrieve the product final price with it's price rules applied.
So, in your case, make sure that provided product is passed with the desired store and customer group id, which can be set as:
Mage::getModel('catalogrule/rule')->calcProductPriceRule($product->setStoreId('STORE_ID')->setCustomerGroupId('CUSTOMER_GROUP_ID'),$product->getPrice())
I discovered the problem. The discounted prices display Ok in the store frontend. The problem was that I was developing a script "external" to Magento (thus not a Magento module), something like:
<?php
set_time_limit(0);
ignore_user_abort();
error_reporting(E_ALL^E_NOTICE);
header("Content-Type: text/plain; charset=utf-8");
require_once "app/Mage.php";
// Get default store code
$default_store = Mage::app()->getStore();
...
For everything to work properly it seems that one must follow the proper Magento bootstrap, and develop everything as a module. My script was so simple that I thought it wouldn't be necessary to code a complete module. In other words, everything in Magento should really be a module.
Concluding, using the module approach, all the methods work as expected:
$_product->getPrice()
$_product->getFinalPrice()
$_product->getSpecialPrice()
Thank you all for your input.
This helped me in this issue: http://www.magentocommerce.com/boards/viewthread/176883/
. Jernej's solution seems plausible, but it does not handle rules that Overwrite other rules by using 'stop processing' and therefore can apply more than one rule.
$original_price = $_product->getPrice();
$store_id = 1; // Use the default store
$discounted_price = Mage::getResourceModel('catalogrule/rule')->getRulePrice(
Mage::app()->getLocale()->storeTimeStamp($store_id),
Mage::app()->getStore($store_id)->getWebsiteId(),
Mage::getSingleton('customer/session')->getCustomerGroupId(),
$_product->getId());
// if the product isn't discounted then default back to the original price
if ($discounted_price===false) {
$discounted_price=$original_price;
}

Magento product load - difference between loadByAttribute and load methods

today I'm fighting with Magento again :) and I found a difference between
$product = Mage::getModel('catalog/product')->loadByAttribute('sku', $product_sku);
and
$product = Mage::getModel('catalog/product')->load($product_id);
Can anyone exaplain me a difference between these two approaches? I found that when I'm loading a product by sku then when I 'try to re-save it with changed data then I get error exception 'Varien_Exception' with message 'Invalid method Varien_Object::save in app\code\core\Mage\CatalogInventory\Model\Observer.php(153): Varien_Object->__call('save', Array) that's true because once you try to load by sku then another observer sets product's stock item as Varien_Object, that looks like pitfall or I just dont understand it enough, but
I do daily Magento development from its beginnig so I know a lot about system and this is new for me. Thanks in advance, Jaro.
Interesting. While both methods will net you a single product model instance with fully loaded EAV data (provided the third parameter of loadByAttribute() is not passed or is *), the observers which add stock-related data are different for products vs. product collections, yet both stock information objects are added to the product data key "stock_item". It's debatable, but this feels like a bug. I would think that Mage_CatalogInventory_Model_Observer::saveInventoryData() or Mage_CatalogInventory_Model_Observer::_prepareItemForSave() would handle this.
You could resolve this issue by setting the product stock item fully on your product instance using the stock_item object.
loadByAttribute is a serious misnomer in my opinion because it doesn't actually trigger a load(); rather it uses getResourceCollection():
public function loadByAttribute($attribute, $value, $additionalAttributes = '*')
{
$collection = $this->getResourceCollection()
->addAttributeToSelect($additionalAttributes)
->addAttributeToFilter($attribute, $value)
->setPage(1,1);
Because it doesn't trigger the observer events associated with load() it means the resulting product object doesn't include the full set of product data you might want. In my case I needed the "description" attribute and it wasn't included.
There are several ways to resolve this:
Use a different method to load by SKU:
$product = Mage::getModel("catalog/product");
$product->load($product->getIdBySku("whatever"));
Force the desired attribute data to be included in the default product resource data by visiting Magento Admin > Catalog > Attributes > Edit attribute > "Used in Product Listing" = "Yes" and then reindexing. You should then be able to use the attribute data (in the frontend, at least) using loadByAttribute().
See also https://magento.stackexchange.com/a/197286/18855

Prestashop: Get id of parent category

I've faced the problem while coding my very first prestashop template. So what I want to do is to get the list of all sub categories which are under the same parent category. So running foreach loop I need to send parent category id.
In the internet there's not so much information about prestas' coding, modules or stuff, but I found two possible solutions.
One was: {$product->id_category_default} but that works only inside a product page (?) Maybe I'm wrong and it's possible to get a solution with this?
Another way sounds bit desperate: {$cookie->last_visited_category}
problem with this one, that it works only if you come from parent category directly, but fails when followed by direct link or any other way.
Also I was thinking of writing php function, which sends MySQL query and returns parent category id, but is this optimal way to do? Also I haven't tried writing my own php functions in smarty, seems it woks in some different way than just calling function.
So to conclude, do anyone knows how to get parent category id without separate php function and if it's so desperate, where and how to define your own php functions for smarty and how to call them.
I'm working with prestashop 1.4.
Thank you for your attention.
I've used this code in a module, you might need to adapt it but basically, the id of the parent category is stored in the database.
$parentCategoryList = array(2, 3, 4, 5);
if(!in_array($id_category, $parentCategoryList)){
$parentCategory = Db::getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS('
SELECT DISTINCT c.id_parent
FROM '._DB_PREFIX_.'category c
WHERE c.id_category = '.(int)($id_category)
);
$id_category_parent = $parentCategory[0]['id_parent'];
}
else{
$id_category_parent = $id_category;
}
In my code, the $parentCategoryList stores the id of my main categories (change it to your values). Then it checks if the category you're viewing ($id_category) is a main category. If not, it looks for the parent category in the database.
I am not really happy about the use of an array to store manually the main categories, but it works.
Hope this helps!

Get simple products belonging to configurable product AFTER configurable product save

In magento, it is possible to get the simple products associated to a configurable product by using the following call:
$childProducts = Mage::getModel('catalog/product_type_configurable')->getUsedProducts(null, $product);
I am trying to call this function after the configurable product is saved, so that I can get the new list of simple products it uses. So I am making the above call from a method that is triggered by the catalog_product_save_after event. However, after the call $childProducts stores the simple products that were associated to $product BEFORE the save operation, not AFTER it.
How could I get the simple products associated to $product after the save operation?
Thanks in advance, any suggestion is appreciated.
Magento's OOP system is very good, and this goodness sometimes creates problems for those who haven't yet gone deep into its structure.
If you closely follow the method "getUsedProducts()" in the class "Mage_Catalog_Model_Product_Type_Configurable", you will see that there are some "if" logics provided, along with the usage of its properties (like "_usedProducts", "_configurableAttributes"). These obstruct you from getting the actual result, but the fault is not of Magento, instead the fault is because of the lack of Magento documentation.
Let me clear you about the first few lines of this method:-
Varien_Profiler::start('CONFIGURABLE:'.__METHOD__);
if (!$this->getProduct($product)->hasData($this->_usedProducts)) {
if (is_null($requiredAttributeIds) and is_null($this->getProduct($product)->getData($this->_configurableAttributes))) {
// If used products load before attributes, we will load attributes.
$this->getConfigurableAttributes($product);
// After attributes loading products loaded too.
Varien_Profiler::stop('CONFIGURABLE:'.__METHOD__);
return $this->getProduct($product)->getData($this->_usedProducts);
}
....
This method has 2 arguments - "$requiredAttributeIds" (Configurable Attribute IDs) & "$product" (configurable product object).
When calling this method, you are passing "null" for the parameter "$requiredAttributeIds", but you are providing the correct Configurable Product object "$product".
This class has a property "_usedProducts" (for maintaining the data of child simple products), which is set for every Configurable Product object. If this value has earlier been set, then Magento will return you the already available values to you. This is the main reason why you are getting the child products before the configurable product was updated.
So, what you can do is you can clear the full Cache Storage, along with refreshing all the Cache processes. May be then your result will work, because internally Magento stores all these used products data in cache.
Hope it helps.

Resources