Skip to content

Instantly share code, notes, and snippets.

@kepek
Created January 24, 2012 11:10
Show Gist options
  • Save kepek/1669666 to your computer and use it in GitHub Desktop.
Save kepek/1669666 to your computer and use it in GitHub Desktop.
/app/code/local/Mage/Catalog/Block/
<?php
/**
* Magento
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@magentocommerce.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Magento to newer
* versions in the future. If you wish to customize Magento for your
* needs please refer to http://www.magentocommerce.com for more information.
*
* @category Mage
* @package Mage_Catalog
* @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
*/
/**
* Catalog navigation
*
* @category Mage
* @package Mage_Catalog
* @author Magento Core Team <core@magentocommerce.com>
*/
class Mage_Catalog_Block_Navigation extends Mage_Core_Block_Template
{
protected $_categoryInstance = null;
/**
* Array of level position counters
*
* @var array
*/
protected $_itemLevelPositions = array();
protected function _construct()
{
$this->addData(array(
'cache_lifetime' => false,
'cache_tags' => array(Mage_Catalog_Model_Category::CACHE_TAG, Mage_Core_Model_Store_Group::CACHE_TAG),
));
}
/**
* Get Key pieces for caching block content
*
* @return array
*/
public function getCacheKeyInfo()
{
return array(
'CATALOG_NAVIGATION',
Mage::app()->getStore()->getId(),
Mage::getDesign()->getPackageName(),
Mage::getDesign()->getTheme('template'),
Mage::getSingleton('customer/session')->getCustomerGroupId(),
'template' => $this->getTemplate(),
$this->getCurrenCategoryKey()
);
}
public function getCurrenCategoryKey()
{
if ($category = Mage::registry('current_category')) {
return $category->getPath();
} else {
return Mage::app()->getStore()->getRootCategoryId();
}
}
/**
* Get catagories of current store
*
* @return Varien_Data_Tree_Node_Collection
*/
public function getStoreCategories()
{
$helper = Mage::helper('catalog/category');
return $helper->getStoreCategories();
}
/**
* Retrieve child categories of current category
*
* @return Varien_Data_Tree_Node_Collection
*/
public function getCurrentChildCategories()
{
$layer = Mage::getSingleton('catalog/layer');
$category = $layer->getCurrentCategory();
/* @var $category Mage_Catalog_Model_Category */
$categories = $category->getChildrenCategories();
$productCollection = Mage::getResourceModel('catalog/product_collection');
$layer->prepareProductCollection($productCollection);
$productCollection->addCountToCategories($categories);
return $categories;
}
/**
* Checkin activity of category
*
* @param Varien_Object $category
* @return bool
*/
public function isCategoryActive($category)
{
if ($this->getCurrentCategory()) {
return in_array($category->getId(), $this->getCurrentCategory()->getPathIds());
}
return false;
}
protected function _getCategoryInstance()
{
if (is_null($this->_categoryInstance)) {
$this->_categoryInstance = Mage::getModel('catalog/category');
}
return $this->_categoryInstance;
}
/**
* Get url for category data
*
* @param Mage_Catalog_Model_Category $category
* @return string
*/
public function getCategoryUrl($category)
{
if ($category instanceof Mage_Catalog_Model_Category) {
$url = $category->getUrl();
} else {
$url = $this->_getCategoryInstance()
->setData($category->getData())
->getUrl();
}
return $url;
}
/**
* Return item position representation in menu tree
*
* @param int $level
* @return string
*/
protected function _getItemPosition($level)
{
if ($level == 0) {
$zeroLevelPosition = isset($this->_itemLevelPositions[$level]) ? $this->_itemLevelPositions[$level] + 1 : 1;
$this->_itemLevelPositions = array();
$this->_itemLevelPositions[$level] = $zeroLevelPosition;
} elseif (isset($this->_itemLevelPositions[$level])) {
$this->_itemLevelPositions[$level]++;
} else {
$this->_itemLevelPositions[$level] = 1;
}
$position = array();
for($i = 0; $i <= $level; $i++) {
if (isset($this->_itemLevelPositions[$i])) {
$position[] = $this->_itemLevelPositions[$i];
}
}
return implode('-', $position);
}
/**
* Render category to html
*
* @param Mage_Catalog_Model_Category $category
* @param int Nesting level number
* @param boolean Whether ot not this item is last, affects list item class
* @param boolean Whether ot not this item is first, affects list item class
* @param boolean Whether ot not this item is outermost, affects list item class
* @param string Extra class of outermost list items
* @param string If specified wraps children list in div with this class
* @param boolean Whether ot not to add on* attributes to list item
* @return string
*/
protected function _renderCategoryMenuItemHtml($category, $level = 0, $isLast = false, $isFirst = false,
$isOutermost = false, $outermostItemClass = '', $childrenWrapClass = '', $noEventAttributes = false)
{
if (!$category->getIsActive()) {
return '';
}
$html = array();
// get all children
if (Mage::helper('catalog/category_flat')->isEnabled()) {
$children = (array)$category->getChildrenNodes();
$childrenCount = count($children);
} else {
$children = $category->getChildren();
$childrenCount = $children->count();
}
$hasChildren = ($children && $childrenCount);
// select active children
$activeChildren = array();
foreach ($children as $child) {
if ($child->getIsActive()) {
$activeChildren[] = $child;
}
}
$activeChildrenCount = count($activeChildren);
$hasActiveChildren = ($activeChildrenCount > 0);
// prepare list item html classes
$classes = array();
$classes[] = 'level' . $level;
$classes[] = 'nav-' . $this->_getItemPosition($level);
$linkClass = '';
if ($isOutermost && $outermostItemClass) {
$classes[] = $outermostItemClass;
$linkClass = ' class="'.$outermostItemClass.'"';
}
if ($this->isCategoryActive($category)) {
$classes[] = 'active';
}
if ($isFirst) {
$classes[] = 'first';
}
if ($isLast) {
$classes[] = 'last';
}
if ($hasActiveChildren) {
$classes[] = 'parent';
}
// prepare list item attributes
$attributes = array();
if (count($classes) > 0) {
$attributes['class'] = implode(' ', $classes);
}
if ($hasActiveChildren && !$noEventAttributes) {
$attributes['onmouseover'] = 'toggleMenu(this,1)';
$attributes['onmouseout'] = 'toggleMenu(this,0)';
}
// assemble list item with attributes
$htmlLi = '<li';
foreach ($attributes as $attrName => $attrValue) {
$htmlLi .= ' ' . $attrName . '="' . str_replace('"', '\"', $attrValue) . '"';
}
$htmlLi .= '>';
$html[] = $htmlLi;
$html[] = '<a href="'.$this->getCategoryUrl($category).'"'.$linkClass.'>';
$html[] = '<span>' . $this->escapeHtml($category->getName()) . '</span>';
$html[] = '</a>';
// render children
$htmlChildren = '';
$j = 0;
foreach ($activeChildren as $child) {
$htmlChildren .= $this->_renderCategoryMenuItemHtml(
$child,
($level + 1),
($j == $activeChildrenCount - 1),
($j == 0),
false,
$outermostItemClass,
$childrenWrapClass,
$noEventAttributes
);
$j++;
}
if (!empty($htmlChildren)) {
if ($childrenWrapClass) {
$html[] = '<div class="' . $childrenWrapClass . '">';
}
$html[] = '<ul class="level' . $level . '">';
$html[] = $htmlChildren;
$html[] = '</ul>';
if ($childrenWrapClass) {
$html[] = '</div>';
}
}
$html[] = '</li>';
$html = implode("\n", $html);
return $html;
}
/**
* Render category to html
*
* @deprecated deprecated after 1.4
* @param Mage_Catalog_Model_Category $category
* @param int Nesting level number
* @param boolean Whether ot not this item is last, affects list item class
* @return string
*/
public function drawItem($category, $level = 0, $last = false)
{
return $this->_renderCategoryMenuItemHtml($category, $level, $last);
}
/**
* Enter description here...
*
* @return Mage_Catalog_Model_Category
*/
public function getCurrentCategory()
{
if (Mage::getSingleton('catalog/layer')) {
return Mage::getSingleton('catalog/layer')->getCurrentCategory();
}
return false;
}
/**
* Enter description here...
*
* @return string
*/
public function getCurrentCategoryPath()
{
if ($this->getCurrentCategory()) {
return explode(',', $this->getCurrentCategory()->getPathInStore());
}
return array();
}
/**
* Enter description here...
*
* @param Mage_Catalog_Model_Category $category
* @return string
* @author Michal Kechner
*/
public function drawOpenCategoryItem($category, $level=0, $productCount=false, $isLast = false, $isFirst = false) {
$html = '';
if (!$category->getIsActive()) {
return $html;
}
// get all children
if (Mage::helper('catalog/category_flat')->isEnabled()) {
$children = (array)$category->getChildrenNodes();
$childrenCount = count($children);
} else {
$children = $category->getChildren();
$childrenCount = $children->count();
}
$hasChildren = ($children && $childrenCount);
// select active children
$activeChildren = array();
foreach ($children as $child) {
if ($child->getIsActive()) {
$activeChildren[] = $child;
}
}
$activeChildrenCount = count($activeChildren);
$hasActiveChildren = ($activeChildrenCount > 0);
$classes = array();
$classes[] = 'level' . $level;
$classes[] = 'nav-' . $this->_getItemPosition($level);
$linkClass = '';
if ($this->isCategoryActive($category)) {
$classes[] = 'active';
}
if ($isFirst) {
$classes[] = 'first';
}
if ($isLast) {
$classes[] = 'last';
}
if ($hasActiveChildren) {
$classes[] = 'parent';
}
// prepare list item attributes
$attributes = array();
if (count($classes) > 0) {
$attributes['class'] = implode(' ', $classes);
}
// assemble list item with attributes
$html = '<li';
foreach ($attributes as $attrName => $attrValue) {
$html.= ' ' . $attrName . '="' . str_replace('"', '\"', $attrValue) . '"';
}
$html.= '>';
if(!$productCount) {
$html.= '<a href="'.$this->getCategoryUrl($category).'"><span>'.$this->htmlEscape($category->getName()).'</span></a>'."\n";
}
else {
$count = Mage::getModel('catalog/layer')->setCurrentCategory(Mage::getModel('catalog/category')->load($category->getId()))->getProductCollection()->getSize();
$html.= '<a href="'.$this->getCategoryUrl($category).'"><span>'.$this->htmlEscape($category->getName()).'</span> <span class="counter">(' . $count . ')</span></a>'."\n";
}
if (in_array($category->getId(), $this->getCurrentCategoryPath())){
if ($hasChildren) {
// render children
$htmlChildren = '';
$j = 0;
foreach ($children as $child) {
$htmlChildren.= $this->drawOpenCategoryItem($child, $level + 1, true, ($j == $activeChildrenCount - 1), ($j == 0));
}
if (!empty($htmlChildren)) {
$html.= '<ul>'."\n"
.$htmlChildren
.'</ul>';
}
}
}
$html.= '</li>'."\n";
return $html;
}
/**
* Render categories menu in HTML
*
* @param int Level number for list item class to start from
* @param string Extra class of outermost list items
* @param string If specified wraps children list in div with this class
* @return string
*/
public function renderCategoriesMenuHtml($level = 0, $outermostItemClass = '', $childrenWrapClass = '')
{
$activeCategories = array();
foreach ($this->getStoreCategories() as $child) {
if ($child->getIsActive()) {
$activeCategories[] = $child;
}
}
$activeCategoriesCount = count($activeCategories);
$hasActiveCategoriesCount = ($activeCategoriesCount > 0);
if (!$hasActiveCategoriesCount) {
return '';
}
$html = '';
$j = 0;
foreach ($activeCategories as $category) {
$html .= $this->_renderCategoryMenuItemHtml(
$category,
$level,
($j == $activeCategoriesCount - 1),
($j == 0),
true,
$outermostItemClass,
$childrenWrapClass,
true
);
$j++;
}
return $html;
}
/**
* @author Michal Kechner
*/
public function getPriceHtml($product)
{
$this->setTemplate('catalog/product/price.phtml');
$this->setProduct($product);
return $this->toHtml();
}
/**
* @author Michal Kechner
*/
public function getSubCategories($parent, $recursionLevel=0, $sorted=false, $asCollection=false, $toLoad=true)
{
$helper = Mage::helper('catalog/category');
return $helper->getSubCategories($parent, $recursionLevel, $sorted, $asCollection, $toLoad);
}
/**
* @author Michal Kechner
*/
protected function _getNavLevel($category) {
$category = $category ? $category : Mage::registry('current_category');
if($category) {
$level = $category->getLevel();
}
else {
$level = Mage::getModel('catalog/category')->load(Mage::app()->getStore()->getRootCategoryId())->getLevel();
}
return $level;
}
/**
* Render categories via levels
*
* @param int Level number for list item class to start from
* @param string Extra class of outermost list items
* @param string If specified wraps children list in div with this class
* @return string
* @author Michal Kechner
*
*
* if home => level = 1
* if category => level = LVL-1
*
*/
public function renderNavigation($category, $recursionLevel, $sorted=false, $asCollection=false, $toLoad=true) {
$category = $category ? $category : Mage::getModel('catalog/category')->load(Mage::app()->getStore()->getRootCategoryId());
if(!empty($recursionLevel)) {
$recursionLevel = $recursionLevel;
}
elseif(is_object(Mage::registry('current_category'))) {
$recursionLevel = Mage::registry('current_category')->getLevel();
}
else {
$recursionLevel = $category->getLevel();
}
$output = '';
$tree = $this->getSubCategories($category->getId(), $recursionLevel, $sorted, $asCollection, $toLoad);
foreach($tree as $id => $branch) {
//$output .= $this->_renderCategoryMenuItemHtml($branch, $branch->getLevel()-1, false, false, false, '', '', true);
$output .= $this->drawOpenCategoryItem($branch, $branch->getLevel()-1);
}
return $output;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment