Cara membuat Blok Serializer Kotak Produk dalam modul Kustom


Jawaban:


15

Dengan asumsi Anda memiliki modul tanpa hubungan produk di sini adalah apa yang Anda butuhkan sebagai tambahan.
Pertama-tama buat tabel relasi antara entitas Anda dan produk. Tambahkan ini di config.xmldalamglobal/models/[module]_resource/entities

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

Tambahkan ini di salah satu 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);

Sekarang buat blok kotak. [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;
    }
}

Sekarang tambahkan tab ini di daftar tab. Di [Namespace]_[Module]_Block_Adminhtml_[Entity]_Edit_Tabs::_beforeToHtmltambahkan ini di bawah tab utama.

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

Sekarang Anda memerlukan tindakan pengontrol untuk menangani produk.

Tambahkan metode ini ke pengontrol admin untuk entitas Anda:

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();
}

Sekarang tata letak untuk 2 tindakan ini. Dalam file tata letak admin untuk modul Anda tambahkan 2 pegangan ini.

<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>

Sekarang menyimpan data. Di saveActioncontroller admin Anda tambahkan ini tepat sebelum memanggil$[entity]->save()

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

Dalam model entitas Anda, tambahkan metode ini dan variabel anggota yang akan memproses hubungan produk:

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;
}

Sekarang Anda membutuhkan model hubungan entitas-produk.

Membuat [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;
    }
}

Anda juga membutuhkan model sumber daya. [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;
    }
}

dan model sumber daya koleksi. Saya berjanji bahwa ini adalah yang terakhir.[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;
    }
}

Yang perlu Anda lakukan adalah untuk menggantikan nilai antara []( [Namespace], [Module], [module], ...) dengan nilai-nilai yang sesungguhnya.
Anda mungkin mengalami beberapa kesalahan, karena cara Anda menyusun modul Anda mungkin sedikit berbeda dari apa yang ada dalam pikiran saya. Tetapi dengan beberapa debug dan perubahan Anda bisa membuatnya berfungsi. Semua beban berat ada di sana.

Itu dia.

Catatan: Kode di atas disalin / ditempelkan (dan mengganti nama nama file) dari apa yang dihasilkan dengan UMC . Anda dapat menggunakannya untuk membuat modul lengkap Anda tanpa harus khawatir tentang menautkan entitas Anda ke produk. Anda cukup mengatakan di UI "Tautan entitas ke produk: Ya".


Ini bukan spam. Ekstensi ini gratis.


2
Saya hanya ingin tahu apakah orang yang mengangkat ini, baca semuanya :).
Marius

Angkat Buddy, kamu Grate :) Saya mencoba yang ini dan membiarkan Anda jika saya punya masalah :)
Keyul Shah

Saya juga Penasaran jika Orang yang mengangkat Pertanyaan.
Keyul Shah

Saya menggunakan kode ini dan ini bekerja dengan sangat baik Terima kasih banyak pria. :)
Keyul Shah

Cara mengatur nilai basis data di bidang tersembunyi masukan
ND17
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.