Magento


What is the standard Magento order status flow?

order submitted, status is set as pending and payment is authorized
order invoiced, status is set as processing and payment is captured
order shipped, status is set as complete and payment is still captured

Some stores will vary slightly on the first order status depending on what they have specified in their payment method as the default status for a new order. If the desired status is not available to the payment method, you’ll need to assign the status (generally pending or processing) to the state (processing).


Why does Magento block cache become invalidated frequently?

In Magento, whenever you make changes to products, static blocks, etc, it recognizes that the data in the database is no longer the same as what it has in the cache. Unfortunately, Magento doesn’t realize what cache data is different, just that something is different. There are many reasons a block cache is invalidated from updates to products, catalog price rule changes, and 3rd party extensions. Also running of cron jobs can cause block caches to become invalidated as well. You will need to go into System > Cache Management and refresh the invalidated cache types.


Override the Magento Category and Resource Models

To override Magento’s core category and category resource model, create the following files. Modify “My” with your namespace.

/app/code/local/My/Catalog/Model/Category.php

class My_Catalog_Model_Category extends Mage_Catalog_Model_Category {}

/app/code/local/My/Catalog/Model/Resource/Category.php

class My_Catalog_Model_Resource_Category extends Mage_Catalog_Model_Resource_Category {}

/app/etc/modules/My_Catalog.xml

<?xml version="1.0"?>
<config>
    <modules>
        <My_Catalog>
            <active>true</active>
            <codePool>local</codePool>
        </My_Catalog>
    </modules>
</config>

/app/code/local/My/Catalog/etc/config.xml

<?xml version="1.0"?>
<config>
<modules>
    <my_catalog>
        <version>0.1</version>
    </my_catalog>
</modules>
<global>
    <models>
        <catalog>
            <rewrite>
                <category>My_Catalog_Model_Category</category>
            </rewrite>
        </catalog>
        <catalog_resource>
            <rewrite>
                <category>My_Catalog_Model_Resource_Category</category>
            </rewrite>
        </catalog_resource>
    </models>
</global>
</config>

Magento recursive category navigation tree

I needed a category navigation in Magento that behaved in the following manner:
1. All categories directly under the store’s root category where displayed as a link
2. The navigation would drill down to the current category being viewed
3. The siblings of the current category would also be visible as a link

The other solutions out there were either not recursive, or they simply displayed a category tree that printed every category, so I ended up writing my own below. Place this code in /app/design/frontend/yourcompany/yourtheme/template/catalog/navigation/left.phtml .

<div class="block block-list block-categories">
    <div id="leftnav" class="block-content" style="display:block">
        <?php
        $currentCategory = Mage::getModel('catalog/category')->load(Mage::registry('current_category')->getId());
        Mage::register('current_category_parent_ids', $currentCategory->getParentIds());
        $rootCategory = Mage::getModel('catalog/category')->load(Mage::app()->getStore()->getRootCategoryId());
        echo getTreeCategories($rootCategory, false);
        ?>
    </div>
</div>
 
 
 
<?php
/**
 * recursive function that builds category tree
 * it'll only load children and siblings of the currently active category
 * @param $parentCategory
 * @param $isChild
 * @param int $level
 * @return string
 */
function getTreeCategories($parentCategory, $isChild, $level = 0) {
    $helper = Mage::helper('catalog/category');
    $parentCategoryIds = Mage::registry('current_category_parent_ids');
    $parentChildren = $parentCategory->getChildrenCategories();
    $class = ($isChild) ? "sub-cat-list" : "cat-list";
    $html = '<ul class="'.$class.'">';
 
    if($parentChildren->getSize()) {
        foreach($parentChildren as $category)
        {
            $html .= '<li class="level' . $level;
            if($category->getId() == Mage::registry('current_category')->getId()) {
                $html .= ' active';
            }
            if((in_array($category->getId(), $parentCategoryIds)) || $category->getId() == Mage::registry('current_category')->getId()) {
                $html .= ' active-parent';
            }
            $html .= '"><a href="' . $helper->getCategoryUrl($category) . '"><span';
            if($level == 0) {
                $html .= ' class="toplevel"';
            }
            $html .= '><div class="sub">' . trim($category->getName(), '- ') . '</div></span></a>';
            $subcats = $category->getChildren();
            if($subcats != '') {
 
                //drill down to show currently selected category, or show currently select category's children
                if((in_array($category->getId(), $parentCategoryIds)) || $category->getId() == Mage::registry('current_category')->getId()) {
                    $html .= getTreeCategories($category, true, ++$level);
                    --$level;
                }
            }
            $html .= '</li>';
        }
    }
    $html .= '</ul>';
 
    return $html;
}

Magento check bundled product visibility

I’ve created a custom module that adds a hyperlink to bundled products on the product view page, however it needs to consider the product’s visibility since Magento will return an error page when visiting a product that is hidden in the catalog. Apparently calling $_product->getVisibility() would return the integer 1-4 we’re looking for on Magento version 1.5, but not so on 1.8. The way I was able to accomplish this with Magento 1.8 is by loading the product and then checking isVisibleInSiteVisibility() like this:

//load full product for bundled selection so we can check visibility		
$selectionProduct = Mage::getModel('catalog/product')->load($_selection->getId());
 
if ($selectionProduct->isVisibleInSiteVisibility()) {
	$priceTitle .= '<a href="' . $_selection->getProductUrl() . '">';
}
$priceTitle .= $this->escapeHtml($_selection->getName());
if ($selectionProduct->isVisibleInSiteVisibility()) {
	$priceTitle .= '</a>';
}

This is applied to the four files at Yourmodule/Bundle/Block/Catalog/Product/View/Type/Bundle/Option/ . The full code for Yourmodule/Bundle/Block/Catalog/Product/View/Type/Bundle/Option/Select.php is

<?php
class Yourmodule_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Select
	extends Mage_Bundle_Block_Catalog_Product_View_Type_Bundle_Option_Select 
{
 
	public function getSelectionTitlePrice($_selection, $includeContainer = true)
	{
		$price = $this->getProduct()->getPriceModel()->getSelectionPreFinalPrice($this->getProduct(), $_selection, 1);
		$tierPrice = $_selection->getTierPrice();
		if (!empty($tierPrice)) {
			$qty = $_selection->getSelectionQty();
			$price = $qty * (float) $_selection->getPriceModel()->getTierPrice($qty, $_selection);
		}
		$this->setFormatProduct($_selection);
 
		$priceTitle = '';
 
		//load full product for bundled selection so we can check visibility		
		$selectionProduct = Mage::getModel('catalog/product')->load($_selection->getId());
 
		if ($selectionProduct->isVisibleInSiteVisibility()) {
			$priceTitle .= '<a href="' . $_selection->getProductUrl() . '">';
		}
		$priceTitle .= $this->escapeHtml($_selection->getName());
		if ($selectionProduct->isVisibleInSiteVisibility()) {
			$priceTitle .= '</a>';
		}
 
		$priceTitle .= ' &nbsp; ' . ($includeContainer ? '<span class="price-notice">' : '')
		. '+' . $this->formatPriceString($price, $includeContainer)
		. ($includeContainer ? '</span>' : '');
		return $priceTitle;
	}
 
}