首页 文章

得到所有类别和SubCatgories而不在foreach循环中加载模型

提问于
浏览
0

我想在主导航菜单中显示所有类别及其子类别 . 当我将鼠标悬停在cateory上时,它应显示其子类别 . 我想实现这个功能,而不在foreach循环中加载Mage :: getModel('catalog / category') .

3 回答

  • 1

    因为你想在phtml文件中编写代码,使用下面代码创建类别的树结构 .

    <ul>
        <?php
            $obj = new Mage_Catalog_Block_Navigation();
            $storeCategories = $obj->getStoreCategories();
            Mage::registry('current_category') ? $currentCategoryId = Mage::registry('current_category')->getId() : $currentCategoryId='';
            foreach ($storeCategories as $_category):
        ?>
                <li>
                    <strong><?php echo $_category->getName(); ?></strong>
                    <?php $categoryChildren = $_category->getChildren(); ?>
                    <?php if($categoryChildren->count()) : ?>
                        <ul>
    
                            <?php foreach($categoryChildren as $_categoryChild) : ?>
                                <?php $_categoryChildModel = Mage::getModel('catalog/category')->load($_categoryChild->getId());?>
                                <?php $categoryGrandchildren=$_categoryChild->getChildren(); ?>
                                <li>
                                    <?php
                                        $currentCategoryId===$_categoryChild->getId() ? $bold="style=\"font-weight:bold\"" : $bold='';
                                        echo '&emsp;' . '<a href="' . $_categoryChildModel->getUrl() . '"' . $bold . '>' .  $_categoryChild->getName() . '(' . $_categoryChildModel->getProductCollection()->count() . ')</a>';
                                    ?>
                                </li>
                                <?php if($categoryGrandchildren->count()) : ?>
                                    <?php foreach($categoryGrandchildren as $_categoryGrandchild) : ?>
                                        <?php $_categoryGrandchildModel = Mage::getModel('catalog/category')->load($_categoryGrandchild->getId());?>
                                        <li>
                                            <?php
                                                $currentCategoryId===$_categoryChild->getId() ? $bold="style=\"font-weight:bold\"" : $bold='';
                                                echo '&emsp;&emsp;' . '<a href="' . $_categoryGrandchildModel->getUrl() . '"' . $bold . '>' .  $_categoryGrandchild->getName() . '(' . $_categoryGrandchildModel->getProductCount() . ')</a>';
                                            ?>
                                        </li>
                                    <?php endforeach; ?>
                                <?php endif; ?>
                            <?php endforeach; ?>
                        </ul>
                    <?php endif; ?>
                </li>
            <?php endforeach ?>
    </ul>
    

    并使用css和HTML,您可以实现在主菜单悬停时显示子菜单的目标 .

    如果你需要任何其他帮助,还是让我 .

    谢谢

  • 0

    好吧所以我只是做了这个,我想我会搜索是否有人想知道如何实现这一目标 . 这个诀窍是

    Mage::getResourceSingleton('catalog/category')->getAttributeRawValue($categoryEntityId,array('name','level','url_key','path','is_active'),Mage::app()->getStore());
    

    这不会加载类别模型让我们来看看它实际上在做什么 .

    转到app / code / core / Mage / Catalog / Model / Resource / Abstract

    public function getAttributeRawValue($entityId, $attribute, $store)
    {
        if (!$entityId || empty($attribute)) {
            return false;
        }
        if (!is_array($attribute)) {
            $attribute = array($attribute);
        }
    
        $attributesData     = array();
        $staticAttributes   = array();
        $typedAttributes    = array();
        $staticTable        = null;
        $adapter            = $this->_getReadAdapter();
    
        foreach ($attribute as $_attribute) {
            /* @var $attribute Mage_Catalog_Model_Entity_Attribute */
            $_attribute = $this->getAttribute($_attribute);
            if (!$_attribute) {
                continue;
            }
            $attributeCode = $_attribute->getAttributeCode();
            $attrTable     = $_attribute->getBackend()->getTable();
            $isStatic      = $_attribute->getBackend()->isStatic();
    
            if ($isStatic) {
                $staticAttributes[] = $attributeCode;
                $staticTable = $attrTable;
            } else {
                /**
                 * That structure needed to avoid farther sql joins for getting attribute's code by id
                 */
                $typedAttributes[$attrTable][$_attribute->getId()] = $attributeCode;
            }
        }
        /**
         * Collecting static attributes
         */
        if ($staticAttributes) {
            $select = $adapter->select()->from($staticTable, $staticAttributes)
                ->where($this->getEntityIdField() . ' = :entity_id');
            $attributesData = $adapter->fetchRow($select, array('entity_id' => $entityId));
        }
    
        /**
         * Collecting typed attributes, performing separate SQL query for each attribute type table
         */
        if ($store instanceof Mage_Core_Model_Store) {
            $store = $store->getId();
        }
    
        $store = (int)$store;
        if ($typedAttributes) {
            foreach ($typedAttributes as $table => $_attributes) {
                $select = $adapter->select()
                    ->from(array('default_value' => $table), array('attribute_id'))
                    ->where('default_value.attribute_id IN (?)', array_keys($_attributes))
                    ->where('default_value.entity_type_id = :entity_type_id')
                    ->where('default_value.entity_id = :entity_id')
                    ->where('default_value.store_id = ?', 0);
                $bind = array(
                    'entity_type_id' => $this->getTypeId(),
                    'entity_id'      => $entityId,
                );
    
                if ($store != $this->getDefaultStoreId()) {
                    $valueExpr = $adapter->getCheckSql('store_value.value IS NULL',
                        'default_value.value', 'store_value.value');
                    $joinCondition = array(
                        $adapter->quoteInto('store_value.attribute_id IN (?)', array_keys($_attributes)),
                        'store_value.entity_type_id = :entity_type_id',
                        'store_value.entity_id = :entity_id',
                        'store_value.store_id = :store_id',
                    );
    
                    $select->joinLeft(
                        array('store_value' => $table),
                        implode(' AND ', $joinCondition),
                        array('attr_value' => $valueExpr)
                    );
    
                    $bind['store_id'] = $store;
    
                } else {
                    $select->columns(array('attr_value' => 'value'), 'default_value');
                }
    
                $result = $adapter->fetchPairs($select, $bind);
                foreach ($result as $attrId => $value) {
                    $attrCode = $typedAttributes[$table][$attrId];
                    $attributesData[$attrCode] = $value;
                }
            }
        }
    
        if (sizeof($attributesData) == 1) {
            $_data = each($attributesData);
            $attributesData = $_data[1];
        }
    
        return $attributesData ? $attributesData : false;
    }
    

    正如您所看到的那样,只有检索特定信息才能发生模型加载 . 同时作为资源摘要的一部分意味着所有目录资源模型(我没有检查过其他资源模型,但我不会太惊讶,在其他资源模型中找到它)可以使用它 .

    如果您在Mage_Catalog_Block_Navigation的覆盖中使用它,则可以在不加载模型的情况下调用所有关于任何类别的信息 . 然而,要遍历树,你必须做一些可怕的事情 .

    你可以使用'path'(在/上爆炸)来轻松检索父母,但你需要弄脏才能检索子类别,这样才能得到孩子 .

    $childrenQuery = "SELECT entity_id FROM catalog_category_entity WHERE path REGEXP '^.*\/" . $categoryId . "\/[[:digit:]]?[[:digit:]]?[[:digit:]]?[[:digit:]]?$'";
            $resource = Mage::getSingleton('core/resource');
            $readCxn = $resource->getConnection('core/read');
            $children = $readCxn->fetchAll($childrenQuery);
            if ($children[0]) {
                return $children;
            } else {
                return;
            }
    

    总体困难是所有模型和资源模型函数都期望一个类别对象的实例使它们只与entity_id一起工作绝对可能只是一种痛苦 .

    所以我不建议这样做通常我这样做的唯一原因是因为在我的情况下默认的magento根类别不是类别的实际功能根(有趣的是) . 如果您使用的是标准根类别,我建议您使用Helper函数并从缓存中检索信息 .

    无论哪种方式,您都必须在Mage_Catalog_Block_Navigation中完成您的功能,并在模板中组合您的菜单 . 你去了;完整的类别菜单,无需访问模型 - >加载 .

  • 1

    Try This Code

    <?php
    require_once("app/Mage.php");
    Mage::app();
    
    function getChildCategories($category, $First = false) {
    
    
            $sub = $First ? $category : $category->getChildren();
    
    
            foreach ($sub as $child) {
                    $_categories[] = [ "name" => $child->getName(), "id" => $child->getId(), "children" => getChildCategories($child) ];
            }
    
    
            return $_categories;
    };
    
    function CategoriesTree($category, $First = false) {
    
    
            $sub = $First ? $category : $category->getChildren();
            echo "<pre>";
    
            foreach ($sub as $child) {
              echo $child->getName(); ;
                    CategoriesTree($child);
            }
    
    }
    
    $_categories = Mage::helper('catalog/category')->getStoreCategories();
    
    
    $categories = getChildCategories($_categories, true);
    
    CategoriesTree($_categories, true);
    
    ?>
    

相关问题