Как переопределить класс, который вызывается другим классом с parent :: method - PullRequest
0 голосов
/ 22 апреля 2010

Я пытаюсь расширить Mage_Catalog_Block_Product_View. Я настроил его в своей версии в локальном каталоге, и все работает нормально, но я не получил желаемых результатов.Затем я увидел, что другой класс также расширил этот класс.Который, казалось, сбрасывал все, что было установлено из моего класса.Я знаю, что мой класс работает хорошо и выполняет.Просто есть другой класс, который является потомком того же класса, который я расширяю и вызываю parent :: method к тому же методу, который я переопределяю, этот класс выполняется после моего класса, и когда он это делает, он запускает оригиналметод, который я переопределяю, а не мой

Это функция

class Mage_Review_Block_Product_View extends Mage_Catalog_Block_Product_View
protected function _prepareLayout()
{
    $this->getLayout()->createBlock('catalog/breadcrumbs');
    $headBlock = $this->getLayout()->getBlock('head');
    if ($headBlock) {
        $title = $this->getProduct()->getMetaTitle();
        if ($title) {
            $headBlock->setTitle($title);
        }
        $keyword = $this->getProduct()->getMetaKeyword();
        $currentCategory = Mage::registry('current_category');
        if ($keyword) {
            $headBlock->setKeywords($keyword);
        } elseif($currentCategory) {
            $headBlock->setKeywords($this->getProduct()->getName());
        }
        $description = $this->getProduct()->getMetaDescription();
        if ($description) {
            $headBlock->setDescription( ($description) );
        } else {
            $headBlock->setDescription( $this->getProduct()->getDescription() );
        }
    }

    return parent::_prepareLayout();
}

Я пытаюсь немного изменить ее следующим образом, имейте в виду, я знаю, что есть префикс заголовкаи суффикс, но он мне нужен только для страницы продукта, а также мне нужно было добавить текст в описание.

class MyCompany_Catalog_Block_Product_View extends Mage_Catalog_Block_Product_View
protected function _prepareLayout()
{
    $storeId = Mage::app()->getStore()->getId();
    $this->getLayout()->createBlock('catalog/breadcrumbs');
    $headBlock = $this->getLayout()->getBlock('head');
    if ($headBlock) {
        $title = $this->getProduct()->getMetaTitle();
        if ($title) {
            if($storeId == 2){
                $title = "Pool Supplies Fast - "  .$title;
            $headBlock->setTitle($title);
        }
            $headBlock->setTitle($title);
        }else{
            $path  = Mage::helper('catalog')->getBreadcrumbPath();

            foreach ($path as $name => $breadcrumb) {
                $title[] = $breadcrumb['label'];
            }
             $newTitle = "Pool Supplies Fast - "  . join($this->getTitleSeparator(), array_reverse($title));
            $headBlock->setTitle($newTitle);
        }
        $keyword = $this->getProduct()->getMetaKeyword();
        $currentCategory = Mage::registry('current_category');
        if ($keyword) {
            $headBlock->setKeywords($keyword);
        } elseif($currentCategory) {
            $headBlock->setKeywords($this->getProduct()->getName());
        }
        $description = $this->getProduct()->getMetaDescription();
        if ($description) {
            if($storeId == 2){
                $description = "Pool Supplies Fast - ". $this->getProduct()->getName() . " - " . $description;
                $headBlock->setDescription( ($description) );
            }else{
              $headBlock->setDescription( ($description) );
            }

        } else {
             if($storeId == 2){
                 $description = "Pool Supplies Fast: ". $this->getProduct()->getName() . " - " . $this->getProduct()->getDescription();
                $headBlock->setDescription( ($description) );
            }else{
              $headBlock->setDescription( $this->getProduct()->getDescription() );
            }

        }
    }

    return Mage_Catalog_Block_Product_Abstract::_prepareLayout();
}

Это выполняется нормально, но затем я замечаю, что следующий класс Mage_Review_Block_Product_View_List расширяется, который расширяет Mage_Review_Block_Product_View и расширяетсяMage_Catalog_Block_Product_View, а также.Внутри этого класса они также вызывают _prepareLayout и вызывают родителя с parent :: _ prepareLayout ()

class Mage_Review_Block_Product_View_List extends Mage_Review_Block_Product_View
protected function _prepareLayout()
{
    parent::_prepareLayout();

    if ($toolbar = $this->getLayout()->getBlock('product_review_list.toolbar')) {
        $toolbar->setCollection($this->getReviewsCollection());
        $this->setChild('toolbar', $toolbar);
    }

    return $this;
}

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

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

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

Ответы [ 3 ]

3 голосов
/ 22 апреля 2010

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

Вот как работает система переопределения Magento.,Я собираюсь использовать модели в качестве примера, но это относится и к помощникам и блокам.

Когда Magento требуется создать экземпляр перезаписываемого класса, он не использует ключевое слово new.

$foo = new FooBar();

Вместо этого для глобального объекта Mage вызывается статический метод фабрики.

$foo = Mage::getModel('foo/bar');

Что делает getModel, это превращает строку "foo / bar" в фактическое имя класса.Это делается на основе ряда правил, одним из которых является проверка конфигурации всех модулей на наличие переопределений.Как только имя класса определено, объект создается.

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

Уточнение : Итак, допустим, у вас есть класс Foo, расширяющий Bar

class Bar
{
    public function example()
    {
    }
} 

class Foo extends Bar
{
    public function example()
    {
        return parent::example();
    }
}

, и вы переопределяете class Bar чем-то вроде

//magento configured ot use Baz in place of Bar
class Baz
{
}

Когда кто-то создает экземпляр объекта Foo и вызывает метод примера, parent преобразуется в класс Bar, , даже если вы переопределили класс Bar в конфигурации Magento.

1 голос
/ 22 апреля 2010

Здесь есть три варианта:

  1. Переопределите также все дочерние классы, чтобы они должным образом происходили из вашего класса (или, по крайней мере, вызывали ваш класс каким-либо образом).

  2. Поместите родительский класс в папку app/code/local/, чтобы Magento нашел его, а не класс по умолчанию. Таким образом, вы должны создать каталог app/code/local/Mage/Catalog/Block/Product/ и скопировать в него файл View.php. Однако это может стать проблемой для обновлений, поскольку вам придется объединить любые изменения, внесенные Varien в класс.

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

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

1 голос
/ 22 апреля 2010

Вы уверены, что правильно переопределили класс?(Я имею в виду размещение тега в config.xml вашего модуля, чтобы magento знал, что вы переопределяете этот класс). Если да, пожалуйста, объясните более понятными словами, что вы расширяете и что, по вашему мнению, не работает

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