magento showing wrong product count in category - magento

I have a strange issue and seems many are having the same on internet. Below picture will define my issue and also my magento version is 1.7
As I have highlighted, LEFT says the category has 16 products, but in actual the Category Products Tab shows 15 products. All my categories are messed up. Please let me know what's going wrong. I've tried disabling the cache, but it didn't worked.
[Edit]
I tried removing one-product from the category, then the number on the left went to 15 and total records 14. So I thought may be a product whose is disabled in there in this category. But when I searched for disabled products none were there.

This will fix them all.
DELETE FROM
catalog_category_product
where product_id NOT IN (SELECT entity_id FROM (catalog_product_entity))
Then, implement the solution in the observer to keep it from happening again.

Hi product count comes from method name loadProductCount which is located at location code/core/Mage/Catalog/Model/Resource/Category/Collection.php
If you will dig in deep this count is coming from a join query between two tables: catalog_category_product and catalog_category_entity
I have fixed this issue by using event observer. you can do the same for time being. And let me know if you find any better solution.
public function deleteCountCategory (Varien_Event_Observer $observer) {
try {
$product = $observer->getEvent()->getProduct();
$productId = $product->getId();
$resource = Mage::getSingleton('core/resource');
$writeConnection = $resource->getConnection('core_write');
$tableName = $resource->getTableName('catalog_category_product');
$query = "DELETE FROM {$tableName} WHERE product_id = ".(int)$productId;
$writeConnection->query($query);
} catch (Exception $e) {
throw $e;
}
return $this;
}
Event used in config.xml
<events>
<catalog_product_delete_after> <!-- identifier of the event we want to catch -->
<observers>
<catalog_product_delete_after_handler> <!-- identifier of the event handler -->
<type>model</type> <!-- class method call type; valid are model, object and singleton -->
<class>countfix/observer</class> <!-- observers class alias -->
<method>deleteCountCategory</method> <!-- observer's method to be called -->
<args></args> <!-- additional arguments passed to observer -->
</catalog_product_delete_after_handler>
</observers>
</catalog_product_delete_after>
</events>

A simple solution to this is go to app/code/core/Mage/Catalog/Model/Category.php
or it's better to create a local file so that it doesn't effects while magento upgrade. So create
app/code/local/Mage/Catalog/Model/Category.php
In this model create a new function say getFrontentProductCount()
public function getFrontentProductCount()
{
$collection = Mage::getResourceModel('catalog/product_collection')
->addCategoryFilter($this);
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
return $collection->count();
}
Now go to your template phtml file where you execute your category product count. In general case it's: theme/template/catalog/navigation/left.phtml
now call the above function as required, like:
<ol>
<?php foreach ($_categories as $_category): ?>
<?php if($_category->getIsActive()): ?>
<li>
<a href="<?php echo $this->getCategoryUrl($_category) ?>"<?php if ($this->isCategoryActive($_category)): ?> class="current"<?php endif; ?>><?php echo $this->htmlEscape($_category->getName()) ?></a> (<?php echo $_category->getFrontentProductCount() ?>)
</li>
<?php endif; ?>
<?php endforeach ?>
</ol>

Related

Magento 2: Switch the price for 'Sold' label after product is out of stock

I'm trying to to switch the price for a 'Sold' label on the product page of products that are out of stock.
If a product is sold out, the price should be hidden and in its stead should be a 'Sold' label.
I figured out that the price is placed in catalog_product_view.xml and it calls upon the vendor/magento/module-catalog/view/base/templates/product/price/final_price.phtml file, but I could not figure out where and how to bring in a condition to check whether product is sold out or not.
Can someone help here?
Thanks in advance.
Yuan
As I understand you have two parts to this issue
1) Hide price on Product-detail page if product is Out-of-stock
Prices are defined in vendor/magento/module-catalog/view/frontend/layout/catalog_product_view.xml
called at class: Magento\Catalog\Pricing\Render and method: _toHtml()
You can override the method using DI to below
protected function _toHtml()
{
/** #var PricingRender $priceRender */
$priceRender = $this->getLayout()->getBlock($this->getPriceRender());
if ($priceRender instanceof PricingRender) {
$product = $this->getProduct();
if ($product instanceof SaleableInterface && $product->isAvailable()) {
$arguments = $this->getData();
$arguments['render_block'] = $this;
return $priceRender->render($this->getPriceTypeCode(), $product, $arguments);
}
}
return parent::_toHtml();
}
$product->isAvailable() is the new condition that we have added
2) Show Sold label
outofstock label is shown by default, but if you still want to show create your block & template in vendor/magento/modul-catalog/view/frontend/layout/catalog_product_view.xml
and $product->isAvailable() function to check product's availability
Hope this helps
Hiding price for out of stock products in Magento 1.
RWD Theme
app/design/frontend/rwd/template/catalog/product/view.phtml
Change
<div class="price-info">
<?php echo $this->getPriceHtml($_product); ?>
<?php echo $this->getChildHtml('bundle_prices') ?>
<?php echo $this->getTierPriceHtml() ?>
</div>
To:
<?php if($_product->isSaleable()): ?>
<div class="price-info">
<?php echo $this->getPriceHtml($_product); ?>
<?php echo $this->getChildHtml('bundle_prices') ?>
<?php echo $this->getTierPriceHtml() ?>
</div>
<?php endif; ?>
Default Theme:
\app\design\frontend\base\default\template\catalog\product\view\type\default.phtml
Change
<?php echo $this->getPriceHtml($_product) ?>
To:
<?php if($_product->isSaleable()): ?>
<?php echo $this->getPriceHtml($_product) ?>
<?php endif; ?>
OR
Hiding price for out of stock products in Magento 2.
On admin page, Click on Stores, then under the Setting section, choose Configuration.
In this page, you find the Inventory section under Catalog. Expand the Stock Options section and you can start to set the custom status of the product.
Before coming to the Out of stock product section, you need to enter this field.
Set Items’ Status to be in Stock When Order in Canceled: You choose YES when you want to return items to your stock if an order is canceled.
Decrease Stock When Order is Placed: if you want to adjust the quantity on hand when the order is placed, you choose Yes
Then we can come to the part that allows you to display or disable the product out of stock in Magento 2.
You want to display the product out of stock, you set the Display Out of Stock Products section is Yes. In contrast, set No if you want to disable it.

Magento - how to filter categories in phtml

I have been working on the maga menu. I got the collection in phtml like:
<?php $_helper = Mage::helper('catalog/category') ?>
<?php $_categories = $_helper->getStoreCategories() ?>
<?php $currentCategory = Mage::registry('current_category') ?>
Now I have to add the filter to show specific categories. Like I have an array(1,2,3,4) of categories that i want to show. so how can I apply filter to this Helper.
Any one have any suggestion please answer.
Thanks.
The first answer is correct but it's not efficient as it consumes unnecessary database round trips. #Karan's code issues a query to the database for every id. Just imagine if the number of category ids to be filtered were 50 or above.
My example would be this:
<?php
$catIds = array(1,2,3,4);
$catCollection = Mage::getModel('catalog/category')->getCollection()->addAttributeToFilter('id', $catIds)->addAttributeToFilter('is_active',1);
foreach($catCollection as $category){
echo $category->getName()." ";
}
This will reduce the database roundtrip to just one.
use this code
<?php $catids[]=array(1,2,3,4);
foreach($catids as $id):
$_category = Mage::getModel('catalog/category')->load($id);
if($_category->getIsActive()):
echo $_category->getName();
endif;
endforeach;
?>
and don't forget to link my answer if it was helpful

Show fatal error when click to product detail page from wishlist page

I am trying to display category name in product detail page. For that I am using
$cat_name=Mage::registry('current_category')->getName();
It shows category name.
But when I went to wishlist page & click to product image then it give error:-
Fatal error: Call to a member function getName() on a non-object in /opt/lampp/htdocs/dominie/app/design/frontend/default/dominie/template/catalog/product/view.phtml.
Please help me how can I solve this issue.
Just tested the code below and it work in v1.7 when added to template/catalog/product/view.phtml.
However Mage::registry('current_category'); is only available if when coming to a product page from a category page (not tested, but may also dependent on if you have seo url that contain the category names within the url)
<?php
$_helper = $this->helper('catalog/output');
$_category_detail=Mage::registry('current_category');
echo $_category_detail->getName(); //gives current category name
echo $_category_detail->getId(); //gives current category id
?>
See http://vinayp.com.np/how-to-get-category-name-and-id-on-product-page-on-magento/
To display all the categories that a product belong to do
<?php $categories = $_product->getCategoryIds(); ?>
<?php foreach($categories as $k => $_category_id): ?>
<?php $_category = Mage::getModel('catalog/category')->load($_category_id) ?>
<?php echo $_category->getName() ?>
<?php endforeach; ?>
See http://www.magentocommerce.com/boards/viewthread/27720/
Try to define $cat_name in your wishlist module so that collection from wishlist module will also contain category name from which it was added to wishlist. This will surely reduce your overhead.

How to make second root category navigation in magento?

Other than the normal navigation I get when I add subcategories to the main root category, I want to be able to make a new root category, assign subcategories to it and have it display as a separate menu.
Is this possible?
May this can help you :Link 1Link 2
To retrieve another root category
<?php
echo '<pre>';
$id=9;
$catagory_model = Mage::getModel('catalog/category');
$categories = $catagory_model->load($id); // where $id will be the known category id
if(!empty($categories))
{
echo 'category name->'.$categories->getName(); //get category name
echo '<br>';
echo 'category image url->'.$categories->getImageUrl(); //get category image url
echo '<br>';
echo 'category url path->'.$categories->getUrlPath(); //get category url path
echo '<br>';
}
?>
now $id=9; is my new root category id.
To retrieve sub categories of these new root category ($id=9;) below is the following reference code.Customize it according to your requirements.
<?php $helper = $this->helper('catalog/category') ?>
<?php $categories = $this->getStoreCategories() ?>
<?php foreach($categories as $category): ?>
<?php $subcategories = $category->getChildren() ?>
<?php foreach($subcategories as $subcategory): ?>
<?php $subsubcategories = $subcategory->getChildren() ?>
<?php foreach($subsubcategories as $subsubcategory): ?>
<?php endforeach; ?><!-- end foreach subsubcategories -->
<?php endforeach; ?><!-- end foreach subcategories -->
<?php endforeach; ?><!-- end foreach categories -->
In an ideal world you would have found the answer by now, but in case you didn't I modified Nikhil's answer to work for me to basically do what you describe, minus any convenience at all...
$id=9;
$catagory_model = Mage::getModel('catalog/category');
$categories = $catagory_model->load($id);
if(!empty($categories))
{
$cats = explode(",", $categories->getChildren());
foreach($cats AS $c)
{
$cat = $catagory_model->load(trim($c));
echo ''.$cat->getName().'';
}
}
I'm just pasting what I used. The reality is you will have to build the html to make this do whatever you want it to do. If you have subcategories within your loop, you will have to run another fetch in the foreach part.
I am not familiar with magento enough to know what methods you can run on the $cat object. I did a print_r($cat) to examine the object and made a lucky guess that getUrlKey would be available.
Magento... pfft! you'd think ebay would have higher standards than this.

MAGENTO getting the descriptions from a sub category

Hi I'm new to magento and have been trying to set up a static block that displays a list of sub categories within a category. I've been succesfull a grabbing the sub-category images and names, but for some reason I can't seem to get the descriptions to show.
Here's the code can't anyone explain why it won't work and how I can fix it?
I've commented out a few lines because I was trying different things to get it to work.
helper('catalog/output');
$category = $this->getCurrentCategory();
getCurrentChildCategories();
?>
<?php foreach ($_categories as $_category): ?> <?php echo
$this->htmlEscape($_category->getCategoryDescription());?>
<?php if($_category->getIsActive()): ?>
<div class="subcategory-image">
<a href="<?php echo $_category->getURL()
?>" title="htmlEscape($_category->getName())
?>">
</a>
<?php /* echo "Find this item->" */ ?>
</div> <div class="sub-category-container">
<h2><a href="<?php echo $_category->getURL()
?>" title="htmlEscape($_category->getName())
?>">htmlEscape($_category->getName())
?>
getURL() ?>"
class="moreLink">[MORE...]
getDescription() ?>-->
getDescription()):
?>
categoryAttribute($_category, $_description, 'description'); ?>
-->
This is one of those cases where Varien decided that they should call "load" on the data collection before returning it when that really isn't necessary and makes the utility function utterly useless.. If you trace the code down for Mage_Catalog_Block_Navigation->getChildrenCategories() you will eventually find this in Mage_Catalog_Model_Resource_Eav_Mysql4_Category:
public function getChildrenCategories($category)
{
$collection = $category->getCollection();
/* #var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection */
$collection->addAttributeToSelect('url_key')
->addAttributeToSelect('name')
->addAttributeToSelect('all_children')
->addAttributeToSelect('is_anchor')
->addAttributeToFilter('is_active', 1)
->addIdFilter($category->getChildren())
->setOrder('position', 'ASC')
->joinUrlRewrite()
->load();
return $collection;
}
The next to last line ->load(); means that the query is executed and the collection is loaded so it is too late to modify the query. So what you will want to do is copy and paste that in place of calling getChildrenCategories and then add the additional attributes you want to use like so:
$_categories = $category->getCollection()
->addAttributeToSelect(
array('url_key','name','all_children','is_anchor','description')
)
->addAttributeToFilter('is_active', 1)
->addIdFilter($category->getChildren())
->setOrder('position', 'ASC')
->joinUrlRewrite()
;
Now the collection will include the description attribute so that getDescription() will work. Notice that you do not need to call load(), it happens automatically when you start using the iterator (the foreach loop triggers this). This is why it is pointless for the load() call to be included in that function because otherwise you could have just added one line below the function call:
$categories->addAttributeToSelect('description');
But instead you have to copy the contents of the function to tweak the query.
Change:
$_category->getCategoryDescription()
To this:
$_category->getDescription()

Resources