Magento - 扩展Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection类

时间:2010-10-06 22:06:44

标签: magento

好的,所以这是我最近在这里提出的另一个问题的引导。基本上,我想扩展 Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection 类,因此我可以为可以在我的商店中重复使用的产品集合添加一些额外的过滤器(例如最畅销的)。这是为了替换我目前使用的以下代码,它位于我的template.phtml文件中:

$_bs_productCollection = Mage::getResourceModel('reports/product_collection')
->addAttributeToSelect('name')
->addAttributeToFilter('visibility', $visibility)
->addOrderedQty()
->setOrder('ordered_qty', 'desc')
->setPageSize(6);
$_bs_productCollection->load();

所以,我设置了我的模块,它正在加载(它显示在admin / system / config / advanced中)。文件夹结构如下:

etc/modules/Samsmodule.xml
local/Samsmodule
local/Samsmodule/Catalog
local/Samsmodule/Catalog/etc
   local/Samsmodule/Catalog/etc/config.xml
local/Samsmodule/Catalog/Model
   local/Samsmodule/Catalog/Model/Resource/Eav/Mysql4/Product/Collection.php
local/Samsmodule/Catalog/Helper (not sure if this is needed or not)

我的 Samsmodule.xml 是:

<config>
<modules>
    <Samsmodule_Catalog>
        <active>true</active>
        <codePool>local</codePool>
    </Samsmodule_Catalog>
</modules>
</config>

我的 config.xml 是:

<config>
<modules>
    <Samsmodule_Catalog>
        <version>0.1.0</version>
    </Samsmodule_Catalog>
</modules>
<global>
    <models>
        <catalog_resource_eav_mysql4>
            <rewrite>
                <product_collection>Samsmodule_Catalog_Model_Resource_Eav_Mysql4_Product_Collection</product_collection>
            </rewrite>
        </catalog_resource_eav_mysql4>
    </models>
</global>
</config>

我的 Collection.php 是:

<?php

class Samsmodule_Catalog_Model_Resource_Eav_Mysql4_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection

{
public function filterbyBestSelling($attribute,$visibility,$_category,$no_of_items)
{
    $this->addAttributeToSelect($attribute)->addOrderedQty()->setOrder('ordered_qty', 'desc')->addAttributeToFilter('visibility', $visibility)->addCategoryFilter($_category)->setPageSize($no_of_items);
    return $this;
}
}

然后从我的template.phtml中我这样称呼它:

$_bs_productCollection = Mage::getResourceModel('reports/product_collection')
->filterbyBestSelling('name',$visibility,$_category,6);

但它不起作用 - 我错过了什么?如果我只是将 Collection.php 中的代码添加到核心 Collection.php 文件的底部,并使用相同的调用,则可以正常使用。

2 个答案:

答案 0 :(得分:21)

(并不是故意让你挂在另一个帖子里,但是对于这个没有快速答案的人来说,这些答案看起来不会像魔术或只是让人们更进一步混淆。)

除非您要更改现有方法的行为,否则无需覆盖类。您只需要创建一个扩展现有类的新类。这是你如何做到的。

正常状态术语

  1. 模型是定义Magento中某些“东西”(产品等)行为的逻辑类/对象

  2. 模型包含模型资源。模型资源是从某些数据存储(mysql等)实际获取数据的类。这是数据映射器模式。

  3. 集合是具有类似数组属性的对象,用于查询数据库并返回一组模型。有点混乱,收藏品模型资源。

  4. 所以,在正常情况下,你可能会说像

    Mage::getModel('catalog/product')
    

    获取产品模型,底层系统使用

    Mage::getResourceModel('catalog/product');
    

    获取查询单个产品的Mode Resource对象,并使用以下

    Mage::getResourceModel('catalog/product_collection');
    Mage::getModel('catalog/product')->getCollection();
    

    获取查询许多模型的Collection对象。在当前版本的Magento中,每个Model对象都有一个名为“getCollection”的方法,该方法返回其相应的Collection Resource。

    报告关闭Rails

    报告有点横向,但一切仍然在如上所述的同一个世界中。事实证明,没有像

    这样的模型
    Mage::getModel('reports/product');
    

    有一个集合

    Mage::getResourceModel('reports/product_collection')
    

    如果你看一下课程(你将在下面展开),你会看到'reports / product_collection'集合

    class Mage_Reports_Model_Mysql4_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
    

    扩展了基础产品系列类。换句话说,在报告部分工作的客户端程序员虽然你做了完全相同的事情。 “我想向Mage::getModelResource('catalog/product_collection')添加一些方法。他们通过扩展基类来实现这一点。

    闭嘴,我只想让它工作

    所以,你真正想做的是

    1. 创建一个扩展基础Samsnamespace_Samscatalog_Model_Mysql4_Product_Collection集合类的新类Mage_Reports_Model_Mysql4_Product_Collection

    2. 确保对Mage::getModelResource('samscatalog/product_collection')的调用通过配置我们的模块来返回上述类的实例,以使用模型和模型资源。

    3. 我们也会稍微改变你的模块结构,以帮助缓解命名混乱。我不是给模块文件夹提供与核心模块相同名称(即“目录”)的忠实粉丝,而顶级文件夹(在本地/之后)实际上是命名空间,而不是模块文件夹。 (命名空间可能包含许多模块)

      我们并没有凌驾于班级之上。我们在您的命名空间下配置自定义模块以使用模型和模型资源。然后我们定义一个模型资源,它扩展了系统中已有的PHP类。仅当您希望更改特定方法调用的行为时才应使用覆盖。 (在这方面喋喋不休的应用,但在公共场合对此有足够的普遍混淆,值得喋喋不休。过去。结束。)

      首先,我们将创建模块目录结构和文件。我们只需要两个

      local/Samsnamespace/Samscatalog/etc/config.xml
      local/Samsnamespace/Samscatalog/Model/Mysql4/Product/Collection.php
      

      (不要忘记在app / etc / modules中启用模块。如果你不确定这意味着什么,start reading

      Collection.php文件应包含

      <?php
      class Samsnamespace_Samscatalog_Model_Mysql4_Product_Collection extends Mage_Reports_Model_Mysql4_Product_Collection    
      {
          /* your custom methods go here*/
      }
      

      配置文件应包含

      <config>
          <modules>
              <Samsnamespace_Samscatalog>
                  <version>0.1.0</version>
              </Samsnamespace_Samscatalog>
          </modules>
          <global>
              <models>
                  <samscatalog>
                      <class>Samsnamespace_Samscatalog_Model</class>
                      <resourceModel>samscatalog_mysql4</resourceModel>
                  </samscatalog>
      
                  <samscatalog_mysql4>
                      <class>Samsnamespace_Samscatalog_Model_Mysql4</class>
                  </samscatalog_mysql4>
              </models>
          </global>
      </config>
      

      启用这些文件并启用模块后,您应该可以调用

      $test = Mage::getResourceModel('samscatalog/product_collection');           
      var_dump(get_class($test));
      

      并且您的收藏品将被退回,您可以根据自己的内容添加方法。

      正在进行什么

      这是精神上的弯曲,所以如果你愿意,你可以停止阅读。这也是我covered elsewhere概念的重复。

      当你说

      Mage::getResourceModel('samscatalog/product_collection');
      

      底层法师系统代码说“好,所以这个资源模型”

      samscatalog/product_collection
      

      的一部分
      samscatalog/product
      

      模型(在这种情况下并非完全正确,但这是系统认为的)。

      因此,由于资源模型samscatalog/product_collectionsamscatalog/product模型的一部分,让我们看看配置

      global/models/samscatalog/resourceModel
      

      获取

      的资源模型URI
      samscatalog_mysql4
      

      然后让我们用它来查看配置

      global/models/samscatalog_mysql4/class
      

      获取属于此模块的所有资源模型的基类名。这最终成为

      Samsnamespace_Samscatalog_Model_Mysql4
      

      这意味着samscatalog/product_collection资源模型名为

      Samsnamespace_Samscatalog_Model_Mysql4_Product_Collection
      

      然后它只是Magento的标准自动加载功能

      include('Samsnamespace/Samscatalog/Model/Mysql4/Product/Collection.php');
      

答案 1 :(得分:0)

最终产品系列的类别是什么?你的覆盖是否有效?

这部分似乎很可疑,如果它确实有效,我会感到惊讶:

<global>
    <models>
        <catalog_resource_eav_mysql4>
            <rewrite>
                <product_collection>Samsmodule_Catalog_Model_Resource_Eav_Mysql4_Product_Collection</product_collection>
            </rewrite>
        </catalog_resource_eav_mysql4>
    </models>
</global>

请改为尝试:

<global>
    <models>
        <catalog>
            <rewrite>
                <resource_eav_mysql4_product_collection>Samsmodule_Catalog_Model_Resource_Eav_Mysql4_Product_Collection</resource_eav_mysql4_product_collection>
            </rewrite>
        </catalog>
    </models>
</global>

里面的标签是指模块。 Catalog是一个模块,而catalog_resource_eav_mysql4则不是。其中的标记指定了一个类句柄,它基本上是类名中Mage_Catalog_Model_之后的所有内容。

希望有所帮助!

谢谢, 乔