dongzhuo1733 2011-07-03 13:13
浏览 24
已采纳

如何在搜索后将“缺货”产品移至列表末尾?

I am a newbie in magento and I need your help. I need to move 'out of stock' products to the end of the lists in search results. How can I do this?

I've found that module catalogsearch is used for searching. Also I've seen there is a table cataloginventory_stock_item and is_in_stock field. Is this a correct flag for checking product is out of stock or not. And I think I should add also an order condition when data is getting from DB. But I can not find where(a file) this data is getting form catalogsearch_query and catalogsearch_result tables and where (and how) should I add an order condition. Can you give me an example?

  • 写回答

2条回答 默认 最新

  • dongshi1868 2011-07-05 14:49
    关注

    I did it. And I would like to share my method with you. Maybe it's a very easy to do for guy who have already worked with magento, but not for newbie.

    The 'CatalogSearch' module is responsible for search through product catalog. The module's path is 'DOC_ROOT/app/code/core/Mage/CatalogSearch'.

    First of all, we should not edit core files (files in 'Mage' folder) and must override core classes and function. To achieve our goal (my topic question) we should edit some function in different classes, so we need to override this functions.

    The are 2 kinds of search thought product catalog in Magento: Simple and Advanced (maybe more, but I don't know another) and we'll influence on these 2 types.

    Step 1: We should tell Magento engine, that we would like to override some its core classes. Hence, we create own module. Go to '/app/etc/modules/' and create file 'YourCompany_YourModuleName.xml' with follow content:

    <?xml version="1.0"?>
    <config>
        <modules>
            <YourCompany_YourModuleName>
                <active>true</active>
                <codePool>local</codePool>
            </YourCompany_YourModuleName>
        </modules>
    </config>
    

    Step 2: Now we should create our module. Go to '/app/code/local/YourCompany/YourModuleName/' and create folders 'etc'. Put 'config.xml' file in this 'etc' folder, we must tell magetno which files/classes we want to override.

    config.xml content:

    <?xml version="1.0"?>
    <config>
        <modules>
            <yourcompany_yourmodulename>
                <version>0.1.0</version>
            </yourcompany_yourmodulename>
        </modules>
        <global>
            <models>
                <catalogsearch>
                    <rewrite>
                        <layer>YourCompany_YourModuleName_Model_CatalogSearch_Layer</layer>
                        <advanced>YourCompany_YourModuleName_CatalogSearch_Advanced</advanced>
                    </rewrite>
                </catalogsearch>
                <catalogsearch_mysql4>
                    <rewrite>
                        <fulltext_collection>YourCompany_YourModuleName_Model_CatalogSearch_Mysql4_Fulltext_Collection</fulltext_collection>
                        <advanced_collection>YourCompany_YourModuleName_Model_CatalogSearch_Mysql4_Advanced_Collection</advanced_collection>
                    </rewrite>
                </catalogsearch_mysql4>     
            </models>
        </global>
    </config>
    

    Now You may have noticed that we override 4 function in 4 classes.

    Step 3: Create 4 new files in our module with follow content:

    1. '/app/code/local/YourCompany/YourModuleName/Model/CatalogSearch/Advanced.php'

      class YourCompany_YourModuleName_Model_CatalogSearch_Advanced extends Mage_CatalogSearch_Model_Advanced
      {
          /**
           * Retrieve advanced search product collection
           *
           * @return Mage_CatalogSearch_Model_Mysql4_Advanced_Collection
           */
          public function getProductCollection(){
              if (is_null($this->_productCollection)) {
                  $this->_productCollection = Mage::getResourceModel('catalogsearch/advanced_collection')
                      ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
                      ->addMinimalPrice()
                      ->addTaxPercents()
                      ->addStoreFilter();
      
                  $this->_productCollection->getSelect()->joinLeft(
                      array('_inventory_table'=>'cataloginventory_stock_item'),
                      "_inventory_table.product_id = e.entity_id",
                      array('is_in_stock', 'manage_stock')
                  );
      
                  $this->_productCollection->addExpressionAttributeToSelect('on_top',
                      '(CASE WHEN (((_inventory_table.use_config_manage_stock = 1) AND (_inventory_table.is_in_stock = 1)) OR  ((_inventory_table.use_config_manage_stock = 0) AND (1 - _inventory_table.manage_stock + _inventory_table.is_in_stock >= 1))) THEN 1 ELSE 0 END)',
                  array());
      
                  Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($this->_productCollection);
                  Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($this->_productCollection);
              }
              return $this->_productCollection;
          }
      }
      
    2. /app/code/local/YourCompany/YourModuleName/Model/CatalogSearch/Layer.php'

      class YourCompany_YourModuleName_Model_CatalogSearch_Layer extends Mage_CatalogSearch_Model_Layer
      {
          public function prepareProductCollection($collection)
          {
              $collection->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
                  ->addSearchFilter(Mage::helper('catalogsearch')->getQuery()->getQueryText())
                  ->setStore(Mage::app()->getStore())
                  ->addMinimalPrice()
                  ->addFinalPrice()
                  ->addTaxPercents()
                  ->addStoreFilter()
                  ->addUrlRewrite();
              $collection->getSelect()->joinLeft(
                      array('_inventory_table'=>'cataloginventory_stock_item'),
                      "_inventory_table.product_id = e.entity_id",
                      array('is_in_stock', 'manage_stock')
                  );
              $collection->addExpressionAttributeToSelect('on_top',
                  '(CASE WHEN (((_inventory_table.use_config_manage_stock = 1)
                  AND (_inventory_table.is_in_stock = 1)) OR  ((_inventory_table.use_config_manage_stock = 0)
                  AND (1 - _inventory_table.manage_stock + _inventory_table.is_in_stock >= 1)))
                  THEN 1 ELSE 0 END)',
              array());
              Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
              Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($collection);
              return $this;
          }
      }
      
    3. /app/code/local/YourCompany/YourModuleName/Model/CatalogSearch/Mysql4/Advanced/Collection.php'

      class YourCompany_YourModuleName_Model_CatalogSearch_Mysql4_Advanced_Collection extends
          Mage_CatalogSearch_Model_Mysql4_Advanced_Collection
      {
          public function setOrder($attribute, $dir='desc')
          {
          $this->addAttributeToSort('on_top', 'desc');
              parent::setOrder($attribute, $dir);
              return $this;
          }
      }
      
    4. '/app/code/local/YourCompany/YourModuleName/Model/CatalogSearch/Mysql4/Fulltext/Collection.php'

      class YourCompany_YourModuleName_Model_CatalogSearch_Mysql4_Fulltext_Collection
          extends Mage_CatalogSearch_Model_Mysql4_Fulltext_Collection
      {
         public function setOrder($attribute, $dir = 'desc')
          {
              if ($attribute == 'relevance') {
                  $this->getSelect()->order("on_top DESC")->order("relevance {$dir}");
              }
              else {
                  parent::setOrder('on_top', 'DESC');
                  parent::setOrder($attribute, $dir);
              }
              return $this;
          }
      }
      

    That's it. How you can see we should just connect to 'cataloginventory_stock_item' table while getting searched data to detect what product is out of stock and add additional order for products.
    Nothing special, but I've had a problem where and what should I do to achieve my goal.

    p.s. if someone can offer the better way to do this - you are welcome. Yet I could not find a proper tutorial to do this.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 informer代码训练自己的数据集,改参数怎么改
  • ¥15 请看一下,学校实验要求,我需要具体代码
  • ¥50 pc微信3.6.0.18不能登陆 有偿解决问题
  • ¥20 MATLAB绘制两隐函数曲面的交线
  • ¥15 求TYPCE母转母转接头24PIN线路板图
  • ¥100 国外网络搭建,有偿交流
  • ¥15 高价求中通快递查询接口
  • ¥15 解决一个加好友限制问题 或者有好的方案
  • ¥15 急matlab编程仿真二阶震荡系统
  • ¥20 TEC-9的数据通路实验