कस्टम एक्सटेंशन में श्रेणी वृक्ष जोड़ें


23

मैं श्रेणी एक्सट्रीम को कस्टम एक्सटेन्शन में जोड़ने की कोशिश कर रहा हूं, श्रेणी ट्री जो एडिट प्रोडक्ट पेज के एक टैब में है

जवाबों:


27

अपने आप को तैयार करें, यह एक लंबा होने जा रहा है। यहाँ जाता हैं।
आपको निम्न फ़ाइलों की आवश्यकता होगी:

app/code/local/[Namespace]/[Module]/Block/Adminhtml/[Entity]/Edit/Tab/Categories.php - टैब जो श्रेणियों को प्रस्तुत करेगा।

<?php
class [Namespace]_[Module]_Block_Adminhtml_[Entity]_Edit_Tab_Categories
    extends Mage_Adminhtml_Block_Catalog_Category_Tree {
    protected $_categoryIds = null;
    protected $_selectedNodes = null;
    public function __construct() {
        parent::__construct();
        $this->setTemplate('[namespace]_module/[entity]/edit/tab/categories.phtml');
        $this->_withProductCount = false;
    }
    public function get[Entity](){
        return Mage::registry('current_[entity]'); //use other registration key if you have one
    }

    public function getCategoryIds(){
        if (is_null($this->_categoryIds)){
            $categories = $this->get[Entity]()->getSelectedCategories();
                $ids = array();
                foreach ($categories as $category){
                    $ids[] = $category->getId();
                }
                $this->_categoryIds = $ids;
        }
        return $this->_categoryIds;
    }
    public function getIdsString(){
        return implode(',', $this->getCategoryIds());
    }
    public function getRootNode(){
        $root = $this->getRoot();
        if ($root && in_array($root->getId(), $this->getCategoryIds())) {
            $root->setChecked(true);
        }
        return $root;
    }

    public function getRoot($parentNodeCategory = null, $recursionLevel = 3){
        if (!is_null($parentNodeCategory) && $parentNodeCategory->getId()) {
            return $this->getNode($parentNodeCategory, $recursionLevel);
        }
        $root = Mage::registry('category_root');
        if (is_null($root)) {
            $rootId = Mage_Catalog_Model_Category::TREE_ROOT_ID;
            $ids = $this->getSelectedCategoryPathIds($rootId);
            $tree = Mage::getResourceSingleton('catalog/category_tree')
                ->loadByIds($ids, false, false);
            if ($this->getCategory()) {
                $tree->loadEnsuredNodes($this->getCategory(), $tree->getNodeById($rootId));
            }
            $tree->addCollectionData($this->getCategoryCollection());
            $root = $tree->getNodeById($rootId);
            Mage::register('category_root', $root);
        }
        return $root;
    }
    protected function _getNodeJson($node, $level = 1){
        $item = parent::_getNodeJson($node, $level);
        if ($this->_isParentSelectedCategory($node)) {
            $item['expanded'] = true;
        }
        if (in_array($node->getId(), $this->getCategoryIds())) {
            $item['checked'] = true;
        }
        return $item;
    }
    protected function _isParentSelectedCategory($node){
        $result = false;
        // Contains string with all category IDs of children (not exactly direct) of the node
        $allChildren = $node->getAllChildren();
        if ($allChildren) {
            $selectedCategoryIds = $this->getCategoryIds();
            $allChildrenArr = explode(',', $allChildren);
            for ($i = 0, $cnt = count($selectedCategoryIds); $i < $cnt; $i++) {
                $isSelf = $node->getId() == $selectedCategoryIds[$i];
                if (!$isSelf && in_array($selectedCategoryIds[$i], $allChildrenArr)) {
                    $result = true;
                    break;
                }
            }
        }
        return $result;
    }
    protected function _getSelectedNodes(){
        if ($this->_selectedNodes === null) {
            $this->_selectedNodes = array();
            $root = $this->getRoot();
            foreach ($this->getCategoryIds() as $categoryId) {
                if ($root) {
                    $this->_selectedNodes[] = $root->getTree()->getNodeById($categoryId);
                }
            }
        }
        return $this->_selectedNodes;
    }

    public function getCategoryChildrenJson($categoryId){
        $category = Mage::getModel('catalog/category')->load($categoryId);
        $node = $this->getRoot($category, 1)->getTree()->getNodeById($categoryId);
        if (!$node || !$node->hasChildren()) {
            return '[]';
        }
        $children = array();
        foreach ($node->getChildren() as $child) {
            $children[] = $this->_getNodeJson($child);
        }
        return Mage::helper('core')->jsonEncode($children);
    }
    public function getLoadTreeUrl($expanded = null){
        return $this->getUrl('*/*/categoriesJson', array('_current' => true));
    }
    public function getSelectedCategoryPathIds($rootId = false){
        $ids = array();
        $categoryIds = $this->getCategoryIds();
        if (empty($categoryIds)) {
            return array();
        }
        $collection = Mage::getResourceModel('catalog/category_collection');
        if ($rootId) {
            $collection->addFieldToFilter('parent_id', $rootId);
        }
        else {
            $collection->addFieldToFilter('entity_id', array('in'=>$categoryIds));
        }

        foreach ($collection as $item) {
            if ($rootId && !in_array($rootId, $item->getPathIds())) {
                continue;
            }
            foreach ($item->getPathIds() as $id) {
                if (!in_array($id, $ids)) {
                    $ids[] = $id;
                }
            }
        }
        return $ids;
    }
}

app/design/adminhtml/default/default/[namespace]_[module]/[entity]/tab/edit/categories.phtml - श्रेणियों को प्रस्तुत करने के लिए आवश्यक टेम्पलेट

<div class="entry-edit">
    <div class="entry-edit-head">
        <h4 class="icon-head head-edit-form fieldset-legend">
            <?php echo Mage::helper('[module]')->__('Categories') ?>
        </h4>
    </div>
    <fieldset id="grop_fields">
        <input type="hidden" name="category_ids" id="[entity]_categories" value="<?php echo $this->getIdsString() ?>">
        <div id="[entity]-categories" class="tree"></div>
    </fieldset>
</div>
<?php if($this->getRootNode() && $this->getRootNode()->hasChildren()): ?>
<script type="text/javascript">
    Ext.EventManager.onDocumentReady(function() {
        var categoryLoader = new Ext.tree.TreeLoader({
           dataUrl: '<?php echo $this->getLoadTreeUrl()?>'
        });
        categoryLoader.createNode = function(config) {
            config.uiProvider = Ext.tree.CheckboxNodeUI;
            var node;
            if (config.children && !config.children.length) {
                delete(config.children);
                node = new Ext.tree.AsyncTreeNode(config);
            }
            else {
                node = new Ext.tree.TreeNode(config);
            }
            return node;
        };
        categoryLoader.on("beforeload", function(treeLoader, node) {
            treeLoader.baseParams.category = node.attributes.id;
        });

        categoryLoader.on("load", function(treeLoader, node, config) {
            varienWindowOnload();
        });
        var tree = new Ext.tree.TreePanel('[entity]-categories', {
            animate:true,
            loader: categoryLoader,
            enableDD:false,
            containerScroll: true,
            rootUIProvider: Ext.tree.CheckboxNodeUI,
            selModel: new Ext.tree.CheckNodeMultiSelectionModel(),
            rootVisible: '<?php echo $this->getRootNode()->getIsVisible() ?>'
        });
        tree.on('check', function(node) {
            if(node.attributes.checked) {
                categoryAdd(node.id);
            } else {
                categoryRemove(node.id);
            }
            varienElementMethods.setHasChanges(node.getUI().checkbox);
        }, tree);
        var root = new Ext.tree.TreeNode({
            text: '<?php echo $this->jsQuoteEscape($this->getRootNode()->getName()) ?>',
            draggable:false,
            checked:'<?php echo $this->getRootNode()->getChecked() ?>',
            id:'<?php echo $this->getRootNode()->getId() ?>',
            disabled: <?php echo ($this->getRootNode()->getDisabled() ? 'true' : 'false') ?>,
            uiProvider: Ext.tree.CheckboxNodeUI
        });
        tree.setRootNode(root);
        bildCategoryTree(root, <?php echo $this->getTreeJson() ?>);
        tree.addListener('click', categoryClick.createDelegate(this));
        tree.render();
        root.expand();
    });
    function bildCategoryTree(parent, config){
        if (!config) {
            return null;
        }
        if (parent && config && config.length){
            for (var i = 0; i < config.length; i++){
                config[i].uiProvider = Ext.tree.CheckboxNodeUI;
                var node;
                var _node = Object.clone(config[i]);
                if (_node.children && !_node.children.length) {
                    delete(_node.children);
                    node = new Ext.tree.AsyncTreeNode(_node);

                }
                else {
                    node = new Ext.tree.TreeNode(config[i]);
                }
                parent.appendChild(node);
                node.loader = node.getOwnerTree().loader;
                if(config[i].children){
                    bildCategoryTree(node, config[i].children);
                }
            }
        }
    }
    function categoryClick(node, e){
        if (node.disabled) {
            return;
        }
        node.getUI().check(!node.getUI().checked());
        varienElementMethods.setHasChanges(Event.element(e), e);
    };
    function categoryAdd(id) {
        var ids = $('[entity]_categories').value.split(',');
        ids.push(id);
        $('[entity]_categories').value = ids.join(',');
    }
    function categoryRemove(id) {
        var ids = $('[entity]_categories').value.split(',');
        while (-1 != ids.indexOf(id)) {
            ids.splice(ids.indexOf(id), 1);
        }
        $('[entity]_categories').value = ids.join(',');
    }
</script>
<?php endif; ?>

अपनी फॉर्म फ़ाइल में जहां आप अपनी कस्टम इकाई के टैब जोड़ते हैं, यह भी जोड़ते हैं:

    $this->addTab('categories', array(
        'label' => Mage::helper('[module]')->__('Associated categories'),
        'url'   => $this->getUrl('*/*/categories', array('_current' => true)),
        'class'    => 'ajax'
    ));

अपनी कस्टम इकाई के व्यवस्थापक कंट्रोलर में इन 2 कार्यों को जो श्रेणियों के अनुरोधों को संभालेगा:

public function categoriesAction(){
    $this->_init[Entity]();
    $this->loadLayout();
    $this->renderLayout();
}
public function categoriesJsonAction(){
    $this->_init[Entity]();
    $this->getResponse()->setBody(
        $this->getLayout()->createBlock('[module]/adminhtml_[entity]_edit_tab_categories')
            ->getCategoryChildrenJson($this->getRequest()->getParam('category'))
    );
}

और सुनिश्चित करें कि एक ही नियंत्रक में यह विधि मौजूद है:

protected function _init[Entity](){
    $[entity]Id  = (int) $this->getRequest()->getParam('id');
    $[enity]    = Mage::getModel('[module]/[entity]');

    if ($[entity]Id) {
        $[entity]->load($[entity]Id);
    }
    Mage::register('current_[entity]', $[entity]);
    return $[entity];
}

अपने मॉड्यूल के व्यवस्थापक लेआउट फ़ाइल में श्रेणियों की कार्रवाई के लिए इस हैंडल को जोड़ें:

<adminhtml_[module]_[entity]_categories>
    <block type="core/text_list" name="root" output="toHtml">
        <block type="[module]/adminhtml_[entity]_edit_tab_categories" name="[entity].edit.tab.categories"/>
    </block>
</adminhtml_[module]_[entity]_categories>

अब अपने डेटा की बचत के लिए आगे बढ़ते हैं।
इसके लिए आपको अपने मॉड्यूल की इंस्टॉल / अपग्रेड स्क्रिप्ट में से एक में निम्नलिखित की आवश्यकता होगी। यह एक तालिका बनाएगा जहां लिंक किए गए मान संग्रहीत किए जाएंगे

$table = $this->getConnection()
    ->newTable($this->getTable('[module]/[entity]_category'))
    ->addColumn('rel_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'unsigned'  => true,
        'identity'  => true,
        'nullable'  => false,
        'primary'   => true,
        ), 'Relation ID')
    ->addColumn('[entity]_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'unsigned'  => true,
        'nullable'  => false,
        'default'   => '0',
    ), '[Entity] ID')
    ->addColumn('category_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'unsigned'  => true,
        'nullable'  => false,
        'default'   => '0',
    ), 'Category ID')
    ->addColumn('position', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'nullable'  => false,
        'default'   => '0',
    ), 'Position')
    ->addIndex($this->getIdxName('[module]/[entity]_category', array('category_id')), array('category_id'))
    ->addForeignKey($this->getFkName('[module]/[entity]_category', '[entity]_id', '[module]/[entity]', 'entity_id'), '[entity]_id', $this->getTable('[module]/[entity]'), 'entity_id', Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
    ->addForeignKey($this->getFkName('[module]/[entity]_category', 'category_id', 'catalog/category', 'entity_id'),    'category_id', $this->getTable('catalog/category'), 'entity_id', Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
    ->addIndex(
    $this->getIdxName(
        '[module]/[entity]_category',
        array('[entity]_id', 'category_id'),
        Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE
    ),
    array('[entity]_id', 'category_id'),
    array('type' => Varien_Db_Adapter_Interface::INDEX_TYPE_UNIQUE))
    ->setComment('[Entity] to Category Linkage Table');
$this->getConnection()->createTable($table);

अपनी तालिका घोषित करें। इसे टैग के config.xmlअंदर जोड़ें<[module]_resource><entities>

<[entity]_category>
    <table>[module]_[entity]_category</table>
</[entity]_category>

श्रेणियों से जोड़ने के लिए आपको एक मॉडल की आवश्यकता होगी:
app/code/local/[Namespace]/[Module]/Model/[Entity]/Category.php

<?php

class [Namespace]_[Module]_Model_[Entity]_Category
    extends Mage_Core_Model_Abstract {
    protected function _construct(){
        $this->_init('[module]/[entity]_category');
    }
    public function save[Entity]Relation($[entity]){
        $data = $[entity]->getCategoriesData();
        if (!is_null($data)) {
            $this->_getResource()->save[Entity]Relation($[entity], $data);
        }
        return $this;
    }
    public function getCategoryCollection($[entity]){
        $collection = Mage::getResourceModel('[module]/[entity]_category_collection')
            ->add[Entity]Filter($[entity]);
        return $collection;
    }
}

और एक संसाधन मॉडल app/code/local/[Namespace]/[Module]/Model/Resource/[Entity]/Category.php:

<?php

class [Namespace]_[Module]_Model_Resource_[Entity]_Category
    extends Mage_Core_Model_Resource_Db_Abstract {

    protected function  _construct(){
        $this->_init('[module]/[entity]_category', 'rel_id');
    }
    public function save[Entity]Relation($[entity], $data){
        if (!is_array($data)) {
            $data = array();
        }
        $deleteCondition = $this->_getWriteAdapter()->quoteInto('[entity]_id=?', $[entity]->getId());
        $this->_getWriteAdapter()->delete($this->getMainTable(), $deleteCondition);

        foreach ($data as $categoryId) {
            if (!empty($categoryId)){
                $this->_getWriteAdapter()->insert($this->getMainTable(), array(
                    '[entity]_id'      => $[entity]->getId(),
                    'category_id'     => $categoryId,
                    'position'      => 1
                ));
            }
        }
        return $this;
    }
}

और एक संग्रह संसाधन मॉडल: app/code/local/[Namespace]/[Module]/Model/Resource/[Entity]/Category/Collection.php

<?php
class [Namespace]_[Module]_Model_Resource_[Entity]_Category_Collection
    extends Mage_Catalog_Model_Resource_Category_Collection{
    protected $_joinedFields = false;
    public function joinFields(){
        if (!$this->_joinedFields){
            $this->getSelect()->join(
                array('related' => $this->getTable('[module]/[entity]_category')),
                'related.category_id = main_table.entity_id',
                array('position')
            );
            $this->_joinedFields = true;
        }
        return $this;
    }
    public function add[Entity]Filter($[entity]){
        if ($[entity] instanceof [Namespace]_[Module]_Model_[Entity]){
            $[entity] = $[entity]->getId();
        }
        if (!$this->_joinedFields){
            $this->joinFields();
        }
        $this->getSelect()->where('related.[entity]_id = ?', $[entity]);
        return $this;
    }
}

अब अपने एडमिन कंट्रोलर के सेव में कॉल करने से पहले इस राइट को ऐड करें $[entity]->save()

$categories = $this->getRequest()->getPost('category_ids', -1);
if ($categories != -1) {
    $categories = explode(',', $categories);
    $categories = array_unique($categories);
    $[entity]->setCategoriesData($categories);
}

अपने इकाई मॉडल में इसे अपनी कक्षा के शीर्ष पर जोड़ें: protected $_categoryInstance = null;और ये विधियाँ कहीं भी:

protected function _afterSave() {
    $this->getCategoryInstance()->save[Entity]Relation($this);
    return parent::_afterSave();
}
public function getCategoryInstance(){
    if (!$this->_categoryInstance) {
        $this->_categoryInstance = Mage::getSingleton('[module]/[entity]_category');
    }
    return $this->_categoryInstance;
}
public function getSelectedCategories(){
    if (!$this->hasSelectedCategories()) {
        $categories = array();
        foreach ($this->getSelectedCategoriesCollection() as $category) {
            $categories[] = $category;
        }
        $this->setSelectedCategories($categories);
    }
    return $this->getData('selected_categories');
}
public function getSelectedCategoriesCollection(){
    $collection = $this->getCategoryInstance()->getCategoryCollection($this);
    return $collection;
}

यह इसके बारे में। मुझे आशा है कि मैंने कुछ भी याद नहीं किया। कोड को कुछ परिवर्तनों की आवश्यकता हो सकती है क्योंकि मुझे नहीं पता कि आपका मॉड्यूल वास्तव में कैसे बनाया गया है, लेकिन मुख्य विचार वहाँ हैं। कुछ डिबगिंग के साथ आपको इसे काम करना चाहिए।


नोट: उपरोक्त कोड अंतिम मॉड्यूल निर्माता v1.9 का उपयोग करके उत्पन्न किया गया था ।


अद्भुत पोस्ट! आपको फॉलो करने के लिए थोड़े कौशल की आवश्यकता होती है, लेकिन अगर आप इस तरह के उत्तर की तलाश में हैं तो आपके पास यह पर्याप्त होना चाहिए। एक टाइपो कहीं हैं (माफ करना, मैं बिल्कुल ठीक नहीं है जहाँ) एक समारोह कहा जाता है ... gradoTy ... gradoRy के बजाय। शुक्रिया मारियस
Giuseppe

आपने अपने मॉड्यूल में डेटा प्राप्त करने और इसे देखने के लिए मैगेंटो श्रेणी के पेड़ एपीआई का उपयोग क्यों नहीं किया। आप इसके साथ बहुत आसानी से खेल सकते हैं।
सौरभ मोदी

@SourabhModi। मैंने उसी तरह श्रेणी कनेक्शन को फिर से बनाया है जो श्रेणियों में उत्पाद को जोड़ने / संपादित करने के लिए किसी उत्पाद को जोड़ने के लिए उपयोग किया जाता है। मैंने इसे लगातार बनाए रखने के बारे में सोचा।
मारियस

मैंने अपने डेटा को category_ids नामक मॉडल फ़ील्ड में सहेजा है।
ग्यूसेप

1
@ मेरी बात आपकी समझ में आ गई लेकिन बात यह है कि अगर आप Magento के API को कॉल कर रहे हैं तो आपकी तरफ से कोड की तुलना में बहुत कम होगा और आंतरिक रूप से Magento वही कर रहा है जब एपीआई को कहा जाता है जैसे उन्होंने उत्पाद जोड़ने / संपादित करने के रूप में श्रेणी को जोड़ा है। । तो इस कोड को फिर से अपने अंत में लिखने का कोई फायदा नहीं है क्योंकि आप एक फ़ंक्शन (एपीआई कॉल एक फ़ंक्शन कॉल) को कॉल करके समान कार्यप्रणाली का उपयोग कर सकते हैं जो आंतरिक रूप से उसी आवश्यक कार्य का उपयोग करते हैं जैसे कि उत्पाद जोड़ें / संपादित करें प्रपत्र।
सौरभ मोदी

2

Magento 1.9 के लिए कम से कम आपको यह सुनिश्चित करना होगा कि extJs लोड हो गया है।
बैकएंड में extJS के उपयोग को सक्रिय करने के लिए निम्न विधियों में से एक का उपयोग करें:

  1. अपने नियंत्रक में इसका उपयोग करें:

    $this->getLayout()->getBlock('head')->setCanLoadExtJs(true);
  2. अपने लेआउट में xml इसका उपयोग करें:

    <reference name="head">
        <action method="setCanLoadExtJs">
            <value>1</value>
        </action>
    </reference>
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.