如何使用parent ::方法覆盖另一个类调用的类

时间:2010-04-22 11:27:22

标签: magento

我正在尝试扩展Mage_Catalog_Block_Product_View我在我的本地目录中设置了它并且一切正常,但我没有得到我想要的结果。然后我看到另一个类也扩展了那个类。这似乎重置了我班上设置的内容。我知道我的班级工作正常并且正在执行。它只是有另一个类是同一个类的子类我正在扩展并调用parent ::方法到我覆盖的相同方法,该类在我的类之后执行,当它执行时,它运行原始我压倒而不是我的方法

这是功能

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();
}

这个executs很好但后来我注意到下面的类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 个答案:

答案 0 :(得分:3)

您的帖子有点不清楚,但我认为您遇到了Magento限制,只能覆盖继承链底部的类。

以下是Magento的覆盖系统的工作原理。我将使用模型作为示例,但它也适用于帮助程序和块。

当Magento需要实例化一个可覆盖的类时,它不会使用new关键字。

$foo = new FooBar();

相反,在全局Mage对象上调用静态工厂方法。

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

getModel做的是将字符串“foo / bar”转换为实际的类名。它基于一系列规则执行此操作,其中一个规则是检查所有模块配置是否有任何覆盖。确定类名后,将实例化一个对象。

这很有效,但这意味着您可以覆盖类的实例化。没有办法覆盖父类的方法,因为这些方法是通过普通的PHP机制继承的。

澄清:所以,假设你有一个扩展Bar的类Foo

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,即使您已在Magento配置中覆盖了类Bar。

答案 1 :(得分:1)

你确定你正确地覆盖了这个类吗? (我的意思是将< rewrite>标记放在模块的config.xml中,让magento知道你重写了这个类) 如果是的话,请用更清楚的词语解释您所延伸的内容以及您认为无效的内容

答案 2 :(得分:1)

这里有三个选项:

  1. 也覆盖所有子类,以便它们适当地从您的类中下降(或者至少以某种方式调用您的类)。

  2. 将父类放入app/code/local/文件夹,以便Magento找到它而不是默认值。因此,您要创建目录app/code/local/Mage/Catalog/Block/Product/并将View.php复制到其中。但这对于升级来说是一个问题,因为你必须合并Varien对该类所做的任何更改。

  3. 放弃重写并在模板中更改它。这可能是最好的选择,因为您不必担心_prepareLayout方法的变化。

  4. 希望有所帮助, 乔