Magento Custom Collection防止正确的按摩复选框选择

时间:2015-04-23 12:32:24

标签: php mysql magento checkbox collections

Magento 1.7.0.2 - 我通过扩展Catalog Product Collection创建了一个自定义集合。基本上是集合是什么:产品的独特组合的集合,如果任何产品具有自定义选项,则产品id /选项id的每个唯一组合是集合中的另一项。收集和计数工作得很好。

然而,"全选"批量操作复选框选择按钮仅选择具有产品ID的行,而不选择product_id与option_id连接的行,如下图所示。

enter image description here

这是我的集合类。

<?php 

class Lightsnholsters_Inventory_Model_Resource_Catalog_Product_Collection extends Mage_Catalog_Model_Resource_Product_Collection
{
  public function getSelectCountSql()
  {   
      $this->_renderFilters();
      $countSelect = clone $this->getSelect();
      $countSelect->reset(Zend_Db_Select::ORDER);
      $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
      $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
      $countSelect->reset(Zend_Db_Select::COLUMNS);

      // Count doesn't work with group by columns keep the group by 
      if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) {
          $countSelect->reset(Zend_Db_Select::GROUP);
          $countSelect->distinct(true);
          $group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
          $countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");
      } else {
          $countSelect->columns('COUNT(*)');
      }
      return $countSelect;
  }

  protected function _initSelect()
  {
      parent::_initSelect();
      $this->joinAttribute('name','catalog_product/name','entity_id');                  

      $this->getSelect()->reset(Zend_Db_Select::COLUMNS);

      $this->getSelect()->joinLeft(
          array('opt' => $this->getTable('catalog/product_option')),
          "e.entity_id = opt.product_id AND opt.type IN('radio','drop_down')",
          array(''));

      $this->getSelect()->joinLeft(
          array('opt_val' => $this->getTable('catalog/product_option_type_value')),
          "opt.option_id = opt_val.option_id AND opt_val.sku != '' AND opt_val.sku IS NOT NULL",
          array('entity_id' => new Zend_Db_Expr("CONCAT_WS('_',e.entity_id,opt_val.option_type_id)"),
                'option_type_id' => new Zend_Db_Expr("IF(opt_val.option_type_id > 0, opt_val.option_type_id,0)")));

      $this->getSelect()->joinLeft(
          array('opt_prc' => $this->getTable('catalog/product_option_type_price')),
          "opt_val.option_type_id = opt_prc.option_type_id AND opt_prc.store_id = {$this->getStoreId()}",
          array(''));

      $this->getSelect()->joinLeft(
          array('opt_ttl' => $this->getTable('catalog/product_option_type_title')),
          "opt_val.option_type_id = opt_ttl.option_type_id AND opt_ttl.store_id = {$this->getStoreId()}",
          array('name' => new Zend_Db_Expr("CONCAT_WS(' ',at_name.value,title)")));

      return $this;
  }  
}

以下是我在网格类中使用的按摩代码

  protected function _prepareMassaction()
  {
    $this->setMassactionIdField('entity_id');
    $this->setMassactionIdFilter('entity_id');
    $this->getMassactionBlock()->setFormFieldName('entity_id');

    $this->getMassactionBlock()->addItem('updateAttributes', array(
      'label'   => $this->__('Update Attributes'),
      'url'     => $this->getUrl('*/*/massUpdateAttributes'),
    ));

    $statuses = array(
      array('label' => '',                    'value'=>''),
      array('label' => $this->__('Disabled'), 'value'=>0 ),
      array('label' => $this->__('Enabled') , 'value'=>1 )
    );
    $this->getMassactionBlock()->addItem('status', array(
         'label'=> $this->__('Change status'),
         'url'  => $this->getUrl('*/*/massStatus', array('_current'=>true)),
         'additional' => array(
             'visibility'  => array(
             'name'   => 'status',
             'type'   => 'select',
             'class'  => 'required-entry',
             'label'  => $this->__('Status'),
             'values' => $statuses
           )
         )
    ));

    Mage::dispatchEvent('lightsnholsters_inventory_autolist_grid_massaction_prepare', array('block' => $this));
    return $this;
  } 

似乎我放在$this->setMassactionIdField('entity_id');中的任何字段都被完全忽略了。

我的目标是当我点击&#34;全选&#34;选中所有复选框,而不仅仅是那些没有连接option_id的复选框。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我已经重新审视了这个问题,并找出了为什么我的集合是有目的地动态创建的 - &gt; joinLeft和动态创建的id列,不允许使用massaction块“Select All”来正确选择单击时的复选框。

因为当我将Mage_Catalog_Model_Resource_Collection扩展为我自己的自定义集合的基础时,该类已经覆盖了Varien_Data_Collection的getAllIds()方法,该方法用于确定哪些ID我们实际上想要在点击“全选”时选择。

在我的模块集合类中,我扩展了Magento的产品集合,我只需要创建自己的getAllIds()方法,它将完全覆盖方法的父版本。

简单地说,一切都很完美,请参阅下面的代码。

<?php 

class Lightsnholsters_Inventory_Model_Resource_Catalog_Product_Collection extends Mage_Catalog_Model_Resource_Product_Collection
{
  /*
  *
  * we had to rewrite this function because the grid had the wrong count, which is actually why we created this class to begin with
  *
  */
  public function getSelectCountSql()
  {   
      $this->_renderFilters();
      $countSelect = clone $this->getSelect();
      $countSelect->reset(Zend_Db_Select::ORDER);
      $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
      $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
      $countSelect->reset(Zend_Db_Select::COLUMNS);

      // Count doesn't work with group by columns keep the group by 
      if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) {
          $countSelect->reset(Zend_Db_Select::GROUP);
          $countSelect->distinct(true);
          $group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
          $countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");
      } else {
          $countSelect->columns('COUNT(*)');
      }
      return $countSelect;
  }

  protected function _initSelect()
  {
      parent::_initSelect();
      $this->joinAttribute('name','catalog_product/name','entity_id');                  

      $this->getSelect()->reset(Zend_Db_Select::COLUMNS);

      $this->getSelect()->joinLeft(
          array('opt' => $this->getTable('catalog/product_option')),
          "e.entity_id = opt.product_id AND opt.type IN('radio','drop_down')",
          array(''));

      $this->getSelect()->joinLeft(
          array('opt_val' => $this->getTable('catalog/product_option_type_value')),
          "opt.option_id = opt_val.option_id AND opt_val.sku != '' AND opt_val.sku IS NOT NULL",
          array('entity_id' => new Zend_Db_Expr("CONCAT_WS('_',e.entity_id,opt_val.option_type_id)"),
                'option_type_id' => new Zend_Db_Expr("IF(opt_val.option_type_id > 0, opt_val.option_type_id,0)")));

      $this->getSelect()->joinLeft(
          array('opt_prc' => $this->getTable('catalog/product_option_type_price')),
          "opt_val.option_type_id = opt_prc.option_type_id AND opt_prc.store_id = {$this->getStoreId()}",
          array(''));

      $this->getSelect()->joinLeft(
          array('opt_ttl' => $this->getTable('catalog/product_option_type_title')),
          "opt_val.option_type_id = opt_ttl.option_type_id AND opt_ttl.store_id = {$this->getStoreId()}",
          array('name' => new Zend_Db_Expr("CONCAT_WS(' ',at_name.value,title)")));

      return $this;
  }  

  /*
  *
  * we override the parent method for all ids because it does not fetch the proper ids for the massaction checkboxes
  *
  */
  public function getAllIds($limit = null, $offset = null)
  {
    $this->_renderFilters();
    $connection = $this->getConnection();
    $idsSelect = clone $this->getSelect();
    $idsSelect->reset(Zend_Db_Select::LIMIT_COUNT);
    $idsSelect->reset(Zend_Db_Select::LIMIT_OFFSET);    
    $statement = $connection->query($idsSelect);
    $ids = $statement->fetchAll(PDO::FETCH_COLUMN);
    return $ids;
  }  
}