Magento - 扩展Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection类

Mar*_*ive 11 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();
Run Code Online (Sandbox Code Playgroud)

所以,我设置了我的模块,它正在加载(它显示在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)
Run Code Online (Sandbox Code Playgroud)

我的Samsmodule.xml是:

<config>
<modules>
    <Samsmodule_Catalog>
        <active>true</active>
        <codePool>local</codePool>
    </Samsmodule_Catalog>
</modules>
</config>
Run Code Online (Sandbox Code Playgroud)

我的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>
Run Code Online (Sandbox Code Playgroud)

我的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;
}
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Ala*_*orm 21

(并不是故意让你停留在另一个主题中,但是对于这个没有快速回答的那个看起来不像魔术或只是让人们进一步混淆.)

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

正常状态的术语

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

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

  3. 集合是具有类似数组属性的对象,用于查询数据库并返回一组模型.有点令人困惑的是,Collections 也是模型资源.

所以,在正常情况下,你可能会说类似的东西

Mage::getModel('catalog/product')
Run Code Online (Sandbox Code Playgroud)

获得产品模型和底层系统使用

Mage::getResourceModel('catalog/product');
Run Code Online (Sandbox Code Playgroud)

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

Mage::getResourceModel('catalog/product_collection');
Mage::getModel('catalog/product')->getCollection();
Run Code Online (Sandbox Code Playgroud)

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

报告关闭Rails

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

Mage::getModel('reports/product');
Run Code Online (Sandbox Code Playgroud)

但是有一个集合

Mage::getResourceModel('reports/product_collection')
Run Code Online (Sandbox Code Playgroud)

如果您查看课程(您将在下面进行扩展),您会看到'reports/product_collection'集合

class Mage_Reports_Model_Mysql4_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
Run Code Online (Sandbox Code Playgroud)

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

闭嘴,我只是希望这个工作

所以,你真正想做的是

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

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

我们还将稍微改变一下Module模块的结构,以帮助缓解命名混乱.我不喜欢给模块文件夹提供与核心模块相同的名称(即"目录"),顶级文件夹(在本地/之后)实际上是命名空间,而不是模块文件夹.(命名空间可能包含许多模块)

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

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

local/Samsnamespace/Samscatalog/etc/config.xml
local/Samsnamespace/Samscatalog/Model/Mysql4/Product/Collection.php
Run Code Online (Sandbox Code Playgroud)

(并且不要忘记在app/etc/modules中启用模块.如果你不确定这意味着什么,请开始阅读)

Collection.php文件应包含

<?php
class Samsnamespace_Samscatalog_Model_Mysql4_Product_Collection extends Mage_Reports_Model_Mysql4_Product_Collection    
{
    /* your custom methods go here*/
}
Run Code Online (Sandbox Code Playgroud)

并且配置文件应该包含

<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>
Run Code Online (Sandbox Code Playgroud)

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

$test = Mage::getResourceModel('samscatalog/product_collection');           
var_dump(get_class($test));
Run Code Online (Sandbox Code Playgroud)

并且您的收藏将被退回,您可以添加方法到您的心脏内容.

这是怎么回事

这是精神上的弯曲,所以如果你愿意,你可以停止阅读.这也是我在其他地方涉及的概念的重述.

当你说

Mage::getResourceModel('samscatalog/product_collection');
Run Code Online (Sandbox Code Playgroud)

基础法师系统代码说"好,所以这个资源模型"

samscatalog/product_collection
Run Code Online (Sandbox Code Playgroud)

是的一部分

samscatalog/product
Run Code Online (Sandbox Code Playgroud)

模型(在这种情况下不完全正确,但它是系统认为的).

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

global/models/samscatalog/resourceModel
Run Code Online (Sandbox Code Playgroud)

获取资源模型的URI

samscatalog_mysql4
Run Code Online (Sandbox Code Playgroud)

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

global/models/samscatalog_mysql4/class
Run Code Online (Sandbox Code Playgroud)

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

Samsnamespace_Samscatalog_Model_Mysql4
Run Code Online (Sandbox Code Playgroud)

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

Samsnamespace_Samscatalog_Model_Mysql4_Product_Collection
Run Code Online (Sandbox Code Playgroud)

然后它只是Magento的标准自动加载,它做了一个

include('Samsnamespace/Samscatalog/Model/Mysql4/Product/Collection.php');
Run Code Online (Sandbox Code Playgroud)

  • 很棒的信息,真的帮助我扩展了一个集合.@Alan Storm你是Magento开发的Jon Skeet :) (2认同)