好的,所以这是我最近在这里提出的另一个问题的引导。基本上,我想扩展 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 文件的底部,并使用相同的调用,则可以正常使用。
答案 0 :(得分:21)
(并不是故意让你挂在另一个帖子里,但是对于这个没有快速答案的人来说,这些答案看起来不会像魔术或只是让人们更进一步混淆。)
除非您要更改现有方法的行为,否则无需覆盖类。您只需要创建一个扩展现有类的新类。这是你如何做到的。
模型是定义Magento中某些“东西”(产品等)行为的逻辑类/对象
模型包含模型资源。模型资源是从某些数据存储(mysql等)实际获取数据的类。这是数据映射器模式。
集合是具有类似数组属性的对象,用于查询数据库并返回一组模型。有点混乱,收藏品也模型资源。
所以,在正常情况下,你可能会说像
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。
报告有点横向,但一切仍然在如上所述的同一个世界中。事实证明,没有像
这样的模型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')
添加一些方法。他们通过扩展基类来实现这一点。
所以,你真正想做的是
创建一个扩展基础Samsnamespace_Samscatalog_Model_Mysql4_Product_Collection
集合类的新类Mage_Reports_Model_Mysql4_Product_Collection
。
确保对Mage::getModelResource('samscatalog/product_collection')
的调用通过配置我们的模块来返回上述类的实例,以使用模型和模型资源。
我们也会稍微改变你的模块结构,以帮助缓解命名混乱。我不是给模块文件夹提供与核心模块相同名称(即“目录”)的忠实粉丝,而顶级文件夹(在本地/之后)实际上是命名空间,而不是模块文件夹。 (命名空间可能包含许多模块)
我们并没有凌驾于班级之上。我们在您的命名空间下配置自定义模块以使用模型和模型资源。然后我们定义一个模型资源,它扩展了系统中已有的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_collection
是samscatalog/product
模型的一部分,让我们看看配置
global/models/samscatalog/resourceModel
获取
的资源模型URIsamscatalog_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_
之后的所有内容。
希望有所帮助!
谢谢, 乔