So erstellen Sie den Product Grid Serializer-Block im benutzerdefinierten Modul

8

Ich möchte die Grid Serializergleiche Funktionalität wie in den Kategorien "Verwalten" erstellen

Wenn jemand diese Art von Funktionalität erstellt, leiten Sie mich bitte.

Keyul Shah
quelle

Antworten:

15

Angenommen, Sie haben das Modul ohne Produktbeziehung, dann benötigen Sie zusätzlich.
Erstellen Sie zunächst eine Beziehungstabelle zwischen Ihrer Entität und den Produkten. Fügen Sie dies in config.xmlderglobal/models/[module]_resource/entities

<[entity]_product>
    <table>[entity]_product</table>
</[entity]_product>

Fügen Sie dies in einem der upgrade scripts.

$table = $this->getConnection()
    ->newTable($this->getTable('[module]/[entity]_product'))
    ->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('product_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'unsigned'  => true,
        'nullable'  => false,
        'default'   => '0',
    ), 'Product ID')
    ->addColumn('position', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array(
        'nullable'  => false,
        'default'   => '0',
    ), 'Position')
    ->addIndex($this->getIdxName('[module]/[entity]_product', array('product_id')), array('product_id'))
    ->addForeignKey($this->getFkName('[module]/[entity]_product', '[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]_product', 'product_id', 'catalog/product', 'entity_id'),    'product_id', $this->getTable('catalog/product'), 'entity_id', Varien_Db_Ddl_Table::ACTION_CASCADE, Varien_Db_Ddl_Table::ACTION_CASCADE)
    ->setComment('[Entity] to Product Linkage Table');
$this->getConnection()->createTable($table);

Erstellen Sie nun den Rasterblock. [Namespace]/[Module]/Block/Adminhtml/[Entity]/Edit/Tab/Product.php

<?php
class [Namespace]_[Module]_Block_Adminhtml_[Entity]_Edit_Tab_Product
    extends Mage_Adminhtml_Block_Widget_Grid {
    public function __construct(){
        parent::__construct();
        $this->setId('product_grid');
        $this->setDefaultSort('position');
        $this->setDefaultDir('ASC');
        $this->setUseAjax(true);
        if ($this->get[Entity]()->getId()) {
            $this->setDefaultFilter(array('in_products'=>1));
        }
    }
    protected function _prepareCollection() {
        $collection = Mage::getResourceModel('catalog/product_collection');
        $collection->addAttributeToSelect('price');
        $adminStore = Mage_Core_Model_App::ADMIN_STORE_ID;
        $collection->joinAttribute('product_name', 'catalog_product/name', 'entity_id', null, 'left', $adminStore);
        if ($this->get[Entity]()->getId()){
            $constraint = '{{table}}.[entity]_id='.$this->get[Entity]()->getId();
        }
        else{
            $constraint = '{{table}}.[entity]_id=0';
        }
        $collection->joinField('position',
            '[module]/[entity]_product',
            'position',
            'product_id=entity_id',
            $constraint,
            'left');
        $this->setCollection($collection);
        parent::_prepareCollection();
        return $this;
    }
     protected function _prepareMassaction(){
        return $this;
    }
    protected function _prepareColumns(){
        $this->addColumn('in_products', array(
            'header_css_class'  => 'a-center',
            'type'  => 'checkbox',
            'name'  => 'in_products',
            'values'=> $this->_getSelectedProducts(),
            'align' => 'center',
            'index' => 'entity_id'
        ));
        $this->addColumn('product_name', array(
            'header'=> Mage::helper('catalog')->__('Name'),
            'align' => 'left',
            'index' => 'product_name',
        ));
        $this->addColumn('sku', array(
            'header'=> Mage::helper('catalog')->__('SKU'),
            'align' => 'left',
            'index' => 'sku',
        ));
        $this->addColumn('price', array(
            'header'=> Mage::helper('catalog')->__('Price'),
            'type'  => 'currency',
            'width' => '1',
            'currency_code' => (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE),
            'index' => 'price'
        ));
        $this->addColumn('position', array(
            'header'=> Mage::helper('catalog')->__('Position'),
            'name'  => 'position',
            'width' => 60,
            'type'  => 'number',
            'validate_class'=> 'validate-number',
            'index' => 'position',
            'editable'  => true,
        ));
    }
    protected function _getSelectedProducts(){
        $products = $this->get[Entity]Products();
        if (!is_array($products)) {
            $products = array_keys($this->getSelectedProducts());
        }
        return $products;
    }
    public function getSelectedProducts() {
        $products = array();
        $selected = Mage::registry('current_[entity]')->getSelectedProducts();
        if (!is_array($selected)){
            $selected = array();
        }
        foreach ($selected as $product) {
            $products[$product->getId()] = array('position' => $product->getPosition());
        }
        return $products;
    }
    public function getRowUrl($item){
        return '#';
    }
    public function getGridUrl(){
        return $this->getUrl('*/*/productsGrid', array(
            'id'=>$this->get[Entity]()->getId()
        ));
    }
    public function get[Entity](){
        return Mage::registry('current_[entity]');
    }
    protected function _addColumnFilterToCollection($column){
        // Set custom filter for in product flag
        if ($column->getId() == 'in_products') {
            $productIds = $this->_getSelectedProducts();
            if (empty($productIds)) {
                $productIds = 0;
            }
            if ($column->getFilter()->getValue()) {
                $this->getCollection()->addFieldToFilter('entity_id', array('in'=>$productIds));
            }
            else {
                if($productIds) {
                    $this->getCollection()->addFieldToFilter('entity_id', array('nin'=>$productIds));
                }
            }
        }
        else {
            parent::_addColumnFilterToCollection($column);
        }
        return $this;
    }
}

Fügen Sie nun diese Registerkarte in die Liste der Registerkarten ein. In [Namespace]_[Module]_Block_Adminhtml_[Entity]_Edit_Tabs::_beforeToHtmlfügen Sie diese unter dem Hauptregister.

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

Jetzt benötigen Sie die Controller-Aktionen, um die Produkte zu handhaben.

Fügen Sie dem Administrator-Controller für Ihre Entität diese Methoden hinzu:

public function productsAction(){
    $this->_initEntity(); //if you don't have such a method then replace it with something that will get you the entity you are editing.
    $this->loadLayout();
    $this->getLayout()->getBlock('[entity].edit.tab.product')
        ->set[Entity]Products($this->getRequest()->getPost('[entity]_products', null));
    $this->renderLayout();
}
public function productsgridAction(){
    $this->_init[Entity]();
    $this->loadLayout();
    $this->getLayout()->getBlock('[entity].edit.tab.product')
        ->set[Entity]Products($this->getRequest()->getPost('[entity]_products', null));
    $this->renderLayout();
}

Nun das Layout für diese 2 Aktionen. Fügen Sie in der Admin-Layoutdatei für Ihr Modul diese beiden Handles hinzu.

<adminhtml_[module]_[entity]_products>
    <block type="core/text_list" name="root" output="toHtml">
        <block type="[module]/adminhtml_[entity]_edit_tab_product" name="[entity].edit.tab.product"/>
        <block type="adminhtml/widget_grid_serializer" name="product_grid_serializer">
            <reference name="product_grid_serializer">
                <action method="initSerializerBlock">
                    <grid_block_name>[entity].edit.tab.product</grid_block_name>
                        <data_callback>getSelectedProducts</data_callback>
                        <hidden_input_name>products</hidden_input_name>
                        <reload_param_name>[entity]_products</reload_param_name>
                </action>
                <action method="addColumnInputName">
                    <input_name>position</input_name>
                </action>
            </reference>
        </block>
    </block>
</adminhtml_[module]_[entity]_products>
<adminhtml_[module]_[entity]_productsgrid>
    <block type="core/text_list" name="root" output="toHtml">
        <block type="[module]/adminhtml_[entity]_edit_tab_product" name="[entity].edit.tab.product"/>
    </block>
</adminhtml_[module]_[entity]_productsgrid>

Speichern Sie nun die Daten. In dem saveActionvon Ihrem Admin - Controller hinzufügen , um dieses Recht vor dem Aufruf$[entity]->save()

$products = $this->getRequest()->getPost('products', -1);
if ($products != -1) {
    $[entity]->setProductsData(Mage::helper('adminhtml/js')->decodeGridSerializedInput($products));
}

Fügen Sie in Ihrem Entitätsmodell die folgenden Methoden und eine Elementvariable hinzu, die die Produktbeziehung verarbeitet:

protected $_productInstance = null;
public function getProductInstance(){
    if (!$this->_productInstance) {
        $this->_productInstance = Mage::getSingleton('[module]/[entity]_product');
    }
    return $this->_productInstance;
}
protected function _afterSave() {
    $this->getProductInstance()->save[Entity]Relation($this);
    return parent::_afterSave();
}
public function getSelectedProducts(){
    if (!$this->hasSelectedProducts()) {
        $products = array();
        foreach ($this->getSelectedProductsCollection() as $product) {
            $products[] = $product;
        }
        $this->setSelectedProducts($products);
    }
    return $this->getData('selected_products');
}
public function getSelectedProductsCollection(){
    $collection = $this->getProductInstance()->getProductCollection($this);
    return $collection;
}

Jetzt benötigen Sie das Entity-Product-Relationship-Modell.

Erstellen [Namespace]/[Module]/Model/[Entity]/Product.php

<?php
class [Namespace]_[Module]_Model_[Entity]_Product
    extends Mage_Core_Model_Abstract {
    protected function _construct(){
        $this->_init('[module]/[entity]_product');
    }
    public function save[Entity]Relation($[entity]){
        $data = $[entity]->getProductsData();
        if (!is_null($data)) {
            $this->_getResource()->save[Entity]Relation($[entity], $data);
        }
        return $this;
    }
    public function getProductCollection($[entity]){
        $collection = Mage::getResourceModel('[module]/[entity]_product_collection')
            ->add[Entity]Filter($[entity]);
        return $collection;
    }
}

Sie benötigen auch ein Ressourcenmodell. [Namespace]/[Module]/Model/Resource/[Entity]/Product.php

<?php
class [Namespace]_[Module]_Model_Resource_[Entity]_Product
    extends Mage_Core_Model_Resource_Db_Abstract {
    protected function  _construct(){
        $this->_init('[module]/[entity]_product', '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 $productId => $info) {
            $this->_getWriteAdapter()->insert($this->getMainTable(), array(
                '[entity]_id'      => $[entity]->getId(),
                'product_id'     => $productId,
                'position'      => @$info['position']
            ));
        }
        return $this;
    }
}

und ein Sammlungsressourcenmodell. Ich verspreche, dass dies der letzte ist.[Namespace]/[Module]/Model/Resource/[Entity]/Product/Collection.php

<?php 
class [Namespace]_[Module]_Model_Resource_[Entity]_Product_Collection
    extends Mage_Catalog_Model_Resource_Product_Collection {
    protected $_joinedFields = false;
    public function joinFields(){
        if (!$this->_joinedFields){
            $this->getSelect()->join(
                array('related' => $this->getTable('[module]/[entity]_product')),
                'related.product_id = e.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;
    }
}

Alles , was Sie tun müssen , ist , die Werte zwischen ersetzen []( [Namespace], [Module], [module], ...) mit realen Werten.
Möglicherweise treten Fehler auf, da die Art und Weise, wie Sie Ihr Modul strukturiert haben, möglicherweise etwas anders ist als ich es mir vorgestellt habe. Aber mit einigen Debugging- und Änderungsvorgängen können Sie es zum Laufen bringen. Das ganze schwere Heben ist da.

Das ist es.

Hinweis: Der obige Code wurde von dem, was mit UMC generiert wurde, kopiert / eingefügt (und die Dateinamen umbenannt) . Damit können Sie Ihr vollständiges Modul erstellen, ohne sich Gedanken über die Verknüpfung Ihrer Entität mit Produkten machen zu müssen. Sie sagen einfach in der Benutzeroberfläche "Entität mit Produkten verknüpfen: Ja".


Dies ist kein Spam. Die Erweiterung ist kostenlos.

Marius
quelle
2
Ich bin nur neugierig, ob die Person (en), die dies positiv bewertet haben, alles lesen :).
Marius
Hats Off Buddy du bist Grate :) Ich versuche es und lass dich, wenn ich ein Problem habe :)
Keyul Shah
Ich bin auch neugierig, ob die Person (en), die die Fragen bewertet haben.
Keyul Shah
Ich benutze diesen Code und es funktioniert sehr gut. Vielen Dank, Männer. :)
Keyul Shah
So legen Sie den Datenbankwert im verborgenen Eingabefeld fest
ND17