Magento - расширение класса Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection - PullRequest
11 голосов
/ 07 октября 2010

ОК, так что это наводит на другой вопрос, который я недавно задал здесь.По сути, я хочу расширить класс 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 /системы / конфигурация / расширенная).Структура папок выглядит следующим образом:

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 ]

21 голосов
/ 07 октября 2010

(Не хотел оставлять вас висеть в другой ветке, но нет быстрого ответа на этот вопрос, который не будет ни казаться волшебством, ни просто сбивать людей с толку).

Вы нене нужно переопределять класс, если вы не собираетесь изменить поведение существующего метода.Вам просто нужно создать новый класс, который расширяет существующего класса.Вот как вы это делаете.

Терминология для нормального состояния вещей

  1. Модели - это логические классы / объекты, которые определяют поведение некоторой "вещи" (продукта,и т. д.) в Magento

  2. Модели содержат ресурсы модели.Ресурсы модели - это классы, которые осуществляют фактическую выборку данных из некоторого хранилища данных (mysql и т. Д.).Это шаблон Data Mapper.

  3. Коллекции - это объекты со свойствами, подобными массиву, которые запрашивают базу данных и возвращают группу моделей.Несколько сбивает с толку, Коллекции являются также Ресурсами Модели.

Итак, в нормальном состоянии вы могли бы сказать что-то вроде

Mage::getModel('catalog/product')

, чтобы получить модель продукта, а базовая система использует

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

, чтобы получить объект Mode Resource, который запрашивает один продукт, и или из следующего используются

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

, чтобы получить объект Collection, который запрашивает многие модели.В текущих версиях Magento каждый объект Model имеет метод с именем «getCollection», который возвращает соответствующий ресурс коллекции.

Отчеты с рельсов

Отчеты идут немного вбок, но все находится в той же вселенной, как описано выше.Оказывается, нет такой модели, как

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') возвращает экземпляр вышеуказанного класса, сконфигурировав наш модуль для использования ресурсов моделей и моделей.

Мы также собираемся изменить структуру вашего модуля вокругнемного, чтобы облегчить путаницу имен. Я не большой поклонник для того, чтобы давать папкам модулей те же имена, что и у основных модулей (например, «Каталог»), а папка верхнего уровня (после local /) на самом деле является пространством имен, а не модулемпапка (пространство имен может содержать много модулей)

Мы не переопределяем класс. Мы настраиваем настраиваемый модуль в вашем пространстве имен для использования как ресурсов моделей, так и ресурсов модели. Затем мы определяем ресурс модели, который расширяетсясуществующий класс PHPуже в системе.Переопределения следует использовать только тогда, когда вы хотите изменить поведение определенного вызова метода.(Приносим извинения за это, но в сообществе достаточно общей путаницы по этому поводу, что стоит обсуждать снова и снова. И снова и снова.)

Во-первых, мы собираемся создать структуру каталогов модулей ифайлы.Нам просто понадобятся два

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

(и не забудьте включить модуль в приложении / etc / modules. Если вы не уверены, что это значит, начните читать )

Файл 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));

, и ваша коллекция будет возвращена, и вы сможете добавлять методы к своему сердцу.

Что происходит

Это умопомрачительный ум, поэтому вы можете перестать читать, если хотите.Это также перефразировка понятий, которые я рассмотрел в другом месте .

Когда вы говорите

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

Базовые коды системы магов говорят: «Хорошо, вот эта модель ресурса»

samscatalog/product_collection

является частью модели

samscatalog/product

(в данном случае это не совсем так, но система так думает).

Итак, поскольку ресурсмодель samscatalog/product_collection является частью модели samscatalog/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');
0 голосов
/ 07 октября 2010

Каков класс полученной коллекции продуктов? Работает ли ваше переопределение?

Этот раздел кажется подозрительным, я удивлен, если он действительно работает:

<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_resource_eav_mysql4 - нет. Тег внутри класса определяет дескриптор класса, который является практически всем после Mage_Catalog_Model_ в имени класса.

Надеюсь, это поможет!

Спасибо, Джо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...